Android 11 এর সাথে কাস্টম ট্যাব ব্যবহার করা

অ্যান্ড্রয়েড 11 ব্যবহারকারী ডিভাইসে ইনস্টল করা অন্যান্য অ্যাপের সাথে অ্যাপগুলি কীভাবে ইন্টারঅ্যাক্ট করতে পারে তার পরিবর্তনগুলি চালু করেছে। আপনি Android ডকুমেন্টেশনে সেই পরিবর্তনগুলি সম্পর্কে আরও পড়তে পারেন।

কাস্টম ট্যাব ব্যবহার করে একটি অ্যান্ড্রয়েড অ্যাপ যখন SDK লেভেল 30 বা তার উপরে লক্ষ্য করে তখন কিছু পরিবর্তনের প্রয়োজন হতে পারে। এই নিবন্ধটি সেই অ্যাপগুলির জন্য প্রয়োজনীয় পরিবর্তনগুলি নিয়ে যায়৷

সহজ ক্ষেত্রে, কাস্টম ট্যাবগুলি একটি ওয়ান-লাইনার দিয়ে চালু করা যেতে পারে:

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

এই পদ্ধতি ব্যবহার করে অ্যাপ্লিকেশানগুলি চালু করা, অথবা এমনকি টুলবারের রঙ পরিবর্তন করার মতো UI কাস্টমাইজেশন যোগ করা, একটি অ্যাকশন বোতাম যোগ করার জন্য অ্যাপ্লিকেশনটিতে কোনো পরিবর্তন করতে হবে না।

নেটিভ অ্যাপ পছন্দ করে

তবে, আপনি যদি সেরা অনুশীলনগুলি অনুসরণ করেন তবে কিছু পরিবর্তনের প্রয়োজন হতে পারে।

প্রথম প্রাসঙ্গিক সর্বোত্তম অভ্যাস হল যে অ্যাপ্লিকেশনগুলিকে একটি কাস্টম ট্যাবের পরিবর্তে একটি নেটিভ অ্যাপ পছন্দ করা উচিত যদি এটি পরিচালনা করতে সক্ষম এমন একটি অ্যাপ ইনস্টল করা থাকে।

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, বা API স্তর 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 অভিপ্রায় সমর্থন করে। এই অ্যাপ্লিকেশনগুলি সম্ভবত ব্রাউজার।

তারপরে, আমরা যে নির্দিষ্ট URL লঞ্চ করতে চাই তার জন্য আইটেন্টগুলি পরিচালনা করে এমন অ্যাপ্লিকেশনগুলির জন্য ক্যোয়ারী৷ এটি সেই URL পরিচালনা করতে ব্রাউজার এবং নেটিভ অ্যাপ্লিকেশন সেটআপ উভয়ই ফিরিয়ে দেবে।

এখন, দ্বিতীয় তালিকা থেকে প্রথম তালিকায় পাওয়া সমস্ত ব্রাউজার মুছে ফেলুন, এবং আমাদের কাছে শুধুমাত্র নেটিভ অ্যাপই থাকবে।

যদি তালিকাটি খালি থাকে, আমরা জানি কোন নেটিভ হ্যান্ডলার নেই এবং মিথ্যা ফেরত দেয়। অন্যথায়, আমরা নেটিভ হ্যান্ডলারের জন্য অভিপ্রায় চালু করি।

সবগুলোকে একত্রে রাখ

আমাদের প্রতিটি অনুষ্ঠানের জন্য সঠিক পদ্ধতি ব্যবহার নিশ্চিত করতে হবে:

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 জানে এবং আমরা নতুন পদ্ধতির সাথে একটি নেটিভা অ্যাপ চালু করার চেষ্টা করতে পারি। অন্যথায়, আমরা পুরানো পদ্ধতির সাথে চালু করার চেষ্টা করি।

যদি একটি নেটিভ অ্যাপ চালু করা ব্যর্থ হয়, তাহলে আমরা একটি কাস্টম ট্যাব চালু করি।

