Lokasi dan Sensor

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

Lokasi

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

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

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

  • LocationProvider – Memberikan data lokasi berdasarkan beberapa kriteria. Glass menyediakan fitur "jarak jauh" khusus penyedia yang memungkinkan Anda mendapatkan data lokasi dari perangkat yang disambungkan yang memiliki MyGlass aplikasi pendamping yang terinstal.

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

Ringkasan

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

Aplikasi di ponsel atau tablet Android mengambil data lokasi dari data lokal Penyedia lokasi GPS dan jaringan di perangkat. Namun, di Glass, kumpulan penyedia lokasi yang tersedia bersifat dinamis dan mungkin menyertakan jarak jauh penyedia lokasi yang menyediakan data lokasi dari sumber lain, seperti Perangkat yang disambungkan dengan Bluetooth dan aplikasi pendamping MyGlass terinstal. Untuk ditangani penyedia tambahan ini, dengarkan pembaruan lokasi dari beberapa penyedia layanan, bukan satu penyedia.

Untuk meminta data dari semua penyedia lokasi yang tersedia:

  1. Membuat Criteria dengan persyaratan lokasi Anda.
  2. Panggil getProviders() untuk mengambil daftar penyedia aktif yang memenuhi kriteria Anda.
  3. Lakukan iterasi pada daftar penyedia dan minta pembaruan dari mereka semua. Hal ini memastikan bahwa Anda menerima pembaruan dari penyedia jarak jauh jika mereka tersedia, tetapi juga dari penyedia lokal di Glass (seperti penyedia jaringan).
  4. Gunakan informasi akurasi dan pengaturan waktu yang disediakan untuk masing-masing Lakukan update untuk menentukan apakah update tersebut cukup bagus atau Anda harus melakukannya tunggu yang lain.

    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 sedang berada di pengguna kepala Anda. Jika diaktifkan, setelan ini akan membantu menghemat baterai saat perangkat sedang tidak digunakan. Anda dapat menggunakan fitur ini di Glassware untuk menonaktifkan atau membatasi layanan latar belakang. Mulailah dengan menerapkan BroadcastReceiver untuk dideteksi ACTION_ON_HEAD_STATE_CHANGE peristiwa.

Contoh berikut menunda dan menonaktifkan pembaruan skor game berdasarkan apakah pengguna telah melepas Glass dari kepalanya:

  1. Mengimplementasikan BroadcastReceiver untuk menangani perubahan status.
  2. Di layanan Anda, implementasikan onCreate() dan mendaftarkan penerima yang mendengarkan ACTION_ON_HEAD_STATE_CHANGE.
  3. Di kolom 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 sesuai dengan 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 penglihatan mereka. Anda tidak dapat mengukur sudut pod optik secara langsung, jadi perhatikan hal ini ketika menggunakan sudut dari sensor ini untuk aplikasi seperti arah kompas.

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

  • Callback peristiwa sensor berjalan pada UI thread, sehingga peristiwa proses dan kembali sebagai secepat mungkin. Pertimbangkan untuk mendorong peristiwa sensor ke dalam antrean dan menggunakan thread latar belakang untuk menanganinya jika pemrosesan memakan waktu terlalu lama.

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

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