مانند نسخه های قبلی، Android 14 شامل تغییرات رفتاری است که ممکن است بر برنامه شما تأثیر بگذارد. تغییرات رفتاری زیر منحصراً برای برنامههایی اعمال میشود که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند. اگر برنامه شما اندروید 14 یا بالاتر را هدف قرار می دهد، باید برنامه خود را تغییر دهید تا در صورت لزوم از این رفتارها به درستی پشتیبانی کند.
حتماً فهرستی از تغییرات رفتاری را نیز مرور کنید که بر همه برنامههای در حال اجرا در Android 14 بدون توجه به targetSdkVersion
برنامه تأثیر میگذارد.
عملکرد اصلی
انواع خدمات پیش زمینه مورد نیاز است
اگر برنامه شما Android 14 (سطح API 34) یا بالاتر را هدف قرار می دهد، باید حداقل یک نوع سرویس پیش زمینه را برای هر سرویس پیش زمینه در برنامه شما مشخص کند. شما باید یک نوع سرویس پیش زمینه را انتخاب کنید که نشان دهنده مورد استفاده برنامه شما باشد. این سیستم انتظار دارد که خدمات پیش زمینه ای که نوع خاصی دارند، مورد استفاده خاص را برآورده کنند.
اگر مورد استفاده در برنامه شما با هیچ یک از این انواع مرتبط نیست، اکیداً توصیه میشود که منطق خود را برای استفاده از WorkManager یا کارهای انتقال داده توسط کاربر تغییر دهید.
اجرای مجوز BLUETOOTH_CONNECT در آداپتور بلوتوث
Android 14 مجوز BLUETOOTH_CONNECT
را هنگام فراخوانی روش BluetoothAdapter
getProfileConnectionState()
برای برنامههایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند، اعمال میکند.
این روش قبلاً به مجوز BLUETOOTH_CONNECT
نیاز داشت، اما اجرا نشد. مطمئن شوید که برنامه شما BLUETOOTH_CONNECT
را در فایل AndroidManifest.xml
برنامه شما همانطور که در قطعه زیر نشان داده شده است، اعلام کرده و بررسی کنید که یک کاربر قبل از تماس با getProfileConnectionState
مجوز را داده است .
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
به روز رسانی OpenJDK 17
Android 14 به کار تازه کردن کتابخانههای اصلی Android ادامه میدهد تا با ویژگیهای جدیدترین نسخه OpenJDK LTS، از جمله بهروزرسانیهای کتابخانه و پشتیبانی از زبان جاوا 17 برای توسعهدهندگان برنامهها و پلتفرمها، هماهنگ شود.
تعدادی از این تغییرات می تواند بر سازگاری برنامه تأثیر بگذارد:
- تغییرات در عبارات منظم : ارجاعات گروه نامعتبر اکنون مجاز نیستند تا معنایی OpenJDK را با دقت بیشتری دنبال کنند. ممکن است موارد جدیدی را مشاهده کنید که در آن یک
IllegalArgumentException
توسط کلاسjava.util.regex.Matcher
پرتاب می شود، بنابراین مطمئن شوید که برنامه خود را برای مناطقی که از عبارات منظم استفاده می کنند آزمایش کنید. برای فعال یا غیرفعال کردن این تغییر در حین آزمایش، پرچمDISALLOW_INVALID_GROUP_REFERENCE
را با استفاده از ابزارهای چارچوب سازگاری تغییر دهید. - مدیریت UUID : متد
java.util.UUID.fromString()
اکنون بررسی های دقیق تری را هنگام تأیید آرگومان ورودی انجام می دهد، بنابراین ممکن است در حین deserialization یکIllegalArgumentException
را مشاهده کنید. برای فعال یا غیرفعال کردن این تغییر در حین آزمایش، پرچمENABLE_STRICT_VALIDATION
را با استفاده از ابزارهای چارچوب سازگاری تغییر دهید. - مشکلات ProGuard : در برخی موارد، افزودن کلاس
java.lang.ClassValue
باعث ایجاد مشکل می شود اگر بخواهید برنامه خود را با استفاده از ProGuard کوچک کنید، مبهم کنید و بهینه کنید. مشکل از یک کتابخانه Kotlin سرچشمه می گیرد که رفتار زمان اجرا را بر اساس اینکهClass.forName("java.lang.ClassValue")
یک کلاس را برمی گرداند یا نه، تغییر می دهد. اگر برنامه شما بر اساس نسخه قدیمیتری از زمان اجرا بدون کلاسjava.lang.ClassValue
در دسترس است، این بهینهسازیها ممکن است متدcomputeValue
را از کلاسهای مشتقشده ازjava.lang.ClassValue
حذف کنند.
JobScheduler رفتار برگشت به تماس و شبکه را تقویت می کند
از زمان معرفی، JobScheduler انتظار دارد برنامه شما در عرض چند ثانیه از onStartJob
یا onStopJob
بازگردد. قبل از اندروید 14، اگر یک کار بیش از حد طولانی شود، متوقف می شود و بی صدا از کار می افتد. اگر برنامه شما Android 14 (سطح API 34) یا بالاتر را هدف قرار دهد و از زمان اعطا شده در رشته اصلی فراتر رود، برنامه یک ANR با پیام خطای «بدون پاسخ به onStartJob
» یا «بدون پاسخ به onStopJob
» راهاندازی میکند. مهاجرت به WorkManager را در نظر بگیرید، که از پردازش ناهمزمان یا انتقال هر کار سنگین به یک رشته پسزمینه پشتیبانی میکند.
JobScheduler
همچنین الزامی را برای اعلام مجوز ACCESS_NETWORK_STATE
در صورت استفاده از محدودیت setRequiredNetworkType
یا setRequiredNetwork
معرفی می کند. اگر برنامه شما مجوز ACCESS_NETWORK_STATE
را هنگام زمانبندی کار اعلام نکند و اندروید 14 یا بالاتر را هدف قرار دهد، منجر به یک SecurityException
میشود.
کاشیها API را راهاندازی میکنند
برای برنامههایی که نسخه ۱۴ و بالاتر را هدف قرار میدهند، TileService#startActivityAndCollapse(Intent)
منسوخ شده است و اکنون هنگام فراخوانی یک استثنا ایجاد میکند. اگر برنامه شما فعالیت ها را از کاشی ها راه اندازی می کند، به جای آن از TileService#startActivityAndCollapse(PendingIntent)
استفاده کنید.
حریم خصوصی
دسترسی جزئی به عکس ها و فیلم ها
Android 14 引入了所选照片访问权限,可让用户授权应用访问其媒体库中的特定图片和视频,而不是授予对指定类型的所有媒体的访问权限。
仅当您的应用以 Android 14(API 级别 34)或更高版本为目标平台时,才会启用此变更。如果您还没有使用照片选择器,建议您在应用中实现该选择器,以便在选择图片和视频时提供一致的体验,同时还可以加强用户隐私保护,而无需请求任何存储权限。
如果您使用存储权限维护自己的图库选择器,并且需要完全控制您的实现,请调整您的实现,以使用新的 READ_MEDIA_VISUAL_USER_SELECTED
权限。如果您的应用不使用新权限,系统会在兼容模式下运行应用。
تجربه کاربری
اعلانهای Intent تمام صفحه را ایمن کنید
在 Android 11(API 级别 30)中,任何应用都可以在手机处于锁定状态时使用 Notification.Builder.setFullScreenIntent
发送全屏 intent。您可以通过在 AndroidManifest 中声明 USE_FULL_SCREEN_INTENT
权限,在应用安装时自动授予此权限。
全屏 intent 通知适用于需要用户立即注意的极高优先级通知,例如用户来电或用户配置的闹钟设置。对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,获准使用此权限的应用仅限于提供通话和闹钟的应用。对于不适合此资料的任何应用,Google Play 商店会撤消其默认的 USE_FULL_SCREEN_INTENT
权限。这些政策变更的截止日期为 2024 年 5 月 31 日。
在用户更新到 Android 14 之前,在手机上安装的应用仍拥有此权限。用户可以开启和关闭此权限。
您可以使用新 API NotificationManager.canUseFullScreenIntent
检查应用是否具有该权限;如果没有,应用可以使用新 intent ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT
启动设置页面,在该页面中,用户可以授予权限。
امنیت
محدودیت برای مقاصد ضمنی و معلق
برای برنامههایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند، Android برنامهها را از ارسال مقاصد ضمنی به اجزای داخلی برنامه به روشهای زیر محدود میکند:
- مقاصد ضمنی فقط به اجزای صادر شده تحویل داده می شوند. برنامهها یا باید از یک قصد صریح برای تحویل به اجزای صادر نشده استفاده کنند یا مؤلفه را بهعنوان صادرشده علامتگذاری کنند.
- اگر یک برنامه یک هدف معلق قابل تغییر ایجاد کند که یک جزء یا بسته را مشخص نمی کند، سیستم یک استثنا ایجاد می کند.
این تغییرات مانع از رهگیری برنامه های مخرب در مقاصد ضمنی می شود که برای استفاده توسط اجزای داخلی برنامه در نظر گرفته شده است.
به عنوان مثال، در اینجا یک فیلتر قصد وجود دارد که می تواند در فایل مانیفست برنامه شما اعلام شود:
<activity
android:name=".AppActivity"
android:exported="false">
<intent-filter>
<action android:name="com.example.action.APP_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
اگر برنامه شما سعی کند این فعالیت را با استفاده از یک هدف ضمنی راه اندازی کند، یک استثنا ActivityNotFoundException
ایجاد می شود:
کاتلین
// Throws an ActivityNotFoundException exception when targeting Android 14. context.startActivity(Intent("com.example.action.APP_ACTION"))
جاوا
// Throws an ActivityNotFoundException exception when targeting Android 14. context.startActivity(new Intent("com.example.action.APP_ACTION"));
برای راه اندازی فعالیت غیرصادراتی، برنامه شما باید به جای آن از یک هدف صریح استفاده کند:
کاتلین
// This makes the intent explicit. val explicitIntent = Intent("com.example.action.APP_ACTION") explicitIntent.apply { package = context.packageName } context.startActivity(explicitIntent)
جاوا
// This makes the intent explicit. Intent explicitIntent = new Intent("com.example.action.APP_ACTION") explicitIntent.setPackage(context.getPackageName()); context.startActivity(explicitIntent);
گیرنده های پخش ثبت شده در زمان اجرا باید رفتار صادراتی را مشخص کنند
برنامهها و سرویسهایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند و از گیرندههای ثبت شده در زمینه استفاده میکنند، باید پرچمی را مشخص کنند تا نشان دهد گیرنده باید به همه برنامههای دیگر دستگاه صادر شود یا نه: به ترتیب RECEIVER_EXPORTED
یا RECEIVER_NOT_EXPORTED
. . این نیاز به محافظت از برنامهها در برابر آسیبپذیریهای امنیتی با استفاده از ویژگیهای این گیرندههای معرفیشده در Android 13 کمک میکند.
استثنا برای گیرنده هایی که فقط پخش سیستم را دریافت می کنند
اگر برنامه شما فقط برای پخشهای سیستمی از طریق روشهای Context#registerReceiver
، مانند Context#registerReceiver()
یک گیرنده را ثبت میکند، پس نباید هنگام ثبت گیرنده پرچمی را مشخص کند.
بارگیری کد پویا ایمن تر
اگر برنامه شما Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهد و از بارگذاری کد پویا (DCL) استفاده میکند، همه فایلهای بارگذاری شده پویا باید بهعنوان فقط خواندنی علامتگذاری شوند. در غیر این صورت، سیستم یک استثنا ایجاد می کند. توصیه میکنیم برنامهها تا حد امکان از بارگذاری پویا کد خودداری کنند ، زیرا انجام این کار خطر آسیبدیدگی یک برنامه با تزریق کد یا دستکاری کد را به شدت افزایش میدهد.
اگر باید کد را به صورت پویا بارگیری کنید، از روش زیر استفاده کنید تا فایل بارگذاری شده پویا (مانند فایل DEX، JAR، یا APK) را بهمحض باز شدن فایل و قبل از نوشتن هر محتوایی فقط خواندنی تنظیم کنید:
کاتلین
val jar = File("DYNAMICALLY_LOADED_FILE.jar") val os = FileOutputStream(jar) os.use { // Set the file to read-only first to prevent race conditions jar.setReadOnly() // Then write the actual file content } val cl = PathClassLoader(jar, parentClassLoader)
جاوا
File jar = new File("DYNAMICALLY_LOADED_FILE.jar"); try (FileOutputStream os = new FileOutputStream(jar)) { // Set the file to read-only first to prevent race conditions jar.setReadOnly(); // Then write the actual file content } catch (IOException e) { ... } PathClassLoader cl = new PathClassLoader(jar, parentClassLoader);
مدیریت فایلهای بارگذاری شده پویا که از قبل وجود دارند
برای جلوگیری از ایجاد استثنا برای فایلهای موجود که به صورت پویا بارگذاری شدهاند، توصیه میکنیم قبل از بارگیری مجدد آنها به صورت پویا در برنامه خود، فایلها را حذف و دوباره ایجاد کنید. همانطور که فایل ها را دوباره ایجاد می کنید، دستورالعمل های قبلی را برای علامت گذاری فایل ها به صورت فقط خواندنی در زمان نوشتن دنبال کنید. همچنین، میتوانید فایلهای موجود را دوباره بهعنوان فقط خواندنی برچسبگذاری کنید، اما در این مورد، اکیداً توصیه میکنیم که ابتدا یکپارچگی فایلها را تأیید کنید (مثلاً با بررسی امضای فایل در برابر یک مقدار قابل اعتماد)، برای کمک به محافظت برنامه شما از اقدامات مخرب
محدودیت های اضافی برای شروع فعالیت ها از پس زمینه
برای برنامههایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند، سیستم زمانی را محدود میکند که برنامهها مجاز به شروع فعالیتها از پسزمینه باشند:
- وقتی یک برنامه با استفاده از
PendingIntent#send()
یا روشهای مشابه، یکPendingIntent
ارسال میکند، اگر برنامه میخواهد امتیازات راهاندازی فعالیت پسزمینه خود را برای شروع هدف معلق اعطا کند، باید آن را انتخاب کند. برای شرکت کردن، برنامه باید یک بستهActivityOptions
باsetPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
ارسال کند. - هنگامی که یک برنامه قابل مشاهده، سرویس برنامه دیگری را که در پسزمینه است با استفاده از روش
bindService()
متصل میکند، برنامه قابل مشاهده اگر میخواهد امتیازات راهاندازی فعالیت پسزمینه خود را به سرویس محدود اعطا کند، اکنون باید شرکت کند. برای شرکت کردن، برنامه باید هنگام فراخوانی متدbindService()
پرچمBIND_ALLOW_ACTIVITY_STARTS
را داشته باشد.
این تغییرات مجموعه محدودیتهای موجود را گسترش میدهد تا با جلوگیری از سوء استفاده برنامههای مخرب از APIها برای شروع فعالیتهای مخرب از پسزمینه، از کاربران محافظت کند.
پیمایش مسیر زیپ
对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,Android 会通过以下方式防止 Zip 路径遍历漏洞:如果 zip 文件条目名称包含“..”或以“/”开头,则 ZipInputStream.getNextEntry()
会抛出 ZipException
。ZipFile(String)
应用可以通过调用 dalvik.system.ZipPathValidator.clearCallback()
选择停用此验证。
رضایت کاربر برای هر جلسه ضبط MediaProjection لازم است
对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,在以下任一情况下,MediaProjection#createVirtualDisplay
会抛出 SecurityException
:
- 您的应用会缓存从
MediaProjectionManager#createScreenCaptureIntent
返回的Intent
,并将其多次传递给MediaProjectionManager#getMediaProjection
。 - 您的应用在同一
MediaProjection
实例上多次调用MediaProjection#createVirtualDisplay
。
您的应用必须在每次捕获会话之前征求用户同意。单次拍摄会话是指对 MediaProjection#createVirtualDisplay
的单次调用,且每个 MediaProjection
实例只能使用一次。
处理配置变更
如果您的应用需要调用 MediaProjection#createVirtualDisplay
来处理配置更改(例如屏幕方向或屏幕尺寸更改),您可以按照以下步骤更新现有 MediaProjection
实例的 VirtualDisplay
:
- 使用新的宽度和高度调用
VirtualDisplay#resize
。 - 为
VirtualDisplay#setSurface
提供具有新宽度和高度的新Surface
。
注册回调
您的应用应注册一个回调,以处理用户不同意继续拍摄会话的情况。为此,请实现 Callback#onStop
并让您的应用发布所有相关资源(例如 VirtualDisplay
和 Surface
)。
如果您的应用未注册此回调,MediaProjection#createVirtualDisplay
会在应用调用此回调时抛出 IllegalStateException
。
محدودیتهای غیر SDK بهروزرسانی شد
Android 14 شامل لیست های به روز شده از رابط های غیر SDK محدود شده بر اساس همکاری با توسعه دهندگان اندروید و آخرین آزمایش داخلی است. در صورت امکان، قبل از اینکه رابطهای غیر SDK را محدود کنیم، مطمئن میشویم که جایگزینهای عمومی در دسترس هستند.
اگر برنامه شما اندروید 14 را هدف قرار نمی دهد، برخی از این تغییرات ممکن است فوراً روی شما تأثیر نگذارند. با این حال، در حالی که در حال حاضر میتوانید از برخی رابطهای غیر SDK ( بسته به سطح API هدف برنامهتان ) استفاده کنید، استفاده از هر روش یا فیلد غیر SDK همیشه خطر شکستن برنامه شما را بالا میبرد.
اگر مطمئن نیستید که برنامه شما از رابط های غیر SDK استفاده می کند، می توانید برنامه خود را آزمایش کنید تا متوجه شوید. اگر برنامه شما به رابطهای غیر SDK متکی است، باید برنامهریزی برای انتقال به جایگزینهای SDK را شروع کنید. با این وجود، میدانیم که برخی از برنامهها دارای موارد استفاده معتبر برای استفاده از رابطهای غیر SDK هستند. اگر نمی توانید جایگزینی برای استفاده از یک رابط غیر SDK برای یک ویژگی در برنامه خود پیدا کنید، باید یک API عمومی جدید درخواست کنید .
如需详细了解此 Android 版本中的变更,请参阅 Android 14 中有关限制非 SDK 接口的更新。如需全面了解有关非 SDK 接口的详细信息,请参阅对非 SDK 接口的限制。
،مانند نسخه های قبلی، Android 14 شامل تغییرات رفتاری است که ممکن است بر برنامه شما تأثیر بگذارد. تغییرات رفتاری زیر منحصراً برای برنامههایی اعمال میشود که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند. اگر برنامه شما اندروید 14 یا بالاتر را هدف قرار می دهد، باید برنامه خود را تغییر دهید تا در صورت لزوم از این رفتارها به درستی پشتیبانی کند.
حتماً فهرستی از تغییرات رفتاری را نیز مرور کنید که بر همه برنامههای در حال اجرا در Android 14 بدون توجه به targetSdkVersion
برنامه تأثیر میگذارد.
عملکرد اصلی
انواع خدمات پیش زمینه مورد نیاز است
اگر برنامه شما Android 14 (سطح API 34) یا بالاتر را هدف قرار می دهد، باید حداقل یک نوع سرویس پیش زمینه را برای هر سرویس پیش زمینه در برنامه شما مشخص کند. شما باید یک نوع سرویس پیش زمینه را انتخاب کنید که نشان دهنده مورد استفاده برنامه شما باشد. این سیستم انتظار دارد که خدمات پیش زمینه ای که نوع خاصی دارند، مورد استفاده خاص را برآورده کنند.
اگر مورد استفاده در برنامه شما با هیچ یک از این انواع مرتبط نیست، اکیداً توصیه میشود که منطق خود را برای استفاده از WorkManager یا کارهای انتقال داده توسط کاربر تغییر دهید.
اجرای مجوز BLUETOOTH_CONNECT در آداپتور بلوتوث
Android 14 مجوز BLUETOOTH_CONNECT
را هنگام فراخوانی روش BluetoothAdapter
getProfileConnectionState()
برای برنامههایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند، اعمال میکند.
این روش قبلاً به مجوز BLUETOOTH_CONNECT
نیاز داشت، اما اجرا نشد. مطمئن شوید که برنامه شما BLUETOOTH_CONNECT
را در فایل AndroidManifest.xml
برنامه شما همانطور که در قطعه زیر نشان داده شده است، اعلام کرده و بررسی کنید که یک کاربر قبل از تماس با getProfileConnectionState
مجوز را داده است .
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
به روز رسانی OpenJDK 17
Android 14 به کار تازه کردن کتابخانههای اصلی Android ادامه میدهد تا با ویژگیهای جدیدترین نسخه OpenJDK LTS، از جمله بهروزرسانیهای کتابخانه و پشتیبانی از زبان جاوا 17 برای توسعهدهندگان برنامهها و پلتفرمها، هماهنگ شود.
تعدادی از این تغییرات می تواند بر سازگاری برنامه تأثیر بگذارد:
- تغییرات در عبارات منظم : ارجاعات گروه نامعتبر اکنون مجاز نیستند تا معنایی OpenJDK را با دقت بیشتری دنبال کنند. ممکن است موارد جدیدی را مشاهده کنید که در آن یک
IllegalArgumentException
توسط کلاسjava.util.regex.Matcher
پرتاب می شود، بنابراین مطمئن شوید که برنامه خود را برای مناطقی که از عبارات منظم استفاده می کنند آزمایش کنید. برای فعال یا غیرفعال کردن این تغییر در حین آزمایش، پرچمDISALLOW_INVALID_GROUP_REFERENCE
را با استفاده از ابزارهای چارچوب سازگاری تغییر دهید. - مدیریت UUID : متد
java.util.UUID.fromString()
اکنون بررسی های دقیق تری را هنگام تأیید آرگومان ورودی انجام می دهد، بنابراین ممکن است در حین deserialization یکIllegalArgumentException
را مشاهده کنید. برای فعال یا غیرفعال کردن این تغییر در حین آزمایش، پرچمENABLE_STRICT_VALIDATION
را با استفاده از ابزارهای چارچوب سازگاری تغییر دهید. - مشکلات ProGuard : در برخی موارد، افزودن کلاس
java.lang.ClassValue
باعث ایجاد مشکل می شود اگر بخواهید برنامه خود را با استفاده از ProGuard کوچک کنید، مبهم کنید و بهینه کنید. مشکل از یک کتابخانه Kotlin سرچشمه می گیرد که رفتار زمان اجرا را بر اساس اینکهClass.forName("java.lang.ClassValue")
یک کلاس را برمی گرداند یا نه، تغییر می دهد. اگر برنامه شما بر اساس نسخه قدیمیتری از زمان اجرا بدون کلاسjava.lang.ClassValue
در دسترس است، این بهینهسازیها ممکن است متدcomputeValue
را از کلاسهای مشتقشده ازjava.lang.ClassValue
حذف کنند.
JobScheduler رفتار برگشت به تماس و شبکه را تقویت می کند
از زمان معرفی، JobScheduler انتظار دارد برنامه شما در عرض چند ثانیه از onStartJob
یا onStopJob
بازگردد. قبل از اندروید 14، اگر یک کار بیش از حد طولانی شود، متوقف می شود و بی صدا از کار می افتد. اگر برنامه شما Android 14 (سطح API 34) یا بالاتر را هدف قرار دهد و از زمان اعطا شده در رشته اصلی فراتر رود، برنامه یک ANR با پیام خطای «بدون پاسخ به onStartJob
» یا «بدون پاسخ به onStopJob
» راهاندازی میکند. مهاجرت به WorkManager را در نظر بگیرید، که از پردازش ناهمزمان یا انتقال هر کار سنگین به یک رشته پسزمینه پشتیبانی میکند.
JobScheduler
همچنین الزامی را برای اعلام مجوز ACCESS_NETWORK_STATE
در صورت استفاده از محدودیت setRequiredNetworkType
یا setRequiredNetwork
معرفی می کند. اگر برنامه شما مجوز ACCESS_NETWORK_STATE
را هنگام زمانبندی کار اعلام نکند و اندروید 14 یا بالاتر را هدف قرار دهد، منجر به یک SecurityException
میشود.
کاشیها API را راهاندازی میکنند
برای برنامههایی که نسخه ۱۴ و بالاتر را هدف قرار میدهند، TileService#startActivityAndCollapse(Intent)
منسوخ شده است و اکنون هنگام فراخوانی یک استثنا ایجاد میکند. اگر برنامه شما فعالیت ها را از کاشی ها راه اندازی می کند، به جای آن از TileService#startActivityAndCollapse(PendingIntent)
استفاده کنید.
حریم خصوصی
دسترسی جزئی به عکس ها و فیلم ها
Android 14 引入了所选照片访问权限,可让用户授权应用访问其媒体库中的特定图片和视频,而不是授予对指定类型的所有媒体的访问权限。
仅当您的应用以 Android 14(API 级别 34)或更高版本为目标平台时,才会启用此变更。如果您还没有使用照片选择器,建议您在应用中实现该选择器,以便在选择图片和视频时提供一致的体验,同时还可以加强用户隐私保护,而无需请求任何存储权限。
如果您使用存储权限维护自己的图库选择器,并且需要完全控制您的实现,请调整您的实现,以使用新的 READ_MEDIA_VISUAL_USER_SELECTED
权限。如果您的应用不使用新权限,系统会在兼容模式下运行应用。
تجربه کاربری
اعلانهای Intent تمام صفحه را ایمن کنید
在 Android 11(API 级别 30)中,任何应用都可以在手机处于锁定状态时使用 Notification.Builder.setFullScreenIntent
发送全屏 intent。您可以通过在 AndroidManifest 中声明 USE_FULL_SCREEN_INTENT
权限,在应用安装时自动授予此权限。
全屏 intent 通知适用于需要用户立即注意的极高优先级通知,例如用户来电或用户配置的闹钟设置。对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,获准使用此权限的应用仅限于提供通话和闹钟的应用。对于不适合此资料的任何应用,Google Play 商店会撤消其默认的 USE_FULL_SCREEN_INTENT
权限。这些政策变更的截止日期为 2024 年 5 月 31 日。
在用户更新到 Android 14 之前,在手机上安装的应用仍拥有此权限。用户可以开启和关闭此权限。
您可以使用新 API NotificationManager.canUseFullScreenIntent
检查应用是否具有该权限;如果没有,应用可以使用新 intent ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT
启动设置页面,在该页面中,用户可以授予权限。
امنیت
محدودیت برای مقاصد ضمنی و معلق
برای برنامههایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند، Android برنامهها را از ارسال مقاصد ضمنی به اجزای داخلی برنامه به روشهای زیر محدود میکند:
- مقاصد ضمنی فقط به اجزای صادر شده تحویل داده می شوند. برنامهها یا باید از یک قصد صریح برای تحویل به اجزای صادر نشده استفاده کنند یا مؤلفه را بهعنوان صادرشده علامتگذاری کنند.
- اگر یک برنامه یک هدف معلق قابل تغییر ایجاد کند که یک جزء یا بسته را مشخص نمی کند، سیستم یک استثنا ایجاد می کند.
این تغییرات مانع از رهگیری برنامه های مخرب در مقاصد ضمنی می شود که برای استفاده توسط اجزای داخلی برنامه در نظر گرفته شده است.
به عنوان مثال، در اینجا یک فیلتر قصد وجود دارد که می تواند در فایل مانیفست برنامه شما اعلام شود:
<activity
android:name=".AppActivity"
android:exported="false">
<intent-filter>
<action android:name="com.example.action.APP_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
اگر برنامه شما سعی کند این فعالیت را با استفاده از یک هدف ضمنی راه اندازی کند، یک استثنا ActivityNotFoundException
ایجاد می شود:
کاتلین
// Throws an ActivityNotFoundException exception when targeting Android 14. context.startActivity(Intent("com.example.action.APP_ACTION"))
جاوا
// Throws an ActivityNotFoundException exception when targeting Android 14. context.startActivity(new Intent("com.example.action.APP_ACTION"));
برای راه اندازی فعالیت غیرصادراتی، برنامه شما باید به جای آن از یک هدف صریح استفاده کند:
کاتلین
// This makes the intent explicit. val explicitIntent = Intent("com.example.action.APP_ACTION") explicitIntent.apply { package = context.packageName } context.startActivity(explicitIntent)
جاوا
// This makes the intent explicit. Intent explicitIntent = new Intent("com.example.action.APP_ACTION") explicitIntent.setPackage(context.getPackageName()); context.startActivity(explicitIntent);
گیرنده های پخش ثبت شده در زمان اجرا باید رفتار صادراتی را مشخص کنند
برنامهها و سرویسهایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند و از گیرندههای ثبت شده در زمینه استفاده میکنند، باید پرچمی را مشخص کنند تا نشان دهد گیرنده باید به همه برنامههای دیگر دستگاه صادر شود یا نه: به ترتیب RECEIVER_EXPORTED
یا RECEIVER_NOT_EXPORTED
. . این نیاز به محافظت از برنامهها در برابر آسیبپذیریهای امنیتی با استفاده از ویژگیهای این گیرندههای معرفیشده در Android 13 کمک میکند.
استثنا برای گیرنده هایی که فقط پخش سیستم را دریافت می کنند
اگر برنامه شما فقط برای پخشهای سیستمی از طریق روشهای Context#registerReceiver
، مانند Context#registerReceiver()
یک گیرنده را ثبت میکند، پس نباید هنگام ثبت گیرنده پرچمی را مشخص کند.
بارگیری کد پویا ایمن تر
اگر برنامه شما Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهد و از بارگذاری کد پویا (DCL) استفاده میکند، همه فایلهای بارگذاری شده پویا باید بهعنوان فقط خواندنی علامتگذاری شوند. در غیر این صورت، سیستم یک استثنا ایجاد می کند. توصیه میکنیم برنامهها تا حد امکان از بارگذاری پویا کد خودداری کنند ، زیرا انجام این کار خطر آسیبدیدگی یک برنامه با تزریق کد یا دستکاری کد را به شدت افزایش میدهد.
اگر باید کد را به صورت پویا بارگیری کنید، از روش زیر استفاده کنید تا فایل بارگذاری شده پویا (مانند فایل DEX، JAR، یا APK) را بهمحض باز شدن فایل و قبل از نوشتن هر محتوایی فقط خواندنی تنظیم کنید:
کاتلین
val jar = File("DYNAMICALLY_LOADED_FILE.jar") val os = FileOutputStream(jar) os.use { // Set the file to read-only first to prevent race conditions jar.setReadOnly() // Then write the actual file content } val cl = PathClassLoader(jar, parentClassLoader)
جاوا
File jar = new File("DYNAMICALLY_LOADED_FILE.jar"); try (FileOutputStream os = new FileOutputStream(jar)) { // Set the file to read-only first to prevent race conditions jar.setReadOnly(); // Then write the actual file content } catch (IOException e) { ... } PathClassLoader cl = new PathClassLoader(jar, parentClassLoader);
مدیریت فایلهای بارگذاری شده پویا که از قبل وجود دارند
برای جلوگیری از ایجاد استثنا برای فایلهای موجود که به صورت پویا بارگذاری شدهاند، توصیه میکنیم قبل از بارگیری مجدد آنها به صورت پویا در برنامه خود، فایلها را حذف و دوباره ایجاد کنید. همانطور که فایل ها را دوباره ایجاد می کنید، دستورالعمل های قبلی را برای علامت گذاری فایل ها به صورت فقط خواندنی در زمان نوشتن دنبال کنید. همچنین، میتوانید فایلهای موجود را دوباره بهعنوان فقط خواندنی برچسبگذاری کنید، اما در این مورد، اکیداً توصیه میکنیم که ابتدا یکپارچگی فایلها را تأیید کنید (مثلاً با بررسی امضای فایل در برابر یک مقدار قابل اعتماد)، برای کمک به محافظت برنامه شما از اقدامات مخرب
محدودیت های اضافی برای شروع فعالیت ها از پس زمینه
برای برنامههایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند، سیستم زمانی را محدود میکند که برنامهها مجاز به شروع فعالیتها از پسزمینه باشند:
- وقتی یک برنامه با استفاده از
PendingIntent#send()
یا روشهای مشابه، یکPendingIntent
ارسال میکند، اگر برنامه میخواهد امتیازات راهاندازی فعالیت پسزمینه خود را برای شروع هدف معلق اعطا کند، باید آن را انتخاب کند. برای شرکت کردن، برنامه باید یک بستهActivityOptions
باsetPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
ارسال کند. - هنگامی که یک برنامه قابل مشاهده، سرویس برنامه دیگری را که در پسزمینه است با استفاده از روش
bindService()
متصل میکند، برنامه قابل مشاهده اگر میخواهد امتیازات راهاندازی فعالیت پسزمینه خود را به سرویس محدود اعطا کند، اکنون باید شرکت کند. برای شرکت کردن، برنامه باید هنگام فراخوانی متدbindService()
پرچمBIND_ALLOW_ACTIVITY_STARTS
را داشته باشد.
این تغییرات مجموعه محدودیتهای موجود را گسترش میدهد تا با جلوگیری از سوء استفاده برنامههای مخرب از APIها برای شروع فعالیتهای مخرب از پسزمینه، از کاربران محافظت کند.
پیمایش مسیر زیپ
对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,Android 会通过以下方式防止 Zip 路径遍历漏洞:如果 zip 文件条目名称包含“..”或以“/”开头,则 ZipInputStream.getNextEntry()
会抛出 ZipException
。ZipFile(String)
应用可以通过调用 dalvik.system.ZipPathValidator.clearCallback()
选择停用此验证。
رضایت کاربر برای هر جلسه ضبط MediaProjection لازم است
对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,在以下任一情况下,MediaProjection#createVirtualDisplay
会抛出 SecurityException
:
- 您的应用会缓存从
MediaProjectionManager#createScreenCaptureIntent
返回的Intent
,并将其多次传递给MediaProjectionManager#getMediaProjection
。 - 您的应用在同一
MediaProjection
实例上多次调用MediaProjection#createVirtualDisplay
。
您的应用必须在每次捕获会话之前征求用户同意。单次拍摄会话是指对 MediaProjection#createVirtualDisplay
的单次调用,且每个 MediaProjection
实例只能使用一次。
处理配置变更
如果您的应用需要调用 MediaProjection#createVirtualDisplay
来处理配置更改(例如屏幕方向或屏幕尺寸更改),您可以按照以下步骤更新现有 MediaProjection
实例的 VirtualDisplay
:
- 使用新的宽度和高度调用
VirtualDisplay#resize
。 - 为
VirtualDisplay#setSurface
提供具有新宽度和高度的新Surface
。
注册回调
您的应用应注册一个回调,以处理用户不同意继续拍摄会话的情况。为此,请实现 Callback#onStop
并让您的应用发布所有相关资源(例如 VirtualDisplay
和 Surface
)。
如果您的应用未注册此回调,MediaProjection#createVirtualDisplay
会在应用调用此回调时抛出 IllegalStateException
。
محدودیتهای غیر SDK بهروزرسانی شد
Android 14 شامل لیست های به روز شده از رابط های غیر SDK محدود شده بر اساس همکاری با توسعه دهندگان اندروید و آخرین آزمایش داخلی است. در صورت امکان، قبل از اینکه رابطهای غیر SDK را محدود کنیم، مطمئن میشویم که جایگزینهای عمومی در دسترس هستند.
اگر برنامه شما اندروید 14 را هدف قرار نمی دهد، برخی از این تغییرات ممکن است فوراً روی شما تأثیر نگذارند. با این حال، در حالی که در حال حاضر میتوانید از برخی رابطهای غیر SDK ( بسته به سطح API هدف برنامهتان ) استفاده کنید، استفاده از هر روش یا فیلد غیر SDK همیشه خطر شکستن برنامه شما را بالا میبرد.
اگر مطمئن نیستید که برنامه شما از رابط های غیر SDK استفاده می کند، می توانید برنامه خود را آزمایش کنید تا متوجه شوید. اگر برنامه شما به رابطهای غیر SDK متکی است، باید برنامهریزی برای انتقال به جایگزینهای SDK را شروع کنید. با این وجود، میدانیم که برخی از برنامهها دارای موارد استفاده معتبر برای استفاده از رابطهای غیر SDK هستند. اگر نمی توانید جایگزینی برای استفاده از یک رابط غیر SDK برای یک ویژگی در برنامه خود پیدا کنید، باید یک API عمومی جدید درخواست کنید .
如需详细了解此 Android 版本中的变更,请参阅 Android 14 中有关限制非 SDK 接口的更新。如需全面了解有关非 SDK 接口的详细信息,请参阅对非 SDK 接口的限制。
،مانند نسخه های قبلی، Android 14 شامل تغییرات رفتاری است که ممکن است بر برنامه شما تأثیر بگذارد. تغییرات رفتاری زیر منحصراً برای برنامههایی اعمال میشود که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند. اگر برنامه شما اندروید 14 یا بالاتر را هدف قرار می دهد، باید برنامه خود را تغییر دهید تا در صورت لزوم از این رفتارها به درستی پشتیبانی کند.
حتماً فهرستی از تغییرات رفتاری را نیز مرور کنید که بر همه برنامههای در حال اجرا در Android 14 بدون توجه به targetSdkVersion
برنامه تأثیر میگذارد.
عملکرد اصلی
انواع خدمات پیش زمینه مورد نیاز است
اگر برنامه شما Android 14 (سطح API 34) یا بالاتر را هدف قرار می دهد، باید حداقل یک نوع سرویس پیش زمینه را برای هر سرویس پیش زمینه در برنامه شما مشخص کند. شما باید یک نوع سرویس پیش زمینه را انتخاب کنید که نشان دهنده مورد استفاده برنامه شما باشد. این سیستم انتظار دارد که خدمات پیش زمینه ای که نوع خاصی دارند، مورد استفاده خاص را برآورده کنند.
اگر مورد استفاده در برنامه شما با هیچ یک از این انواع مرتبط نیست، اکیداً توصیه میشود که منطق خود را برای استفاده از WorkManager یا کارهای انتقال داده توسط کاربر تغییر دهید.
اجرای مجوز BLUETOOTH_CONNECT در آداپتور بلوتوث
Android 14 مجوز BLUETOOTH_CONNECT
را هنگام فراخوانی روش BluetoothAdapter
getProfileConnectionState()
برای برنامههایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند، اعمال میکند.
این روش قبلاً به مجوز BLUETOOTH_CONNECT
نیاز داشت، اما اجرا نشد. مطمئن شوید که برنامه شما BLUETOOTH_CONNECT
را در فایل AndroidManifest.xml
برنامه شما همانطور که در قطعه زیر نشان داده شده است، اعلام کرده و بررسی کنید که یک کاربر قبل از تماس با getProfileConnectionState
مجوز را داده است .
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
به روز رسانی OpenJDK 17
Android 14 به کار تازه کردن کتابخانههای اصلی Android ادامه میدهد تا با ویژگیهای جدیدترین نسخه OpenJDK LTS، از جمله بهروزرسانیهای کتابخانه و پشتیبانی از زبان جاوا 17 برای توسعهدهندگان برنامهها و پلتفرمها، هماهنگ شود.
تعدادی از این تغییرات می تواند بر سازگاری برنامه تأثیر بگذارد:
- تغییرات در عبارات منظم : ارجاعات گروه نامعتبر اکنون مجاز نیستند تا معنایی OpenJDK را با دقت بیشتری دنبال کنند. ممکن است موارد جدیدی را مشاهده کنید که در آن یک
IllegalArgumentException
توسط کلاسjava.util.regex.Matcher
پرتاب می شود، بنابراین مطمئن شوید که برنامه خود را برای مناطقی که از عبارات منظم استفاده می کنند آزمایش کنید. برای فعال یا غیرفعال کردن این تغییر در حین آزمایش، پرچمDISALLOW_INVALID_GROUP_REFERENCE
را با استفاده از ابزارهای چارچوب سازگاری تغییر دهید. - مدیریت UUID : متد
java.util.UUID.fromString()
اکنون بررسی های دقیق تری را هنگام تأیید آرگومان ورودی انجام می دهد، بنابراین ممکن است در حین deserialization یکIllegalArgumentException
را مشاهده کنید. برای فعال یا غیرفعال کردن این تغییر در حین آزمایش، پرچمENABLE_STRICT_VALIDATION
را با استفاده از ابزارهای چارچوب سازگاری تغییر دهید. - مشکلات ProGuard : در برخی موارد، افزودن کلاس
java.lang.ClassValue
باعث ایجاد مشکل می شود اگر بخواهید برنامه خود را با استفاده از ProGuard کوچک کنید، مبهم کنید و بهینه کنید. مشکل از یک کتابخانه Kotlin سرچشمه می گیرد که رفتار زمان اجرا را بر اساس اینکهClass.forName("java.lang.ClassValue")
یک کلاس را برمی گرداند یا نه، تغییر می دهد. اگر برنامه شما بر اساس نسخه قدیمیتری از زمان اجرا بدون کلاسjava.lang.ClassValue
در دسترس است، این بهینهسازیها ممکن است متدcomputeValue
را از کلاسهای مشتقشده ازjava.lang.ClassValue
حذف کنند.
JobScheduler رفتار برگشت به تماس و شبکه را تقویت می کند
از زمان معرفی، JobScheduler انتظار دارد برنامه شما در عرض چند ثانیه از onStartJob
یا onStopJob
بازگردد. قبل از اندروید 14، اگر یک کار بیش از حد طولانی شود، متوقف می شود و بی صدا از کار می افتد. اگر برنامه شما Android 14 (سطح API 34) یا بالاتر را هدف قرار دهد و از زمان اعطا شده در رشته اصلی فراتر رود، برنامه یک ANR با پیام خطای «بدون پاسخ به onStartJob
» یا «بدون پاسخ به onStopJob
» راهاندازی میکند. مهاجرت به WorkManager را در نظر بگیرید، که از پردازش ناهمزمان یا انتقال هر کار سنگین به یک رشته پسزمینه پشتیبانی میکند.
JobScheduler
همچنین الزامی را برای اعلام مجوز ACCESS_NETWORK_STATE
در صورت استفاده از محدودیت setRequiredNetworkType
یا setRequiredNetwork
معرفی می کند. اگر برنامه شما مجوز ACCESS_NETWORK_STATE
را هنگام زمانبندی کار اعلام نکند و اندروید 14 یا بالاتر را هدف قرار دهد، منجر به یک SecurityException
میشود.
کاشیها API را راهاندازی میکنند
برای برنامههایی که نسخه ۱۴ و بالاتر را هدف قرار میدهند، TileService#startActivityAndCollapse(Intent)
منسوخ شده است و اکنون هنگام فراخوانی یک استثنا ایجاد میکند. اگر برنامه شما فعالیت ها را از کاشی ها راه اندازی می کند، به جای آن از TileService#startActivityAndCollapse(PendingIntent)
استفاده کنید.
حریم خصوصی
دسترسی جزئی به عکس ها و فیلم ها
Android 14 引入了所选照片访问权限,可让用户授权应用访问其媒体库中的特定图片和视频,而不是授予对指定类型的所有媒体的访问权限。
仅当您的应用以 Android 14(API 级别 34)或更高版本为目标平台时,才会启用此变更。如果您还没有使用照片选择器,建议您在应用中实现该选择器,以便在选择图片和视频时提供一致的体验,同时还可以加强用户隐私保护,而无需请求任何存储权限。
如果您使用存储权限维护自己的图库选择器,并且需要完全控制您的实现,请调整您的实现,以使用新的 READ_MEDIA_VISUAL_USER_SELECTED
权限。如果您的应用不使用新权限,系统会在兼容模式下运行应用。
تجربه کاربری
اعلانهای Intent تمام صفحه را ایمن کنید
在 Android 11(API 级别 30)中,任何应用都可以在手机处于锁定状态时使用 Notification.Builder.setFullScreenIntent
发送全屏 intent。您可以通过在 AndroidManifest 中声明 USE_FULL_SCREEN_INTENT
权限,在应用安装时自动授予此权限。
全屏 intent 通知适用于需要用户立即注意的极高优先级通知,例如用户来电或用户配置的闹钟设置。对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,获准使用此权限的应用仅限于提供通话和闹钟的应用。对于不适合此资料的任何应用,Google Play 商店会撤消其默认的 USE_FULL_SCREEN_INTENT
权限。这些政策变更的截止日期为 2024 年 5 月 31 日。
在用户更新到 Android 14 之前,在手机上安装的应用仍拥有此权限。用户可以开启和关闭此权限。
您可以使用新 API NotificationManager.canUseFullScreenIntent
检查应用是否具有该权限;如果没有,应用可以使用新 intent ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT
启动设置页面,在该页面中,用户可以授予权限。
امنیت
محدودیت برای مقاصد ضمنی و معلق
برای برنامههایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند، Android برنامهها را از ارسال مقاصد ضمنی به اجزای داخلی برنامه به روشهای زیر محدود میکند:
- مقاصد ضمنی فقط به اجزای صادر شده تحویل داده می شوند. برنامهها یا باید از یک قصد صریح برای تحویل به اجزای صادر نشده استفاده کنند یا مؤلفه را بهعنوان صادرشده علامتگذاری کنند.
- اگر یک برنامه یک هدف معلق قابل تغییر ایجاد کند که یک جزء یا بسته را مشخص نمی کند، سیستم یک استثنا ایجاد می کند.
این تغییرات مانع از رهگیری برنامه های مخرب در مقاصد ضمنی می شود که برای استفاده توسط اجزای داخلی برنامه در نظر گرفته شده است.
به عنوان مثال، در اینجا یک فیلتر قصد وجود دارد که می تواند در فایل مانیفست برنامه شما اعلام شود:
<activity
android:name=".AppActivity"
android:exported="false">
<intent-filter>
<action android:name="com.example.action.APP_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
اگر برنامه شما سعی کند این فعالیت را با استفاده از یک هدف ضمنی راه اندازی کند، یک استثنا ActivityNotFoundException
ایجاد می شود:
کاتلین
// Throws an ActivityNotFoundException exception when targeting Android 14. context.startActivity(Intent("com.example.action.APP_ACTION"))
جاوا
// Throws an ActivityNotFoundException exception when targeting Android 14. context.startActivity(new Intent("com.example.action.APP_ACTION"));
برای راه اندازی فعالیت غیرصادراتی، برنامه شما باید به جای آن از یک هدف صریح استفاده کند:
کاتلین
// This makes the intent explicit. val explicitIntent = Intent("com.example.action.APP_ACTION") explicitIntent.apply { package = context.packageName } context.startActivity(explicitIntent)
جاوا
// This makes the intent explicit. Intent explicitIntent = new Intent("com.example.action.APP_ACTION") explicitIntent.setPackage(context.getPackageName()); context.startActivity(explicitIntent);
گیرنده های پخش ثبت شده در زمان اجرا باید رفتار صادراتی را مشخص کنند
برنامهها و سرویسهایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند و از گیرندههای ثبت شده در زمینه استفاده میکنند، باید پرچمی را مشخص کنند تا نشان دهد گیرنده باید به همه برنامههای دیگر دستگاه صادر شود یا نه: به ترتیب RECEIVER_EXPORTED
یا RECEIVER_NOT_EXPORTED
. . این نیاز به محافظت از برنامهها در برابر آسیبپذیریهای امنیتی با استفاده از ویژگیهای این گیرندههای معرفیشده در Android 13 کمک میکند.
استثنا برای گیرنده هایی که فقط پخش سیستم را دریافت می کنند
اگر برنامه شما فقط برای پخشهای سیستمی از طریق روشهای Context#registerReceiver
، مانند Context#registerReceiver()
یک گیرنده را ثبت میکند، پس نباید هنگام ثبت گیرنده پرچمی را مشخص کند.
بارگیری کد پویا ایمن تر
اگر برنامه شما Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهد و از بارگذاری کد پویا (DCL) استفاده میکند، همه فایلهای بارگذاری شده پویا باید بهعنوان فقط خواندنی علامتگذاری شوند. در غیر این صورت، سیستم یک استثنا ایجاد می کند. توصیه میکنیم برنامهها تا حد امکان از بارگذاری پویا کد خودداری کنند ، زیرا انجام این کار خطر آسیبدیدگی یک برنامه با تزریق کد یا دستکاری کد را به شدت افزایش میدهد.
اگر باید کد را به صورت پویا بارگیری کنید، از روش زیر استفاده کنید تا فایل بارگذاری شده پویا (مانند فایل DEX، JAR، یا APK) را بهمحض باز شدن فایل و قبل از نوشتن هر محتوایی فقط خواندنی تنظیم کنید:
کاتلین
val jar = File("DYNAMICALLY_LOADED_FILE.jar") val os = FileOutputStream(jar) os.use { // Set the file to read-only first to prevent race conditions jar.setReadOnly() // Then write the actual file content } val cl = PathClassLoader(jar, parentClassLoader)
جاوا
File jar = new File("DYNAMICALLY_LOADED_FILE.jar"); try (FileOutputStream os = new FileOutputStream(jar)) { // Set the file to read-only first to prevent race conditions jar.setReadOnly(); // Then write the actual file content } catch (IOException e) { ... } PathClassLoader cl = new PathClassLoader(jar, parentClassLoader);
مدیریت فایلهای بارگذاری شده پویا که از قبل وجود دارند
برای جلوگیری از ایجاد استثنا برای فایلهای موجود که به صورت پویا بارگذاری شدهاند، توصیه میکنیم قبل از بارگیری مجدد آنها به صورت پویا در برنامه خود، فایلها را حذف و دوباره ایجاد کنید. همانطور که فایل ها را دوباره ایجاد می کنید، دستورالعمل های قبلی را برای علامت گذاری فایل ها به صورت فقط خواندنی در زمان نوشتن دنبال کنید. همچنین، میتوانید فایلهای موجود را دوباره بهعنوان فقط خواندنی برچسبگذاری کنید، اما در این مورد، اکیداً توصیه میکنیم که ابتدا یکپارچگی فایلها را تأیید کنید (مثلاً با بررسی امضای فایل در برابر یک مقدار قابل اعتماد)، برای کمک به محافظت برنامه شما از اقدامات مخرب
محدودیت های اضافی برای شروع فعالیت ها از پس زمینه
برای برنامههایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند، سیستم زمانی را محدود میکند که برنامهها مجاز به شروع فعالیتها از پسزمینه باشند:
- وقتی یک برنامه با استفاده از
PendingIntent#send()
یا روشهای مشابه، یکPendingIntent
ارسال میکند، اگر برنامه میخواهد امتیازات راهاندازی فعالیت پسزمینه خود را برای شروع هدف معلق اعطا کند، باید آن را انتخاب کند. برای شرکت کردن، برنامه باید یک بستهActivityOptions
باsetPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
ارسال کند. - هنگامی که یک برنامه قابل مشاهده، سرویس برنامه دیگری را که در پسزمینه است با استفاده از روش
bindService()
متصل میکند، برنامه قابل مشاهده اگر میخواهد امتیازات راهاندازی فعالیت پسزمینه خود را به سرویس محدود اعطا کند، اکنون باید شرکت کند. برای شرکت کردن، برنامه باید هنگام فراخوانی متدbindService()
پرچمBIND_ALLOW_ACTIVITY_STARTS
را داشته باشد.
این تغییرات مجموعه محدودیتهای موجود را گسترش میدهد تا با جلوگیری از سوء استفاده برنامههای مخرب از APIها برای شروع فعالیتهای مخرب از پسزمینه، از کاربران محافظت کند.
پیمایش مسیر زیپ
对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,Android 会通过以下方式防止 Zip 路径遍历漏洞:如果 zip 文件条目名称包含“..”或以“/”开头,则 ZipInputStream.getNextEntry()
会抛出 ZipException
。ZipFile(String)
应用可以通过调用 dalvik.system.ZipPathValidator.clearCallback()
选择停用此验证。
رضایت کاربر برای هر جلسه ضبط MediaProjection لازم است
对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,在以下任一情况下,MediaProjection#createVirtualDisplay
会抛出 SecurityException
:
- 您的应用会缓存从
MediaProjectionManager#createScreenCaptureIntent
返回的Intent
,并将其多次传递给MediaProjectionManager#getMediaProjection
。 - 您的应用在同一
MediaProjection
实例上多次调用MediaProjection#createVirtualDisplay
。
您的应用必须在每次捕获会话之前征求用户同意。单次拍摄会话是指对 MediaProjection#createVirtualDisplay
的单次调用,且每个 MediaProjection
实例只能使用一次。
处理配置变更
如果您的应用需要调用 MediaProjection#createVirtualDisplay
来处理配置更改(例如屏幕方向或屏幕尺寸更改),您可以按照以下步骤更新现有 MediaProjection
实例的 VirtualDisplay
:
- 使用新的宽度和高度调用
VirtualDisplay#resize
。 - 为
VirtualDisplay#setSurface
提供具有新宽度和高度的新Surface
。
注册回调
您的应用应注册一个回调,以处理用户不同意继续拍摄会话的情况。为此,请实现 Callback#onStop
并让您的应用发布所有相关资源(例如 VirtualDisplay
和 Surface
)。
如果您的应用未注册此回调,MediaProjection#createVirtualDisplay
会在应用调用此回调时抛出 IllegalStateException
。
محدودیتهای غیر SDK بهروزرسانی شد
Android 14 شامل لیست های به روز شده از رابط های غیر SDK محدود شده بر اساس همکاری با توسعه دهندگان اندروید و آخرین آزمایش داخلی است. در صورت امکان، قبل از اینکه رابطهای غیر SDK را محدود کنیم، مطمئن میشویم که جایگزینهای عمومی در دسترس هستند.
اگر برنامه شما اندروید 14 را هدف قرار نمی دهد، برخی از این تغییرات ممکن است فوراً روی شما تأثیر نگذارند. با این حال، در حالی که در حال حاضر میتوانید از برخی رابطهای غیر SDK ( بسته به سطح API هدف برنامهتان ) استفاده کنید، استفاده از هر روش یا فیلد غیر SDK همیشه خطر شکستن برنامه شما را بالا میبرد.
اگر مطمئن نیستید که برنامه شما از رابط های غیر SDK استفاده می کند، می توانید برنامه خود را آزمایش کنید تا متوجه شوید. اگر برنامه شما به رابطهای غیر SDK متکی است، باید برنامهریزی برای انتقال به جایگزینهای SDK را شروع کنید. با این وجود، میدانیم که برخی از برنامهها دارای موارد استفاده معتبر برای استفاده از رابطهای غیر SDK هستند. اگر نمی توانید جایگزینی برای استفاده از یک رابط غیر SDK برای یک ویژگی در برنامه خود پیدا کنید، باید یک API عمومی جدید درخواست کنید .
如需详细了解此 Android 版本中的变更,请参阅 Android 14 中有关限制非 SDK 接口的更新。如需全面了解有关非 SDK 接口的详细信息,请参阅对非 SDK 接口的限制。
،مانند نسخه های قبلی، Android 14 شامل تغییرات رفتاری است که ممکن است بر برنامه شما تأثیر بگذارد. تغییرات رفتاری زیر منحصراً برای برنامههایی اعمال میشود که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند. اگر برنامه شما اندروید 14 یا بالاتر را هدف قرار می دهد، باید برنامه خود را تغییر دهید تا در صورت لزوم از این رفتارها به درستی پشتیبانی کند.
حتماً فهرستی از تغییرات رفتاری را نیز مرور کنید که بر همه برنامههای در حال اجرا در Android 14 بدون توجه به targetSdkVersion
برنامه تأثیر میگذارد.
عملکرد اصلی
انواع خدمات پیش زمینه مورد نیاز است
اگر برنامه شما Android 14 (سطح API 34) یا بالاتر را هدف قرار می دهد، باید حداقل یک نوع سرویس پیش زمینه را برای هر سرویس پیش زمینه در برنامه شما مشخص کند. شما باید یک نوع سرویس پیش زمینه را انتخاب کنید که نشان دهنده مورد استفاده برنامه شما باشد. این سیستم انتظار دارد که خدمات پیش زمینه ای که نوع خاصی دارند، مورد استفاده خاص را برآورده کنند.
اگر مورد استفاده در برنامه شما با هیچ یک از این انواع مرتبط نیست، اکیداً توصیه میشود که منطق خود را برای استفاده از WorkManager یا کارهای انتقال داده توسط کاربر تغییر دهید.
اجرای مجوز BLUETOOTH_CONNECT در آداپتور بلوتوث
Android 14 مجوز BLUETOOTH_CONNECT
را هنگام فراخوانی روش BluetoothAdapter
getProfileConnectionState()
برای برنامههایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند، اعمال میکند.
این روش قبلاً به مجوز BLUETOOTH_CONNECT
نیاز داشت، اما اجرا نشد. مطمئن شوید که برنامه شما BLUETOOTH_CONNECT
را در فایل AndroidManifest.xml
برنامه شما همانطور که در قطعه زیر نشان داده شده است، اعلام کرده و بررسی کنید که یک کاربر قبل از تماس با getProfileConnectionState
مجوز را داده است .
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
به روز رسانی OpenJDK 17
Android 14 به کار تازه کردن کتابخانههای اصلی Android ادامه میدهد تا با ویژگیهای جدیدترین نسخه OpenJDK LTS، از جمله بهروزرسانیهای کتابخانه و پشتیبانی از زبان جاوا 17 برای توسعهدهندگان برنامهها و پلتفرمها، هماهنگ شود.
تعدادی از این تغییرات می تواند بر سازگاری برنامه تأثیر بگذارد:
- تغییرات در عبارات منظم : ارجاعات گروه نامعتبر اکنون مجاز نیستند تا معنایی OpenJDK را با دقت بیشتری دنبال کنند. ممکن است موارد جدیدی را مشاهده کنید که در آن یک
IllegalArgumentException
توسط کلاسjava.util.regex.Matcher
پرتاب می شود، بنابراین مطمئن شوید که برنامه خود را برای مناطقی که از عبارات منظم استفاده می کنند آزمایش کنید. برای فعال یا غیرفعال کردن این تغییر در حین آزمایش، پرچمDISALLOW_INVALID_GROUP_REFERENCE
را با استفاده از ابزارهای چارچوب سازگاری تغییر دهید. - مدیریت UUID : متد
java.util.UUID.fromString()
اکنون بررسی های دقیق تری را هنگام تأیید آرگومان ورودی انجام می دهد، بنابراین ممکن است در حین deserialization یکIllegalArgumentException
را مشاهده کنید. برای فعال یا غیرفعال کردن این تغییر در حین آزمایش، پرچمENABLE_STRICT_VALIDATION
را با استفاده از ابزارهای چارچوب سازگاری تغییر دهید. - مشکلات ProGuard : در برخی موارد، افزودن کلاس
java.lang.ClassValue
باعث ایجاد مشکل می شود اگر بخواهید برنامه خود را با استفاده از ProGuard کوچک کنید، مبهم کنید و بهینه کنید. مشکل از یک کتابخانه Kotlin سرچشمه می گیرد که رفتار زمان اجرا را بر اساس اینکهClass.forName("java.lang.ClassValue")
یک کلاس را برمی گرداند یا نه، تغییر می دهد. اگر برنامه شما بر اساس نسخه قدیمیتری از زمان اجرا بدون کلاسjava.lang.ClassValue
در دسترس است، این بهینهسازیها ممکن است متدcomputeValue
را از کلاسهای مشتقشده ازjava.lang.ClassValue
حذف کنند.
JobScheduler رفتار برگشت به تماس و شبکه را تقویت می کند
از زمان معرفی، JobScheduler انتظار دارد برنامه شما در عرض چند ثانیه از onStartJob
یا onStopJob
بازگردد. قبل از اندروید 14، اگر یک کار بیش از حد طولانی شود، متوقف می شود و بی صدا از کار می افتد. اگر برنامه شما Android 14 (سطح API 34) یا بالاتر را هدف قرار دهد و از زمان اعطا شده در رشته اصلی فراتر رود، برنامه یک ANR با پیام خطای «بدون پاسخ به onStartJob
» یا «بدون پاسخ به onStopJob
» راهاندازی میکند. مهاجرت به WorkManager را در نظر بگیرید، که از پردازش ناهمزمان یا انتقال هر کار سنگین به یک رشته پسزمینه پشتیبانی میکند.
JobScheduler
همچنین الزامی را برای اعلام مجوز ACCESS_NETWORK_STATE
در صورت استفاده از محدودیت setRequiredNetworkType
یا setRequiredNetwork
معرفی می کند. اگر برنامه شما مجوز ACCESS_NETWORK_STATE
را هنگام زمانبندی کار اعلام نکند و اندروید 14 یا بالاتر را هدف قرار دهد، منجر به یک SecurityException
میشود.
کاشیها API را راهاندازی میکنند
برای برنامههایی که نسخه ۱۴ و بالاتر را هدف قرار میدهند، TileService#startActivityAndCollapse(Intent)
منسوخ شده است و اکنون هنگام فراخوانی یک استثنا ایجاد میکند. اگر برنامه شما فعالیت ها را از کاشی ها راه اندازی می کند، به جای آن از TileService#startActivityAndCollapse(PendingIntent)
استفاده کنید.
حریم خصوصی
دسترسی جزئی به عکس ها و فیلم ها
Android 14 引入了所选照片访问权限,可让用户授权应用访问其媒体库中的特定图片和视频,而不是授予对指定类型的所有媒体的访问权限。
仅当您的应用以 Android 14(API 级别 34)或更高版本为目标平台时,才会启用此变更。如果您还没有使用照片选择器,建议您在应用中实现该选择器,以便在选择图片和视频时提供一致的体验,同时还可以加强用户隐私保护,而无需请求任何存储权限。
如果您使用存储权限维护自己的图库选择器,并且需要完全控制您的实现,请调整您的实现,以使用新的 READ_MEDIA_VISUAL_USER_SELECTED
权限。如果您的应用不使用新权限,系统会在兼容模式下运行应用。
تجربه کاربری
اعلانهای Intent تمام صفحه را ایمن کنید
在 Android 11(API 级别 30)中,任何应用都可以在手机处于锁定状态时使用 Notification.Builder.setFullScreenIntent
发送全屏 intent。您可以通过在 AndroidManifest 中声明 USE_FULL_SCREEN_INTENT
权限,在应用安装时自动授予此权限。
全屏 intent 通知适用于需要用户立即注意的极高优先级通知,例如用户来电或用户配置的闹钟设置。对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,获准使用此权限的应用仅限于提供通话和闹钟的应用。对于不适合此资料的任何应用,Google Play 商店会撤消其默认的 USE_FULL_SCREEN_INTENT
权限。这些政策变更的截止日期为 2024 年 5 月 31 日。
在用户更新到 Android 14 之前,在手机上安装的应用仍拥有此权限。用户可以开启和关闭此权限。
您可以使用新 API NotificationManager.canUseFullScreenIntent
检查应用是否具有该权限;如果没有,应用可以使用新 intent ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT
启动设置页面,在该页面中,用户可以授予权限。
امنیت
محدودیت برای مقاصد ضمنی و معلق
برای برنامههایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند، Android برنامهها را از ارسال مقاصد ضمنی به اجزای داخلی برنامه به روشهای زیر محدود میکند:
- مقاصد ضمنی فقط به اجزای صادر شده تحویل داده می شوند. برنامهها یا باید از یک قصد صریح برای تحویل به اجزای صادر نشده استفاده کنند یا مؤلفه را بهعنوان صادرشده علامتگذاری کنند.
- اگر یک برنامه یک هدف معلق قابل تغییر ایجاد کند که یک جزء یا بسته را مشخص نمی کند، سیستم یک استثنا ایجاد می کند.
این تغییرات مانع از رهگیری برنامه های مخرب در مقاصد ضمنی می شود که برای استفاده توسط اجزای داخلی برنامه در نظر گرفته شده است.
به عنوان مثال، در اینجا یک فیلتر قصد وجود دارد که می تواند در فایل مانیفست برنامه شما اعلام شود:
<activity
android:name=".AppActivity"
android:exported="false">
<intent-filter>
<action android:name="com.example.action.APP_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
اگر برنامه شما سعی کند این فعالیت را با استفاده از یک هدف ضمنی راه اندازی کند، یک استثنا ActivityNotFoundException
ایجاد می شود:
کاتلین
// Throws an ActivityNotFoundException exception when targeting Android 14. context.startActivity(Intent("com.example.action.APP_ACTION"))
جاوا
// Throws an ActivityNotFoundException exception when targeting Android 14. context.startActivity(new Intent("com.example.action.APP_ACTION"));
برای راه اندازی فعالیت غیرصادراتی، برنامه شما باید به جای آن از یک هدف صریح استفاده کند:
کاتلین
// This makes the intent explicit. val explicitIntent = Intent("com.example.action.APP_ACTION") explicitIntent.apply { package = context.packageName } context.startActivity(explicitIntent)
جاوا
// This makes the intent explicit. Intent explicitIntent = new Intent("com.example.action.APP_ACTION") explicitIntent.setPackage(context.getPackageName()); context.startActivity(explicitIntent);
گیرنده های پخش ثبت شده در زمان اجرا باید رفتار صادراتی را مشخص کنند
برنامهها و سرویسهایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند و از گیرندههای ثبت شده در زمینه استفاده میکنند، باید پرچمی را مشخص کنند تا نشان دهد گیرنده باید به همه برنامههای دیگر دستگاه صادر شود یا نه: به ترتیب RECEIVER_EXPORTED
یا RECEIVER_NOT_EXPORTED
. . این نیاز به محافظت از برنامهها در برابر آسیبپذیریهای امنیتی با استفاده از ویژگیهای این گیرندههای معرفیشده در Android 13 کمک میکند.
استثنا برای گیرنده هایی که فقط پخش سیستم را دریافت می کنند
اگر برنامه شما فقط برای پخشهای سیستمی از طریق روشهای Context#registerReceiver
، مانند Context#registerReceiver()
یک گیرنده را ثبت میکند، پس نباید هنگام ثبت گیرنده پرچمی را مشخص کند.
بارگیری کد پویا ایمن تر
اگر برنامه شما Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهد و از بارگذاری کد پویا (DCL) استفاده میکند، همه فایلهای بارگذاری شده پویا باید بهعنوان فقط خواندنی علامتگذاری شوند. در غیر این صورت، سیستم یک استثنا ایجاد می کند. توصیه میکنیم برنامهها تا حد امکان از بارگذاری پویا کد خودداری کنند ، زیرا انجام این کار خطر آسیبدیدگی یک برنامه با تزریق کد یا دستکاری کد را به شدت افزایش میدهد.
اگر باید کد را به صورت پویا بارگیری کنید، از روش زیر استفاده کنید تا فایل بارگذاری شده پویا (مانند فایل DEX، JAR، یا APK) را بهمحض باز شدن فایل و قبل از نوشتن هر محتوایی فقط خواندنی تنظیم کنید:
کاتلین
val jar = File("DYNAMICALLY_LOADED_FILE.jar") val os = FileOutputStream(jar) os.use { // Set the file to read-only first to prevent race conditions jar.setReadOnly() // Then write the actual file content } val cl = PathClassLoader(jar, parentClassLoader)
جاوا
File jar = new File("DYNAMICALLY_LOADED_FILE.jar"); try (FileOutputStream os = new FileOutputStream(jar)) { // Set the file to read-only first to prevent race conditions jar.setReadOnly(); // Then write the actual file content } catch (IOException e) { ... } PathClassLoader cl = new PathClassLoader(jar, parentClassLoader);
مدیریت فایلهای بارگذاری شده پویا که از قبل وجود دارند
برای جلوگیری از ایجاد استثنا برای فایلهای موجود که به صورت پویا بارگذاری شدهاند، توصیه میکنیم قبل از بارگیری مجدد آنها به صورت پویا در برنامه خود، فایلها را حذف و دوباره ایجاد کنید. همانطور که فایل ها را دوباره ایجاد می کنید، دستورالعمل های قبلی را برای علامت گذاری فایل ها به صورت فقط خواندنی در زمان نوشتن دنبال کنید. همچنین، میتوانید فایلهای موجود را دوباره بهعنوان فقط خواندنی برچسبگذاری کنید، اما در این مورد، اکیداً توصیه میکنیم که ابتدا یکپارچگی فایلها را تأیید کنید (مثلاً با بررسی امضای فایل در برابر یک مقدار قابل اعتماد)، برای کمک به محافظت برنامه شما از اقدامات مخرب
محدودیت های اضافی برای شروع فعالیت ها از پس زمینه
برای برنامههایی که Android 14 (سطح API 34) یا بالاتر را هدف قرار میدهند، سیستم زمانی را محدود میکند که برنامهها مجاز به شروع فعالیتها از پسزمینه باشند:
- وقتی یک برنامه با استفاده از
PendingIntent#send()
یا روشهای مشابه، یکPendingIntent
ارسال میکند، اگر برنامه میخواهد امتیازات راهاندازی فعالیت پسزمینه خود را برای شروع هدف معلق اعطا کند، باید آن را انتخاب کند. برای شرکت کردن، برنامه باید یک بستهActivityOptions
باsetPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
ارسال کند. - هنگامی که یک برنامه قابل مشاهده، سرویس برنامه دیگری را که در پسزمینه است با استفاده از روش
bindService()
متصل میکند، برنامه قابل مشاهده اگر میخواهد امتیازات راهاندازی فعالیت پسزمینه خود را به سرویس محدود اعطا کند، اکنون باید شرکت کند. برای شرکت کردن، برنامه باید هنگام فراخوانی متدbindService()
پرچمBIND_ALLOW_ACTIVITY_STARTS
را داشته باشد.
این تغییرات مجموعه محدودیتهای موجود را گسترش میدهد تا با جلوگیری از سوء استفاده برنامههای مخرب از APIها برای شروع فعالیتهای مخرب از پسزمینه، از کاربران محافظت کند.
پیمایش مسیر زیپ
对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,Android 会通过以下方式防止 Zip 路径遍历漏洞:如果 zip 文件条目名称包含“..”或以“/”开头,则 ZipInputStream.getNextEntry()
会抛出 ZipException
。ZipFile(String)
应用可以通过调用 dalvik.system.ZipPathValidator.clearCallback()
选择停用此验证。
رضایت کاربر برای هر جلسه ضبط MediaProjection لازم است
对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,在以下任一情况下,MediaProjection#createVirtualDisplay
会抛出 SecurityException
:
- 您的应用会缓存从
MediaProjectionManager#createScreenCaptureIntent
返回的Intent
,并将其多次传递给MediaProjectionManager#getMediaProjection
。 - 您的应用在同一
MediaProjection
实例上多次调用MediaProjection#createVirtualDisplay
。
您的应用必须在每次捕获会话之前征求用户同意。单次拍摄会话是指对 MediaProjection#createVirtualDisplay
的单次调用,且每个 MediaProjection
实例只能使用一次。
处理配置变更
如果您的应用需要调用 MediaProjection#createVirtualDisplay
来处理配置更改(例如屏幕方向或屏幕尺寸更改),您可以按照以下步骤更新现有 MediaProjection
实例的 VirtualDisplay
:
- 使用新的宽度和高度调用
VirtualDisplay#resize
。 - 为
VirtualDisplay#setSurface
提供具有新宽度和高度的新Surface
。
注册回调
您的应用应注册一个回调,以处理用户不同意继续拍摄会话的情况。为此,请实现 Callback#onStop
并让您的应用发布所有相关资源(例如 VirtualDisplay
和 Surface
)。
如果您的应用未注册此回调,MediaProjection#createVirtualDisplay
会在应用调用此回调时抛出 IllegalStateException
。
محدودیتهای غیر SDK بهروزرسانی شد
Android 14 شامل لیست های به روز شده از رابط های غیر SDK محدود شده بر اساس همکاری با توسعه دهندگان اندروید و آخرین آزمایش داخلی است. در صورت امکان، قبل از اینکه رابطهای غیر SDK را محدود کنیم، مطمئن میشویم که جایگزینهای عمومی در دسترس هستند.
اگر برنامه شما اندروید 14 را هدف قرار نمی دهد، برخی از این تغییرات ممکن است فوراً روی شما تأثیر نگذارند. با این حال، در حالی که در حال حاضر میتوانید از برخی رابطهای غیر SDK ( بسته به سطح API هدف برنامهتان ) استفاده کنید، استفاده از هر روش یا فیلد غیر SDK همیشه خطر شکستن برنامه شما را بالا میبرد.
اگر مطمئن نیستید که برنامه شما از رابط های غیر SDK استفاده می کند، می توانید برنامه خود را آزمایش کنید تا متوجه شوید. اگر برنامه شما به رابطهای غیر SDK متکی است، باید برنامهریزی برای انتقال به جایگزینهای SDK را شروع کنید. با این وجود، میدانیم که برخی از برنامهها دارای موارد استفاده معتبر برای استفاده از رابطهای غیر SDK هستند. اگر نمی توانید جایگزینی برای استفاده از یک رابط غیر SDK برای یک ویژگی در برنامه خود پیدا کنید، باید یک API عمومی جدید درخواست کنید .
如需详细了解此 Android 版本中的变更,请参阅 Android 14 中有关限制非 SDK 接口的更新。如需全面了解有关非 SDK 接口的详细信息,请参阅对非 SDK 接口的限制。