ממשקי API של Android 4.4

רמת ה-API: 19

Android 4.4‏ (KITKAT) היא גרסה חדשה של פלטפורמת Android שמציעה תכונות חדשות למשתמשים ולמפתחי אפליקציות. במסמך הזה נספק מבוא לממשקי ה-API החדשים הבולטים ביותר.

מפתחי אפליקציות צריכים להוריד את קובץ האימג' של מערכת Android 4.4 ואת פלטפורמת ה-SDK מ-SDK Manager בהקדם האפשרי. אם אין לכם מכשיר עם Android 4.4 שבו תוכלו לבדוק את האפליקציה, תוכלו להשתמש בתמונת המערכת של Android 4.4 כדי לבדוק את האפליקציה במכונה וירטואלית ל-Android. לאחר מכן, תוכלו לפתח את האפליקציות שלכם לפלטפורמת Android 4.4 כדי להתחיל להשתמש בממשקי ה-API העדכניים ביותר.

עדכון רמת ה-API לטירגוט

כדי לבצע אופטימיזציה טובה יותר של האפליקציה למכשירים עם Android 4.4, צריך להגדיר את targetSdkVersion לערך "19", להתקין אותה בתמונת מערכת של Android 4.4, לבדוק אותה ולפרסם עדכון עם השינוי הזה.

כדי להשתמש בממשקי API ב-Android 4.4 תוך תמיכה בגרסאות ישנות יותר, אפשר להוסיף לקוד תנאים שבודקים את רמת ה-API של המערכת לפני שמפעילים ממשקי API שלא נתמכים ב-minSdkVersion. מידע נוסף על שמירה על תאימות לאחור זמין במאמר תמיכה בגרסאות שונות של פלטפורמות.

מידע נוסף על אופן הפעולה של רמות API זמין במאמר מהי רמת API?

שינויים חשובים בהתנהגות

אם כבר פרסמתם אפליקציה ל-Android, חשוב לדעת שהאפליקציה שלכם עשויה להיות מושפעת משינויים ב-Android 4.4.

אם האפליקציה קוראת מהתקן אחסון חיצוני...

האפליקציה לא יכולה לקרוא קבצים משותפים באחסון החיצוני כשהיא פועלת ב-Android 4.4, אלא אם יש לה את ההרשאה READ_EXTERNAL_STORAGE. כלומר, לא ניתן לגשת יותר לקבצים בספרייה שמוחזרת על ידי getExternalStoragePublicDirectory() בלי ההרשאה. עם זאת, אם אתם צריכים לגשת רק לספריות הספציפיות לאפליקציה שלכם, שסופקו על ידי getExternalFilesDir(), אין צורך בהרשאה READ_EXTERNAL_STORAGE.

אם האפליקציה שלכם משתמשת ב-WebView...

יכול להיות שהאפליקציה תתנהג בצורה שונה כשהיא פועלת ב-Android 4.4, במיוחד אם מעדכנים את targetSdkVersion של האפליקציה ל-'19' ואילך.

הקוד שמבוסס על הכיתה WebView ועל ממשקי ה-API הקשורים שודרג כך שיהיה מבוסס על קובץ snapshot מודרני של קוד המקור של Chromium. בעקבות השדרוג, יש מגוון שיפורים בביצועים, תמיכה בתכונות HTML5 חדשות ותמיכה בניפוי באגים מרחוק של תוכן WebView. היקף השדרוג הזה אומר שאם האפליקציה שלכם משתמשת ב-WebView, יכול להיות שההתנהגות שלה תושפע במקרים מסוימים. אמנם שינויים ידועים בהתנהגות מתועדים, ובדרך כלל הם משפיעים על האפליקציה רק כשמעדכנים את targetSdkVersion של האפליקציה ל-'19' ואילך – WebView החדש פועל ב'מצב תכונות ייחודיות' כדי לספק פונקציונליות מסוימת מדור קודם באפליקציות שמטרגטות רמת API 18 ומטה – אבל יכול להיות שהאפליקציה שלכם תלויה בהתנהגויות לא ידועות מהגרסה הקודמת של WebView.

לכן, אם האפליקציה הקיימת שלכם משתמשת ב-WebView, חשוב לבדוק אותה ב-Android 4.4 בהקדם האפשרי ולעיין במאמר מעבר ל-WebView ב-Android 4.4 כדי לקבל מידע על האופן שבו האפליקציה עשויה להיות מושפעת מהעדכון של targetSdkVersion ל-'19' ואילך.

אם האפליקציה שלכם משתמשת ב-AlarmManager…

אם תגדירו את targetSdkVersion של האפליקציה ל-'19' או יותר, ההתראות שתיצרו באמצעות set() או setRepeating() לא יהיו מדויקות.

כדי לשפר את יעילות השימוש באנרגיה, מערכת Android משלבת עכשיו התראות מכל האפליקציות שמתרחשות בזמנים דומים למדי, כך שהמערכת מעירת את המכשיר פעם אחת במקום כמה פעמים כדי לטפל בכל התראה.

אם השעון המעורר לא משויך לשעה מדויקת, אבל עדיין חשוב שהשעון המעורר יופעל במהלך טווח זמן ספציפי (למשל, בין השעות 14:00 ל-16:00), אפשר להשתמש בשיטה החדשה setWindow(), שמקבלת שעה 'מוקדמת' לשעון המעורר ו'חלון' זמן אחרי השעה המוקדמת ביותר שבה המערכת צריכה להפעיל את השעון המעורר.

אם צריך להצמיד את ההתראה לשעה מדויקת בשעון (למשל, לתזכורת לאירוע ביומן), אפשר להשתמש בשיטה החדשה setExact().

ההתנהגות הלא מדויקת של הקיבוץ חלה רק על אפליקציות מעודכנות. אם הגדרתם את targetSdkVersion ל-'18' או לערכים נמוכים יותר, ההתראות ימשיכו לפעול כמו בגרסאות קודמות כשהן פועלות ב-Android 4.4.

אם האפליקציה מסנכרנת נתונים באמצעות ContentResolver…

כשמגדירים את targetSdkVersion של האפליקציה ל-'19' או יותר, יצירת סנכרון עם addPeriodicSync() תבצע את פעולות הסנכרון במרווח זמן גמיש שמוגדר כברירת מחדל, של כ-4% מהתקופה שציינתם. לדוגמה, אם תדירות הסקר היא 24 שעות, פעולת הסנכרון עשויה להתרחש בחלון זמן של שעה בערך בכל יום, במקום באותה שעה בדיוק בכל יום.

