Android 4.4 के लिए API

एपीआई लेवल: 19

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

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

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

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

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

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

व्यवहार से जुड़े अहम बदलाव

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

अगर आपका ऐप्लिकेशन बाहरी स्टोरेज से डेटा पढ़ता है, तो...

Android 4.4 पर चलने वाले आपके ऐप्लिकेशन में, बाहरी स्टोरेज में शेयर की गई फ़ाइलों को तब तक नहीं पढ़ा जा सकता, जब तक आपके ऐप्लिकेशन के पास READ_EXTERNAL_STORAGE अनुमति न हो. इसका मतलब है कि getExternalStoragePublicDirectory() से मिली डायरेक्ट्री में मौजूद फ़ाइलों को अब अनुमति के बिना ऐक्सेस नहीं किया जा सकता. हालांकि, अगर आपको सिर्फ़ getExternalFilesDir() की ओर से दी गई, अपने ऐप्लिकेशन से जुड़ी डायरेक्ट्री ऐक्सेस करनी हैं, तो आपको READ_EXTERNAL_STORAGE की अनुमति की ज़रूरत नहीं है.

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

Android 4.4 पर चलने के दौरान, आपका ऐप्लिकेशन अलग तरह से काम कर सकता है. ऐसा खास तौर पर तब होता है, जब आपने अपने ऐप्लिकेशन के targetSdkVersion को "19" या उसके बाद के वर्शन पर अपडेट किया हो.

WebView क्लास और उससे जुड़े एपीआई के कोड को अपग्रेड किया गया है, ताकि यह Chromium सोर्स कोड के आधुनिक स्नैपशॉट पर आधारित हो. इससे परफ़ॉर्मेंस को बेहतर बनाने के साथ-साथ, HTML5 की नई सुविधाओं का इस्तेमाल करने और WebView कॉन्टेंट को रिमोट से डीबग करने में मदद मिलती है. इस अपग्रेड का दायरा इस बात से तय होता है कि अगर आपका ऐप्लिकेशन WebView का इस्तेमाल करता है, तो कुछ मामलों में उसके काम करने के तरीके पर असर पड़ सकता है. हालांकि, व्यवहार में हुए बदलावों को दस्तावेज़ में दर्ज किया जाता है और इनका असर आपके ऐप्लिकेशन पर सिर्फ़ तब पड़ता है, जब आपने अपने ऐप्लिकेशन के targetSdkVersion को "19" या उससे ज़्यादा पर अपडेट किया हो. नया WebView, "क्विर्क मोड" में काम करता है, ताकि API लेवल 18 और उससे पहले के वर्शन को टारगेट करने वाले ऐप्लिकेशन में कुछ लेगसी फ़ंक्शन उपलब्ध कराए जा सकें. ऐसा हो सकता है कि आपका ऐप्लिकेशन, WebView के पिछले वर्शन के ऐसे व्यवहार पर निर्भर हो जिसकी जानकारी नहीं है.

इसलिए, अगर आपका मौजूदा ऐप्लिकेशन WebView का इस्तेमाल करता है, तो आपको जल्द से जल्द Android 4.4 पर टेस्ट करना होगा. साथ ही, targetSdkVersion को "19" या उसके बाद के वर्शन पर अपडेट करने पर, आपके ऐप्लिकेशन पर क्या असर पड़ सकता है, इस बारे में जानने के लिए Android 4.4 में वेबव्यू पर माइग्रेट करना लेख पढ़ें.

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

अपने ऐप्लिकेशन के targetSdkVersion को "19" या उससे ज़्यादा पर सेट करने पर, set() या setRepeating() का इस्तेमाल करके बनाए गए अलार्म सटीक नहीं होंगे.

बैटरी की खपत को कम करने के लिए, Android अब एक ही समय पर बजने वाले सभी ऐप्लिकेशन के अलार्म को एक साथ बजाता है. इससे सिस्टम को हर अलार्म को मैनेज करने के लिए, डिवाइस को कई बार के बजाय एक बार ही चालू करना पड़ता है.

अगर आपका अलार्म, घड़ी के सटीक समय से जुड़ा नहीं है, लेकिन यह ज़रूरी है कि आपका अलार्म किसी खास समयसीमा (जैसे, दोपहर 2 बजे से शाम 4 बजे के बीच) के दौरान बज जाए, तो setWindow() के नए तरीके का इस्तेमाल किया जा सकता है. यह अलार्म के लिए "सबसे पहले" समय और सबसे पहले समय के बाद की "विंडो" स्वीकार करता है. इस विंडो के दौरान, सिस्टम को अलार्म बजाना चाहिए.

अगर आपको अलार्म को घड़ी के किसी खास समय पर पिन करना है, जैसे कि कैलेंडर इवेंट के रिमाइंडर के लिए, तो setExact() के नए तरीके का इस्तेमाल करें.

बैच में डेटा अपलोड करने की यह सुविधा, सिर्फ़ अपडेट किए गए ऐप्लिकेशन पर लागू होती है. अगर आपने targetSdkVersion को "18" या उससे कम पर सेट किया है, तो Android 4.4 पर काम करते समय, आपके अलार्म पहले की तरह ही काम करते रहेंगे.

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

अपने ऐप्लिकेशन के targetSdkVersion को "19" या उससे ज़्यादा पर सेट करने पर, addPeriodicSync() के साथ सिंक करने पर, आपके सिंक ऑपरेशन, तय की गई अवधि के करीब 4% के डिफ़ॉल्ट फ़्लेक्स इंटरवल में पूरे हो जाएंगे. उदाहरण के लिए, अगर आपके पोल की फ़्रीक्वेंसी 24 घंटे है, तो सिंक करने की प्रोसेस हर दिन एक ही समय पर होने के बजाय, हर दिन करीब एक घंटे की विंडो में हो सकती है.

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

