ইনটেন্ট ও ইনটেন্ট ফিল্টার

Intent হল একটি মেসেজিং অবজেক্ট যা আপনি অন্য অ্যাপ কম্পোনেন্ট থেকে কোনও অ্যাকশনের অনুরোধ করতে ব্যবহার করতে পারেন। যদিও ইনটেন্ট বিভিন্ন উপায়ে কম্পোনেন্টের মধ্যে যোগাযোগে সুবিধা প্রদান করে, তিনটি মৌলিক ব্যবহারের কেস আছে:

  • অ্যাক্টিভিটি শুরু করা

    Activity হল অ্যাপের একটি স্ক্রিন। আপনি startActivity()-এ Intent পাস করে Activity-এর নতুন ইনস্ট্যান্স শুরু করতে পারবেন। Intent অ্যাক্টিভিটি শুরু করার বিবরণ দেয় এবং প্রয়োজনীয় ডেটা বহন করে।

    অ্যাক্টিভিটি শেষ হওয়ার পরে আপনি যদি ফলাফল পেতে চান, তাহলে startActivityForResult()-এ কল করুন। আপনার অ্যাক্টিভিটি, অ্যাক্টিভিটির onActivityResult() কলব্যাকে আলাদা Intent অবজেক্ট হিসেবে ফলাফল পায়। আরও তথ্যের জন্য, অ্যাক্টিভিটি সংক্রান্ত নির্দেশিকা দেখুন।

  • পরিষেবা শুরু করা

    Service হল এমন একটি কম্পোনেন্ট যা ইউজার ইন্টারফেস ছাড়াই ব্যাকগ্রাউন্ডে অপারেশন করে। Android 5.0 (API লেভেল ২১) এবং তার পরবর্তী ভার্সনে, আপনি JobScheduler-এর মাধ্যমে কোনও পরিষেবা শুরু করতে পারবেন। JobScheduler সম্পর্কে আরও তথ্যের জন্য, API-reference documentation দেখুন।

    Android 5.0 (API লেভেল ২১)-এর আগের ভার্সনের জন্য, আপনি Service ক্লাসের পদ্ধতি ব্যবহার করে কোনও পরিষেবা শুরু করতে পারেন। আপনি startService()-এ Intent পাস করে এককালীন অপারেশন (যেমন ফাইল ডাউনলোড করা) সম্পূর্ণ করার জন্য কোনও পরিষেবা শুরু করতে পারেন। Intent পরিষেবা শুরু করার জন্য বর্ণনা করে এবং প্রয়োজনীয় ডেটা বহন করে।

    পরিষেবাটি যদি ক্লায়েন্ট-সার্ভার ইন্টারফেসের সাথে ডিজাইন করা হয়, তাহলে আপনি Intent থেকে bindService()-এ পাস করে অন্য কম্পোনেন্ট থেকে পরিষেবাতে বাইন্ড করতে পারবেন। আরও তথ্যের জন্য, পরিষেবা সংক্রান্ত নির্দেশিকা দেখুন।

  • ব্রডকাস্ট ডেলিভার করা

    ব্রডকাস্ট হল এমন একটি মেসেজ যা যেকোনও অ্যাপ গ্রহণ করতে পারে। সিস্টেম ইভেন্টের জন্য সিস্টেম বিভিন্ন ব্রডকাস্ট ডেলিভার করে, যেমন সিস্টেম বুট-আপ হলে বা ডিভাইস চার্জ হতে শুরু করলে। আপনি Intent-কে sendBroadcast() বা sendOrderedBroadcast()-এ পাস করে অন্যান্য অ্যাপে ব্রডকাস্ট ডেলিভার করতে পারবেন।

এই পৃষ্ঠার বাকি অংশে ইনটেন্ট কীভাবে কাজ করে এবং কীভাবে সেগুলি ব্যবহার করতে হয় তা ব্যাখ্যা করা হয়েছে। এই সম্পর্কিত তথ্যের জন্য, অন্যান্য অ্যাপের সাথে ইন্টার‍্যাক্ট করা এবং কন্টেন্ট শেয়ার করা দেখুন।

ইনটেন্টের ধরন

দুই ধরনের ইনটেন্ট আছে:

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

অ্যাক্টিভিটি শুরু করার সময় কীভাবে ইনটেন্ট ব্যবহার করা হয় তা ছবি ১-এ দেখানো হয়েছে। Intent অবজেক্ট যখন নির্দিষ্ট অ্যাক্টিভিটি কম্পোনেন্টের নাম স্পষ্টভাবে উল্লেখ করে, তখন সিস্টেম অবিলম্বে সেই কম্পোনেন্ট শুরু করে।

ছবি ১. অন্য অ্যাক্টিভিটি শুরু করার জন্য সিস্টেমের মাধ্যমে কীভাবে ইমপ্লিসিট ইনটেন্ট ডেলিভার করা হয়: [১] অ্যাক্টিভিটি A অ্যাকশন বিবরণ সহ Intent তৈরি করে এবং startActivity()-এ পাস করে। [২] Android সিস্টেম ইনটেন্টের সাথে ম্যাচ করে এমন ইনটেন্ট ফিল্টারের জন্য সব অ্যাপ সার্চ করে। ম্যাচ পাওয়া গেলে, [3] সিস্টেম ম্যাচিং অ্যাক্টিভিটি (অ্যাক্টিভিটি B) শুরু করে, এর জন্য onCreate() পদ্ধতি ব্যবহার করে এবং Intent পাস করে।

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

ইনটেন্ট ফিল্টার হল অ্যাপের ম্যানিফেস্ট ফাইলের একটি এক্সপ্রেশন যা কম্পোনেন্টটি যে ধরনের ইনটেন্ট পেতে চায় তা নির্দিষ্ট করে। যেমন, কোনও অ্যাক্টিভিটির জন্য ইনটেন্ট ফিল্টার ঘোষণা করে, আপনি অন্যান্য অ্যাপের জন্য নির্দিষ্ট ধরনের ইনটেন্ট সহ সরাসরি আপনার অ্যাক্টিভিটি শুরু করা সম্ভব করেন। একইভাবে, আপনি কোনও অ্যাক্টিভিটির জন্য ইনটেন্ট ফিল্টার ঘোষণা না করলে, এটি শুধুমাত্র এক্সপ্লিসিট ইনটেন্টের মাধ্যমে শুরু করা যেতে পারে।

সতর্কতা: আপনার অ্যাপ সুরক্ষিত আছে কিনা তা নিশ্চিত করতে, Service শুরু করার সময় সবসময় এক্সপ্লিসিট ইনটেন্ট ব্যবহার করুন এবং আপনার পরিষেবার জন্য ইনটেন্ট ফিল্টার ঘোষণা করবেন না। কোনও পরিষেবা শুরু করার জন্য ইমপ্লিসিট ইনটেন্ট ব্যবহার করা নিরাপত্তার ক্ষেত্রে বিপজ্জনক কারণ কোন পরিষেবা ইনটেন্টের উত্তর দেবে তা আপনি নিশ্চিতভাবে বলতে পারবেন না এবং কোন পরিষেবা শুরু হয়েছে তা ব্যবহারকারী দেখতে পাবেন না। Android 5.0 (API লেভেল ২১) থেকে শুরু করে, আপনি ইমপ্লিসিট ইনটেন্ট সহ bindService() কল করলে সিস্টেম ব্যতিক্রম দেখায়।

অভিপ্রায় তৈরি করা হচ্ছে

একটি Intent অবজেক্টে এমন তথ্য থাকে যা Android সিস্টেম কোন কম্পোনেন্ট শুরু করতে হবে তা নির্ধারণ করতে ব্যবহার করে (যেমন সঠিক কম্পোনেন্টের নাম বা কম্পোনেন্ট বিভাগ যা ইনটেন্ট গ্রহণ করবে), সাথে প্রাপক কম্পোনেন্ট সঠিকভাবে অ্যাকশনটি সম্পাদন করার জন্য যে তথ্য ব্যবহার করে (যেমন কোন অ্যাকশন নিতে হবে এবং কোন ডেটার উপর কাজ করতে হবে)।

Intent-এ থাকা প্রাথমিক তথ্যগুলি হল:

কম্পোনেন্টের নাম
কম্পোনেন্ট শুরু করার নাম।

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

মনে রাখবেন: Service শুরু করার সময়, সবসময় কম্পোনেন্টের নাম উল্লেখ করুন। অন্যথায়, আপনি নিশ্চিত হতে পারবেন না যে কোন পরিষেবা ইনটেন্টের উত্তর দেবে এবং ব্যবহারকারী দেখতে পাবেন না যে কোন পরিষেবা শুরু হয়েছে।

Intent-এর এই ফিল্ডটি হল একটি ComponentName অবজেক্ট, যা আপনি টার্গেট কম্পোনেন্টের সম্পূর্ণ যোগ্য ক্লাস নাম ব্যবহার করে নির্দিষ্ট করতে পারেন, যার মধ্যে অ্যাপের প্যাকেজ নামও অন্তর্ভুক্ত, যেমন, com.example.ExampleActivity। আপনি setComponent(), setClass(), setClassName(), বা Intent কনস্ট্রাক্টর দিয়ে কম্পোনেন্টের নাম সেট করতে পারেন।