כדי לציין מרווח זמן גמיש משלכם לפעולות סנכרון, כדאי להתחיל להשתמש בשיטה החדשה requestSync(). פרטים נוספים זמינים בקטע מתאמי סנכרון שבהמשך.

ההתנהגות הזו של מרווח הזמן הגמיש חלה רק על אפליקציות מעודכנות. אם הגדרתם את targetSdkVersion ל-'18' או לערכים נמוכים יותר, בקשות הסנכרון הקיימות ימשיכו לפעול כמו בגרסאות קודמות כשהן יפעלו ב-Android 4.4.

מסגרת הדפסה

מעכשיו, Android כולל מסגרת מלאה שמאפשרת למשתמשים להדפיס כל מסמך באמצעות מדפסת שמחוברת באמצעות Wi-Fi, ‏ Bluetooth או שירותים אחרים. המערכת מטפלת בעסקה בין אפליקציה שרוצה להדפיס מסמך לבין השירותים שמעבירים את משימות ההדפסה למדפסת. המסגרת android.print מספקת את כל ממשקי ה-API הנדרשים כדי לציין מסמך להדפסה ולשלוח אותו למערכת להדפסה. ממשקי ה-API הנדרשים בפועל למשימה הדפסה מסוימת תלויים בתוכן שלכם.

הדפסת תוכן כללי

אם רוצים להדפיס תוכן מממשק המשתמש כמסמך, צריך קודם ליצור קבוצת משנה של PrintDocumentAdapter. בכיתה הזו צריך להטמיע כמה שיטות קריאה חוזרת (callback), כולל onLayout() כדי להגדיר את הפריסה על סמך מאפייני ההדפסה שסופקו, ו-onWrite() כדי לסדר את התוכן שאפשר להדפיס ב-ParcelFileDescriptor.

כדי לכתוב את התוכן ב-ParcelFileDescriptor, צריך להעביר לו קובץ PDF. ממשקי ה-API החדשים של PdfDocument מספקים דרך נוחה לעשות זאת, על ידי מתן Canvas מ-getCanvas(), שבו אפשר לצייר את התוכן שרוצים להדפיס. לאחר מכן כותבים את PdfDocument ב-ParcelFileDescriptor באמצעות השיטה writeTo().

אחרי שמגדירים את ההטמעה של PrintDocumentAdapter, אפשר להריץ משימות הדפסה לפי בקשת המשתמש באמצעות השיטה PrintManager, print(), שמקבלת את PrintDocumentAdapter כאחד מהארגומנטים שלה.

הדפסת תמונות

אם רוצים להדפיס רק תמונה או קובץ BMP אחר, ממשקי ה-API העוזרים בספריית התמיכה יבצעו את כל העבודה. פשוט יוצרים מכונה חדשה של PrintHelper, מגדירים את מצב התאמת העומס באמצעות setScaleMode() ומעבירים את Bitmap אל printBitmap(). זה הכל. הספרייה מטפלת בכל שאר האינטראקציות עם המערכת כדי להעביר את קובץ ה-bitmap למדפסת.

פיתוח שירותי הדפסה

יצרני ציוד מקורי (OEM) של מדפסות יכולים להשתמש במסגרת android.printservice כדי לספק יכולת פעולה הדדית עם המדפסות שלהם ממכשירי Android. אתם יכולים ליצור ולהפיץ שירותי הדפסה כחבילות APK, שהמשתמשים יכולים להתקין במכשירים שלהם . אפליקציית שירותי הדפסה פועלת בעיקר כשירות ללא ממשק גרפי (headless) על ידי יצירת תת-סוג של הכיתה PrintService, שמקבלת משימות הדפסה מהמערכת ומעבירה את המשימות למדפסות שלה באמצעות הפרוטוקולים המתאימים.

מידע נוסף על הדפסת תוכן האפליקציה זמין במאמר הדפסת תוכן.

ספק SMS

ספק התוכן Telephony ('ספק ה-SMS') מאפשר לאפליקציות לקרוא ולכתוב הודעות SMS ו-MMS במכשיר. הוא כולל טבלאות של הודעות SMS ו-MMS שהתקבלו, שנוסחו, שנשלחו, בהמתנה ועוד.

החל מגרסה 4.4 של Android, הגדרות המערכת מאפשרות למשתמשים לבחור 'אפליקציית SMS שמוגדרת כברירת מחדל'. אחרי הבחירה, רק אפליקציית ברירת המחדל להודעות SMS יכולה לכתוב לספק ה-SMS, ורק אפליקציית ברירת המחדל להודעות SMS מקבלת את השידור SMS_DELIVER_ACTION כשהמשתמש מקבל הודעת SMS, או את השידור WAP_PUSH_DELIVER_ACTION כשהמשתמש מקבל הודעת MMS. אפליקציית ה-SMS שמוגדרת כברירת מחדל אחראית לכתוב פרטים לספק ה-SMS כשהיא מקבלת או שולחת הודעה חדשה.

אפליקציות אחרות שלא נבחרו כאפליקציית ברירת המחדל ל-SMS יכולות לקרוא רק את ספק ה-SMS, אבל הן יכולות גם לקבל התראה כשמתקבלת הודעת SMS חדשה על ידי האזנה לשידור SMS_RECEIVED_ACTION. זהו שידור שלא ניתן לבטל, שיכול להישלח לכמה אפליקציות. השידור הזה מיועד לאפליקציות שצריכות לקרוא הודעות נכנסות מיוחדות, גם אם הן לא נבחרו כאפליקציית ברירת המחדל ל-SMS, למשל כדי לבצע אימות של מספר טלפון.

מידע נוסף זמין בפוסט בבלוג הכנת אפליקציות ה-SMS ל-KitKat.

תקשורת אלחוטית וקישוריות

Host Card Emulation

אפליקציות ל-Android יכולות עכשיו לדמות כרטיסי NFC מסוג ISO14443-4‏ (ISO-DEP) שמשתמשים ב-APDU לצורך החלפת נתונים (כפי שמפורט ב-ISO7816-4). כך מכשיר עם תמיכה ב-NFC שפועל עם Android 4.4 יכול לדמות כמה כרטיסי NFC בו-זמנית, ומסוף תשלום NFC או קורא NFC אחר יכולים להתחיל עסקה עם כרטיס ה-NFC המתאים על סמך מזהה האפליקציה (AID).