फ़्लेक्स इंटरवल का यह व्यवहार, सिर्फ़ अपडेट किए गए ऐप्लिकेशन पर लागू होता है. अगर आपने targetSdkVersion को "18" या उससे पहले के वर्शन पर सेट किया है, तो Android 4.4 पर चलने के दौरान, सिंक करने के आपके मौजूदा अनुरोधों का व्यवहार पिछले वर्शन की तरह ही होगा.

प्रिंटिंग फ़्रेमवर्क

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

सामान्य कॉन्टेंट को प्रिंट करना

अगर आपको अपने यूज़र इंटरफ़ेस (यूआई) से कॉन्टेंट को दस्तावेज़ के तौर पर प्रिंट करना है, तो आपको सबसे पहले PrintDocumentAdapter का सबक्लास बनाना होगा. इस क्लास में, आपको कुछ कॉलबैक तरीके लागू करने होंगे. इनमें, प्रिंटिंग के लिए दी गई प्रॉपर्टी के आधार पर अपना लेआउट सेट करने के लिए onLayout() और प्रिंट किए जा सकने वाले कॉन्टेंट को ParcelFileDescriptor में सीरियलाइज़ करने के लिए onWrite() शामिल है.

ParcelFileDescriptor में अपना कॉन्टेंट लिखने के लिए, आपको उसे PDF फ़ॉर्मैट में भेजना होगा. PdfDocument के नए एपीआई, getCanvas() से Canvas उपलब्ध कराकर, ऐसा करने का आसान तरीका देते हैं. इस Canvas पर, प्रिंट किया जा सकने वाला कॉन्टेंट बनाया जा सकता है. इसके बाद, writeTo() तरीके का इस्तेमाल करके PdfDocument को ParcelFileDescriptor में बदलें.

PrintDocumentAdapter के लिए लागू करने का तरीका तय करने के बाद, उपयोगकर्ता के अनुरोध पर प्रिंट जॉब को PrintManager तरीके, print() का इस्तेमाल करके चलाया जा सकता है. यह तरीका, PrintDocumentAdapter को अपने एक आर्ग्युमेंट के तौर पर लेता है.

इमेज प्रिंट करना

अगर आपको सिर्फ़ एक फ़ोटो या कोई अन्य बिटमैप प्रिंट करना है, तो सहायता लाइब्रेरी में मौजूद हेल्पर एपीआई आपके लिए सारा काम कर देंगे. इसके लिए, PrintHelper का नया इंस्टेंस बनाएं और setScaleMode() के साथ स्केल मोड सेट करें. इसके बाद, Bitmap को printBitmap() में पास करें. हो गया. लाइब्रेरी, प्रिंटर को बिटमैप डिलीवर करने के लिए, सिस्टम के साथ बाकी सभी इंटरैक्शन को मैनेज करती है.

प्रिंट सेवाएं उपलब्ध कराना

प्रिंटर OEM के तौर पर, android.printservice फ़्रेमवर्क का इस्तेमाल करके, Android डिवाइसों से अपने प्रिंटर को इंटरऑपरेबल बनाया जा सकता है. प्रिंट सेवाओं को APK के तौर पर बनाया और डिस्ट्रिब्यूट किया जा सकता है. उपयोगकर्ता, इन्हें अपने डिवाइसों पर इंस्टॉल कर सकते हैं. प्रिंट सेवा ऐप्लिकेशन, मुख्य रूप से हेडलेस सेवा के तौर पर काम करता है. इसके लिए, यह PrintService क्लास की सबक्लास बनाता है. यह क्लास, सिस्टम से प्रिंट जॉब पाती है और सही प्रोटोकॉल का इस्तेमाल करके, अपने प्रिंटर को जॉब भेजती है.

अपने ऐप्लिकेशन के कॉन्टेंट को प्रिंट करने के तरीके के बारे में ज़्यादा जानने के लिए, कॉन्टेंट प्रिंट करना लेख पढ़ें.

एसएमएस सेवा देने वाली कंपनी

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

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

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

ज़्यादा जानकारी के लिए, अपने एसएमएस ऐप्लिकेशन को KitKat के लिए तैयार करना ब्लॉग पोस्ट पढ़ें.

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

होस्ट कार्ड एम्युलेशन

Android ऐप्लिकेशन अब ISO14443-4 (ISO-DEP) एनएफ़सी कार्ड को एमुलेट कर सकते हैं. ये कार्ड, डेटा एक्सचेंज के लिए APDU का इस्तेमाल करते हैं. इस बारे में ISO7816-4 में बताया गया है. इससे, Android 4.4 पर चलने वाले NFC की सुविधा वाले डिवाइस पर एक साथ कई NFC कार्ड का इस्तेमाल किया जा सकता है. साथ ही, NFC पेमेंट टर्मिनल या किसी अन्य NFC रीडर को ऐप्लिकेशन आइडेंटिफ़ायर (एआईडी) के आधार पर, सही NFC कार्ड से लेन-देन शुरू करने की अनुमति मिलती है.

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

ज़्यादा जानकारी के लिए, एनएफ़सी कार्ड इम्यूलेशन गाइड पढ़ें.

एनएफ़सी रीडर मोड

नए एनएफ़सी रीडर मोड की मदद से, किसी गतिविधि को सिर्फ़ उन टैग को पढ़ने की अनुमति दी जा सकती है जिनमें उसकी दिलचस्पी है. ऐसा तब किया जा सकता है, जब गतिविधि फ़ोरग्राउंड में हो. enableReaderMode() की मदद से, अपनी गतिविधि के लिए रीडर मोड चालू किया जा सकता है. इसके लिए, NfcAdapter.ReaderCallback को लागू करें, ताकि नए टैग का पता चलने पर कॉलबैक मिल सके.

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

इन्फ़्रारेड ट्रांसमीटर

