Tecnologías Móviles

clase 13

Ejercicio de la clase anterior

WebSocket

Ejercicio de la clase anterior

public class ApiClientService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener {
    ...

    public void onCreate() {
        handler = new Handler(getMainLooper());
        ...
    }

    private void runOnUIThread(Runnable r) {
        handler.post(r);
    }

    ...
}

ApiClientService

Ejercicio de la clase anterior

public class ApiClientService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener {
    ...
    protected void setUrl() {
        if(mSocket!=null) {
            mSocket.off();
            mSocket.disconnect();
        }
        try {
            mSocket = IO.socket(mPreferences.getString("url", "http://tm5-agmoyano.rhcloud.com/"));
            mSocket.on("api:error", new Emitter.Listener() {
                @Override
                public void call(Object... args) {
                    Log.e("WEBSOCKET", args[0] + "");
                }
            });
            mSocket.on("post:login", new Emitter.Listener() {
                @Override
                public void call(Object... args) {
                    JSONObject user = (JSONObject) args[0];
                    mPreferences.edit().putString("current-user", user.optString("_id")).commit();
                }
            });
            mSocket.on("get:user", new Emitter.Listener() {
                @Override
                public void call(Object... args) {
                    final JSONArray users = (JSONArray) args[0];
                    runOnUIThread(new Runnable() {
                        @Override
                        public void run() {
                            UserAdapter.getInstance().setUsers(users);
                        }
                    });
                }
            });
            ...
    }
    ...
}

ApiClientService

Ejercicio de la clase anterior

public class ApiClientService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener {
    ...
    protected void setUrl() {
        ...
            mSocket.on("get:chat", new Emitter.Listener() {
                @Override
                public void call(Object... args) {
                    final JSONArray chats = (JSONArray) args[0];
                    runOnUIThread(new Runnable() {
                        @Override
                        public void run() {
                            ChatAdapter.getInstance(ApiClientService.this).setChats(chats);
                        }
                    });
                }
            });
            mSocket.on("post:chat", new Emitter.Listener() {
                @Override
                public void call(Object... args) {
                    final JSONObject chat = (JSONObject) args[0];
                    runOnUIThread(new Runnable() {
                        @Override
                        public void run() {
                            ChatAdapter.getInstance(ApiClientService.this).setChat(chat);
                        }
                    });
                }
            });
            ...
    }
    ...
}

ApiClientService

Ejercicio de la clase anterior

    ...
    protected void setUrl() {
        ...
            mSocket.on("post:message", new Emitter.Listener() {
                @Override
                public void call(Object... args) {
                    final JSONObject msg = (JSONObject) args[0];
                    runOnUIThread(new Runnable() {
                        @Override
                        public void run() {
                            MsgAdapter.getInstance(ApiClientService.this).setMsg(msg);
                        }
                    });
                }
            });
            mSocket.on("get:message", new Emitter.Listener() {
                @Override
                public void call(Object... args) {
                    final JSONArray msgs = (JSONArray) args[0];
                    if(msgs.length()>0) {
                        runOnUIThread(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    MsgAdapter.getInstance(ApiClientService.this)
                                        .setMsgs(msgs.getJSONObject(0).optString("chat"), msgs);
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                        });
                    }

                }
            });
            mSocket.connect();
    }
    ...

ApiClientService

Ejercicio de la clase anterior

public class APIBinder extends Binder {

        public void login()  {
            Object[] o = {mEmail};
            mSocket.emit("post:login", o, new Ack() {
                @Override
                public void call(Object... args) {
                    mBinder.findUsers();
                    mBinder.findChats();
                }
            });
        }

        public void findChats() { mSocket.emit("get:chat"); }

        public void findMsgs(final String chatId) { mSocket.emit("get:message", chatId); }

        public void findUsers() { mSocket.emit("get:user"); }

        public void addChat(String uid, Ack ack) {
            Object[] o = {uid};
            mSocket.emit("post:chat", o, ack);
        }

        public void addMsg(final String chatId, final String msg) {
            mSocket.emit("post:message", chatId, msg);
        }

        public void addUser(final JSONObject usuario) { mSocket.emit("post:user", usuario); }