אם רוצים לדמות באפליקציה כרטיס NFC שמשתמש בפרוטוקולים האלה, צריך ליצור רכיב שירות שמבוסס על הכיתה HostApduService. לעומת זאת, אם האפליקציה משתמשת ברכיב מאובטח לצורך אמולציה של כרטיס, צריך ליצור שירות שמבוסס על הכיתה OffHostApduService. השירות הזה לא יהיה מעורב ישירות בטרנזקציות, אבל הוא נדרש כדי לרשום את מזהי ה-AID שצריך לטפל בהם באמצעות הרכיב המאובטח.

מידע נוסף זמין במדריך הדמיית כרטיס NFC.

מצב קורא NFC

מצב חדש של קורא NFC מאפשר לפעילות להגביל את כל הפעילות ב-NFC לקריאה בלבד של סוגי התגים שבהם הפעילות מעוניינת בזמן שהיא בחזית. אפשר להפעיל את מצב הקראה בפעילות באמצעות enableReaderMode(), על ידי מתן הטמעה של NfcAdapter.ReaderCallback שמקבלת קריאה חוזרת כשמזוהים תגים חדשים.

היכולת החדשה הזו, בשילוב עם הדמיה של כרטיס מארח, מאפשרת ל-Android לפעול בשני הקצוות של ממשק תשלום בנייד: מכשיר אחד פועל כמסוף תשלום (מכשיר שפועלת בו פעילות במצב קורא) ומכשיר אחר פועל כלקוח תשלום (מכשיר שמבצע הדמיה של כרטיס NFC).

משדרי אינפרה-אדום

כשמפעילים את הקוד במכשיר שכולל משדר אינפרה-אדום (IR), עכשיו אפשר לשדר אותות IR באמצעות ממשקי ה-API של ConsumerIrManager. כדי לקבל מופע של ConsumerIrManager, קוראים ל-getSystemService() עם CONSUMER_IR_SERVICE כארגומנט. לאחר מכן אפשר להריץ שאילתה על תדרי ה-IR הנתמכים במכשיר באמצעות getCarrierFrequencies() ולהעביר אותות על ידי העברת התדירות ותבנית האות הרצויים באמצעות transmit().

תמיד צריך לבדוק קודם אם המכשיר כולל משדר אינפרה-אדום באמצעות קריאה ל-hasIrEmitter(), אבל אם האפליקציה תואמת רק למכשירים שיש בהם משדר כזה, צריך לכלול את האלמנט <uses-feature> במניפסט של "android.hardware.consumerir" (FEATURE_CONSUMER_IR).

מולטימדיה

הפעלה דינמית

תמיכה בהפעלת וידאו אדפטיבית זמינה עכשיו באמצעות ממשקי ה-API של MediaCodec, ומאפשרת שינוי חלק של הרזולוציה במהלך ההפעלה ב-Surface – אפשר להזין לקודק את מסגרות הקלט ברזולוציה חדשה, והרזולוציה של מאגרי הפלט משתנה ללא פער משמעותי.

כדי להפעיל הפעלה אדפטיבית, מוסיפים שני מפתחות ל-MediaFormat שמציינים את הרזולוציה המקסימלית שהאפליקציה דורשת מהקודק: KEY_MAX_WIDTH ו-KEY_MAX_HEIGHT. אחרי שמוסיפים את הפרטים האלה ל-MediaFormat, מעבירים את MediaFormat למכונה של MediaCodec באמצעות configure().

הקודק יעביר בצורה חלקה בין רזולוציות שזהות לערכים האלה או קטנות מהם. יכול להיות שהקודק תומך גם ברזולוציות גדולות יותר מהרזולוציות המקסימליות שצוינו (כל עוד הן נמצאות במגבלות של הפרופילים הנתמכים), אבל יכול להיות שהמעבר לרזולוציות גדולות יותר לא יהיה חלק.

כדי לשנות את הרזולוציה במהלך פענוח סרטון H.264, ממשיכים להוסיף פריימים לתור באמצעות MediaCodec.queueInputBuffer(), אבל חשוב לוודא שמספקים את הערכים החדשים של קבוצת הפרמטרים של הרצף (SPS) וקבוצת הפרמטרים של התמונה (PPS) יחד עם הפריים של רענון המפענח המיידי (IDR) במאגר יחיד.

עם זאת, לפני שמנסים להגדיר את הקודק להפעלה אדפטיבית, צריך לוודא שהמכשיר תומך בהפעלה אדפטיבית. לשם כך, קוראים ל-isFeatureSupported(String) עם FEATURE_AdaptivePlayback.

הערה: התמיכה בהפעלה אדפטיבית היא ספציפית לספק. יכול להיות שלחלק מהקודקים יידרשו יותר זיכרון כדי לשלוח רמזים לרזולוציות גדולות יותר. לכן, כדאי להגדיר את הרזולוציות המקסימליות על סמך חומר המקור שאתם מבצעים עליו פענוח.

חותמות זמן של אודיו על פי דרישה

כדי להקל על סנכרון הווידאו והאודיו, הכיתה החדשה AudioTimestamp מספקת פרטי ציר זמן לגבי 'פריים' ספציפי בשידור אודיו שמטופל על ידי AudioTrack. כדי לקבל את חותמת הזמן העדכנית ביותר שזמינה, יוצרים אובייקט AudioTimestamp ומעבירים אותו ל-getTimestamp(). אם הבקשה לחותמת הזמן תאושר, מופע AudioTrack יאוכלס במיקום ביחידות של פריימים, יחד עם השעה המשוערת שבה הפריים הוצג או התחייב להופיע.

אפשר להשתמש בערך של nanoTime ב-AudioTimestamp (שנמצא במגמת עלייה) כדי למצוא את פריים הווידאו המשויך הקרוב ביותר ל-framePosition, וכך להסיר, להכפיל או לבצע אינטרפולציה של פריטי וידאו כדי להתאים אותם לאודיו. לחלופין, אפשר לקבוע את זמן הדלתה בין הערך של nanoTime לבין הזמן הצפוי של פריים וידאו עתידי (תוך התחשבות בשיעור הדגימה) כדי לחזות איזה פריים אודיו צפוי באותו רגע שבו מופיע פריים וידאו.

קורא תמונות על משטחים

