בדומה לגרסאות קודמות, Android 16 כולל שינויים בהתנהגות שעשויים להשפיע על האפליקציה שלכם. שינויי ההתנהגות הבאים רלוונטיים רק לאפליקציות שמטרגטות את Android 16 ואילך. אם האפליקציה שלכם מטרגטת את Android מגרסה 16 ואילך, אתם צריכים לשנות את האפליקציה כדי שהיא תתמוך בהתנהגויות האלה, במקרים הרלוונטיים.
חשוב גם לבדוק את רשימת השינויים בהתנהגות שמשפיעים על כל האפליקציות שפועלות ב-Android 16, בלי קשר ל-targetSdkVersion של האפליקציה.
חוויית המשתמש וממשק המשתמש של המערכת
Android 16 (API ברמה 36) כוללת את השינויים הבאים, שנועדו ליצור חוויית משתמש עקבית ואינטואיטיבית יותר.
האפשרות להסיר את התצוגה מקצה לקצה תבוטל
ב-Android 15 נאכף מצב מקצה לקצה באפליקציות שמטרגטות ל-Android 15 (רמת API 35), אבל אפשר להשבית את המצב הזה באפליקציה על ידי הגדרת R.attr#windowOptOutEdgeToEdgeEnforcement ל-true. באפליקציות שמטרגטות ל-Android 16 (רמת API 36), התכונה R.attr#windowOptOutEdgeToEdgeEnforcement הוצאה משימוש והושבתה, ולא ניתן להשבית את התצוגה מקצה לקצה באפליקציה.
- אם האפליקציה מטרגטת ל-Android 16 (רמת API 36) והיא פועלת במכשיר Android 15, התג
R.attr#windowOptOutEdgeToEdgeEnforcementממשיך לפעול. - אם האפליקציה מטרגטת ל-Android 16 (רמת API 36) והיא פועלת במכשיר Android 16, התכונה
R.attr#windowOptOutEdgeToEdgeEnforcementמושבתת.
כדי לבדוק ב-Android 16, מוודאים שהאפליקציה תומכת בתצוגה מקצה לקצה ומסירים את השימוש ב-R.attr#windowOptOutEdgeToEdgeEnforcement כדי שהאפליקציה תתמוך בתצוגה מקצה לקצה גם במכשיר Android 15. הוראות לגבי תמיכה בתצוגה מקצה לקצה מופיעות במאמרים יצירת תצוגות ותצוגות.
כדי להשתמש בתכונה "חיזוי החזרה", צריך לבצע העברה או לבטל את ההסכמה
对于以 Android 16(API 级别 36)或更高版本为目标平台且在 Android 16 或更高版本的设备上运行的应用,预测性返回系统动画(返回主屏幕、跨任务和跨 activity)默认处于启用状态。此外,系统不再调用 onBackPressed,也不再调度 KeyEvent.KEYCODE_BACK。
如果您的应用会拦截返回事件,但您尚未迁移到预测性返回,请更新应用以使用受支持的返回导航 API,或者通过在应用的 AndroidManifest.xml 文件的 <application> 或 <activity> 标记中将 android:enableOnBackInvokedCallback 属性设置为 false 来暂时选择停用。
הוצאה משימוש והשבתה של ממשקי API אלגנטיים לגופנים
באפליקציות שמטרגטות ל-Android 15 (רמת API 35), מאפיין elegantTextHeight TextView מוגדר כ-true כברירת מחדל, והגופן הקומפקטי מוחלף בגופן קריא הרבה יותר. אפשר לשנות את ההגדרה הזו על ידי הגדרת המאפיין elegantTextHeight לערך false.
ב-Android 16, המאפיין elegantTextHeight הוצא משימוש. המערכת תתעלם מהמאפיין הזה ברגע שהאפליקציה תטרגט ל-Android 16. ממשקי ה-API האלה שולטים ב'גופנים של ממשק המשתמש', אבל הם יוצאים משימוש. לכן, צריך להתאים את הפריסות כדי להבטיח עיבוד עקבי של טקסט בעברית, בלאית, במיאנמר, בטמילית, בגוג'ראטית, בקנאדה, במלאיאלאם, באודיה, בטלוגו או בתאילנדית.
ההתנהגות של elegantTextHeight באפליקציות שמטרגטות ל-Android
14 (רמת API 34) ומטה, או באפליקציות שמטרגטות ל-Android 15 (רמת API 35) ששינו את ברירת המחדל על ידי הגדרת המאפיין elegantTextHeight ל-false.
התנהגות elegantTextHeight באפליקציות שמטרגטות ל-Android
16 (רמת API 36), או באפליקציות שמטרגטות ל-Android 15 (רמת API 35) שלא
ביטלו את ברירת המחדל על ידי הגדרת המאפיין elegantTextHeight לערך false.פונקציונליות עיקרית
Android 16 (API ברמה 36) כוללת את השינויים הבאים, שמשנים או מרחיבים יכולות ליבה שונות של מערכת Android.
אופטימיזציה של תזמון פעולה בקצב קבוע
לפני הטירגוט ל-Android 16, אם scheduleAtFixedRate החמיץ ביצוע של משימה כי הוא לא היה במחזור חיים תקין של תהליך, כל הביצועים שהוחמצו מתבצעים באופן מיידי כשהאפליקציה חוזרת למחזור חיים תקין.
כשמטרגטים ל-Android 16, פעולה אחת שהוחמצה של scheduleAtFixedRate תושלם באופן מיידי כשהאפליקציה תחזור למחזור חיים תקין. שינוי ההתנהגות הזה צפוי לשפר את ביצועי האפליקציה. כדאי לבדוק את ההתנהגות הזו באפליקציה כדי לראות אם היא מושפעת.
אפשר גם לבדוק באמצעות מסגרת התאימות לאפליקציות ולהפעיל את הדגל STPE_SKIP_MULTIPLE_MISSED_PERIODIC_TASKS compat.
גורמי צורה של מכשירים
Android 16 (רמת API 36) כוללת את השינויים הבאים באפליקציות כשהן מוצגות במכשירים עם מסך גדול.
פריסות מותאמות
אפליקציות ל-Android פועלות עכשיו במגוון מכשירים (כמו טלפונים, טאבלטים, מכשירים מתקפלים, מחשבים, מכוניות וטלוויזיות) ובמצבי תצוגת חלונות במסכים גדולים (כמו מסך מפוצל וממשק מחשב). לכן, מפתחים צריכים ליצור אפליקציות ל-Android שמותאמות לכל גודל מסך וחלון, בלי קשר לכיוון המסך במכשיר. פרדיגמות כמו הגבלת כיוון המסך והגבלת שינוי הגודל כבר לא מתאימות לעולם של היום, שבו משתמשים במספר מכשירים.
התעלמות מהגבלות על כיוון, שינוי גודל ויחס גובה-רוחב
באפליקציות שמטרגטות ל-Android 16 (רמת API 36), ההגבלות על כיוון, שינוי גודל ויחס גובה-רוחב לא חלות יותר על מסכים עם רוחב מינימלי של 600dp ומעלה. האפליקציות ממלאות את חלון התצוגה, בלי קשר ליחס הגובה-רוחב או להעדפת הכיוון של המשתמש, ולא נעשה שימוש בבפורמט pillarbox.
השינוי הזה מציג התנהגות חדשה של הפלטפורמה. מערכת Android עוברת למודל שבו האפליקציות צריכות להתאים את עצמן לכיוונים, לגדלים של מסכים וליחסי גובה-רוחב שונים. כיוון מסך קבוע או שינוי גודל מוגבל מקשים על התאמת האפליקציה. כדי לספק את חוויית המשתמש הטובה ביותר, צריך להתאים את האפליקציה למצבים שונים.
אפשר גם לבדוק את ההתנהגות הזו באמצעות מסגרת התאימות של האפליקציה והפעלת דגל התאימות UNIVERSAL_RESIZABLE_BY_DEFAULT.
שינויי תוכנה נפוצים שעלולים לגרום לכשלים
התעלמות מהגבלות על כיוון, שינוי גודל ויחס גובה-רוחב עלולה להשפיע על ממשק המשתמש של האפליקציה במכשירים מסוימים, במיוחד על רכיבים שנועדו לפריסות קטנות שמוגבלות לכיוון לאורך: לדוגמה, בעיות כמו פריסות מתוחות ואנימציות ורכיבים מחוץ למסך. הנחות לגבי יחס הגובה-רוחב או הכיוון עלולות לגרום לבעיות חזותיות באפליקציה. מידע נוסף על איך להימנע מבעיות כאלה ולשפר את יכולת ההתאמה של האפליקציה למצבים שונים.
כשמאפשרים סיבוב מכשיר, מתבצעות יותר יצירות מחדש של פעילויות, וזה עלול להוביל לאובדן מצב המשתמש אם הוא לא נשמר כראוי. במאמר שמירת מצבי ממשק המשתמש מוסבר איך לשמור אותם נכון.
פרטי ההטמעה
במכשירים עם מסך גדול במצב מסך מלא ובמצב ריבוי חלונות, המערכת מתעלמת ממאפייני המניפסט וממשקי ה-API של זמן הריצה הבאים:
screenOrientationresizableActivityminAspectRatiomaxAspectRatiosetRequestedOrientation()getRequestedOrientation()
המערכת מתעלמת מהערכים הבאים של screenOrientation, setRequestedOrientation() ו-getRequestedOrientation():
portraitreversePortraitsensorPortraituserPortraitlandscapereverseLandscapesensorLandscapeuserLandscape
לגבי שינוי הגודל של התצוגה, הערכים הבאים לא מושפעים: android:resizeableActivity="false", android:minAspectRatio ו-android:maxAspectRatio.
באפליקציות שמיועדות ל-Android 16 (API ברמה 36), המערכת מתעלמת כברירת מחדל מהגבלות על כיוון האפליקציה, שינוי הגודל ויחס הגובה-רוחב במסכים גדולים. אפשר לבטל את ההתנהגות הזו באופן זמני באפליקציות שעדיין לא מוכנות (וזה יגרום להצבה במצב תאימות, כמו בהתנהגות הקודמת).
חריגים
ההגבלות על כיוון, שינוי גודל ויחס גובה-רוחב ב-Android 16 לא חלות במצבים הבאים:
- משחקים (מבוססים על הדגל של
android:appCategory) - משתמשים שמביעים הסכמה מפורשת לפעולת ברירת המחדל של האפליקציה בהגדרות יחס הגובה-רוחב של המכשיר
- מסכים שקטנים מ-
sw600dp
ביטול זמני של ההסכמה
כדי לבטל את ההסכמה למעקב אחרי פעילות ספציפית, צריך להצהיר על מאפיין המניפסט PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY:
<activity ...>
<property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY" android:value="true" />
...
</activity>
אם יותר מדי חלקים באפליקציה לא מוכנים ל-Android 16, אפשר לבטל את ההסכמה באופן מלא על ידי החלת אותו מאפיין ברמת האפליקציה:
<application ...>
<property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY" android:value="true" />
</application>
בריאות וכושר
Android 16 (API ברמה 36) כוללת את השינויים הבאים שקשורים לנתוני בריאות וכושר.
הרשאות ל"בריאות וכושר"
对于以 Android 16(API 级别 36)或更高版本为目标平台的应用,
BODY_SENSORS 权限使用更精细的权限
under android.permissions.health,which Health Connect
also uses。从 Android 16 开始,凡是以前需要具有 BODY_SENSORS
或 BODY_SENSORS_BACKGROUND 权限的 API,现在都需要获取相应的
android.permissions.health 权限。这会影响以下数据类型、API 和前台服务类型:
HEART_RATE_BPMWear OS 上的健康服务Sensor.TYPE_HEART_RATE来自 Android Sensor ManagerheartRateAccuracy和heartRateBpm(来自 Wear OS 上的ProtoLayout)FOREGROUND_SERVICE_TYPE_HEALTH,其中需要使用相应的android.permission.health权限来代替BODY_SENSORS
如果您的应用使用这些 API,则应请求相应的精细权限:
- 如需在使用期间监测心率、血氧饱和度或体表温度:
请请求
android.permissions.health下的精细权限,例如READ_HEART_RATE,而不是BODY_SENSORS。 - 如需访问后台传感器,请请求
READ_HEALTH_DATA_IN_BACKGROUND,而不是BODY_SENSORS_BACKGROUND。
这些权限与保护对 Health Connect(用于存储健康、 健身和保健数据的 Android 数据存储区)中数据的读取访问权限的权限相同。
移动应用
迁移为使用 READ_HEART_RATE 和其他精细权限的移动应用还必须 声明一项 activity 以显示应用的隐私权政策。这与健康数据共享的要求相同。
קישוריות
Android 16 (רמת API 36) כוללת את השינויים הבאים במערך Bluetooth כדי לשפר את הקישוריות למכשירים היקפיים.
כוונה חדשה לטיפול באובדן של קשרים ושינויים בהצפנה
作为改进了对键值对丢失的处理的一部分,Android 16 还引入了 2 个新 intent,以便应用更好地了解键值对丢失和加密更改。
以 Android 16 为目标平台的应用现在可以:
- 在检测到远程键盘连接丢失时接收
ACTION_KEY_MISSINGintent,以便提供更具信息量的用户反馈并采取适当的措施。 - 每当链接的加密状态发生变化时,都会收到
ACTION_ENCRYPTION_CHANGEintent。这包括加密状态更改、加密算法更改和加密密钥大小更改。如果应用在稍后收到ACTION_ENCRYPTION_CHANGEintent 时成功加密了链接,则必须将该绑定视为已恢复。
适应不同的 OEM 实现
虽然 Android 16 引入了这些新 intent,但其实现和广播可能会因不同的设备制造商 (OEM) 而异。为了确保您的应用在所有设备上都能提供一致且可靠的体验,开发者应设计其绑定丢失处理机制,以妥善适应这些潜在的变化。
我们建议您采用以下应用行为:
如果广播
ACTION_KEY_MISSINGintent:系统会断开 ACL(异步无连接)链接,但会保留设备的配对信息(如此处所述)。
您的应用应将此 intent 用作检测配对丢失的主要信号,并在发起设备忘记或重新配对之前引导用户确认远程设备是否在范围内。
如果设备在收到
ACTION_KEY_MISSING后断开连接,您的应用应谨慎重新连接,因为设备可能已不再与系统绑定。如果未广播
ACTION_KEY_MISSINGintent:ACL 链接将保持连接状态,系统会移除设备的配对信息,与 Android 15 中的行为相同。
在这种情况下,您的应用应继续使用与之前的 Android 版本相同的现有配对丢失处理机制,以检测和管理配对丢失事件。
דרך חדשה להסרת שיוך Bluetooth
现在,以 Android 16 为目标平台的所有应用都可以使用 CompanionDeviceManager 中的公共 API 解除蓝牙设备配对。如果配套设备作为 CDM 关联进行管理,则应用可以在关联的设备上使用新的 removeBond(int) API 触发蓝牙配对的移除。该应用可以通过监听蓝牙设备广播事件 ACTION_BOND_STATE_CHANGED 来监控配对状态变化。
אבטחה
Android 16 (API ברמה 36) כוללת את שינויי האבטחה הבאים.
נעילת גרסה של MediaStore
对于以 Android 16 或更高版本为目标平台的应用,MediaStore#getVersion() 现在将是每个应用的唯一标识。这会从版本字符串中移除标识属性,以防止滥用和用于指纹识别技术。应用不应对此版本的格式做出任何假设。在使用此 API 时,应用应已处理版本变更,并且在大多数情况下无需更改其当前行为,除非开发者尝试推断超出此 API 预期范围的其他信息。
כוונות בטוחות יותר
התכונה Safer Intents היא יוזמת אבטחה רב-שלבית שנועדה לשפר את האבטחה של מנגנון ההחלטה לגבי כוונות ב-Android. המטרה היא להגן על אפליקציות מפני פעולות זדוניות על ידי הוספת בדיקות במהלך עיבוד הכוונות וסינון כוונות שלא עומדות בקריטריונים ספציפיים.
ב-Android 15 התכונה התמקדה באפליקציה השולחת, ועכשיו ב-Android 16, השליטה עוברת לאפליקציה המקבלת, ומאפשרת למפתחים להביע הסכמה לפתרון קפדני של כוונות באמצעות קובץ מניפסט של אפליקציה.
אנחנו מטמיעים שני שינויים מרכזיים:
התאמה של Intents מפורשים למסנן ה-Intent של רכיב היעד: אם Intent מטרגט רכיב באופן מפורש, הוא צריך להתאים למסנן ה-Intent של הרכיב הזה.
אובייקטים מסוג Intent ללא פעולה לא יכולים להתאים למסנן Intent כלשהו: אובייקטים מסוג Intent שלא צוינה להם פעולה לא אמורים להיות מזוהים כמסנן Intent כלשהו.
השינויים האלה חלים רק כשמעורבות כמה אפליקציות, והם לא משפיעים על הטיפול ב-Intent באפליקציה אחת.
השפעה
התכונה היא אופציונלית, ולכן מפתחים צריכים להפעיל אותה באופן מפורש בקובץ מניפסט של אפליקציה כדי שהיא תיכנס לתוקף. לכן, ההשפעה של התכונה תוגבל לאפליקציות שהמפתחים שלהן:
- מודעים לתכונה 'כוונות בטוחות יותר' ולתועלות שלה.
- בוחרים באופן פעיל לשלב באפליקציות שלהם שיטות מחמירות יותר לטיפול בכוונות.
הגישה הזו מאפשרת להצטרף באופן אופציונלי, וכך מצמצמת את הסיכון לפגיעה באפליקציות קיימות שעשויות להסתמך על ההתנהגות הנוכחית של פתרון כוונות ברמת אבטחה נמוכה.
יכול להיות שההשפעה הראשונית ב-Android 16 תהיה מוגבלת, אבל ליוזמת Safer Intents יש תוכנית להשפעה רחבה יותר בגרסאות עתידיות של Android. התוכנית היא שבסופו של דבר, התנהגות ברירת המחדל תהיה זיהוי כוונות מדויק.
התכונה Safer Intents יכולה לשפר באופן משמעותי את האבטחה של מערכת Android, כי היא מקשה על אפליקציות זדוניות לנצל נקודות חולשה במנגנון של פתרון כוונות.
עם זאת, המעבר לביטול ההסכמה ולאכיפה מחייבת צריך להתבצע בזהירות כדי לפתור בעיות אפשריות בתאימות לאפליקציות קיימות.
הטמעה
המפתחים צריכים להפעיל באופן מפורש התאמה מחמירה יותר של Intent באמצעות המאפיין intentMatchingFlags בקובץ המניפסט של האפליקציה.
הנה דוגמה שבה התכונה מופעלת בהסכמה לכל האפליקציה,
אבל מושבתת או שבוטלה בהסכמה במקלט:
<application android:intentMatchingFlags="enforceIntentFilter">
<receiver android:name=".MyBroadcastReceiver" android:exported="true" android:intentMatchingFlags="none">
<intent-filter>
<action android:name="com.example.MY_CUSTOM_ACTION" />
</intent-filter>
<intent-filter>
<action android:name="com.example.MY_ANOTHER_CUSTOM_ACTION" />
</intent-filter>
</receiver>
</application>
מידע נוסף על הדגלים הנתמכים:
| שם ההתרעה | תיאור |
|---|---|
| enforceIntentFilter | התנאי הזה אוכף התאמה מחמירה יותר של כוונות נכנסות |
| ללא | השבתה של כל כללי ההתאמה המיוחדים לכוונות נכנסות. כשמציינים כמה דגלים, ערכים סותרים נפתרים על ידי מתן עדיפות לדגל 'none' |
| allowNullAction | הכלל הזה מרחיב את כללי ההתאמה כדי לאפשר התאמה של כוונות ללא פעולה. הדגל הזה משמש בשילוב עם enforceIntentFilter כדי להשיג התנהגות ספציפית |
בדיקה וניפוי באגים
כשהאכיפה פעילה, האפליקציות אמורות לפעול בצורה תקינה אם האפליקציה שקוראת ל-Intent מילאה את ה-Intent בצורה תקינה.
עם זאת, כוונות חסומות יפעילו הודעות אזהרה ביומן כמו
"Intent does not match component's intent filter:" ו-"Access blocked:"
עם התג "PackageManager."
ההודעות האלה מצביעות על בעיה פוטנציאלית שעלולה להשפיע על האפליקציה ודורשת
טיפול.
מסנן Logcat:
tag=:PackageManager & (message:"Intent does not match component's intent filter:" | message: "Access blocked:")
סינון של קריאות מערכת ל-GPU
为了加固 Mali GPU Surface,我们已在生产版本中屏蔽了已废弃或仅用于 GPU 开发的 Mali GPU IOCTL。 此外,用于 GPU 性能剖析的 IOCTL 已限制为 shell 进程或可调试的应用。如需详细了解平台级政策,请参阅 SAC 更新。
此项变更适用于使用 Mali GPU 的 Pixel 设备(Pixel 6-9)。Arm
已在其 r54p2 release 版本的
Documentation/ioctl-categories.rst 中提供了 IOCTL 的官方分类。此列表将在未来的驱动程序版本中继续维护。
此项变更不会影响受支持的图形 API(包括 Vulkan 和 OpenGL),预计也不会影响开发者或现有应用。 Streamline Performance Analyzer 和 Android GPU 检查器等 GPU 性能剖析工具不会受到影响。
测试
如果您看到类似以下内容的 SELinux 拒绝,则您的应用很可能受到了此项变更的影响:
06-30 10:47:18.617 20360 20360 W roidJUnitRunner: type=1400 audit(0.0:85): avc: denied { ioctl }
for path="/dev/mali0" dev="tmpfs" ino=1188 ioctlcmd=0x8023
scontext=u:r:untrusted_app_25:s0:c512,c768 tcontext=u:object_r:gpu_device:s0 tclass=chr_file
permissive=0 app=com.google.android.selinux.pts
如果您的应用需要使用被屏蔽的 IOCTL,请提交 bug 并将其分配给 android-partner-security@google.com。
常见问题解答
此项政策变更是否适用于所有 OEM? 此项变更将采用选择启用模式,但任何想要使用此加固方法的原始设备制造商(OEM)都可以使用。如需了解如何实现此项变更,请参阅实现文档。
是否必须在 OEM 代码库中进行更改才能实现此项变更,还是默认随新的 AOSP 版本提供? 平台级变更将默认随新的 AOSP 版本提供。供应商可以选择在其代码库中启用此项变更,以便应用此项变更。
SoC 是否负责让 IOCTL 列表保持最新状态?例如,如果我的设备使用 ARM Mali GPU,我是否需要就任何变更与 ARM 联系? 各个 SoC 必须在驱动程序发布后根据设备更新其 IOCTL 列表。 例如,ARM 会在驱动程序更新后更新其发布的 IOCTL 列表。 不过,OEM 应确保将更新纳入其 SEPolicy,并根据需要将任何选定的自定义 IOCTL 添加到列表中。
此项变更是否会自动应用于所有在售 Pixel 设备,还是需要用户执行操作来切换某些内容以应用此项变更? 此项变更适用于所有使用 Mali GPU 的在售 Pixel 设备(Pixel 6-9)。无需用户执行任何操作即可应用此项变更。
使用此政策是否会影响内核驱动程序的性能? 我们已使用 GFXBench 在 Mali GPU 上对此政策进行了测试,未观察到 GPU 性能发生任何可衡量的变化。
IOCTL 列表是否需要与当前的用户空间和内核驱动程序版本保持一致?是,允许的 IOCTL 列表必须与用户空间和内核驱动程序支持的 IOCTL 同步。如果用户空间或内核驱动程序中的 IOCTL 发生更新,则必须更新 SEPolicy IOCTL 列表以进行匹配。
ARM 已将 IOCTL 分类为“受限”/“检测”,但我们希望在生产用例中使用其中的一些 IOCTL,并/或拒绝其他 IOCTL。 各个 OEM/SoC 负责根据其用户空间 Mali 库的配置,决定如何对其使用的 IOCTL 进行分类。 ARM 的列表可用于帮助决定这些内容,但每个 OEM/SoC 的用例可能有所不同。
פרטיות
Android 16 (API ברמה 36) כוללת את השינויים הבאים שקשורים לפרטיות.
הרשאה לגישה לרשת המקומית
具有 INTERNET 权限的任何应用都可以访问局域网中的设备。
这使得应用可以轻松连接到本地设备,但也存在隐私方面的影响,例如形成用户指纹,以及成为位置信息的代理。
本地网络保护项目旨在通过在新的运行时权限后限制对本地网络的访问,来保护用户的隐私。
发布计划
这项变更将分别在 25Q2 和 26Q2 这两个版本之间部署。 开发者必须遵循 25Q2 的相关指南并分享反馈,因为这些保护措施将在后续 Android 版本中强制执行。此外,他们还需要按照以下指南更新依赖于隐式本地网络访问权限的场景,并为用户拒绝和撤消新权限做好准备。
影响
在当前阶段,LNP 是一项选择启用功能,这意味着只有选择启用的应用会受到影响。选择启用阶段的目标是让应用开发者了解应用的哪些部分依赖于隐式本地网络访问权限,以便他们为下一个版本做好权限保护准备。
如果应用使用以下方式访问用户的本地网络,则会受到影响:
- 直接或通过库使用本地网络地址(例如 mDNS 或 SSDP 服务发现协议)上的原始套接字
- 使用可访问本地网络的框架级类(例如 NsdManager)
向本地网络地址发送流量和从本地网络地址接收流量需要本地网络访问权限。下表列出了一些常见情况:
| 应用低级层网络操作 | 需要本地网络权限 |
|---|---|
| 建立出站 TCP 连接 | 是 |
| 接受传入的 TCP 连接 | 是 |
| 发送 UDP 单播、多播、广播 | 是 |
| 接收传入的 UDP 单播、多播、广播 | 是 |
这些限制是在网络堆栈深处实现的,因此适用于所有网络 API。这包括在原生代码或受管理代码中创建的套接字、Cronet 和 OkHttp 等网络库,以及基于这些库实现的任何 API。尝试解析本地网络上的服务(即带有 .local 后缀的服务)将需要本地网络权限。
上述规则的例外情况:
- 如果设备的 DNS 服务器位于本地网络上,则进出该服务器(位于端口 53)的流量不需要本地网络访问权限。
- 使用输出切换器作为其应用内选择器的应用将不需要本地网络权限(更多指南将在 2025 年第 4 季度发布)。
开发者指南(选择启用)
如需选择启用本地网络限制,请执行以下操作:
- 将设备刷写到 25Q2 Beta 3 或更高版本的 build。
- 安装要测试的应用。
在 adb 中切换 Appcompat 标志:
adb shell am compat enable RESTRICT_LOCAL_NETWORK <package_name>重启设备
现在,您的应用对本地网络的访问受到限制,任何访问本地网络的尝试都会导致套接字错误。如果您使用的 API 在应用进程之外执行本地网络操作(例如:NsdManager),在选择启用阶段,这些 API 不会受到影响。
如需恢复访问权限,您必须向应用授予 NEARBY_WIFI_DEVICES 权限。
- 确保应用在其清单中声明了
NEARBY_WIFI_DEVICES权限。 - 依次前往设置 > 应用 > [应用名称] > 权限 > 附近的设备 > 允许。
现在,应用对本地网络的访问权限应该已恢复,并且所有场景都应像选择启用应用之前一样正常运行。
本地网络保护功能开始强制执行后,应用的网络流量将受到以下影响。
| 权限 | 出站 LAN 请求 | 出站/入站互联网请求 | 入站 LAN 请求 |
|---|---|---|---|
| 已授予 | Works | Works | Works |
| 未授予 | 最差排行榜 | Works | 最差排行榜 |
使用以下命令关闭应用兼容性标志
adb shell am compat disable RESTRICT_LOCAL_NETWORK <package_name>
错误
每当调用套接字调用 send 或 send 变体向本地网络地址发送数据时,系统都会向该套接字返回因这些限制而产生的错误。
错误示例:
sendto failed: EPERM (Operation not permitted)
sendto failed: ECONNABORTED (Operation not permitted)
本地网络定义
此项目中的本地网络是指使用支持广播的网络接口(例如 Wi-Fi 或以太网)的 IP 网络,但不包括移动网络 (WWAN) 或 VPN 连接。
以下网络被视为本地网络:
IPv4:
- 169.254.0.0/16 // 链路本地
- 100.64.0.0/10 // CGNAT
- 10.0.0.0/8 // RFC1918
- 172.16.0.0/12 // RFC1918
- 192.168.0.0/16 // RFC1918
IPv6:
- 链路本地
- 直接连接的路线
- Thread 等桩网络
- 多子网(待定)
此外,多播地址 (224.0.0.0/4、ff00::/8) 和 IPv4 广播地址 (255.255.255.255) 也被归类为本地网络地址。
תמונות בבעלות האפליקציה
כשמוצגת בקשה להענקת הרשאות גישה לתמונות ולסרטונים מאפליקציה שתואמת ל-SDK מגרסה 36 ואילך במכשירים עם Android מגרסה 16 ואילך, משתמשים שבוחרים להגביל את הגישה למדיה שנבחרה יראו את כל התמונות שבבעלות האפליקציה שנבחרו מראש בבורר התמונות. המשתמשים יכולים לבטל את הבחירה של כל אחד מהפריטים שנבחרו מראש, וכך לבטל את הגישה של האפליקציה לתמונות ולסרטונים האלה.