अगर आपका ऐप्लिकेशन किसी ऐसे डिवाइस पर चल रहा है जिसमें इंफ़्रारेड (आईआर) ट्रांसमीटर है, तो अब ConsumerIrManager एपीआई का इस्तेमाल करके आईआर सिग्नल भेजे जा सकते हैं. ConsumerIrManager का इंस्टेंस पाने के लिए, getSystemService() को आर्ग्युमेंट के तौर पर CONSUMER_IR_SERVICE के साथ कॉल करें. इसके बाद, getCarrierFrequencies() की मदद से डिवाइस पर काम करने वाली आईआर फ़्रीक्वेंसी के बारे में क्वेरी की जा सकती है. साथ ही, transmit() की मदद से अपनी पसंद की फ़्रीक्वेंसी और सिग्नल पैटर्न डालकर सिग्नल ट्रांसमिट किए जा सकते हैं.

आपको हमेशा पहले यह देखना चाहिए कि किसी डिवाइस में hasIrEmitter() को कॉल करके, आईआर ट्रांसमीटर शामिल है या नहीं. हालांकि, अगर आपका ऐप्लिकेशन सिर्फ़ उन डिवाइसों के साथ काम करता है जिनमें आईआर ट्रांसमीटर है, तो आपको "android.hardware.consumerir" (FEATURE_CONSUMER_IR) के लिए अपने मेनिफ़ेस्ट में <uses-feature> एलिमेंट शामिल करना चाहिए.

मल्टीमीडिया

अडैप्टिव प्लेबैक

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

MediaFormat में दो कुंजियां जोड़कर, वीडियो के हिसाब से रिज़ॉल्यूशन बदलने की सुविधा चालू की जा सकती है. ये कुंजियां, कोडेक से आपके ऐप्लिकेशन के लिए ज़रूरी ज़्यादा से ज़्यादा रिज़ॉल्यूशन के बारे में बताती हैं: KEY_MAX_WIDTH और KEY_MAX_HEIGHT. MediaFormat में इन फ़ंक्शन को जोड़ने के बाद, configure() की मदद से MediaFormat को अपने MediaCodec इंस्टेंस में पास करें.

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

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

हालांकि, अपने कोडेक को अडैप्टिव प्लेबैक के लिए कॉन्फ़िगर करने से पहले, आपको यह पुष्टि करनी होगी कि डिवाइस पर अडैप्टिव प्लेबैक की सुविधा काम करती है या नहीं. इसके लिए, FEATURE_AdaptivePlayback के साथ isFeatureSupported(String) को कॉल करें.

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

मांग पर ऑडियो सुनने की सुविधा के टाइमस्टैंप

ऑडियो-वीडियो सिंक करने की सुविधा देने के लिए, नई AudioTimestamp क्लास, AudioTrack की मदद से मैनेज की जाने वाली ऑडियो स्ट्रीम में किसी खास "फ़्रेम" की टाइमलाइन की जानकारी देती है. सबसे हाल ही का टाइमस्टैंप पाने के लिए, AudioTimestamp ऑब्जेक्ट को इंस्टैंशिएट करें और उसे getTimestamp() को पास करें. अगर टाइमस्टैंप का अनुरोध पूरा हो जाता है, तो AudioTrack इंस्टेंस को फ़्रेम यूनिट में पोज़िशन के साथ भरा जाता है. साथ ही, उस फ़्रेम को दिखाए जाने या दिखाए जाने के लिए कमिट किए जाने के अनुमानित समय की जानकारी भी दी जाती है.

AudioTimestamp में nanoTime की वैल्यू का इस्तेमाल करके, framePosition से मिलता-जुलता सबसे नज़दीकी वीडियो फ़्रेम ढूंढा जा सकता है. इससे, ऑडियो से मैच करने के लिए वीडियो फ़्रेम को ड्रॉप, डुप्लीकेट या इंटरपोल किया जा सकता है. इसके अलावा, nanoTime की वैल्यू और आने वाले समय में वीडियो फ़्रेम के अनुमानित समय (सैंपल रेट को ध्यान में रखते हुए) के बीच का डेल्टा टाइम तय करके, यह अनुमान लगाया जा सकता है कि वीडियो फ़्रेम के साथ कौनसा ऑडियो फ़्रेम दिखेगा.

Surface इमेज रीडर

नया ImageReader API, इमेज बफ़र को सीधे ऐक्सेस करने की सुविधा देता है, क्योंकि इन्हें Surface में रेंडर किया जाता है. स्टैटिक तरीके newInstance() से ImageReader हासिल किया जा सकता है. इसके बाद, नया Surface बनाने के लिए getSurface() को कॉल करें और MediaPlayer या MediaCodec जैसे प्रोड्यूसर की मदद से अपनी इमेज का डेटा डिलीवर करें. जब प्लैटफ़ॉर्म पर नई इमेज उपलब्ध हों, तब सूचना पाने के लिए, ImageReader.OnImageAvailableListener इंटरफ़ेस लागू करें और उसे setOnImageAvailableListener() के साथ रजिस्टर करें.

अब जब Surface में कॉन्टेंट ड्रॉ किया जाता है, तो ImageReader.OnImageAvailableListener को onImageAvailable() का कॉल मिलता है. ऐसा हर बार तब होता है, जब कोई नया इमेज फ़्रेम उपलब्ध होता है. इससे आपको उससे जुड़ा ImageReader मिलता है. acquireLatestImage() या acquireNextImage() को कॉल करके, फ़्रेम की इमेज का डेटा Image ऑब्जेक्ट के तौर पर पाने के लिए, ImageReader का इस्तेमाल किया जा सकता है.

Image ऑब्जेक्ट, ByteBuffer में इमेज के टाइमस्टैंप, फ़ॉर्मैट, डाइमेंशन, और पिक्सल डेटा को सीधे ऐक्सेस करने की सुविधा देता है. हालांकि, Image क्लास को आपकी इमेज का विश्लेषण करने के लिए, उन्हें ImageFormat या PixelFormat में दिए गए कॉन्स्टेंट के हिसाब से फ़ॉर्मैट किया जाना चाहिए.