অ্যাকশন
একটি স্ট্রিং যা পারফর্ম করার জন্য জেনেরিক অ্যাকশন নির্দিষ্ট করে (যেমন দেখুন বা বেছে নিন)।

ব্রডকাস্ট ইনটেন্টের ক্ষেত্রে, এটি হল সেই অ্যাকশন যা ঘটেছে এবং রিপোর্ট করা হচ্ছে। অ্যাকশনটি মূলত নির্ধারণ করে যে বাকি ইনটেন্ট কীভাবে স্ট্রাকচার করা হয়েছে—বিশেষ করে ডেটা এবং এক্সট্রাতে থাকা তথ্য।

আপনার অ্যাপের মধ্যে ইনটেন্ট দ্বারা ব্যবহারের জন্য (অথবা আপনার অ্যাপে কম্পোনেন্ট চালু করার জন্য অন্যান্য অ্যাপের ব্যবহারের জন্য) আপনি নিজের অ্যাকশন নির্দিষ্ট করতে পারেন, তবে আপনি সাধারণত Intent ক্লাস বা অন্যান্য ফ্রেমওয়ার্ক ক্লাস দ্বারা সংজ্ঞায়িত অ্যাকশন কনস্ট্যান্ট নির্দিষ্ট করেন। অ্যাক্টিভিটি শুরু করার জন্য কিছু সাধারণ অ্যাকশন এখানে দেওয়া হল:

ACTION_VIEW
কোনও অ্যাক্টিভিটি ব্যবহারকারীকে দেখাতে পারে এমন কিছু তথ্য আপনার কাছে থাকলে, startActivity()-এর সাথে ইনটেন্টে এই অ্যাকশন ব্যবহার করুন, যেমন গ্যালারি অ্যাপে দেখার জন্য কোনও ফটো বা ম্যাপ অ্যাপে দেখার জন্য কোনও ঠিকানা।
ACTION_SEND
শেয়ার ইনটেন্ট হিসেবেও পরিচিত, আপনার কাছে এমন কিছু ডেটা থাকলে যা ব্যবহারকারী অন্য অ্যাপের মাধ্যমে শেয়ার করতে পারবেন, যেমন ইমেল অ্যাপ বা সোশ্যাল শেয়ারিং অ্যাপ, তাহলে startActivity() সহ ইনটেন্টে এটি ব্যবহার করা উচিত।

জেনেরিক অ্যাকশন সংজ্ঞায়িত করে এমন আরও কনস্ট্যান্টের জন্য Intent ক্লাস রেফারেন্স দেখুন। অন্যান্য অ্যাকশন Android ফ্রেমওয়ার্কের অন্য কোথাও সংজ্ঞায়িত করা হয়, যেমন Settings-এ অ্যাকশনের জন্য যা সিস্টেমের সেটিংস অ্যাপে নির্দিষ্ট স্ক্রিন খোলে।

আপনি setAction() বা Intent কনস্ট্রাক্টরের মাধ্যমে ইনটেন্টের জন্য অ্যাকশন নির্দিষ্ট করতে পারবেন।

আপনি নিজের অ্যাকশন নির্ধারণ করলে, প্রিফিক্স হিসেবে আপনার অ্যাপের প্যাকেজের নাম অন্তর্ভুক্ত করতে ভুলবেন না, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

Kotlin

const val ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL"

জাভা

static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
ডেটা
URI (একটি Uri অবজেক্ট) যা ডেটার রেফারেন্স দেয় এবং/অথবা সেই ডেটার MIME টাইপ। সাধারণত ইনটেন্টের অ্যাকশন অনুযায়ী ডেটার ধরন সরবরাহ করা হয়। যেমন, অ্যাকশনটি ACTION_EDIT হলে, ডেটাতে এডিট করার জন্য ডকুমেন্টের URI থাকতে হবে।

ইনটেন্ট তৈরি করার সময়, URI ছাড়াও ডেটার ধরন (এর MIME-এর প্রকার) উল্লেখ করা প্রায়শই গুরুত্বপূর্ণ হয়। যেমন, ছবি দেখাতে পারে এমন অ্যাক্টিভিটি সম্ভবত অডিও ফাইল চালাতে পারবে না, যদিও URI ফর্ম্যাট একই হতে পারে। আপনার ডেটার MIME-এর প্রকার উল্লেখ করলে, Android সিস্টেমকে আপনার ইনটেন্ট রিসিভ করার জন্য সেরা কম্পোনেন্ট খুঁজে পেতে সাহায্য করে। তবে, MIME-এর প্রকার কখনও কখনও URI থেকে অনুমান করা যেতে পারে—বিশেষ করে যখন ডেটা একটি content: URI হয়। content: URI থেকে বোঝা যায় যে ডেটা ডিভাইসে আছে এবং সেটি ContentProvider দ্বারা নিয়ন্ত্রিত, যার ফলে ডেটা MIME-এর প্রকার সিস্টেমের কাছে দৃশ্যমান হয়।

শুধুমাত্র ডেটা URI সেট করতে, setData() কল করুন। শুধু MIME-এর ধরন সেট করতে, setType()-কে কল করুন। প্রয়োজন হলে, আপনি setDataAndType()-এর মাধ্যমে দুটিই স্পষ্টভাবে সেট করতে পারবেন।

সতর্কতা: আপনি URI ও MIME-এর প্রকার, দুটিই সেট করতে চাইলে, setData() ও setType() কল করবেন না, কারণ, এগুলি একে অপরের ভ্যালু বাতিল করে দেয়। URI এবং MIME-এর ধরন, দুটিই সেট করতে সবসময় setDataAndType() ব্যবহার করুন।

বিভাগ
ইনটেন্ট ম্যানেজ করা উচিত এমন কম্পোনেন্টের ধরন সম্পর্কে অতিরিক্ত তথ্য সহ একটি স্ট্রিং। ইনটেন্টে যেকোনও সংখ্যক বিভাগের বিবরণ যোগ করা যেতে পারে, তবে বেশিরভাগ ইনটেন্টের জন্য বিভাগের প্রয়োজন হয় না। এখানে কিছু সাধারণ বিভাগ দেওয়া হল:
CATEGORY_BROWSABLE
টার্গেট অ্যাক্টিভিটি নিজেকে কোনও ওয়েব ব্রাউজারের মাধ্যমে শুরু করার অনুমতি দেয় যাতে কোনও লিঙ্কের মাধ্যমে রেফার করা ডেটা দেখানো যায়, যেমন কোনও ছবি বা ইমেল মেসেজ।
CATEGORY_LAUNCHER
অ্যাক্টিভিটি হল কোনও টাস্কের প্রাথমিক অ্যাক্টিভিটি এবং এটি সিস্টেমের অ্যাপ্লিকেশন লঞ্চারে তালিকাভুক্ত করা থাকে।

বিভাগের সম্পূর্ণ তালিকার জন্য Intent ক্লাসের বিবরণ দেখুন।

আপনি addCategory()-এর মাধ্যমে কোনও বিভাগ নির্দিষ্ট করতে পারবেন।

উপরে তালিকাভুক্ত এইসব প্রপার্টি (কম্পোনেন্টের নাম, অ্যাকশন, ডেটা ও বিভাগ) ইনটেন্টের সংজ্ঞায়িত বৈশিষ্ট্যকে তুলে ধরে। এইসব প্রপার্টি পড়ে, Android সিস্টেম কোন অ্যাপ কম্পোনেন্ট চালু করা উচিত তা সমাধান করতে পারে। তবে, কোনও ইনটেন্ট অতিরিক্ত তথ্য বহন করতে পারে যা কোনও অ্যাপ কম্পোনেন্টে কীভাবে এটি সমাধান করা হয় তাকে প্রভাবিত করে না। এছাড়াও, ইনটেন্ট নিম্নলিখিত তথ্য প্রদান করতে পারে:

অতিরিক্ত
অনুরোধ করা অ্যাকশন সম্পূর্ণ করার জন্য প্রয়োজনীয় অতিরিক্ত তথ্য বহনকারী কী-ভ্যালু পেয়ার। কিছু অ্যাকশন যেমন নির্দিষ্ট ধরনের ডেটা URI ব্যবহার করে, তেমনই কিছু অ্যাকশন নির্দিষ্ট অতিরিক্ত তথ্যও ব্যবহার করে।

আপনি বিভিন্ন putExtra() পদ্ধতির মাধ্যমে অতিরিক্ত ডেটা যোগ করতে পারেন, প্রতিটি পদ্ধতি দুটি প্যারামিটার গ্রহণ করে: কী-এর নাম এবং ভ্যালু। এছাড়াও, আপনি সব অতিরিক্ত ডেটা সহ একটি Bundle অবজেক্ট তৈরি করতে পারেন, তারপর putExtras() সহ Intent-এ Bundle যোগ করুন।

যেমন, ACTION_SEND-এর মাধ্যমে ইমেল পাঠানোর ইনটেন্ট তৈরি করার সময়, আপনি EXTRA_EMAIL কী-এর মাধ্যমে প্রাপক এবং EXTRA_SUBJECT কী-এর মাধ্যমে বিষয় উল্লেখ করতে পারেন।

