Yaygın kullanım alanlarını karşılarken paketin görünürlüğünü sınırlı tutun

Bu belgede, bir uygulamanın diğer uygulamalarla etkileşimde bulunduğu yaygın kullanım alanlarından bazıları açıklanmaktadır. Her bölümde, uygulamanız Android 11'i (API düzeyi 30) veya sonraki bir sürümü hedefliyorsa dikkate almanız gereken, sınırlı paket görünürlüğüyle uygulama işlevinin nasıl yerine getirileceği konusunda rehberlik sağlanır.

Android 11 veya sonraki sürümleri hedefleyen bir uygulama, başka bir uygulamada etkinlik başlatmak için bir amaç kullandığında en basit yaklaşım, amacı çağırmak ve hiçbir uygulama kullanılamıyorsa ActivityNotFoundException istisnasını işlemektir.

Uygulamanızın bir bölümü, startActivity() çağrısının başarılı olup olmadığını bilmeye bağlıysa (ör. kullanıcı arayüzü gösterme), uygulamanızın manifest dosyasındaki <queries> öğesine bir öğe ekleyin. Bu genellikle bir <intent> öğesidir.

URL'leri açma

Bu bölümde, Android 11 veya sonraki sürümleri hedefleyen bir uygulamada URL'leri açmanın çeşitli yolları açıklanmaktadır.

URL'leri tarayıcıda veya başka bir uygulamada açma

Bir URL'yi açmak için ACTION_VIEW amaç işlemini içeren bir amaç kullanın. Bu işlem, web URL'si yükleme kılavuzunda açıklanmıştır. Bu amaçla startActivity() işlevini çağırdıktan sonra aşağıdaki durumlardan biri gerçekleşir:

  • URL, web tarayıcısı uygulamasında açılır.
  • URL, derin bağlantı olarak URL'yi destekleyen bir uygulamada açılır.
  • Kullanıcının URL'yi hangi uygulamanın açacağını seçmesine olanak tanıyan bir açıklama amaçlı iletişim kutusu gösterilir.
  • Cihazda URL'yi açabilecek bir uygulama yüklü olmadığından ActivityNotFoundException oluşur. (Bu olağan dışı bir durumdur.)

    Uygulamanızın ActivityNotFoundException hatasını yakalayıp işlemesi önerilir.

startActivity() yöntemi, başka bir uygulamanın etkinliğini başlatmak için paket görünürlüğü gerektirmediğinden uygulamanızın manifestine <queries> öğesi eklemeniz veya mevcut bir <queries> öğesinde değişiklik yapmanız gerekmez. Bu durum, bir URL'yi açan hem örtülü hem de açık amaçlar için geçerlidir.

Tarayıcının kullanılabilir olup olmadığını kontrol etme

Bazı durumlarda uygulamanız, bir URL'yi açmaya çalışmadan önce cihazda en az bir tarayıcının bulunduğunu veya belirli bir tarayıcının varsayılan tarayıcı olduğunu doğrulamak isteyebilir. Bu durumlarda, manifest dosyanızdaki <queries> öğesinin bir parçası olarak aşağıdaki <intent> öğesini ekleyin:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data android:scheme="https" />
</intent>

queryIntentActivities() işlevini çağırıp web amacını bağımsız değişken olarak ilettiğinizde, döndürülen listede bazı durumlarda kullanılabilir tarayıcı uygulamaları yer alır. Kullanıcı, URL'yi varsayılan olarak tarayıcı olmayan bir uygulamada açılacak şekilde yapılandırdıysa listede tarayıcı uygulamaları yer almaz.

URL'leri özel sekmelerde açma

Özel Sekmeler, uygulamaların tarayıcının görünümünü ve tarzını özelleştirmesine olanak tanır. Uygulama manifestinizdeki <queries> öğesini eklemeniz veya değiştirmeniz gerekmeden bir URL'yi özel sekmede açabilirsiniz.

Ancak, cihazda özel sekmeleri destekleyen bir tarayıcı olup olmadığını kontrol etmek veya CustomTabsClient.getPackageName() simgesini kullanarak özel sekmelerle başlatılacak belirli bir tarayıcıyı seçmek isteyebilirsiniz. Bu durumlarda, manifest dosyanızdaki <queries> öğesinin bir parçası olarak aşağıdaki <intent> öğesini ekleyin:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>

