Вы получаете доступ к данным о местоположении и датчикам, используя стандартные API-интерфейсы платформы Android.
Расположение
Определение местоположения на Glass предполагает использование стандартных API-интерфейсов платформы Android для получения данных о местоположении от доступных провайдеров определения местоположения.
Вы будете использовать следующие классы Android SDK для получения данных о местоположении:
LocationManager
— предоставляет доступ к службе системы определения местоположения Android, которая обрабатывает связь сLocationProvider
.LocationProvider
— предоставляет данные о местоположении на основе некоторых критериев. Glass предоставляет специальных «удаленных» провайдеров, которые позволяют вам получать данные о местоположении с сопряженного устройства, на котором установлено сопутствующее приложение MyGlass.Criteria
— позволяет создать набор критериев для выбора наилучшегоLocationProvider
на основе заданных вами критериев.
Обзор
Чтобы получить данные о местоположении, вам потребуется использовать класс LocationManager
для получения данных от одного или нескольких поставщиков местоположений.
Приложения на телефоне или планшете Android получают данные о местоположении от местных поставщиков услуг GPS и сетевых местоположений на устройстве. Однако в Glass набор доступных провайдеров определения местоположения является динамическим и может включать поставщиков удаленных местоположений, которые предоставляют данные о местоположении из другого источника, например устройства, сопряженного по Bluetooth, с установленным сопутствующим приложением MyGlass. Чтобы справиться с этими дополнительными поставщиками, прослушивайте обновления местоположения от нескольких поставщиков , а не от одного поставщика.
Чтобы запросить данные у всех доступных провайдеров геолокации:
- Создайте объект
Criteria
с вашими требованиями к местоположению. - Вызовите
getProviders()
, чтобы получить список включенных поставщиков, которые удовлетворяют вашим критериям. - Просмотрите список поставщиков и запросите обновления у всех из них. Это гарантирует получение обновлений от удаленных поставщиков, если они доступны, а также от локальных поставщиков на Glass (например, поставщика беспроводной сети).
Используйте информацию о точности и сроках, предоставленную с каждым обновлением, чтобы определить, достаточно ли оно хорошее, или вам следует подождать другого.
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); }
Датчики
Стекло
В Glass есть специальный датчик, который определяет, находится ли устройство на голове пользователя. Если этот параметр включен, он помогает экономить заряд батареи, когда устройство не используется. Вы можете использовать эту функцию в Glassware для отключения или ограничения фоновых служб. Начните с реализации BroadcastReceiver
для обнаружения событий ACTION_ON_HEAD_STATE_CHANGE
.
Следующий пример задерживает и отключает обновление результатов игры в зависимости от того, снял ли пользователь Glass со своей головы:
- Реализуйте
BroadcastReceiver
для обработки изменения состояния. - В своей службе реализуйте метод
onCreate()
и зарегистрируйте получателя, который прослушивает намерениеACTION_ON_HEAD_STATE_CHANGE
. В методе
onDestroy()
отмените регистрацию получателя.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; } }
Андроид
На Glass поддерживаются следующие датчики Android:
-
TYPE_ACCELEROMETER
-
TYPE_GRAVITY
-
TYPE_GYROSCOPE
-
TYPE_LIGHT
-
TYPE_LINEAR_ACCELERATION
-
TYPE_MAGNETIC_FIELD
-
TYPE_ORIENTATION
(устарело) -
TYPE_ROTATION_VECTOR
Следующие датчики Android не поддерживаются:
Вот несколько советов по использованию сенсоров на стекле:
- Система координат датчика Glass показана ниже относительно дисплея Glass. Для получения дополнительной информации см. систему координат датчика .
Акселерометр, гироскоп и магнитометр расположены на оптической части устройства Glass, которую пользователи поворачивают, чтобы совместить устройство со своим прицелом. Вы не можете измерить угол модуля оптики напрямую, поэтому помните об этом при использовании углов от этих датчиков для таких приложений, как направление по компасу.
Чтобы продлить срок службы батареи, прислушивайтесь к датчикам только тогда, когда они вам нужны. Например, если ваше устройство Glassware использует
Service
для отображенияLiveCard
, и вам нужны датчики только тогда, когда отображается живая карта, используйте методы обратного вызова поверхностиLiveCard
, чтобы начать и прекратить прослушивание датчиков.Обратные вызовы событий датчиков выполняются в потоке пользовательского интерфейса, поэтому события обрабатываются и возвращаются как можно быстрее. Рассмотрите возможность помещения событий датчика в очередь и использования фонового потока для их обработки, если обработка занимает слишком много времени.
50 Гц часто является достаточной частотой дискретизации для отслеживания движения головы.
Дополнительные сведения об использовании датчиков см. в руководстве для разработчиков Android .