Intent ক্লাস স্ট্যান্ডার্ডাইজড ডেটার ধরনের জন্য অনেক EXTRA_* কনস্ট্যান্ট নির্দিষ্ট করে। আপনাকে যদি নিজের অতিরিক্ত কী ঘোষণা করতে হয় (আপনার অ্যাপ যে ইনটেন্ট রিসিভ করে তার জন্য), তাহলে প্রিফিক্স হিসেবে আপনার অ্যাপের প্যাকেজের নাম অন্তর্ভুক্ত করতে ভুলবেন না, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

Kotlin

const val EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS"

জাভা

static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";

সতর্কতা: আপনি আশা করেন যে অন্য অ্যাপ পাবে এমন ইনটেন্ট পাঠানোর সময় Parcelable বা Serializable ডেটা ব্যবহার করবেন না। কোনও অ্যাপ Bundle অবজেক্টে ডেটা অ্যাক্সেস করার চেষ্টা করলে, কিন্তু পার্সেল করা বা সিরিয়ালাইজ করা ক্লাসে অ্যাক্সেস না থাকলে, সিস্টেম RuntimeException দেখায়।

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

আরও তথ্যের জন্য, setFlags() পদ্ধতি দেখুন।

এক্সপ্লিসিট ইনটেন্টের উদাহরণ

এক্সপ্লিসিট ইনটেন্ট হল এমন একটি ইনটেন্ট যা আপনি নির্দিষ্ট অ্যাপ কম্পোনেন্ট লঞ্চ করার জন্য ব্যবহার করেন, যেমন আপনার অ্যাপে কোনও নির্দিষ্ট অ্যাক্টিভিটি বা পরিষেবা। এক্সপ্লিসিট ইনটেন্ট তৈরি করতে, Intent অবজেক্টের জন্য কম্পোনেন্টের নাম নির্ধারণ করুন—অন্য সব ইনটেন্ট প্রপার্টি ঐচ্ছিক।

যেমন, আপনি যদি নিজের অ্যাপে DownloadService নামে কোনও পরিষেবা তৈরি করেন, যা ওয়েব থেকে ফাইল ডাউনলোড করার জন্য ডিজাইন করা হয়েছে, তাহলে আপনি নিম্নলিখিত কোড দিয়ে এটি শুরু করতে পারবেন:

Kotlin

// Executed in an Activity, so 'this' is the Context
// The fileUrl is a string URL, such as "http://www.example.com/image.png"
val downloadIntent = Intent(this, DownloadService::class.java).apply {
    data = Uri.parse(fileUrl)
}
startService(downloadIntent)

জাভা

// Executed in an Activity, so 'this' is the Context
// The fileUrl is a string URL, such as "http://www.example.com/image.png"
Intent downloadIntent = new Intent(this, DownloadService.class);
downloadIntent.setData(Uri.parse(fileUrl));
startService(downloadIntent);

Intent(Context, Class) কনস্ট্রাক্টর অ্যাপ Context এবং কম্পোনেন্টকে Class অবজেক্ট প্রদান করে। সেই কারণে, এই ইনটেন্ট অ্যাপে স্পষ্টভাবে DownloadService ক্লাস শুরু করে।

কোনও পরিষেবা তৈরি ও শুরু করা সম্পর্কে আরও তথ্যের জন্য, পরিষেবা সংক্রান্ত নির্দেশিকা দেখুন।

ইমপ্লিসিট ইনটেন্টের উদাহরণ

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

যেমন, আপনার কাছে এমন কন্টেন্ট থাকলে যা আপনি চান যে ব্যবহারকারী অন্য লোকজনের সাথে শেয়ার করুক, তাহলে ACTION_SEND অ্যাকশন সহ ইনটেন্ট তৈরি করুন এবং শেয়ার করার জন্য কন্টেন্ট নির্দিষ্ট করে এমন অতিরিক্ত তথ্য যোগ করুন। আপনি যখন সেই ইনটেন্ট সহ startActivity() কল করেন, তখন ব্যবহারকারী একটি অ্যাপ বেছে নিতে পারেন যার মাধ্যমে কন্টেন্ট শেয়ার করা যায়।

Kotlin

// Create the text message with a string.
val sendIntent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, textMessage)
    type = "text/plain"
}

// Try to invoke the intent.
try {
    startActivity(sendIntent)
} catch (e: ActivityNotFoundException) {
    // Define what your app should do if no activity can handle the intent.
}

জাভা

// Create the text message with a string.
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");

// Try to invoke the intent.
try {
    startActivity(sendIntent);
} catch (ActivityNotFoundException e) {
    // Define what your app should do if no activity can handle the intent.
}

startActivity() কল করা হলে, সিস্টেম ইনস্টল করা সব অ্যাপ পরীক্ষা করে দেখে যে কোন অ্যাপ এই ধরনের ইনটেন্ট (ACTION_SEND অ্যাকশন সহ ইনটেন্ট এবং যা "text/plain" ডেটা বহন করে) ম্যানেজ করতে পারে। যদি শুধুমাত্র একটি অ্যাপ এটি ম্যানেজ করতে পারে, তাহলে সেই অ্যাপটি অবিলম্বে খুলে যায় এবং সেটিকে ইনটেন্ট দেওয়া হয়। অন্য কোনও অ্যাপ এটি ম্যানেজ করতে না পারলে, আপনার অ্যাপ ActivityNotFoundException ক্যাচ করতে পারবে। একাধিক অ্যাক্টিভিটি ইনটেন্ট গ্রহণ করলে, সিস্টেম ছবি ২-এ দেখানো ডায়ালগের মতো একটি ডায়ালগ দেখায়, যাতে ব্যবহারকারী কোন অ্যাপ ব্যবহার করবেন তা বেছে নিতে পারেন।

অন্যান্য অ্যাপ লঞ্চ করার ব্যাপারে আরও তথ্য ব্যবহারকারীকে অন্য অ্যাপে পাঠানো সংক্রান্ত নির্দেশিকায় দেওয়া আছে।

ছবি ২. একটি বাছাইকারী ডায়ালগ।

অ্যাপ বেছে নেওয়ার জন্য জোর করা হচ্ছে

আপনার ইমপ্লিসিট ইনটেন্টে একাধিক অ্যাপ সাড়া দিলে, ব্যবহারকারী কোন অ্যাপ ব্যবহার করবেন তা বেছে নিতে পারবেন এবং সেই অ্যাপটিকে অ্যাকশনের জন্য ডিফল্ট হিসেবে সেট করতে পারবেন। ডিফল্ট বেছে নেওয়ার সুবিধাটি এমন কোনও অ্যাকশন পারফর্ম করার সময় সহায়ক হয়, যার জন্য ব্যবহারকারী সম্ভবত প্রতিবার একই অ্যাপ ব্যবহার করতে চান, যেমন কোনও ওয়েব পেজ খোলার সময় (ব্যবহারকারীরা প্রায়শই শুধু একটি ওয়েব ব্রাউজার পছন্দ করেন)।

তবে, একাধিক অ্যাপ ইনটেন্টের উত্তর দিতে পারলে এবং ব্যবহারকারী প্রতিবার আলাদা অ্যাপ ব্যবহার করতে চাইলে, আপনাকে স্পষ্টভাবে একটি বাছাইকারী ডায়ালগ দেখাতে হবে। বেছে নেওয়ার ডায়ালগ ব্যবহারকারীকে জিজ্ঞাসা করে যে অ্যাকশনের জন্য কোন অ্যাপ ব্যবহার করতে হবে (ব্যবহারকারী অ্যাকশনের জন্য ডিফল্ট অ্যাপ বেছে নিতে পারবেন না)। যেমন, আপনার অ্যাপ ACTION_SEND অ্যাকশনের মাধ্যমে "শেয়ার" করলে, ব্যবহারকারী বর্তমান পরিস্থিতির উপর নির্ভর করে অন্য কোনও অ্যাপের মাধ্যমে শেয়ার করতে চাইতে পারেন, তাই আপনাকে সবসময় বেছে নেওয়ার ডায়ালগ ব্যবহার করতে হবে, যেমনটি চিত্র ২-এ দেখানো হয়েছে।

বেছে নেওয়ার বিকল্প দেখাতে, createChooser() ব্যবহার করে একটি Intent তৈরি করুন এবং নিচের উদাহরণে দেখানো অনুযায়ী এটি startActivity()-এ পাস করুন। এই উদাহরণে এমন একটি ডায়ালগ দেখানো হয়েছে যেখানে অ্যাপের তালিকা রয়েছে। এই অ্যাপগুলি createChooser() মেথডে পাস করা ইনটেন্টের উত্তর দেয় এবং সাপ্লাই করা টেক্সটকে ডায়ালগের শীর্ষক হিসেবে ব্যবহার করে।

Kotlin

val sendIntent = Intent(Intent.ACTION_SEND)
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
val title: String = resources.getString(R.string.chooser_title)
// Create intent to show the chooser dialog
val chooser: Intent = Intent.createChooser(sendIntent, title)

// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(packageManager) != null) {
    startActivity(chooser)
}

জাভা

Intent sendIntent = new Intent(Intent.ACTION_SEND);
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show the chooser dialog
Intent chooser = Intent.createChooser(sendIntent, title);

// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(chooser);
}

