पिछले रिलीज़ की तरह ही, Android 15 में भी ऐप्लिकेशन के काम करने के तरीके में बदलाव किए गए हैं. इन बदलावों का आपके ऐप्लिकेशन पर असर पड़ सकता है. ऐप्लिकेशन के काम करने के तरीके में ये बदलाव, सिर्फ़ उन ऐप्लिकेशन पर लागू होते हैं जो Android 15 या इसके बाद के वर्शन को टारगेट करते हैं. अगर आपका ऐप्लिकेशन Android 15 या उसके बाद के वर्शन को टारगेट कर रहा है, तो आपको अपने ऐप्लिकेशन में बदलाव करना चाहिए, ताकि जहां भी लागू हो वहां इन बदलावों का सही तरीके से इस्तेमाल किया जा सके.
Android 15 पर काम करने वाले सभी ऐप्लिकेशन पर असर डालने वाले बदलावों की सूची भी देखना न भूलें. भले ही, आपके ऐप्लिकेशन का targetSdkVersion
कुछ भी हो.
मुख्य फ़ंक्शन
Android 15 में, Android सिस्टम की कई मुख्य सुविधाओं में बदलाव किया गया है या उन्हें बेहतर बनाया गया है.
फ़ोरग्राउंड सेवाओं में हुए बदलाव
हम Android 15 में फ़ोरग्राउंड सेवाओं में ये बदलाव कर रहे हैं.
- डेटा सिंक करने वाली फ़ोरग्राउंड सेवा के टाइम आउट का व्यवहार
- मीडिया प्रोसेस करने वाली नई फ़ोरग्राउंड सेवा का टाइप
- फ़ोरग्राउंड सेवाएं लॉन्च करने वाले
BOOT_COMPLETED
ब्रॉडकास्ट रिसीवर पर पाबंदियां - ऐप्लिकेशन के पास
SYSTEM_ALERT_WINDOW
अनुमति होने पर, फ़ोरग्राउंड सेवाएं शुरू करने से जुड़ी पाबंदियां
डेटा सिंक करने वाली फ़ोरग्राउंड सेवा के टाइम आउट का व्यवहार
Android 15 में, dataSync
के लिए टाइम आउट का नया तरीका जोड़ा गया है. यह तरीका, Android 15 (एपीआई लेवल 35) या उसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन के लिए है. यह व्यवहार,
mediaProcessing
फ़ोरग्राउंड सेवा के नए टाइप पर भी लागू होता है.
सिस्टम, किसी ऐप्लिकेशन की dataSync
सेवाओं को 24 घंटे में कुल छह घंटे तक चलने की अनुमति देता है. इसके बाद, सिस्टम चल रही सेवा के Service.onTimeout(int, int)
तरीके को कॉल करता है. इसे Android 15 में लॉन्च किया गया था. इस दौरान, सेवा के पास Service.stopSelf()
को कॉल करने के लिए कुछ सेकंड होते हैं. Service.onTimeout()
को कॉल करने के बाद, सेवा को फ़ोरग्राउंड सेवा नहीं माना जाता. अगर सेवा Service.stopSelf()
को कॉल नहीं करती है, तो सिस्टम में कोई इंटरनल अपवाद दिखता है. अपवाद को Logcat में इस मैसेज के साथ लॉग किया जाता है:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type dataSync did not stop within its timeout: [component name]"
इस बदलाव की वजह से होने वाली समस्याओं से बचने के लिए, इनमें से एक या एक से ज़्यादा काम किए जा सकते हैं:
- अपनी सेवा में
Service.onTimeout(int, int)
का नया तरीका लागू करें. जब आपके ऐप्लिकेशन को कॉलबैक मिल जाए, तोstopSelf()
को कुछ सेकंड के अंदर कॉल करना न भूलें. (अगर ऐप्लिकेशन को तुरंत बंद नहीं किया जाता है, तो सिस्टम गड़बड़ी का मैसेज जनरेट करता है.) - पक्का करें कि आपके ऐप्लिकेशन की
dataSync
सेवाएं, 24 घंटे में कुल छह घंटे से ज़्यादा न चलें. ऐसा तब तक नहीं होगा, जब तक उपयोगकर्ता ऐप्लिकेशन के साथ इंटरैक्ट करके, टाइमर को रीसेट नहीं करता. - सीधे उपयोगकर्ता के साथ इंटरैक्शन होने पर ही,
dataSync
फ़ोरग्राउंड सेवाएं शुरू करें. सेवा शुरू होने के समय, आपका ऐप्लिकेशन फ़ोरग्राउंड में होता है. इसलिए, ऐप्लिकेशन के बैकग्राउंड में चलने के बाद, आपकी सेवा को पूरे छह घंटे तक चालू रखा जाता है. dataSync
फ़ोरग्राउंड सेवा का इस्तेमाल करने के बजाय, किसी अन्य एपीआई का इस्तेमाल करें.
अगर आपके ऐप्लिकेशन की dataSync
फ़ोरग्राउंड सेवाएं पिछले 24 में छह घंटे तक चली हैं, तो आपके पास dataSync
की दूसरी फ़ोरग्राउंड सेवा शुरू करने का विकल्प नहीं है. जब तक उपयोगकर्ता आपके ऐप्लिकेशन को फ़ोरग्राउंड में न ले जाए (इससे टाइमर रीसेट हो जाता है). अगर कोई दूसरी dataSync
फ़ोरग्राउंड सेवा शुरू करने की कोशिश की जाती है, तो सिस्टम ForegroundServiceStartNotAllowedException
को गड़बड़ी का मैसेज दिखाता है. जैसे, "dataSync टाइप की फ़ोरग्राउंड सेवा के लिए, समयसीमा पहले ही खत्म हो चुकी है".
टेस्ट करना
अपने ऐप्लिकेशन के व्यवहार की जांच करने के लिए, डेटा सिंक टाइम आउट की सुविधा चालू की जा सकती है. भले ही, आपका ऐप्लिकेशन Android 15 को टारगेट न करता हो. हालांकि, यह ज़रूरी है कि ऐप्लिकेशन Android 15 वाले डिवाइस पर चल रहा हो. टाइम आउट की सुविधा चालू करने के लिए, यह adb
कमांड चलाएं:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
टाइम आउट की अवधि में बदलाव भी किया जा सकता है. इससे यह जांचना आसान हो जाता है कि
तय सीमा पूरी होने पर, आपका ऐप्लिकेशन कैसे काम करता है. टाइम आउट की नई अवधि सेट करने के लिए, यह adb
कमांड चलाएं:
adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds
मीडिया प्रोसेस करने वाली नई फ़ोरग्राउंड सेवा का टाइप
Android 15 में, फ़ोरग्राउंड सेवा का एक नया टाइप mediaProcessing
जोड़ा गया है. यह सेवा टाइप, मीडिया फ़ाइलों को ट्रांसकोड करने जैसे कामों के लिए सही है. उदाहरण के लिए, कोई मीडिया ऐप्लिकेशन किसी ऑडियो फ़ाइल को डाउनलोड कर सकता है और उसे चलाने से पहले, किसी दूसरे फ़ॉर्मैट में बदल सकता है. mediaProcessing
फ़ोरग्राउंड सेवा का इस्तेमाल करके, यह पक्का किया जा सकता है कि ऐप्लिकेशन बैकग्राउंड में होने पर भी कन्वर्ज़न जारी रहे.
सिस्टम किसी ऐप्लिकेशन की mediaProcessing
सेवाओं को 24 घंटों में कुल छह घंटे चलाने की अनुमति देता है. इसके बाद, सिस्टम, मौजूदा सेवा के Service.onTimeout(int, int)
तरीके को कॉल करता है (Android 15 में शुरू किया गया). फ़िलहाल, Service.stopSelf()
को कॉल करने के लिए सेवा को कुछ सेकंड मिलेंगे. अगर सेवा Service.stopSelf()
को कॉल नहीं करती है, तो सिस्टम में कोई इंटरनल अपवाद दिखता है. अपवाद को Logcat में लॉग इन किया जाता है जिसमें यह मैसेज शामिल है:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type mediaProcessing did not stop within its timeout: [component name]"
अपवाद से बचने के लिए, इनमें से कोई एक काम किया जा सकता है:
- अपनी सेवा में
Service.onTimeout(int, int)
का नया तरीका लागू करें. जब आपके ऐप्लिकेशन को कॉलबैक मिलता है, तो कुछ सेकंड के अंदरstopSelf()
को कॉल करना न भूलें. (अगर ऐप्लिकेशन को तुरंत नहीं रोका जाता, तो सिस्टम गड़बड़ी जनरेट करता है.) - पक्का करें कि आपके ऐप्लिकेशन की
mediaProcessing
सेवाएं, 24 घंटे में कुल छह घंटे से ज़्यादा न चलें. ऐसा तब तक नहीं होगा, जब तक उपयोगकर्ता ऐप्लिकेशन के साथ इंटरैक्ट करके, टाइमर को रीसेट नहीं करता. - सीधे उपयोगकर्ता के साथ इंटरैक्शन होने पर ही,
mediaProcessing
फ़ोरग्राउंड सेवाएं शुरू करें. सेवा शुरू होने के समय, आपका ऐप्लिकेशन फ़ोरग्राउंड में होता है. इसलिए, ऐप्लिकेशन के बैकग्राउंड में चलने के बाद, आपकी सेवा को पूरे छह घंटे तक चालू रखा जाता है. mediaProcessing
फ़ोरग्राउंड सेवा का इस्तेमाल करने के बजाय, WorkManager जैसे अन्य एपीआई का इस्तेमाल करें.
अगर आपके ऐप्लिकेशन की mediaProcessing
फ़ोरग्राउंड सेवाएं पिछले 24 में छह घंटों तक चली हैं, तो mediaProcessing
फ़ोरग्राउंड सेवा को तब तक शुरू नहीं किया जा सकता, जब तक
उपयोगकर्ता आपके ऐप्लिकेशन को फ़ोरग्राउंड में न ले जाए (इससे टाइमर रीसेट हो जाता है). अगर कोई दूसरी mediaProcessing
फ़ोरग्राउंड सेवा शुरू करने की कोशिश की जाती है, तो सिस्टम ForegroundServiceStartNotAllowedException
को गड़बड़ी का मैसेज दिखाता है. जैसे, "mediaProcessing टाइप की फ़ोरग्राउंड सेवा के लिए, समयसीमा पहले ही खत्म हो चुकी है".
mediaProcessing
सेवा टाइप के बारे में ज़्यादा जानकारी के लिए, Android 15 के लिए फ़ोरग्राउंड सेवा टाइप में हुए बदलाव: मीडिया प्रोसेसिंग देखें.
टेस्ट करना
अपने ऐप्लिकेशन के काम करने के तरीके की जांच करने के लिए, मीडिया प्रोसेसिंग के टाइम आउट को चालू किया जा सकता है. भले ही, आपका ऐप्लिकेशन Android 15 को टारगेट न करता हो (जब तक कि ऐप्लिकेशन, Android 15 डिवाइस पर चल रहा हो). टाइम आउट की सुविधा चालू करने के लिए, यह adb
कमांड चलाएं:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
टाइम आउट की अवधि में बदलाव भी किया जा सकता है. इससे यह जांचना आसान हो जाता है कि
तय सीमा पूरी होने पर, आपका ऐप्लिकेशन कैसे काम करता है. टाइम आउट की नई अवधि सेट करने के लिए, यह adb
कमांड चलाएं:
adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds
फ़ोरग्राउंड सेवाएं लॉन्च करने वाले BOOT_COMPLETED
ब्रॉडकास्ट रिसीवर पर पाबंदियां
在启动 BOOT_COMPLETED
广播接收器方面存在新限制
前台服务。BOOT_COMPLETED
接收器不能启动
以下类型的前台服务:
dataSync
camera
mediaPlayback
phoneCall
mediaProjection
microphone
(自 Android 14 起,microphone
就受到此限制)
如果 BOOT_COMPLETED
接收器尝试启动任何上述类型的前台
服务,系统会抛出 ForegroundServiceStartNotAllowedException
。
测试
如需测试应用的行为,您可以启用这些新限制,即使您的应用并未以 Android 15 为目标平台(只要应用在 Android 15 设备上运行)也是如此。运行以下 adb
命令:
adb shell am compat enable FGS_BOOT_COMPLETED_RESTRICTIONS your-package-name
如需在不重启设备的情况下发送 BOOT_COMPLETED
广播,请运行以下 adb
命令:
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED your-package-name
जब कोई ऐप्लिकेशन SYSTEM_ALERT_WINDOW
अनुमति का इस्तेमाल कर रहा हो, तब फ़ोरग्राउंड सेवाएं शुरू करने से जुड़ी पाबंदियां
पहले, अगर किसी ऐप्लिकेशन के पास SYSTEM_ALERT_WINDOW
अनुमति होती थी, तो वह फ़ोरग्राउंड सेवा को लॉन्च कर सकता था. भले ही, वह ऐप्लिकेशन फ़िलहाल बैकग्राउंड में हो. इस बारे में बैकग्राउंड में शुरू करने से जुड़ी पाबंदियों से छूट में बताया गया है.
अगर कोई ऐप्लिकेशन Android 15 को टारगेट करता है, तो अब यह छूट कम हो गई है. ऐप्लिकेशन को अब SYSTEM_ALERT_WINDOW
की अनुमति की ज़रूरत होगी. साथ ही, उसमें भी एक दिखने वाला ओवरले विंडो भी होनी चाहिए. इसका मतलब है कि ऐप्लिकेशन को सबसे पहले TYPE_APPLICATION_OVERLAY
विंडो लॉन्च करनी होगी और फ़ोरग्राउंड सेवा शुरू करने से पहले, विंडो दिखनी चाहिए.
अगर आपका ऐप्लिकेशन इन नई ज़रूरी शर्तों को पूरा किए बिना, बैकग्राउंड से फ़ोरग्राउंड सेवा शुरू करने की कोशिश करता है और उसे कोई छूट नहीं मिली है, तो सिस्टम ForegroundServiceStartNotAllowedException
दिखाता है.
अगर आपका ऐप्लिकेशन SYSTEM_ALERT_WINDOW
अनुमति का एलान करता है और बैकग्राउंड से फ़ोरग्राउंड सेवाएं लॉन्च करता है, तो इस बदलाव का उस पर असर पड़ सकता है. अगर आपके ऐप्लिकेशन को ForegroundServiceStartNotAllowedException
मिलता है, तो अपने ऐप्लिकेशन के काम करने का क्रम देखें और पक्का करें कि बैकग्राउंड से फ़ोरग्राउंड सेवा शुरू करने से पहले, आपके ऐप्लिकेशन में एक ऐक्टिव ओवरले विंडो हो. View.getWindowVisibility()
को कॉल करके, यह देखा जा सकता है कि ओवरले विंडो फ़िलहाल दिख रही है या नहीं. इसके अलावा, View.onWindowVisibilityChanged()
को बदलकर, यह भी सेट किया जा सकता है कि ओवरले विंडो दिखने या न दिखने पर सूचना मिलती रहे.
टेस्ट करना
अपने ऐप्लिकेशन के व्यवहार की जांच करने के लिए, ये नई पाबंदियां चालू की जा सकती हैं. भले ही, आपका ऐप्लिकेशन Android 15 को टारगेट न करता हो. हालांकि, यह ज़रूरी है कि ऐप्लिकेशन Android 15 वाले डिवाइस पर चल रहा हो. बैकग्राउंड से फ़ोरग्राउंड सेवाएं शुरू करने से जुड़ी इन नई पाबंदियों को चालू करने के लिए, यहां दिया गया adb
निर्देश चलाएं:
adb shell am compat enable FGS_SAW_RESTRICTIONS your-package-name
ऐप्लिकेशन, परेशान न करें मोड की ग्लोबल स्थिति में कब बदलाव कर सकते हैं, इसमें बदलाव
以 Android 15(API 级别 35)及更高版本为目标平台的应用无法再更改设备上的勿扰 (DND) 功能的全局状态或政策(无论是通过修改用户设置还是关闭勿扰模式)。相反,应用必须提供 AutomaticZenRule
,系统会将其与现有的“最严格的政策优先”方案合并为一个全局政策。对之前会影响全局状态的现有 API 的调用(setInterruptionFilter
、setNotificationPolicy
)会导致创建或更新隐式 AutomaticZenRule
,该 AutomaticZenRule
会根据这些 API 调用的调用周期开启和关闭。
请注意,只有当应用调用 setInterruptionFilter(INTERRUPTION_FILTER_ALL)
并希望该调用停用之前由其所有者激活的 AutomaticZenRule
时,此更改才会影响可观察到的行为。
OpenJDK API में हुए बदलाव
Android 15 में, Android की मुख्य लाइब्रेरी को रीफ़्रेश करने का काम जारी है, ताकि इसे OpenJDK LTS के नए रिलीज़ की सुविधाओं के साथ अलाइन किया जा सके.
इनमें से कुछ बदलावों का असर, Android 15 (एपीआई लेवल 35) को टारगेट करने वाले ऐप्लिकेशन के साथ काम करने की सुविधा पर पड़ सकता है:
स्ट्रिंग फ़ॉर्मैटिंग एपीआई में बदलाव: इन
String.format()
औरFormatter.format()
एपीआई का इस्तेमाल करते समय, आर्ग्युमेंट इंडेक्स, फ़्लैग, चौड़ाई, और सटीक वैल्यू की पुष्टि अब ज़्यादा सख्त तरीके से की जाती है:String.format(String, Object[])
String.format(Locale, String, Object[])
Formatter.format(String, Object[])
Formatter.format(Locale, String, Object[])
उदाहरण के लिए, आर्ग्युमेंट के इंडेक्स के तौर पर 0 का इस्तेमाल करने पर (फ़ॉर्मैट स्ट्रिंग में
%0
), यह अपवाद दिखता है:IllegalFormatArgumentIndexException: Illegal format argument index = 0
इस मामले में, फ़ॉर्मैट स्ट्रिंग में 1 (
%1
) के आर्ग्युमेंट इंडेक्स का इस्तेमाल करके, समस्या को ठीक किया जा सकता है.Arrays.asList(...).toArray()
के कॉम्पोनेंट टाइप में बदलाव:Arrays.asList(...).toArray()
का इस्तेमाल करने पर, नतीजे के ऐरे का कॉम्पोनेंट टाइप अबObject
है, न कि ऐरे के एलिमेंट का टाइप. इसलिए, यह कोडClassCastException
दिखाता है:String[] elements = (String[]) Arrays.asList("one", "two").toArray();
इस मामले में, नतीजे के ऐरे में
String
को कॉम्पोनेंट टाइप के तौर पर बनाए रखने के लिए,Collection.toArray(Object[])
का इस्तेमाल किया जा सकता है:String[] elements = Arrays.asList("two", "one").toArray(new String[0]);
भाषा कोड को मैनेज करने के तरीके में बदलाव:
Locale
एपीआई का इस्तेमाल करते समय, अब हिब्रू, येहुदी, और इंडोनेशियन भाषा के कोड, उनके पुराने फ़ॉर्म (हिब्रू:iw
, येहुदी:ji
, और इंडोनेशियन:in
) में बदले नहीं जाते. इनमें से किसी एक स्थानीय भाषा के लिए भाषा कोड तय करते समय, ISO 639-1 के कोड का इस्तेमाल करें (हिब्रू:he
, येहुदी:yi
, और इंडोनेशियन:id
).रैंडम int सीक्वेंस में बदलाव: https://bugs.openjdk.org/browse/JDK-8301574 में किए गए बदलावों के बाद, यहां दिए गए
Random.ints()
तरीके अब संख्याओं का एक अलग क्रम दिखाते हैं, जबकिRandom.nextInt()
तरीके ऐसा नहीं करते:आम तौर पर, इस बदलाव से ऐप्लिकेशन के काम करने के तरीके पर कोई असर नहीं पड़ना चाहिए. हालांकि, आपके कोड को यह उम्मीद नहीं करनी चाहिए कि
Random.ints()
तरीकों से जनरेट किया गया क्रम,Random.nextInt()
से मैच करेगा.
Android 15 (एपीआई लेवल 35) का इस्तेमाल करने के लिए, अपने ऐप्लिकेशन के बिल्ड कॉन्फ़िगरेशन में compileSdk
को अपडेट करने के बाद, नए SequencedCollection
एपीआई से आपके ऐप्लिकेशन के काम करने के तरीके पर असर पड़ सकता है:
kotlin-stdlib
मेंMutableList.removeFirst()
औरMutableList.removeLast()
एक्सटेंशन फ़ंक्शन के साथ कॉलिज़नJava में
List
टाइप, Kotlin मेंMutableList
टाइप से मैप होता है. Android 15 (एपीआई लेवल 35) मेंList.removeFirst()
औरList.removeLast()
एपीआई को शामिल किया गया है. इसलिए, Kotlin कंपाइलर,list.removeFirst()
जैसे फ़ंक्शन कॉल कोkotlin-stdlib
में मौजूद एक्सटेंशन फ़ंक्शन के बजाय, नएList
एपीआई के लिए स्टैटिक तौर पर हल करता है.अगर किसी ऐप्लिकेशन को
compileSdk
को35
पर सेट करके औरminSdk
को34
या उससे पहले के वर्शन पर सेट करके फिर से कंपाइल किया जाता है और फिर उस ऐप्लिकेशन को Android 14 और उससे पहले के वर्शन पर चलाया जाता है, तो रनटाइम के दौरान गड़बड़ी का मैसेज दिखता है:java.lang.NoSuchMethodError: No virtual method removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;
Android Gradle प्लग इन में मौजूद
NewApi
lint विकल्प, एपीआई के इन नए इस्तेमालों का पता लगा सकता है../gradlew lint
MainActivity.kt:41: Error: Call requires API level 35 (current min is 34): java.util.List#removeFirst [NewApi] list.removeFirst()रनटाइम अपवाद और लिंट की गड़बड़ियों को ठीक करने के लिए, Kotlin में
removeFirst()
औरremoveLast()
फ़ंक्शन कॉल को क्रमशःremoveAt(0)
औरremoveAt(list.lastIndex)
से बदला जा सकता है. अगर Android Studio Ladybug | 2024.1.3 या इसके बाद के वर्शन का इस्तेमाल किया जा रहा है, तो इन गड़बड़ियों को तुरंत ठीक करने का विकल्प भी मिलता है.अगर लिंट करने का विकल्प बंद है, तो
@SuppressLint("NewApi")
औरlintOptions { disable 'NewApi' }
को हटाएं.Java में अन्य तरीकों के साथ टकराव
मौजूदा टाइप में नए तरीके जोड़े गए हैं. उदाहरण के लिए,
List
औरDeque
. ऐसा हो सकता है कि ये नए तरीके, दूसरे इंटरफ़ेस और क्लास में मौजूद, एक जैसे नाम और आर्ग्युमेंट टाइप वाले तरीकों के साथ काम न करें. अगर किसी मेथड के सिग्नेचर में, काम न करने वाले सिग्नेचर का इस्तेमाल किया गया है, तोjavac
कंपाइलर, बिल्ड के समय गड़बड़ी का मैसेज दिखाता है. उदाहरण के लिए:गड़बड़ी का पहला उदाहरण:
javac MyList.java
MyList.java:135: error: removeLast() in MyList cannot implement removeLast() in List public void removeLast() { ^ return type void is not compatible with Object where E is a type-variable: E extends Object declared in interface Listगड़बड़ी का दूसरा उदाहरण:
javac MyList.java
MyList.java:7: error: types Deque<Object> and List<Object> are incompatible; public class MyList implements List<Object>, Deque<Object> { both define reversed(), but with unrelated return types 1 errorतीसरी गड़बड़ी का उदाहरण:
javac MyList.java
MyList.java:43: error: types List<E#1> and MyInterface<E#2> are incompatible; public static class MyList implements List<Object>, MyInterface<Object> { class MyList inherits unrelated defaults for getFirst() from types List and MyInterface where E#1,E#2 are type-variables: E#1 extends Object declared in interface List E#2 extends Object declared in interface MyInterface 1 errorबिल्ड से जुड़ी इन गड़बड़ियों को ठीक करने के लिए, इन इंटरफ़ेस को लागू करने वाली क्लास को, काम करने वाले रिटर्न टाइप के साथ, तरीके को बदलना चाहिए. उदाहरण के लिए:
@Override public Object getFirst() { return List.super.getFirst(); }
सुरक्षा
Android 15 में ऐसे बदलाव किए गए हैं जिनसे सिस्टम की सुरक्षा को बेहतर बनाया जा सके. इससे ऐप्लिकेशन और उपयोगकर्ताओं को नुकसान पहुंचाने वाले ऐप्लिकेशन से सुरक्षित रखने में मदद मिलती है.
प्रतिबंधित TLS वर्शन
Android 15, TLS के 1.0 और 1.1 वर्शन के इस्तेमाल पर पाबंदी लगाता है. इन वर्शन को पहले Android में बंद कर दिया गया था. हालांकि, अब Android 15 को टारगेट करने वाले ऐप्लिकेशन के लिए, इनका इस्तेमाल करने की अनुमति नहीं है.
सुरक्षित बैकग्राउंड गतिविधि शुरू होना
Android 15 可保护用户免受恶意应用的侵害,并让用户更好地控制 来防止恶意后台应用 将其他应用置于前台、提升其权限以及滥用 用户互动自以下时间以来,后台活动启动一直受到限制 Android 10(API 级别 29)。
禁止与堆栈中的顶部 UID 不匹配的应用启动 activity
恶意应用可以在同一任务中启动另一个应用的 activity,然后
叠加在上面,营造出像该应用一样的错觉。这个“任务”
劫持"攻击绕过了当前的后台启动限制,
会发生在同一个可见任务中。为了降低这种风险,Android 15 新增了
用于阻止与堆栈中的顶层 UID 不匹配的应用启动的标志
活动。如需选择启用应用的所有活动,请更新
allowCrossUidActivitySwitchFromBelow
属性:AndroidManifest.xml
<application android:allowCrossUidActivitySwitchFromBelow="false" >
如果满足以下所有条件,则启用新的安全措施:
- 执行启动的应用以 Android 15 为目标平台。
- 任务堆栈顶部的应用以 Android 15 为目标平台。
- 所有可见活动都已选择启用新保护措施
如果启用了安全措施,应用可能会返回主屏幕,而不是返回 最后一个可见应用(如果他们自行完成任务)。
其他变更
除了限制 UID 匹配之外,这些其他变更也 包括:
- 更改
PendingIntent
创作者,以阻止后台活动启动,具体方法是: 默认。这有助于防止应用意外创建 可能被恶意操作者滥用的PendingIntent
。 - 请勿将应用调到前台,除非
PendingIntent
发送者 允许它。此变更旨在防止恶意应用滥用 在后台启动 activity 的功能。默认情况下,应用 允许将任务堆栈转到前台,除非创建者允许 后台活动启动权限或发送者有后台活动 启动权限 - 控制任务堆栈的顶层 activity 完成其任务的方式。如果 顶层 activity 完成一项任务后,Android 会返回到之前执行的 上次活动时间。此外,如果非顶层 activity 完成其任务,Android 将 返回主屏幕;因此不会阻碍这个非顶层的 活动。
- 防止将其他应用中的任意 activity 启动到您自己的 activity 任务。这项变更旨在防止恶意应用 看起来像是来自其他应用的活动
- 禁止将不可见窗口视为后台活动 发布。这有助于防止恶意应用滥用后台 activity 来向用户显示不需要或恶意的内容。
ज़्यादा सुरक्षित इंटेंट
Android 15 引入了新的可选安全措施,以提高 intent 的安全性和稳健性。这些变更旨在防止潜在的漏洞以及恶意应用可能利用的 intent 滥用行为。Android 15 对 intent 的安全性进行了两项主要改进:
- 与目标 intent 过滤器匹配:定位到特定组件的 intent 必须与目标的 intent 过滤器规范完全匹配。如果您发送 intent 来启动其他应用的 activity,目标 intent 组件需要与接收 activity 声明的 intent 过滤器保持一致。
- intent 必须具有操作:没有操作的 intent 将不再与任何 intent 过滤器匹配。这意味着,用于启动 activity 或服务的 intent 必须具有明确定义的操作。
如需检查您的应用对这些更改的响应方式,请在应用中使用 StrictMode
。如需查看有关 Intent
使用违规行为的详细日志,请添加以下方法:
Kotlin
fun onCreate() { StrictMode.setVmPolicy(VmPolicy.Builder() .detectUnsafeIntentLaunch() .build() ) }
Java
public void onCreate() { StrictMode.setVmPolicy(new VmPolicy.Builder() .detectUnsafeIntentLaunch() .build()); }
उपयोगकर्ता अनुभव और सिस्टम यूज़र इंटरफ़ेस (यूआई)
Android 15 में कुछ बदलाव किए गए हैं. इनका मकसद, उपयोगकर्ताओं को एक जैसा और आसान अनुभव देना है.
विंडो इनसेट में बदलाव
Android 15 में, विंडो इनसेट से जुड़े दो बदलाव किए गए हैं: डिफ़ॉल्ट रूप से, स्क्रीन के किनारों तक विंडो दिखती है. साथ ही, कॉन्फ़िगरेशन में भी बदलाव किए गए हैं. जैसे, सिस्टम बार का डिफ़ॉल्ट कॉन्फ़िगरेशन.
全面实施政策
如果应用以 Android 15(API 级别 35)为目标平台,则在搭载 Android 15 的设备上,应用默认会采用边到边显示模式。
这是一项重大变更,可能会对应用的界面产生负面影响。这些变更会影响以下界面区域:
- 手势操作手柄导航栏
- 默认透明。
- 底部偏移量处于停用状态,因此除非应用边衬区,否则内容会绘制在系统导航栏后面。
setNavigationBarColor
和R.attr#navigationBarColor
已废弃,不会影响手势导航。setNavigationBarContrastEnforced
和R.attr#navigationBarContrastEnforced
对手势导航的影响仍然不变。
- “三按钮”导航
- 默认情况下,不透明度设置为 80%,颜色可能与窗口背景相匹配。
- 底部偏移量处于停用状态,因此除非应用了边衬区,否则内容会绘制在系统导航栏后面。
- 默认情况下,
setNavigationBarColor
和R.attr#navigationBarColor
会设置为与窗口背景相匹配。窗口背景必须是彩色可绘制对象,此默认值才能应用。此 API 已废弃,但仍会影响三按钮导航。 setNavigationBarContrastEnforced
和R.attr#navigationBarContrastEnforced
默认均为 true,这会在三按钮导航栏中添加 80% 不透明的背景。
- 状态栏
- 默认透明。
- 顶部偏移量处于停用状态,因此除非应用边衬区,否则内容会绘制在状态栏后面。
setStatusBarColor
和R.attr#statusBarColor
已废弃,对 Android 15 没有任何影响。setStatusBarContrastEnforced
和R.attr#statusBarContrastEnforced
已废弃,但对 Android 15 仍有影响。
- 刘海屏
- 非浮动窗口的
layoutInDisplayCutoutMode
必须为LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
。SHORT_EDGES
、NEVER
和DEFAULT
会被解读为ALWAYS
,以便用户不会看到由显示屏缺口导致的黑条,并且应用会显示到屏幕边缘。
- 非浮动窗口的
以下示例展示了应用在以 Android 15(API 级别 35)为目标平台之前和之后,以及应用在应用内嵌之前和之后的效果。
如何检查应用是否已采用边到边设计
如果您的应用已经是边到边且应用了内边距,则除以下情况外,您大多不会受到影响。不过,即使您认为自己没有受到影响,我们也建议您测试应用。
- 您有一个非浮动窗口,例如使用
SHORT_EDGES
、NEVER
或DEFAULT
(而非LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
)的Activity
。如果您的应用在启动时崩溃,这可能是因为您的启动画面存在问题。您可以将核心启动画面依赖项升级到 1.2.0-alpha01 或更高版本,也可以设置window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
。 - 有些流量较低的屏幕可能存在遮挡界面的情况。验证这些访问次数较少的屏幕是否存在遮挡的界面。流量较低的屏幕包括:
- 初始配置或登录屏幕
- “设置”页面
如果您的应用尚未采用边到边设计,应检查哪些方面
如果您的应用尚未采用边到边设计,您很可能受到影响。除了已经采用边到边设计的应用的场景之外,您还应考虑以下情况:
- 如果应用在 Compose 中使用 Material 3 组件 (
androidx.compose.material3
),例如TopAppBar
、BottomAppBar
和NavigationBar
,这些组件可能不会受到影响,因为它们会自动处理边衬区。 - 如果应用使用的是 Compose 中的 Material 2 组件 (
androidx.compose.material
),这些组件本身并不会自动处理边衬区。不过,您可以获得边衬区的访问权限,然后手动应用边衬区。在 androidx.compose.material 1.6.0 及更高版本中,使用windowInsets
参数可为BottomAppBar
、TopAppBar
、BottomNavigation
和NavigationRail
手动应用边衬区。同样,请为Scaffold
使用contentWindowInsets
参数。 - 如果应用使用了 View 和 Material 组件 (
com.google.android.material
),则大多数基于 View 的 Material 组件(例如BottomNavigationView
、BottomAppBar
、NavigationRailView
或NavigationView
)都会处理边衬区,因此不需要执行额外的操作。不过,如果使用的是AppBarLayout
,则需要添加android:fitsSystemWindows="true"
。 - 对于自定义可组合项,请手动将边衬区应用为内边距。如果您的内容位于
Scaffold
中,您可以使用Scaffold
内边距值使用内边距。否则,请使用WindowInsets
之一应用内边距。 - 如果应用使用的是 View 和
BottomSheet
、SideSheet
或自定义容器,请使用ViewCompat.setOnApplyWindowInsetsListener
应用内边距。对于RecyclerView
,请使用此监听器应用内边距,同时添加clipToPadding="false"
。
如果您的应用必须提供自定义后台保护,应检查哪些方面
如果您的应用必须为三按钮导航栏或状态栏提供自定义背景保护,则应使用 WindowInsets.Type#tappableElement()
获取三按钮导航栏高度或 WindowInsets.Type#statusBars
,将可组合项或视图放置在系统栏后面。
其他端到端资源
如需了解有关应用内边距的其他注意事项,请参阅边到边视图和边到边 Compose 指南。
已弃用的 API
以下 API 已废弃,但并未停用:
R.attr#enforceStatusBarContrast
R.attr#navigationBarColor
(适用于三按钮导航,透明度为 80%)Window#isStatusBarContrastEnforced
Window#setNavigationBarColor
(适用于三按钮导航,透明度为 80%)Window#setStatusBarContrastEnforced
以下 API 已废弃并停用:
R.attr#navigationBarColor
(适用于手势导航)R.attr#navigationBarDividerColor
R.attr#statusBarColor
Window#setDecorFitsSystemWindows
Window#getNavigationBarColor
Window#getNavigationBarDividerColor
Window#getStatusBarColor
Window#setNavigationBarColor
(适用于手势导航)Window#setNavigationBarDividerColor
Window#setStatusBarColor
稳定配置
अगर आपका ऐप्लिकेशन Android 15 (एपीआई लेवल 35) या उसके बाद के वर्शन को टारगेट करता है, तो Configuration
अब सिस्टम बार को शामिल नहीं करता. अगर लेआउट का हिसाब लगाने के लिए, Configuration
क्लास में स्क्रीन साइज़ का इस्तेमाल किया जाता है, तो आपको इसे बेहतर विकल्पों से बदलना चाहिए. जैसे, अपनी ज़रूरत के हिसाब से ViewGroup
, WindowInsets
या WindowMetricsCalculator
.
Configuration
, एपीआई 1 से उपलब्ध है. आम तौर पर, यह जानकारी Activity.onConfigurationChanged
से मिलती है. इसमें विंडो की डेंसिटी, ओरिएंटेशन, और साइज़ जैसी जानकारी मिलती है. Configuration
से मिली विंडो के साइज़ की एक अहम खासियत यह है कि पहले इसमें सिस्टम बार शामिल नहीं थे.
कॉन्फ़िगरेशन साइज़ का इस्तेमाल आम तौर पर संसाधन चुनने के लिए किया जाता है, जैसे कि
/res/layout-h500dp
. यह अब भी इस्तेमाल का मान्य उदाहरण है. हालांकि, लेआउट के हिसाब लगाने के लिए, इसका इस्तेमाल करने का सुझाव नहीं दिया जाता. अगर ऐसा है, तो आपको अब इससे दूर हो जाना चाहिए. आपको अपने इस्तेमाल के उदाहरण के आधार पर, Configuration
के इस्तेमाल को किसी और ज़्यादा सही चीज़ से बदलना चाहिए.
अगर लेआउट का हिसाब लगाने के लिए इसका इस्तेमाल किया जाता है, तो सही ViewGroup
का इस्तेमाल करें, जैसे कि
CoordinatorLayout
या ConstraintLayout
. अगर इसका इस्तेमाल सिस्टम के नेविगेशन बार की ऊंचाई तय करने के लिए किया जाता है, तो WindowInsets
का इस्तेमाल करें. अगर आपको अपने ऐप्लिकेशन की विंडो का मौजूदा साइज़ जानना है, तो computeCurrentWindowMetrics
का इस्तेमाल करें.
इस बदलाव से जिन फ़ील्ड पर असर पड़ा है उनके बारे में यहां बताया गया है:
Configuration.screenWidthDp
औरscreenHeightDp
साइज़ में अब सिस्टम बार शामिल नहीं किए जाते.screenWidthDp
औरscreenHeightDp
में किए गए बदलावों का असर,Configuration.smallestScreenWidthDp
पर भी पड़ता है.- स्क्वेयर के करीब के डिवाइसों पर,
screenWidthDp
औरscreenHeightDp
में किए गए बदलावों काConfiguration.orientation
पर असर पड़ता है. Configuration
में किए गए बदलावों का असर,Display.getSize(Point)
पर सीधे तौर पर नहीं पड़ता. एपीआई लेवल 30 से, इसे बंद कर दिया गया था.- एपीआई लेवल 33 से ही
Display.getMetrics()
इस तरह काम कर रहा है.
elegantTextHeight एट्रिब्यूट की वैल्यू डिफ़ॉल्ट रूप से 'सही' पर सेट होती है
Android 15 (एपीआई लेवल 35) को टारगेट करने वाले ऐप्लिकेशन के लिए, elegantTextHeight
TextView
एट्रिब्यूट डिफ़ॉल्ट रूप से true
हो जाता है. इससे, डिफ़ॉल्ट रूप से इस्तेमाल किए जाने वाले कॉम्पैक्ट फ़ॉन्ट की जगह, कुछ ऐसी स्क्रिप्ट का इस्तेमाल किया जाता है जिनमें बड़ी वर्टिकल मेट्रिक होती हैं. इन मेट्रिक को पढ़ना ज़्यादा आसान होता है.
कॉम्पैक्ट फ़ॉन्ट को लेआउट के बीच में रुकावट आने से रोकने के लिए लॉन्च किया गया था. Android 13 (एपीआई लेवल 33), fallbackLineSpacing
एट्रिब्यूट का इस्तेमाल करके, टेक्स्ट लेआउट की वर्टिकल ऊंचाई को बढ़ाकर, इनमें से कई रुकावटों को रोकता है.
Android 15 में, कॉम्पैक्ट फ़ॉन्ट अब भी सिस्टम में मौजूद है. इसलिए, आपका ऐप्लिकेशन पहले जैसा व्यवहार पाने के लिए, elegantTextHeight
को false
पर सेट कर सकता है. हालांकि, आने वाले समय में रिलीज़ होने वाले वर्शन में, इसकी सुविधा काम नहीं करेगी. इसलिए, अगर आपका ऐप्लिकेशन इन स्क्रिप्ट के साथ काम करता है: ऐरेबिक, लाओ, म्यांमार, तमिल, गुजराती, कन्नड़, मलयालम, उड़ीया, तेलुगु या थाई, तो elegantTextHeight
को true
पर सेट करके अपने ऐप्लिकेशन की जांच करें.
अक्षरों के जटिल आकार के लिए, TextView की चौड़ाई में बदलाव
在以前的 Android 版本中,某些具有复杂形状的手写字体或语言可能会在上一个或下一个字符的区域绘制字母。在某些情况下,此类字母会在开头或结尾处被剪裁。从 Android 15 开始,TextView
会分配宽度,以便为此类字母绘制足够的空间,并允许应用请求向左额外添加内边距以防止剪裁。
由于此更改会影响 TextView
确定宽度的方式,因此如果应用以 Android 15(API 级别 35)或更高版本为目标平台,TextView
会默认分配更多宽度。您可以通过对 TextView
调用 setUseBoundsForWidth
API 来启用或停用此行为。
由于添加左内边距可能会导致现有布局未对齐,因此默认情况下不会添加内边距,即使以 Android 15 或更高版本为目标平台的应用也是如此。不过,您可以通过调用 setShiftDrawingOffsetForStartOverhang
添加额外的内边距以防止剪裁。
以下示例展示了这些更改如何改进某些字体和语言的文本布局。
EditText के लिए, स्थानीय भाषा के हिसाब से डिफ़ॉल्ट लाइन की ऊंचाई
Android के पिछले वर्शन में, टेक्स्ट लेआउट, टेक्स्ट की ऊंचाई को बढ़ा देता था, ताकि मौजूदा स्थानीय भाषा से मैच करने वाले फ़ॉन्ट की लाइन की ऊंचाई पूरी की जा सके. उदाहरण के लिए, अगर कॉन्टेंट जैपनीज़ में था, तो टेक्स्ट की ऊंचाई थोड़ी ज़्यादा हो गई, क्योंकि जैपनीज़ फ़ॉन्ट की लाइन की ऊंचाई, लैटिन फ़ॉन्ट की लाइन की ऊंचाई से थोड़ी ज़्यादा होती है. हालांकि, लाइन हाइट में इन अंतरों के बावजूद, इस्तेमाल किए जा रहे स्थानीय भाषा के बावजूद, EditText
एलिमेंट का साइज़ एक जैसा था, जैसा कि इस इमेज में दिखाया गया है:
Android 15 (एपीआई लेवल 35) को टारगेट करने वाले ऐप्लिकेशन के लिए, EditText
के लिए कम से कम लाइन हाइट तय की गई है. इससे, तय की गई लोकेल के रेफ़रंस फ़ॉन्ट से मैच करने में मदद मिलती है. इसकी जानकारी इस इमेज में दी गई है:
ज़रूरत पड़ने पर, आपका ऐप्लिकेशन useLocalePreferredLineHeightForMinimum
एट्रिब्यूट को false
पर सेट करके, पहले जैसा व्यवहार वापस ला सकता है. साथ ही, आपका ऐप्लिकेशन Kotlin और Java में setMinimumFontMetrics
एपीआई का इस्तेमाल करके, कस्टम मिनिमम वर्टिकल मेट्रिक सेट कर सकता है.
कैमरा और मीडिया
Android 15 में, कैमरे और मीडिया के व्यवहार में ये बदलाव किए गए हैं. ये बदलाव, Android 15 या इसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन के लिए किए गए हैं.
ऑडियो फ़ोकस का अनुरोध करने से जुड़ी पाबंदियां
Android 15 (एपीआई लेवल 35) को टारगेट करने वाले ऐप्लिकेशन को ऑडियो फ़ोकस का अनुरोध करने के लिए, टॉप ऐप्लिकेशन या फ़ोरग्राउंड सेवा के तौर पर चलना होगा. अगर कोई ऐप्लिकेशन इनमें से किसी एक ज़रूरी शर्त को पूरा न करने पर फ़ोकस का अनुरोध करता है, तो कॉल AUDIOFOCUS_REQUEST_FAILED
दिखाता है.
ऑडियो फ़ोकस के बारे में ज़्यादा जानने के लिए, ऑडियो फ़ोकस मैनेज करें पर जाएं.
SDK टूल के अलावा अन्य तरीकों से डेटा इकट्ठा करने पर लगी पाबंदियां अपडेट की गईं
Android 15 में, पाबंदी वाले ऐसे इंटरफ़ेस की अपडेट की गई सूचियां शामिल हैं जो एसडीके टूल के दायरे में नहीं आते. ये सूचियां, Android डेवलपर के साथ मिलकर की गई जांच और नई इंटरनल जांच के आधार पर बनाई गई हैं. जब भी मुमकिन हो, हम यह पक्का करते हैं कि SDK टूल के बाहर के इंटरफ़ेस पर पाबंदी लगाने से पहले, सार्वजनिक विकल्प उपलब्ध हों.
अगर आपका ऐप्लिकेशन Android 15 को टारगेट नहीं करता है, तो हो सकता है कि इनमें से कुछ बदलावों का असर आप पर तुरंत न पड़े. हालांकि, आपके ऐप्लिकेशन के टारगेट एपीआई लेवल के आधार पर, आपके ऐप्लिकेशन के पास कुछ ऐसे इंटरफ़ेस को ऐक्सेस करने का विकल्प होता है जो SDK टूल के नहीं होते. हालांकि, SDK टूल के अलावा किसी भी तरीके या फ़ील्ड का इस्तेमाल करने पर, आपके ऐप्लिकेशन के क्रैश होने का खतरा हमेशा बना रहता है.
अगर आपको नहीं पता कि आपका ऐप्लिकेशन, SDK टूल के अलावा किसी दूसरे इंटरफ़ेस का इस्तेमाल करता है या नहीं, तो इसकी पुष्टि करने के लिए अपने ऐप्लिकेशन की जांच करें. अगर आपका ऐप्लिकेशन, SDK टूल के अलावा किसी दूसरे इंटरफ़ेस पर निर्भर है, तो आपको SDK टूल के विकल्पों पर माइग्रेट करने की योजना बनानी चाहिए. हालांकि, हम समझते हैं कि कुछ ऐप्लिकेशन के लिए, गैर-SDK इंटरफ़ेस इस्तेमाल करने के मान्य उदाहरण हैं. अगर आपको अपने ऐप्लिकेशन में किसी सुविधा के लिए, SDK इंटरफ़ेस के अलावा कोई दूसरा विकल्प नहीं मिल रहा है, तो आपको नए सार्वजनिक एपीआई का अनुरोध करना चाहिए.
Android के इस वर्शन में हुए बदलावों के बारे में ज़्यादा जानने के लिए, Android 15 में, SDK टूल के अलावा अन्य इंटरफ़ेस से जुड़ी पाबंदियों में हुए अपडेट देखें. आम तौर पर, SDK टूल के बाहर के इंटरफ़ेस के बारे में ज़्यादा जानने के लिए, SDK टूल के बाहर के इंटरफ़ेस पर लगी पाबंदियां देखें.