ממשק ה-API החדש של ImageReader מספק גישה ישירה למאגרי תמונות בזמן שהן עוברות עיבוד ל-Surface. אפשר לקבל ImageReader באמצעות השיטה הסטטית newInstance(). לאחר מכן, צריך לבצע קריאה ל-getSurface() כדי ליצור Surface חדש ולשלוח את נתוני התמונות באמצעות יוצר כמו MediaPlayer או MediaCodec. כדי לקבל התראות כשתמונות חדשות יהיו זמינות מהמשטח, צריך להטמיע את הממשק ImageReader.OnImageAvailableListener ולרשום אותו ב-setOnImageAvailableListener().

עכשיו, כשאתם מציירים תוכן ב-Surface, ה-ImageReader.OnImageAvailableListener מקבל קריאה ל-onImageAvailable() בכל פעם שמסגרת תמונה חדשה הופכת לזמינה, ומספק לכם את ה-ImageReader התואם. אפשר להשתמש ב-ImageReader כדי לקבל את נתוני התמונה של המסגרת כאובייקט Image, על ידי קריאה ל-acquireLatestImage() או ל-acquireNextImage().

האובייקט Image מספק גישה ישירה לחותמת הזמן, לפורמט, למימדים ולנתוני הפיקסלים של התמונה ב-ByteBuffer. עם זאת, כדי שאפשר יהיה לפרש את התמונות בכיתה Image, הפורמט שלהן צריך להתאים לאחד מהסוגים שמוגדרים על ידי קבועים ב-ImageFormat או ב-PixelFormat.

מדידה של שיא ו-RMS

עכשיו אפשר לשלוח שאילתות לגבי השיא וה-RMS של מקור האודיו הנוכחי מ-Visualizer על ידי יצירת מופע חדש של Visualizer.MeasurementPeakRms והעברתו אל getMeasurementPeakRms(). כשקוראים לשיטה הזו, ערכי השיא וה-RMS של Visualizer.MeasurementPeakRms הנתון מוגדרים לערכים שנמדדו לאחרונה.

הכלי לשיפור עוצמת הקול

LoudnessEnhancer הוא קבוצת משנה חדשה של AudioEffect שמאפשרת להגדיל את עוצמת הקול של MediaPlayer או AudioTrack. האפשרות הזו יכולה להיות שימושית במיוחד בשילוב עם השיטה החדשה getMeasurementPeakRms() שצוינה למעלה, כדי להגביר את עוצמת הקול של טראקים של אודיו דיבור בזמן שהמדיה האחרת פועלת.

שלטים רחוקים

ב-Android 4.0 (רמת API 14) הוצגו ממשקי ה-API של RemoteControlClient שמאפשרים לאפליקציות מדיה לצרוך אירועים של פקדי מדיה מלקוחות מרוחקים, כמו פקדי מדיה במסך הנעילה. עכשיו, ממשקי ה-API החדשים של RemoteController מאפשרים לכם ליצור שלט רחוק משלכם, וכך ליצור אפליקציות ופריטי חומרה חיצוניים חדשניים שיכולים לשלוט בהפעלה של כל אפליקציית מדיה שמשולבת עם RemoteControlClient.

כדי ליצור שלט רחוק, אפשר להטמיע את ממשק המשתמש בכל דרך שרוצים, אבל כדי להעביר את האירועים של לחצני המדיה לאפליקציית המדיה של המשתמש, צריך ליצור שירות שמרחיב את הכיתה NotificationListenerService ומטמיע את הממשק RemoteController.OnClientUpdateListener. חשוב להשתמש ב-NotificationListenerService כבסיס כי הוא מספק את הגבלות הפרטיות המתאימות, שמחייבות את המשתמשים להפעיל את האפליקציה שלכם כמאזין להתראות בהגדרות האבטחה של המערכת.

הכיתה NotificationListenerService כוללת כמה שיטות מופשטות שצריך להטמיע, אבל אם אתם מתעניינים רק באירועים של בקר המדיה לצורך טיפול בהפעלת המדיה, אתם יכולים להשאיר את ההטמעה שלהם ריקה ולהתמקד במקום זאת בשיטות של RemoteController.OnClientUpdateListener.

דירוגים משלטים רחוקים

ב-Android 4.4 נוספה יכולת חדשה ללקוחות של שלט רחוק (אפליקציות שמקבלות אירועי בקרת מדיה באמצעות RemoteControlClient), שמאפשרת למשתמשים לדרג את הטראק הנוכחי באמצעות השלט הרחוק.

הכיתה החדשה Rating מכילה מידע על דירוג של משתמש. דירוג מוגדר לפי סגנון הדירוג שלו (RATING_HEART, ‏ RATING_THUMB_UP_DOWN, ‏ RATING_3_STARS, ‏ RATING_4_STARS, ‏ RATING_5_STARS או RATING_PERCENTAGE) וערך הדירוג שמתאים לסגנון הזה.

כדי לאפשר למשתמשים לדרג את הטראקים שלכם באמצעות שלט רחוק:

כדי לקבל קריאה חוזרת כשהמשתמש משנה את הדירוג באמצעות השלט הרחוק, מטמיעים את הממשק החדש RemoteControlClient.OnMetadataUpdateListener ומעבירים מופע ל-setMetadataUpdateListener(). כשהמשתמש משנה את הדירוג, ה-RemoteControlClient.OnMetadataUpdateListener מקבל קריאה ל-onMetadataUpdate(), ומעביר את RATING_KEY_BY_USER כמפתח ואובייקט Rating כערך.

כתוביות

VideoView תומך עכשיו בטראקים של כתוביות WebVTT כשמפעילים סרטונים ב-HTTP Live Stream ‏ (HLS). הטראק של הכתוביות מוצג בהתאם להעדפות של הכתוביות שהמשתמש הגדיר בהגדרות המערכת.

אפשר גם לספק ל-VideoView את הטראקים של כתוביות ה-WebVTT באמצעות השיטה addSubtitleSource(). השיטה הזו מקבלת אובייקט InputStream שנושא את נתוני הכתוביות ואובייקט MediaFormat שמציין את הפורמט של נתוני הכתוביות. אפשר לציין את הפורמט באמצעות createSubtitleFormat(). הכתוביות האלה מופיעות גם מעל הסרטון בהתאם להעדפות המשתמש.

