व्यवहार में बदलाव: सभी ऐप्लिकेशन

Android 10 में, ऐप्लिकेशन के काम करने के तरीके में कुछ बदलाव किए गए हैं. इनसे आपके ऐप्लिकेशन पर असर पड़ सकता है. इस पेज पर बताए गए बदलाव, Android 10 पर चलने वाले आपके ऐप्लिकेशन पर लागू होते हैं. भले ही, ऐप्लिकेशन का targetSdkVersion कुछ भी हो. आपको अपने ऐप्लिकेशन की जांच करनी चाहिए और ज़रूरत के हिसाब से उसमें बदलाव करने चाहिए, ताकि ये बदलाव सही तरीके से काम कर सकें.

अगर आपके ऐप्लिकेशन का targetSdkVersion 29 या उसके बाद का है, तो आपको कुछ और बदलाव भी करने होंगे. ज़्यादा जानकारी के लिए, 29 साल को टारगेट करने वाले ऐप्लिकेशन के व्यवहार में होने वाले बदलाव ज़रूर पढ़ें.

ध्यान दें: इस पेज पर बताए गए बदलावों के अलावा, Android 10 में कई निजता से जुड़े बदलाव और पाबंदियां भी शामिल की गई हैं. इनमें ये शामिल हैं:

  • डिवाइस की जगह की जानकारी को बैकग्राउंड में ऐक्सेस करना
  • बैकग्राउंड में गतिविधि शुरू होती है
  • संपर्क अफ़िनिटी जानकारी
  • एमएसी पते को रैंडम पर सेट करना
  • कैमरे का मेटाडेटा
  • अनुमतियों का मॉडल

इन बदलावों से सभी ऐप्लिकेशन पर असर पड़ेगा और उपयोगकर्ता की निजता बेहतर होगी. इन बदलावों को लागू करने के तरीके के बारे में ज़्यादा जानने के लिए, निजता से जुड़े बदलाव पेज पर जाएं.

बिना SDK टूल वाले इंटरफ़ेस से जुड़ी पाबंदियां

ऐप्लिकेशन के काम करने और उसके साथ अन्य ऐप्लिकेशन के काम करने की सुविधा को पक्का करने के लिए, प्लैटफ़ॉर्म ने यह पाबंदी लगाना शुरू कर दिया है कि Android 9 (एपीआई लेवल 28) में आपका ऐप्लिकेशन, एसडीके टूल के अलावा किन इंटरफ़ेस का इस्तेमाल कर सकता है. Android 10 में, Android डेवलपर के साथ मिलकर की गई नई इंटरनल टेस्टिंग और उनके सुझावों के आधार पर, पाबंदी वाले ऐसे इंटरफ़ेस की अपडेट की गई सूचियां शामिल हैं जो SDK टूल के नहीं हैं. हमारा मकसद यह पक्का करना है कि SDK टूल के बाहर के इंटरफ़ेस पर पाबंदी लगाने से पहले, सार्वजनिक विकल्प उपलब्ध हों.

अगर आपको Android 10 (एपीआई लेवल 29) को टारगेट नहीं करना है, तो हो सकता है कि इनमें से कुछ बदलावों का असर आप पर तुरंत न पड़े. हालांकि, फ़िलहाल कुछ ऐसे इंटरफ़ेस इस्तेमाल किए जा सकते हैं जो SDK टूल के नहीं हैं. यह आपके ऐप्लिकेशन के टारगेट एपीआई लेवल पर निर्भर करता है. हालांकि, SDK टूल के अलावा किसी भी तरीके या फ़ील्ड का इस्तेमाल करने पर, आपके ऐप्लिकेशन के काम न करने का खतरा हमेशा बना रहता है.

अगर आपको नहीं पता कि आपका ऐप्लिकेशन, SDK टूल के अलावा किसी दूसरे इंटरफ़ेस का इस्तेमाल करता है या नहीं, तो इसकी पुष्टि करने के लिए अपने ऐप्लिकेशन की जांच करें. अगर आपका ऐप्लिकेशन ऐसे इंटरफ़ेस पर काम करता है जिनमें SDK टूल नहीं हैं, तो आपको SDK टूल के दूसरे विकल्पों पर माइग्रेट करना शुरू करना चाहिए. हालांकि, हम समझते हैं कि कुछ ऐप्लिकेशन में, गैर-एसडीके इंटरफ़ेस का इस्तेमाल करने के लिए मान्य उदाहरण हैं. अगर आपको अपने ऐप्लिकेशन में किसी सुविधा के लिए, गैर-SDK इंटरफ़ेस का इस्तेमाल करने का कोई विकल्प नहीं मिलता है, तो आपको नए सार्वजनिक एपीआई का अनुरोध करना चाहिए.

