Puedes acceder a los datos de ubicación y del sensor con las API de plataforma de Android estándar.
Ubicación
La ubicación en Glass implica el uso de las API de la plataforma de Android estándar 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 en función de algunos criterios. Glass proporciona proveedores "remotos" especiales que te permiten obtener datos de ubicación desde un dispositivo sincronizado que tenga instalada la app complementaria de MyGlass.Criteria
: Te permite crear un conjunto de criterios que selecciona el mejorLocationProvider
según los criterios que establezcas.
Descripción general
A fin de obtener datos de ubicación, deberás usar la clase LocationManager
para obtener datos de uno o más proveedores de ubicaciones.
Las aplicaciones en un teléfono o tablet Android recuperan datos de ubicación de GPS locales y proveedores de ubicación de red en el dispositivo. Sin embargo, en Glass, el conjunto de proveedores de ubicación disponibles es dinámico y puede incluir proveedores de ubicación remota que proporcionan datos de ubicación desde otra fuente, como un dispositivo sincronizado con Bluetooth con la app complementaria de MyGlass instalada. Para controlar estos proveedores adicionales, detecta las actualizaciones de ubicación de varios proveedores en lugar de un solo proveedor.
Para solicitar datos de todos los proveedores de ubicación disponibles:
- Crea un objeto
Criteria
con tus requisitos de ubicación. - Llama a
getProviders()
para recuperar la lista de proveedores habilitados que cumplen con tus criterios. - Repita la lista de proveedores y solicite 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 sincronización que se proporciona con cada actualización para determinar si es lo suficientemente buena o si debes esperar otra.
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á sobre la cabeza del usuario. Cuando está habilitada, esta configuración ayuda a conservar la batería cuando el dispositivo no está en uso. Puedes usar esta función en tu Glassware para inhabilitar o limitar los servicios en segundo plano. Comienza por implementar una BroadcastReceiver
para detectar eventos ACTION_ON_HEAD_STATE_CHANGE
.
En el siguiente ejemplo, se retrasan y se inhabilitan las actualizaciones de la 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()
, anula 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 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
No se admiten los siguientes sensores Android:
Estas son algunas sugerencias para usar sensores en Glass:
- A continuación, se muestra el sistema de coordenadas del sensor de Glass en relación con la pantalla Glass. Para obtener más información, consulta el sistema de coordenadas de sensores.
El acelerómetro, el giroscopio y el magnetómetro se encuentran en el pod óptico del dispositivo Glass, que los usuarios giran para alinearlo con su visión. No puedes medir directamente el ángulo del pod óptico, así que ten esto en cuenta cuando uses ángulos de estos sensores para aplicaciones como la orientación de la brújula.
Para conservar la duración de la batería, solo escucha los sensores cuando los necesites. Por ejemplo, si tu Glassware usa un
Service
para procesar unLiveCard
y solo necesitas los sensores cuando la tarjeta en vivo está visible, usa los métodos de devolución de llamada de superficieLiveCard
para iniciar y dejar de escuchar los sensores.Las devoluciones de llamada de eventos del 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 eventos del sensor a una cola y usar un subproceso en segundo plano para controlarlos si el procesamiento lleva demasiado tiempo.
A menudo, una frecuencia de muestreo de 50 Hz es suficiente para realizar un seguimiento del movimiento de la cabeza.
Para obtener más información sobre cómo usar los sensores, consulta la Guía para desarrolladores de Android.