ממשקי API של Android 4.3

רמת API: 18

Android 4.3 (JELLY_BEAN_MR2) הוא עדכון לגרסה של Jelly Bean שמציע תכונות חדשות למשתמשים ולאפליקציה למפתחים. במסמך הזה מתוארות המבוא ממשקי API חדשים.

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

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

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

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

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

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

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

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

אם האפליקציה משתמשת באובייקטים מרומזים של Intent...

יכול להיות שהאפליקציה לא תפעל בצורה תקינה בסביבת פרופיל מוגבלת.

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

כשמשתמשים ב-Intent מרומז, תמיד צריך לוודא שהאפליקציה זמינה לטיפול בכוונה על ידי קריאה אל resolveActivity() או queryIntentActivities(). לדוגמה:

Kotlin

val intent = Intent(Intent.ACTION_SEND)
...
if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
} else {
    Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show()
}

Java

Intent intent = new Intent(Intent.ACTION_SEND);
...
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
} else {
    Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show();
}

אם האפליקציה מסתמכת על חשבונות...

יכול להיות שהאפליקציה לא תפעל בצורה תקינה בסביבת פרופיל מוגבלת.

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

אם ברצונך למנוע לחלוטין שימוש באפליקציה שלך בפרופילים מוגבלים מפני האפליקציה תלויה בפרטי החשבון שמכילים מידע רגיש. יש לציין את המאפיין android:requiredAccountType במניפסט <application> לרכיב מסוים.

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

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

ייתכן שהסרטון שלך ייראה קטן יותר ב-Android 4.3.

בגרסאות קודמות של Android, הווידג'ט VideoView שגוי חישבנו את הערך "wrap_content" עבור layout_height ו-layout_width כך שיהיה זהה ל-"match_parent". לכן, למרות שהגודל או הרוחב של "wrap_content" מספקים בעבר את פריסת הסרטון הרצויה, הדבר עלול להוביל לסרטון קטן בהרבה ב-Android 4.3 ואילך. כדי לפתור את הבעיה, צריך להחליף "wrap_content" אצל "match_parent" ומאמתים שהסרטון מופיע כצפוי ב- Android 4.3 וכן בגרסאות ישנות יותר.

פרופילים מוגבלים

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

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

בשיטה onReceive() של שלך, BroadcastReceiver, עליך ליצור RestrictionEntry לכל הגבלה שהאפליקציה שלך מספקת. כל RestrictionEntry מגדיר שם, תיאור של הגבלה ו סוגי הנתונים הבאים:

  • TYPE_BOOLEAN עבור הגבלה שהיא או TRUE או FALSE.
  • TYPE_CHOICE עבור הגבלה שחלה עליה אפשרויות מרובות שאינן יכולות להתקיים בו-זמנית (בחירות של לחצן בחירה).
  • TYPE_MULTI_SELECT עבור הגבלה כולל כמה אפשרויות בחירה שאינן זהות (אפשרויות בחירה עם תיבות סימון).

לאחר מכן צריך להזין את כל האובייקטים של RestrictionEntry ב-ArrayList ולהוסיף אותם לתוצאה של מקלט השידור כערך של עוד EXTRA_RESTRICTIONS_LIST.

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

אם רוצים לספק הגבלות ספציפיות יותר שלא ניתן לטפל בהן באמצעות ערך בוליאני, וערכי שאלות אמריקאיות, אז תוכלו ליצור פעילות שבה המשתמש יכול לציין ולאפשר למשתמשים לפתוח את הפעילות הזו דרך הגדרות ההגבלה. ב מקלט שידורים, כולל תוספת EXTRA_RESTRICTIONS_INTENT בתוצאה Bundle. הנוסף הזה חייב לציין Intent שמציין את המחלקה Activity להשקה (השתמשו ב- putParcelable() כדי להעביר את EXTRA_RESTRICTIONS_INTENT עם Intent). כשהמשתמש הראשי מזין את הפעילות שלכם כדי להגדיר הגבלות בהתאמה אישית, לאחר מכן, הפעילות חייבת להחזיר תוצאה שמכילה את ערכי ההגבלה בתוספת באמצעות אחד מקש EXTRA_RESTRICTIONS_LIST או EXTRA_RESTRICTIONS_BUNDLE, בהתאם למה שמציינים RestrictionEntry אובייקטים או צמדי מפתח/ערך, בהתאמה.