ज़्यादा जानने के लिए, Android 10 में, SDK टूल के अलावा अन्य इंटरफ़ेस से जुड़ी पाबंदियों से जुड़े अपडेट देखें. साथ ही, बिना SDK टूल वाले इंटरफ़ेस पर लागू होने वाली पाबंदियां देखें.

जेस्चर वाला नेविगेशन

Android 10 और इसके बाद के वर्शन में, उपयोगकर्ता अपने डिवाइस पर जेस्चर वाला नेविगेशन चालू कर सकते हैं. अगर कोई उपयोगकर्ता हाथ के जेस्चर (हाव-भाव) वाला नेविगेशन चालू करता है, तो इसका असर डिवाइस के सभी ऐप्लिकेशन पर पड़ता है. इस बात से कोई फ़र्क़ नहीं पड़ता कि ऐप्लिकेशन, एपीआई लेवल 29 को टारगेट करता है या नहीं. उदाहरण के लिए, अगर उपयोगकर्ता स्क्रीन के किनारे से अंदर की ओर स्वाइप करता है, तो सिस्टम उस जेस्चर को बैक नेविगेशन के तौर पर समझता है. ऐसा तब तक होता है, जब तक कोई ऐप्लिकेशन स्क्रीन के कुछ हिस्सों के लिए खास तौर पर उस जेस्चर को बदल न दे.

अपने ऐप्लिकेशन को हाथ के जेस्चर वाले नेविगेशन के साथ काम करने के लिए, आपको ऐप्लिकेशन के कॉन्टेंट को एक से दूसरे किनारे तक ले जाना होगा. साथ ही, अलग-अलग जेस्चर का सही तरीके से इस्तेमाल करना होगा. ज़्यादा जानकारी के लिए, जेस्चर वाला नेविगेशन दस्तावेज़ देखें.

एनडीके

Android 10 में, NDK में ये बदलाव किए गए हैं.

शेयर किए गए ऑब्जेक्ट में टेक्स्ट की जगह बदलना शामिल नहीं हो सकता

Android 6.0 (एपीआई लेवल 23) में, शेयर किए गए ऑब्जेक्ट में टेक्स्ट को दूसरी जगह ले जाने की सुविधा का इस्तेमाल करने की अनुमति नहीं है. कोड को जैसा है वैसा ही लोड किया जाना चाहिए और उसमें बदलाव नहीं किया जाना चाहिए. इस बदलाव से, ऐप्लिकेशन लोड होने में लगने वाला समय और सुरक्षा बेहतर होती है.

SELinux उन ऐप्लिकेशन पर यह पाबंदी लागू करता है जो Android 10 या उसके बाद के वर्शन को टारगेट करते हैं. अगर ये ऐप्लिकेशन शेयर किए गए ऐसे ऑब्जेक्ट का इस्तेमाल करना जारी रखते हैं जिनमें टेक्स्ट की जगह बदली गई है, तो उनके टूट जाने का जोखिम ज़्यादा है.

Bionic लाइब्रेरी और डाइनैमिक लिंकर पाथ में बदलाव

Android 10 और इसके बाद के वर्शन में, कई पाथ में सामान्य फ़ाइलों के बजाय, सिम्बॉलिक लिंक होते हैं. जो ऐप्लिकेशन नियमित फ़ाइलों के पाथ पर निर्भर रहते हैं वे टूट सकते हैं:

  • /system/lib/libc.so -> /apex/com.android.runtime/lib/bionic/libc.so
  • /system/lib/libm.so -> /apex/com.android.runtime/lib/bionic/libm.so
  • /system/lib/libdl.so -> /apex/com.android.runtime/lib/bionic/libdl.so
  • /system/bin/linker -> /apex/com.android.runtime/bin/linker

ये बदलाव, फ़ाइल के 64-बिट वर्शन पर भी लागू होते हैं. हालांकि, lib/ की जगह lib64/ का इस्तेमाल किया जाता है.

पुराने सिस्टम के साथ काम करने के लिए, सिंकलिंक पुराने पाथ पर दिए जाते हैं. उदाहरण के लिए, /system/lib/libc.so, /apex/com.android.runtime/lib/bionic/libc.so का सिमलिंक है. इसलिए, dlopen(“/system/lib/libc.so”) काम करता रहेगा. हालांकि, जब ऐप्लिकेशन /proc/self/maps या इससे मिलते-जुलते कॉन्टेंट को पढ़कर, लोड की गई लाइब्रेरी की जांच करने की कोशिश करेंगे, तो उन्हें अंतर दिख सकता है. हालांकि, आम तौर पर ऐसा नहीं होता है. हालांकि, हमने पाया है कि कुछ ऐप्लिकेशन, हैकिंग रोकने की अपनी प्रोसेस के तहत ऐसा करते हैं. अगर ऐसा है, तो Bionic फ़ाइलों के लिए, /apex/… पाथ को मान्य पाथ के तौर पर जोड़ा जाना चाहिए.