पीक और आरएमएस मेज़रमेंट

अब Visualizer से मौजूदा ऑडियो स्ट्रीम के पीक और आरएमएस की क्वेरी की जा सकती है. इसके लिए, Visualizer.MeasurementPeakRms का नया इंस्टेंस बनाएं और उसे getMeasurementPeakRms() को पास करें. इस तरीके को कॉल करने पर, दिए गए Visualizer.MeasurementPeakRms की पीक और आरएमएस वैल्यू, मेज़र की गई नई वैल्यू पर सेट हो जाती हैं.

लाउडनेस एन्हैंसर

LoudnessEnhancer, AudioEffect का एक नया सबक्लास है. इसकी मदद से, MediaPlayer या AudioTrack की आवाज़ को तेज़ किया जा सकता है. यह तरीका, ऊपर बताए गए नए getMeasurementPeakRms() तरीके के साथ खास तौर पर तब मददगार हो सकता है, जब कोई दूसरा मीडिया चल रहा हो और आपको बोले गए ऑडियो ट्रैक की आवाज़ बढ़ानी हो.

रिमोट कंट्रोल

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

रिमोट कंट्रोलर बनाने के लिए, यूज़र इंटरफ़ेस को किसी भी तरीके से लागू किया जा सकता है. हालांकि, उपयोगकर्ता के मीडिया ऐप्लिकेशन में मीडिया बटन इवेंट डिलीवर करने के लिए, आपको ऐसी सेवा बनानी होगी जो NotificationListenerService क्लास को बढ़ाती हो और RemoteController.OnClientUpdateListener इंटरफ़ेस को लागू करती हो. NotificationListenerService को आधार के तौर पर इस्तेमाल करना ज़रूरी है, क्योंकि इससे निजता से जुड़ी सही पाबंदियां मिलती हैं. इन पाबंदियों के तहत, उपयोगकर्ताओं को सिस्टम की सुरक्षा सेटिंग में, आपके ऐप्लिकेशन को सूचना सुनने वाले के तौर पर चालू करना होता है.

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

रिमोट कंट्रोल से दी गई रेटिंग

Android 4.4 में, रिमोट कंट्रोल क्लाइंट (ऐसे ऐप्लिकेशन जिन्हें RemoteControlClient के साथ मीडिया कंट्रोल इवेंट मिलते हैं) की मौजूदा सुविधाओं को बेहतर बनाया गया है. इसमें, उपयोगकर्ताओं को रिमोट कंट्रोल से मौजूदा ट्रैक को रेटिंग देने की सुविधा जोड़ी गई है.

नई Rating क्लास में, उपयोगकर्ता रेटिंग की जानकारी शामिल होती है. रेटिंग को रेटिंग स्टाइल (RATING_HEART, RATING_THUMB_UP_DOWN, RATING_3_STARS, RATING_4_STARS, RATING_5_STARS या RATING_PERCENTAGE) और उस स्टाइल के हिसाब से रेटिंग वैल्यू से तय किया जाता है.

उपयोगकर्ताओं को रिमोट कंट्रोल से आपके ट्रैक को रेटिंग देने की अनुमति देने के लिए:

  • setTransportControlFlags() में FLAG_KEY_MEDIA_RATING फ़्लैग जोड़कर, यह सिग्नल दें कि आपको उपयोगकर्ता को रेटिंग यूज़र इंटरफ़ेस (अगर लागू हो) दिखाना है.
  • RemoteControlClient.MetadataEditor को वापस पाने के लिए editMetadata() को कॉल करें और उसे addEditableKey() के साथ RATING_KEY_BY_USER को पास करें.
  • इसके बाद, putObject() को कॉल करके रेटिंग का स्टाइल तय करें. इसके लिए, RATING_KEY_BY_USER को कुंजी के तौर पर और ऊपर बताए गए रेटिंग स्टाइल में से किसी एक को वैल्यू के तौर पर पास करें.

जब उपयोगकर्ता रिमोट कंट्रोल से रेटिंग बदलता है, तो कॉलबैक पाने के लिए, नया RemoteControlClient.OnMetadataUpdateListener इंटरफ़ेस लागू करें और setMetadataUpdateListener() को एक इंस्टेंस पास करें. जब उपयोगकर्ता रेटिंग बदलता है, तो आपके RemoteControlClient.OnMetadataUpdateListener को onMetadataUpdate() का कॉल मिलता है. इसमें RATING_KEY_BY_USER को बतौर कुंजी और Rating ऑब्जेक्ट को वैल्यू के तौर पर पास किया जाता है.

सबटाइटल

VideoView अब एचटीटीपी लाइव स्ट्रीम (एचएलएस) वीडियो चलाते समय, WebVTT सबटाइटल ट्रैक के साथ काम करता है. यह सबटाइटल ट्रैक, सिस्टम सेटिंग में उपयोगकर्ता की तय की गई सबटाइटल सेटिंग के हिसाब से दिखता है.

addSubtitleSource() तरीके का इस्तेमाल करके, अपने WebVTT सबटाइटल ट्रैक के साथ VideoView भी दिया जा सकता है. यह तरीका, सबटाइटल का डेटा रखने वाले InputStream और सबटाइटल के डेटा के फ़ॉर्मैट की जानकारी देने वाले MediaFormat ऑब्जेक्ट को स्वीकार करता है. createSubtitleFormat() का इस्तेमाल करके, इस फ़ॉर्मैट की जानकारी दी जा सकती है. ये सबटाइटल, उपयोगकर्ता की प्राथमिकताओं के हिसाब से वीडियो पर भी दिखते हैं.

