Posizioni e sensori

Accedi ai dati dei sensori e della posizione utilizzando il le API della piattaforma.

Località

La posizione su Glass prevede l'utilizzo dello standard Android API della piattaforma per ottenere i dati sulla posizione i fornitori di servizi di localizzazione.

Per ottenere i dati sulla posizione, utilizzerai le seguenti classi dell'SDK Android:

  • LocationManager - Fornisce l'accesso al servizio del sistema di geolocalizzazione di Android che gestisce la comunicazione con LocationProvider.

  • LocationProvider - Fornisce dati sulla posizione in base ad alcuni criteri. Glass offre uno speciale "telecomando" provider che ti consentono di ottenere i dati sulla posizione da un dispositivo accoppiato con MyGlass app complementare installata.

  • Criteria - Consente di creare un insieme di criteri che seleziona il LocationProvider migliore in base ai criteri impostati.

Panoramica

Per ottenere i dati sulla posizione, devi utilizzare LocationManager per ottenere dati da uno o più fornitori di località.

Le app su uno smartphone o tablet Android recuperano i dati sulla posizione dai Fornitori di servizi di localizzazione di rete e GPS sul dispositivo. Su Glass, invece, l'insieme di fornitori di posizione disponibili è dinamico e può includere telecomando fornitori di servizi di localizzazione che forniscono dati sulla posizione da un'altra origine, come una Dispositivo accoppiato tramite Bluetooth con l'app complementare MyGlass installata. Per gestire questi altri fornitori, ascoltano gli aggiornamenti sulla posizione di o di un altro provider.

Per richiedere i dati a tutti i fornitori di posizione disponibili:

  1. Crea una Criteria con i tuoi requisiti di località.
  2. Chiama il numero getProviders() per recuperare l'elenco dei provider abilitati che soddisfano i tuoi criteri.
  3. Ripeti l'elenco dei fornitori e richiedi aggiornamenti da tutti. In questo modo, avrai la certezza di ricevere gli aggiornamenti dai provider remoti, se sono ma anche dai fornitori locali su Glass (come una rete wireless dell'operatore di rete).
  4. Usa le informazioni sull'accuratezza e sulle tempistiche fornite con ogni aggiorna per determinare se l'aggiornamento è sufficiente o se dovresti aspettarne un altro.

    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);
    }
    

Sensori

Vetro

Glass dispone di un sensore specializzato per rilevare se il dispositivo si trova utente testa. Quando è attiva, questa impostazione consente di risparmiare batteria quando il dispositivo non è in uso. Puoi usare questa funzionalità in Glassware per disattivare o dei servizi in background. Per iniziare, implementa un BroadcastReceiver per rilevare ACTION_ON_HEAD_STATE_CHANGE eventi.

L'esempio seguente ritarda e disattiva gli aggiornamenti dei punteggi delle partite a seconda che l'utente ha rimosso Glass dalla testa:

  1. Implementare un modello BroadcastReceiver per gestire la modifica dello stato.
  2. Nel tuo servizio, implementa il onCreate() e registrare un ricevitore che ascolti Intento ACTION_ON_HEAD_STATE_CHANGE.
  3. Nella onDestroy() annulla la registrazione del ricevitore.

    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

Su Glass sono supportati i seguenti sensori Android:

I seguenti sensori Android non sono supportati:

di Gemini Advanced.

Ecco alcuni suggerimenti per l'utilizzo dei sensori su Glass:

  • Di seguito è mostrato il sistema di coordinate dei sensori di Glass rispetto al display di Glass. Per ulteriori informazioni, vedi sistema di coordinate dei sensori.

  • L'accelerometro, il giroscopio e il magnetometro si trovano sul pod ottico del dispositivo Glass, che gli utenti ruotano per allineare il dispositivo alla vista. Non è possibile misurare l'angolazione del pod ottica, quindi tienine conto quando utilizzando gli angoli di questi sensori per applicazioni come l'orientamento della bussola.

  • Per preservare la durata della batteria, ascolta i sensori solo quando ti serve. Ad esempio, se il tuo oggetto utilizza un Service per eseguire il rendering LiveCard e i sensori sono necessari solo quando la scheda live è visibile, usa LiveCard individua i metodi di callback per avviare e interrompere l'ascolto dei sensori.

  • I callback degli eventi dei sensori vengono eseguiti sul thread dell'interfaccia utente, quindi gli eventi vengono elaborati e restituiti come il più rapidamente possibile. Valuta la possibilità di inserire in coda gli eventi dei sensori e di utilizzare un thread in background se l'elaborazione richiede troppo tempo.

  • 50 Hz è spesso una frequenza di campionamento sufficiente per tracciare il movimento della testa.

Per ulteriori informazioni su come utilizzare i sensori, vedi le Guida per gli sviluppatori Android.