सिस्टम बाइनरी/लाइब्रेरी को, सिर्फ़ मेमोरी को एक्ज़ीक्यूट करने के लिए मैप किया जाता है

Android 10 से, सिस्टम बाइनरी और लाइब्रेरी के एक्ज़ीक्यूटेबल सेगमेंट को मेमोरी में सिर्फ़ एक्ज़ीक्यूट (नहीं पढ़ा जा सकता) के तौर पर मैप किया जाता है. ऐसा, कोड के फिर से इस्तेमाल से जुड़े हमलों से बचने के लिए किया जाता है. अगर आपका ऐप्लिकेशन, सिर्फ़ एक्सीक्यूट करने के तौर पर मार्क किए गए मेमोरी सेगमेंट में, पढ़ने की कार्रवाइयां करता है, तो सिस्टम आपके ऐप्लिकेशन को SIGSEGV सिग्नल भेजता है. भले ही, ऐसा गड़बड़ी, जोखिम या मेमोरी की जांच करने के मकसद से किया गया हो.

/data/tombstones/ में इससे जुड़ी टूंबस्टोन फ़ाइल की जांच करके पता लगाया जा सकता है कि इस व्यवहार की वजह से क्रैश हुआ है या नहीं. सिर्फ़ एक्सीक्यूट करने से जुड़े क्रैश में, प्रोसेस को रोकने का यह मैसेज दिखता है:

Cause: execute-only (no-read) memory access error; likely due to data in .text.

मेमोरी की जांच जैसे काम करने के लिए, इस समस्या को हल किया जा सकता है. इसके लिए, mprotect() को कॉल करके, सिर्फ़ एक्सीक्यूट किए जाने वाले सेगमेंट को रीड+एक्सीक्यूट के तौर पर मार्क किया जा सकता है. हालांकि, हमारा सुझाव है कि इसके बाद, इसे फिर से सिर्फ़ 'कार्रवाई करने की अनुमति' पर सेट करें. ऐसा इसलिए, क्योंकि ऐक्सेस की अनुमति की यह सेटिंग आपके ऐप्लिकेशन और उपयोगकर्ताओं को बेहतर सुरक्षा देती है.

सुरक्षा

Android 10 में सुरक्षा से जुड़े ये बदलाव शामिल हैं.

TLS 1.3 डिफ़ॉल्ट रूप से चालू रहता है

Android 10 और उसके बाद के वर्शन में, सभी TLS कनेक्शन के लिए TLS 1.3 डिफ़ॉल्ट रूप से चालू होता है. TLS 1.3 को लागू करने के बारे में कुछ अहम जानकारी यहां दी गई है:

  • TLS 1.3 साइफ़र सुइट को पसंद के मुताबिक नहीं बनाया जा सकता. TLS 1.3 के चालू होने पर, काम करने वाले TLS 1.3 साइफ़र सुइट हमेशा चालू रहते हैं. setEnabledCipherSuites() को कॉल करके उन्हें बंद करने की कोशिश को अनदेखा कर दिया जाता है.
  • TLS 1.3 के इस्तेमाल पर बातचीत होने पर, HandshakeCompletedListener ऑब्जेक्ट को सेशन कैश मेमोरी में सेशन जोड़े जाने से पहले कॉल किया जाता है. (TLS 1.2 और पिछले वर्शन में, ये ऑब्जेक्ट सेशन की कैश मेमोरी में सेशन जोड़े जाने के बाद कॉल किए जाते हैं.)
  • कुछ मामलों में, जहां SSLEngine इंस्टेंस की वजह से Android के पिछले वर्शन पर SSLHandshakeException दिखता है, वहां इन इंस्टेंस में Android 10 और उसके बाद के वर्शन के बजाय, SSLProtocolException का पता चलता है.
  • 0-RTT मोड काम नहीं करता.

अगर आप चाहें, तो SSLContext.getInstance("TLSv1.2") को कॉल करके, ऐसा SSLContext पाया जा सकता है जिसमें टीएलएस 1.3 बंद हो. प्रोटोकॉल के वर्शन को हर कनेक्शन के हिसाब से चालू या बंद भी किया जा सकता है. इसके लिए, किसी सही ऑब्जेक्ट पर setEnabledProtocols() को कॉल करें.

SHA-1 से हस्ताक्षर किए गए सर्टिफ़िकेट पर, TLS में भरोसा नहीं किया जाता

Android 10 में, SHA-1 हैश एल्गोरिदम का इस्तेमाल करने वाले सर्टिफ़िकेट, TLS कनेक्शन में भरोसेमंद नहीं माने जाते. रूट सीए ने 2016 से इस तरह का सर्टिफ़िकेट जारी नहीं किया है. साथ ही, Chrome या अन्य मुख्य ब्राउज़र अब उन पर भरोसा नहीं करते.

अगर कनेक्शन किसी ऐसी साइट से है जो SHA-1 का इस्तेमाल करके सर्टिफ़िकेट दिखाती है, तो कनेक्ट करने की कोशिश पूरी नहीं हो पाती.

