Android 4.3 API

एपीआई लेवल: 18

Android 4.3 (JELLY_BEAN_MR2), Jelly Bean रिलीज़ का अपडेट है. इसमें उपयोगकर्ताओं और ऐप्लिकेशन डेवलपर के लिए नई सुविधाएं उपलब्ध हैं. इस दस्तावेज़ में उन लेखों के बारे में नए एपीआई हैं.

ऐप्लिकेशन डेवलपर के रूप में, आपको Android 4.3 सिस्टम इमेज डाउनलोड करनी चाहिए और SDK Manager से SDK प्लैटफ़ॉर्म जल्द से जल्द. यदि आपके पास Android 4.3 चलाने वाला डिवाइस नहीं है जिस पर अपने ऐप की जाँच करने के लिए, Android 4.3 सिस्टम का उपयोग करें Android एम्युलेटर पर अपने ऐप्लिकेशन की जांच करने के लिए इमेज का इस्तेमाल करें. इसके बाद Android 4.3 प्लेटफ़ॉर्म के लिए अपने ऐप्लिकेशन बनाएं, ताकि आप एपीआई के सबसे नए वर्शन पर भी काम करता है.

अपने टारगेट एपीआई लेवल को अपडेट करना

Android 4.3 पर चलने वाले डिवाइसों के लिए, अपने ऐप्लिकेशन को बेहतर तरीके से ऑप्टिमाइज़ करने के लिए, आपको अपने targetSdkVersion को "18" पर सेट करना चाहिए. इसके बाद, इसे Android 4.3 सिस्टम इमेज पर इंस्टॉल करें और जांच करें. इसके बाद, इस बदलाव के साथ अपडेट पब्लिश करें.

आप Android 4.3 में API का उपयोग कर सकते हैं, जबकि पुराने वर्शन का भी समर्थन कर सकते हैं: अपने कोड की ऐसी शर्तें सेट करें जो लागू करने से पहले सिस्टम के एपीआई लेवल की जांच करती हैं ऐसे एपीआई जो आपके minSdkVersion पर काम नहीं करते. पुराने वर्शन के साथ काम करने की सुविधा बनाए रखने के बारे में ज़्यादा जानने के लिए, अलग-अलग प्लैटफ़ॉर्म के वर्शन के साथ काम करने की सुविधा लेख पढ़ें.

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

एपीआई लेवल के काम करने के तरीके के बारे में ज़्यादा जानने के लिए, एपीआई लेवल क्या है? लेख पढ़ें

व्यवहार में होने वाले अहम बदलाव

अगर आपने Android के लिए पहले कोई ऐप्लिकेशन पब्लिश किया था, तो ध्यान रखें कि आपका ऐप्लिकेशन Android 4.3 में हुए बदलावों का असर पड़ता है.

अगर आपका ऐप्लिकेशन इंप्लिसिट इंटेंट का इस्तेमाल करता है...

आपका ऐप्लिकेशन, प्रतिबंधित प्रोफ़ाइल में शायद ठीक से काम न करे.

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

किसी इंप्लिसिट इंटेंट का इस्तेमाल करते समय, आपको हमेशा यह पुष्टि करनी चाहिए कि resolveActivity() या queryIntentActivities() को कॉल करके, इंटेंट को मैनेज करने के लिए कोई ऐप्लिकेशन उपलब्ध है या नहीं. उदाहरण के लिए:

Kotlin

val intent = Intent(Intent.ACTION_SEND)
...
if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
} else {
    Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show()
}

Java

Intent intent = new Intent(Intent.ACTION_SEND);
...
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
} else {
    Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show();
}

अगर आपका ऐप्लिकेशन खातों पर निर्भर करता है...

आपका ऐप्लिकेशन, प्रतिबंधित प्रोफ़ाइल में शायद ठीक से काम न करे.

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

अगर आपको पाबंदी वाली प्रोफ़ाइलों को अपने ऐप्लिकेशन का इस्तेमाल करने से पूरी तरह से रोकना है, क्योंकि आपका ऐप्लिकेशन संवेदनशील खाता जानकारी पर निर्भर करता है, तो अपने मेनिफ़ेस्ट के <application> एलिमेंट में android:requiredAccountType एट्रिब्यूट की वैल्यू सबमिट करें.

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

अगर आपका ऐप्लिकेशन VideoView का इस्तेमाल करता है, तो...

Android 4.3 पर आपका वीडियो छोटा दिख सकता है.

Android के पिछले वर्शन में, VideoView विजेट ने layout_height और layout_width के लिए "wrap_content" वैल्यू को गलत तरीके से "match_parent" के तौर पर कैलकुलेट किया था. इसलिए, हो सकता है कि पहले ऊंचाई या चौड़ाई के लिए "wrap_content" का इस्तेमाल करने पर, आपको अपनी पसंद का वीडियो लेआउट मिल गया हो. हालांकि, ऐसा करने पर Android 4.3 और उसके बाद के वर्शन पर, वीडियो का साइज़ बहुत छोटा हो सकता है. समस्या को ठीक करने के लिए, "wrap_content" को "match_parent" से बदलें. साथ ही, पुष्टि करें कि आपका वीडियो Android 4.3 और इससे पुराने वर्शन पर सही तरीके से दिख रहा है.

प्रतिबंधित प्रोफ़ाइल

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

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

अपने BroadcastReceiver के onReceive() तरीके में, आपको अपने ऐप्लिकेशन की हर पाबंदी के लिए एक RestrictionEntry बनाना होगा. हर RestrictionEntry में पाबंदी का टाइटल, ब्यौरा, और इनमें से कोई एक डेटा टाइप होता है:

  • TYPE_BOOLEAN, किसी ऐसी पाबंदी के लिए है जो सही या गलत हो सकती है.
  • ऐसी पाबंदी के लिए TYPE_CHOICE जिसमें एकाधिक विकल्प जो पारस्परिक रूप से विशिष्ट हैं (रेडियो बटन विकल्प).
  • इस पाबंदी के लिए TYPE_MULTI_SELECT में ऐसे कई विकल्प हैं जो म्यूचुअली एक्सक्लूसिव (चेकबॉक्स विकल्प) नहीं हैं.

इसके बाद, सभी RestrictionEntry ऑब्जेक्ट को एक ArrayList में रखा जाता है और उसे ब्रॉडकास्ट रिसीवर के नतीजे में, EXTRA_RESTRICTIONS_LIST अतिरिक्त.

सिस्टम, सेटिंग ऐप्लिकेशन में आपके ऐप्लिकेशन की पाबंदियों के लिए यूज़र इंटरफ़ेस (यूआई) बनाता है और हर एक को सेव करता है हर RestrictionEntry के लिए, आपकी दी गई यूनीक कुंजी के साथ पाबंदी ऑब्जेक्ट है. जब उपयोगकर्ता आपका ऐप्लिकेशन खोलता है, तो आप getApplicationRestrictions() पर कॉल किया जा रहा है. यह हर पाबंदी के लिए, की-वैल्यू पेयर वाला Bundle दिखाता है आपने RestrictionEntry ऑब्जेक्ट की मदद से तय किया है.