অসুরক্ষিত ইনটেন্ট লঞ্চ শনাক্ত করা

আপনার অ্যাপের মধ্যে কম্পোনেন্টের মধ্যে নেভিগেট করতে বা অন্য অ্যাপের হয়ে কোনও অ্যাকশন পারফর্ম করতে, আপনার অ্যাপ ইনটেন্ট লঞ্চ করতে পারে। প্ল্যাটফর্মের নিরাপত্তা উন্নত করতে, Android 12 (API লেভেল 31) এবং তার পরবর্তী ভার্সন একটি ডিবাগিং ফিচার প্রদান করে যা আপনার অ্যাপ কোনও ইনটেন্টের অসুরক্ষিত লঞ্চ করলে আপনাকে সতর্ক করে। যেমন, আপনার অ্যাপ কোনও নেস্টেড ইনটেন্ট-এর অসুরক্ষিত লঞ্চ করতে পারে, যা অন্য ইনটেন্টে অতিরিক্ত হিসেবে পাস করা একটি ইনটেন্ট।

আপনার অ্যাপ যদি নিম্নলিখিত দুটি অ্যাকশনই করে, তাহলে সিস্টেম একটি অসুরক্ষিত ইনটেন্ট লঞ্চ শনাক্ত করে এবং একটি StrictMode লঙ্ঘন ঘটে:

  1. আপনার অ্যাপ ডেলিভার করা ইনটেন্টের অতিরিক্ত থেকে নেস্টেড ইনটেন্ট আনপার্সেল করে।
  2. আপনার অ্যাপ অবিলম্বে নেস্টেড ইনটেন্ট ব্যবহার করে একটি অ্যাপ কম্পোনেন্ট শুরু করে, যেমন ইনটেন্টকে startActivity(), startService(), অথবা bindService()-এ পাস করা।

এই পরিস্থিতি কীভাবে শনাক্ত করবেন এবং আপনার অ্যাপে পরিবর্তন করবেন সেই সম্পর্কে আরও বিশদ বিবরণের জন্য, Medium-এ Android Nesting Intents সম্পর্কে ব্লগ পোস্ট পড়ুন।

অসুরক্ষিত ইনটেন্ট লঞ্চের জন্য চেক করা

আপনার অ্যাপে অসুরক্ষিত ইনটেন্ট লঞ্চ চেক করতে, detectUnsafeIntentLaunch() কল করুন যখন আপনি VmPolicy কনফিগার করবেন, যেমন নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে। আপনার অ্যাপ StrictMode লঙ্ঘন শনাক্ত করলে, সম্ভাব্য সংবেদনশীল তথ্য সুরক্ষিত রাখতে আপনি অ্যাপ এক্সিকিউশন বন্ধ করতে চাইতে পারেন।

Kotlin

fun onCreate() {
    StrictMode.setVmPolicy(VmPolicy.Builder()
        // Other StrictMode checks that you've previously added.
        // ...
        .detectUnsafeIntentLaunch()
        .penaltyLog()
        // Consider also adding penaltyDeath()
        .build())
}

জাভা

protected void onCreate() {
    StrictMode.setVmPolicy(new VmPolicy.Builder()
        // Other StrictMode checks that you've previously added.
        // ...
        .detectUnsafeIntentLaunch()
        .penaltyLog()
        // Consider also adding penaltyDeath()
        .build());
}

আরও দায়িত্ব সহকারে ইনটেন্ট ব্যবহার করুন

অনিরাপদ ইনটেন্ট লঞ্চের সম্ভাবনা এবং StrictMode লঙ্ঘন কমানোর জন্য, এইসব পেশাদার পদ্ধতি অনুসরণ করুন।

ইনটেন্টের মধ্যে শুধু প্রয়োজনীয় অতিরিক্ত তথ্য কপি করুন এবং প্রয়োজনীয় স্যানিটেশন ও যাচাইকরণ সম্পূর্ণ করুন। আপনার অ্যাপ একটি ইনটেন্ট থেকে অন্য ইনটেন্টে অতিরিক্ত কপি করতে পারে যা একটি নতুন কম্পোনেন্ট চালু করতে ব্যবহৃত হয়। আপনার অ্যাপ putExtras(Intent) বা putExtras(Bundle) কল করলে এটি হয়। আপনার অ্যাপ যদি এইসব অপারেশনের মধ্যে কোনও একটি করে, তাহলে শুধুমাত্র সেই অতিরিক্ত ডেটা কপি করুন যা রিসিভিং কম্পোনেন্ট আশা করে। অন্য ইনটেন্ট (যা কপি পায়) এমন কম্পোনেন্ট লঞ্চ করলে যা এক্সপোর্ট করা হয়নি, তাহলে কম্পোনেন্ট লঞ্চ করা ইনটেন্টে কপি করার আগে অতিরিক্ত ডেটা স্যানিটাইজ ও যাচাই করুন।

আপনার অ্যাপের কম্পোনেন্ট অপ্রয়োজনীয়ভাবে এক্সপোর্ট করবেন না। যেমন, আপনি যদি ইন্টার্নাল নেস্টেড ইনটেন্ট ব্যবহার করে কোনও অ্যাপ কম্পোনেন্ট লঞ্চ করতে চান, তাহলে সেই কম্পোনেন্টের android:exported অ্যাট্রিবিউট false-এ সেট করুন।

নেস্টেড ইনটেন্টের পরিবর্তে PendingIntent ব্যবহার করুন। এইভাবে, অন্য কোনও অ্যাপ যখন Intent-এর মধ্যে থাকা PendingIntent আনপার্সেল করে, তখন অন্য অ্যাপটি আপনার অ্যাপের পরিচয় ব্যবহার করে PendingIntent লঞ্চ করতে পারে। এই কনফিগারেশন অন্য অ্যাপকে আপনার অ্যাপে এক্সপোর্ট না করা কম্পোনেন্ট সহ যেকোনও কম্পোনেন্ট নিরাপদে লঞ্চ করার অনুমতি দেয়।

চিত্র ২-এর ডায়াগ্রাম থেকে বোঝা যায় যে সিস্টেম কীভাবে আপনার (ক্লায়েন্ট) অ্যাপ থেকে অন্য (পরিষেবা) অ্যাপে কন্ট্রোল পাস করে এবং আপনার অ্যাপে ফিরে আসে:

  1. আপনার অ্যাপ এমন একটি ইনটেন্ট তৈরি করে যা অন্য অ্যাপে অ্যাক্টিভিটি চালু করে। সেই ইনটেন্টের মধ্যে, আপনি অতিরিক্ত হিসেবে একটি PendingIntent অবজেক্ট যোগ করেন। এই পেন্ডিং ইনটেন্ট আপনার অ্যাপের একটি কম্পোনেন্টকে কল করে; এই কম্পোনেন্টটি এক্সপোর্ট করা হয়নি।
  2. আপনার অ্যাপের ইনটেন্ট পাওয়ার পরে, অন্য অ্যাপ নেস্টেড PendingIntent অবজেক্ট এক্সট্র্যাক্ট করে।
  3. অন্য অ্যাপটি PendingIntent অবজেক্টে send() পদ্ধতিটি আহ্বান করে।
  4. আপনার অ্যাপে কন্ট্রোল ফিরিয়ে দেওয়ার পরে, সিস্টেম আপনার অ্যাপের কন্টেক্সট ব্যবহার করে পেন্ডিং ইনটেন্টকে ইনভোক করে।

ছবি ২. নেস্টেড পেন্ডিং ইনটেন্ট ব্যবহার করার সময় অ্যাপ-টু-অ্যাপ কমিউনিকেশনের ডায়াগ্রাম।

ইমপ্লিসিট ইনটেন্ট পাওয়া

আপনার অ্যাপ কোন ইমপ্লিসিট ইনটেন্ট পেতে পারে তা বিজ্ঞাপন দিতে, আপনার ম্যানিফেস্ট ফাইলে <intent-filter> এলিমেন্ট সহ আপনার প্রতিটি অ্যাপ কম্পোনেন্টের জন্য এক বা একাধিক ইনটেন্ট ফিল্টার ঘোষণা করুন। প্রতিটি ইনটেন্ট ফিল্টার, ইনটেন্টের অ্যাকশন, ডেটা ও বিভাগের উপর ভিত্তি করে, এটি কোন ধরনের ইনটেন্ট গ্রহণ করে তা নির্দিষ্ট করে। ইনটেন্ট আপনার কোনও ইনটেন্ট ফিল্টারের মাধ্যমে পাস করতে পারলে তবেই সিস্টেম আপনার অ্যাপ কম্পোনেন্টে ইমপ্লিসিট ইনটেন্ট ডেলিভার করে।

মনে রাখবেন: কম্পোনেন্ট যে ইনটেন্ট ফিল্টারই ঘোষণা করুক না কেন, এক্সপ্লিসিট ইনটেন্ট সবসময় তার টার্গেটে ডেলিভার করা হয়।