अगर वीडियो कॉन्टेंट दिखाने के लिए VideoView का इस्तेमाल नहीं किया जाता है, तो आपको अपने सबटाइटल ओवरले को, उपयोगकर्ता की सबटाइटल की सेटिंग के हिसाब से बनाना चाहिए. नए CaptioningManager एपीआई की मदद से, उपयोगकर्ता की सबटाइटल की प्राथमिकताओं के बारे में क्वेरी की जा सकती है. इसमें CaptioningManager.CaptionStyle से तय किए गए स्टाइल, जैसे कि टाइपफ़ेस और रंग शामिल हैं. अगर वीडियो शुरू होने के बाद, उपयोगकर्ता कुछ सेटिंग में बदलाव करता है, तो आपको सेटिंग में होने वाले बदलावों को सुनना चाहिए. इसके लिए, CaptioningManager.CaptioningChangeListener का एक इंस्टेंस रजिस्टर करें, ताकि किसी भी सेटिंग में बदलाव होने पर आपको कॉलबैक मिल सके. इसके बाद, ज़रूरत के हिसाब से अपने सबटाइटल अपडेट करें.

ऐनिमेशन और ग्राफ़िक्स

सीन और ट्रांज़िशन

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

आम तौर पर, दो सीन के बीच ट्रांज़िशन करने के लिए, आपको ये काम करने होंगे:

  1. वह ViewGroup तय करें जिसमें वे यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट शामिल हैं जिन्हें आपको बदलना है.
  2. बदलाव के आखिरी नतीजे (अगले सीन) को दिखाने वाला लेआउट तय करें.
  3. उस ट्रांज़िशन टाइप की जानकारी दें जिससे लेआउट में बदलाव को ऐनिमेशन के साथ दिखाया जा सके.
  4. ट्रांज़िशन लागू करें.

पहले और दूसरे चरण को पूरा करने के लिए, Scene ऑब्जेक्ट का इस्तेमाल किया जा सकता है. Scene में, ट्रांज़िशन करने के लिए ज़रूरी लेआउट की प्रॉपर्टी के बारे में बताने वाला मेटाडेटा होता है. इसमें सीन का पैरंट व्यू और सीन का लेआउट भी शामिल है. क्लास कन्स्ट्रक्टर या स्टैटिक तरीके getSceneForLayout() का इस्तेमाल करके, Scene बनाया जा सकता है.

इसके बाद, तीसरे और चौथे चरण को पूरा करने के लिए, आपको TransitionManager का इस्तेमाल करना होगा. एक तरीका यह है कि अपने Scene को स्टैटिक तरीके go() में पास करें. यह मौजूदा लेआउट में सीन का पैरंट व्यू ढूंढता है. साथ ही, Scene से तय किए गए लेआउट तक पहुंचने के लिए, चाइल्ड व्यू पर ट्रांज़िशन करता है.

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

ज़्यादा कंट्रोल के लिए, प्रोजेक्ट res/transition/ डायरेक्ट्री में मौजूद एक्सएमएल फ़ाइल का इस्तेमाल करके, पहले से तय किए गए सीन के बीच होने वाले ट्रांज़िशन के सेट तय किए जा सकते हैं. <transitionManager> एलिमेंट में, एक या एक से ज़्यादा <transition> टैग डालें. हर टैग में एक सीन (लेआउट फ़ाइल का रेफ़रंस) और उस सीन में प्रवेश करने और/या उससे बाहर निकलने के दौरान लागू होने वाला ट्रांज़िशन शामिल होता है. इसके बाद, inflateTransitionManager() का इस्तेमाल करके ट्रांज़िशन के इस सेट को बड़ा करें. transitionTo() के साथ हर ट्रांज़िशन को लागू करने के लिए, दिखाए गए TransitionManager का इस्तेमाल करें. इसके लिए, <transition> टैग में से किसी एक से दिखाया गया Scene पास करें. TransitionManager एपीआई की मदद से, प्रोग्राम के हिसाब से ट्रांज़िशन के सेट भी तय किए जा सकते हैं.

ट्रांज़िशन तय करते समय, Transition के सबक्लास से तय किए गए कई पहले से तय किए गए टाइप का इस्तेमाल किया जा सकता है. जैसे, Fade और ChangeBounds. अगर आपने ट्रांज़िशन टाइप नहीं बताया है, तो सिस्टम डिफ़ॉल्ट रूप से AutoTransition का इस्तेमाल करता है. यह ज़रूरत के हिसाब से व्यू को अपने-आप फ़ेड करता है, उन्हें एक जगह से दूसरी जगह ले जाता है, और उनका साइज़ बदलता है. इसके अलावा, अपनी पसंद के मुताबिक ऐनिमेशन करने के लिए, इनमें से किसी भी क्लास को एक्सटेंड करके कस्टम ट्रांज़िशन बनाए जा सकते हैं. कस्टम ट्रांज़िशन, प्रॉपर्टी में हुए किसी भी बदलाव को ट्रैक कर सकता है. साथ ही, उन बदलावों के आधार पर कोई भी ऐनिमेशन बना सकता है. उदाहरण के लिए, Transition का एक सबक्लास दिया जा सकता है, जो किसी व्यू की "रोटेशन" प्रॉपर्टी में होने वाले बदलावों को सुनता है. इसके बाद, वह किसी भी बदलाव को ऐनिमेट करता है.

ज़्यादा जानकारी के लिए, TransitionManager दस्तावेज़ देखें.

ऐनिमेशन रोकना

Animator एपीआई की मदद से, अब pause() और resume() तरीकों से चल रहे ऐनिमेशन को रोका और फिर से शुरू किया जा सकता है.

किसी ऐनिमेशन की स्थिति को ट्रैक करने के लिए, Animator.AnimatorPauseListener इंटरफ़ेस लागू किया जा सकता है. यह इंटरफ़ेस, ऐनिमेशन के रोके और फिर से शुरू किए जाने पर कॉलबैक देता है: pause() और resume(). इसके बाद, addPauseListener() की मदद से, लिसनर को Animator ऑब्जेक्ट में जोड़ें.