अगर आपको ऐसी खास पाबंदियां देनी हैं जिन्हें बूलियन, एक विकल्प, और कई विकल्प वाली वैल्यू से मैनेज नहीं किया जा सकता, तो कोई ऐसी गतिविधि बनाएं जिसमें उपयोगकर्ता पाबंदियां तय कर सकें. साथ ही, उपयोगकर्ताओं को पाबंदी की सेटिंग से उस गतिविधि को खोलने की अनुमति दें. अपने ब्रॉडकास्ट रिसीवर में, नतीजे Bundle में EXTRA_RESTRICTIONS_INTENT एक्सट्रा शामिल करें. इस अतिरिक्त सुविधा में Intent तय होना चाहिए यह दिखाता है कि Activity क्लास लॉन्च करनी है (इसका इस्तेमाल करें इंटेंट के साथ EXTRA_RESTRICTIONS_INTENT पास करने के लिए putParcelable() तरीका). जब प्राइमरी उपयोगकर्ता अपनी पसंद के मुताबिक पाबंदियां सेट करने के लिए आपकी गतिविधि डालेगा, तो आपका गतिविधि को फिर EXTRA_RESTRICTIONS_LIST या EXTRA_RESTRICTIONS_BUNDLE कुंजी, जो इस बात पर निर्भर करता है कि RestrictionEntry ऑब्जेक्ट या की-वैल्यू पेयर, क्रम से हैं.

