ব্যবহারকারীরা ছবি, ভিডিও এবং অন্যান্য অভিব্যক্তিপূর্ণ কন্টেন্ট পছন্দ করেন, কিন্তু অ্যাপে এই কন্টেন্ট যোগ করা এবং সরানো সবসময় সহজ নয়। অ্যাপের জন্য রিচ কন্টেন্ট গ্রহণ করার প্রক্রিয়া সহজ করতে, অ্যান্ড্রয়েড ১২ (এপিআই লেভেল ৩১) একটি সমন্বিত এপিআই চালু করেছে, যা আপনার অ্যাপকে যেকোনো উৎস থেকে কন্টেন্ট গ্রহণ করতে দেয়: ক্লিপবোর্ড, কিবোর্ড বা ড্র্যাগিং।
আপনি UI কম্পোনেন্টগুলোর সাথে OnReceiveContentListener মতো একটি ইন্টারফেস সংযুক্ত করতে পারেন এবং যেকোনো পদ্ধতিতে কন্টেন্ট যুক্ত হলে একটি কলব্যাক পেতে পারেন। এই কলব্যাকটিই আপনার কোডের জন্য সমস্ত কন্টেন্ট—সাধারণ ও স্টাইল করা টেক্সট থেকে শুরু করে মার্কআপ, ছবি, ভিডিও, অডিও ফাইল এবং অন্যান্য—গ্রহণের কাজটি পরিচালনা করার একমাত্র জায়গা হয়ে ওঠে।
পূর্ববর্তী অ্যান্ড্রয়েড সংস্করণগুলির সাথে পশ্চাৎ সামঞ্জস্যের জন্য, এই API-টি AndroidX-এও উপলব্ধ, যা Core 1.7 এবং Appcompat 1.4 থেকে শুরু হয়েছে, এবং এই কার্যকারিতাটি বাস্তবায়নের সময় আমরা আপনাকে সেগুলি ব্যবহার করার পরামর্শ দিই।
সংক্ষিপ্ত বিবরণ
অন্যান্য বিদ্যমান এপিআই-এর ক্ষেত্রে, প্রতিটি ইউআই মেকানিজম—যেমন টাচ অ্যান্ড হোল্ড মেনু বা ড্র্যাগিং—এর নিজস্ব সংশ্লিষ্ট এপিআই থাকে। এর মানে হলো, আপনাকে প্রতিটি এপিআই-এর সাথে আলাদাভাবে ইন্টিগ্রেট করতে হবে এবং কন্টেন্ট ইনসার্ট করে এমন প্রতিটি মেকানিজমের জন্য একই ধরনের কোড যোগ করতে হবে:
OnReceiveContentListener API এই বিভিন্ন কোড পাথগুলোকে একত্রিত করে বাস্তবায়নের জন্য একটি একক API তৈরি করে, ফলে আপনি আপনার অ্যাপ-নির্দিষ্ট লজিকের উপর মনোযোগ দিতে পারেন এবং বাকিটা প্ল্যাটফর্মের উপর ছেড়ে দিতে পারেন:
এই পদ্ধতির আরেকটি সুবিধা হলো, যখন প্ল্যাটফর্মে কন্টেন্ট যুক্ত করার নতুন কোনো উপায় যোগ করা হয়, তখন আপনার অ্যাপে সেটির সাপোর্ট চালু করার জন্য অতিরিক্ত কোনো কোড পরিবর্তনের প্রয়োজন হয় না। আর যদি কোনো নির্দিষ্ট ব্যবহারের জন্য আপনার অ্যাপে সম্পূর্ণ কাস্টমাইজেশনের প্রয়োজন হয়, তাহলেও আপনি বিদ্যমান এপিআইগুলো ব্যবহার করতে পারবেন, যেগুলো আগের মতোই কাজ করতে থাকবে।
বাস্তবায়ন
এপিআইটি হলো একটি লিসেনার ইন্টারফেস, যাতে OnReceiveContentListener নামে একটিমাত্র মেথড রয়েছে। অ্যান্ড্রয়েড প্ল্যাটফর্মের পুরোনো সংস্করণগুলোকে সমর্থন করার জন্য, আমরা AndroidX Core লাইব্রেরিতে থাকা অনুরূপ OnReceiveContentListener ইন্টারফেসটি ব্যবহার করার পরামর্শ দিই।
এপিআই ব্যবহার করতে, আপনার অ্যাপ কী ধরনের কন্টেন্ট পরিচালনা করতে পারে তা নির্দিষ্ট করে লিসেনারটি ইমপ্লিমেন্ট করুন:
কোটলিন
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 টাইপ সমর্থন করে, সেগুলি নির্দিষ্ট করার পরে লিসেনারের বাকি অংশটি বাস্তবায়ন করুন:
কোটলিন
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; } }
আপনার অ্যাপে যদি আগে থেকেই ইন্টেন্টের মাধ্যমে শেয়ারিং-এর সুবিধা থাকে, তাহলে আপনি কন্টেন্ট ইউআরআই পরিচালনার জন্য আপনার অ্যাপ-নির্দিষ্ট লজিক পুনরায় ব্যবহার করতে পারেন। অবশিষ্ট ডেটা রিটার্ন করে সেই ডেটার পরিচালনার দায়িত্ব প্ল্যাটফর্মের ওপর অর্পণ করুন।
লিসেনারটি প্রয়োগ করার পর, আপনার অ্যাপের উপযুক্ত UI এলিমেন্টগুলিতে এটি সেট করুন:
কোটলিন
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 হলে super-কে ডেলিগেট করুন।
কিবোর্ড ইমেজ এপিআই-এর সাথে তুলনা
আপনি OnReceiveContentListener API-টিকে বিদ্যমান কীবোর্ড ইমেজ API- এর পরবর্তী সংস্করণ হিসেবে ভাবতে পারেন। এই সমন্বিত API-টি কীবোর্ড ইমেজ API-এর কার্যকারিতার পাশাপাশি কিছু অতিরিক্ত বৈশিষ্ট্যও সমর্থন করে। আপনি Jetpack লাইব্রেরি ব্যবহার করছেন নাকি Android SDK-এর নেটিভ API ব্যবহার করছেন, তার উপর নির্ভর করে ডিভাইস এবং বৈশিষ্ট্যের সামঞ্জস্যতা ভিন্ন হয়।
| ক্রিয়া বা বৈশিষ্ট্য | কিবোর্ড ইমেজ এপিআই দ্বারা সমর্থিত | একীভূত এপিআই দ্বারা সমর্থিত |
|---|---|---|
| কিবোর্ড থেকে প্রবেশ করান | হ্যাঁ (এপিআই লেভেল ১৩ এবং তার বেশি) | হ্যাঁ (এপিআই লেভেল ১৩ এবং তার বেশি) |
| টাচ ও হোল্ড মেনু থেকে পেস্ট ব্যবহার করে প্রবেশ করান। | না | হ্যাঁ |
| ড্র্যাগ-অ্যান্ড-ড্রপ ব্যবহার করে সন্নিবেশ করুন | না | হ্যাঁ (এপিআই লেভেল ২৪ এবং তার বেশি) |
| ক্রিয়া বা বৈশিষ্ট্য | কিবোর্ড ইমেজ এপিআই দ্বারা সমর্থিত | একীভূত এপিআই দ্বারা সমর্থিত |
|---|---|---|
| কিবোর্ড থেকে প্রবেশ করান | হ্যাঁ (এপিআই লেভেল ২৫ এবং তার বেশি) | হ্যাঁ (অ্যান্ড্রয়েড ১২ এবং তার পরবর্তী সংস্করণ) |
| টাচ ও হোল্ড মেনু থেকে পেস্ট ব্যবহার করে প্রবেশ করান। | না | |
| ড্র্যাগ অ্যান্ড ড্রপ ব্যবহার করে সন্নিবেশ করুন | না |