इसके अलावा, AnimatorListenerAdapter ऐब्सट्रैक्ट क्लास की सबक्लास बनाई जा सकती है. इसमें अब Animator.AnimatorPauseListener के तय किए गए रोकें और फिर से शुरू करें कॉलबैक के लिए, खाली तरीके शामिल किए गए हैं.

फिर से इस्तेमाल किए जा सकने वाले बिटमैप

अब किसी भी दूसरे बिटमैप को डिकोड करने के लिए, BitmapFactory में मौजूद किसी भी बिटमैप का फिर से इस्तेमाल किया जा सकता है. भले ही, नया बिटमैप किसी दूसरे साइज़ का हो. ऐसा तब तक किया जा सकता है, जब तक कि डिकोड किए गए बिटमैप (getByteCount() से उपलब्ध) के बाइट की संख्या, फिर से इस्तेमाल किए गए बिटमैप (getAllocationByteCount() से उपलब्ध) के बाइट की संख्या से कम या उसके बराबर हो. ज़्यादा जानकारी के लिए, inBitmap देखें.

Bitmap के लिए नए एपीआई, BitmapFactory के बाहर फिर से इस्तेमाल करने के लिए, मिलते-जुलते कॉन्फ़िगरेशन की अनुमति देते हैं. ऐसा मैन्युअल बिटमैप जनरेशन या कस्टम डिकोडिंग लॉजिक के लिए किया जाता है. अब setHeight() और setWidth() के तरीकों से बिटमैप के डाइमेंशन सेट किए जा सकते हैं. साथ ही, setConfig() की मदद से नया Bitmap.Config तय किया जा सकता है. इससे, बिटमैप के मौजूदा ऐलोकेशन पर कोई असर नहीं पड़ेगा. reconfigure() तरीके से, एक कॉल में इन बदलावों को आसानी से जोड़ा जा सकता है.

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

यूज़र जनरेटेड कॉन्टेंट

स्टोरेज ऐक्सेस फ़्रेमवर्क

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

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

queryRoots()
इससे आपको एक Cursor दिखना चाहिए, जिसमें DocumentsContract.Root में बताए गए कॉलम का इस्तेमाल करके, आपके दस्तावेज़ के स्टोरेज की सभी रूट डायरेक्ट्री के बारे में बताया गया हो.
queryChildDocuments()
इससे एक Cursor दिखना चाहिए, जिसमें DocumentsContract.Document में बताए गए कॉलम का इस्तेमाल करके, बताई गई डायरेक्ट्री की सभी फ़ाइलों के बारे में बताया गया हो.
queryDocument()
इससे Cursor दिखना चाहिए, जिसमें DocumentsContract.Document में बताए गए कॉलम का इस्तेमाल करके, बताई गई फ़ाइल के बारे में जानकारी दी गई हो.
openDocument()
इससे, बताई गई फ़ाइल को दिखाने वाला ParcelFileDescriptor दिखना चाहिए. उपयोगकर्ता किसी फ़ाइल को चुनने के बाद, सिस्टम इस तरीके को कॉल करता है. साथ ही, क्लाइंट ऐप्लिकेशन openFileDescriptor() को कॉल करके, फ़ाइल का ऐक्सेस पाने का अनुरोध करता है.

ज़्यादा जानकारी के लिए, स्टोरेज ऐक्सेस फ़्रेमवर्क की गाइड देखें.

बाहरी स्टोरेज का ऐक्सेस

अब ऐप्लिकेशन से जुड़ी फ़ाइलों को, सेकंडरी बाहरी स्टोरेज मीडिया पर पढ़ा और उसमें बदलाव किया जा सकता है. जैसे, जब किसी डिवाइस में एमुलेट किया गया स्टोरेज और एसडी कार्ड, दोनों मौजूद हों. नया तरीका getExternalFilesDirs(), मौजूदा getExternalFilesDir() तरीके की तरह ही काम करता है. हालांकि, यह File ऑब्जेक्ट का कलेक्शन दिखाता है. इस तरीके से मिले किसी भी पाथ को पढ़ने या उसमें लिखने से पहले, File ऑब्जेक्ट को नए getStorageState() तरीके में पास करें. इससे यह पुष्टि की जा सकेगी कि स्टोरेज फ़िलहाल उपलब्ध है या नहीं.

आपके ऐप्लिकेशन के हिसाब से बनाई गई कैश मेमोरी डायरेक्ट्री और OBB डायरेक्ट्री को ऐक्सेस करने के अन्य तरीकों के लिए भी, अब उनके हिसाब से वर्शन उपलब्ध हैं. ये वर्शन, सेकंडरी स्टोरेज डिवाइसों को ऐक्सेस करने की सुविधा देते हैं: getExternalCacheDirs() और getObbDirs().

दिखाए गए File कलेक्शन में पहली एंट्री को डिवाइस का मुख्य बाहरी स्टोरेज माना जाता है. यह getExternalFilesDir() जैसे मौजूदा तरीकों से दिखाए गए File से मेल खाता है.

ध्यान दें: Android 4.4 के बाद, प्लैटफ़ॉर्म के लिए यह ज़रूरी नहीं है कि आपका ऐप्लिकेशन WRITE_EXTERNAL_STORAGE या READ_EXTERNAL_STORAGE ऐक्सेस करे. ऐसा तब ज़रूरी नहीं है, जब आपको ऊपर बताए गए तरीकों का इस्तेमाल करके, सिर्फ़ ऐप्लिकेशन के लिए तय किए गए स्टोरेज का ऐक्सेस चाहिए. हालांकि, अगर आपको getExternalStoragePublicDirectory() की दी गई बाहरी स्टोरेज की शेयर की जा सकने वाली जगहों को ऐक्सेस करना है, तो अनुमतियां ज़रूरी हैं.

