Zengin içerik alma

Şekil 1. Birleştirilmiş API, dokunup tutma menüsünden yapıştırma veya sürükle bırak kullanma gibi belirli kullanıcı arayüzü mekanizmalarından bağımsız olarak gelen içeriği tek bir yerden işleme olanağı sunar.

Kullanıcılar resimlere, videolara ve ifade edici diğer içeriklere bayılır ancak bu içerikleri uygulamalara eklemek ve taşımak her zaman kolay değildir. Uygulamaların zengin içerik almasını kolaylaştırmak için Android 12 (API düzeyi 31), uygulamanızın herhangi bir kaynaktan (ör. panos, klavye veya sürükleme) içerik kabul etmesine olanak tanıyan birleşik bir API'yi kullanıma sunar.

Kullanıcı arayüzü bileşenlerine OnReceiveContentListener gibi bir arayüz ekleyebilir ve herhangi bir mekanizma aracılığıyla içerik eklendiğinde geri çağırma alabilirsiniz. Geri çağırma işlevi, kodunuzun düz ve stilize metinden işaretlemeye, resimlere, videolara, ses dosyalarına ve diğer tüm içerikleri almasını sağlayan tek yer olur.

Önceki Android sürümleriyle geriye dönük uyumluluk için bu API, Core 1.7 ve Appcompat 1.4'ten itibaren AndroidX'te de kullanılabilir. Bu işlevi uygularken bu sürümü kullanmanızı öneririz.

Genel Bakış

Mevcut diğer API'lerde, dokunup basılı tutma menüsü veya sürükleme gibi her kullanıcı arayüzü mekanizmasının kendi API'si vardır. Bu nedenle, her API ile ayrı ayrı entegrasyon yapmanız ve içerik ekleyen her mekanizma için benzer kod eklemeniz gerekir:

Farklı işlemleri ve uygulanacak ilgili API'yi gösteren resim
Şekil 2. Önceden uygulamalar, içerik eklemek için her kullanıcı arayüzü mekanizması için farklı bir API uyguluyordu.

OnReceiveContentListener API, uygulanacak tek bir API oluşturarak bu farklı kod yollarını birleştirir. Böylece, uygulamanıza özgü mantığınıza odaklanabilir ve geri kalanı platformun halletmesine izin verebilirsiniz:

Basitleştirilmiş birleştirilmiş API'yi gösteren resim
Şekil 3. Birleştirilmiş API, tüm kullanıcı arayüzü mekanizmalarını destekleyen tek bir API uygulamanıza olanak tanır.

Bu yaklaşım, platforma yeni içerik ekleme yöntemleri eklendiğinde uygulamanızda desteği etkinleştirmek için ek kod değişiklikleri yapmanız gerekmediği anlamına da gelir. Ayrıca, uygulamanızın belirli bir kullanım alanı için tam özelleştirme uygulaması gerekiyorsa aynı şekilde çalışmaya devam eden mevcut API'leri kullanmaya devam edebilirsiniz.

Uygulama

API, OnReceiveContentListener adlı tek bir yönteme sahip bir dinleyici arayüzüdür. Android platformunun eski sürümlerini desteklemek için AndroidX Core kitaplığındaki eşleşen OnReceiveContentListener arayüzünü kullanmanızı öneririz.

API'yi kullanmak için dinleyiciyi, uygulamanızın hangi içerik türlerini işleyebileceğini belirterek uygulayın:

Kotlin

object MyReceiver : OnReceiveContentListener {
    val MIME_TYPES = arrayOf("image/*", "video/*")
    
    // ...
    
    override fun onReceiveContent(view: View, payload: ContentInfoCompat): ContentInfoCompat? {
        TODO("Not yet implemented")
    }
}

Java

public class MyReceiver implements OnReceiveContentListener {
     public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"};
     // ...
}

Uygulamanızın desteklediği tüm içerik MIME türlerini belirttikten sonra dinleyicinin geri kalanını uygulayın:

Kotlin

class MyReceiver : OnReceiveContentListener {
    override fun onReceiveContent(view: View, contentInfo: ContentInfoCompat): ContentInfoCompat {
        val split = contentInfo.partition { item: ClipData.Item -> item.uri != null }
        val uriContent = split.first
        val remaining = split.second
        if (uriContent != null) {
            // App-specific logic to handle the URI(s) in uriContent.
        }
        // Return anything that your app didn't handle. This preserves the
        // default platform behavior for text and anything else that you aren't
        // implementing custom handling for.
        return remaining
    }

    companion object {
        val MIME_TYPES = arrayOf("image/*", "video/*")
    }
}

