Lokasi dan Sensor

Anda mengakses data sensor dan lokasi menggunakan API platform Android standar.

Lokasi

Lokasi di Glass melibatkan penggunaan API platform Android standar untuk mendapatkan data lokasi dari penyedia lokasi yang tersedia.

Anda akan menggunakan class Android SDK berikut untuk mendapatkan data lokasi:

  • LocationManager – Memberikan akses ke layanan sistem lokasi Android yang menangani komunikasi dengan LocationProvider.

  • LocationProvider – Memberikan data lokasi berdasarkan beberapa kriteria. Glass menyediakan penyedia "jarak jauh" khusus yang memungkinkan Anda memperoleh data lokasi dari perangkat yang dipasangkan dan menginstal aplikasi pendamping MyGlass.

  • Criteria – Memungkinkan Anda membuat kumpulan kriteria yang memilih LocationProvider terbaik berdasarkan kriteria yang Anda tetapkan.

Ringkasan

Untuk mendapatkan data lokasi, Anda harus menggunakan class LocationManager untuk mendapatkan data dari satu atau beberapa penyedia lokasi.

Aplikasi di ponsel atau tablet Android mengambil data lokasi dari GPS lokal dan penyedia lokasi jaringan di perangkat. Namun, pada Glass, kumpulan penyedia lokasi yang tersedia bersifat dinamis dan dapat mencakup penyedia lokasi jarak jauh yang menyediakan data lokasi dari sumber lain, seperti perangkat yang disambungkan dengan Bluetooth yang menginstal aplikasi pendamping MyGlass. Untuk menangani penyedia tambahan ini, proses pembaruan lokasi dari beberapa penyedia, bukan dari satu penyedia.

Untuk meminta data dari semua penyedia lokasi yang tersedia:

  1. Buat objek Criteria dengan persyaratan lokasi Anda.
  2. Panggil getProviders() untuk mengambil daftar penyedia yang diaktifkan yang memenuhi kriteria Anda.
  3. Lakukan iterasi pada daftar penyedia dan minta pembaruan dari semua penyedia tersebut. Hal ini memastikan bahwa Anda menerima update dari penyedia jarak jauh jika tersedia, tetapi juga dari penyedia lokal di Glass (seperti penyedia jaringan nirkabel).
  4. Gunakan informasi akurasi dan pengaturan waktu yang disediakan dengan setiap update untuk menentukan apakah update tersebut cukup baik atau apakah Anda harus menunggu update lainnya.

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

Sensor

Kaca

Glass memiliki sensor khusus untuk mendeteksi apakah perangkat berada di kepala pengguna atau tidak. Jika diaktifkan, setelan ini akan membantu menghemat baterai saat perangkat tidak digunakan. Anda dapat menggunakan fitur ini di Glassware untuk menonaktifkan atau membatasi layanan latar belakang. Mulai dengan mengimplementasikan BroadcastReceiver untuk mendeteksi peristiwa ACTION_ON_HEAD_STATE_CHANGE.

Contoh berikut menunda dan menonaktifkan update skor game berdasarkan apakah pengguna telah menghapus Glass dari kepalanya:

  1. Terapkan BroadcastReceiver untuk menangani perubahan status.
  2. Dalam layanan Anda, implementasikan metode onCreate() dan daftarkan penerima yang memproses intent ACTION_ON_HEAD_STATE_CHANGE.
  3. Dalam metode onDestroy(), batalkan pendaftaran penerima.

    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

Sensor Android berikut didukung di Glass:

Sensor Android berikut tidak didukung:

Berikut beberapa tips saat menggunakan sensor pada Glass:

  • Sistem koordinat sensor Glass ditampilkan di bawah relatif terhadap layar Glass. Untuk informasi selengkapnya, lihat sistem koordinat sensor.

  • Akselerometer, giroskop, dan magnetometer terletak di pod optik perangkat Glass, yang diputar pengguna untuk menyelaraskan perangkat dengan penglihatannya. Anda tidak dapat mengukur sudut pod optik secara langsung, jadi perhatikan hal ini saat menggunakan sudut dari sensor ini untuk aplikasi seperti arah kompas.

  • Untuk menghemat masa pakai baterai, hanya dengarkan sensor saat Anda membutuhkannya. Misalnya, jika Glassware menggunakan Service untuk merender LiveCard dan Anda hanya memerlukan sensor saat kartu aktif terlihat, gunakan metode callback platform LiveCard untuk mulai dan berhenti memproses sensor.

  • Callback peristiwa sensor berjalan pada UI thread, jadi proses peristiwa dan kembalikan secepat mungkin. Pertimbangkan untuk mengirim peristiwa sensor ke antrean dan menggunakan thread latar belakang untuk menanganinya jika pemrosesan Anda terlalu lama.

  • 50 Hz sering kali merupakan frekuensi sampling yang cukup untuk melacak gerakan kepala.

Untuk mengetahui informasi selengkapnya tentang cara menggunakan sensor, lihat panduan developer Android.