Android 11'de Özel Sekmeleri Kullanma

Android 11'de uygulamaların, kullanıcının cihaza yüklediği diğer uygulamalarla nasıl etkileşimde bulunabileceği konusunda değişiklikler yapıldı. Bu değişiklikler hakkında daha fazla bilgiyi Android dokümanlarında bulabilirsiniz.

Özel Sekmeler kullanan bir Android uygulaması SDK düzeyi 30 veya üstünü hedeflediğinde bazı değişiklikler gerekebilir. Bu makalede, bu uygulamalar için gerekebilecek değişiklikler açıklanmaktadır.

En basit şekilde, Özel Sekmeler aşağıdaki gibi tek satırlık bir metinle başlatılabilir:

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

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

Yerel Uygulamaları Tercih Etme

Ancak, en iyi uygulamaları takip ettiyseniz bazı değişiklikler yapılması gerekebilir.

İlgili ilk en iyi uygulama, uygulamayı işleyebilecek bir uygulama yüklenirse uygulamaların Özel Sekme yerine amacı işleyebilmek için yerel uygulamayı tercih etmesidir.

Android 11 ve sonraki sürümlerde

Android 11'de, yeni bir Amaç işareti (FLAG_ACTIVITY_REQUIRE_NON_BROWSER) kullanıma sunuldu. Bu özellik, uygulamanın herhangi bir paket yöneticisi sorgusu tanımlamasını 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ı ve FLAG_ACTIVITY_REQUIRE_NON_BROWSER kullanarak lansman sırasında Android'den tarayıcılardan kaçınmasını istemektir.

Bu Intent'i işleyebilen yerel bir uygulama bulunmazsa ActivityNotFoundException hatası verilir.

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 anlamayacaktır. Bu durumda, Paket Yöneticisi'ni sorgulamak zorundayız:

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 bir http amacını 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 belirli URL için itent'leri işleyen uygulamaları sorgulayın. Bu işlem, hem tarayıcıları hem de yerel uygulama ayarlarını bu URL'yi işleyecek şekilde döndürür.

Şimdi, ikinci listedeki ilk listede bulunan tüm tarayıcıları kaldırdığınızda, geriye yalnızca yerel uygulamalar kalır.

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

Özet

Her durum için doğru yöntemi kullandığını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ğlıyor. 30'a eşit veya 30'dan büyükse Android FLAG_ACTIVITY_REQUIRE_NON_BROWSER anlar ve yeni yaklaşımla bir nativa uygulaması başlatmayı deneyebiliriz. Aksi takdirde, eski yaklaşımı kullanmaya çalışırız.

Yerel bir uygulamanın başlatılması başarısız olursa Özel Sekmeler başlatılır.

Bu en iyi uygulamada bazı ortak metinlerden bahsedilmektedir. Karmaşıklığı bir kütüphaneye dahil ederek bunu kolaylaştırmaya çalışıyoruz. android-browser-helper destek kitaplığında yapılacak güncellemeler için bizi takip etmeye devam edin.

Özel Sekmeleri destekleyen tarayıcıları algılama

Yaygın olarak kullanılan diğer bir kalıp, cihazda hangi tarayıcıların özel sekmeleri desteklediğini algılamak için PackageManager kullanmaktır. Bunun için yaygın kullanım alanları, paketi uygulamadaki belirsizlik giderme iletişimini önlemek için Intent'te ayarlamak veya Özel Sekmeler hizmetine bağlanırken hangi tarayıcıya bağlanılacağını seçmektir.

API düzeyi 30'u hedeflerken, geliştiricilerin Android Manifest'lerine bir sorgular bölümü eklemeleri ve Özel Sekmeler destekli tarayıcılarla eşleşen bir amaç filtresi beyan etmeleri gerekir.

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

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

Sık Sorulan Sorular

S: https:// amaçlarını işleyebilen uygulamalar için Özel Sekmeler sağlayıcı sorgularını arayan kod, ancak sorgu filtresi yalnızca bir android.support.customtabs.action.CustomTabsService sorgusu tanımlar. https:// amaçları için bir sorgunun beyan edilmesi gerekmez mi?

Y: Bir sorgu filtresi bildirildiğinde, PackageManager için sorguya verilen yanıtlar filtrelenir, sorgunun kendisine filtre uygulanmaz. Özel Sekmeleri destekleyen tarayıcılar CustomTabsService'in işlendiğini bildirdiği için bu tarayıcılar filtrelenmez. Özel Sekmeleri desteklemeyen tarayıcılar filtrelenir.

Sonuç

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

Herhangi bir sorunuz veya geri bildiriminiz olursa lütfen bize bildirin.