        public void setUser(JSONObject usuario) { mSocket.emit("put:user", usuario); }

        public void rmUser() { mSocket.emit("delete:user"); }

    }

ApiClientService

Location

compile 'com.google.android.gms:play-services:9.0.1'

Gradle

Google Play location service API

AndroidManifest

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  • ACCESS_COARSE_LOCATION: Consume menos recursos, pero es menos preciso.
  • ACCESS_FINE_LOCATION: Consume mayores recursos, pero es mas preciso.

Location

if (mGoogleApiClient == null) {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
        .addConnectionCallbacks(this)
        .addOnConnectionFailedListener(this)
        .addApi(LocationServices.API)
        .build();
}

MainActivity - onCreate

Conectar y Desconectar

protected void onStart() {
    super.onStart();
    mGoogleApiClient.connect();
}

protected void onStop() {
    super.onStop();
    mGoogleApiClient.disconnect();
}

Location

public class MainActivity extends ActionBarActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
    @Override
    public void onConnected(Bundle connectionHint) {
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

        if (mLastLocation != null) {
            mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
            mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
        }
    }
}

Obtener la última posición

Location

public void onConnected(Bundle connectionHint) {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(10000);
    mLocationRequest.setFastestInterval(5000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}

Actualizar la posición actual

1. Creamos un LocationRequest

  • setInterval: Intervalo preferido para recibir actualizaciones. Si otra aplicación tiene un intervalo menor, la posición se actualiza con ese intervalo.
  • setFastestInterval: Intervalo mínimo soportado por la aplicación.
  • setPriority:
    • ​PRIORITY_BALANCED_POWER_ACCURACY: Precisión de aproximadamente 100 metros.
    • PRIORITY_HIGH_ACCURACY: Prima la precisión sobre el consumo de energía.
    • PRIORITY_LOW_POWER: Precisión de aproximadamente 10 kilómetros
    • PRIORITY_LOW_POWER: Actualiza la posición si otras aplicaciones lo piden.

Location

@Override
public void onConnected(Bundle connectionHint) {
    ...
    if (mRequestingLocationUpdates) {
        startLocationUpdates();
    }
}

protected void startLocationUpdates() {
    LocationServices.FusedLocationApi.requestLocationUpdates(
            mGoogleApiClient, mLocationRequest, this);
}

Actualizar la posición actual

2. Registramos un listener para la actualización de la posición

Location

public class MainActivity extends ActionBarActivity implements
        ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
    ...
    @Override
    public void onLocationChanged(Location location) {
        mCurrentLocation = location;
        mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
        updateUI();
    }

    private void updateUI() {
        mLatitudeTextView.setText(String.valueOf(mCurrentLocation.getLatitude()));
        mLongitudeTextView.setText(String.valueOf(mCurrentLocation.getLongitude()));
        mLastUpdateTimeTextView.setText(mLastUpdateTime);
    }
}

Actualizar la posición actual

3. Definimos el listener 

Location

@Override
protected void onPause() {
    super.onPause();
    stopLocationUpdates();
}

protected void stopLocationUpdates() {
    LocationServices.FusedLocationApi.removeLocationUpdates(
            mGoogleApiClient, this);
}

@Override
public void onResume() {
    super.onResume();
    if (mGoogleApiClient.isConnected() && !mRequestingLocationUpdates) {
        startLocationUpdates();
    }
}

Actualizar la posición actual

4. Ciclo de vida 

Ejercicio

Basado en el ejercicio de la clase anterior:

  • Agregar una preferencia en la configuración de la aplicación que pregunte si el usuario quiere compartir su ubicación actual.
  • Si la ubicación se comparte, se debe enviar el evento "on:location" con 2 parámetros (latitud,longitud), cada vez que haya una actualización de ubicación.
  • Agregar una preferencia en la configuración que determine la prioridad de la precisión de la ubicación (setPriority)
  • Si la ubicación no se comparte, se debe eliminar el listener de ubicación, y se debe enviar el evento "off:location".

Tecnologías Móviles - Clase 13

By Agustin Moyano

Tecnologías Móviles - Clase 13

  • 672