يمكنك الوصول إلى بيانات الموقع الجغرافي وجهاز الاستشعار باستخدام واجهات برمجة التطبيقات العادية لنظام التشغيل Android الأساسي.
الموقع الجغرافي
يتضمن الموقع على Glass استخدام واجهات برمجة تطبيقات نظام Android الأساسي القياسية للحصول على بيانات الموقع من موردي المواقع المتوفرين.
ستستخدم فئات Android SDK التالية للحصول على بيانات الموقع:
LocationManager
– يوفر هذا الإعداد إمكانية الوصول إلى خدمة نظام الموقع الجغرافي لنظام التشغيل Android التي تعالج الاتصال بـLocationProvider
.LocationProvider
– تقدم بيانات الموقع بناءً على بعض المعايير. يوفر تطبيق Glass مزودي خدمة "بعيد" خاصين يتيحون لك الحصول على بيانات الموقع من جهاز مقترن تم تثبيت تطبيق MyGlass المصاحب عليه.Criteria
– تتيح لك هذه الميزة إنشاء مجموعة من المعايير التي تختار أفضلLocationProvider
بناءً على المعايير التي تحدّدها.
نظرة عامة
للحصول على بيانات الموقع الجغرافي، ستحتاج إلى استخدام فئة
LocationManager
للحصول على بيانات من موفّر موقع جغرافي واحد أو أكثر.
تسترد التطبيقات على هاتف أو جهاز لوحي يعمل بنظام التشغيل Android بيانات الموقع الجغرافي من نظام تحديد المواقع العالمي (GPS) ومقدمي خدمات الشبكة على الجهاز. ومع ذلك، في مجموعة Glass، تكون مجموعة موفري المواقع الجغرافية المتاحة ديناميكية، وقد تتضمن مقدمي خدمة الموقع عن بُعد الذين يقدمون بيانات الموقع من مصدر آخر، مثل جهاز تم إقرانه عبر بلوتوث مع تثبيت التطبيق المصاحب لنظاراتي. للتعامل مع مقدمي الخدمة الإضافيين هؤلاء، استمع إلى تحديثات الموقع من مقدمي الخدمة بدلاً من مزود واحد.
لطلب البيانات من جميع موفري المواقع المتاحة:
- أنشئ كائن
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()
وسجِّل جهاز استقبال يستمع إلى intent في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; } }
Android
تتوافق أجهزة استشعار Android التالية مع Glass:
TYPE_ACCELEROMETER
TYPE_GRAVITY
TYPE_GYROSCOPE
TYPE_LIGHT
TYPE_LINEAR_ACCELERATION
TYPE_MAGNETIC_FIELD
TYPE_ORIENTATION
(مهمل)TYPE_ROTATION_VECTOR
أجهزة استشعار Android التالية غير متوافقة:
إليك بعض النصائح عند استخدام أجهزة الاستشعار على Glass:
- يتم عرض نظام إحداثيات مستشعر Glass أدناه بالنسبة إلى شاشة عرض Glass. لمزيد من المعلومات، يمكنك الاطّلاع على نظام إحداثيات أجهزة الاستشعار.
يمكن العثور على مقياس التسارع والجيروسكوب ومقياس المغناطيسية في لوحة البصريات في جهاز Glass، والتي يتم تدويرها لمحاذاة الجهاز مع العين. لا يمكنك قياس زاوية لوحة اللوحات البصرية مباشرة، لذا يجب الانتباه لذلك عند استخدام الزوايا من أجهزة الاستشعار هذه لتطبيقات مثل عنوان البوصلة.
للحفاظ على عمر البطارية، استمع إلى أجهزة الاستشعار عند الحاجة إليها فقط. على سبيل المثال، إذا كانت Glassware تستخدم
Service
لعرضLiveCard
وكنت لا تحتاج إلى أجهزة الاستشعار إلا عندما تكون البطاقة المباشرة مرئية، استخدِم طرق معاودة الاتصال على سطحLiveCard
لبدء الاستماع إلى أجهزة الاستشعار وإيقافها.تعمل استدعاءات أحداث أداة الاستشعار على سلسلة واجهة المستخدم، لذا يمكنك معالجة الأحداث والرجوع إليها في أسرع وقت ممكن. يمكنك إرسال أحداث المستشعر إلى قائمة الانتظار واستخدام سلسلة محادثات للتعامل معها إذا استغرقت المعالجة وقتًا طويلاً.
غالبًا ما يكون معدل العينات 50 هرتز كافيًا لتتبع حركة الرأس.
لمزيد من المعلومات حول كيفية استخدام أجهزة الاستشعار، يمكنك الاطّلاع على دليل مطوّري برامج Android.