הגישה לנתוני המיקום והחיישנים מתבצעת באמצעות מכשיר Android הרגיל ממשקי API של הפלטפורמה.
מיקום
המיקום ב-Glass כולל שימוש במכשיר Android הרגיל ממשקי API של הפלטפורמה לקבלת נתוני מיקום זמינים ספקי מיקום.
כדי לקבל נתוני מיקום, תשתמשו במחלקות הבאות של Android SDK:
LocationManager
– מספק גישה לשירות מערכת המיקום של Android שמטפל בתקשורת עםLocationProvider
LocationProvider
– מספקת נתוני מיקום על סמך קריטריונים מסוימים. Glass מספקים "שלט רחוק" מיוחד ספקים שמאפשרים לקבל נתוני מיקום ממכשיר מותאם עם MyGlass אפליקציה נלווית מותקנת.Criteria
– מאפשרת לכם ליצור קבוצה של קריטריונים בוחר אתLocationProvider
הטוב ביותר על סמך הקריטריונים שאתם מגדירים.
סקירה כללית
כדי לקבל נתוני מיקום, צריך להשתמש
LocationManager
כדי לקבל נתונים מספק מיקום אחד או יותר.
אפליקציות בטלפון או בטאבלט Android מאחזרות נתוני מיקום ספקי מיקום של רשתות ו-GPS במכשיר. ב-Glass, הקבוצה של ספקי המיקום הזמינים היא דינמית ויכולה לכלול מרחוק ספקי מיקום שמספקים נתוני מיקום ממקור אחר, כמו מכשיר המותאם Bluetooth עם האפליקציה הנלווית של MyGlass. כדי לטפל ב: ספקים נוספים אלה, מקשיבים לעדכוני מיקום ספקים ולא ספק אחד.
כדי לבקש נתונים מכל ספקי המיקום הזמינים:
- יצירת
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 כדי להשבית או
שירותי רקע של ויסות נתונים (throttle). קודם כל, צריך להטמיע
BroadcastReceiver
לזהות
ACTION_ON_HEAD_STATE_CHANGE
אירועים.
בדוגמה הבאה לעיכובים ולהשבתה של עדכוני תוצאות המשחקים, המשתמש הסיר את Glass מהראש שלו:
- ליישם
BroadcastReceiver
לטפל בשינוי המצב. - בשירות שלכם, מטמיעים את
onCreate()
ורושמים מקלט שמאזין IntentACTION_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, שמשתמשים מסובבים כדי ליישר את המכשיר ביחס למראה שלהם. אי אפשר למדוד את הזווית הישירה של רצף האופטיקה, לכן חשוב לשים לב לכך באמצעות זוויות מהחיישנים האלה לאפליקציות כמו כיוון מצפן.
כדי להאריך את חיי הסוללה, חשוב להאזין לחיישנים רק כשיש לך צורך בהם. לדוגמה, אם משתמש ב-
Service
כדי לעבדLiveCard
וצריך את החיישנים רק כשהכרטיס הפעיל גלוי, משתמשיםLiveCard
הצגת שיטות קריאה חוזרת (callback) כדי להתחיל ולהפסיק להאזין לחיישנים.קריאות חוזרות (callbacks) של אירועים מהחיישן פועלות בשרשור של ממשק המשתמש, לכן המערכת מעבדת את האירועים וחוזרת בתור במהירות האפשרית. כדאי להעביר אירועי חיישנים לתור ולהשתמש בשרשור ברקע לטפל בהן אם העיבוד נמשך יותר מדי זמן.
תדירות דגימה של 50 Hz לעיתים קרובות מספיקה למעקב אחרי תנועת הראש.
לקבלת מידע נוסף על אופן השימוש בחיישנים, אפשר לעיין במאמר המדריך למפתחי Android.