אם אתם לא משתמשים ב-VideoView כדי להציג את תוכן הסרטון, כדאי שהשכבה של הכתוביות תתאים ככל האפשר להעדפות של המשתמש לגבי כתוביות. ממשק API חדש של CaptioningManager מאפשר להריץ שאילתות לגבי העדפות המשתמש בנושא כתוביות, כולל סגנונות שהוגדרו על ידי CaptioningManager.CaptionStyle, כמו משפחת גופנים וצבע. אם המשתמש משנה כמה העדפות אחרי שהסרטון כבר התחיל, צריך להאזין לשינויים בהעדפות על ידי רישום מופע של CaptioningManager.CaptioningChangeListener כדי לקבל קריאה חוזרת כשאחת מההעדפות משתנה, ואז לעדכן את הכתוביות לפי הצורך.

אנימציה וגרפיקה

סצנות ומעברים

המסגרת החדשה android.transition מספקת ממשקי API שמאפשרים להציג אנימציות בין מצבים שונים של ממשק המשתמש. אחת מהתכונות העיקריות היא היכולת להגדיר מצבים נפרדים של ממשק המשתמש, שנקראים 'סצנות', על ידי יצירת פריסה נפרדת לכל אחת מהן. כשרוצים להוסיף אנימציה מסצנה אחת לסצנה אחרת, מבצעים 'מעבר', שמחשב את האנימציה הנדרשת כדי לשנות את הפריסה מהסצנה הנוכחית לסצנה הבאה.

כדי לעבור בין שתי סצנות, בדרך כלל צריך לבצע את הפעולות הבאות:

  1. מציינים את ה-ViewGroup שמכיל את רכיבי ממשק המשתמש שרוצים לשנות.
  2. מציינים את הפריסה שמייצגת את התוצאה הסופית של השינוי (הסצנה הבאה).
  3. מציינים את סוג המעבר שצריך להציג אנימציה של שינוי הפריסה.
  4. מפעילים את המעבר.

אפשר להשתמש באובייקט Scene כדי לבצע את שלבים 1 ו-2. ה-Scene מכיל מטא-נתונים שמתארים את המאפיינים של פריסה שנדרשים לביצוע מעבר, כולל תצוגת ההורה של הסצנה והפריסה של הסצנה. אפשר ליצור Scene באמצעות מגדיר הכיתה או באמצעות השיטה הסטטית getSceneForLayout().

לאחר מכן, צריך להשתמש ב-TransitionManager כדי לבצע את השלבים 3 ו-4. אחת הדרכים היא להעביר את Scene ל-method הסטטי go(). הפונקציה מאתרת את תצוגת ההורה של הסצנה בפריסה הנוכחית ומבצעת מעבר בתצוגות הצאצא כדי להגיע לפריסה שמוגדרת על ידי Scene.

לחלופין, אין צורך ליצור אובייקט Scene בכלל, אלא אפשר להפעיל את beginDelayedTransition() ולציין ViewGroup שמכיל את התצוגות שרוצים לשנות. לאחר מכן מוסיפים, מסירים או מגדירים מחדש את תצוגות היעד. אחרי שהמערכת תציג את השינויים לפי הצורך, תתחיל תנועה של כל התצוגות שהושפעו מהמעבר.

כדי לשלוט טוב יותר, אפשר להגדיר קבוצות של מעברים שצריכים להתרחש בין סצנות שהוגדרו מראש, באמצעות קובץ XML בספרייה res/transition/ של הפרויקט. בתוך רכיב <transitionManager>, מציינים תג <transition> אחד או יותר, שבו מצוין כל אחד מהם סצנה (הפניה לקובץ פריסה) והמעבר שיחולו כשנכנסים לסצנה הזו ו/או יוצאים ממנה. לאחר מכן, מנפחים את קבוצת המעברים הזו באמצעות inflateTransitionManager(). משתמשים ב-TransitionManager שהוחזר כדי לבצע כל מעבר באמצעות transitionTo(), ומעבירים Scene שמיוצג על ידי אחד מהתגים <transition>. אפשר גם להגדיר קבוצות של מעברים באופן פרוגרמטי באמצעות ממשקי ה-API של TransitionManager.

כשמציינים מעבר, אפשר להשתמש בכמה סוגים מוגדרים מראש שמוגדרים על ידי תת-כיתות של Transition, כמו Fade ו-ChangeBounds. אם לא מציינים סוג מעבר, המערכת משתמשת ב-AutoTransition כברירת מחדל, שמאפשר להעביר את התצוגות באופן אוטומטי, לשנות את הגודל שלהן ולהעביר אותן בהדרגה. בנוסף, אפשר ליצור מעברים מותאמים אישית על ידי הרחבה של כל אחת מהכיתות האלה כדי לבצע את האנימציות כרצונכם. מעבר בהתאמה אישית יכול לעקוב אחרי כל שינוי בנכס שתרצו, וליצור כל אנימציה שתרצו על סמך השינויים האלה. לדוגמה, אפשר לספק Subclass של Transition שמקשיב לשינויים במאפיין 'rotation' של תצוגה, ואז יוצר אנימציה של השינויים.

מידע נוסף זמין במסמכי העזרה של TransitionManager.

השהיה של האנימציה

ממשקי ה-API של Animator מאפשרים עכשיו להשהות ולהמשיך אנימציה מתמשכת באמצעות השיטות pause() ו-resume().

כדי לעקוב אחרי המצב של אנימציה, אפשר להטמיע את הממשק Animator.AnimatorPauseListener, שמספק פונקציות קריאה חוזרת כשאנימציה מושהית וממשיכה: pause() ו-resume(). לאחר מכן מוסיפים את המאזין לאובייקט Animator באמצעות addPauseListener().

לחלופין, אפשר ליצור תת-מחלקה של המחלקה הזו, שכוללת עכשיו הטמעות ריקות של פונקציות ה-call back להשהיה ולהמשך שהוגדרו על ידי Animator.AnimatorPauseListener.AnimatorListenerAdapter

מפות בייט לשימוש חוזר

מעכשיו אפשר לעשות שימוש חוזר בכל מפת סיביות שניתן לשינוי ב-BitmapFactory כדי לפענח כל מפת סיביות אחרת – גם אם מפת הסיביות החדשה היא בגודל שונה – כל עוד מספר הבייטים שנוצרו במפת הסיביות שפוענחה (זמין ב-getByteCount()) קטן או שווה למספר הבייטים שהוקצו למפת הסיביות שנעשה בה שימוש חוזר (זמין ב-getAllocationByteCount()). מידע נוסף זמין במאמר inBitmap.

