Zengin içerik alma

Şekil 1. Birleştirilmiş API, dokunup basma menüsünden yapıştırma veya sürükleyip bırakma gibi belirli kullanıcı arayüzü mekanizmalarından bağımsız olarak gelen içeriği işlemek için tek bir yer sağlar.

Kullanıcılar resimleri, videoları ve diğer etkileyici 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 herhangi bir kaynaktan (pano, klavye veya sürükleme) içerik kabul etmesine olanak tanıyan birleşik bir API 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, kodunuzun düz ve stilize edilmiş metinden işaretlemeye, resimlere, videolara, ses dosyalarına ve diğerlerine kadar tüm içeriği almayı işleyeceği tek yer haline gelir.

Ö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 API'yi 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 kodlar eklemeniz gerekir:

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

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

Basitleştirilmiş birleştirilmiş API'yi gösteren resim
3.şekil 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 destek sağlamak için ek kod değişiklikleri yapmanız gerekmediği anlamına da gelir. Uygulamanızın belirli bir kullanım alanı için tam özelleştirme uygulaması gerekiyorsa mevcut API'leri kullanmaya devam edebilirsiniz. Bu API'ler aynı şekilde çalışmaya devam eder.

Uygulama

API, tek bir yöntemi olan bir işleyici arayüzüdür: OnReceiveContentListener. Android platformunun eski sürümlerini desteklemek için AndroidX Core kitaplığında eşleşen OnReceiveContentListener arayüzünü kullanmanızı öneririz.

API'yi kullanmak için uygulamanızın hangi içerik türlerini işleyebileceğini belirterek dinleyiciyi 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<ContentInfoCompat, ContentInfoCompat> 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ızda halihazırda Intent'lerle paylaşım destekleniyorsa içerik URI'lerini işlemek için uygulamaya özel 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ü öğelerinde 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 iptal edilir.

Uygulamanız normalde içerik URI'lerini bir hizmette veya etkinlikte işler. Uzun süren işlemler için WorkManager'ı kullanın. Bu işlemi uyguladığınızda, içeriği Intent.setClipData kullanarak iletip bayrağı FLAG_GRANT_READ_URI_PERMISSION olarak ayarlayarak izinleri hedef hizmete veya etkinliğe genişletin.

Alternatif olarak, içeriği işlemek için mevcut bağlamda bir arka plan iş parçacığı kullanabilirsiniz. Bu durumda, izinlerin platform tarafından erken iptal edilmemesi 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 öğesinin atlanmadığından emin olun.

View sınıfınız onCreateInputConnection yöntemini geçersiz kılıyorsa InputConnection 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ştirilmiş 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'daki 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ırarak ekleme Hayır Evet
Sürükle ve bırak özelliğini kullanarak 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 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ırarak ekleme Hayır
Sürükle ve bırak özelliğini kullanarak ekleme Hayır