অ্যাপের কম্পোনেন্টকে প্রতিটি অনন্য কাজের জন্য আলাদা ফিল্টার ঘোষণা করতে হবে। যেমন, ইমেজ গ্যালারি অ্যাপের একটি অ্যাক্টিভিটিতে দুটি ফিল্টার থাকতে পারে: একটি ফিল্টার ছবি দেখার জন্য এবং আরেকটি ফিল্টার ছবি এডিট করার জন্য। অ্যাক্টিভিটি শুরু হলে, এটি Intent পরীক্ষা করে এবং Intent-এ থাকা তথ্যের ভিত্তিতে কীভাবে আচরণ করতে হবে তা স্থির করে (যেমন এডিটর কন্ট্রোল দেখানো হবে কিনা)।

প্রতিটি ইনটেন্ট ফিল্টার অ্যাপের ম্যানিফেস্ট ফাইলে <intent-filter> এলিমেন্ট দ্বারা সংজ্ঞায়িত করা হয়, যা সংশ্লিষ্ট অ্যাপ কম্পোনেন্টে (যেমন <activity> এলিমেন্ট) নেস্ট করা থাকে।

<intent-filter> এলিমেন্ট অন্তর্ভুক্ত প্রতিটি অ্যাপ কম্পোনেন্টে, android:exported-এর জন্য স্পষ্টভাবে একটি ভ্যালু সেট করুন। এই অ্যাট্রিবিউট থেকে বোঝা যায় যে অ্যাপ কম্পোনেন্ট অন্য অ্যাপের জন্য অ্যাক্সেসযোগ্য কিনা। কিছু পরিস্থিতিতে, যেমন যেসব অ্যাক্টিভিটির ইনটেন্ট ফিল্টারে LAUNCHER বিভাগ অন্তর্ভুক্ত থাকে, সেখানে এই অ্যাট্রিবিউট true-এ সেট করা উপযোগী। অন্যথায়, এই অ্যাট্রিবিউট false-এ সেট করা আরও নিরাপদ।

সতর্কতা: আপনার অ্যাপের কোনও অ্যাক্টিভিটি, পরিষেবা বা ব্রডকাস্ট রিসিভার যদি ইনটেন্ট ফিল্টার ব্যবহার করে এবং android:exported-এর জন্য স্পষ্টভাবে ভ্যালু সেট না করে, তাহলে Android ১২ বা তার পরবর্তী ভার্সনে চলে এমন ডিভাইসে আপনার অ্যাপ ইনস্টল করা যাবে না।

<intent-filter>-এর মধ্যে, আপনি এই তিনটি এলিমেন্টের মধ্যে এক বা একাধিক ব্যবহার করে গ্রহণ করার জন্য ইনটেন্টের ধরন নির্দিষ্ট করতে পারেন:

<action>
name অ্যাট্রিবিউটে, ইনটেন্ট অ্যাকশন গ্রহণ করা হয়েছে বলে ঘোষণা করে। ভ্যালু অবশ্যই কোনও অ্যাকশনের লিটারেল স্ট্রিং ভ্যালু হতে হবে, ক্লাস কনস্ট্যান্ট নয়।
<data>
এক বা একাধিক অ্যাট্রিবিউট ব্যবহার করে, যে ধরনের ডেটা গ্রহণ করা হয় তা ঘোষণা করে, যা ডেটা URI (scheme, host, port, path) এবং MIME-এর প্রকারের বিভিন্ন দিক নির্দিষ্ট করে।
<category>
name অ্যাট্রিবিউটে, ইনটেন্ট ক্যাটেগরি গ্রহণ করা হয়েছে বলে ঘোষণা করে। ভ্যালু অবশ্যই কোনও অ্যাকশনের আক্ষরিক স্ট্রিং ভ্যালু হতে হবে, ক্লাস কনস্ট্যান্ট নয়।

মনে রাখবেন: ইমপ্লিসিট ইনটেন্ট পেতে, আপনাকে ইনটেন্ট ফিল্টারে CATEGORY_DEFAULT বিভাগ অবশ্যই অন্তর্ভুক্ত করতে হবে। startActivity() এবং startActivityForResult() পদ্ধতিগুলি সব ইনটেন্টকে এমনভাবে ট্রিট করে যেন তারা CATEGORY_DEFAULT ক্যাটেগরি ঘোষণা করেছে। আপনি ইনটেন্ট ফিল্টারে এই বিভাগ ঘোষণা না করলে, কোনও ইমপ্লিসিট ইনটেন্ট আপনার অ্যাক্টিভিটিতে রিজলভ হবে না।

যেমন, ডেটার ধরন টেক্সট হলে, ACTION_SEND ইনটেন্ট পাওয়ার জন্য ইনটেন্ট ফিল্টার সহ অ্যাক্টিভিটি ডিক্লারেশন এখানে দেওয়া হল:

<activity android:name="ShareActivity" android:exported="false">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

আপনি এমন ফিল্টার তৈরি করতে পারবেন যাতে <action>, <data> অথবা <category>-এর একাধিক উদাহরণ অন্তর্ভুক্ত থাকে। আপনি যদি তা করেন, তাহলে আপনাকে নিশ্চিত হতে হবে যে কম্পোনেন্টটি সেই ফিল্টার এলিমেন্টের যেকোনও এবং সব কম্বিনেশন ম্যানেজ করতে পারে।

আপনি যখন একাধিক ধরনের ইনটেন্ট ম্যানেজ করতে চান, কিন্তু শুধুমাত্র অ্যাকশন, ডেটা ও বিভাগের ধরনের নির্দিষ্ট কম্বিনেশনে, তখন আপনাকে একাধিক ইনটেন্ট ফিল্টার তৈরি করতে হবে।

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

সতর্কতা: অন্য অ্যাপ যাতে আপনার কম্পোনেন্ট চালু করতে না পারে, তার জন্য ইনটেন্ট ফিল্টার ব্যবহার করা কোনও নিরাপদ উপায় নয়। ইনটেন্ট ফিল্টার কোনও কম্পোনেন্টকে শুধুমাত্র নির্দিষ্ট ধরনের ইমপ্লিসিট ইনটেন্টে প্রতিক্রিয়া জানাতে সীমাবদ্ধ করলেও, ডেভেলপার আপনার কম্পোনেন্টের নাম নির্ধারণ করলে, অন্য কোনও অ্যাপ এক্সপ্লিসিট ইনটেন্ট ব্যবহার করে আপনার অ্যাপ কম্পোনেন্ট চালু করতে পারে। শুধুমাত্র আপনার নিজের অ্যাপ যাতে আপনার কোনও কম্পোনেন্ট শুরু করতে পারে, সেটি যদি গুরুত্বপূর্ণ হয়, তাহলে আপনার ম্যানিফেস্টে ইনটেন্ট ফিল্টার ঘোষণা করবেন না। পরিবর্তে, সেই কম্পোনেন্টের জন্য exported অ্যাট্রিবিউট "false"-এ সেট করুন।

একইভাবে, অনিচ্ছাকৃতভাবে অন্য অ্যাপের Service চালানো এড়াতে, আপনার নিজের পরিষেবা শুরু করার জন্য সবসময় এক্সপ্লিসিট ইনটেন্ট ব্যবহার করুন।

মনে রাখবেন: সব অ্যাক্টিভিটির জন্য, আপনাকে ম্যানিফেস্ট ফাইলে ইনটেন্ট ফিল্টার ঘোষণা করতে হবে। তবে, সম্প্রচার রিসিভারের জন্য ফিল্টারগুলি registerReceiver() কল করে ডাইনামিকভাবে রেজিস্টার করা যেতে পারে। তারপর আপনি unregisterReceiver()-এর মাধ্যমে রিসিভারকে আনরেজিস্টার করতে পারবেন। এটি করলে, আপনার অ্যাপ চালু থাকাকালীন শুধুমাত্র নির্দিষ্ট সময়সীমার মধ্যে নির্দিষ্ট ব্রডকাস্ট শোনার জন্য আপনার অ্যাপকে অনুমতি দেয়।

উদাহরণ ফিল্টার

ইনটেন্ট ফিল্টারের কিছু আচরণ দেখানোর জন্য, এখানে একটি সোশ্যাল-শেয়ারিং অ্যাপের ম্যানিফেস্ট ফাইল থেকে একটি উদাহরণ দেওয়া হল:

<activity android:name="MainActivity" android:exported="true">
    <!-- This activity is the main entry, should appear in app launcher -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity android:name="ShareActivity" android:exported="false">
    <!-- This activity handles "SEND" actions with text data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
    <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <action android:name="android.intent.action.SEND_MULTIPLE"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="application/vnd.google.panorama360+jpg"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="video/*"/>
    </intent-filter>
</activity>

প্রথম অ্যাক্টিভিটি, MainActivity, হল অ্যাপের প্রধান এন্ট্রি পয়েন্ট—যে অ্যাক্টিভিটি ব্যবহারকারী লঞ্চার আইকন দিয়ে প্রাথমিকভাবে অ্যাপ লঞ্চ করলে খোলে:

  • ACTION_MAIN অ্যাকশন ইঙ্গিত করে যে এটিই মূল এন্ট্রি পয়েন্ট এবং কোনও ইনটেন্ট ডেটা আশা করে না।
  • CATEGORY_LAUNCHER বিভাগটি নির্দেশ করে যে এই অ্যাক্টিভিটির আইকন সিস্টেমের অ্যাপ লঞ্চারে রাখা উচিত। <activity> এলিমেন্ট icon-এর সাথে কোনও আইকন নির্দিষ্ট না করলে, সিস্টেম <application> এলিমেন্ট থেকে আইকন ব্যবহার করে।

