Вы получаете доступ к данным о местоположении и датчикам, используя стандартные 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, который пользователи поворачивают, чтобы совместить устройство со своим зрением. Вы не можете измерить угол оптики напрямую, поэтому имейте это в виду при использовании углов от этих датчиков для таких приложений, как направление по компасу.
Чтобы продлить срок службы батареи, прислушивайтесь к сигналам датчиков только тогда, когда они вам нужны. Например, если ваша стеклянная посуда использует
Service
для отображенияLiveCard
, а датчики нужны только тогда, когда живая карта видна, используйте методы обратного вызова поверхностиLiveCard
, чтобы начать и прекратить прослушивание датчиков.Обратные вызовы событий датчиков выполняются в потоке пользовательского интерфейса, поэтому события обрабатываются и возвращаются как можно быстрее. Рассмотрите возможность помещения событий датчиков в очередь и использования фонового потока для их обработки, если обработка занимает слишком много времени.
Частоты 50 Гц часто бывает достаточной для отслеживания движения головы.
Дополнительную информацию о том, как использовать датчики, можно найти в руководстве для разработчиков Android .