תמיכה בחשבונות בפרופיל מוגבל

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

  • מתן גישה לחשבונות של הבעלים מפרופיל מוגבל.

    כדי לקבל גישה לחשבון מפרופיל מוגבל, צריך להוסיף את המאפיין android:restrictedAccountType לתג <application>:

    <application ...
        android:restrictedAccountType="com.example.account.type" >
    

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

  • השבתת פונקציונליות מסוימת כשלא ניתן לשנות חשבונות.

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

    Kotlin

    val um = context.getSystemService(Context.USER_SERVICE) as UserManager
    val restrictions: Bundle = um.userRestrictions
    if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
        // cannot add accounts, disable some functionality
    }
    

    Java

    UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
    Bundle restrictions = um.getUserRestrictions();
    if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
        // cannot add accounts, disable some functionality
    }
    

    הערה: במקרה הזה, לא להצהיר על מאפיינים חדשים בקובץ המניפסט.

  • השבתת האפליקציה אם אין לך גישה לחשבונות פרטיים.

    אם חשוב במקום זאת שהאפליקציה לא תהיה זמינה לפרופילים מוגבלים, האפליקציה תלויה במידע אישי רגיש בחשבון (ובגלל שפרופילים מוגבלים כרגע אין אפשרות להוסיף חשבונות חדשים), להוסיף המאפיין android:requiredAccountType לתג <application>:

    <application ...
        android:requiredAccountType="com.example.account.type" >
    

    לדוגמה, אפליקציית Gmail משתמשת במאפיין הזה כדי להשבית את עצמה לפרופילים מוגבלים, כי האימייל האישי של הבעלים לא אמור להיות זמין לפרופילים מוגבלים.

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

    Bluetooth עם צריכת אנרגיה נמוכה (הכנה חכמה)

    מערכת Android תומכת עכשיו ב-Bluetooth עם צריכת אנרגיה נמוכה (LE) עם ממשקי API חדשים בandroid.bluetooth. בעזרת ממשקי ה-API החדשים, אפשר לבנות אפליקציות ל-Android שמתחברות באמצעות Bluetooth עם צריכת אנרגיה נמוכה ציוד היקפי, כמו מוניטורים לדופק ומדי צעדים.

    כי Bluetooth LE היא תכונת חומרה שלא זמינה בכל המכשירים מכשירים מבוססי Android, חובה להצהיר בקובץ המניפסט על <uses-feature> רכיב עבור "android.hardware.bluetooth_le":

    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
    

    אם אתם כבר מכירים את ממשקי ה-API הקלאסיים של Bluetooth ב-Android, שימו לב יש כמה הבדלים בממשקי ה-API של Bluetooth LE API. הדבר החשוב ביותר הוא שיש עכשיו כיתת BluetoothManager שאפשר להשתמש בה לביצוע פעולות ברמה גבוהה כמו רכישה של BluetoothAdapter, קבלת רשימה של מכשירים, ובדיקת המצב של המכשיר. לדוגמה, כך תקבלו עכשיו את BluetoothAdapter:

    Kotlin

    val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
    bluetoothAdapter = bluetoothManager.adapter
    

    Java

    final BluetoothManager bluetoothManager =
            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    bluetoothAdapter = bluetoothManager.getAdapter();
    

    כדי למצוא ציוד היקפי עם Bluetooth LE, צריך להפעיל את startLeScan() ב-BluetoothAdapter ולהעביר אותו של הממשק BluetoothAdapter.LeScanCallback. כשחיבור ה-Bluetooth המתאם מזהה ציוד היקפי מסוג Bluetooth LE, בהטמעת BluetoothAdapter.LeScanCallback מתבצעת קריאה אל onLeScan(). הזה ה-method מספקת לכם אובייקט BluetoothDevice שמייצג את המכשיר שזוהה, ערך ה-RSSI של המכשיר ומערך בייטים שמכיל את רשומת מודעה.

    אם רוצים לסרוק רק סוגים ספציפיים של ציוד היקפי, אפשר לקרוא ל-startLeScan() ולכלול מערך של UUID אובייקטים שמציינים את שירותי ה-GATT שהאפליקציה שלכם תומכת בהם.

    הערה: אפשר לסרוק אחר מכשירי Bluetooth LE רק או לסרוק כדי לאתר מכשירי Bluetooth מהגרסה הקלאסית של ממשקי API קודמים. לא ניתן לסרוק גם ל-LE וגם ל-Classic מכשירי Bluetooth בו-זמנית.

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

    כדי לגשת לתכונות Bluetooth במכשיר, האפליקציה צריכה לבקש גם הרשאות משתמש Bluetooth. מידע נוסף זמין במדריך ה-API של Bluetooth Low Energy.

    מצב סריקת Wi-Fi בלבד

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

    אם אתם רוצים לאתר את המיקום של המשתמש אבל ה-Wi-Fi כבוי כרגע, תוכלו לבקש משתמש כדי להפעיל מצב סריקת Wi-Fi בלבד על ידי קריאה ל-startActivity() עם הפעולה ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE.

    הגדרת Wi-Fi

    ממשקי ה-API החדשים של WifiEnterpriseConfig מאפשרים לשירותים שמיועדים לארגונים להגדיר תצורה של Wi-Fi במכשירים מנוהלים באופן אוטומטי.

    תגובה מהירה לשיחות נכנסות

    החל מ-Android 4.0, התכונה נקראת 'תגובה מהירה' מאפשרת למשתמשים להשיב שיחות באמצעות הודעת טקסט מיידית בלי לענות לשיחה או לבטל את הנעילה של המכשיר. עד עכשיו, ההודעות המהירות האלה טופלו תמיד על ידי אפליקציית ברירת המחדל להעברת הודעות. עכשיו כל אפליקציה יכול להצהיר על היכולת שלו לטפל בהודעות האלה על ידי יצירה של Service עם מסנן Intent עבור ACTION_RESPOND_VIA_MESSAGE.

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

    כדי לקבל את הכוונה הזו, עליך להצהיר על ההרשאה SEND_RESPOND_VIA_MESSAGE.

    מולטימדיה

    שיפורים של Mediaחלץ' וב-MediaCodec

    עכשיו קל יותר לכתוב ב-Android מודעה דינמית סטרימינג בנגני HTTP (DASH) בהתאם לתקן ISO/IEC 23009-1, באמצעות ממשקי API קיימים ב-MediaCodec וב-MediaExtractor. המסגרת שבבסיס ממשקי ה-API האלה עודכנה והיא תומכת ניתוח של קובצי MP4 מקוטעים, אבל האפליקציה שלך עדיין אחראית לניתוח המטא-נתונים של MPD ומעבירים את כל השידורים הנפרדים אל MediaExtractor.

    אם רוצים להשתמש ב-DASH עם תוכן מוצפן, חשוב לשים לב ששיטת getSampleCryptoInfo() מחזירה את המטא-נתונים MediaCodec.CryptoInfo שמתארים את המבנה של כל מדיה מוצפנת. לדוגמה. כמו כן, השיטה getPsshInfo() נוספה אל MediaExtractor כדי שתוכלו לגשת למטא-נתונים של PSSH עבור מדיה ב-DASH. השיטה הזו מחזירה מפה של UUID לבייטים, עם הפונקציה UUID שמציין את סכמת הקריפטו, והבייטים הם הנתונים הספציפיים לסכמה הזאת.

    DRM למדיה

    המחלקה החדשה MediaDrm מספקת פתרון מודולרי לזכויות דיגיטליות ניהול (DRM) בתוכן המדיה שלך על ידי הפרדה בין בעיות הקשורות לניהול זכויות דיגיטליות (DRM) לבין הפעלת מדיה. עבור הפרדת ה-API הזו מאפשרת להפעיל תוכן בהצפנת Widevine מבלי שיהיה צורך כדי להשתמש בפורמט המדיה של Widevine. פתרון DRM זה תומך גם ב-DASH Common Encryption כדי יכולים להשתמש במגוון סכמות DRM בתוכן הסטרימינג שלכם.

    אפשר להשתמש ב-MediaDrm כדי לקבל הודעות אטומות של בקשת מפתח ועיבוד הודעות לתגובת מפתח מהשרת עבור קבלת רישיונות והקצאה. האפליקציה שלך אחראי לטיפול בתקשורת הרשת עם השרתים; הכיתה MediaDrm מאפשרת רק ליצור ולעבד הודעות.

    ממשקי ה-API של MediaDrm מיועדים לשימוש בשילוב עם ממשקי API של MediaCodec שהושקו ב-Android 4.1 (רמת API 16), כולל MediaCodec לקידוד ופענוח של התוכן, MediaCrypto לטיפול בתוכן מוצפן ו-MediaExtractor לחילוץ והדמייה של התוכן.

    קודם צריך ליצור את MediaExtractor וגם MediaCodec אובייקטים. לאחר מכן תוכל לגשת לכלי לזיהוי סכימת DRM UUID, בדרך כלל מהמטא-נתונים בתוכן, ולהשתמש בו כדי ליצור של אובייקט MediaDrm באמצעות ה-constructor שלו.

    קידוד וידאו מ-Surface

    Android 4.1 (רמת API 16) הוסיף את המחלקה MediaCodec לרמה נמוכה לקידוד ולפענוח של תוכן מדיה. בעת קידוד וידאו, נדרש עבור Android 4.1 את המדיה באמצעות מערך ByteBuffer, אבל ב-Android 4.3 אפשר עכשיו להשתמש ב-Surface כקלט למקודד. לדוגמה, כך אפשר לקודד קלט מקובץ וידאו קיים או באמצעות פריימים שנוצרו מ-OpenGL ES.

    כדי להשתמש ב-Surface כקלט למקודד, צריך קודם להפעיל את הפקודה configure() בשביל MediaCodec. אחר כך צריך להתקשר אל createInputSurface() כדי לקבל את ה-Surface שבו אפשר לשדר את המדיה.

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

    כדי להתחיל בקידוד, יש להפעיל את start() במכשיר MediaCodec. בסיום, צריך להתקשר אל signalEndOfInputStream() כדי לסיים את הקידוד, וקוראים לפונקציה release() Surface.

    רמיקס של מדיה

    המחלקה החדשה של MediaMuxer מאפשרת שכפול בין שידור אודיו אחד וזרם וידאו אחד. ממשקי ה-API האלה פועלים במקביל ל-MediaExtractor נוסף ל-Android 4.2 עבור מדיה להסרת ריבוי כפילויות (המרת טקסט).

    פורמטים נתמכים של פלט מוגדרים ב-MediaMuxer.OutputFormat. נכון לעכשיו, MP4 הוא פורמט הפלט היחיד שנתמך, וכרגע יש תמיכה ב-MediaMuxer שידור אודיו אחד בלבד ו/או שידור וידאו אחד בכל פעם.

    האפליקציה MediaMuxer תוכננה בעיקר לפעול עם MediaCodec כך שאפשר לבצע עיבוד וידאו באמצעות MediaCodec ואז לשמור את כפלט לקובץ MP4 באמצעות MediaMuxer. אפשר גם להשתמש בפונקציה MediaMuxer בשילוב עם MediaExtractor כדי לבצע לעריכת מדיה ללא צורך בקידוד או בפענוח קוד.

    התקדמות ההפעלה ובחירת המיקום (scrub) עבור RemoteControlClient

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

    קודם כול צריך להפעיל את הדגל FLAG_KEY_MEDIA_POSITION_UPDATE על ידי העברתו אל setTransportControlsFlags().

    לאחר מכן מטמיעים את שני הממשקים החדשים הבאים:

    RemoteControlClient.OnGetPlaybackPositionListener
    זה כולל את הקריאה החוזרת onGetPlaybackPosition(), שמבקשת את המיקום הנוכחי של המדיה שלך כשהשלט הרחוק צריך לעדכן את ההתקדמות בממשק המשתמש שלו.
    RemoteControlClient.OnPlaybackPositionUpdateListener
    הערכים האלה כוללים את הקריאה החוזרת (callback) של onPlaybackPositionUpdate(), מציין לאפליקציה את קוד הזמן החדש עבור המדיה כאשר המשתמש מקרצף את ההפעלה באמצעות ממשק משתמש לשלט רחוק.

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

    כאשר הממשקים האלה מוגדרים, אפשר להגדיר אותם עבור RemoteControlClient על ידי קריאה ל-setOnGetPlaybackPositionListener() setPlaybackPositionUpdateListener(), בהתאמה.

    גרפיקה

    תמיכה ב-OpenGL ES 3.0

    מערכת Android 4.3 כוללת ממשקי Java ותמיכה מובנית ב-OpenGL ES 3.0. פונקציונליות חדשה חשובה שסופק ב-OpenGL ES 3.0 כולל:

    • האצה של אפקטים חזותיים מתקדמים
    • דחיסת נתוני ETC2/EAC באיכות גבוהה כתכונה סטנדרטית
    • גרסה חדשה של שפת ההצללה של GLSL ES עם מספר שלם ותמיכה בנקודה צפה (floating-point) של 32 ביט
    • עיבוד טקסטורה מתקדם
    • סטנדרטיזציה רחבה יותר של גודל המרקם ופורמטים של מאגר נתונים זמני לעיבוד

    ממשק Java ל-OpenGL ES 3.0 ב-Android מסופק עם GLES30. כשמשתמשים ב-OpenGL ES 3.0, חשוב להצהיר עליו בקובץ המניפסט עם <uses-feature> את התג ואת המאפיין android:glEsVersion. לדוגמה:

    <manifest>
        <uses-feature android:glEsVersion="0x00030000" />
        ...
    </manifest>
    

    וחשוב לזכור לציין את ההקשר של OpenGL ES באמצעות קריאה ל-setEGLContextClientVersion(), להעביר את 3 כגרסה.

    למידע נוסף על השימוש ב-OpenGL ES, כולל הוראות לבדיקה אם המכשיר נתמך בגרסת OpenGL ES בזמן הריצה, כדאי לעיין במדריך ל-API של OpenGL ES.

    מיקרו-פעולות (Mipming) של פריטים שניתן להזזה

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

    ב-Android 4.2 (רמת API 17) נוספה תמיכה במיפויי מפות בBitmap כיתה – מערכת Android מחליפה את תמונות ה-mip ב-Bitmap לאחר סיפק מקור Mipmap והפעלת את setHasMipMap(). ב-Android 4.3 אפשר עכשיו להפעיל מפות Mipmap גם עבור אובייקט BitmapDrawable, על ידי הוספה של נכס Mipmap הגדרת המאפיין android:mipMap בקובץ משאב של מפת סיביות (bitmap) או באמצעות קריאה ל-hasMipMap().

    ממשק משתמש

    הצגת שכבות-על

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

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

    כשיוצרים שכבת-על לתצוגת ווידג'ט כמו Button, יכול להוסיף Drawable אובייקטים לשכבת-העל באמצעות קריאה add(Drawable). אם קוראים לפונקציה getOverlay() לתצוגת פריסה, כמו RelativeLayout, האובייקט המוחזר הוא ViewGroupOverlay. כיתה אחת (ViewGroupOverlay) היא מחלקה משנית של ViewOverlay, שמאפשר לך גם להוסיף View לאובייקטים באמצעות add(View).

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

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

    Kotlin

    val view: View? = findViewById(R.id.view_to_remove)
    val container: ViewGroup? = view?.parent as ViewGroup
    
    container?.apply {
        overlay.add(view)
        ObjectAnimator.ofFloat(view, "translationX", right.toFloat())
                .start()
    }
    

    Java

    View view = findViewById(R.id.view_to_remove);
    ViewGroup container = (ViewGroup) view.getParent();
    container.getOverlay().add(view);
    ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationX", container.getRight());
    anim.start();
    

    פריסת גבולות אופטיים

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

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

    הערה: בצילום המסך שבאיורים 1 ו-2 יש את הכיתוב "Show" גבולות הפריסה" הגדרת המפתח מופעלת. בכל תצוגה, קווים אדומים מציינים גבולות, קווים כחולים מציינים את גבולות הקליפ וורוד מציין שוליים.

    איור 1. פריסה באמצעות גבולות קליפ (ברירת מחדל).

    איור 2. פריסה באמצעות גבולות אופטיים.

    כדי ליישר את התצוגות על סמך הגבולות האופטיים שלהן, צריך להגדיר את המאפיין android:layoutMode כ-"opticalBounds" באחת מפריסות ההורה. לדוגמה:

    <LinearLayout android:layoutMode="opticalBounds" ... >
    

    איור 3. תצוגה מוגדלת של תשעה תיקונים בלחצן Holo עם גבולות אופטיים.

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

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

    אם תיצרו תצוגה מותאמת אישית על ידי סיווג משנה של View, ViewGroup או כל תת-מחלקה שלה, התצוגה תירש את ההתנהגויות הקשורות האלה.

    הערה: כל הווידג'טים שנתמכים בעיצוב של Holo עודכנו עם גבולות אופטיים, כולל Button, Spinner EditText ואחרים. כך תוכלו ליהנות מהיתרונות הבאים באופן מיידי המאפיין android:layoutMode של המאפיין "opticalBounds" אם האפליקציה מחילה עיצוב Holo (Theme.Holo, Theme.Holo.Light וכו').

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

    אנימציה של ערכי מלבן

    עכשיו אפשר להוסיף אנימציה בין שני ערכים של Rect עם הערך החדש RectEvaluator. הכיתה החדשה היא יישום של TypeEvaluator שאפשר להעביר ל-ValueAnimator.setEvaluator().

    צירוף חלונות והתמקדות ב-listener

    בעבר, רציתם לראות מתי התצוגה שלכם מחוברת לחלון או מנותקת ממנו כשהמיקוד השתנה, היה עליך לשנות את המחלקה View לערך להטמיע את onAttachedToWindow() ואת onDetachedFromWindow(), או onWindowFocusChanged(), בהתאמה.

    עכשיו, כדי לקבל אירועים של צירוף ולנתק, אפשר במקום זאת להטמיע את ViewTreeObserver.OnWindowAttachListener ולהגדיר אותו בתצוגה באמצעות addOnWindowAttachListener(). כדי לקבל אירועי התמקדות, אפשר להטמיע את ViewTreeObserver.OnWindowFocusChangeListener ולהגדיר אותו בתצוגה באמצעות addOnWindowFocusChangeListener().

    תמיכה בסריקת יתר בטלוויזיה

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

    כיוון המסך

    <activity> screenOrientation של התג יש עכשיו תמיכה בערכים נוספים בהתאם להעדפת המשתמש לסיבוב אוטומטי:

    "userLandscape"
    פועל כמו "sensorLandscape", אלא אם המשתמש משבית את הסיבוב האוטומטי לאחר מכן הוא ננעל בכיוון הרגיל לרוחב ולא מתחלף.
    "userPortrait"
    התנהגות זהה לזו של "sensorPortrait", אלא אם המשתמש משבית את הסיבוב האוטומטי אז הוא ננעל בפריסה לאורך הרגיל ולא מתהפך.
    "fullUser"
    התנהגות זהה ל-"fullSensor" ומאפשרת סיבוב בכל ארבעת הכיוונים, אם המשתמש משבית את הסיבוב האוטומטי, הוא ננעל בכיוון המועדף של המשתמש.

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

    אנימציות סיבוב

    שדה rotationAnimation החדש ב WindowManager מאפשר לך לבחור אחת מתוך שלוש אנימציות שאתה רוצה שבו רוצים להשתמש כשהמערכת משנה את כיוון המסך. שלוש האנימציות הן:

    הערה: האנימציות האלו זמינות רק אם הגדרתם שהפעילות היא במסך מלא. מצב, שאפשר להפעיל עם עיצובים כמו Theme.Holo.NoActionBar.Fullscreen.

    לדוגמה, כך ניתן להפעיל את האפשרות 'עמעום הדרגתי' אנימציה:

    Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        val params: WindowManager.LayoutParams = window.attributes
        params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE
        window.attributes = params
        ...
    }
    

    Java

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        WindowManager.LayoutParams params = getWindow().getAttributes();
        params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
        getWindow().setAttributes(params);
        ...
    }
    

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

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

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

    החיישנים החדשים של TYPE_GYROSCOPE_UNCALIBRATED ו-TYPE_MAGNETIC_FIELD_UNCALIBRATED מספקים נתוני חיישנים גולמיים ללא בנוגע להערכות הטיה. כלומר, הערכים הקיימים TYPE_GYROSCOPE ו-TYPE_MAGNETIC_FIELD חיישנים מספקים נתוני חיישנים שלוקחים בחשבון את ההטיה המשוערת מסחף הג'יירו וברזל קשה במכשיר, בהתאמה. אבל המודל החדש 'לא מכויל' גרסאות של החיישנים האלה את הנתונים הגולמיים של החיישנים, ולהציע את ערכי ההטיות המשוערים בנפרד. החיישנים האלה מאפשרים לכם לספק כיול מותאם אישית משלכם לנתוני החיישן על ידי שיפור ההטיות המשוערות באמצעות נתונים חיצוניים.

    האזנה להתראות

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

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

    ניהול אנשי הקשר

    שאילתה עבור "אנשי קשר"

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

    שאילתה לגבי דלתא של אנשי קשר

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

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

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

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

    לקבלת קוד לדוגמה באמצעות ממשקי ה-API האלה כדי לבדוק אם יש שינויים באנשי הקשר, היכנסו ל-ApiDemos שזמינה בהורדה של דוגמאות SDK.

    התאמה לשוק המקומי

    תמיכה משופרת בטקסט דו-כיווני

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

    לדוגמה, כשרוצים ליצור משפט עם משתנה מחרוזת, למשל "האם התכוונת ל: 15 Bay Street, Laurel, CA?", בדרך כלל מעבירים משאב מחרוזת מותאם לשוק המקומי, ואת המשתנה String.format():

    Kotlin

    val suggestion = String.format(resources.getString(R.string.did_you_mean), address)
    

    Java

    Resources res = getResources();
    String suggestion = String.format(res.getString(R.string.did_you_mean), address);
    

    עם זאת, אם הלוקאל הוא עברית, המחרוזת המפורמטת תופיע כך:

    האם הפנייה שלך היא ברחוב ביי 15, לורל, קליפורניה?

    זה לא נכון כי המספר 15 צריך להיות משמאל ל-Bay Street. הפתרון הוא להשתמש ב-BidiFormatter וב-method unicodeWrap(). לדוגמה, הקוד שלמעלה הופך ל:

    Kotlin

    val bidiFormatter = BidiFormatter.getInstance()
    val suggestion = String.format(
            resources.getString(R.string.did_you_mean),
            bidiFormatter.unicodeWrap(address)
    )
    

    Java

    Resources res = getResources();
    BidiFormatter bidiFormatter = BidiFormatter.getInstance();
    String suggestion = String.format(res.getString(R.string.did_you_mean),
            bidiFormatter.unicodeWrap(address));
    

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

    הערה: ממשקי ה-API החדשים האלה זמינים גם לגרסאות קודמות. של Android דרך התמיכה של Android ספרייה, עם המחלקה BidiFormatter וממשקי API קשורים.

    שירותי נגישות

    טיפול באירועים מרכזיים

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

    בחירת טקסט והעתקה/הדבקה

    עכשיו יש ב-AccessibilityNodeInfo ממשקי API שמאפשרים AccessibilityService כדי לבחור, לגזור, להעתיק ולהדביק של הטקסט בצומת.

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

    לאחר מכן אפשר לגזור או להעתיק באמצעות ACTION_CUT, ACTION_COPY, ולאחר מכן מדביקים באמצעות ACTION_PASTE.

    הערה: ממשקי ה-API החדשים האלה זמינים גם לגרסאות קודמות. של Android דרך התמיכה של Android ספרייה, עם AccessibilityNodeInfoCompat בכיתה.

    הצהרה על תכונות נגישות

    החל מ-Android 4.3, שירות נגישות צריך להצהיר על יכולות נגישות בקובץ המטא-נתונים שלו כדי להשתמש בתכונות נגישות מסוימות. אם אין אפשרות בקובץ המטא-נתונים, התכונה תהיה ללא פעילות. כדי להצהיר על שירות השירות שלכם יכולות נגישות, עליך להשתמש במאפייני XML שתואמים יכולת קבועים ב-AccessibilityServiceInfo בכיתה.

    לדוגמה, אם שירות מסוים לא מבקש את היכולת flagRequestFilterKeyEvents, הוא לא יקבל אירועים מרכזיים.

    בדיקה וניפוי באגים

    בדיקה אוטומטית של ממשק המשתמש

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

    כדי לקבל מופע של UiAutomation, צריך להפעיל את Instrumentation.getUiAutomation(). לפי הסדר כדי שזה יעבוד, צריך לספק את האפשרות -w באמצעות הפקודה instrument כשמריצים את InstrumentationTestCase מ-adb shell.

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

    כדי לצפות בכל האירועים במהלך הבדיקה, צריך ליצור הטמעה של UiAutomation.OnAccessibilityEventListener ולהעביר אותה אל setOnAccessibilityEventListener(). לאחר מכן ממשק ה-listener מקבל קריאה ל-onAccessibilityEvent() בכל פעם שאירוע מתרחש, קבלת אובייקט AccessibilityEvent שמתאר את האירוע.

    יש מגוון פעולות אחרות שממשקי ה-API של UiAutomation חושפים ברמה נמוכה מאוד כדי לעודד פיתוח של כלים לבדיקה של ממשק המשתמש, כמו uiautomator. לדוגמה, UiAutomation יכול גם:

    • החדרת אירועי קלט
    • שינוי כיוון המסך
    • יצירת צילומי מסך

    הדבר החשוב ביותר מבחינת כלים לבדיקת ממשק המשתמש, ממשקי ה-API של UiAutomation פועלים מעבר לגבולות האפליקציה, שלא כמו בגבולות ה-Instrumentation.

    אירועי Systrace לאפליקציות

    מערכת Android 4.3 מוסיפה את המחלקה Trace באמצעות שתי שיטות סטטיות: beginSection() וגם endSection(), שמאפשרות להגדיר בלוקים של קוד שייכללו בדוח ה-systrace. על ידי יצירה של הקוד שניתן למעקב באפליקציה, יומני ה-Systrace מספקים כדי להבין איפה מתרחשת האטה באפליקציה שלכם.

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

    אבטחה

    מאגר מפתחות של Android למפתחות פרטיים של אפליקציות

    מערכת Android מציעה עכשיו ספק אבטחה בהתאמה אישית של Java בKeyStore שנקראת Android Key Store, שמאפשרת ליצור ולשמור מפתחות פרטיים ניתנים לצפייה ולשימוש באפליקציה שלך בלבד. כדי לטעון את 'חנות המפתחות של Android', מעבירים "AndroidKeyStore" עד KeyStore.getInstance().

    כדי לנהל את פרטי הכניסה הפרטיים של האפליקציה ב-Android Key Store, יש ליצור מפתח חדש עם KeyPairGenerator עם KeyPairGeneratorSpec. לדף הראשון כדי לקבל מופע של KeyPairGenerator בקריאה אל getInstance(). ואז להתקשר initialize(), מעבירים אותה מופע של KeyPairGeneratorSpec, ואפשר לקבל באמצעותו KeyPairGeneratorSpec.Builder. לסיום, צריך להתקשר אל generateKeyPair() כדי לקבל את KeyPair.

    אחסון פרטי כניסה לחומרה

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

    הצהרות מניפסט

    תכונות נדרשות שניתנות להצהרה

    הערכים הבאים נתמכים עכשיו ב<uses-feature> כך שתוכלו לוודא שהאפליקציה מותקנת רק במכשירים שמספקים את התכונות שדרושה לאפליקציה.

    FEATURE_APP_WIDGETS
    הצהרה שהאפליקציה שלך מספקת ווידג'ט לאפליקציה ושצריך להתקין אותה רק במכשירים לכלול מסך בית או מיקום דומה שבו המשתמשים יכולים להטמיע ווידג'טים של אפליקציות. דוגמה:
    <uses-feature android:name="android.software.app_widgets" android:required="true" />
    
    FEATURE_HOME_SCREEN
    הצהרה שהאפליקציה פועלת כתחליף למסך הבית ושצריך להתקין אותה רק מכשירים שתומכים באפליקציות של צד שלישי במסך הבית. דוגמה:
    <uses-feature android:name="android.software.home_screen" android:required="true" />
    
    FEATURE_INPUT_METHODS
    הצהרה שהאפליקציה שלך מספקת שיטת קלט מותאמת אישית (מקלדת שפותחה עם InputMethodService) וצריך להתקין אותה רק במכשירים תומכים בשיטות קלט של צד שלישי. דוגמה:
    <uses-feature android:name="android.software.input_methods" android:required="true" />
    
    FEATURE_BLUETOOTH_LE
    הצהרה שהאפליקציה שלך משתמשת בממשקי Bluetooth עם צריכת אנרגיה נמוכה ושצריך להתקין אותה רק במכשירים שיכולים לתקשר עם מכשירים אחרים באמצעות Bluetooth Low Energy. דוגמה:
    <uses-feature android:name="android.software.bluetooth_le" android:required="true" />
    

    הרשאות המשתמשים

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

    BIND_NOTIFICATION_LISTENER_SERVICE
    חובה להשתמש בממשקי ה-API החדשים של NotificationListenerService.
    SEND_RESPOND_VIA_MESSAGE
    נדרש כדי לקבל את ACTION_RESPOND_VIA_MESSAGE בכוונה טובה.

    לתצוגה מפורטת של כל שינויי ה-API ב-Android 4.3 אפשר לעיין במאמר דוח ההבדלים בין ה-API