सिंक अडैप्टर

ContentResolver में मौजूद requestSync() का नया तरीका, आपके ContentProvider के लिए सिंक अनुरोध तय करने की कुछ प्रक्रिया को आसान बनाता है. यह, अनुरोधों को नए SyncRequest ऑब्जेक्ट में कैप्सुलेट करके करता है. SyncRequest ऑब्जेक्ट को SyncRequest.Builder की मदद से बनाया जा सकता है. SyncRequest में मौजूद प्रॉपर्टी, मौजूदा ContentProvider सिंक कॉल की तरह ही काम करती हैं. हालांकि, setDisallowMetered() को चालू करके यह तय किया जा सकता है कि नेटवर्क मेज़र होने पर सिंक को छोड़ दिया जाए.

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

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

नया TYPE_GEOMAGNETIC_ROTATION_VECTOR सेंसर, मैग्नेटोमीटर के आधार पर रोटेशन वेक्टर का डेटा उपलब्ध कराता है. यह TYPE_ROTATION_VECTOR सेंसर का एक अच्छा विकल्प है. इसका इस्तेमाल तब किया जाता है, जब फ़ोन स्लीप मोड में हो और डिवाइस के ओरिएंटेशन को रिकॉर्ड करने के लिए, बैच में सेंसर इवेंट के साथ इस्तेमाल किया जा रहा हो. इस सेंसर को TYPE_ROTATION_VECTOR से कम पावर की ज़रूरत होती है. हालांकि, हो सकता है कि इवेंट डेटा में गड़बड़ी हो. साथ ही, यह उपयोगकर्ता के बाहर होने पर सबसे ज़्यादा असरदार होता है.

Android अब हार्डवेयर में पहले से मौजूद कदमों के सेंसर के साथ भी काम करता है:

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

ध्यान रखें कि ये दो चरणों वाले सेंसर, हमेशा एक जैसे नतीजे नहीं देते. TYPE_STEP_COUNTER इवेंट, TYPE_STEP_DETECTOR इवेंट की तुलना में ज़्यादा इंतज़ार के साथ होते हैं. ऐसा इसलिए होता है, क्योंकि TYPE_STEP_COUNTER एल्गोरिदम, गलत सकारात्मक नतीजों को हटाने के लिए ज़्यादा प्रोसेसिंग करता है. इसलिए, हो सकता है कि TYPE_STEP_COUNTER इवेंट डिलीवर करने में ज़्यादा समय ले, लेकिन इसके नतीजे ज़्यादा सटीक होने चाहिए.

दोनों स्टेप सेंसर, हार्डवेयर पर निर्भर होते हैं. Nexus 5, इनका इस्तेमाल करने वाला पहला डिवाइस है. इसलिए, आपको hasSystemFeature() के साथ उपलब्धता की जांच करनी चाहिए. इसके लिए, FEATURE_SENSOR_STEP_DETECTOR और FEATURE_SENSOR_STEP_COUNTER कॉन्स्टेंट का इस्तेमाल करें.

एक साथ भेजे गए सेंसर इवेंट

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

एक साथ कई अनुरोध करने की सुविधा देने के लिए, SensorManager क्लास में registerListener() तरीके के दो नए वर्शन जोड़े गए हैं. इनकी मदद से, "रिपोर्ट के लिए ज़्यादा से ज़्यादा इंतज़ार का समय" तय किया जा सकता है. इस नए पैरामीटर से पता चलता है कि नए सेंसर इवेंट की डिलीवरी के लिए, आपका SensorEventListener कितनी देरी कर सकता है. उदाहरण के लिए, अगर आपने एक मिनट की बैचिंग में लगने वाले समय की जानकारी दी है, तो सिस्टम एक मिनट से ज़्यादा के अंतराल पर, बैच किए गए इवेंट का नया सेट डिलीवर करेगा. इसके लिए, सिस्टम आपके onSensorChanged() तरीके को लगातार कॉल करेगा. हर बैच किए गए इवेंट के लिए एक बार कॉल किया जाएगा. सेंसर इवेंट, रिपोर्ट में देरी की तय सीमा से ज़्यादा समय तक कभी नहीं दिखेंगे. हालांकि, अगर दूसरे ऐप्लिकेशन ने उसी सेंसर के लिए देरी की कम अवधि का अनुरोध किया है, तो इवेंट जल्दी दिख सकते हैं.

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

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

कंट्रोलर की पहचान

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

कनेक्ट किए गए डिवाइस अब प्रॉडक्ट और वेंडर आईडी भी उपलब्ध कराते हैं. ये आईडी, getProductId() और getVendorId() से मिलते हैं. अगर आपको किसी डिवाइस पर उपलब्ध बटन के सेट के आधार पर, बटन मैपिंग में बदलाव करना है, तो डिवाइस से क्वेरी करके यह पता लगाया जा सकता है कि hasKeys(int...) के साथ कुछ बटन उपलब्ध हैं या नहीं.

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

इमर्सिव फ़ुल-स्क्रीन मोड

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

ट्रांसलूसंट सिस्टम बार

अब नई थीम, Theme.Holo.NoActionBar.TranslucentDecor और Theme.Holo.Light.NoActionBar.TranslucentDecor की मदद से, सिस्टम बार को कुछ हद तक पारदर्शी बनाया जा सकता है. पारदर्शी सिस्टम बार चालू करने पर, आपका लेआउट सिस्टम बार के पीछे के हिस्से को भर देगा. इसलिए, आपको अपने लेआउट के उस हिस्से के लिए भी fitsSystemWindows चालू करना होगा जिसे सिस्टम बार से नहीं छिपाना है.

अगर कोई कस्टम थीम बनाई जा रही है, तो इनमें से किसी एक थीम को पैरंट थीम के तौर पर सेट करें या अपनी थीम में windowTranslucentNavigation और windowTranslucentStatus स्टाइल प्रॉपर्टी शामिल करें.

