المواقع الجغرافية وأجهزة الاستشعار

يمكنك الوصول إلى بيانات الموقع وجهاز الاستشعار باستخدام نظام Android العادي للمنصة.

الموقع الجغرافي

يتضمن تحديد الموقع على Glass استخدام نظام التشغيل Android القياسي واجهات برمجة التطبيقات (API) لنظام التشغيل للحصول على بيانات الموقع من المتوفرة مقدمو خدمات المواقع الجغرافية.

ستستخدم فئات حزمة تطوير البرامج (SDK) التالية لنظام التشغيل Android للحصول على بيانات الموقع الجغرافي:

  • LocationManager – تتيح الوصول إلى خدمة نظام الموقع الجغرافي على Android. تتعامل مع التواصل مع LocationProvider

  • LocationProvider – تقدم بيانات الموقع الجغرافي استنادًا إلى بعض المعايير. يوفر Glass ميزة "عن بُعد" خاصة مقدّمو خدمة التي تتيح لك الحصول على بيانات الموقع من جهاز مقترن يحتوي على عدسة MyGlass تطبيق مصاحب مثبت.

  • Criteria – تتيح لك إنشاء مجموعة من المعايير التي يختار أفضل LocationProvider استنادًا إلى المعايير التي تحدّدها.

نظرة عامة

للحصول على بيانات الموقع، ستحتاج إلى استخدام LocationManager للحصول على بيانات من موفر موقع واحد أو أكثر.

تسترد التطبيقات على هاتف Android أو جهاز 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() وتسجيل جهاز استقبال يستمع إلى 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، الذي يقوم المستخدمون بتدويره لمحاذاة الجهاز مع بصرهم. ولا يمكنك قياس زاوية المجموعة البصرية مباشرة، لذا كن على دراية بذلك استخدام زوايا من أدوات الاستشعار هذه في تطبيقات مثل رأس البوصلة.

  • للحفاظ على عمر البطارية، يجب الاستماع إلى أجهزة الاستشعار عند الحاجة فقط. على سبيل المثال، إذا كان Glassware تستخدم Service لعرض LiveCard وتحتاج فقط إلى أجهزة الاستشعار عندما تكون البطاقة المباشرة مرئية، فاستخدم يعرض LiveCard طرق معاودة الاتصال لبدء الاستماع إلى أدوات الاستشعار وإيقافها.

  • يتم تشغيل استدعاءات حدث جهاز الاستشعار في سلسلة واجهة المستخدم، لذا يجب معالجة الأحداث والعودة بأسرع وقت ممكن. ننصحك بإرسال أحداث أداة الاستشعار إلى قائمة انتظار واستخدام سلسلة محادثات في الخلفية. لمعالجتها إذا استغرقت عملية المعالجة وقتًا طويلاً جدًا

  • غالبًا ما يكون 50 هرتز معدل عينات كافيًا لتتبع حركة الرأس.

لمزيد من المعلومات حول كيفية استخدام أدوات الاستشعار، يمكنك مراجعة دليل مطوّري برامج Android