KeyChain के काम करने के तरीके में बदलाव और सुधार

Google Chrome जैसे कुछ ब्राउज़र, उपयोगकर्ताओं को सर्टिफ़िकेट चुनने की अनुमति देते हैं. ऐसा तब होता है, जब टीएलएस हैंडशेक के हिस्से के तौर पर, टीएलएस सर्वर सर्टिफ़िकेट का अनुरोध करने वाला मैसेज भेजता है. Android 10 के बाद, KeyChain ऑब्जेक्ट, सर्टिफ़िकेट जारी करने वाली संस्थाओं और खास स्पेसिफ़िकेशन पैरामीटर का पालन करते हैं. ऐसा इसलिए, ताकि उपयोगकर्ताओं को सर्टिफ़िकेट चुनने का प्रॉम्प्ट दिखाया जा सके. इसके लिए, KeyChain.choosePrivateKeyAlias() को कॉल किया जाता है. खास तौर पर, इस प्रॉम्प्ट में ऐसे विकल्प नहीं होते जो सर्वर की खास बातों के मुताबिक न हों.

अगर उपयोगकर्ता के पास चुनने के लिए कोई सर्टिफ़िकेट उपलब्ध नहीं है, तो सर्टिफ़िकेट चुनने का अनुरोध नहीं दिखता. ऐसा तब होता है, जब कोई सर्टिफ़िकेट सर्वर की स्पेसिफ़िकेशन से मेल न खाता हो या किसी डिवाइस में कोई सर्टिफ़िकेट इंस्टॉल न हो.

इसके अलावा, KeyChain ऑब्जेक्ट में कुंजियों या सीए सर्टिफ़िकेट इंपोर्ट करने के लिए, Android 10 या इसके बाद के वर्शन पर डिवाइस स्क्रीन लॉक होना ज़रूरी नहीं है.

TLS और क्रिप्टोग्राफ़ी से जुड़े अन्य बदलाव

TLS और क्रिप्टोग्राफ़ी लाइब्रेरी में कुछ छोटे बदलाव हुए हैं. ये बदलाव Android 10 पर लागू होंगे:

  • AES/GCM/NoPadding और ChaCha20/Poly1305/NoPadding सिफर, getOutputSize() से ज़्यादा सटीक बफ़र साइज़ दिखाते हैं.
  • TLS_FALLBACK_SCSV सिफर सुइट को, TLS 1.2 या उससे ज़्यादा के मैक्स प्रोटोकॉल के साथ कनेक्शन की कोशिशों से हटा दिया जाता है. TLS सर्वर के लागू होने में हुए सुधारों की वजह से, हमारा सुझाव है कि आप TLS-बाहरी फ़ॉलबैक की कोशिश न करें. इसके बजाय, हमारा सुझाव है कि आप TLS वर्शन के लिए बातचीत करने की सुविधा का इस्तेमाल करें.
  • ChaCha20-Poly1305, ChaCha20/Poly1305/NoPadding का दूसरा नाम है.
  • आखिर में बिंदु वाले होस्टनेम को एसएनआई होस्टनेम के तौर पर मान्य नहीं माना जाता.
  • सर्टिफ़िकेट के रिस्पॉन्स के लिए साइनिंग पासकोड चुनते समय, CertificateRequest में काम करने वाले_signature_algorithms एक्सटेंशन का इस्तेमाल किया जाता है.
  • Android कीस्टोर जैसी ओपेक साइनिंग पासकोड का इस्तेमाल, TLS में आरएसए-पीएसएस हस्ताक्षर के साथ किया जा सकता है.

Wi-Fi Direct ब्रॉडकास्ट

Android 10 पर, Wi-Fi Direct की सुविधा वाले नीचे दिए गए ब्रॉडकास्ट स्टिकी नहीं हैं:

स्टिकी होने की वजह से, अगर आपके ऐप्लिकेशन ने रजिस्टर किए गए इन ब्रॉडकास्ट को पाने पर भरोसा किया है, तो जानकारी पाने के लिए, शुरू करते समय सही get() तरीके का इस्तेमाल करें.

वाई-फ़ाई अवेयर सुविधाएं

Android 10 में, वाई-फ़ाई अवेयर डेटापाथ का इस्तेमाल करके टीसीपी/यूडीपी सॉकेट बनाने की सुविधा जोड़ी गई है. ServerSocket से कनेक्ट करने वाला टीसीपी/यूडीपी सॉकेट बनाने के लिए, क्लाइंट डिवाइस को सर्वर का आईपीवी6 पता और पोर्ट पता पता होना चाहिए. पहले, इस सुविधा को आउट-ऑफ़-बैंड के बारे में बताने की ज़रूरत होती थी. जैसे, बीटी या वाई-फ़ाई अवेयर लेयर 2 मैसेज सेवा का इस्तेमाल करना या mडीएनएस जैसे दूसरे प्रोटोकॉल की मदद से इन-बैंड का पता लगाना. Android 10 में, नेटवर्क सेटअप के दौरान यह जानकारी शेयर की जा सकती है.