Tarayıcı olmayan uygulamaların URL'leri işlemesine izin verme

Uygulamanız, özel sekmeleri kullanarak URL'leri açabiliyor olsa bile mümkünse tarayıcı olmayan bir uygulamanın URL'yi açmasına izin vermeniz önerilir. Uygulamanızda bu özelliği sağlamak için FLAG_ACTIVITY_REQUIRE_NON_BROWSER amaç işaretini ayarlayan bir amaç kullanarak startActivity() numarasına çağrı yapmayı deneyin. Sistem ActivityNotFoundException oluşturursa uygulamanız URL'yi özel sekmede açabilir.

Bir amaç bu işareti içeriyorsa startActivity() çağrısı, aşağıdaki koşullardan biri gerçekleştiğinde ActivityNotFoundException oluşturulmasına neden olur:

  • Arama doğrudan bir tarayıcı uygulamasını başlatırdı.
  • Bu durumda, kullanıcıya yalnızca tarayıcı uygulamalarının yer aldığı bir netleştirme iletişim kutusu gösterilirdi.

Aşağıdaki kod snippet'inde, mantığınızı FLAG_ACTIVITY_REQUIRE_NON_BROWSER amaç işaretini kullanacak şekilde nasıl güncelleyeceğiniz gösterilmektedir:

Kotlin

try {
    val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply {
        // The URL should either launch directly in a non-browser app (if it's
        // the default) or in the disambiguation dialog.
        addCategory(CATEGORY_BROWSABLE)
        flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER
    }
    startActivity(intent)
} catch (e: ActivityNotFoundException) {
    // Only browser apps are available, or a browser is the default.
    // So you can open the URL directly in your app, for example in a
    // Custom Tab.
    openInCustomTabs(url)
}

Java

try {
    Intent intent = new Intent(ACTION_VIEW, Uri.parse(url));
    // The URL should either launch directly in a non-browser app (if it's the
    // default) or in the disambiguation dialog.
    intent.addCategory(CATEGORY_BROWSABLE);
    intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER);
    startActivity(intent);
} catch (ActivityNotFoundException e) {
    // Only browser apps are available, or a browser is the default.
    // So you can open the URL directly in your app, for example in a
    // Custom Tab.
    openInCustomTabs(url);
}

Belirsizliği giderme iletişim kutusunu önleme

Kullanıcıların bir URL'yi açtıklarında görebilecekleri netleştirme iletişim kutusunu göstermekten kaçınmak ve bunun yerine bu durumlarda URL'yi kendiniz işlemek istiyorsanız FLAG_ACTIVITY_REQUIRE_DEFAULT niyet işaretini ayarlayan bir niyet kullanabilirsiniz.

Bir amaç bu işareti içeriyorsa startActivity() işlevi çağrıldığında, kullanıcılara belirsizliği giderme iletişim kutusu gösterilmesi gereken durumlarda ActivityNotFoundException istisnası oluşturulur.

Bir amaç hem bu işareti hem de FLAG_ACTIVITY_REQUIRE_NON_BROWSER amaç işaretini içeriyorsa startActivity() işlevine yapılan bir çağrı, aşağıdaki koşullardan herhangi biri gerçekleştiğinde ActivityNotFoundException oluşturulmasına neden olur:

  • Arama doğrudan tarayıcı uygulamasını başlatırdı.
  • Bu durumda, kullanıcıya netleştirme iletişim kutusu gösterilirdi.

Aşağıdaki kod snippet'inde, FLAG_ACTIVITY_REQUIRE_NON_BROWSER ve FLAG_ACTIVITY_REQUIRE_DEFAULT işaretlerinin birlikte nasıl kullanılacağı gösterilmektedir:

Kotlin

val url = URL_TO_LOAD
try {
    // For this intent to be invoked, the system must directly launch a
    // non-browser app.
    val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply {
        addCategory(CATEGORY_BROWSABLE)
        flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER or
                FLAG_ACTIVITY_REQUIRE_DEFAULT
    }
    startActivity(intent)
} catch (e: ActivityNotFoundException) {
    // This code executes in one of the following cases:
    // 1. Only browser apps can handle the intent.
    // 2. The user has set a browser app as the default app.
    // 3. The user hasn't set any app as the default for handling this URL.
    openInCustomTabs(url)
}

