Zengin içerik alma

Şekil 1. Birleşik API, belirli kullanıcı arayüzü mekanizmasından bağımsız olarak, dokunup basılı tutma menüsünden yapıştırma veya sürükle ve bırak özelliğini kullanma gibi gelen içerikleri tek bir yerden işlemek için kullanılır.

Kullanıcılar resimleri, videoları ve etkileyici diğer içerikleri sever, ancak bu içerikleri uygulamalara eklemek ve taşımak her zaman kolay olmaz. Android 12 (API düzeyi 31), uygulamaların zengin içerik almasını kolaylaştırmak için uygulamanızın pano, klavye veya sürükleme gibi her türlü kaynaktan içerik kabul etmesini sağlayan birleşik bir API sunar.

Kullanıcı arayüzü bileşenlerine OnReceiveContentListener gibi bir arayüz ekleyebilir ve içerik herhangi bir mekanizmadan eklendiğinde geri çağırma alabilirsiniz. Geri çağırma, kodunuzun düz ve stilize edilmiş metinlerden işaretleme, resimler, videolar, ses dosyaları ve diğer içeriklere kadar tüm içeriği almada tek yer haline gelir.

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

Genel bakış

Mevcut diğer API'lerle, her kullanıcı arayüzü mekanizmasının (dokunup basılı tutma menüsü veya sürükleme gibi) kendi API'si vardır. Bu, içerik ekleyen her mekanizma için benzer bir kod ekleyerek her bir API ile ayrı ayrı entegrasyon yapmanız gerektiği anlamına gelir:

Farklı işlemleri ve uygulanacak göreli API'yi gösteren resim
Şekil 2. Önceden uygulamalar, içerik eklemek amacıyla 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ı bir araya getirir. Böylece, uygulamanıza özel mantığınıza odaklanabilir ve gerisini platforma bırakabilirsiniz:

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ıza gerek kalmayacağı anlamına gelir. 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, tek yöntem olan OnReceiveContentListener adlı bir işleyici arayüzüdür. Android platformunun eski sürümlerini desteklemek için AndroidX Core kitaplığındaki eşleştirme OnReceiveContentListener arayüzünü kullanmanızı öneririz.

API'yi kullanmak için uygulamanızın işleyebileceği içerik türlerini belirterek işleyiciyi 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 işleyicinin 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 amaçlar ile paylaşımı zaten destekliyorsa içerik URI'lerini işlemek için uygulamaya özel mantığınızı yeniden kullanabilirsiniz. Kalan verileri döndürerek söz konusu verilerin işlenmesi için platforma yetki verin.

İşleyiciyi 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'a iletilen yükteki tüm içerik URI'leri için platform tarafından otomatik olarak verilir ve serbest bırakılır.

Normalde, uygulamanız bir hizmet veya etkinlikteki içerik URI'lerini işler. Uzun süreli işleme için WorkManager'ı kullanın. Bunu uyguladığınızda içeriği Intent.setClipData kullanarak ileterek ve işareti FLAG_GRANT_READ_URI_PERMISSION ayarlayarak izinleri hedef hizmete veya etkinliğe genişletin.

Alternatif olarak, içeriği işlemek için geçerli bağlamda bir arka plan ileti dizisi kullanabilirsiniz. Bu durumda, izinlerin platform tarafından zamanında iptal edilmediğinden emin olmak için dinleyici tarafından alınan payload nesnesine bir referans tutmanız gerekir.

Özel görünümler

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

View sınıfınız onCreateInputConnection yöntemini geçersiz kılıyorsa InputConnection öğesini 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 Super'a yetki verin.

Klavye görüntüsü API'si ile karşılaştırma

OnReceiveContentListener API'yi, mevcut klavye görüntüsü API'sinin bir sonraki sürümü olarak düşünebilirsiniz. Bu birleştirilmiş API, klavye görüntüsü API'sinin işlevlerinin yanı sıra bazı ek özellikleri de destekler. Cihaz ve özellik uyumluluğu, Jetpack kitaplığını veya Android SDK'sının yerel API'lerini kullanmanıza bağlı olarak değişiklik gösterir.

Tablo 1. Jetpack için desteklenen özellikler ve API düzeyleri.
İşlem veya özellik Klavye görüntüsü API'si tarafından desteklenir Birleştirilmiş API tarafından desteklenir
Klavyeden ekleme Evet (API düzeyi 13 ve üstü) Evet (API düzeyi 13 ve üstü)
Dokunup basılı tutma menüsünden yapıştırarak ekleme Hayır Evet
Sürükleyip bırakarak ekleme Hayır Evet (API düzeyi 24 ve üstü)
Tablo 2. Yerel API'ler için desteklenen özellikler ve API düzeyleri.
İşlem veya özellik Klavye görüntüsü API'si tarafından desteklenir Birleştirilmiş 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ırarak ekleme Hayır
Sürükleyip bırakarak ekleme Hayır