Android 11 पर कस्टम टैब इस्तेमाल करना

Android 11 में, ऐप्लिकेशन के उन दूसरे ऐप्लिकेशन के साथ इंटरैक्ट करने के तरीके में बदलाव किए गए हैं जिन्हें उपयोगकर्ता ने डिवाइस पर इंस्टॉल किया है. इन बदलावों के बारे में ज़्यादा जानने के लिए, Android दस्तावेज़ पर जाएं.

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

सबसे आसान तरीके से, कस्टम टैब को एक लाइन वाले कोड से लॉन्च किया जा सकता है. जैसे:

new CustomTabsIntent.Builder().build()
        .launchUrl(this, Uri.parse("https://www.example.com"));

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

नेटिव ऐप्लिकेशन को प्राथमिकता देना

हालांकि, अगर आपने सबसे सही तरीकों का पालन किया है, तो हो सकता है कि आपको कुछ बदलाव करने पड़ें.

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

Android 11 और उसके बाद के वर्शन पर

Android 11 में एक नया इंटेंट फ़्लैग, FLAG_ACTIVITY_REQUIRE_NON_BROWSER जोड़ा गया है. किसी नेटिव ऐप्लिकेशन को खोलने के लिए, इसे इस्तेमाल करने का सुझाव दिया जाता है. ऐसा इसलिए, क्योंकि इसके लिए ऐप्लिकेशन को पैकेज मैनेजर से जुड़ी कोई क्वेरी नहीं देनी पड़ती.

static boolean launchNativeApi30(Context context, Uri uri) {
    Intent nativeAppIntent = new Intent(Intent.ACTION_VIEW, uri)
            .addCategory(Intent.CATEGORY_BROWSABLE)
            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                    Intent.FLAG_ACTIVITY_REQUIRE_NON_BROWSER);
    try {
        context.startActivity(nativeAppIntent);
        return true;
    } catch (ActivityNotFoundException ex) {
        return false;
    }
}

इसका हल यह है कि इंटेंट को लॉन्च करने की कोशिश करें और FLAG_ACTIVITY_REQUIRE_NON_BROWSER का इस्तेमाल करके, Android को लॉन्च करते समय ब्राउज़र से बचने के लिए कहें.

अगर कोई ऐसा नेटिव ऐप्लिकेशन नहीं मिलता जो इस इंटेंट को मैनेज कर सकता है, तो एक ActivityNotFoundException को थ्रो किया जाएगा.

Android 11 से पहले

भले ही, ऐप्लिकेशन Android 11 या एपीआई लेवल 30 को टारगेट करता हो, लेकिन Android के पिछले वर्शन में FLAG_ACTIVITY_REQUIRE_NON_BROWSER फ़्लैग काम नहीं करेगा. इसलिए, हमें उन मामलों में पैकेज मैनेजर से क्वेरी करने की ज़रूरत पड़ेगी:

private static boolean launchNativeBeforeApi30(Context context, Uri uri) {
    PackageManager pm = context.getPackageManager();

    // Get all Apps that resolve a generic url
    Intent browserActivityIntent = new Intent()
            .setAction(Intent.ACTION_VIEW)
            .addCategory(Intent.CATEGORY_BROWSABLE)
            .setData(Uri.fromParts("http", "", null));
    Set<String> genericResolvedList = extractPackageNames(
            pm.queryIntentActivities(browserActivityIntent, 0));

    // Get all apps that resolve the specific Url
    Intent specializedActivityIntent = new Intent(Intent.ACTION_VIEW, uri)
            .addCategory(Intent.CATEGORY_BROWSABLE);
    Set<String> resolvedSpecializedList = extractPackageNames(
            pm.queryIntentActivities(specializedActivityIntent, 0));

    // Keep only the Urls that resolve the specific, but not the generic
    // urls.
    resolvedSpecializedList.removeAll(genericResolvedList);

    // If the list is empty, no native app handlers were found.
    if (resolvedSpecializedList.isEmpty()) {
        return false;
    }

    // We found native handlers. Launch the Intent.
    specializedActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(specializedActivityIntent);
    return true;
}

यहां इस्तेमाल किए गए तरीके में, पैकेज मैनेजर से उन ऐप्लिकेशन के बारे में क्वेरी की जाती है जो सामान्य http इंटेंट के साथ काम करते हैं. ऐसा हो सकता है कि वे ऐप्लिकेशन ब्राउज़र हों.

इसके बाद, उस यूआरएल के लिए ऐप्लिकेशन ढूंढें जो हमें लॉन्च करना है. इससे, उस यूआरएल को मैनेज करने के लिए, ब्राउज़र और नेटिव ऐप्लिकेशन, दोनों का सेटअप दिखेगा.