অ্যাপ লঞ্চারে অ্যাক্টিভিটি দেখতে হলে এই দুটিকে একসাথে পেয়ার করতে হবে।

দ্বিতীয় অ্যাক্টিভিটি, ShareActivity, টেক্সট ও মিডিয়া কন্টেন্ট শেয়ার করার সুবিধা প্রদান করার জন্য তৈরি করা হয়েছে। যদিও ব্যবহারকারীরা MainActivity থেকে নেভিগেট করে এই অ্যাক্টিভিটিতে প্রবেশ করতে পারেন, তারা সরাসরি অন্য অ্যাপ থেকেও ShareActivity-এ প্রবেশ করতে পারেন যা দুটি ইনটেন্ট ফিল্টারের মধ্যে একটির সাথে মিলে যাওয়া ইমপ্লিসিট ইনটেন্ট ইস্যু করে।

মনে রাখবেন: MIME-এর প্রকার, application/vnd.google.panorama360+jpg, হল একটি বিশেষ ডেটার প্রকার যা প্যানোরামিক ফটো নির্দিষ্ট করে, যা আপনি Google প্যানোরামা API-এর মাধ্যমে ম্যানেজ করতে পারবেন।

অন্য অ্যাপের ইনটেন্ট ফিল্টারের সাথে ইনটেন্ট ম্যাচ করুন

অন্য কোনও অ্যাপ Android ১৩ (API লেভেল ৩৩) বা তার পরবর্তী কোনও ভার্সনকে টার্গেট করলে, সেটি আপনার অ্যাপের ইনটেন্ট তখনই ম্যানেজ করতে পারবে, যদি আপনার ইনটেন্ট অন্য অ্যাপের <intent-filter> এলিমেন্টের অ্যাকশন ও বিভাগের সাথে ম্যাচ করে। সিস্টেম কোনও ম্যাচ খুঁজে না পেলে, এটি ActivityNotFoundException থ্রো করে। যে অ্যাপ পাঠাচ্ছে সেটিকে অবশ্যই এই ব্যতিক্রম ম্যানেজ করতে হবে।

একইভাবে, আপনি যদি নিজের অ্যাপ আপডেট করেন যাতে এটি Android 13 বা তার পরবর্তী যেকোনও ভার্সনকে টার্গেট করে, তাহলে এক্সটার্নাল অ্যাপ থেকে আসা সমস্ত ইনটেন্ট আপনার অ্যাপের এক্সপোর্ট করা কম্পোনেন্টে তখনই ডেলিভার করা হয় যখন সেই ইনটেন্ট আপনার অ্যাপের ঘোষণা করা <intent-filter> এলিমেন্টের অ্যাকশন এবং বিভাগের সাথে মেলে। প্রেরক অ্যাপের টার্গেট SDK ভার্সন যাই হোক না কেন, এই আচরণ দেখা যায়।

নিম্নলিখিত ক্ষেত্রে, ইনটেন্ট ম্যাচিং প্রয়োগ করা হয় না:

  • কোনও ইনটেন্ট ফিল্টার ঘোষণা করে না এমন কম্পোনেন্টে ইনটেন্ট ডেলিভার করা হয়েছে।
  • একই অ্যাপের মধ্যে থেকে তৈরি হওয়া ইনটেন্ট।
  • সিস্টেম থেকে উদ্ভূত ইনটেন্ট; অর্থাৎ, "সিস্টেম UID" (uid=1000) থেকে পাঠানো ইনটেন্ট। সিস্টেম অ্যাপের মধ্যে system_server এবং android:sharedUserId থেকে android.uid.system-এ সেট করা অ্যাপ অন্তর্ভুক্ত।
  • রুট থেকে উদ্ভূত ইনটেন্ট।

ইনটেন্ট ম্যাচিং সম্পর্কে আরও জানুন।

বাকি থাকা ইনটেন্ট ব্যবহার করা হচ্ছে

PendingIntent অবজেক্ট হল Intent অবজেক্টের চারপাশে একটি র‍্যাপার। PendingIntent-এর প্রাথমিক উদ্দেশ্য হল বিদেশি অ্যাপ্লিকেশনকে অনুমতি দেওয়া যাতে সেটি Intent ব্যবহার করতে পারে, যেন সেটি আপনার অ্যাপের নিজস্ব প্রসেস থেকে এক্সিকিউট করা হয়েছে।

পেন্ডিং ইনটেন্টের প্রধান ব্যবহারের ক্ষেত্রে নিম্নলিখিতগুলি অন্তর্ভুক্ত:

  • ব্যবহারকারী আপনার বিজ্ঞপ্তির সাথে কোনও অ্যাকশন পারফর্ম করলে, এক্সিকিউট করার জন্য ইনটেন্ট ঘোষণা করা (Android সিস্টেমের NotificationManager Intent এক্সিকিউট করে)।
  • ব্যবহারকারী আপনার অ্যাপ উইজেট-এর সাথে কোনও অ্যাকশন করলে, এক্সিকিউট করার জন্য ইনটেন্ট ঘোষণা করা (হোম স্ক্রিন অ্যাপ Intent এক্সিকিউট করে)।
  • ভবিষ্যতে নির্দিষ্ট সময়ে কার্যকর করার জন্য ইনটেন্ট ঘোষণা করা (Android সিস্টেমের AlarmManager, Intent কার্যকর করে)।

প্রতিটি Intent অবজেক্ট যেমন নির্দিষ্ট ধরনের অ্যাপ কম্পোনেন্ট (হয় Activity, Service অথবা BroadcastReceiver) দ্বারা ম্যানেজ করার জন্য ডিজাইন করা হয়, তেমনই PendingIntent-কেও একই বিষয় বিবেচনা করে তৈরি করতে হবে। পেন্ডিং ইনটেন্ট ব্যবহার করার সময়, আপনার অ্যাপ startActivity()-এর মতো কলের মাধ্যমে ইনটেন্ট এক্সিকিউট করে না। পরিবর্তে, আপনি যখন সংশ্লিষ্ট ক্রিয়েটর পদ্ধতি কল করে PendingIntent তৈরি করবেন, তখন আপনাকে অবশ্যই উদ্দিষ্ট কম্পোনেন্টের ধরন ঘোষণা করতে হবে:

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

প্রতিটি পদ্ধতি বর্তমান অ্যাপ Context, আপনি যে Intent র‍্যাপ করতে চান এবং এক বা একাধিক ফ্ল্যাগ নেয় যা ইনটেন্ট কীভাবে ব্যবহার করা উচিত তা নির্দিষ্ট করে (যেমন ইনটেন্ট একাধিকবার ব্যবহার করা যাবে কিনা)।

পেন্ডিং ইনটেন্ট ব্যবহার করার ব্যাপারে আরও তথ্যের জন্য, প্রতিটি ব্যবহারের ক্ষেত্রের জন্য ডকুমেন্টেশন দেখুন, যেমন বিজ্ঞপ্তি এবং অ্যাপ উইজেট API গাইড।

মিউটেবিলিটি নির্দিষ্ট করুন

আপনার অ্যাপ Android 12 বা তার পরবর্তী যেকোনও ভার্সনকে টার্গেট করলে, আপনার অ্যাপের তৈরি করা প্রতিটি PendingIntent অবজেক্টের মিউটেবিলিটি আপনাকে নির্দিষ্ট করতে হবে। প্রদত্ত PendingIntent অবজেক্টটি মিউটেবল নাকি ইমিউটেবল তা ঘোষণা করতে, যথাক্রমে PendingIntent.FLAG_MUTABLE বা PendingIntent.FLAG_IMMUTABLE ফ্ল্যাগ ব্যবহার করুন।

আপনার অ্যাপ যদি কোনও মিউটেবিলিটি ফ্ল্যাগ সেট না করেই PendingIntent অবজেক্ট তৈরি করার চেষ্টা করে, তাহলে সিস্টেম একটি IllegalArgumentException থ্রো করে এবং Logcat-এ নিম্নলিখিত মেসেজটি দেখা যায়:

PACKAGE_NAME: Targeting S+ (version 31 and above) requires that one of \
FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.

Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if \
some functionality depends on the PendingIntent being mutable, e.g. if \
it needs to be used with inline replies or bubbles.

যখনই সম্ভব হবে, অপরিবর্তনীয় পেন্ডিং ইনটেন্ট তৈরি করুন

বেশিরভাগ ক্ষেত্রে, আপনার অ্যাপের অপরিবর্তনীয় PendingIntent অবজেক্ট তৈরি করা উচিত, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে। কোনও PendingIntent অবজেক্ট অপরিবর্তনীয় হলে, অন্যান্য অ্যাপ ইনটেন্টকে কল করার ফলাফল অ্যাডজাস্ট করার জন্য ইনটেন্টকে পরিবর্তন করতে পারে না।

Kotlin

val pendingIntent = PendingIntent.getActivity(applicationContext,
        REQUEST_CODE, intent,
        /* flags */ PendingIntent.FLAG_IMMUTABLE)

জাভা

PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
        REQUEST_CODE, intent,
        /* flags */ PendingIntent.FLAG_IMMUTABLE);

