پلتفرم اندروید ۱۷ شامل تغییرات رفتاری است که ممکن است بر برنامه شما تأثیر بگذارد. تغییرات رفتاری زیر برای همه برنامهها هنگام اجرا در اندروید ۱۷، صرف نظر از targetSdkVersion ، اعمال میشود. شما باید برنامه خود را آزمایش کنید و سپس در صورت لزوم، آن را برای پشتیبانی از این تغییرات، در صورت لزوم، اصلاح کنید.
حتماً فهرست تغییرات رفتاری که فقط بر برنامههای اندروید ۱۷ تأثیر میگذارند را نیز بررسی کنید.
عملکرد اصلی
اندروید ۱۷ (سطح API ۳۷) شامل تغییرات زیر است که قابلیتهای اصلی مختلف سیستم اندروید را اصلاح یا گسترش میدهد.
محدودیتهای حافظه برنامه
Android 17 引入了基于设备总 RAM 的应用内存限制,以便为您的应用和 Android 用户打造更稳定、更确定的环境。在 Android 17 中,系统会保守地设置限制,以建立系统基准,在极端内存泄漏和其他异常情况导致系统范围内的不稳定(导致界面卡顿、耗电过快和应用被终止)之前,针对这些情况采取措施。虽然我们预计此变化对绝大多数应用会话的影响微乎其微,但我们建议您遵循以下内存最佳实践,包括建立内存基准。
您可以通过在 ApplicationExitInfo 中调用 getDescription 来确定应用会话是否受到影响;如果应用受到影响,退出原因将为 REASON_OTHER,说明将包含字符串 "MemoryLimiter:AnonSwap" 以及其他信息。您还可以将 TRIGGER_TYPE_ANOMALY 与基于触发器的分析搭配使用,以获取在达到内存限制时收集的堆转储。
管理应用的内存文档提供的信息可帮助您诊断应用的内存问题并优化其资源消耗。
在内存受限的情况下测试应用的运行情况
您可以使用 Android 调试桥 (adb) 调整或停用任何施加内存限制的设备上的内存限制。shell 命令 am 提供了三个用于调整内存限制的子命令。(这些命令对未施加内存限制的设备没有影响。)
am memory-limiter ignore <uid>|none|allam memory-limiter manual <pid> <limit>|max|noneam memory-limiter status
ignore指示内存限制器忽略部分或全部进程。传递 UID(Android 用户 ID)会指示内存限制器忽略对与该 UID 相关联的所有进程的强制执行。您还可以传递
all(忽略所有应用)或none(不忽略任何应用)。传递none会替换之前对am memory-limiter ignore的任何调用。如果您指示内存限制器忽略某个 UID,您仍然可以通过调用
am memory-limiter manual为应用内的进程应用手动内存限制。manual指示系统对具有指定 PID(进程 ID)的进程施加内存限制。内存限制以整数形式的 MB 数指定;例如,传递
30指定进程的内存限制为 30 MB。传递max会移除相应进程的所有内存限制。 传递none会移除对进程设置的所有手动限制,从而恢复系统的默认限制(如果有)。status报告内存限制器的当前状态。该状态包括对可见进程和非可见进程施加的内存限制。
حریم خصوصی
اندروید ۱۷ شامل تغییرات زیر برای بهبود حریم خصوصی کاربران است.
محافظت از طریق OTP در پیامک
با شروع اندروید ۱۷، اندروید محافظت خود را برای پیامهای متنی حاوی رمزهای عبور یکبار مصرف (OTP) گسترش میدهد.
در نسخههای قبلی اندروید، این محافظت عمدتاً بر روی فرمت SMS Retriever متمرکز بود. تحویل پیامهای حاوی هش SMS Retriever برای اکثر برنامهها به مدت سه ساعت به تأخیر میافتاد. با این حال، برخی از برنامهها (مانند برنامه مدیریت پیشفرض SMS) از این تأخیر معاف بودند و برنامهای که صاحب هش بود نیز از این امر مستثنی بود.
از اندروید ۱۷ به بعد، این محافظت برای پیامهای با فرمت WebOTP نیز اعمال میشود. اگر برنامهای مجوز خواندن پیامکها را داشته باشد اما گیرنده مورد نظر پیام WebOTP نباشد (همانطور که توسط تأیید دامنه تعیین میشود)، پیام تا سه ساعت پس از دریافت پیام برای برنامه قابل دسترسی نیست. این تغییر با هدف بهبود امنیت کاربر و با اطمینان از اینکه فقط برنامههای مرتبط با دامنه ذکر شده در پیام میتوانند کد تأیید را به صورت برنامهنویسی بخوانند، در نظر گرفته شده است.
در طول این تأخیر سه ساعته، پخش SMS_RECEIVED_ACTION متوقف میشود و کوئریهای پایگاه داده ارائه دهنده پیامک فیلتر میشوند. پیام پیامکی پس از تأخیر برای این برنامهها در دسترس است. این تغییر برای همه برنامهها ، صرف نظر از سطح API هدف آنها، اعمال میشود.
برخی از برنامهها مانند برنامه دستیار پیامک پیشفرض، برنامههای همراه دستگاههای متصل و غیره، از این تأخیر معاف هستند. همه برنامههایی که برای استخراج OTP به خواندن پیامهای پیامکی متکی هستند، باید برای اطمینان از عملکرد مداوم، به استفاده از SMS Retriever یا APIهای رضایت کاربر SMS روی آورند.
امنیت
اندروید ۱۷ شامل بهبودهای زیر در امنیت دستگاه و برنامهها است.
طرح منسوخشدهی usesClearTraffic
در نسخههای آینده، قصد داریم عنصر usesCleartextTraffic را منسوخ کنیم. برنامههایی که نیاز به برقراری اتصالات رمزگذاری نشده (HTTP) دارند، باید به استفاده از یک فایل پیکربندی امنیت شبکه مهاجرت کنند، که به شما امکان میدهد مشخص کنید برنامه شما برای برقراری اتصالات cleartext به کدام دامنهها نیاز دارد.
توجه داشته باشید که فایلهای پیکربندی امنیت شبکه فقط در سطوح API 24 و بالاتر پشتیبانی میشوند. اگر برنامه شما حداقل سطح API کمتر از 24 دارد، باید هر دو کار زیر را انجام دهید:
- ویژگی
usesCleartextTrafficرا رویtrueتنظیم کنید. - استفاده از فایل پیکربندی شبکه
اگر حداقل سطح API برنامه شما ۲۴ یا بالاتر است، میتوانید از یک فایل پیکربندی شبکه استفاده کنید و نیازی به تنظیم usesCleartextTraffic ندارید.
محدود کردن مجوزهای ضمنی URI
目前,如果应用启动的 intent 具有 URI,且该 URI 具有操作
ACTION_SEND、ACTION_SEND_MULTIPLE或
ACTION_IMAGE_CAPTURE,则系统会自动向目标应用授予读取和
写入 URI 权限。从 Android 18 开始,系统将
不再自动授予这些权限。因此,我们建议应用明确授予相关 URI 权限,而不是依赖系统授予这些权限。
如需检测应用中这些 intent 的使用情况,请将 StrictMode 与
detectImplicitUriPermissionGrant() 结合使用,以触发违规行为:
Kotlin
val policy = StrictMode.VmPolicy.Builder() .detectImplicitUriPermissionGrant() .penaltyLog() .build() StrictMode.setVmPolicy(policy)
Java
StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() .detectImplicitUriPermissionGrant() .penaltyLog() .build(); StrictMode.setVmPolicy(policy);
或者,您也可以监控包含消息 Please set the grant explicitly in the app 的已记录异常,该消息会在系统隐式设置授予时显示。您可以使用以下 adb 命令监控这些日志:
adb logcat | grep "Please set the grant explicitly in the app"
如需明确授予必要的权限,请将
FLAG_GRANT_READ_URI_PERMISSION标志添加到ACTION_SEND和
ACTION_SEND_MULTIPLEintent:
Kotlin
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
Java
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
对于
ACTION_IMAGE_CAPTURE intent,请同时添加FLAG_GRANT_READ_URI_PERMISSION 和
FLAG_GRANT_WRITE_URI_PERMISSION 标志:
Kotlin
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
Java
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
محدودیتهای فروشگاه کلید در هر برنامه
برنامهها باید از ایجاد تعداد بیش از حد کلید در Android Keystore خودداری کنند، زیرا این یک منبع مشترک برای همه برنامههای روی دستگاه است. از اندروید ۱۷ به بعد، سیستم محدودیتی را برای تعداد کلیدهایی که یک برنامه میتواند داشته باشد، اعمال میکند. این محدودیت برای برنامههای غیرسیستمی که اندروید ۱۷ (سطح API ۳۷) یا بالاتر را هدف قرار میدهند، ۵۰۰۰۰ کلید و برای سایر برنامهها ۲۰۰۰۰۰ کلید است. برنامههای سیستمی صرف نظر از اینکه کدام سطح API را هدف قرار میدهند، محدودیت ۲۰۰۰۰۰ کلید دارند.
اگر برنامهای سعی کند کلیدهایی فراتر از محدودیت ایجاد کند، ایجاد کلید با خطای KeyStoreException با شکست مواجه میشود. رشته پیام این استثنا حاوی اطلاعاتی در مورد محدودیت کلید است. اگر برنامه تابع getNumericErrorCode() را در مورد استثنا فراخوانی کند، مقدار بازگشتی به سطح API مورد نظر برنامه بستگی دارد:
- برنامههایی که اندروید ۱۷ (سطح API ۳۷) یا بالاتر را هدف قرار میدهند:
getNumericErrorCode()مقدار جدیدERROR_TOO_MANY_KEYSرا برمیگرداند. - همه برنامههای دیگر:
getNumericErrorCode()ERROR_INCORRECT_USAGEرا برمیگرداند.
مسدود کردن ترافیک loopback بین پروفایلی
从 Android 17 开始,默认情况下不再允许跨个人资料环回流量。同一个人资料内的环回流量不受影响。 此项变更适用于在 Android 17 或更高版本上运行的所有应用,无论应用以哪个 API 级别为目标平台。
تجربه کاربری و رابط کاربری سیستم
اندروید ۱۷ شامل تغییرات زیر است که برای ایجاد یک تجربه کاربری سازگارتر و شهودیتر در نظر گرفته شدهاند.
بازیابی قابلیت مشاهده پیشفرض IME پس از چرخش
从 Android 17 开始,当设备的配置发生变化(例如,通过旋转)且应用本身未处理此变化时,系统不会恢复之前的 IME 可见性。
如果应用经历了它无法处理的配置更改,并且应用需要在更改后显示键盘,您必须明确请求此行为。您可以通过以下方式之一提出此要求:
- 将
android:windowSoftInputMode属性设置为stateAlwaysVisible。 - 在 activity 的
onCreate()方法中以编程方式请求显示软键盘,或添加onConfigurationChanged()方法。
ورودی انسانی
اندروید ۱۷ شامل تغییرات زیر است که بر نحوه تعامل برنامهها با دستگاههای ورودی انسان مانند صفحهکلید و تاچپد تأثیر میگذارد.
تاچپدها به طور پیشفرض رویدادهای نسبی را هنگام گرفتن اشارهگر نمایش میدهند
از اندروید ۱۷ به بعد، اگر برنامهای با استفاده از View.requestPointerCapture() درخواست ضبط اشارهگر را داشته باشد و کاربر از تاچپد استفاده کند، سیستم حرکت اشارهگر و حرکات پیمایش را از لمسهای کاربر تشخیص میدهد و آنها را به همان روشی که حرکات اشارهگر و چرخ اسکرول از یک ماوس ضبط شده انجام میشود، به برنامه گزارش میدهد. در بیشتر موارد، این امر نیاز برنامههایی که از ماوسهای ضبط شده پشتیبانی میکنند را برای اضافه کردن منطق مدیریت ویژه برای تاچپدها برطرف میکند. برای جزئیات بیشتر، به مستندات View.POINTER_CAPTURE_MODE_RELATIVE مراجعه کنید.
پیش از این، سیستم تلاشی برای تشخیص حرکات از صفحه لمسی نمیکرد و در عوض، مکانهای خام و قطعی انگشت را با فرمتی مشابه لمسهای صفحه لمسی به برنامه تحویل میداد. اگر برنامهای هنوز به این دادههای قطعی نیاز دارد، باید به جای آن، متد جدید View.requestPointerCapture(int) را با View.POINTER_CAPTURE_MODE_ABSOLUTE فراخوانی کند.
رسانه
اندروید ۱۷ شامل تغییرات زیر در رفتار رسانهای است.
تقویت صدای پسزمینه
با شروع اندروید ۱۷، چارچوب صوتی محدودیتهایی را در تعاملات صوتی پسزمینه از جمله پخش صدا، درخواستهای فوکوس صدا و APIهای تغییر صدا اعمال میکند تا اطمینان حاصل شود که این تغییرات عمداً توسط کاربر آغاز میشوند.
اگر برنامه سعی کند APIهای صوتی را در حالی که برنامه در چرخه حیات معتبری نیست، فراخوانی کند، APIهای پخش صدا و تغییر صدا بدون ایجاد استثنا یا ارائه پیام خطا، بیصدا با شکست مواجه میشوند. API فوکوس صوتی با کد نتیجه AUDIOFOCUS_REQUEST_FAILED با شکست مواجه میشود.
برای اطلاعات بیشتر، از جمله استراتژیهای کاهش، به مقاومسازی صدای پسزمینه مراجعه کنید.
اتصال
اندروید ۱۷ شامل تغییرات زیر برای بهبود اتصال دستگاه است.
جفتسازی مجدد خودکار برای از دست رفتن اتصال بلوتوث
اندروید ۱۷ قابلیت جفتسازی مجدد خودکار را معرفی میکند، یک بهبود در سطح سیستم که برای حل خودکار مشکل از دست دادن اتصال بلوتوث طراحی شده است.
پیش از این، اگر یک اتصال از بین میرفت، کاربران مجبور بودند به صورت دستی به تنظیمات بروند تا اتصال را قطع و سپس دوباره وصل کنند. این ویژگی بر اساس بهبود امنیتی اندروید ۱۶ ساخته شده است و به سیستم اجازه میدهد تا اتصالها را در پسزمینه دوباره برقرار کند، بدون اینکه کاربران مجبور باشند به صورت دستی به تنظیمات بروند تا اتصال را قطع و دوباره وصل کنند.
اگرچه اکثر برنامهها نیازی به تغییر کد ندارند، توسعهدهندگان باید از تغییرات رفتاری زیر در پشته بلوتوث آگاه باشند:
- زمینه جفتسازی جدید:
ACTION_PAIRING_REQUESTاکنون شاملEXTRA_PAIRING_CONTEXTاضافی است که به برنامهها اجازه میدهد بین یک درخواست جفتسازی استاندارد و یک تلاش جفتسازی مجدد خودکار توسط سیستم، تمایز قائل شوند. - بهروزرسانیهای مشروط کلید: کلیدهای امنیتی موجود تنها در صورتی جایگزین میشوند که جفتسازی مجدد موفقیتآمیز باشد و اتصال جدید سطح امنیتی پیوند قبلی را برآورده کند یا از آن فراتر رود.
- زمانبندی اینتنت اصلاحشده: اینتنت
ACTION_KEY_MISSINGاکنون فقط در صورتی پخش میشود که تلاش برای جفتسازی مجدد خودکار با شکست مواجه شود. این امر در صورتی که سیستم با موفقیت پیوند را در پسزمینه بازیابی کند، مدیریت خطاهای غیرضروری در برنامه را کاهش میدهد. - اعلان کاربر: سیستم، جفتسازی مجدد را از طریق اعلانها و پنجرههای محاورهای جدید رابط کاربری مدیریت میکند. از کاربران خواسته میشود تا تلاش برای جفتسازی مجدد را تأیید کنند تا از اتصال مجدد مطلع شوند.
تولیدکنندگان دستگاههای جانبی و توسعهدهندگان برنامههای همراه باید تأیید کنند که سختافزار و برنامه به خوبی از پس انتقال اتصال برمیآیند. برای آزمایش این رفتار، با استفاده از یکی از روشهای زیر، از دست دادن اتصال از راه دور را شبیهسازی کنید:
- اطلاعات مربوط به پیوند را به صورت دستی از دستگاه جانبی حذف کنید
- اتصال دستگاه را به صورت دستی از طریق تنظیمات > دستگاههای متصل قطع کنید