Zengin içerik alma

Şekil 1. Birleştirilmiş API, dokunup tutma menüsünden yapıştırma veya sürükle ve bırak 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 resimleri, videoları ve diğer etkileyici içerikleri sever, ancak Bu içerikleri uygulamalarda taşımak her zaman kolay olmuyor. Böylece, uygulamalarınızın Android 12 (API düzeyi 31) kullanıma sunulan birleşik bir API ile uygulamanızın pano, klavye veya sürükleme gibi herhangi bir kaynaktan içerik kabul etmesini sağlar.

Örneğin, OnReceiveContentListener, herhangi bir bileşene içerik eklendiğinde geri çağırma mekanizmasıdır. Geri çağırma, kodunuzun işleneceği tek yer haline gelir düz ve stil özellikleri ayarlanmış metinden işaretleme, resim, video, ses dosyaları ve diğerleri.

Önceki Android sürümleriyle geriye dönük uyumluluk için bu API ayrıca AndroidX'te mevcuttur, bu tarihten itibaren Core 1.7 ve Appcompat 1.4, bu işlevi uygularken kullanmanızı öneririz.

Genel Bakış

Mevcut diğer API'lerle her bir kullanıcı arayüzü mekanizması (ör. dokunma ve basılı tutma menüsü kendine karşılık gelen bir 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 bir 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, tek bir Tüm kullanıcı arayüzü mekanizmalarını destekleyen API.

Bu yaklaşım aynı zamanda, desteği etkinleştirmek için ek kod değişiklikleri yapmanız gerekmez. dokunun. Uygulamanızın bir kullanmaya devam ederseniz mevcut API'leri kullanmaya devam edebilirsiniz. aynı şekilde ele alacağız.

Uygulama

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

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

KotlinJava
object MyReceiver : OnReceiveContentListener {
    val MIME_TYPES = arrayOf("image/*", "video/*")
    
    // ...
    
    override fun onReceiveContent(view: View, payload: ContentInfoCompat): ContentInfoCompat? {
        TODO("Not yet implemented")
    }
}
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:

KotlinJava
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/*")
    }
}
 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ı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.

İşleyiciyi uyguladıktan sonra, uygulamanız:

KotlinJava
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())
    }
}
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, tüm cihazlar için platform tarafından otomatik olarak verilir ve içerik URI'leri ile yük OnReceiveContentListener'e aktarılmıştır.

Normalde, uygulamanız bir hizmet veya etkinlikteki içerik URI'lerini 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, örneğin mevcut bağlamda bir arka plan ileti dizisi işleyeceğiz. 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ızda özel bir View alt sınıfı kullanılıyorsa OnReceiveContentListener atlanmaz.

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ştirilmiş API, klavye görüntüsü API'sinin işlevlerinin yanı sıra sunuyor. 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. Şunlar için desteklenen özellikler ve API düzeyleri: Jetpack.
İşlem veya özellik Klavye resmi API'si tarafından desteklenir Birleşik API tarafından desteklenir
Klavyeden ekleme Evet (API düzeyi 13 ve sonraki sürümler) Evet (API düzeyi 13 ve üstü)
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. Yerel reklamlar için desteklenen özellikler ve API düzeyleri API'ler.
İş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)
Dokunarak &yapıştırarak ekleyin basılı tutma menüsü Hayır
Sürükle ve bırak yöntemini kullanarak ekleme Hayır