Java

 public class MyReceiver implements OnReceiveContentListener {
     public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"};

     @Override
     public ContentInfoCompat onReceiveContent(View view, ContentInfoCompat contentInfo) {
         Pair split = contentInfo.partition(
                 item -> item.getUri() != null);
         ContentInfo uriContent = split.first;
         ContentInfo remaining = split.second;
         if (uriContent != null) {
             // App-specific logic to handle the URI(s) in uriContent.
         }
         // Return anything that your app didn't handle. This preserves the
         // default platform behavior for text and anything else that you aren't
         // implementing custom handling for.
         return remaining;
     }
 }

Uygulamanız halihazırda intent'lerle paylaşımı destekliyorsa içerik URI'lerini işlemek için uygulamaya özgü mantığınızı yeniden kullanabilirsiniz. Kalan verileri döndürerek bu verilerin işlenmesini platforma devredin.

Dinleyiciyi uyguladıktan sonra uygulamanızdaki uygun kullanıcı arayüzü öğelerine ayarlayın:

Kotlin

class MyActivity : Activity() {
    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
        val myInput = findViewById(R.id.my_input)
        ViewCompat.setOnReceiveContentListener(myInput, MyReceiver.MIME_TYPES, MyReceiver())
    }
}

Java

public class MyActivity extends Activity {
     @Override
     public void onCreate(Bundle savedInstanceState) {
         // ...

         AppCompatEditText myInput = findViewById(R.id.my_input);
         ViewCompat.setOnReceiveContentListener(myInput, MyReceiver.MIME_TYPES, new MyReceiver());
     }
}

URI izinleri

Okuma izinleri, OnReceiveContentListener'ye iletilen yükteki tüm içerik URI'leri için platform tarafından otomatik olarak verilir ve kaldırılır.

Normalde uygulamanız, içerik URI'lerini bir hizmette veya etkinlikte işler. Uzun süren işlemler için WorkManager'ı kullanın. Bunu uygularken Intent.setClipData kullanarak içeriği ileterek ve FLAG_GRANT_READ_URI_PERMISSION işaretini ayarlayarak hedef hizmete veya etkinliğe izinleri genişletin.

Alternatif olarak, içeriği işlemek için mevcut bağlamda bir arka plan iş parçacığı da kullanabilirsiniz. Bu durumda, izinlerin platform tarafından erken iptal edilmemesini sağlamak için dinleyici tarafından alınan payload nesnesine referans vermeniz gerekir.

Özel görünümler

Uygulamanız özel bir View alt sınıfı kullanıyorsa OnReceiveContentListener sınıfının atlanmadığından emin olun.

View sınıfınız onCreateInputConnection yöntemini geçersiz kılıyorsa InputConnection'yi yapılandırmak için Jetpack API'yi InputConnectionCompat.createWrapper kullanın.

View sınıfınız onTextContextMenuItem yöntemini geçersiz kılıyorsa menü öğesi R.id.paste veya R.id.pasteAsPlainText olduğunda süper yöneticiye yetki verin.

Klavye resmi API'siyle karşılaştırma

OnReceiveContentListener API'yi mevcut klavye resmi API'sinin sonraki sürümü olarak düşünebilirsiniz. Bu birleşik API, klavye resmi API'sinin işlevselliğinin yanı sıra bazı ek özellikleri de destekler. Cihaz ve özellik uyumluluğu, Jetpack kitaplığını mı yoksa Android SDK'sındaki yerel API'leri mi kullandığınıza bağlı olarak değişir.

Tablo 1. Jetpack için desteklenen özellikler ve API düzeyleri
İşlem veya özellik Klavye resmi API'si tarafından desteklenir. Birleşik API tarafından desteklenir
Klavyeden ekleme Evet (API düzeyi 13 ve üzeri) Evet (API düzeyi 13 ve üzeri)
Dokunup basılı tutma menüsünden yapıştırma özelliğini kullanarak ekleme Hayır Evet
Sürükle ve bırak yöntemini kullanarak ekleme Hayır Evet (API düzeyi 24 ve üstü)
Tablo 2. Yerleşik API'ler için desteklenen özellikler ve API düzeyleri.
İşlem veya özellik Klavye resmi API'si tarafından desteklenir. Birleşik API tarafından desteklenir
Klavyeden ekleme Evet (API düzeyi 25 ve üstü) Evet (Android 12 ve sonraki sürümler)
Dokunup basılı tutma menüsünden yapıştırma özelliğini kullanarak ekleme Hayır
Sürükle ve bırak yöntemini kullanarak ekleme Hayır