তবে, কিছু ব্যবহারের ক্ষেত্রে মিউটেবল PendingIntent অবজেক্টের প্রয়োজন হয়:

  • বিজ্ঞপ্তিতে সরাসরি উত্তর দেওয়ার অ্যাকশন কাজ করে। সরাসরি উত্তর ফিচারের জন্য উত্তরের সাথে যুক্ত PendingIntent অবজেক্টের ক্লিপ ডেটাতে পরিবর্তন করতে হবে। সাধারণত, আপনি fillIn() পদ্ধতিতে ফ্ল্যাগ হিসেবে FILL_IN_CLIP_DATA পাস করে এই পরিবর্তনের অনুরোধ করেন।
  • CarAppExtender-এর ইনস্ট্যান্স ব্যবহার করে Android Auto ফ্রেমওয়ার্কের সাথে বিজ্ঞপ্তি অ্যাসোসিয়েট করা।
  • PendingIntent-এর ইনস্ট্যান্স ব্যবহার করে বাবল-এ কথোপকথন রাখা। একটি পরিবর্তনযোগ্য PendingIntent অবজেক্ট সিস্টেমকে সঠিক ফ্ল্যাগ প্রয়োগ করতে দেয়, যেমন FLAG_ACTIVITY_MULTIPLE_TASK এবং FLAG_ACTIVITY_NEW_DOCUMENT।
  • requestLocationUpdates() বা একই ধরনের API কল করে ডিভাইসের লোকেশন সংক্রান্ত তথ্য চাওয়া হচ্ছে। মিউটেবল PendingIntent অবজেক্ট সিস্টেমকে লোকেশন লাইফসাইকেল ইভেন্টকে উপস্থাপন করে এমন ইনটেন্ট এক্সট্রা যোগ করার অনুমতি দেয়। এইসব ইভেন্টের মধ্যে লোকেশন পরিবর্তন এবং কোনও পরিষেবা প্রদানকারী উপলভ্য হওয়ার মতো বিষয় অন্তর্ভুক্ত।
  • AlarmManager ব্যবহার করে অ্যালার্ম শিডিউল করা। মিউটেবল PendingIntent অবজেক্ট সিস্টেমকে EXTRA_ALARM_COUNT ইনটেন্ট এক্সট্রা যোগ করার অনুমতি দেয়। এই অতিরিক্ত তথ্যটি দেখায় যে কতবার একটি পুনরাবৃত্তিমূলক অ্যালার্ম ট্রিগার করা হয়েছে। এই অতিরিক্ত তথ্য অন্তর্ভুক্ত করার মাধ্যমে, ইনটেন্ট কোনও অ্যাপকে সঠিকভাবে জানাতে পারে যে একটি পুনরাবৃত্তিমূলক অ্যালার্ম একাধিকবার ট্রিগার করা হয়েছে কিনা, যেমন যখন ডিভাইসটি স্লিপ মোডে ছিল।

আপনার অ্যাপ যদি পরিবর্তনযোগ্য PendingIntent অবজেক্ট তৈরি করে, তাহলে আপনাকে এক্সপ্লিসিট ইনটেন্ট ব্যবহার করতে এবং ComponentName পূরণ করতে জোর দিয়ে সাজেস্ট করা হচ্ছে। এর ফলে, অন্য কোনও অ্যাপ PendingIntent-কে কল করে আপনার অ্যাপে কন্ট্রোল ফিরিয়ে দিলে, আপনার অ্যাপের একই কম্পোনেন্ট সবসময় চালু হয়।

পেন্ডিং ইনটেন্টের মধ্যে এক্সপ্লিসিট ইনটেন্ট ব্যবহার করা

অন্যান্য অ্যাপ কীভাবে আপনার অ্যাপের পেন্ডিং ইনটেন্ট ব্যবহার করতে পারে তা আরও ভালোভাবে নির্ধারণ করতে, সবসময় পেন্ডিং ইনটেন্টকে এক্সপ্লিসিট ইনটেন্ট-এর সাথে র‍্যাপ করুন। এই পেশাদার পদ্ধতি অনুসরণ করতে, নিম্নলিখিত ধাপগুলি অনুসরণ করুন:

  1. বেস ইনটেন্টের অ্যাকশন, প্যাকেজ ও কম্পোনেন্ট ফিল্ড সেট করা আছে কিনা তা চেক করুন।
  2. পেন্ডিং ইনটেন্ট তৈরি করতে, Android 6.0 (API লেভেল ২৩)-এ যোগ করা FLAG_IMMUTABLE ব্যবহার করুন। এই ফ্ল্যাগ PendingIntent পাওয়া অ্যাপকে অসম্পূর্ণ প্রপার্টি পূরণ করা থেকে আটকায়। আপনার অ্যাপের minSdkVersion যদি 22 বা তার কম হয়, তাহলে আপনি নিম্নলিখিত কোড ব্যবহার করে একসাথে নিরাপত্তা ও কম্প্যাটিবিলিটি প্রদান করতে পারবেন:

    if (Build.VERSION.SDK_INT >= 23) {
      // Create a PendingIntent using FLAG_IMMUTABLE.
    } else {
      // Existing code that creates a PendingIntent.
    }

ইনটেন্ট রেজোলিউশন

কোনও অ্যাক্টিভিটি শুরু করার জন্য সিস্টেম যখন ইমপ্লিসিট ইনটেন্ট পায়, তখন এটি তিনটি বিষয়ের উপর ভিত্তি করে ইনটেন্ট ফিল্টারের সাথে তুলনা করে ইনটেন্টের জন্য সেরা অ্যাক্টিভিটি খোঁজে:

  • অ্যাকশন।
  • ডেটা (URI এবং ডেটার ধরন, দুটিই)।
  • বিভাগ।

অ্যাপের ম্যানিফেস্ট ফাইলে ইনটেন্ট ফিল্টার ঘোষণা অনুযায়ী ইনটেন্ট কীভাবে উপযুক্ত কম্পোনেন্টের সাথে ম্যাচ করে তা নিম্নলিখিত বিভাগে বর্ণনা করা হয়েছে।

অ্যাকশন টেস্ট

গ্রহণ করা ইনটেন্ট অ্যাকশন নির্দিষ্ট করতে, ইনটেন্ট ফিল্টার শূন্য বা তার বেশি <action> এলিমেন্ট ঘোষণা করতে পারে, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

<intent-filter>
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.VIEW" />
    ...
</intent-filter>

এই ফিল্টার পাস করতে, Intent-এ উল্লেখ করা অ্যাকশন ফিল্টারে তালিকাভুক্ত অ্যাকশনগুলির মধ্যে একটির সাথে অবশ্যই মিলতে হবে।

ফিল্টারে কোনও অ্যাকশন তালিকাভুক্ত না থাকলে, ইনটেন্টের সাথে ম্যাচ করার মতো কিছু থাকে না, তাই সব ইনটেন্ট টেস্টে ব্যর্থ হয়। তবে, কোনও Intent-এ অ্যাকশন নির্দিষ্ট করা না থাকলে, ফিল্টারে অন্তত একটি অ্যাকশন থাকলে এটি টেস্টে পাস করে।

ক্যাটেগরি টেস্ট

গ্রহণ করা ইনটেন্ট ক্যাটেগরি নির্দিষ্ট করতে, ইনটেন্ট ফিল্টার শূন্য বা তার বেশি <category> এলিমেন্ট ঘোষণা করতে পারে, যেমন নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

<intent-filter>
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    ...
</intent-filter>

কোনও ইনটেন্টকে ক্যাটেগরি টেস্টে পাস করতে হলে, Intent-এর প্রতিটি ক্যাটেগরিকে ফিল্টারের কোনও ক্যাটেগরির সাথে ম্যাচ করতে হবে। The reverse is not necessary—the intent filter may declare more categories than are specified in the Intent and the Intent still passes. তাই, কোনও বিভাগ ছাড়া ইনটেন্ট সবসময় এই টেস্টে পাস করে, ফিল্টারে যে বিভাগই ঘোষণা করা হোক না কেন।

মনে রাখবেন: Android অটোমেটিক CATEGORY_DEFAULT বিভাগটি startActivity() এবং startActivityForResult()-এ পাস করা সব ইমপ্লিসিট ইনটেন্টে প্রয়োগ করে। আপনার অ্যাক্টিভিটি যাতে ইমপ্লিসিট ইনটেন্ট গ্রহণ করতে পারে, তার জন্য ইনটেন্ট ফিল্টারে "android.intent.category.DEFAULT"-এর জন্য একটি বিভাগ অন্তর্ভুক্ত করতে হবে, যেমনটি আগের <intent-filter> উদাহরণে দেখানো হয়েছে।

ডেটা টেস্ট

গ্রহণ করা ইনটেন্ট ডেটা নির্দিষ্ট করতে, ইনটেন্ট ফিল্টার শূন্য বা তার বেশি <data> এলিমেন্ট ঘোষণা করতে পারে, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

<intent-filter>
    <data android:mimeType="video/mpeg" android:scheme="http" ... />
    <data android:mimeType="audio/mpeg" android:scheme="http" ... />
    ...
</intent-filter>

