Vị trí và cảm biến

Bạn truy cập vào dữ liệu vị trí và cảm biến bằng ứng dụng Android tiêu chuẩn các API nền tảng.

Vị trí

Vị trí trên Glass liên quan đến việc sử dụng phiên bản Android API Platform để lấy dữ liệu vị trí trình cung cấp vị trí.

Bạn sẽ sử dụng các lớp SDK Android sau để lấy dữ liệu vị trí:

  • LocationManager – Cấp quyền truy cập vào dịch vụ hệ thống vị trí của Android xử lý giao tiếp với LocationProvider.

  • LocationProvider – Cung cấp dữ liệu vị trí dựa trên một số tiêu chí. Glass cung cấp "điều khiển từ xa" đặc biệt các nhà cung cấp cho phép bạn lấy dữ liệu vị trí từ một thiết bị được ghép nối có MyGlass ứng dụng đồng hành.

  • Criteria – Cho phép bạn tạo một bộ tiêu chí chọn LocationProvider phù hợp nhất dựa trên các tiêu chí mà bạn đặt ra.

Tổng quan

Để có được dữ liệu vị trí, bạn cần sử dụng LocationManager để nhận dữ liệu từ một hoặc nhiều nhà cung cấp vị trí.

Các ứng dụng trên điện thoại hoặc máy tính bảng Android truy xuất dữ liệu vị trí từ thiết bị Nhà cung cấp vị trí mạng và GPS trên thiết bị. Tuy nhiên, trên Glass, Các nhà cung cấp vị trí hiện có có tính năng động và có thể bao gồm điều khiển từ xa nhà cung cấp vị trí cung cấp dữ liệu vị trí từ một nguồn khác, chẳng hạn như Thiết bị ghép nối Bluetooth đã cài đặt ứng dụng đồng hành MyGlass. Cần xử lý các nhà cung cấp khác này, hãy theo dõi thông tin cập nhật về vị trí từ nhiều nhà cung cấp thay vì một nhà cung cấp duy nhất.

Để yêu cầu dữ liệu từ tất cả các nhà cung cấp vị trí hiện có:

  1. Tạo một Criteria bằng các yêu cầu vị trí của bạn.
  2. Gọi getProviders() để truy xuất danh sách các nhà cung cấp được cho phép đáp ứng tiêu chí của bạn.
  3. Lặp lại danh sách các nhà cung cấp và yêu cầu cập nhật từ tất cả các nhà cung cấp đó. Việc này giúp đảm bảo rằng bạn nhận được thông tin cập nhật từ các nhà cung cấp từ xa nếu họ mà còn từ các nhà cung cấp địa phương trên Glass (chẳng hạn như nhà cung cấp dịch vụ mạng).
  4. Hãy sử dụng độ chính xác và thông tin về thời gian được cung cấp trong mỗi để xác định xem bản cập nhật đã đủ tốt hay chưa hoặc bạn nên cập nhật hãy đợi một lát nữa.

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

Cảm biến

Ly

Glass có cảm biến chuyên biệt để phát hiện xem thiết bị có đang ở trên của người dùng đầu. Khi được bật, chế độ cài đặt này sẽ giúp tiết kiệm pin khi thiết bị không được sử dụng. Bạn có thể sử dụng tính năng này trong Glassware để tắt hoặc điều tiết các dịch vụ nền. Hãy bắt đầu bằng cách triển khai một BroadcastReceiver để phát hiện ACTION_ON_HEAD_STATE_CHANGE sự kiện.

Ví dụ sau đây trì hoãn và tắt tính năng cập nhật điểm số trò chơi dựa trên việc người dùng đã gỡ Glass ra khỏi đầu:

  1. Triển khai một BroadcastReceiver để xử lý thay đổi trạng thái.
  2. Trong dịch vụ của mình, hãy triển khai onCreate() và đăng ký trình nhận để lắng nghe Ý định của ACTION_ON_HEAD_STATE_CHANGE.
  3. Trong onDestroy() huỷ đăng ký trình nhận.

    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

Các cảm biến Android sau đây được hỗ trợ trên Glass:

Các cảm biến Android sau không được hỗ trợ:

Dưới đây là một số mẹo khi sử dụng các cảm biến trên Glass:

  • Hệ thống toạ độ của cảm biến Glass được hiển thị bên dưới so với màn hình Glass. Để biết thêm thông tin, hãy xem hệ thống toạ độ cảm biến.

  • Gia tốc kế, con quay hồi chuyển và từ kế được đặt trên nhóm quang học của thiết bị Glass, mà người dùng xoay để căn chỉnh thiết bị với tầm nhìn của họ. Bạn không thể đo lường góc của nhóm quang học, nên hãy lưu ý điều này khi sử dụng các góc từ các cảm biến này cho các ứng dụng như hướng la bàn.

  • Để duy trì thời lượng pin, hãy chỉ nghe cảm biến khi cần. Ví dụ: nếu Đồ thuỷ tinh của bạn sử dụng Service để kết xuất LiveCard và chỉ cần cảm biến khi thẻ trực tiếp hiển thị, hãy sử dụng LiveCard hiển thị các phương thức gọi lại để bắt đầu và dừng lắng nghe cảm biến.

  • Các lệnh gọi lại sự kiện cảm biến chạy trên luồng giao diện người dùng, vì vậy, hãy xử lý các sự kiện và trả về dưới dạng nhanh nhất có thể. Cân nhắc việc đẩy các sự kiện cảm biến vào hàng đợi và sử dụng luồng trong nền để xử lý chúng nếu việc xử lý của bạn mất quá nhiều thời gian.

  • 50 Hz thường là tốc độ lấy mẫu đủ để theo dõi chuyển động của đầu.

Để biết thêm thông tin về cách sử dụng cảm biến, hãy xem Hướng dẫn cho nhà phát triển Android.