Sensórica - TeamSecurityFirst/GeoGuardianWiki GitHub Wiki

Actualmente se hacen uso de dos grandes tipos de sensores

Sensor de iluminación

Se ha incorporado un sensor de iluminación para poder permitir a los usuarios tener una visión del mapa en modo nocturno o de baja luz. De esta manera, si la luz ambiente del dispositivo no es lo suficientemente alta, el mapa (tanto en la clase del mapa principal, como en la edición de rutas) se pondrá en modo nocturno. De esta manera, permitiremos a los usuarios la opción de adaptar la interfaz gráfica a su luz ambiente, favoreciendo su experiencia en la aplicación.

Su implementación se puede encontrar en la clase Fragment Map. Entre las características más importantes, destacan:

En el OnCreate, obtenemos una instancia de SensorManager, necesario para la gestión de los distintos sensores presentes en el dispositivo. Gracias a esto, obtenemos una instancia de tipo SensorLight.

    @Override
    public void onCreate() {
        .
        .
        .
       // Getting the light sensor of the device
        mSensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE);
        mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
    }

Posteriormente, debemos registrar un SensorEventListener (listener preparado para la escucha de los valores de los sensores) en el método onResume(). Además, en el propio método onResume, nos aseguramos de que el dispositivo actual tenga disponible el sensor de iluminación (algo extramedamente habitual hoy en día), para esto, solo es necesario comprobar que se ha registrado correctamente la instancia del sensor de luz creada previamente. También lo desregistramos en el onPause().

    @Override
    public void onResume() {
        super.onResume();
        boolean isSensorPresent;
        // Registering the sensor listener
        isSensorPresent = mSensorManager.registerListener(this, mLightSensor,
                SensorManager.SENSOR_DELAY_NORMAL);

        if (isSensorPresent) {
            flagSensor = true;
        }
        else {
            Log.d("NOT_LIGHT_SENSOR", "Device does not support Light Sensor");
        }
    }

    @Override
    public void onPause(){
        super.onPause();
        // Leaving the sensor control
        mSensorManager.unregisterListener(this);
    }

Por último, ha sido necesario implementar los método de la interfaz onSensorChanged y onAccuracyChanged. El primero de ellos es fundamental, puesto que registra constantemente cuando ha habido un cambio en los valores del sensor (de la luz en nuestro caso). Cuando está por encima o por debajo de un valor de referencia, el mapa cambiará de tema, pasando de claro a oscuro y al revés.

@Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        lightValue = sensorEvent.values[0];
        Log.d("LightValue", "LightValue:" + lightValue);

        // Waiting for the response in Handler (1 sec)
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            public void run() {
                if (flagSensor) {
                    if (lightValue >= 15) {
                        mGoogleMap.setMapStyle(MapStyleOptions.loadRawResourceStyle(getActivity(), R.raw.style_map_light));

                    }
                    else {
                        mGoogleMap.setMapStyle(MapStyleOptions.loadRawResourceStyle(getActivity(), R.raw.style_map_dark));
                    }
                }


            }
        }, 1000);
    }

Comentar que, debido a que es necesario tener una instancia cargada correctamente del mapa previo a hacer ningún tipo de cambio sobre él, se ha añadido un Handler de 1000ms para asegurarnos por completo que el mapa ha cargado previamente. De lo contrario, en ocaciones se detectaban antes cambios en la iluminación que la propia carga del mapa (obtenida en el método OnMapReady), lo que ocasionaba problemas en la aplicación.

Respecto al método onAccuracyChanged, no ha sido incluir ninguna lógica, puesto que por el momento no hemos contemplado ningún uso del mismo en nuestra aplicación.

Imagen en formato GIF a modo de demostración del cambio en el mapa

Geolocalización (GPS)

Tal y como hemos comentado en secciones anteriores, la base de todas nuestras funcionalidades requiere la constante actualización de la localización por parte de los usuarios. Para esto, usamos el API de GooglePlayServices, FusedLocationProvider, que combina de manera optimizada diferentes señales del dispositivo para obtener su localización, como son el GPS (mediante combinación de sensores como el de posición o el giroscopio) y el Wi-fi, lo que nos permite solicitar los datos más precisos disponibles o la mejor precisión posible sin consumo de energía adicional. El uso de esta API de alto nivel por parte de la aplicación se puede observar en mayor detalle aquí.