Zengin içerik alma

Şekil 1. Birleşik API, belirli kullanıcı arayüzü mekanizmalarından (dokunup basılı tut menüsünden yapıştırma veya sürükle ve bırak özelliğini kullanma) bağımsız olarak gelen içeriklerin tek bir yerde işlenebilmesini sağlar.

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

Kullanıcı arayüzü bileşenlerine OnReceiveContentListener gibi bir arayüz ekleyebilir ve içerik herhangi bir sistemden eklendiğinde geri çağırma elde edebilirsiniz. Geri çağırma, kodunuzun düz ve stilize edilmiş metinden işaretleme, resimler, videolar, ses dosyaları ve diğer öğelere 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 kullanmanızı öneririz.

Genel bakış

Mevcut diğer API'lerde 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 nedenle, içerik ekleyen her mekanizma için benzer kod ekleyerek her API ile ayrı ayrı entegrasyon gerçekleştirmeniz gerekir:

Uygulanacak farklı işlemleri ve göreli API'yi gösteren resim
Şekil 2. Daha önce 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, uygulamaya ö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 aynı zamanda, platforma içerik eklemenin yeni yolları eklendiğinde, uygulamanızda desteği sağlamak için ek kod değişiklikleri yapmanıza gerek olmadığı anlamına gelir. Ayrıca uygulamanızın belirli bir kullanım durumu 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 işleyici 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 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 belirledikten 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 hâlihazırda niyetle paylaşımı destekliyorsa içerik URI'lerini işlemek için uygulamaya özgü mantığınızı yeniden kullanabilirsiniz. Verilerin işlenmesini platforma yetkilendirmek için kalan verileri döndürün.

İş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

OnReceiveContentListener'e aktarılan yükteki tüm içerik URI'leri için platform tarafından otomatik olarak okuma izinleri verilir ve serbest bırakılır.

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

Alternatif olarak, içeriği işlemek için mevcut bağlamda bir arka plan ileti dizisi kullanabilirsiniz. Bu durumda, izinlerin platform tarafından erken iptal edilmediğinden emin olmak için işleyici tarafından alınan payload nesnesine bir referans sağlamanız 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ırması 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 değerine yetki verin.

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

OnReceiveContentListener API'sini, mevcut klavye görüntüsü API'sinin yeni sürümü olarak düşünebilirsiniz. Bu birleştirilmiş API, bazı ek özelliklerin yanı sıra klavye görüntüsü API'sinin işlevlerini de destekler. Cihaz ve özellik uyumluluğu, Jetpack kitaplığını veya Android SDK'sındaki yerel API'leri 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'sı 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ırmayı kullanarak ekleyin Hayır Evet
Sürükleyip bırakarak ekleyin 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'sı 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ırmayı kullanarak ekleyin Hayır
Sürükle ve bırak yöntemiyle ekle Hayır