위치 및 센서

표준 Android 플랫폼 API를 사용하여 위치 및 센서 데이터에 액세스합니다.

위치

Glass의 위치는 표준 Android 플랫폼 API를 사용하여 사용 가능한 위치 제공자로부터 위치 데이터를 가져옵니다.

다음 Android SDK 클래스를 사용하여 위치 데이터를 가져옵니다.

  • LocationManagerLocationProvider와의 통신을 처리하는 Android 위치 시스템 서비스에 대한 액세스를 제공합니다.

  • LocationProvider - 일부 기준에 따라 위치 데이터를 제공합니다. Glass는 MyGlass 호환 앱이 설치된 페어링된 기기에서 위치 데이터를 가져올 수 있는 특수한 '원격' 제공업체를 제공합니다.

  • Criteria – 설정한 기준에 따라 최상의 LocationProvider를 선택하는 일련의 기준을 만들 수 있습니다.

개요

위치 데이터를 가져오려면 LocationManager 클래스를 사용하여 하나 이상의 위치 제공업체로부터 데이터를 가져와야 합니다.

Android 휴대전화 또는 태블릿의 애플리케이션은 기기의 로컬 GPS 및 네트워크 위치 제공업체로부터 위치 데이터를 검색합니다. 그러나 Glass에서는 사용 가능한 위치 제공자 집합이 동적이며 MyGlass 호환 앱이 설치된 블루투스 페어링 기기와 같이 다른 소스의 위치 데이터를 제공하는 원격 위치 제공자가 포함될 수 있습니다. 이러한 추가 제공업체를 처리하려면 단일 제공업체가 아닌 여러 제공업체의 위치 업데이트를 수신 대기하세요.

사용 가능한 모든 위치 제공업체에 데이터를 요청하는 방법은 다음과 같습니다.

  1. 위치 요구사항을 사용하여 Criteria 객체를 만듭니다.
  2. getProviders()를 호출하여 기준을 충족하는 사용 설정된 제공업체 목록을 가져옵니다.
  3. 제공업체 목록을 반복하고 모든 제공업체에 업데이트를 요청합니다. 이렇게 하면 원격 제공자가 업데이트를 제공받을 수 있을 뿐만 아니라 Glass의 로컬 제공업체 (예: 무선 네트워크 제공업체)로부터 업데이트도 받을 수 있습니다.
  4. 각 업데이트와 함께 제공된 정확도 및 타이밍 정보를 사용하여 해당 업데이트가 적절한지 또는 다른 업데이트를 기다려야 하는지 확인합니다.

    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에는 기기가 사용자의 머리 위에 있는지 감지하기 위한 특수 센서가 있습니다. 이 설정을 사용하면 기기를 사용하지 않을 때 배터리를 절약하는 데 도움이 됩니다. Glass 소프트웨어에서 이 기능을 사용하여 백그라운드 서비스를 사용 중지하거나 제한할 수 있습니다. 먼저 BroadcastReceiver를 구현하여 ACTION_ON_HEAD_STATE_CHANGE 이벤트를 감지합니다.

다음 예에서는 사용자가 머리에서 Glass를 삭제했는지 여부에 따라 게임 점수 업데이트를 지연하고 사용 중지합니다.

  1. BroadcastReceiver를 구현하여 상태 변경을 처리합니다.
  2. 서비스에서 onCreate() 메서드를 구현하고 ACTION_ON_HEAD_STATE_CHANGE 인텐트를 수신 대기하는 수신기를 등록합니다.
  3. 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;
        }
    }
    

Android

Glass에서는 다음과 같은 Android 센서가 지원됩니다.

다음 Android 센서는 지원되지 않습니다.

다음은 Glass에서 센서를 사용할 때 유용한 도움말입니다.

  • Glass 센서 좌표계는 Glass 디스플레이를 기준으로 아래에 표시됩니다. 자세한 내용은 센서 좌표계를 참고하세요.

  • 가속도계, 자이로스코프, 자기계는 사용자가 기기에 맞게 기기를 회전하도록 Glass 기기의 광학 포드에 있습니다. 광학 포드의 각도를 직접 측정할 수는 없으므로 나침반 방향과 같은 애플리케이션에서 이러한 센서의 각도를 사용할 때는 이 점에 유의하세요.

  • 배터리 수명을 절약하려면 필요할 때만 센서를 청취하세요. 예를 들어 Glass 소프트웨어가 Service를 사용하여 LiveCard를 렌더링하고 실시간 카드가 표시될 때만 센서가 필요한 경우 LiveCard 표면 콜백 메서드를 사용하여 센서 수신을 시작하고 중지합니다.

  • 센서 이벤트 콜백은 UI 스레드에서 실행되므로 이벤트를 처리하고 최대한 빨리 반환합니다. 처리 시간이 너무 오래 걸리면 센서 이벤트를 큐로 푸시하고 백그라운드 스레드를 사용하여 처리하는 것이 좋습니다.

  • 일반적으로 50Hz는 머리 움직임을 추적하는 데 충분한 샘플링 레이트입니다.

센서 사용 방법에 관한 자세한 내용은 Android 개발자 가이드를 참고하세요.