ตำแหน่งและเซ็นเซอร์

คุณเข้าถึงข้อมูลตำแหน่งและเซ็นเซอร์โดยใช้ Android มาตรฐาน API ของแพลตฟอร์ม

ตำแหน่ง

ตำแหน่งใน Glass เกี่ยวข้องกับการใช้ Android มาตรฐาน API ของแพลตฟอร์มเพื่อรับข้อมูลตำแหน่งจาก ผู้ให้บริการตำแหน่ง

คุณจะใช้คลาส Android SDK ต่อไปนี้เพื่อรับข้อมูลตำแหน่ง

  • LocationManager ให้สิทธิ์เข้าถึงบริการตำแหน่งของ Android ที่จัดการการสื่อสารกับ LocationProvider

  • LocationProvider ให้ข้อมูลตำแหน่งตามเกณฑ์ Glass มี "รีโมต" พิเศษ ผู้ให้บริการ ที่ช่วยให้คุณรับข้อมูลตำแหน่งจากอุปกรณ์ที่จับคู่ไว้ซึ่งมี MyGlass ติดตั้งแอปที่ใช้ร่วมกันแล้ว

  • Criteria ให้คุณสร้างชุดเกณฑ์ที่ เลือก LocationProvider ที่ดีที่สุดตามเกณฑ์ที่คุณตั้งไว้

ภาพรวม

หากต้องการดูข้อมูลตำแหน่ง คุณจะต้องใช้ LocationManager เพื่อรับข้อมูลจากผู้ให้บริการตำแหน่งอย่างน้อย 1 ราย

แอปพลิเคชันบนโทรศัพท์หรือแท็บเล็ต 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 มีเซ็นเซอร์พิเศษในการตรวจจับว่าอุปกรณ์อยู่บน ผู้ใช้ ศีรษะ เมื่อเปิดใช้ การตั้งค่านี้จะช่วยประหยัดแบตเตอรี่เมื่ออุปกรณ์ ไม่มีการใช้งาน คุณสามารถใช้ฟีเจอร์นี้ใน Glassware เพื่อปิดใช้หรือ ควบคุมบริการที่ทำงานอยู่เบื้องหลัง เริ่มต้นด้วยการติดตั้งใช้งาน BroadcastReceiver เพื่อตรวจหา ACTION_ON_HEAD_STATE_CHANGE กิจกรรม

ตัวอย่างต่อไปนี้จะหน่วงเวลาและปิดใช้การอัปเดตคะแนนเกมโดยพิจารณาจาก ผู้ใช้ได้ถอด Glass ออกจากศีรษะ:

  1. ใช้ BroadcastReceiver ในการรับมือกับการเปลี่ยนแปลงสถานะ
  2. ในบริการของคุณ ให้ใช้ onCreate() และลงทะเบียนรีซีฟเวอร์ที่รอฟังฟังก์ชัน Intent ของ 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

เซ็นเซอร์ Android ต่อไปนี้ใช้ได้ใน Glass

ไม่รองรับเซ็นเซอร์ Android ต่อไปนี้

ต่อไปนี้คือเคล็ดลับบางประการเมื่อใช้เซ็นเซอร์ใน Glass

  • ระบบพิกัดเซ็นเซอร์ของ Glass แสดงอยู่ด้านล่างโดยสัมพันธ์กับจอแสดงผลของ Glass สำหรับข้อมูลเพิ่มเติม โปรดดู ระบบพิกัดเซ็นเซอร์

  • ตัวตรวจวัดความเร่ง เครื่องวัดการหมุน และเครื่องวัดค่าความเข้มข้นของสนามแม่เหล็กอยู่ที่พ็อดกล้องของอุปกรณ์ Glass ซึ่งจะหมุนอุปกรณ์ให้อยู่ในแนวเดียวกับสายตาของผู้ใช้ คุณไม่สามารถวัดค่า มุมของพ็อดกล้องโดยตรง จึงควรระวังเรื่องนี้เมื่อ โดยใช้มุมจากเซ็นเซอร์เหล่านี้สำหรับการใช้งาน เช่น ทิศทางของเข็มทิศ

  • โปรดฟังเซ็นเซอร์เมื่อจำเป็นเท่านั้นเพื่อยืดอายุการใช้งานแบตเตอรี่ ตัวอย่างเช่น ถ้ากลาสแวร์ของคุณ ใช้ Service เพื่อแสดงผล LiveCard และคุณต้องใช้เซ็นเซอร์เมื่อมองเห็นการ์ดถ่ายทอดสดเท่านั้น ให้ใช้ LiveCard จะแสดงเมธอด Callback เพื่อเริ่มและหยุดฟังเซ็นเซอร์

  • Callback ของเหตุการณ์เซ็นเซอร์จะทำงานในชุดข้อความ UI ดังนั้นให้ประมวลผลเหตุการณ์และแสดงผลเป็น โดยเร็วที่สุด ลองพุชเหตุการณ์เซ็นเซอร์เข้าไปในคิวและใช้ชุดข้อความเบื้องหลัง หากการประมวลผลของคุณใช้เวลานานเกินไป

  • 50 Hz มักเป็นอัตราการสุ่มตัวอย่างที่เพียงพอสำหรับการติดตามการเคลื่อนไหวของศีรษะ

ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้งานเซ็นเซอร์ได้ที่ คู่มือนักพัฒนาซอฟต์แวร์ Android