Java

String url = URL_TO_LOAD;
try {
    // For this intent to be invoked, the system must directly launch a
    // non-browser app.
    Intent intent = new Intent(ACTION_VIEW, Uri.parse(url));
    intent.addCategory(CATEGORY_BROWSABLE);
    intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER |
            FLAG_ACTIVITY_REQUIRE_DEFAULT);
    startActivity(intent);
} catch (ActivityNotFoundException e) {
    // This code executes in one of the following cases:
    // 1. Only browser apps can handle the intent.
    // 2. The user has set a browser app as the default app.
    // 3. The user hasn't set any app as the default for handling this URL.
    openInCustomTabs(url);
}

Dosya aç

Uygulamanız dosyaları veya ekleri işliyorsa (ör. bir cihazın belirli bir dosyayı açıp açamayacağını kontrol ediyorsa) genellikle dosyayı işleyebilecek bir etkinliği başlatmayı denemek en kolay yöntemdir. Bunu yapmak için ACTION_VIEWintent action ve belirli dosyayı temsil eden URI'yi içeren bir amaç kullanın. Cihazda uygulama yoksa uygulamanız ActivityNotFoundException yakalayabilir. Hata işleme mantığınızda bir hata gösterebilir veya dosyayı kendiniz işlemeyi deneyebilirsiniz.

Uygulamanızın, başka bir uygulamanın belirli bir dosyayı açıp açamayacağını önceden bilmesi gerekiyorsa manifestinizdeki <queries> öğesinin bir parçası olarak aşağıdaki kod snippet'inde <intent> öğesini ekleyin. Derleme zamanında dosya türünü zaten biliyorsanız bu türü ekleyin.

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.VIEW" />
  <!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". -->
  <data android:mimeType="application/pdf" />
</intent>

Ardından, resolveActivity() ile niyetinizi belirterek bir uygulamanın kullanılabilir olup olmadığını kontrol edebilirsiniz.

URI erişimi verme

Not: Bu bölümde açıklandığı şekilde URI erişim izinlerinin beyan edilmesi, Android 11'i (API düzeyi 30) veya sonraki sürümleri hedefleyen uygulamalar için zorunludur. Hedef SDK sürümünden ve içerik sağlayıcılarını dışa aktarıp aktarmadıklarından bağımsız olarak tüm uygulamalar için önerilir.

İçerik URI'sine erişmek için Android 11 veya sonraki sürümleri hedefleyen uygulamalarda, uygulamanızın niyeti aşağıdaki niyet işaretlerinden birini veya her ikisini ayarlayarak URI erişim izinlerini beyan etmelidir: FLAG_GRANT_READ_URI_PERMISSION ve FLAG_GRANT_WRITE_URI_PERMISSION.

Android 11 ve sonraki sürümlerde URI erişim izinleri, Intent'i alan uygulamaya aşağıdaki özellikleri verir:

  • Belirtilen URI izinlerine bağlı olarak, içerik URI'sinin temsil ettiği verileri okuma veya verilere yazma
  • URI yetkilisiyle eşleşen içerik sağlayıcıyı içeren uygulamayı görünür hale getirin. İçerik sağlayıcıyı içeren uygulama, amaç gönderen uygulamadan farklı olabilir.

Aşağıdaki kod snippet'i, Android 11 veya sonraki sürümleri hedefleyen başka bir uygulamanın içerik URI'sindeki verileri görüntüleyebilmesi için URI izinleri intent işareti eklemenin nasıl yapılacağını gösterir:

Kotlin

val shareIntent = Intent(Intent.ACTION_VIEW).apply {
    flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
    data = CONTENT_URI_TO_SHARE_WITH_OTHER_APP
}

Java