এই সেরা অনুশীলনের সাথে জড়িত কিছু বয়লারপ্লেট আছে। আমরা একটি লাইব্রেরিতে জটিলতা এনক্যাপসুলেট করে এটিকে সহজ করার জন্য কাজ করছি। অ্যান্ড্রয়েড-ব্রাউজার-হেল্পার সাপোর্ট লাইব্রেরির আপডেটের জন্য সাথে থাকুন।

কাস্টম ট্যাব সমর্থন করে এমন ব্রাউজার সনাক্ত করা

আরেকটি সাধারণ প্যাটার্ন হল ডিভাইসে কোন ব্রাউজারগুলি কাস্টম ট্যাব সমর্থন করে তা সনাক্ত করতে প্যাকেজ ম্যানেজার ব্যবহার করা। এর জন্য সাধারণ ব্যবহারের ক্ষেত্রে অ্যাপ দ্ব্যর্থতাহীন ডায়ালগ এড়াতে অভিপ্রায় প্যাকেজ সেট করা বা কাস্টম ট্যাব পরিষেবার সাথে সংযোগ করার সময় কোন ব্রাউজারে সংযোগ করতে হবে তা বেছে নেওয়া।

API লেভেল 30 টার্গেট করার সময়, ডেভেলপারদের তাদের অ্যান্ড্রয়েড ম্যানিফেস্টে একটি ক্যোয়ারী বিভাগ যোগ করতে হবে, একটি অভিপ্রায়-ফিল্টার ঘোষণা করে যা কাস্টম ট্যাব সমর্থন সহ ব্রাউজারগুলির সাথে মেলে।

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

মার্কআপের জায়গায়, কাস্টম ট্যাব সমর্থন করে এমন ব্রাউজারগুলির জন্য অনুসন্ধানের জন্য ব্যবহৃত বিদ্যমান কোডটি প্রত্যাশা অনুযায়ী কাজ করবে।

সচরাচর জিজ্ঞাস্য

প্রশ্ন: যে কোডটি কাস্টম ট্যাব প্রদানকারী অ্যাপ্লিকেশনগুলির জন্য অনুসন্ধান করে যেগুলি https:// intents পরিচালনা করতে পারে, কিন্তু ক্যোয়ারী ফিল্টার শুধুমাত্র একটি android.support.customtabs.action.CustomTabsService ক্যোয়ারী ঘোষণা করে৷ https:// ইন্টেন্টের জন্য একটি প্রশ্ন ঘোষণা করা উচিত নয়?

উত্তর: একটি ক্যোয়ারী ফিল্টার ঘোষণা করার সময়, এটি প্যাকেজ ম্যানেজারে একটি প্রশ্নের উত্তর ফিল্টার করবে, ক্যোয়ারী নিজেই নয়। যেহেতু কাস্টম ট্যাব সমর্থন করে এমন ব্রাউজারগুলি কাস্টম ট্যাবসার্ভিস পরিচালনা করার ঘোষণা দেয়, সেগুলি ফিল্টার করা হবে না৷ কাস্টম ট্যাব সমর্থন করে না এমন ব্রাউজারগুলি ফিল্টার করা হবে৷

উপসংহার

অ্যান্ড্রয়েড 11-এর সাথে কাজ করার জন্য একটি বিদ্যমান কাস্টম ট্যাব ইন্টিগ্রেশনকে মানিয়ে নেওয়ার জন্য এই সমস্ত পরিবর্তনগুলি প্রয়োজন৷ একটি অ্যান্ড্রয়েড অ্যাপে কাস্টম ট্যাবগুলিকে একীভূত করার বিষয়ে আরও জানতে, বাস্তবায়ন নির্দেশিকা দিয়ে শুরু করুন তারপর একটি প্রথম-শ্রেণীর নির্মাণ সম্পর্কে শিখতে সেরা অনুশীলনগুলি দেখুন৷ মিশ্রণ.

আপনার কোন প্রশ্ন বা প্রতিক্রিয়া থাকলে আমাদের জানান!