Puedes acceder a los datos de ubicación y de sensores con las APIs estándar de la plataforma de Android.
Ubicación
La ubicación en Glass implica el uso de las APIs estándar de la plataforma de Android para obtener datos de ubicación de los proveedores de ubicación disponibles.
Usarás las siguientes clases del SDK de Android para obtener datos de ubicación:
LocationManager
: Proporciona acceso al servicio del sistema de ubicación de Android que controla la comunicación con unLocationProvider
.LocationProvider
: Proporciona datos de ubicación según algunos criterios. Glass ofrece proveedores "remotos" especiales que te permiten obtener datos de ubicación de un dispositivo vinculado que tenga instalada la app complementaria de MyGlass.Criteria
: Te permite crear un conjunto de criterios que selecciona el mejorLocationProvider
en función de los criterios que establezcas.
Descripción general
Para obtener datos de ubicación, deberás usar la clase LocationManager
para obtener datos de uno o más proveedores de ubicación.
Las aplicaciones en un teléfono o tablet Android recuperan datos de ubicación de los proveedores de ubicación de red y GPS local del dispositivo. Sin embargo, en Glass, el conjunto de proveedores de ubicación disponibles es dinámico y puede incluir proveedores de ubicación remoto que proporcionan datos de ubicación de otra fuente, como un dispositivo vinculado con Bluetooth que tiene instalada la aplicación complementaria MyGlass. Para controlar estos proveedores adicionales, escucha las actualizaciones de ubicación de varios proveedores en lugar de uno solo.
Para solicitar datos de todos los proveedores de ubicación disponibles, sigue estos pasos:
- Crea un objeto
Criteria
con tus requisitos de ubicación. - Llama a
getProviders()
para recuperar la lista de proveedores habilitados que cumplan con tus criterios. - Itera la lista de proveedores y solicita actualizaciones a todos ellos. Esto garantiza que recibas actualizaciones de los proveedores remotos, si están disponibles, pero también de los proveedores locales en Glass (como un proveedor de red inalámbrica).
Usa la información de precisión y tiempo proporcionada con cada actualización para determinar si la actualización es lo suficientemente buena o si debes esperar una nueva.
LocationManager locationManager; // initialized elsewhere // This example requests fine accuracy and requires altitude, but // these criteria could be whatever you want. Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setAltitudeRequired(true); List<String> providers = locationManager.getProviders( criteria, true /* enabledOnly */); for (String provider : providers) { locationManager.requestLocationUpdates(provider, minTime, minDistance, listener); }
Sensores
Vidrio
Glass tiene un sensor especializado para detectar si el dispositivo está o no en la cabeza del usuario. Cuando se habilita, este parámetro de configuración ayuda a ahorrar batería cuando el dispositivo no está en uso. Puedes usar esta función en Glassware para inhabilitar o limitar los servicios en segundo plano. Comienza por implementar un BroadcastReceiver
para detectar eventos ACTION_ON_HEAD_STATE_CHANGE
.
En el siguiente ejemplo, se inhabilitan y retrasan las actualizaciones de puntuación del juego en función de si el usuario quitó Glass de su cabeza:
- Implementa un
BroadcastReceiver
para controlar el cambio de estado. - En tu servicio, implementa el método
onCreate()
y registra un receptor que escuche el intentACTION_ON_HEAD_STATE_CHANGE
. En el método
onDestroy()
, cancela el registro del receptor.import com.google.android.glass.content.Intents; ... public class LiveCardService extends Service { ... private boolean mIsStopped = false; private final BroadcastReceiver broadCastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (Intents.ACTION_ON_HEAD_STATE_CHANGED.equals(intent.getAction())) { boolean onHead = intent.getBooleanExtra(Intents.EXTRA_IS_ON_HEAD, false); if (onHead) { mDelay = LiveCardService.DELAY_MILLIS; if (isStopped()) { // Resume updating scores setStop(false); // Restart immediately to get a refreshed score mHandler.postDelayed(mUpdateLiveCardRunnable, 0); } } else { // Increase the delay when the device is off head mDelay = LiveCardService.DELAY_MILLIS_EXT; } } } }; private final Runnable mUpdateLiveCardRunnable = new Runnable() { @Override public void run() { if (mDelay == DELAY_MILLIS_EXT) { // Count the increased delay as a retry attempt mRetryCount++; } else if (mDelay == DELAY_MILLIS) { mRetryCount = 0; } if (mRetryCount > MAX_RETRIES) { // Stop updating scores mIsStopped = true; } if (!isStopped()) { // Generate fake points. homeScore += mPointsGenerator.nextInt(3); awayScore += mPointsGenerator.nextInt(3); // Update the remote view with the new scores. mLiveCardView = getRemoteViews(homeScore, awayScore); // Always call setViews() to update the live card's RemoteViews. mLiveCard.setViews(mLiveCardView); // Queue another score update in 30 seconds. mHandler.postDelayed(mUpdateLiveCardRunnable, mDelay); } } }; @Override public void onCreate() { super.onCreate(); mPointsGenerator = new Random(); mDelay = DELAY_MILLIS; registerReceiver(broadCastReceiver, new IntentFilter( Intents.ACTION_ON_HEAD_STATE_CHANGED)); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (mLiveCard == null) { // Get an instance of a live card mLiveCard = new LiveCard(this, LIVE_CARD_TAG); // Inflate a layout into a remote view mLiveCardView = new RemoteViews(getPackageName(), R.layout.live_card); // Set up initial RemoteViews values homeScore = 0; awayScore = 0; mLiveCardView = getRemoteViews(homeScore, awayScore); // Set up the live card's action with a pending intent // to show a menu when tapped Intent menuIntent = new Intent(this, LiveCardMenuActivity.class); menuIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); mLiveCard.setAction(PendingIntent.getActivity( this, 0, menuIntent, 0)); // Publish the live card mLiveCard.publish(PublishMode.REVEAL); // Queue the update text runnable mHandler.post(mUpdateLiveCardRunnable); } return START_STICKY; } @Override public void onDestroy() { if (mLiveCard != null && mLiveCard.isPublished()) { //Stop the handler from queuing more Runnable jobs setStop(true); mLiveCard.unpublish(); mLiveCard = null; } unregisterReceiver(broadCastReceiver); super.onDestroy(); } @Override public IBinder onBind(Intent intent) { return null; } private RemoteViews getRemoteViews(int homeScore, int awayScore) { RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.live_card); remoteViews.setTextViewText(R.id.home_team_name_text_view, getString(R.string.home_team)); remoteViews.setTextViewText(R.id.away_team_name_text_view, getString(R.string.away_team)); remoteViews.setTextViewText(R.id.footer_text, getString(R.string.game_quarter)); remoteViews.setTextViewText(R.id.home_score_text_view, String.valueOf(homeScore)); remoteViews.setTextViewText(R.id.away_score_text_view, String.valueOf(awayScore)); return remoteViews; } public boolean isStopped() { return mIsStopped; } public void setStop(boolean isStopped) { mIsStopped = isStopped; } }
Android
Los siguientes sensores de Android son compatibles con Glass:
TYPE_ACCELEROMETER
TYPE_GRAVITY
TYPE_GYROSCOPE
TYPE_LIGHT
TYPE_LINEAR_ACCELERATION
TYPE_MAGNETIC_FIELD
TYPE_ORIENTATION
(obsoleto)TYPE_ROTATION_VECTOR
Los siguientes sensores de Android no son compatibles:
A continuación, se ofrecen algunas sugerencias para usar sensores en Glass:
- El sistema de coordenadas del sensor Glass se muestra a continuación en relación con la pantalla Glass. Para obtener más información, consulta Sistema de coordenadas del sensor.
El acelerómetro, el giroscopio y el magnetómetro se encuentran en el pod de óptica del dispositivo Glass, que los usuarios rotan para alinear el dispositivo con su vista. No puedes medir el ángulo del pod de la óptica directamente, así que ten esto en cuenta cuando uses los ángulos de estos sensores para aplicaciones como la orientación de la brújula.
Para preservar la duración de batería, solo escucha los sensores cuando los necesites. Por ejemplo, si tu Glassware usa un
Service
para renderizar unLiveCard
y solo necesitas los sensores cuando la tarjeta activa está visible, usa los métodos de devolución de llamada de superficieLiveCard
para comenzar a escuchar los sensores y dejar de hacerlo.Las devoluciones de llamada de eventos de sensor se ejecutan en el subproceso de IU, por lo que debes procesar los eventos y mostrarlos lo más rápido posible. Considera enviar los eventos del sensor a una cola y usar un subproceso en segundo plano para controlarlos si el procesamiento lleva demasiado tiempo.
A menudo, 50 Hz es suficiente tasa de muestreo para monitorear el movimiento de la cabeza.
Para obtener más información sobre cómo usar sensores, consulta la guía para desarrolladores de Android.