प्रतिबंधित प्रोफ़ाइल में खाते जोड़ना

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

  • प्रतिबंधित प्रोफ़ाइल से, मालिक के खातों को ऐक्सेस करने की अनुमति दें.

    पाबंदी वाली प्रोफ़ाइल से किसी खाते का ऐक्सेस पाने के लिए, आपको <application> टैग में android:restrictedAccountType एट्रिब्यूट जोड़ना होगा:

    <application ...
        android:restrictedAccountType="com.example.account.type" >

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

  • अगर आप खातों में बदलाव नहीं कर पा रहे हैं, तो कुछ सुविधाएं बंद कर दें.

    अगर आपको खातों का इस्तेमाल करना है, लेकिन असल में उन्हें अपने ऐप्लिकेशन के मुख्य की सुविधा है, तो आप खाते की उपलब्धता देख सकते हैं और सुविधाएं उपलब्ध न होने पर उन्हें बंद कर सकते हैं. सबसे पहले, यह देख लें कि आपके पास कोई मौजूदा खाता है या नहीं. अगर ऐसा नहीं है, तो यह क्वेरी करें कि getUserRestrictions() पर कॉल करके नया खाता बनाया जा सकता है और नतीजे में DISALLOW_MODIFY_ACCOUNTS की अतिरिक्त जांच की जा सकती है. अगर यह true है, तो आपको अपने ऐप्लिकेशन की उस सुविधा को बंद कर देना चाहिए जिसके लिए खातों को ऐक्सेस करने की ज़रूरत है. उदाहरण के लिए:

    Kotlin

    val um = context.getSystemService(Context.USER_SERVICE) as UserManager
    val restrictions: Bundle = um.userRestrictions
    if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
        // cannot add accounts, disable some functionality
    }

    Java

    UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
    Bundle restrictions = um.getUserRestrictions();
    if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
        // cannot add accounts, disable some functionality
    }

    ध्यान दें: इस स्थिति में, आपको अपनी मेनिफ़ेस्ट फ़ाइल में किसी भी नए एट्रिब्यूट का एलान नहीं करना चाहिए.

  • निजी खातों को ऐक्सेस न कर पाने पर, अपना ऐप्लिकेशन बंद कर दें.

    इसके बजाय, अगर पाबंदी वाली प्रोफ़ाइलों के लिए आपका ऐप्लिकेशन उपलब्ध नहीं है, तो आपका ऐप्लिकेशन, खाते में मौजूद संवेदनशील निजी जानकारी (न कि प्रतिबंधित प्रोफ़ाइल) पर निर्भर करता है वर्तमान में नए खाते नहीं जोड़े जा सकते), जोड़ें <application> टैग के लिए android:requiredAccountType एट्रिब्यूट:

    <application ...
        android:requiredAccountType="com.example.account.type" >

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

  • वायरलेस और कनेक्टिविटी

    ब्लूटूथ कम ऊर्जा (स्मार्ट रेडी)

    Android अब android.bluetooth में नए एपीआई के साथ, ब्लूटूथ स्मार्ट (LE) के साथ काम करता है. नए एपीआई की मदद से, ऐसे Android ऐप्लिकेशन बनाए जा सकते हैं जो ब्लूटूथ लो एनर्जी डिवाइसों के साथ काम करते हैं. जैसे, हृदय की गति दिखाने वाले मॉनिटर और पैडोमीटर.

    क्योंकि Bluetooth LE एक हार्डवेयर सुविधा है, जो Android पर चलने वाले डिवाइस, तो आपको अपनी मेनिफ़ेस्ट फ़ाइल में <uses-feature> का एलान करना होगा "android.hardware.bluetooth_le" के लिए एलिमेंट:

    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />

    अगर आप Android के क्लासिक ब्लूटूथ एपीआई के बारे में पहले से जानते हैं, तो ध्यान दें कि ब्लूटूथ LE API में कुछ अंतर हैं. सबसे अहम बात यह है कि अब एक BluetoothManager क्लास मौजूद है जिसका इस्तेमाल आपको कुछ हाई लेवल की कार्रवाइयों के लिए करना चाहिए जैसे, BluetoothAdapter हासिल करना, और किसी डिवाइस की स्थिति की जाँच की जा रही है. उदाहरण के लिए, अब आपको BluetoothAdapter पाने का यह तरीका अपनाना चाहिए:

    Kotlin

    val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
    bluetoothAdapter = bluetoothManager.adapter

    Java

    final BluetoothManager bluetoothManager =
            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    bluetoothAdapter = bluetoothManager.getAdapter();

    ब्लूटूथ LE वाले सहायक डिवाइस (जैसे, कीबोर्ड, माउस, मॉनिटर, वेबकैम वगैरह) का पता लगाने के लिए, BluetoothAdapter पर startLeScan() को कॉल करें. इसके बाद, इसे लागू करें BluetoothAdapter.LeScanCallback के इंटरफ़ेस में से एक है. जब ब्लूटूथ अडैप्टर, ब्लूटूथ LE वाले सहायक डिवाइस का पता लगाता है. ऐसा करने पर, आपके BluetoothAdapter.LeScanCallback को लागू करने के लिए onLeScan() तरीका. यह तरीका आपको BluetoothDevice ऑब्जेक्ट देता है, जो डिवाइस की पहचान की गई, उस डिवाइस की आरएसएसआई वैल्यू, और एक बाइट अरे जिसमें डिवाइस विज्ञापन रिकॉर्ड.

    अगर आपको सिर्फ़ खास तरह के सहायक डिवाइसों (जैसे, कीबोर्ड, माउस, मॉनिटर, वेबकैम वगैरह) के लिए स्कैन करना है, तो startLeScan() को कॉल करके UUID ऑब्जेक्ट का कलेक्शन शामिल किया जा सकता है. इससे पता चलता है कि आपका ऐप्लिकेशन किन GATT सेवाओं के साथ काम करता है.

    ध्यान दें: सिर्फ़ ब्लूटूथ एलई डिवाइसों को स्कैन किया जा सकता है या पिछले एपीआई का इस्तेमाल करके, क्लासिक ब्लूटूथ डिवाइसों को स्कैन किया जा सकता है. एक साथ, LE और क्लासिक ब्लूटूथ डिवाइसों को स्कैन नहीं किया जा सकता.

    इसके बाद, ब्लूटूथ एलई डिवाइस से कनेक्ट करने के लिए, उससे जुड़े BluetoothDevice ऑब्जेक्ट पर connectGatt() को कॉल करें. साथ ही, उसे BluetoothGattCallback को लागू करने का तरीका दें. BluetoothGattCallback को लागू करने पर, आपको कनेक्टिविटी से जुड़े कॉलबैक मिलते हैं स्थिति डिवाइस और अन्य इवेंट के साथ दिखाई देती है. onConnectionStateChange() callback के दौरान, डिवाइस से बातचीत शुरू की जा सकती है. हालांकि, इसके लिए ज़रूरी है कि नई स्थिति के तौर पर STATE_CONNECTED को पास किया गया हो.

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

    सिर्फ़ वाई-फ़ाई स्कैन करने वाला मोड

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

    अगर आपको उपयोगकर्ता की जगह की जानकारी चाहिए, लेकिन वाई-फ़ाई फ़िलहाल बंद है, तो उपयोगकर्ता से ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE ऐक्शन के साथ startActivity() को कॉल करके, सिर्फ़ वाई-फ़ाई स्कैन मोड चालू करने का अनुरोध किया जा सकता है.

    वाई-फ़ाई कॉन्फ़िगरेशन

    नए WifiEnterpriseConfig एपीआई की मदद से, एंटरप्राइज़ के हिसाब से बनाई गई सेवाएं, मैनेज किए जा रहे डिवाइसों के लिए वाई-फ़ाई कॉन्फ़िगरेशन को अपने-आप सेट कर सकती हैं.

    इनकमिंग कॉल के लिए पहले से तैयार जवाब

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

    जब उपयोगकर्ता पहले से तैयार जवाब के साथ किसी इनकमिंग कॉल का जवाब देता है, तो फ़ोन ऐप्लिकेशन यूआरआई के साथ ACTION_RESPOND_VIA_MESSAGE इंटेंट मैसेज पाने वाले (कॉलर) और EXTRA_TEXT की अन्य जानकारी के बारे में जिस मैसेज को उपयोगकर्ता भेजना चाहता है. जब आपकी सेवा को यह मकसद मिलता है, तो उसे यह बताना चाहिए कि और तुरंत अपने-आप बंद हो जाता है (आपके ऐप्लिकेशन को कोई गतिविधि नहीं दिखानी चाहिए).

    यह इंटेंट पाने के लिए, आपको SEND_RESPOND_VIA_MESSAGE की अनुमति का एलान करना होगा.

    मल्टीमीडिया

    MediaExtractor और MediaCodec को बेहतर बनाने की सुविधा

    Android अब आपके लिए अपना डाइनैमिक अडैप्टिव लिखना आसान बनाता है ISO/IEC 23009-1 मानक के अनुसार एचटीटीपी (DASH) प्लेयर पर स्ट्रीमिंग, MediaCodec और MediaExtractor में मौजूदा एपीआई का इस्तेमाल करके. इन एपीआई के फ़्रेमवर्क को अपडेट किया गया है, ताकि वे फ़्रैगमेंट वाली MP4 फ़ाइलों को पार्स कर सकें. हालांकि, एमपीडी मेटाडेटा को पार्स करने और अलग-अलग स्ट्रीम को MediaExtractor को पास करने की ज़िम्मेदारी अब भी आपके ऐप्लिकेशन की है.

    अगर आपको एन्क्रिप्ट (सुरक्षित) किए गए कॉन्टेंट के साथ DASH का इस्तेमाल करना है, तो ध्यान दें कि getSampleCryptoInfo() तरीका, एन्क्रिप्ट (सुरक्षित) किए गए हर मीडिया के स्ट्रक्चर की जानकारी देने वाला MediaCodec.CryptoInfo मेटाडेटा दिखाता है सैंपल. साथ ही, getPsshInfo() तरीका MediaExtractor में जोड़ा गया है, ताकि आप अपने DASH मीडिया के लिए PSSH मेटाडेटा को ऐक्सेस कर सकें. यह तरीका UUID ऑब्जेक्ट को बाइट में मैप करता है, जिसमें UUID क्रिप्टो स्कीम के बारे में बताता है और बाइट डेटा के हिसाब से हैं उस स्कीम को आज़माएं.

    मीडिया के लिए डीआरएम

    नई MediaDrm क्लास, डिजिटल अधिकारों के लिए मॉड्यूलर समाधान उपलब्ध कराती है मीडिया प्लेबैक से DRM समस्याओं को अलग करके अपने मीडिया कॉन्टेंट के साथ मैनेजमेंट (डीआरएम) कर सकते हैं. उदाहरण के लिए, एपीआई को अलग करने की सुविधा की मदद से, Widevine मीडिया फ़ॉर्मैट का इस्तेमाल किए बिना, Widevine से एन्क्रिप्ट (सुरक्षित) किया गया कॉन्टेंट चलाया जा सकता है. यह डीआरएम सलूशन, DASH कॉमन एन्क्रिप्शन के साथ भी काम करता है. इससे, स्ट्रीमिंग कॉन्टेंट के साथ कई तरह के डीआरएम स्कीम का इस्तेमाल किया जा सकता है.

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

    MediaDrm एपीआई को, MediaCodec एपीआई जिन्हें Android 4.1 (एपीआई लेवल 16) में पेश किया गया था, इसमें आपके कॉन्टेंट को कोड में बदलने और डिकोड करने के लिए, MediaCodec, एन्क्रिप्ट (सुरक्षित) किए गए कॉन्टेंट को मैनेज करने के लिए MediaCrypto, और MediaExtractor शामिल हैं करने के लिए डिज़ाइन किया गया है.

    पहले आपको MediaExtractor बनाना होगा और MediaCodec ऑब्जेक्ट. इसके बाद, आम तौर पर कॉन्टेंट के मेटाडेटा से, डीआरएम-स्कीम की पहचान करने वाले UUID को ऐक्सेस किया जा सकता है. साथ ही, इसका इस्तेमाल अपने कन्स्ट्रक्टर के साथ MediaDrm ऑब्जेक्ट का उदाहरण बनाने के लिए किया जा सकता है.

    किसी प्लैटफ़ॉर्म से वीडियो को कोड में बदलने का तरीका

    Android 4.1 (एपीआई लेवल 16) ने MediaCodec क्लास को कम लेवल के लिए जोड़ा मीडिया कॉन्टेंट को कोड में बदलने और डिकोड करने की सुविधा. वीडियो को एन्कोड करते समय, Android 4.1 के लिए ज़रूरी है कि आप मीडिया को ByteBuffer कलेक्शन के साथ दें. हालांकि, Android 4.3 में अब एन्कोडर के इनपुट के तौर पर Surface का इस्तेमाल किया जा सकता है. उदाहरण के लिए, यह आपको इनपुट को एन्कोड करने की या OpenGL ES से जनरेट किए गए फ़्रेम का इस्तेमाल करके.

    अपने एन्कोडर में इनपुट के तौर पर Surface का इस्तेमाल करने के लिए, पहले MediaCodec को configure() पर कॉल करें. इसके बाद, Surface पाने के लिए createInputSurface() को कॉल करें. इस Surface की मदद से, मीडिया स्ट्रीम किया जा सकता है.

    उदाहरण के लिए, OpenGL की विंडो के तौर पर दिए गए Surface का इस्तेमाल किया जा सकता है संदर्भ के बारे में जानने के लिए उसे eglCreateWindowSurface() को पास करें. इसके बाद, सरफ़ेस को रेंडर करते समय, फ़्रेम को MediaCodec को पास करने के लिए, eglSwapBuffers() को कॉल करें.

    एन्कोडिंग शुरू करने के लिए, MediaCodec पर start() को कॉल करें. वीडियो को एन्कोड करने के बाद, एन्कोडिंग बंद करने के लिए signalEndOfInputStream() पर और Surface पर release() पर कॉल करें.

    मीडिया मल्टीप्लेक्सिंग

    नई MediaMuxer क्लास की मदद से, एक ऑडियो स्ट्रीम के बीच मल्टीप्लेक्सिंग की जा सकती है और एक वीडियो स्ट्रीम. ये एपीआई, मीडिया को अलग-अलग चैनलों में बांटने (डि-मल्टीप्लेक्स करने) के लिए, Android 4.2 में जोड़े गए MediaExtractor क्लास के साथ काम करते हैं.

    इस्तेमाल किए जा सकने वाले आउटपुट फ़ॉर्मैट, MediaMuxer.OutputFormat में बताए गए हैं. फ़िलहाल, सिर्फ़ MP4 आउटपुट फ़ॉर्मैट का इस्तेमाल किया जा सकता है. साथ ही, MediaMuxer में एक बार में सिर्फ़ एक ऑडियो स्ट्रीम और/या एक वीडियो स्ट्रीम का इस्तेमाल किया जा सकता है.

    MediaMuxer को ज़्यादातर MediaCodec के साथ काम करने के लिए डिज़ाइन किया गया है, ताकि MediaCodec की मदद से वीडियो प्रोसेस किया जा सके. इसके बाद, MediaMuxer की मदद से आउटपुट को MP4 फ़ाइल में सेव किया जा सके. मीडिया में बदलाव करने के लिए, MediaMuxer को MediaExtractor के साथ भी इस्तेमाल किया जा सकता है. इसके लिए, आपको मीडिया को कोड में बदलने या उसे डिकोड करने की ज़रूरत नहीं पड़ेगी.

    RemoteControlClient के लिए, प्लेबैक की प्रोग्रेस और स्क्रेबिंग

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

    सबसे पहले, आपको FLAG_KEY_MEDIA_POSITION_UPDATE फ़्लैग को चालू करना होगा. इसके लिए, इसे setTransportControlsFlags().

    इसके बाद, इन दो नए इंटरफ़ेस को लागू करें:

    RemoteControlClient.OnGetPlaybackPositionListener
    इसमें कॉलबैक onGetPlaybackPosition() भी शामिल है. यह आपके मीडिया की मौजूदा स्थिति का अनुरोध करता है, जब रिमोट कंट्रोल को अपने यूज़र इंटरफ़ेस (यूआई) में प्रोग्रेस अपडेट करनी होती है.
    RemoteControlClient.OnPlaybackPositionUpdateListener
    इसमें कॉलबैक onPlaybackPositionUpdate() शामिल है, जो यह आपके ऐप्लिकेशन को आपके मीडिया के लिए एक नया टाइम कोड बताता है. ऐसा तब होता है, जब उपयोगकर्ता रिमोट कंट्रोल यूज़र इंटरफ़ेस (यूआई).

    वीडियो को नई जगह पर चलाने के बाद, setPlaybackState() को कॉल करके, वीडियो के चलने की नई स्थिति, जगह, और स्पीड के बारे में बताएं.

    इन इंटरफ़ेस के साथ, आप setOnGetPlaybackPositionListener() को कॉल करके और इन्हें अपने RemoteControlClient के लिए सेट कर सकते हैं setPlaybackPositionUpdateListener().

    ग्राफ़िक्स

    OpenGL ES 3.0 के साथ काम करने की सुविधा

    Android 4.3 में OpenGL ES 3.0 के लिए Java इंटरफ़ेस और नेटिव सपोर्ट की सुविधा मिलती है. मुख्य नई सुविधा OpenGL ES 3.0 में दिए गए विकल्पों में ये शामिल हैं:

    • बेहतर विज़ुअल इफ़ेक्ट इस्तेमाल करने की सुविधा
    • स्टैंडर्ड सुविधा के तौर पर, अच्छी क्वालिटी वाले ETC2/EAC टेक्सचर कंप्रेस करने की सुविधा
    • पूर्णांक और 32-बिट फ़्लोटिंग पॉइंट सपोर्ट के साथ, GLSL ES शेडिंग लैंग्वेज का नया वर्शन
    • बेहतर टेक्स्चर रेंडरिंग
    • टेक्सचर साइज़ और रेंडर-बफ़र फ़ॉर्मैट के लिए, बड़े पैमाने पर स्टैंडर्ड तय करना

    Android पर OpenGL ES 3.0 के लिए Java इंटरफ़ेस, GLES30 के साथ दिया गया है. OpenGL ES 3.0 का इस्तेमाल करते समय, पक्का करें कि आपने अपनी मेनिफ़ेस्ट फ़ाइल में, <uses-feature> टैग और android:glEsVersion एट्रिब्यूट के साथ इसका एलान किया हो. उदाहरण के लिए:

    <manifest>
        <uses-feature android:glEsVersion="0x00030000" />
        ...
    </manifest>

    साथ ही, setEGLContextClientVersion() को कॉल करके OpenGL ES संदर्भ बताना न भूलें, 3 को वर्शन के रूप में पास कर रही हूँ.

    OpenGL ES का इस्तेमाल करने के बारे में ज़्यादा जानकारी के साथ-साथ यह देखने के लिए कि डिवाइस पर काम करता है या नहीं रनटाइम के दौरान OpenGL ES वर्शन, OpenGL ES API गाइड देखें.

    ड्रॉएबल के लिए Mipmapping

    अपने बिटमैप या ड्रॉबल के सोर्स के तौर पर, मैप का इस्तेमाल करना, अच्छी क्वालिटी वाली इमेज और इमेज के अलग-अलग स्केल देने का एक आसान तरीका है. यह तब खास तौर पर मददगार हो सकता है, जब आपको ऐनिमेशन के दौरान अपनी इमेज को स्केल करना हो.

    Android 4.2 (एपीआई लेवल 17) ने Bitmap में, मिपमैप के साथ काम करने की सुविधा जोड़ी है क्लास—Android आपके Bitmap में मिप इमेज को स्वैप कर देता है जब आप ने एक मिपमैप स्रोत दिया और setHasMipMap() को सक्षम किया है. अब Android 4.3 में, BitmapDrawable ऑब्जेक्ट के लिए भी मिपमैप चालू किए जा सकते हैं. इसके लिए, आपको मिपमैप ऐसेट उपलब्ध कराना होगा और किसी बिटमैप संसाधन फ़ाइल में android:mipMap एट्रिब्यूट सेट करने या hasMipMap() को कॉल करने का विकल्प होता है.

    यूज़र इंटरफ़ेस

    ओवरले देखना

    नई ViewOverlay क्लास, सबसे ऊपर एक पारदर्शी लेयर देती है View किस तरह का विज़ुअल कॉन्टेंट जोड़ा जा सकता है. सकता है. getOverlay() पर कॉल करके, किसी भी View के लिए ViewOverlay लिया जा सकता है. ओवरले हमेशा इसके होस्ट व्यू (जिस व्यू से इसे बनाया गया था) के समान आकार और स्थिति होती है, इससे होस्ट व्यू के सामने कॉन्टेंट जोड़ा जा सकता है, लेकिन उसे बढ़ाया नहीं जा सकता की सीमाएँ शामिल हैं.

    ViewOverlay का इस्तेमाल करना, खास तौर पर तब काम आता है, जब आपको ऐनिमेशन, जैसे कि किसी व्यू को कंटेनर के बाहर स्लाइड करना या आइटम को स्क्रीन पर इधर-उधर ले जाना वह भी व्यू हैरारकी पर असर डाले बिना. हालांकि, ओवरले का इस्तेमाल किया जा सकने वाला हिस्सा उसके होस्ट व्यू के समान क्षेत्र तक प्रतिबंधित है, अगर आप बाहर जाते हुए किसी व्यू को ऐनिमेट करना चाहते हैं लेआउट में इसकी स्थिति है, तो आपको ऐसे पैरंट व्यू से ओवरले का इस्तेमाल करना होगा जिसमें लेआउट बाउंड है.

    Button जैसे विजेट व्यू के लिए ओवरले बनाने पर, add(Drawable) को कॉल करके ओवरले में Drawable ऑब्जेक्ट जोड़े जा सकते हैं. अगर RelativeLayout जैसे किसी लेआउट व्यू के लिए getOverlay() को कॉल किया जाता है, वापस किया गया ऑब्जेक्ट ViewGroupOverlay है. ViewGroupOverlay क्लास, ViewOverlay की सबसे छोटी क्लास है. इसकी मदद से, add(View) को कॉल करके View ऑब्जेक्ट भी जोड़े जा सकते हैं.

    ध्यान दें: ओवरले में जोड़े जाने वाले ड्रॉएबल और व्यू वे सिर्फ़ विज़ुअल होते हैं. इन पर फ़ोकस या इनपुट इवेंट नहीं मिल सकते.

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

    Kotlin

    val view: View? = findViewById(R.id.view_to_remove)
    val container: ViewGroup? = view?.parent as ViewGroup
    
    container?.apply {
        overlay.add(view)
        ObjectAnimator.ofFloat(view, "translationX", right.toFloat())
                .start()
    }

    Java

    View view = findViewById(R.id.view_to_remove);
    ViewGroup container = (ViewGroup) view.getParent();
    container.getOverlay().add(view);
    ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationX", container.getRight());
    anim.start();

    ऑप्टिकल बाउंड लेआउट

    उन व्यू के लिए जिनमें नौ-पैच बैकग्राउंड इमेज होती हैं, अब आप तय कर सकते हैं कि उन्हें "ऑप्टिकल" के आधार पर आस-पास के बैकग्राउंड इमेज की सीमाएं "क्लिप" के बजाय की सीमा से बाहर है.

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

    ध्यान दें: पहली और दूसरी इमेज के स्क्रीनशॉट में "दिखाएं लेआउट बाउंड" डेवलपर सेटिंग चालू की गई. हर व्यू के लिए, लाल रंग की लाइनें ऑप्टिकल बाउंड, नीली लाइनें क्लिप की बाउंड को दिखाती हैं, और गुलाबी रंग का मतलब है कि मार्जिन.

    पहला डायग्राम. क्लिप के बॉउंड का इस्तेमाल करने वाला लेआउट (डिफ़ॉल्ट).

    दूसरी इमेज. ऑप्टिकल बाउंड का इस्तेमाल करके लेआउट.

    व्यू को उनके ऑप्टिकल बाउंड के आधार पर अलाइन करने के लिए, किसी पैरंट लेआउट में android:layoutMode एट्रिब्यूट को "opticalBounds" पर सेट करें. उदाहरण के लिए:

    <LinearLayout android:layoutMode="opticalBounds" ... >

    तीसरी इमेज. 9-पैच वाले होलो बटन का ज़ूम किया गया व्यू ऑप्टिकल बाउंड.

    यह काम करे, इसके लिए आपके व्यू के बैकग्राउंड पर लागू की गई नौ-पैच वाली इमेज में, नाइन-पैच फ़ाइल के नीचे और दाईं ओर की लाल रेखाओं का उपयोग करके ऑप्टिकल बाउंड (जैसे कि तीसरी इमेज में दिखाया गया है). लाल रेखाएं उस क्षेत्र को इंगित करती हैं जिसे घटाना चाहिए क्लिप बाउंड है, जिससे चित्र की ऑप्टिकल सीमाएं छोड़ दी गई हैं.

    जब अपने लेआउट में ViewGroup के लिए ऑप्टिकल बाउंड्री चालू की जाती है, तो सभी डिसेंडेंट व्यू, ऑप्टिकल बाउंड लेआउट मोड को इनहेरिट करते हैं, जब तक कि आप इसे 'इसके हिसाब से ग्रुप बनाएं' ग्रुप के लिए नहीं बदलते android:layoutMode को "clipBounds" पर सेट कर रही हूँ. सभी लेआउट एलिमेंट उनके बच्चे के विचारों की ऑप्टिकल सीमाओं के आधार पर, खुद के बाउंड व्यू की संख्या बढ़ा सकते हैं. हालांकि, फ़िलहाल लेआउट एलिमेंट (ViewGroup के सबक्लास), अपने बैकग्राउंड पर लागू की गई नाइन-पैच इमेज के लिए ऑप्टिकल बाउंड के साथ काम नहीं करते.

    अगर आपने View, ViewGroup या इनके किसी सबक्लास को सबक्लास करके कस्टम व्यू बनाया है, तो आपके व्यू में ऑप्टिकल बाउंड वाले ये व्यवहार इनहेरिट हो जाएंगे.

    ध्यान दें: Holo थीम के साथ काम करने वाले सभी विजेट को ऑप्टिकल बाउंड के साथ अपडेट किया गया है. इनमें Button, Spinner, EditText वगैरह शामिल हैं. तो आप इस मूल्य को सेट करके तुरंत लाभ उठा सकते हैं अगर आपका ऐप्लिकेशन Holo थीम लागू करता है, तो "opticalBounds" के लिए android:layoutMode एट्रिब्यूट (Theme.Holo, Theme.Holo.Light वगैरह).

    ड्रॉ 9-पैच टूल का इस्तेमाल करके अपनी नौ-पैच इमेज के लिए ऑप्टिकल बाउंड्री तय करने के लिए, 'कंट्रोल' को दबाकर रखें जब क्लिक करके बॉर्डर पिक्सल पर क्लिक करें.

    Rect वैल्यू के लिए ऐनिमेशन

    अब RectEvaluator की मदद से, Rect की दो वैल्यू को ऐनिमेट किया जा सकता है. यह नई क्लास TypeEvaluator का एक इंप्लीमेंटेशन है, जिसे आप ValueAnimator.setEvaluator() को पास कर सकते हैं.

    विंडो अटैच और फ़ोकस करने वाला लिसनर

    पहले, अगर आपको यह सुनना था कि आपका व्यू कब विंडो से जुड़ा या अलग हुआ था या जब इसका फ़ोकस बदल गया, तो आपको View क्लास को बदलकर, onAttachedToWindow() और onDetachedFromWindow() या onWindowFocusChanged() को लागू करें.

    इवेंट को अटैच और अलग करने के लिए, अब ViewTreeObserver.OnWindowAttachListener को लागू किया जा सकता है. साथ ही, इसे व्यू पर सेट करने के लिए, addOnWindowAttachListener(). फ़ोकस इवेंट पाने के लिए, ViewTreeObserver.OnWindowFocusChangeListener लागू करें और इसे addOnWindowFocusChangeListener() के साथ किसी व्यू पर सेट करें.

    टीवी पर ओवरस्कैन की सुविधा

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

    स्क्रीन ओरिएंटेशन

    <activity> टैग के screenOrientation एट्रिब्यूट में अब अन्य वैल्यू का इस्तेमाल किया जा सकता है. इससे, उपयोगकर्ता की ऑटो-रोटेशन की प्राथमिकता को पूरा किया जा सकता है:

    "userLandscape"
    "sensorLandscape" की तरह काम करता है. हालांकि, अगर उपयोगकर्ता अपने-आप दिशा बदलना (ऑटो-रोटेट) की सुविधा बंद करता है, तो तो यह सामान्य लैंडस्केप ओरिएंटेशन में लॉक हो जाता है और फ़्लिप नहीं होगा.
    "userPortrait"
    "sensorPortrait" की तरह काम करता है. हालांकि, अगर उपयोगकर्ता अपने-आप दिशा बदलने की सुविधा को बंद करता है, तो यह सामान्य पोर्ट्रेट ओरिएंटेशन में लॉक हो जाता है और फ़्लिप नहीं होगा.
    "fullUser"
    "fullSensor" की तरह ही काम करता है और चारों दिशाओं में घूमने की अनुमति देता है. हालांकि, अगर उपयोगकर्ता ने अपने-आप घूमने की सुविधा बंद कर दी है, तो यह उपयोगकर्ता के पसंदीदा ओरिएंटेशन में लॉक हो जाता है.

    इसके अलावा, अब अपने ऐप्लिकेशन के ओरिएंटेशन को स्क्रीन के मौजूदा ओरिएंटेशन में लॉक करने के लिए, "locked" का एलान भी किया जा सकता है.

    रोटेशन ऐनिमेशन

    इसमें नया rotationAnimation फ़ील्ड WindowManager से आपको तीन ऐनिमेशन में से किसी एक को चुनने की सुविधा मिलती है जब सिस्टम स्क्रीन ओरिएंटेशन स्विच करता है, तो का उपयोग करना चाहते हैं. ये तीन ऐनिमेशन हैं:

    ध्यान दें: ये ऐनिमेशन सिर्फ़ तब उपलब्ध होते हैं, जब आपने अपनी गतिविधि को "फ़ुलस्क्रीन" मोड में इस्तेमाल करने के लिए सेट किया हो. इसे Theme.Holo.NoActionBar.Fullscreen जैसी थीम की मदद से चालू किया जा सकता है.

    उदाहरण के लिए, यहां बताया गया है कि "क्रॉसफ़ेड" को कैसे चालू किया जा सकता है ऐनिमेशन:

    Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        val params: WindowManager.LayoutParams = window.attributes
        params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE
        window.attributes = params
        ...
    }

    Java

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        WindowManager.LayoutParams params = getWindow().getAttributes();
        params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
        getWindow().setAttributes(params);
        ...
    }

    उपयोगकर्ता का इनपुट

    सेंसर के नए टाइप

    नए TYPE_GAME_ROTATION_VECTOR सेंसर की मदद से, चुंबकीय रुकावट की चिंता किए बिना, डिवाइस के रोटेशन का पता लगाया जा सकता है. TYPE_ROTATION_VECTOR सेंसर के उलट, TYPE_GAME_ROTATION_VECTOR मैग्नेटिक नॉर्थ पर आधारित नहीं होता.

    नए TYPE_GYROSCOPE_UNCALIBRATED और TYPE_MAGNETIC_FIELD_UNCALIBRATED सेंसर, बिना किसी पूर्वाग्रह के अनुमान के रॉ सेंसर डेटा उपलब्ध कराते हैं. इसका मतलब है कि मौजूदा TYPE_GYROSCOPE और TYPE_MAGNETIC_FIELD सेंसर, सेंसर का ऐसा डेटा देते हैं जिसमें डिवाइस में मौजूद, जियो-ड्रिफ़्ट और हार्ड आयरन से होने वाले अनुमानित पूर्वाग्रह को ध्यान में रखा जाता है. वहीं दूसरी ओर, नया "बिना कैलिब्रेट किया" का के कई वर्शन हैं, तो सेंसर डेटा का इस्तेमाल कर सकता है. साथ ही, अनुमानित बायस वैल्यू को अलग से दिखा सकता है. ये सेंसर आपको इसकी मदद से, सेंसर डेटा के लिए अनुमानित फ़र्क़ को बढ़ाकर, सेंसर डेटा के लिए अपना कस्टम कैलिब्रेशन किया जाता है बाहरी डेटा शामिल है.

    सूचना को सुनने की सुविधा

    Android 4.3 में एक नई सेवा श्रेणी, NotificationListenerService जोड़ी गई है, जो आपके ऐप्लिकेशन को सिस्टम की ओर से पोस्ट की जाने वाली नई सूचनाओं के बारे में जानकारी पाने देती है.

    अगर आपका ऐप्लिकेशन फ़िलहाल, सिस्टम सूचनाओं को ऐक्सेस करने के लिए सुलभता सेवा एपीआई का इस्तेमाल करता है, तो आपको इन एपीआई का इस्तेमाल करने के लिए अपने ऐप्लिकेशन को अपडेट करना चाहिए.

    संपर्क सूची

    "संपर्क किए जा सकने वाले लोगों" के लिए क्वेरी

    नई संपर्क कंपनी क्वेरी, Contactables.CONTENT_URI, एक Cursor पाने का असरदार तरीका बताती है जिसमें बताई गई क्वेरी से मेल खाने वाले सभी संपर्कों के सभी ईमेल पते और फ़ोन नंबर शामिल हैं.

    संपर्कों के डेल्टा के लिए क्वेरी

    Contacts Provider में नए एपीआई जोड़े गए हैं. इनकी मदद से, संपर्कों के डेटा में हुए हाल के बदलावों के बारे में बेहतर तरीके से क्वेरी की जा सकती है. पहले, संपर्कों के डेटा में कोई बदलाव होने पर, आपके ऐप्लिकेशन को सूचना मिल सकती थी. हालांकि, आपको यह पता नहीं चलता था कि क्या बदलाव हुआ है. साथ ही, बदलाव का पता लगाने के लिए, आपको सभी संपर्कों को वापस लाना होता था और फिर उनमें बदलाव देखना होता था.

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

    कौनसे संपर्क मिटाए गए हैं, यह ट्रैक करने के लिए नई टेबल ContactsContract.DeletedContacts में मिटाए गए संपर्कों का लॉग उपलब्ध होता है. हालांकि, मिटाए गए हर संपर्क को इस टेबल में सीमित समय के लिए रखा जाता है. CONTACT_LAST_UPDATED_TIMESTAMP की तरह ही, नए चुनने वाले पैरामीटर CONTACT_DELETED_TIMESTAMP का इस्तेमाल करके देखा जा सकता है कि कंपनी से पिछली बार क्वेरी करने के बाद से, कौनसे संपर्क मिटाए गए हैं. टेबल में एक कॉन्स्टेंट DAYS_KEPT_MILLISECONDS भी होता है, जिसमें उन दिनों की संख्या (मिलीसेकंड में) होती है जितना लॉग सेव रखा जाएगा.

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

    संपर्कों में हुए बदलावों की जांच करने के लिए इन एपीआई का इस्तेमाल करने वाले सैंपल कोड के लिए, ApiDemos पर जाएं सैंपल, एसडीके सैंपल डाउनलोड में उपलब्ध है.

    स्थानीय भाषा के अनुसार

    दो-तरफ़ा टेक्स्ट के लिए बेहतर सहायता

    Android के पिछले वर्शन, दाईं से बाईं ओर (आरटीएल) लिखी जाने वाली भाषाओं और लेआउट के साथ काम करते हैं. हालांकि, कभी-कभी वे अलग-अलग दिशाओं में लिखे गए टेक्स्ट को सही तरीके से हैंडल नहीं करते. इसलिए, Android 4.3 में BidiFormatter एपीआई जोड़े गए हैं. इनकी मदद से, टेक्स्ट के किसी भी हिस्से को गड़बड़ा किए बिना, टेक्स्ट को सही तरीके से फ़ॉर्मैट किया जा सकता है.

    उदाहरण के लिए, अगर आपको स्ट्रिंग वैरिएबल वाला वाक्य बनाना है, जैसे कि "क्या आपका मतलब था 15 बे स्ट्रीट, लॉरेल, सीए?", तो आम तौर पर स्थानीय भाषा में मौजूद स्ट्रिंग रिसॉर्स और वैरिएबल को String.format() में पास किया जाता है:

    Kotlin

    val suggestion = String.format(resources.getString(R.string.did_you_mean), address)

    Java

    Resources res = getResources();
    String suggestion = String.format(res.getString(R.string.did_you_mean), address);

    हालांकि, अगर स्थान-भाषा हिब्रू है, तो फ़ॉर्मैट की गई स्ट्रिंग इस तरह आती है:

    האם התכוונת ל 15 Bay Street, Laurel, CA?

    यह ग़लत है, क्योंकि "15" "बे स्ट्रीट" के बाईं ओर होना चाहिए. इसे बदलने के लिए, BidiFormatter और इसके unicodeWrap() तरीके का इस्तेमाल करें. उदाहरण के लिए, ऊपर दिया गया कोड बन जाता है:

    Kotlin

    val bidiFormatter = BidiFormatter.getInstance()
    val suggestion = String.format(
            resources.getString(R.string.did_you_mean),
            bidiFormatter.unicodeWrap(address)
    )

    Java

    Resources res = getResources();
    BidiFormatter bidiFormatter = BidiFormatter.getInstance();
    String suggestion = String.format(res.getString(R.string.did_you_mean),
            bidiFormatter.unicodeWrap(address));

    डिफ़ॉल्ट रूप से, unicodeWrap() निर्देशात्मकता का पहला अनुमान लगाने पर, जो चीज़ों को गलत बना सकता है. टेक्स्ट दिशा के लिए सिग्नल, पूरे कॉन्टेंट के लिए सही दिशा नहीं दिखाता. अगर ज़रूरी हो, तो TextDirectionHeuristics के TextDirectionHeuristic कॉन्सटेंट में से किसी एक को पास करके, अलग अनुमान तय किया जा सकता है unicodeWrap() के लिए.

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

    सुलभता सेवाएं

    मुख्य इवेंट मैनेज करना

    AccessibilityService को अब onKeyEvent() कॉलबैक वाले तरीके से, मुख्य इनपुट इवेंट के लिए कॉलबैक मिल सकता है. इससे आपकी सुलभता सेवा को कुंजी पर आधारित इनपुट डिवाइस, जैसे कि कीबोर्ड का इस्तेमाल करें. साथ ही, उन इवेंट को खास कार्रवाइयों में बदल दें पहले ऐसा हो सकता था कि सिर्फ़ टच इनपुट या डिवाइस के डी-पैड का इस्तेमाल करके ऐसा किया जा सके.

    टेक्स्ट चुनना और कॉपी/चिपकाना

    AccessibilityNodeInfo अब ऐसे एपीआई उपलब्ध कराता है जिनकी मदद से AccessibilityService, किसी नोड में टेक्स्ट चुन सकता है, उसे काट सकता है, कॉपी कर सकता है, और चिपकाया जा सकता है.

    काटने या कॉपी करने के लिए चुने गए टेक्स्ट की जानकारी देने के लिए, आपकी सुलभता सेवा, नई कार्रवाई ACTION_SET_SELECTION का इस्तेमाल कर सकती है. साथ ही, ACTION_ARGUMENT_SELECTION_START_INT और ACTION_ARGUMENT_SELECTION_END_INT की मदद से, चुने गए टेक्स्ट की शुरुआत और आखिर की पोज़िशन की जानकारी दे सकती है. इसके अलावा, आप मौजूदा टेक्स्ट का इस्तेमाल करके कर्सर की जगह में बदलाव करके टेक्स्ट चुन सकते हैं ऐक्शन, ACTION_NEXT_AT_MOVEMENT_GRANULARITY (यह फ़ंक्शन पहले सिर्फ़ कर्सर की जगह बदलने के लिए इस्तेमाल किया गया था) और ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN आर्ग्युमेंट जोड़ना होगा.

    इसके बाद, ACTION_CUT, ACTION_COPY का इस्तेमाल करके काटें या कॉपी करें. इसके बाद, ACTION_PASTE का इस्तेमाल करके चिपकाएं.

    ध्यान दें: ये नए एपीआई, Android के पिछले वर्शन के लिए भी उपलब्ध हैं. इसके लिए, AccessibilityNodeInfoCompat क्लास के साथ Android सहायता लाइब्रेरी का इस्तेमाल करें.

    सुलभता सुविधाओं के बारे में बताना

    Android 4.3 से, सुलभता सेवा को अपनी मेटाडेटा फ़ाइल में सुलभता की सुविधाओं के बारे में एलान करना होगा. ऐसा, सुलभता की कुछ सुविधाओं का इस्तेमाल करने के लिए ज़रूरी है. अगर सुविधा उपलब्ध नहीं है अनुरोध किया गया है, तो सुविधा नो-ऑप होगी. घोषणा करने के लिए कि है, तो आपको उन एक्सएमएल एट्रिब्यूट का इस्तेमाल करना होगा जो अलग-अलग "क्षमता" AccessibilityServiceInfo में कॉन्सटेंट क्लास.

    उदाहरण के लिए, अगर कोई सेवा flagRequestFilterKeyEvents की सुविधा का अनुरोध नहीं करती है, तो उसे मुख्य इवेंट नहीं मिलेंगे.

    जांच करना और डीबग करना

    अपने-आप यूज़र इंटरफ़ेस (यूआई) टेस्टिंग

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

    UiAutomation का इंस्टेंस पाने के लिए, Instrumentation.getUiAutomation() को कॉल करें. ऑर्डर में शामिल है यह काम करे, इसके लिए आपको instrument कमांड के साथ -w विकल्प देना होगा जब आपका InstrumentationTestCase adb shell से चल रहा हो.

    UiAutomation इंस्टेंस की मदद से, अपनी जांच के लिए आर्बिट्रेरी इवेंट एक्ज़ीक्यूट किए जा सकते हैं executeAndWaitForEvent() पर कॉल करके, अपने ऐप्लिकेशन को परफ़ॉर्म करने के लिए Runnable पास करें. इसके बाद, टाइम आउट लागू हो जाएगा कार्रवाई की अवधि और UiAutomation.AccessibilityEventFilter इंटरफ़ेस को लागू करने की अवधि. UiAutomation.AccessibilityEventFilter लागू करने के दौरान, आपको एक कॉल मिलेगा. इसकी मदद से, अपनी पसंद के इवेंट फ़िल्टर किए जा सकते हैं. साथ ही, किसी टेस्ट केस के काम करने या न करने का पता लगाया जा सकता है.

    टेस्ट के दौरान सभी इवेंट की निगरानी करने के लिए, UiAutomation.OnAccessibilityEventListener को लागू करें और उसे setOnAccessibilityEventListener() को पास करें. इसके बाद, जब भी कोई इवेंट होता है, तो आपके लिसनर इंटरफ़ेस को onAccessibilityEvent() के लिए कॉल मिलता है. साथ ही, इवेंट के बारे में बताने वाला AccessibilityEvent ऑब्जेक्ट मिलता है.

    UiAutomation एपीआई से कई तरह की अन्य कार्रवाइयां की जाती हैं बहुत कम लेवल पर, uiautomator जैसे यूज़र इंटरफ़ेस (यूआई) टेस्ट टूल के डेवलपमेंट को बढ़ावा देता है. उदाहरण के लिए, UiAutomation ये काम भी कर सकता है:

    • इंजेक्ट इनपुट इवेंट
    • स्क्रीन का ओरिएंटेशन बदलें
    • स्क्रीनशॉट ले सकते हैं

    यूज़र इंटरफ़ेस (यूआई) टेस्ट टूल के लिए सबसे अहम बात यह है कि UiAutomation एपीआई, Instrumentation एपीआई के उलट, ऐप्लिकेशन की सीमाओं के पार काम करते हैं.

    ऐप्लिकेशन के लिए Systrace इवेंट

    Android 4.3 में, Trace क्लास को दो स्टैटिक तरीकों के साथ जोड़ा गया है, beginSection() और endSection(). इनकी मदद से, systrace रिपोर्ट में शामिल करने के लिए कोड के ब्लॉक तय किए जा सकते हैं. आपके ऐप्लिकेशन में, ट्रैक किए जा सकने वाले कोड के सेक्शन बनाकर, systrace लॉग आपको इस बारे में ज़्यादा जानकारी देते हैं कि आपके ऐप्लिकेशन में कहां पर धीमापन होता है.

    Systrace टूल का इस्तेमाल करने के बारे में जानने के लिए, Systrace की मदद से डिसप्ले और परफ़ॉर्मेंस का विश्लेषण करना लेख पढ़ें.

    सुरक्षा

    ऐप्लिकेशन की निजी कुंजियों के लिए Android पासकोड स्टोर

    Android अब KeyStore सुविधा में कस्टम Java Security Provider की सुविधा देता है. इसे Android Key Store कहा जाता है. इसकी मदद से, निजी कुंजियां जनरेट और सेव की जा सकती हैं. इन कुंजियों को सिर्फ़ आपका ऐप्लिकेशन देख सकता है और उनका इस्तेमाल कर सकता है. Android Key Store को लोड करने के लिए, "AndroidKeyStore" को KeyStore.getInstance() पर पास करें.

    Android Key Store में अपने ऐप्लिकेशन के निजी क्रेडेंशियल मैनेज करने के लिए, KeyPairGenerator के साथ KeyPairGeneratorSpec का इस्तेमाल करके नई कुंजी जनरेट करें. सबसे पहले, getInstance() को कॉल करके KeyPairGenerator का इंस्टेंस पाएं. फिर कॉल करें initialize(), इसे KeyPairGeneratorSpec, इनका इस्तेमाल किया जा सकता है KeyPairGeneratorSpec.Builder. आखिर में, generateKeyPair() पर कॉल करके अपना KeyPair पाएं.

    हार्डवेयर क्रेडेंशियल स्टोरेज

    Android, अब आपके KeyChain के लिए हार्डवेयर-बैक्ड स्टोरेज की सुविधा भी देता है क्रेडेंशियल से, एक्सट्रैक्ट करने के लिए कुंजियों को उपलब्ध न कराने से ज़्यादा सुरक्षा मिलती है. इसका मतलब है कि जब कुंजियां, हार्डवेयर के साथ काम करने वाले कीस्टोर (सिक्योर एलिमेंट, टीपीएम या ट्रस्टज़ोन) में मौजूद होती हैं, तो उनका इस्तेमाल क्रिप्टोग्राफ़िक ऑपरेशन के लिए किया जा सकता है. हालांकि, निजी कुंजी का कॉन्टेंट एक्सपोर्ट नहीं किया जा सकता. यहां तक कि OS कर्नेल भी इस मुख्य सामग्री को ऐक्सेस नहीं कर सकता. हालांकि, Android पर चलने वाले सभी डिवाइस, स्टोरेज का इस्तेमाल नहीं करते हार्डवेयर है, तो रनटाइम के दौरान यह देखा जा सकता है कि हार्डवेयर-बैक्ड स्टोरेज उपलब्ध है या नहीं KeyChain.IsBoundKeyAlgorithm().

    मेनिफ़ेस्ट में किए गए एलान

    एलान करने लायक ज़रूरी सुविधाएं

    <uses-feature> एलिमेंट में अब ये वैल्यू काम करती हैं, ताकि आप यह पक्का कर सकें कि आपका ऐप्लिकेशन सिर्फ़ उन डिवाइसों पर इंस्टॉल हो जो आपके ऐप्लिकेशन के लिए ज़रूरी सुविधाएं उपलब्ध कराते हैं.

    FEATURE_APP_WIDGETS
    एलान करता है कि आपका ऐप्लिकेशन एक ऐप्लिकेशन विजेट देता है और उसे सिर्फ़ उन डिवाइस पर इंस्टॉल किया जाना चाहिए होम स्क्रीन या ऐसी ही जगह की जानकारी शामिल करें जहां उपयोगकर्ता ऐप्लिकेशन विजेट एम्बेड कर सकें. उदाहरण:
    <uses-feature android:name="android.software.app_widgets" android:required="true" />
    FEATURE_HOME_SCREEN
    यह एलान करता है कि आपका ऐप्लिकेशन, होम स्क्रीन की जगह इस्तेमाल किया जा सकता है और इसे सिर्फ़ इस डिवाइस पर इंस्टॉल किया जाना चाहिए ऐसे डिवाइस जिनमें तीसरे पक्ष के होम स्क्रीन ऐप्लिकेशन काम करते हैं. उदाहरण:
    <uses-feature android:name="android.software.home_screen" android:required="true" />
    FEATURE_INPUT_METHODS
    एलान करता है कि आपका ऐप्लिकेशन पसंद के मुताबिक इनपुट का तरीका (InputMethodService के साथ बनाया गया कीबोर्ड) देता है और उसे सिर्फ़ उन डिवाइस पर इंस्टॉल किया जाना चाहिए का इस्तेमाल तीसरे पक्ष के इनपुट के तरीकों के लिए किया जा सकता है. उदाहरण:
    <uses-feature android:name="android.software.input_methods" android:required="true" />
    FEATURE_BLUETOOTH_LE
    इससे पता चलता है कि आपका ऐप्लिकेशन, ब्लूटूथ स्मार्ट डिवाइसों के लिए बने एपीआई का इस्तेमाल करता है. साथ ही, यह सिर्फ़ उन डिवाइसों पर इंस्टॉल किया जाना चाहिए जो ब्लूटूथ स्मार्ट डिवाइसों के ज़रिए दूसरे डिवाइसों से कनेक्ट कर सकते हैं. उदाहरण:
    <uses-feature android:name="android.software.bluetooth_le" android:required="true" />

    उपयोगकर्ता की अनुमतियां

    कुछ एपीआई को ऐक्सेस करने के लिए, आपके ऐप्लिकेशन को जिन अनुमतियों की ज़रूरत होती है उन्हें बताने के लिए, अब <uses-permission> में ये वैल्यू इस्तेमाल की जा सकती हैं.

    BIND_NOTIFICATION_LISTENER_SERVICE
    नए NotificationListenerService API का इस्तेमाल करने के लिए ज़रूरी है.
    SEND_RESPOND_VIA_MESSAGE
    ACTION_RESPOND_VIA_MESSAGE के इंटेंट को पाने के लिए ज़रूरी है.

    Android 4.3 में सभी API बदलावों के विस्तृत दृश्य के लिए, एपीआई में अंतर की रिपोर्ट.