রিচ কন্টেন্ট পাওয়া

ছবি ১. ইউনিফায়েড API, নির্দিষ্ট UI মেকানিজম নির্বিশেষে, ইনকামিং কন্টেন্ট ম্যানেজ করার জন্য একটি একক জায়গা প্রদান করে, যেমন টাচ করে ধরে রাখার মেনু থেকে পেস্ট করা বা টেনে নিয়ে রাখুন ফিচার ব্যবহার করা।

ব্যবহারকারীরা ছবি, ভিডিও এবং অন্যান্য অভিব্যক্তিপূর্ণ কন্টেন্ট পছন্দ করেন, কিন্তু অ্যাপে এই কন্টেন্ট যোগ করা এবং সরানো সবসময় সহজ নয়। অ্যাপের জন্য রিচ কন্টেন্ট রিসিভ করার প্রসেস আরও সহজ করতে, Android 12 (API লেভেল 31) একটি ইউনিফায়েড API নিয়ে এসেছে যা আপনার অ্যাপকে যেকোনও সোর্স থেকে কন্টেন্ট গ্রহণ করার অনুমতি দেয়: ক্লিপবোর্ড, কীবোর্ড বা টেনে আনা।

আপনি UI কম্পোনেন্টে OnReceiveContentListener-এর মতো ইন্টারফেস অ্যাটাচ করতে পারেন এবং কোনও মেকানিজমের মাধ্যমে কন্টেন্ট যোগ করা হলে কলব্যাক পেতে পারেন। কলব্যাক আপনার কোডের জন্য প্লেইন ও স্টাইল করা টেক্সট থেকে শুরু করে মার্কআপ, ছবি, ভিডিও, অডিও ফাইল এবং অন্যান্য সব কন্টেন্ট রিসিভ করার একমাত্র জায়গা হয়ে ওঠে।

Android-এর আগের ভার্সনের সাথে ব্যাকওয়ার্ড কম্প্যাটিবিলিটির জন্য, এই API Core 1.7 এবং Appcompat 1.4 থেকে শুরু করে AndroidX-এও উপলভ্য, যা আমরা এই কার্যকারিতা প্রয়োগ করার সময় আপনাকে ব্যবহার করার জন্য সাজেস্ট করি।

এক নজরে

অন্যান্য বিদ্যমান API-এর সাথে, প্রতিটি UI মেকানিজম—যেমন টাচ অ্যান্ড হোল্ড মেনু বা টেনে আনা—এর নিজস্ব সংশ্লিষ্ট API আছে। এর অর্থ হল, আপনাকে প্রতিটি API-এর সাথে আলাদাভাবে ইন্টিগ্রেট করতে হবে এবং কন্টেন্ট যোগ করার প্রতিটি মেকানিজমের জন্য একই ধরনের কোড যোগ করতে হবে:

বিভিন্ন অ্যাকশন এবং প্রয়োগ করার জন্য সংশ্লিষ্ট API দেখানো একটি ছবি
ছবি ২. আগে, কন্টেন্ট যোগ করার জন্য প্রতিটি UI মেকানিজমের জন্য অ্যাপগুলি আলাদা API প্রয়োগ করত।

OnReceiveContentListener API এই বিভিন্ন কোড পাথকে একত্রিত করে প্রয়োগ করার জন্য একটি একক API তৈরি করে, যাতে আপনি আপনার অ্যাপ-নির্দিষ্ট লজিকের উপর ফোকাস করতে পারেন এবং প্ল্যাটফর্মকে বাকিগুলি পরিচালনা করতে দিতে পারেন:

সহজ করা ইউনিফায়েড API দেখানো ছবি
ছবি ৩. ইউনিফায়েড API-এর সাহায্যে আপনি এমন একটি API প্রয়োগ করতে পারবেন যা সব UI মেকানিজমকে সাপোর্ট করে।

এই পদ্ধতির অর্থ হল, প্ল্যাটফর্মে কন্টেন্ট যোগ করার নতুন উপায় যোগ করা হলে, আপনার অ্যাপে সেটি চালু করার জন্য আপনাকে অতিরিক্ত কোড পরিবর্তন করতে হবে না। এবং আপনার অ্যাপে কোনও নির্দিষ্ট ব্যবহারের ক্ষেত্রে সম্পূর্ণ কাস্টমাইজেশন প্রয়োগ করতে হলে, আপনি এখনও আগের API ব্যবহার করতে পারবেন, যা একইভাবে কাজ করা চালিয়ে যাবে।

প্রয়োগ

API হল একটি লিসেনার ইন্টারফেস যার একটিই পদ্ধতি আছে, OnReceiveContentListener। Android প্ল্যাটফর্মের পুরনো ভার্সন সাপোর্ট করার জন্য, আমরা AndroidX Core লাইব্রেরিতে ম্যাচিং OnReceiveContentListener ইন্টারফেস ব্যবহার করার সাজেশন দিই।

API ব্যবহার করতে, আপনার অ্যাপ কোন ধরনের কন্টেন্ট ম্যানেজ করতে পারে তা নির্দিষ্ট করে লিসেনার প্রয়োগ করুন:

Kotlin

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/*"};
     // ...
}

আপনার অ্যাপে কাজ করে এমন সব কন্টেন্ট MIME-এর প্রকার উল্লেখ করার পরে, বাকি লিসেনার প্রয়োগ করুন:

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

জাভা

 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;
     }
 }

আপনার অ্যাপে আগে থেকেই ইনটেন্টের মাধ্যমে শেয়ার করার সুবিধা থাকলে, কন্টেন্ট URI ম্যানেজ করার জন্য অ্যাপ-নির্দিষ্ট লজিক আবার ব্যবহার করতে পারবেন। বাকি ডেটা প্ল্যাটফর্মে ডেটা ম্যানেজ করার জন্য ডেলিগেটকে ফেরত দিন।

লিসেনার প্রয়োগ করার পরে, আপনার অ্যাপের উপযুক্ত UI এলিমেন্টে এটি সেট করুন:

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())
    }
}

জাভা

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 সংক্রান্ত অনুমতি

OnReceiveContentListener-এ পাস করা পেলোডে যেকোনও কন্টেন্ট URI-এর জন্য প্ল্যাটফর্মের মাধ্যমে অটোমেটিক রিড পার্মিশন দেওয়া ও রিলিজ করা হয়।

সাধারণত, আপনার অ্যাপ কোনও পরিষেবা বা অ্যাক্টিভিটিতে কন্টেন্ট URI প্রসেস করে। দীর্ঘ সময় ধরে চলা প্রসেসিংয়ের জন্য, WorkManager ব্যবহার করুন। আপনি এটি প্রয়োগ করলে, Intent.setClipData ব্যবহার করে কন্টেন্ট পাস করার মাধ্যমে টার্গেট পরিষেবা বা অ্যাক্টিভিটিতে অনুমতি বাড়ান এবং FLAG_GRANT_READ_URI_PERMISSION ফ্ল্যাগ সেট করুন।

বিকল্প হিসেবে, কন্টেন্ট প্রসেস করার জন্য আপনি বর্তমান কন্টেক্সটের মধ্যে ব্যাকগ্রাউন্ড থ্রেড ব্যবহার করতে পারেন। এই ক্ষেত্রে, আপনাকে অবশ্যই লিসনারের মাধ্যমে পাওয়া payload অবজেক্টের রেফারেন্স বজায় রাখতে হবে যাতে প্ল্যাটফর্মের মাধ্যমে সময়ের আগেই অনুমতি প্রত্যাহার করা না হয়।

কাস্টম ভিউ

আপনার অ্যাপ কাস্টম View সাবক্লাস ব্যবহার করলে, OnReceiveContentListener যাতে বাইপাস না হয় তা নিশ্চিত করুন।

আপনার View ক্লাস যদি onCreateInputConnection পদ্ধতি ওভাররাইড করে, তাহলে InputConnection কনফিগার করতে Jetpack API InputConnectionCompat.createWrapper ব্যবহার করুন।

আপনার View ক্লাস onTextContextMenuItem পদ্ধতি ওভাররাইড করলে, মেনু আইটেম R.id.paste বা R.id.pasteAsPlainText হলে সুপারকে ডেলিগেট করুন।

কীবোর্ড ইমেজ API-এর সাথে তুলনা

আপনি OnReceiveContentListener API-কে আগে থেকে থাকা কীবোর্ড ইমেজ API-এর পরবর্তী ভার্সন হিসেবে ভাবতে পারেন। এই ইউনিফায়েড API, কীবোর্ড ইমেজ API-এর কার্যকারিতা এবং কিছু অতিরিক্ত ফিচার সমর্থন করে। আপনি Jetpack লাইব্রেরি নাকি Android SDK থেকে নেটিভ API ব্যবহার করছেন তার উপর নির্ভর করে ডিভাইস ও ফিচার কম্প্যাটিবিলিটি আলাদা আলাদা হয়।

টেবিল ১. Jetpack-এর জন্য কাজ করে এমন ফিচার ও API লেভেল।
অ্যাকশন বা ফিচার কীবোর্ড ইমেজ API দ্বারা সমর্থিত ইউনিফায়েড API-তে কাজ করে
কীবোর্ড থেকে যোগ করুন হ্যাঁ (API লেভেল ১৩ এবং তার পরবর্তী যেকোনও ভার্সন) হ্যাঁ (API লেভেল ১৩ এবং তার থেকে বেশি)
টাচ করে ধরে থাকার মেনু থেকে পেস্ট ব্যবহার করে যোগ করুন না হ্যাঁ
টেনে নিয়ে রাখার সুবিধা ব্যবহার করে যোগ করুন না হ্যাঁ (API লেভেল ২৪ এবং তার থেকে বেশি)
সারণী ২. নেটিভ API-এর জন্য কাজ করে এমন ফিচার ও API লেভেল।
অ্যাকশন বা ফিচার কীবোর্ড ইমেজ API দ্বারা সমর্থিত ইউনিফায়েড API-তে কাজ করে
কীবোর্ড থেকে যোগ করুন হ্যাঁ (API লেভেল ২৫ এবং তার চেয়ে বেশি) হ্যাঁ (Android 12 ও তার পরের যেকোনও ভার্সন)
টাচ করে ধরে থাকার মেনু থেকে পেস্ট ব্যবহার করে যোগ করুন না
টেনে নিয়ে রাখার সুবিধা ব্যবহার করে যোগ করুন না