सूचना को सुनने की बेहतर सुविधा

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

नए Notification.extras फ़ील्ड में एक Bundle शामिल होता है, ताकि सूचना बिल्डर को EXTRA_TITLE और EXTRA_PICTURE जैसे अतिरिक्त मेटाडेटा डिलीवर किए जा सकें. नई Notification.Action क्लास, सूचना से जुड़ी कार्रवाई की विशेषताओं के बारे में बताती है. इन्हें नए actions फ़ील्ड से वापस पाया जा सकता है.

दाएं से बाएं लिखी जाने वाली भाषाओं के लेआउट के लिए, डरावल मिररिंग

अगर आपके ऐप्लिकेशन में ऐसी इमेज शामिल हैं जिन्हें दाईं से बाईं ओर के लेआउट के लिए, उनके हॉरिज़ॉन्टल ओरिएंटेशन को उलटना चाहिए, तो आपको drawables-ldrtl/ संसाधन डायरेक्ट्री में मिरर की गई इमेज शामिल करनी होगी. अब सिस्टम, ड्रॉ किए जा सकने वाले संसाधन पर autoMirrored एट्रिब्यूट को चालू करके या setAutoMirrored() को कॉल करके, आपके लिए इमेज को अपने-आप मिरर कर सकता है. यह सुविधा चालू होने पर, लेआउट की दिशा दाईं से बाईं होने पर, Drawable अपने-आप मिरर हो जाता है.

सुलभता

View क्लास की मदद से, अब अपने यूज़र इंटरफ़ेस (यूआई) के उन हिस्सों के लिए "लाइव रीजन" तय किए जा सकते हैं जो नए टेक्स्ट कॉन्टेंट के साथ डाइनैमिक तौर पर अपडेट होते हैं. इसके लिए, अपने एक्सएमएल लेआउट में नया accessibilityLiveRegion एट्रिब्यूट जोड़ें या setAccessibilityLiveRegion() को कॉल करें. उदाहरण के लिए, "गलत पासवर्ड" सूचना दिखाने वाले टेक्स्ट फ़ील्ड वाली लॉगिन स्क्रीन को लाइव क्षेत्र के तौर पर मार्क किया जाना चाहिए. इससे स्क्रीन रीडर, मैसेज बदलने पर उसे पढ़कर सुनाएगा.

सुलभता सेवा देने वाले ऐप्लिकेशन, अब नए एपीआई की मदद से अपनी सुविधाओं को बेहतर बना सकते हैं. ये एपीआई, AccessibilityNodeInfo.CollectionInfo और AccessibilityNodeInfo.CollectionItemInfo का इस्तेमाल करके, सूची या ग्रिड व्यू जैसे व्यू कलेक्शन के बारे में जानकारी देते हैं.

ऐप्लिकेशन अनुमतियां

यहां दी गई नई अनुमतियां हैं. कुछ नए एपीआई का इस्तेमाल करने के लिए, आपके ऐप्लिकेशन को <uses-permission> टैग के साथ इनका अनुरोध करना होगा:

INSTALL_SHORTCUT
ऐप्लिकेशन को लॉन्चर में शॉर्टकट इंस्टॉल करने की अनुमति देता है
UNINSTALL_SHORTCUT
ऐप्लिकेशन को लॉन्चर में मौजूद शॉर्टकट को अनइंस्टॉल करने की अनुमति देता है
TRANSMIT_IR
ऐप्लिकेशन को डिवाइस के आईआर ट्रांसमीटर का इस्तेमाल करने की अनुमति देता है. हालांकि, यह अनुमति सिर्फ़ तब दी जाती है, जब डिवाइस में आईआर ट्रांसमीटर मौजूद हो

ध्यान दें: Android 4.4 के बाद, getExternalFilesDir() जैसे तरीकों का इस्तेमाल करके, बाहरी स्टोरेज में ऐप्लिकेशन के लिए खास तौर पर सेट किए गए हिस्से को ऐक्सेस करने के लिए, आपके ऐप्लिकेशन को WRITE_EXTERNAL_STORAGE या READ_EXTERNAL_STORAGE की ज़रूरत नहीं है. हालांकि, अगर आपको getExternalStoragePublicDirectory() की दी गई बाहरी स्टोरेज की शेयर की जा सकने वाली जगहों को ऐक्सेस करना है, तो अनुमतियां लेना ज़रूरी है.

डिवाइस की सुविधाएं

यहां डिवाइस की नई सुविधाओं के बारे में बताया गया है. इन सुविधाओं के बारे में <uses-feature> टैग का इस्तेमाल करके बताया जा सकता है. इससे, ऐप्लिकेशन की ज़रूरी शर्तों के बारे में जानकारी दी जा सकती है. साथ ही, Google Play पर फ़िल्टर करने की सुविधा चालू की जा सकती है या रनटाइम के दौरान इसकी जांच की जा सकती है:

FEATURE_CONSUMER_IR
डिवाइस, उपभोक्ता के आईआर डिवाइसों से संपर्क कर सकता है.
FEATURE_DEVICE_ADMIN
डिवाइस एडमिन के ज़रिए, डिवाइस पर नीति लागू करने की सुविधा काम करती है.
FEATURE_NFC_HOST_CARD_EMULATION
डिवाइस पर, होस्ट-आधारित एनएफ़सी कार्ड इम्यूलेशन की सुविधा काम करती है.
FEATURE_SENSOR_STEP_COUNTER
डिवाइस में हार्डवेयर स्टैप काउंटर शामिल है.
FEATURE_SENSOR_STEP_DETECTOR
डिवाइस में कदमों की गिनती करने वाला हार्डवेयर डिटेक्टर शामिल है.

Android 4.4 में एपीआई से जुड़े सभी बदलावों के बारे में ज़्यादा जानने के लिए, एपीआई के बीच अंतर की रिपोर्ट देखें.