ממשקי API חדשים ל-Bitmap מאפשרים לבצע הגדרה מחדש דומה לשימוש חוזר מחוץ ל-BitmapFactory (ליצירת ביטים ידנית או לצורך לוגיקה מותאמת אישית של פענוח). עכשיו אפשר להגדיר את המאפיינים של מפת הבייטמאפ באמצעות השיטות setHeight() ו-setWidth(), ולציין Bitmap.Config חדש באמצעות setConfig() בלי להשפיע על ההקצאה הבסיסית של מפת הבייטמאפ. השיטה reconfigure() מספקת גם דרך נוחה לשלב את השינויים האלה בקריאה אחת.

עם זאת, לא מומלץ לשנות את ההגדרות של קובץ BMP שמערכת התצוגה משתמשת בו כרגע, כי לא תתבצע מיפוי מחדש של מאגר הפיקסלים הבסיסי באופן צפוי.

תוכן משתמשים

מסגרת גישה לאחסון

בגרסאות קודמות של Android, אם רוצים שהאפליקציה תוכל לאחזר קובץ מסוג ספציפי מאפליקציה אחרת, צריך להפעיל כוונה עם הפעולה ACTION_GET_CONTENT. הפעולה הזו עדיין היא הדרך המתאימה לבקש קובץ שרוצים לייבא לאפליקציה. עם זאת, ב-Android 4.4 נוספה הפעולה ACTION_OPEN_DOCUMENT, שמאפשרת למשתמש לבחור קובץ מסוג ספציפי ולהעניק לאפליקציה גישה לקריאה לטווח ארוך לקובץ הזה (יכול להיות עם גישה לכתיבה) בלי לייבא את הקובץ לאפליקציה.

אם אתם מפתחים אפליקציה שמספקת שירותי אחסון לקבצים (כמו שירות שמאפשר לשמור קבצים בענן), אתם יכולים להשתמש בממשק המשתמש המאוחד הזה לבחירת קבצים על ידי הטמעת ספק תוכן כסוג משנה של הכיתה החדשה DocumentsProvider. תת-הסוג של DocumentsProvider חייב לכלול מסנן Intent שמקבל את הפעולה PROVIDER_INTERFACE ("android.content.action.DOCUMENTS_PROVIDER"). לאחר מכן, צריך להטמיע את ארבע השיטות המופשטות ב-DocumentsProvider:

queryRoots()
הפונקציה הזו חייבת להחזיר Cursor שמתאר את כל תיקיות השורש של אחסון המסמכים, באמצעות עמודות שהוגדרו ב-DocumentsContract.Root.
queryChildDocuments()
הפונקציה הזו חייבת להחזיר Cursor שמתאר את כל הקבצים בספרייה שצוינה, באמצעות העמודות שמוגדרות ב-DocumentsContract.Document.
queryDocument()
היא חייבת להחזיר Cursor שמתאר את הקובץ שצוין, באמצעות עמודות שמוגדרות ב-DocumentsContract.Document.
openDocument()
היא חייבת להחזיר ParcelFileDescriptor שמייצג את הקובץ שצוין. המערכת קוראת לשיטה הזו אחרי שהמשתמש בוחר קובץ ואפליקציית הלקוח מבקשת גישה אליו באמצעות קריאה ל-openFileDescriptor().

מידע נוסף זמין במדריך Storage Access Framework.

גישה לאחסון חיצוני

עכשיו אפשר לקרוא ולכתוב קבצים ספציפיים לאפליקציות במדיה אחסון חיצונית משנית, למשל כשהמכשיר כולל גם אחסון ממולא וגם כרטיס SD. השיטה החדשה getExternalFilesDirs() פועלת כמו השיטה הקיימת getExternalFilesDir(), חוץ מכך שהיא מחזירה מערך של אובייקטים מסוג File. לפני קריאה או כתיבת באחד מהנתיבים שמוחזרים על ידי השיטה הזו, מעבירים את האובייקט File לשיטה החדשה getStorageState() כדי לוודא שהאחסון זמין כרגע.

לשיטות אחרות לגישה לספריית המטמון ולספריית ה-OBB שספציפיות לאפליקציה יש עכשיו גם גרסאות תואמות שמספקות גישה למכשירי אחסון משניים: getExternalCacheDirs() ו-getObbDirs(), בהתאמה.

הערך הראשון במערך File המוחזר נחשב לאחסון החיצוני הראשי של המכשיר, והוא זהה ל-File שמוחזר על ידי שיטות קיימות כמו getExternalFilesDir().

הערה: החל מגרסה 4.4 של Android, הפלטפורמה כבר לא דורשת שהאפליקציה תקבל את ההרשאות WRITE_EXTERNAL_STORAGE או READ_EXTERNAL_STORAGE כשצריך לגשת רק לאזורים הספציפיים לאפליקציה באחסון החיצוני באמצעות השיטות שלמעלה. עם זאת, ההרשאות נדרשות אם רוצים לגשת לאזורים שניתן לשתף באחסון החיצוני, שמספק getExternalStoragePublicDirectory().

מתאמי סנכרון

השיטה החדשה requestSync() ב-ContentResolver מפשטת חלק מהתהליך של הגדרת בקשת סנכרון ל-ContentProvider על ידי אנקפסולציה של הבקשות באובייקט SyncRequest החדש, שאפשר ליצור באמצעות SyncRequest.Builder. המאפיינים ב-SyncRequest מספקים את אותה פונקציונליות כמו קריאות הסנכרון הקיימות של ContentProvider, אבל מאפשרים לציין שצריך לבטל סנכרון אם הרשת מוקצית, על ידי הפעלת setDisallowMetered().

קלט של משתמשים

סוגי חיישנים חדשים

החיישן החדש TYPE_GEOMAGNETIC_ROTATION_VECTOR מספק נתוני וקטור סיבוב על סמך מגנטומטר. זהו תחליף שימושי לחיישן TYPE_ROTATION_VECTOR כשג'ירוסקופ לא זמין, או כשמשתמשים בו עם אירועי חיישנים באצווה כדי לתעד את כיוון המכשיר בזמן שהטלפון במצב שינה. החיישן הזה צורך פחות חשמל מ-TYPE_ROTATION_VECTOR, אבל הוא עלול להיות נתון לרעש בנתוני האירועים, והוא הכי יעיל כשהמשתמש נמצא בחוץ.

ב-Android יש עכשיו גם תמיכה בחיישנים מובנים למעקב אחר צעדים בחומרה:

TYPE_STEP_DETECTOR
החיישן הזה מפעיל אירוע בכל פעם שהמשתמש עושה צעד. בכל שלב של המשתמש, החיישן הזה שולח אירוע עם הערך 1.0 חותמת זמן שמציינת מתי השלב התרחש.
TYPE_STEP_COUNTER
החיישן הזה גם מפעיל אירוע בכל צעד שזוהה, אבל במקום זאת הוא מספק את המספר הכולל של השלבים המצטברים מאז שהחיישן הזה נרשם לראשונה על ידי אפליקציה.

חשוב לדעת ששני חיישני השלבים האלה לא תמיד מספקים את אותן תוצאות. אירועי TYPE_STEP_COUNTER מתרחשים עם זמן אחזור ארוך יותר מאשר אירועים מ-TYPE_STEP_DETECTOR, אבל הסיבה לכך היא שהאלגוריתם TYPE_STEP_COUNTER מבצע יותר עיבוד כדי למנוע תוצאות חיוביות שגויות. לכן, יכול להיות שהאירועים יישלחו לאט יותר דרך TYPE_STEP_COUNTER, אבל התוצאות שלו אמורות להיות מדויקות יותר.

שני חיישני הצעדים תלויים בחומרה (Nexus 5 הוא המכשיר הראשון שתומך בהם), לכן צריך לבדוק את הזמינות באמצעות hasSystemFeature(), באמצעות הקבועים FEATURE_SENSOR_STEP_DETECTOR ו-FEATURE_SENSOR_STEP_COUNTER.

אירועי חיישן באצווה

כדי לנהל טוב יותר את צריכת החשמל של המכשיר, ממשקי ה-API של SensorManager מאפשרים לכם עכשיו לציין את התדירות שבה המערכת תשלח לאפליקציה שלכם קבוצות של אירועי חיישנים. הפעולה הזו לא מפחיתה את מספר אירועי החיישנים בפועל שזמינים לאפליקציה בפרק זמן נתון, אלא רק את התדירות שבה המערכת קוראת ל-SensorEventListener שלכם עם עדכוני חיישנים. כלומר, במקום לשלוח כל אירוע לאפליקציה ברגע שהוא מתרחש, המערכת שומרת את כל האירועים שמתרחשים לאורך תקופה מסוימת, ולאחר מכן שולחת אותם לאפליקציה בבת אחת.

כדי לספק אצווה, לכיתה SensorManager נוספות שתי גרסאות חדשות של השיטה registerListener() שמאפשרות לציין את 'זמן האחזור המקסימלי של הדוח'. הפרמטר החדש הזה מציין את העיכוב המקסימלי ש-SensorEventListener יסבול בזמן שליחת אירועי חיישן חדשים. לדוגמה, אם מציינים זמן אחזור של קבוצה של אירועים של דקה אחת, המערכת תעביר את הקבוצה האחרונה של אירועים שנאספו בקבוצה במרווח זמן של לא יותר מדקה אחת, על ידי ביצוע קריאות רצופות לשיטה onSensorChanged() – פעם אחת לכל אירוע שנאסף בקבוצה. אירועי החיישן לעולם לא יתעכבו יותר מזמן האחזור המקסימלי של הדיווח, אבל הם עשויים להגיע מוקדם יותר אם אפליקציות אחרות ביקשו זמן אחזור קצר יותר לאותו חיישן.

עם זאת, חשוב לדעת שהחיישן יעביר לאפליקציה את האירועים שנאספו בקבוצה על סמך זמן האחזור לדיווח רק כשמעבד ה-CPU פעיל. חיישן חומרה שתומך בקיבוץ ימשיך לאסוף אירועי חיישן בזמן שהמעבד במצב שינה, אבל הוא לא יעיר את המעבד כדי להעביר לאפליקציה את האירועים המקובצים. כשהזיכרון של החיישן יפוג בסופו של דבר, הוא יתחיל למחוק את האירועים הישנים ביותר כדי לשמור את האירועים החדשים ביותר. כדי למנוע אובדן אירועים, אפשר להעיר את המכשיר לפני שהזיכרון של החיישן מתמלא, ואז להפעיל את הפונקציה flush() כדי לתעד את קבוצת האירועים האחרונה. כדי להעריך מתי הזיכרון יתמלא ויהיה צורך לנקות אותו, צריך להפעיל את getFifoMaxEventCount() כדי לקבל את המספר המקסימלי של אירועי חיישן שאפשר לשמור, ולחלק את המספר הזה בשיעור שבו האפליקציה רוצה לקבל כל אירוע. אפשר להשתמש בחישוב הזה כדי להגדיר התראות התעוררות באמצעות AlarmManager שמפעילות את Service (שמטמיע את SensorEventListener) כדי לנקות את החיישן.

הערה: לא כל המכשירים תומכים בקיבוץ אירועי חיישנים, כי הדבר מחייב תמיכה בחיישן החומרה. עם זאת, החל מ-Android 4.4, תמיד צריך להשתמש בשיטות החדשות של registerListener(), כי אם המכשיר לא תומך בצבירה, המערכת תתעלם בעדינות מהארגומנט של זמן האחזור של האצווה ותשלח אירועי חיישן בזמן אמת.

זהויות של בקרי מידע

מעכשיו, Android מזהה כל בקר מחובר באמצעות מספר שלם ייחודי שאפשר לשלוח עליו שאילתה באמצעות getControllerNumber(). כך קל יותר לשייך כל בקר לשחקן אחר במשחק. המספר של כל בקר עשוי להשתנות בגלל שהמשתמש ניתק, חיבר או הגדר מחדש את הבקרים. לכן, כדי לעקוב אחרי המספר של הבקר שתואם לכל מכשיר קלט, צריך לרשום מופע של InputManager.InputDeviceListener. לאחר מכן, צריך לקרוא ל-getControllerNumber() לכל InputDevice כשמתרחש שינוי.

עכשיו, מכשירים מחוברים מספקים גם מזהי מוצרים ומזהי ספקים שזמינים ב-getProductId() וב-getVendorId(). אם אתם צריכים לשנות את מיפויי המפתחות בהתאם לקבוצת המפתחות הזמינה במכשיר, אתם יכולים לשלוח שאילתה למכשיר כדי לבדוק אם מקשים מסוימים זמינים באמצעות hasKeys(int...).

ממשק משתמש

מצב מסך מלא immersive