Intent shareIntent = new Intent(Intent.ACTION_VIEW);
shareIntent.setFlags(FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.setData(CONTENT_URI_TO_SHARE_WITH_OTHER_APP);

Hizmetlere bağlanma

Uygulamanızın otomatik olarak görünür olmayan bir hizmetle etkileşimde bulunması gerekiyorsa <queries> öğesi içinde uygun amaç işlemini bildirebilirsiniz. Aşağıdaki bölümlerde, sık erişilen hizmetlerin kullanıldığı örnekler verilmiştir.

Metin okuma motoruna bağlanma

Uygulamanız bir metin okuma (TTS) motoruyla etkileşimde bulunuyorsa manifestinizdeki <queries> öğesinin bir parçası olarak aşağıdaki <intent> öğesini ekleyin:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.TTS_SERVICE" />
</intent>

Konuşma tanıma hizmetine bağlanma

Uygulamanız bir konuşma tanıma hizmetiyle etkileşimde bulunuyorsa manifest dosyanızdaki <queries> öğesinin bir parçası olarak aşağıdaki <intent> öğesini ekleyin:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.speech.RecognitionService" />
</intent>

Medya tarayıcı hizmetlerine bağlanma

Uygulamanız bir istemci medya tarayıcısı uygulamasıysa manifest dosyanızdaki <queries> öğesinin bir parçası olarak aşağıdaki <intent> öğesini ekleyin:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.media.browse.MediaBrowserService" />
</intent>

Özel işlevler sağlama

Uygulamanızın, diğer uygulamalarla etkileşimlerine bağlı olarak özelleştirilebilir işlemler gerçekleştirmesi veya özelleştirilebilir bilgiler göstermesi gerekiyorsa bu özel davranışı, manifestinizdeki <queries> öğesinin bir parçası olarak amaç filtresi imzalarını kullanarak temsil edebilirsiniz. Aşağıdaki bölümlerde, sık karşılaşılan çeşitli senaryolarla ilgili ayrıntılı bilgiler verilmektedir.

SMS uygulamaları için sorgu

Uygulamanızın, cihaza yüklü SMS uygulamaları grubu hakkında bilgiye ihtiyacı varsa (ör. cihazın varsayılan SMS işleyicisinin hangi uygulama olduğunu kontrol etmek için) manifestinizdeki <queries> öğesinin bir parçası olarak aşağıdaki <intent> öğesini ekleyin:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.SENDTO"/>
  <data android:scheme="smsto" android:host="*" />
</intent>

Özel paylaşım sayfası oluşturma

Mümkün olduğunda sistem tarafından sağlanan paylaşım sayfasını kullanın. Alternatif olarak, manifest dosyanızdaki <queries> öğesinin bir parçası olarak aşağıdaki <intent> öğesini ekleyin:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.SEND" />
  <!-- Replace with the MIME type that your app works with, if needed. -->
  <data android:mimeType="image/jpeg" />
</intent>

Uygulamanızın mantığında paylaşım sayfasını oluşturma süreci (ör. queryIntentActivities() çağrısı) Android 11'den önceki Android sürümlerine kıyasla değişmeden kalır.

Özel metin seçme işlemlerini gösterme

Kullanıcılar uygulamanızda metin seçtiğinde, seçili metinde gerçekleştirilebilecek olası işlemlerin kümesini gösteren bir metin seçme araç çubuğu gösterilir. Bu araç çubuğu diğer uygulamalardan özel işlemler gösteriyorsa aşağıdaki <intent> öğesini manifest dosyanızdaki <queries> öğesinin bir parçası olarak ekleyin:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.PROCESS_TEXT" />
  <data android:mimeType="text/plain" />
</intent>

Bir kişi için özel veri satırlarını gösterme

Uygulamalar, Kişiler Sağlayıcı'ya özel veri satırları ekleyebilir. Bir kişiler uygulamasının bu özel verileri göstermesi için aşağıdakileri yapabilmesi gerekir:

  1. Diğer uygulamalardan contacts.xml dosyasını okuyun.
  2. Özel MIME türüne karşılık gelen bir simge yükleyin.

Uygulamanız bir kişiler uygulamasıysa manifest dosyanızdaki <queries> öğesinin bir parçası olarak aşağıdaki <intent> öğelerini ekleyin:

<!-- Place inside the <queries> element. -->
<!-- Lets the app read the contacts.xml file from other apps. -->
<intent>
  <action android:name="android.accounts.AccountAuthenticator" />
</intent>
<!-- Lets the app load an icon corresponding to the custom MIME type. -->
<intent>
  <action android:name="android.intent.action.VIEW" />
  <data android:scheme="content" android:host="com.android.contacts"
        android:mimeType="vnd.android.cursor.item/*" />
</intent>