প্রতিটি <data> এলিমেন্ট একটি URI স্ট্রাকচার এবং ডেটার ধরন (MIME মিডিয়ার ধরন) নির্দিষ্ট করতে পারে। URI-এর প্রতিটি অংশ হল আলাদা অ্যাট্রিবিউট: scheme, host, port, এবং path:

<scheme>://<host>:<port>/<path>

নিম্নলিখিত উদাহরণে এইসব অ্যাট্রিবিউটের সম্ভাব্য ভ্যালু দেখানো হয়েছে:

content://com.example.project:200/folder/subfolder/etc

এই URI-তে, স্কিম হল content, হোস্ট হল com.example.project, পোর্ট হল 200 এবং পাথ হল folder/subfolder/etc।

<data> এলিমেন্টে এই প্রতিটি অ্যাট্রিবিউট ঐচ্ছিক, তবে লিনিয়ার ডিপেন্ডেন্সি আছে:

  • কোনও স্কিম উল্লেখ না করা হলে, হোস্টকে উপেক্ষা করা হয়।
  • হোস্ট নির্দিষ্ট করা না থাকলে, পোর্ট উপেক্ষা করা হয়।
  • স্কিম ও হোস্ট, দুটির কোনওটিই উল্লেখ করা না থাকলে, পাথটি উপেক্ষা করা হয়।

কোনও ইনটেন্টে URI-কে ফিল্টারে URI স্পেসিফিকেশনের সাথে তুলনা করা হলে, এটি শুধুমাত্র ফিল্টারে অন্তর্ভুক্ত URI-এর অংশের সাথে তুলনা করা হয়। যেমন:

  • কোনও ফিল্টার যদি শুধুমাত্র একটি স্কিম নির্দিষ্ট করে, তাহলে সেই স্কিম সহ সমস্ত URI ফিল্টারের সাথে ম্যাচ করে।
  • কোনও ফিল্টার যদি কোনও স্কিম এবং অথরিটি নির্দিষ্ট করে কিন্তু কোনও পাথ না থাকে, তাহলে একই স্কিম এবং অথরিটি সহ সমস্ত URI ফিল্টারটি পাস করে, তাদের পাথ যাই হোক না কেন।
  • কোনও ফিল্টার যদি স্কিম, অথরিটি ও পাথ নির্দিষ্ট করে, তাহলে শুধুমাত্র একই স্কিম, অথরিটি ও পাথ সহ URI ফিল্টার পাস করে।

মনে রাখবেন: পাথ স্পেসিফিকেশনে ওয়াইল্ডকার্ড অ্যাসটেরিক্স (*) থাকতে পারে যাতে পাথ নামের শুধু আংশিক মিলের প্রয়োজন হয়।

ডেটা টেস্ট ইনটেন্টের URI ও MIME-এর প্রকার, ফিল্টারে উল্লেখ করা URI ও MIME-এর প্রকারের সাথে তুলনা করে। নিয়মগুলি নিচে উল্লেখ করা হল:

  1. কোনও ইনটেন্টে URI বা MIME-এর প্রকার না থাকলে, সেটি তখনই টেস্টে পাস করে যদি ফিল্টারে কোনও URI বা MIME-এর প্রকার উল্লেখ করা না থাকে।
  2. কোনও ইনটেন্টে URI থাকলেও MIME-এর ধরন (স্পষ্টভাবে বা URI থেকে অনুমান করা যায় এমন) না থাকলে, সেটি তখনই টেস্টে পাস করে যখন তার URI ফিল্টারের URI ফর্ম্যাটের সাথে মেলে এবং ফিল্টারও একইভাবে MIME-এর ধরন উল্লেখ করে না।
  3. কোনও ইনটেন্টে MIME-এর ধরন থাকলেও URI না থাকলে, সেটি তখনই টেস্টে পাস করে যখন ফিল্টারে একই MIME-এর ধরন তালিকাভুক্ত থাকে এবং URI ফর্ম্যাট উল্লেখ করা থাকে না।
  4. URI এবং MIME-এর প্রকার (স্পষ্ট বা URI থেকে অনুমানযোগ্য) উভয়ই আছে এমন ইনটেন্ট MIME-এর প্রকারের টেস্টের অংশ তখনই পাস করে যদি সেই প্রকার ফিল্টারে তালিকাভুক্ত প্রকারের সাথে মেলে। এটি পরীক্ষার URI অংশটি পাস করে যদি এর URI ফিল্টারের কোনও URI-এর সাথে মেলে অথবা যদি এতে একটি content: বা file: URI থাকে এবং ফিল্টারটি কোনও URI নির্দিষ্ট না করে। অন্যভাবে বলতে গেলে, কোনও কম্পোনেন্ট content: এবং file: ডেটা সাপোর্ট করে বলে ধরে নেওয়া হয় যদি তার ফিল্টার শুধুমাত্র MIME টাইপ তালিকাভুক্ত করে।

মনে রাখবেন: কোনও ইনটেন্ট URI বা MIME-এর প্রকার নির্দিষ্ট করলে, <intent-filter>-এ কোনও <data> এলিমেন্ট না থাকলে ডেটা টেস্ট ব্যর্থ হবে।

এই শেষ নিয়ম, নিয়ম (d), এই প্রত্যাশা প্রতিফলিত করে যে কম্পোনেন্টগুলি ফাইল বা কন্টেন্ট প্রোভাইডার থেকে লোকাল ডেটা পেতে সক্ষম। তাই, তাদের ফিল্টারগুলি শুধুমাত্র একটি ডেটা টাইপ তালিকাভুক্ত করতে পারে এবং স্পষ্টভাবে content: এবং file: স্কিমের নাম দেওয়ার প্রয়োজন নেই। নিম্নলিখিত উদাহরণে একটি সাধারণ কেস দেখানো হয়েছে যেখানে <data> এলিমেন্ট Android-কে বলে যে কম্পোনেন্টটি কন্টেন্ট প্রোভাইডার থেকে ছবির ডেটা পেতে এবং তা দেখাতে পারে:

<intent-filter>
    <data android:mimeType="image/*" />
    ...
</intent-filter>

যেসব ফিল্টার ডেটার ধরন নির্দিষ্ট করে কিন্তু URI নয়, সেগুলিই সম্ভবত সবচেয়ে সাধারণ, কারণ উপলভ্য বেশিরভাগ ডেটা কন্টেন্ট প্রোভাইডাররা প্রদান করে।

অন্য একটি সাধারণ কনফিগারেশন হল স্কিম ও ডেটার ধরন সহ ফিল্টার। যেমন, নিম্নলিখিত <data> এলিমেন্ট Android-কে জানায় যে অ্যাকশনটি সম্পূর্ণ করার জন্য কম্পোনেন্টটি নেটওয়ার্ক থেকে ভিডিও ডেটা সংগ্রহ করতে পারে:

<intent-filter>
    <data android:scheme="http" android:mimeType="video/*" />
    ...
</intent-filter>

ইনটেন্ট ম্যাচিং

ইনটেন্ট ফিল্টারের সাথে ইনটেন্ট ম্যাচ করা হয়, শুধু টার্গেট কম্পোনেন্ট খুঁজে অ্যাক্টিভেট করার জন্য নয়, ডিভাইসে কম্পোনেন্টের সেট সম্পর্কে কিছু খুঁজে বের করার জন্যও। যেমন, Home অ্যাপ, ইনটেন্ট ফিল্টার সহ সব অ্যাক্টিভিটি খুঁজে অ্যাপ লঞ্চার পপুলেট করে, যা ACTION_MAIN অ্যাকশন এবং CATEGORY_LAUNCHER বিভাগ নির্দিষ্ট করে। IntentFilter ক্লাসের জন্য ডকুমেন্টেশনে যেমন বর্ণনা করা হয়েছে, ফিল্টারের বিপরীতে ইনটেন্টের অ্যাকশন এবং বিভাগগুলি মিললে তবেই একটি মিল সফল হয়।

Home অ্যাপ যেভাবে ইনটেন্ট ম্যাচিং করে, আপনার অ্যাপ্লিকেশনও সেইভাবে ইনটেন্ট ম্যাচিং করতে পারে। PackageManager-এ query...() মেথডের একটি সেট আছে যা এমন সব কম্পোনেন্ট রিটার্ন করে যা কোনও নির্দিষ্ট ইনটেন্ট গ্রহণ করতে পারে এবং resolve...() মেথডের একই ধরনের সিরিজ আছে যা কোনও ইনটেন্টের উত্তর দেওয়ার জন্য সেরা কম্পোনেন্ট নির্ধারণ করে। যেমন, queryIntentActivities() এমন সব অ্যাক্টিভিটির তালিকা দেখায় যা আর্গুমেন্ট হিসেবে পাস করা ইনটেন্ট সম্পূর্ণ করতে পারে এবং queryIntentServices() একই ধরনের পরিষেবার তালিকা দেখায়। কোনও পদ্ধতিই কম্পোনেন্ট অ্যাক্টিভেট করে না; তারা শুধু সেইসব কম্পোনেন্টের তালিকা দেখায় যেগুলি উত্তর দিতে পারে। ব্রডকাস্ট রিসিভারের জন্য একই ধরনের পদ্ধতি, queryBroadcastReceivers(), আছে।