सर्वर इनमें से कोई एक काम कर सकता है:

  • ServerSocket को शुरू करें और इस्तेमाल किए जाने वाले पोर्ट को सेट करें या पाएं.
  • वाई-फ़ाई अवेयर नेटवर्क के अनुरोध के हिस्से के तौर पर, पोर्ट की जानकारी दें.

यहां दिए गए कोड सैंपल में, नेटवर्क अनुरोध के हिस्से के तौर पर पोर्ट की जानकारी देने का तरीका बताया गया है:

Kotlin

val ss = ServerSocket()
val ns = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle)
  .setPskPassphrase("some-password")
  .setPort(ss.localPort)
  .build()

val myNetworkRequest = NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build()

Java

ServerSocket ss = new ServerSocket();
WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier
  .Builder(discoverySession, peerHandle)
  .setPskPassphrase(some-password)
  .setPort(ss.getLocalPort())
  .build();

NetworkRequest myNetworkRequest = new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build();

इसके बाद, क्लाइंट IPv6 और सर्वर से मिले पोर्ट को पाने के लिए, Wi-Fi Aware नेटवर्क का अनुरोध करता है:

Kotlin

val callback = object : ConnectivityManager.NetworkCallback() {
  override fun onAvailable(network: Network) {
    ...
  }
  
  override fun onLinkPropertiesChanged(network: Network,
      linkProperties: LinkProperties) {
    ...
  }

  override fun onCapabilitiesChanged(network: Network,
      networkCapabilities: NetworkCapabilities) {
    ...
    val ti = networkCapabilities.transportInfo
    if (ti is WifiAwareNetworkInfo) {
       val peerAddress = ti.peerIpv6Addr
       val peerPort = ti.port
    }
  }
  override fun onLost(network: Network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback)

Java

callback = new ConnectivityManager.NetworkCallback() {
  @Override
  public void onAvailable(Network network) {
    ...
  }
  @Override
  public void onLinkPropertiesChanged(Network network,
      LinkProperties linkProperties) {
    ...
  }
  @Override
  public void onCapabilitiesChanged(Network network,
      NetworkCapabilities networkCapabilities) {
    ...
    TransportInfo ti = networkCapabilities.getTransportInfo();
    if (ti instanceof WifiAwareNetworkInfo) {
       WifiAwareNetworkInfo info = (WifiAwareNetworkInfo) ti;
       Inet6Address peerAddress = info.getPeerIpv6Addr();
       int peerPort = info.getPort();
    }
  }
  @Override
  public void onLost(Network network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback);

Go डिवाइसों पर SYSTEM_ALERT_WINDOW

Android 10 (Go वर्शन) वाले डिवाइसों पर चलने वाले ऐप्लिकेशन को SYSTEM_ALERT_WINDOW अनुमति नहीं मिल सकती. इसकी वजह यह है कि ओवरले विंडो बनाने के लिए बहुत ज़्यादा मेमोरी का इस्तेमाल होता है. यह कम मेमोरी वाले Android डिवाइसों की परफ़ॉर्मेंस के लिए खास तौर पर नुकसानदेह है.

अगर Android 9 या इससे पहले के वर्शन वाले Go डिवाइस पर चल रहे किसी ऐप्लिकेशन को SYSTEM_ALERT_WINDOW अनुमति मिलती है, तो डिवाइस को Android 10 पर अपग्रेड करने के बाद भी, ऐप्लिकेशन के पास यह अनुमति बनी रहती है. हालांकि, जिन ऐप्लिकेशन के पास पहले से यह अनुमति नहीं है उन्हें डिवाइस अपग्रेड होने के बाद यह अनुमति नहीं दी जा सकती.

अगर Go डिवाइस पर कोई ऐप्लिकेशन, कार्रवाई ACTION_MANAGE_OVERLAY_PERMISSION के साथ कोई इंटेंट भेजता है, तो सिस्टम अपने-आप अनुरोध अस्वीकार कर देता है. साथ ही, उपयोगकर्ता को सेटिंग स्क्रीन पर ले जाता है. इस स्क्रीन पर यह जानकारी दिखती है कि अनुमति नहीं दी जा सकती, क्योंकि इससे डिवाइस की परफ़ॉर्मेंस पर असर पड़ता है. अगर किसी Go डिवाइस पर कोई ऐप्लिकेशन Settings.canDrawOverlays() को कॉल करता है, तो यह तरीका हमेशा गलत दिखाता है. हम दोबारा बताना चाहते हैं कि ये पाबंदियां उन ऐप्लिकेशन पर लागू नहीं होतीं जिन्हें डिवाइस को Android 10 पर अपग्रेड करने से पहले, SYSTEM_ALERT_WINDOW अनुमति मिली थी.

Android के पुराने वर्शन को टारगेट करने वाले ऐप्लिकेशन के लिए चेतावनियां

Android 10 या इसके बाद के वर्शन वाले डिवाइसों पर, पहली बार Android 5.1 (एपीआई लेवल 22) या उससे पहले के वर्शन को टारगेट करने वाले किसी भी ऐप्लिकेशन को चलाने पर, उपयोगकर्ताओं को चेतावनी दी जाती है. अगर ऐप्लिकेशन को उपयोगकर्ता से अनुमतियां चाहिए, तो ऐप्लिकेशन को पहली बार चलाने से पहले, उपयोगकर्ता को ऐप्लिकेशन की अनुमतियों में बदलाव करने का मौका भी दिया जाता है.

Google Play के टारगेट एपीआई लेवल से जुड़ी ज़रूरी शर्तों की वजह से, उपयोगकर्ता को ये चेतावनियां सिर्फ़ तब दिखती हैं, जब वह ऐसा ऐप्लिकेशन चलाता है जिसे हाल ही में अपडेट नहीं किया गया है. अन्य स्टोर से डिस्ट्रिब्यूट किए जाने वाले ऐप्लिकेशन के लिए, टारगेट एपीआई के लिए तय की गई मिलती-जुलती ज़रूरी शर्तें 2019 में लागू होंगी. इन ज़रूरी शर्तों के बारे में ज़्यादा जानकारी के लिए, 2019 में टारगेट एपीआई लेवल की ज़रूरी शर्तों को बढ़ाना देखें.

SHA-2 CBC साइफ़र सुइट हटाए गए

प्लैटफ़ॉर्म से, SHA-2 CBC वाले इन सिफर सुइट को हटा दिया गया है:

  • TLS_RSA_WITH_AES_128_CBC_SHA256
  • TLS_RSA_WITH_AES_256_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

ये सिफर सुइट, GCM का इस्तेमाल करने वाले मिलते-जुलते सिफर सुइट के मुकाबले कम सुरक्षित होते हैं. साथ ही, ज़्यादातर सर्वर इन सिफर सुइट के GCM और CBC, दोनों वैरिएंट के साथ काम करते हैं या फिर इनमें से किसी के साथ भी काम नहीं करते.

ऐप्लिकेशन का उपयोग

Android 10 में ऐप्लिकेशन के इस्तेमाल से जुड़े ये बदलाव किए गए हैं:

  • इसके अलावा, Android 10, इंस्टैंट ऐप्लिकेशन के इस्तेमाल को सही तरीके से ट्रैक करता है.

एचटीटीपीएस कनेक्शन में बदलाव

अगर Android 10 चलाने वाला कोई ऐप्लिकेशन null को setSSLSocketFactory() में पास करता है, तो यह IllegalArgumentException होगा. पिछले वर्शन में, null को setSSLSocketFactory() में पास करने का असर, मौजूदा डिफ़ॉल्ट फ़ैक्ट्री को पास करने जैसा ही होता था.

android.preference लाइब्रेरी अब काम नहीं करती

android.preference लाइब्रेरी, Android 10 के साथ काम नहीं करती. इसके बजाय, डेवलपर को Android Jetpack का हिस्सा, AndroidX की प्राथमिकता लाइब्रेरी का इस्तेमाल करना चाहिए. माइग्रेशन और डेवलपमेंट में मदद करने वाले अन्य संसाधनों के लिए, अपडेट की गई सेटिंग की गाइड देखें. साथ ही, हमारे सार्वजनिक सैंपल ऐप्लिकेशन और रेफ़रंस दस्तावेज़ देखें.

ZIP फ़ाइल की यूटिलिटी लाइब्रेरी में हुए बदलाव

Android 10 में java.util.zip पैकेज की क्लास में ये बदलाव किए गए हैं, जो ZIP फ़ाइलों को मैनेज करते हैं. इन बदलावों से, Android और java.util.zip का इस्तेमाल करने वाले अन्य प्लैटफ़ॉर्म पर, लाइब्रेरी के काम करने का तरीका एक जैसा हो जाता है.

इनफ़्लेटर

पिछले वर्शन में, end() को कॉल करने के बाद Inflater क्लास के कुछ तरीकों को शुरू करने पर, IllegalStateException का मैसेज दिखता था. Android 10 में, इन तरीकों के बजाय NullPointerException का इस्तेमाल किया जाता है.

ज़िपफ़ाइल

Android 10 और उसके बाद वाले वर्शन में, ZipFile के लिए कंस्ट्रक्टर जो File, int, और Charset टाइप के आर्ग्युमेंट लेता है, अगर दी गई ZIP फ़ाइल में कोई फ़ाइल नहीं है, तो यह ZipException नहीं करता.

ZipOutputStream

Android 10 और उसके बाद के वर्शन में, ZipOutputStream में मौजूद finish() तरीके से ऐसी ZIP फ़ाइल के लिए कोई आउटपुट स्ट्रीम लिखने की कोशिश करने पर ZipException नहीं मिलता जिसमें कोई फ़ाइल नहीं होती.

कैमरे में बदलाव

कैमरे का इस्तेमाल करने वाले कई ऐप्लिकेशन को लगता है कि अगर डिवाइस पोर्ट्रेट कॉन्फ़िगरेशन में है, तो फ़िज़िकल डिवाइस भी पोर्ट्रेट ओरिएंटेशन में है, जैसा कि कैमरा ओरिएंटेशन में बताया गया है. पहले यह माना जाता था कि फ़ोन के फ़ॉर्म फ़ैक्टर में कोई बदलाव नहीं होगा. हालांकि, फ़ोल्ड किए जा सकने वाले फ़ोन जैसे फ़ॉर्म फ़ैक्टर के उपलब्ध होने से यह बात बदल गई है. इन डिवाइसों पर यह मानने पर, कैमरे के व्यूफ़ाइंडर को गलत तरीके से घुमाया या स्केल किया जा सकता है. इसके अलावा, ऐसा भी हो सकता है कि उसे दोनों तरीकों से घुमाया या स्केल किया जाए.

एपीआई लेवल 24 या उसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन में, android:resizeableActivity को साफ़ तौर पर सेट करना चाहिए. साथ ही, मल्टी-विंडो ऑपरेशन को मैनेज करने के लिए, ज़रूरी फ़ंक्शन भी उपलब्ध कराने चाहिए.

बैटरी खर्च को ट्रैक करना

Android 10 और इसके बाद के वर्शन में, SystemHealthManager बैटरी खर्च के आंकड़े रीसेट कर देता है. ऐसा तब किया जाता है, जब बड़ी बैटरी चार्ज करने की किसी घटना के बाद डिवाइस का अनप्लग हो जाता है. आम तौर पर, चार्जिंग का कोई बड़ा इवेंट तब होता है, जब डिवाइस पूरी तरह चार्ज हो जाता है या डिवाइस की बैटरी पूरी तरह खत्म होने के बाद, ज़्यादातर चार्ज हो जाती है.

Android 10 से पहले, डिवाइस को चार्जिंग से हटाने पर बैटरी के इस्तेमाल के आंकड़े रीसेट हो जाते थे. भले ही, बैटरी के लेवल में थोड़ा सा भी बदलाव हुआ हो.

Android बीम की सुविधा बंद होना

हम Android 10 में, Android Beam की सुविधा को आधिकारिक तौर पर बंद कर रहे हैं. यह सुविधा, नियर फ़ील्ड कम्यूनिकेशन (एनएफ़सी) की मदद से, एक डिवाइस से दूसरे डिवाइस पर डेटा शेयर करने की पुरानी सुविधा है. हम NFC से जुड़े कई एपीआई भी बंद कर रहे हैं. Android Beam, डिवाइस बनाने वाले उन पार्टनर के लिए उपलब्ध है जो इसका इस्तेमाल करना चाहते हैं. हालांकि, इसे अब डेवलप नहीं किया जा रहा है. Android, NFC की अन्य सुविधाओं और एपीआई के साथ काम करता रहेगा. साथ ही, टैग से डेटा पढ़ने और पेमेंट करने जैसे काम उम्मीद के मुताबिक चलते रहेंगे.

java.math.BigDecimal.stripTraLINGzeros() के व्यवहार में बदलाव

इनपुट वैल्यू शून्य होने पर, BigDecimal.stripTrailingZeros() खास केस के तौर पर आखिरी शून्यों को सुरक्षित नहीं रखता है.

java.util.regex.Matcher और Pattern के काम करने के तरीके में बदलाव

इनपुट की शुरुआत में शून्य-चौड़ाई का मिलान होने पर split() के नतीजे को बदलकर, अब खाली String ("") से शुरू नहीं किया गया था. इससे String.split() पर भी असर पड़ता है. उदाहरण के लिए, अब "x".split("") नतीजे के तौर पर {"x"} दिखाता है, जबकि Android के पुराने वर्शन पर यह {"", "x"} दिखाता है. "aardvark".split("(?=a)" अब {"", "a", "ardv", "ark"} के बजाय {"a", "ardv", "ark"} दिखाता है.

अमान्य आर्ग्युमेंट के लिए अपवाद का व्यवहार भी बेहतर बनाया गया है:

  • अगर बदले गए टेक्स्ट String में आखिर में एक बैकस्लैश है, जो गैर-कानूनी है, तो appendReplacement(StringBuffer, String) अब IndexOutOfBoundsException के बजाय IllegalArgumentException दिखाता है. अगर बदले जाने वाले String के आखिर में $ है, तो अब वही अपवाद दिखेगा. पहले, इस स्थिति में कोई अपवाद नहीं था.
  • अगर Matcher से NullPointerException मिलता है, तो replaceFirst(null) अब reset() को कॉल नहीं करता. अब NullPointerException तब भी दिखता है, जब कोई मैच न मिले. पहले, यह सिर्फ़ मैच होने पर दिखता था.
  • अगर ग्रुप इंडेक्स सीमा से बाहर है, तो start(int group), end(int group), और group(int group) अब ज़्यादा सामान्य IndexOutOfBoundsException देते हैं. पहले, इन तरीकों में ArrayIndexOutOfBoundsException दिया जाता था.

GradientDrawable के लिए डिफ़ॉल्ट ऐंगल अब TOP_BOTTOM है

Android 10 में, अगर एक्सएमएल में GradientDrawable तय किया जाता है और ऐंगल मेज़रमेंट नहीं दिया जाता है, तो ग्रेडिएंट ओरिएंटेशन डिफ़ॉल्ट रूप से TOP_BOTTOM पर सेट हो जाता है. यह Android के पिछले वर्शन से अलग है, जहां डिफ़ॉल्ट तौर पर LEFT_RIGHT था.

इस समस्या को हल करने के लिए, AAPT2 के सबसे नए वर्शन पर अपडेट करें. अगर ऐंगल का कोई मेज़रमेंट नहीं दिया गया है, तो टूल लेगसी ऐप्लिकेशन के लिए ऐंगल का मेज़रमेंट 0 पर सेट कर देता है.

डिफ़ॉल्ट SUID का इस्तेमाल करके, क्रम से लगाए गए ऑब्जेक्ट के लिए लॉग इन करना

Android 7.0 (एपीआई लेवल 24) के बाद से, इस प्लैटफ़ॉर्म ने क्रम से लगाए जा सकने वाले ऑब्जेक्ट के लिए, डिफ़ॉल्ट serialVersionUID को ठीक किया. इस सुधार का असर, एपीआई लेवल 23 या उससे पहले के लेवल को टारगेट करने वाले ऐप्लिकेशन पर नहीं पड़ा.

अगर कोई ऐप्लिकेशन, एपीआई लेवल 23 या इससे पहले के वर्शन को टारगेट करता है और पुराने, गलत, डिफ़ॉल्ट serialVersionUID का इस्तेमाल करता है, तो सिस्टम चेतावनी लॉग करता है और कोड में सुधार करने का सुझाव देता है.

खास तौर पर, अगर नीचे दी गई सभी बातें सही हैं, तो सिस्टम एक चेतावनी लॉग करता है:

  • ऐप्लिकेशन, एपीआई लेवल 23 या उससे पहले के वर्शन को टारगेट करता हो.
  • क्लास को सीरियल के तौर पर सेट किया जाता है.
  • सीरियलाइज़ की गई क्लास, serialVersionUID को साफ़ तौर पर सेट करने के बजाय, डिफ़ॉल्ट serialVersionUID का इस्तेमाल करती है.
  • डिफ़ॉल्ट serialVersionUID, उस serialVersionUID से अलग होता है जो ऐप्लिकेशन के टारगेट एपीआई लेवल 24 या उसके बाद के लेवल के हिसाब से होता है.

जिन क्लास पर असर पड़ा है उनके लिए, यह चेतावनी एक बार लॉग की जाती है. चेतावनी वाले मैसेज में, समस्या को ठीक करने का सुझाव दिया गया है. इसके मुताबिक, serialVersionUID को साफ़ तौर पर उस डिफ़ॉल्ट वैल्यू पर सेट करना होगा जो ऐप्लिकेशन के टारगेट एपीआई लेवल 24 या उसके बाद के वर्शन के हिसाब से कैलकुलेट की जाएगी. इस सुधार का इस्तेमाल करके, यह पक्का किया जा सकता है कि अगर उस क्लास का कोई ऑब्जेक्ट, एपीआई लेवल 23 या उससे पहले के लेवल को टारगेट करने वाले ऐप्लिकेशन पर क्रम से रखा गया है, तो उस ऑब्जेक्ट को 24 या उससे बाद के लेवल को टारगेट करने वाले ऐप्लिकेशन सही ढंग से पढ़ पाएंगे.

java.io.FileChannel.map() में हुए बदलाव

Android 10 से, /dev/zero जैसी नॉन-स्टैंडर्ड फ़ाइलों के लिए FileChannel.map() का इस्तेमाल नहीं किया जा सकता. इन फ़ाइलों का साइज़, truncate() का इस्तेमाल करके बदला नहीं जा सकता. Android के पिछले वर्शन में, truncate() से मिले errno को अनदेखा कर दिया जाता था. हालांकि, Android 10 में IOException का मैसेज दिखता है. अगर आपको पुराना व्यवहार चाहिए, तो आपको नेटिव कोड का इस्तेमाल करना होगा.