अब, पहली सूची में मौजूद सभी ब्राउज़र को दूसरी सूची से हटाएं. ऐसा करने पर, हमारे पास सिर्फ़ नेटिव ऐप्लिकेशन ही बचे रहेंगे.

अगर सूची खाली है, तो इसका मतलब है कि कोई नेटिव हैंडलर नहीं है. ऐसे में, हम 'गलत है' दिखाते हैं. ऐसा न होने पर, हम नेटिव हैंडलर के लिए इंटेंट लॉन्च करते हैं.

यह रही पूरी जानकारी

हमें यह पक्का करना होगा कि हर अवसर के लिए सही तरीका इस्तेमाल किया जा रहा हो:

static void launchUri(Context context, Uri uri) {
    boolean launched = Build.VERSION.SDK_INT >= 30 ?
            launchNativeApi30(context, uri) :
            launchNativeBeforeApi30(context, uri);

    if (!launched) {
        new CustomTabsIntent.Builder()
                .build()
                .launchUrl(context, uri);
    }
}

Build.VERSION.SDK_INT से हमें ज़रूरी जानकारी मिलती है. अगर यह वैल्यू 30 के बराबर या उससे ज़्यादा है, तो Android को FLAG_ACTIVITY_REQUIRE_NON_BROWSER के बारे में पता होता है. साथ ही, हम नए तरीके से नेटिव ऐप्लिकेशन लॉन्च करने की कोशिश कर सकते हैं. अगर ऐसा नहीं है, तो हम पुराने तरीके से लॉन्च करने की कोशिश करते हैं.

अगर नेटिव ऐप्लिकेशन लॉन्च नहीं होता है, तो हम कस्टम टैब लॉन्च करते हैं.

इस सबसे सही तरीके में, कुछ बोयलरप्लेट शामिल हैं. हम इसे आसान बनाने के लिए, लाइब्रेरी में मौजूद जटिलताओं को शामिल कर रहे हैं. android-browser-helper सहायता लाइब्रेरी के अपडेट पाने के लिए, हमारे साथ बने रहें.

कस्टम टैब की सुविधा के साथ काम करने वाले ब्राउज़र का पता लगाना

एक और सामान्य पैटर्न यह है कि डिवाइस पर कौनसे ब्राउज़र कस्टम टैब के साथ काम करते हैं, यह पता लगाने के लिए PackageManager का इस्तेमाल किया जाता है. इसका इस्तेमाल आम तौर पर इन कामों के लिए किया जाता है: ऐप्लिकेशन के नाम से जुड़ी गड़बड़ी को ठीक करने वाले डायलॉग बॉक्स से बचने के लिए, इंटेंट पर पैकेज सेट करना या कस्टम टैब सेवा से कनेक्ट करते समय यह चुनना कि किस ब्राउज़र से कनेक्ट करना है.

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

<queries>
    <intent>
        <action android:name=
            "android.support.customtabs.action.CustomTabsService" />
    </intent>
</queries>

मार्कअप लागू होने के बाद, कस्टम टैब के साथ काम करने वाले ब्राउज़र के लिए क्वेरी करने के लिए इस्तेमाल किया जाने वाला मौजूदा कोड उम्मीद के मुताबिक काम करेगा.

अक्सर पूछे जाने वाले सवाल

सवाल: कस्टम टैब के लिए क्वेरी देने वाले कोड में, उन ऐप्लिकेशन के लिए क्वेरी खोजी जाती हैं जो https:// इंटेंट को मैनेज कर सकते हैं. हालांकि, क्वेरी फ़िल्टर सिर्फ़ android.support.customtabs.action.CustomTabsService क्वेरी दिखाता है. क्या https:// इंटेंट के लिए क्वेरी नहीं बनाई जानी चाहिए?

जवाब: क्वेरी फ़िल्टर का एलान करने पर, यह PackageManager को क्वेरी के जवाबों को फ़िल्टर करेगा, न कि क्वेरी को. कस्टम टैब के साथ काम करने वाले ब्राउज़र, CustomTabsService को मैनेज करने का एलान करते हैं. इसलिए, उन्हें फ़िल्टर नहीं किया जाएगा. कस्टम टैब की सुविधा के साथ काम न करने वाले ब्राउज़र को फ़िल्टर कर दिया जाएगा.

नतीजा

Android 11 के साथ काम करने के लिए, मौजूदा कस्टम टैब इंटिग्रेशन में ये सभी बदलाव ज़रूरी हैं. किसी Android ऐप्लिकेशन में कस्टम टैब इंटिग्रेट करने के बारे में ज़्यादा जानने के लिए, इस्तेमाल करने से जुड़ी गाइड देखें. इसके बाद, बेहतर इंटिग्रेशन बनाने के बारे में जानने के लिए, सबसे सही तरीके देखें.

अगर आपका कोई सवाल या सुझाव/राय है, तो हमें बताएं!