כדי לספק לאפליקציה פריסה שתמלא את כל המסך, הדגל החדש SYSTEM_UI_FLAG_IMMERSIVE עבור setSystemUiVisibility() (בשילוב עם SYSTEM_UI_FLAG_HIDE_NAVIGATION) מאפשר מצב מסך מלא חדש מרתק. כשמצב המסך המלא העשיר מופעל, הפעילות שלכם ממשיכה לקבל את כל אירועי המגע. המשתמש יכול לחשוף את סרחי המערכת באמצעות החלקה פנימה באזור שבו הם מופיעים בדרך כלל. הפעולה הזו מנקה את הדגל SYSTEM_UI_FLAG_HIDE_NAVIGATION (ואת הדגל SYSTEM_UI_FLAG_FULLSCREEN, אם הוא הוחל) כדי שסרגל המערכת יישאר גלוי. עם זאת, אם רוצים שהסרגל המערכת ייעלם שוב אחרי כמה רגעים, אפשר להשתמש במקום זאת בדגל SYSTEM_UI_FLAG_IMMERSIVE_STICKY.

סרגי מערכת שקופים

עכשיו אפשר להפוך את שורות המערכת לשקופות חלקית בעזרת עיצובים חדשים, Theme.Holo.NoActionBar.TranslucentDecor ו-Theme.Holo.Light.NoActionBar.TranslucentDecor. כשמפעילים את סטטוס השקיפות של שורת הסטטוס, הפריסה ממלאת את האזור שמאחורי שורת הסטטוס, לכן צריך להפעיל גם את fitsSystemWindows בחלק מהפריסה שלא אמור להיות מכוסה על ידי שורת הסטטוס.

אם אתם יוצרים נושא מותאם אישית, צריך להגדיר אחד מהנושאים האלה כנושא ההורה או לכלול את מאפייני הסגנון windowTranslucentNavigation ו-windowTranslucentStatus בנושא.

מאזין משופר להתראות

ב-Android 4.3 נוספו ממשקי ה-API של NotificationListenerService, שמאפשרים לאפליקציות לקבל מידע על התראות חדשות כשהן מתפרסמות על ידי המערכת. ב-Android 4.4, מאזינים להתראות יכולים לאחזר מטא-נתונים נוספים של ההתראה ופרטים מלאים על הפעולות של ההתראה:

השדה החדש Notification.extras כולל Bundle כדי לספק לכלי ליצירת התראות מטא-נתונים נוספים, כמו EXTRA_TITLE ו-EXTRA_PICTURE. הכיתה החדשה Notification.Action מגדירה את המאפיינים של פעולה שמצורפת להתראה, ואפשר לאחזר אותה מהשדה החדש actions.

שיקוף של רכיבי drawable לפריסות מימין לשמאל

בגרסאות קודמות של Android, אם האפליקציה כוללת תמונות שצריך להפוך את הכיוון האופקי שלהן לפריסות מימין לשמאל, צריך לכלול את התמונה המשתקפת בספריית משאבים מסוג drawables-ldrtl/. עכשיו המערכת יכולה לשקף תמונות באופן אוטומטי על ידי הפעלת המאפיין autoMirrored במשאב drawable או על ידי קריאה ל-setAutoMirrored(). כשהאפשרות הזו מופעלת, ה-Drawable משתקף באופן אוטומטי כשכיוון הפריסה הוא מימין לשמאל.

נגישות

מעכשיו, אפשר להוסיף את המאפיין החדש accessibilityLiveRegion לפריסה של ה-XML או להפעיל את setAccessibilityLiveRegion() כדי להצהיר על 'אזורים פעילים' בחלקים של ממשק המשתמש שמתעדכנים באופן דינמי עם תוכן טקסט חדש, באמצעות הכיתה View. לדוגמה, מסך התחברות עם שדה טקסט שבו מוצגת ההתראה 'סיסמה שגויה' צריך להיות מסומן כאזור פעיל, כדי שקורא המסך יקריא את ההודעה כשהיא תשתנה.

אפליקציות שמספקות שירות נגישות יכולות עכשיו לשפר את היכולות שלהן באמצעות ממשקי API חדשים שמספקים מידע על אוספי תצוגות, כמו תצוגות רשימה או תצוגות רשת, באמצעות AccessibilityNodeInfo.CollectionInfo ו-AccessibilityNodeInfo.CollectionItemInfo.

הרשאות הניתנות לאפליקציה

אלה ההרשאות החדשות שהאפליקציה שלכם צריכה לבקש באמצעות התג <uses-permission> כדי להשתמש בממשקי API חדשים מסוימים:

INSTALL_SHORTCUT
מאפשרת לאפליקציה להתקין קיצור דרך במרכז האפליקציות
UNINSTALL_SHORTCUT
מאפשרת לאפליקציה להסיר קיצור דרך במרכז האפליקציות
TRANSMIT_IR
מאפשרת לאפליקציה להשתמש במשדר האינפרה-אדום של המכשיר, אם הוא זמין

הערה: החל מגרסה 4.4 של Android, הפלטפורמה כבר לא דורשת שהאפליקציה תקבל את ההרשאות WRITE_EXTERNAL_STORAGE או READ_EXTERNAL_STORAGE כשרוצים לגשת לאזורים הספציפיים לאפליקציה באחסון החיצוני באמצעות שיטות כמו getExternalFilesDir(). עם זאת, עדיין נדרשות ההרשאות האלה אם רוצים לגשת לאזורים שניתן לשתף באחסון החיצוני, ש-getExternalStoragePublicDirectory() מספק.

תכונות המכשיר

אלה תכונות מכשיר חדשות שאפשר להצהיר עליהן באמצעות התג <uses-feature> כדי להצהיר על דרישות האפליקציה ולהפעיל סינון ב-Google Play או לבדוק אותן במהלך זמן הריצה:

FEATURE_CONSUMER_IR
המכשיר מסוגל לתקשר עם מכשירי אינפרה-אדום של צרכנים.
FEATURE_DEVICE_ADMIN
המכשיר תומך באכיפה של מדיניות המכשיר באמצעות אדמינים של המכשיר.
FEATURE_NFC_HOST_CARD_EMULATION
המכשיר תומך באמולציה של כרטיס NFC מבוסס-מארח.
FEATURE_SENSOR_STEP_COUNTER
המכשיר כולל ספירת צעדים בחומרה.
FEATURE_SENSOR_STEP_DETECTOR
המכשיר כולל גלאי צעדים בחומרה.

בדוח ההבדלים ב-API מפורטות כל השינויים ב-API ב-Android 4.4.