Android 11'de Özel Sekmeleri Kullanma

Android 11, uygulamaların kullanıcının cihaza yüklediği diğer uygulamalarla etkileşime geçme şekliyle ilgili değişiklikler getirdi. Bu değişiklikler hakkında daha fazla bilgiyi Android belgelerinde bulabilirsiniz.

Özel Sekmeler kullanan bir Android uygulaması SDK düzeyi 30 veya üstünü hedeflediğinde bazı değişiklikler gerekebilir. Bu makalede, söz konusu uygulamalar için yapılması gerekebilecek değişiklikler ele alınmaktadır.

En basit durumda, özel sekmeler aşağıdaki gibi tek satırlık bir komutla başlatılabilir:

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

Bu yaklaşımı kullanarak uygulama başlatan veya hatta araç çubuğu rengini değiştirme, işlem düğmesi ekleme gibi kullanıcı arayüzü özelleştirmeleri ekleyen uygulamaların uygulamada herhangi bir değişiklik yapması gerekmez.

Yerel uygulamaları tercih etme

Ancak en iyi uygulamalara uyduysanız bazı değişiklikler yapmanız gerekebilir.

Alakalı ilk en iyi uygulama, uygulamaların, işleme yeteneğine sahip bir uygulama yüklüyse Özel Sekme yerine intent'i işlemek için yerel bir uygulamayı tercih etmesidir.

Android 11 ve sonraki sürümlerde

Android 11'de, FLAG_ACTIVITY_REQUIRE_NON_BROWSER adlı yeni bir Intent işareti kullanıma sunulmuştur. Bu işaret, uygulamanın paket yöneticisi sorguları belirtmesini gerektirmediğinden, yerel bir uygulamayı açmayı denemek için önerilen yöntemdir.

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;
    }
}

Çözüm, Intent'i başlatmayı denemek ve Android'den başlatırken tarayıcılardan kaçınmasını istemek için FLAG_ACTIVITY_REQUIRE_NON_BROWSER kullanmaktır.

Bu Intent'i işleyebilen bir yerel uygulama bulunamazsa bir ActivityNotFoundException oluşturulur.

Android 11'den önce

Uygulama Android 11'i veya API düzeyi 30'u hedeflese bile önceki Android sürümleri FLAG_ACTIVITY_REQUIRE_NON_BROWSER işaretini anlamaz. Bu nedenle, bu durumlarda Paket Yöneticisi'ni sorgulamamız gerekir:

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;
}

Burada kullanılan yaklaşım, genel http intent'i destekleyen uygulamalar için Paket Yöneticisi'ni sorgulamaktır. Bu uygulamalar büyük olasılıkla tarayıcılardır.

Ardından, başlatmak istediğimiz URL için öğeleri işleyen uygulamaları sorgulayın. Bu işlem, hem tarayıcıları hem de bu URL'yi işlemek için ayarlanmış yerel uygulamaları döndürür.

Şimdi, ilk listede bulunan tüm tarayıcıları ikinci listeden kaldırın. Böylece yalnızca yerel uygulamalar kalır.

Liste boşsa yerel işleyici olmadığını biliriz ve false değerini döndürürüz. Aksi takdirde, yerel işleyici için intent'i başlatırız.

Tüm unsurların birleşimi

Her durum için doğru yöntemi kullandığımızdan emin olmamız gerekir:

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, ihtiyacımız olan bilgileri sağlar. 30'a eşit veya 30'dan büyükse Android, FLAG_ACTIVITY_REQUIRE_NON_BROWSER değerini bilir ve yeni yaklaşımla bir yerel uygulama başlatmayı deneyebiliriz. Aksi takdirde, eski yaklaşımla lansmanı yapmayı deneriz.

Yerel uygulama başlatma işlemi başarısız olursa Özel Sekmeler'i başlatırız.

Bu en iyi uygulamada bazı standart metinler vardır. Karmaşıklığı bir kitaplıkta kapsayarak bu süreci basitleştirmek için çalışıyoruz. android-browser-helper destek kitaplığındaki güncellemeler için bizi takip etmeye devam edin.

Özel Sekmeler'i destekleyen tarayıcıları algılama

Sık kullanılan başka bir kalıp da cihazda hangi tarayıcıların Özel Sekmeler'i desteklediğini tespit etmek için PackageManager'ı kullanmaktır. Bunun yaygın kullanım alanları arasında, uygulamanın anlamını açıklayan iletişim kutusunu önlemek için Intent'te paketi ayarlamak veya özel sekmeler hizmetine bağlanırken hangi tarayıcıya bağlanacağınızı seçmek yer alır.

API düzeyi 30'u hedefleyen geliştiricilerin, Android manifest dosyalarına bir sorgu bölümü eklemeleri ve Özel Sekmeler desteğine sahip tarayıcılarla eşleşen bir intent-filter beyan etmeleri gerekir.

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

İşaretleme uygulandığında, Özel Sekmeler'i destekleyen tarayıcıları sorgulamak için kullanılan mevcut kod beklendiği gibi çalışır.

Sık Sorulan Sorular

S: Özel Sekmeler sağlayıcılarını arayan kod, https:// amaçlarını işleyebilecek uygulamalar için sorgu gönderir ancak sorgu filtresi yalnızca android.support.customtabs.action.CustomTabsService sorgusu tanımlar. https:// isteklerini belirten bir sorgu beyan edilmeli mi?

C: Sorgu filtresi tanımlanırken, sorgunun yanıtları değil, PackageManager'a gönderilen sorgular filtrelenir. Özel Sekmeler'i destekleyen tarayıcılar, CustomTabsService'i işlediklerini beyan ettiğinden filtrelenmez. Özel Sekmeler'i desteklemeyen tarayıcılar filtrelenir.

Sonuç

Mevcut bir Özel Sekmeler entegrasyonunu Android 11 ile çalışacak şekilde uyarlamak için gereken tüm değişiklikler bunlardır. Özel Sekmeler'i bir Android uygulamasına entegre etme hakkında daha fazla bilgi edinmek için uygulama kılavuzundan başlayın. Ardından, birinci sınıf bir entegrasyon oluşturma hakkında bilgi edinmek için en iyi uygulamalara göz atın.

Sorularınız veya geri bildirimleriniz varsa bize iletebilirsiniz.