Intent হলো একটি মেসেজিং অবজেক্ট, যা ব্যবহার করে আপনি অ্যাপের অন্য কোনো কম্পোনেন্ট থেকে কোনো কাজের অনুরোধ করতে পারেন। যদিও ইনটেন্ট বিভিন্ন উপায়ে কম্পোনেন্টগুলোর মধ্যে যোগাযোগ সহজ করে, এর তিনটি মৌলিক ব্যবহার রয়েছে:
- একটি কার্যকলাপ শুরু করা
একটি
Activityএকটি অ্যাপের একটিমাত্র স্ক্রিনকে উপস্থাপন করে। আপনিstartActivity()ফাংশনে একটিIntentপাস করে একটিActivityনতুন ইনস্ট্যান্স শুরু করতে পারেন।Intentকোন অ্যাক্টিভিটি শুরু করতে হবে তা বর্ণনা করে এবং এতে প্রয়োজনীয় ডেটা থাকে।অ্যাক্টিভিটি শেষ হলে তার ফলাফল পেতে চাইলে
startActivityForResult()কল করুন। আপনার অ্যাক্টিভিটি তারonActivityResult()কলব্যাকে ফলাফলটি একটি আলাদাIntentঅবজেক্ট হিসেবে গ্রহণ করে। আরও তথ্যের জন্য, অ্যাক্টিভিটিজ গাইড দেখুন। - একটি পরিষেবা শুরু করা
Serviceহলো এমন একটি কম্পোনেন্ট যা কোনো ইউজার ইন্টারফেস ছাড়াই ব্যাকগ্রাউন্ডে বিভিন্ন অপারেশন সম্পাদন করে। অ্যান্ড্রয়েড ৫.০ (এপিআই লেভেল ২১) এবং এর পরবর্তী সংস্করণগুলোতে, আপনিJobSchedulerব্যবহার করে একটি সার্ভিস চালু করতে পারেন।JobSchedulerসম্পর্কে আরও তথ্যের জন্য, এরAPI-reference documentationদেখুন।অ্যান্ড্রয়েড ৫.০ (এপিআই লেভেল ২১)-এর আগের সংস্করণগুলিতে, আপনি
Serviceক্লাসের মেথড ব্যবহার করে একটি সার্ভিস চালু করতে পারেন।startService()একটিIntentপাস করে আপনি এককালীন কোনো কাজ (যেমন একটি ফাইল ডাউনলোড করা) করার জন্য সার্ভিসটি চালু করতে পারেন।Intentকোন সার্ভিস চালু করতে হবে তা বর্ণনা করে এবং এতে প্রয়োজনীয় ডেটা থাকে।যদি সার্ভিসটি ক্লায়েন্ট-সার্ভার ইন্টারফেস দিয়ে ডিজাইন করা হয়, তাহলে আপনি
bindService()ফাংশনে একটিIntentপাস করে অন্য কোনো কম্পোনেন্ট থেকে সার্ভিসটির সাথে বাইন্ড করতে পারেন। আরও তথ্যের জন্য, সার্ভিসেস গাইডটি দেখুন। - একটি সম্প্রচার প্রদান করা
ব্রডকাস্ট হলো এমন একটি বার্তা যা যেকোনো অ্যাপ গ্রহণ করতে পারে। সিস্টেম বিভিন্ন সিস্টেম ইভেন্টের জন্য ব্রডকাস্ট পাঠায়, যেমন যখন সিস্টেম বুট আপ হয় বা ডিভাইস চার্জ হওয়া শুরু করে। আপনি
sendBroadcast()বাsendOrderedBroadcast()ফাংশনে একটিIntentপাস করে অন্যান্য অ্যাপে ব্রডকাস্ট পাঠাতে পারেন।
এই পৃষ্ঠার বাকি অংশে ইনটেন্ট কীভাবে কাজ করে এবং কীভাবে তা ব্যবহার করতে হয়, তা ব্যাখ্যা করা হয়েছে। সম্পর্কিত তথ্যের জন্য, ‘অন্যান্য অ্যাপের সাথে মিথস্ক্রিয়া’ এবং ‘কন্টেন্ট শেয়ার করা’ দেখুন।
অভিপ্রায়ের প্রকারভেদ
দুই ধরনের অভিপ্রায় আছে:
- এক্সপ্লিসিট ইন্টেন্ট একটি সম্পূর্ণ
ComponentNameউল্লেখ করার মাধ্যমে নির্দিষ্ট করে দেয় যে কোন অ্যাপ্লিকেশনের কোন কম্পোনেন্টটি ইন্টেন্টটি পূরণ করবে। আপনি সাধারণত আপনার নিজের অ্যাপের কোনো কম্পোনেন্ট চালু করার জন্য একটি এক্সপ্লিসিট ইন্টেন্ট ব্যবহার করবেন, কারণ আপনি যে অ্যাক্টিভিটি বা সার্ভিসটি চালু করতে চান তার ক্লাস নেম আপনার জানা থাকে। উদাহরণস্বরূপ, আপনি ব্যবহারকারীর কোনো কাজের প্রতিক্রিয়ায় আপনার অ্যাপের মধ্যে একটি নতুন অ্যাক্টিভিটি চালু করতে পারেন, অথবা ব্যাকগ্রাউন্ডে একটি ফাইল ডাউনলোড করার জন্য কোনো সার্ভিস চালু করতে পারেন। - ইমপ্লিসিট ইন্টেন্ট কোনো নির্দিষ্ট কম্পোনেন্টের নাম উল্লেখ করে না, বরং এটি সম্পাদনের জন্য একটি সাধারণ কাজ ঘোষণা করে, যা অন্য কোনো অ্যাপের কম্পোনেন্টকে তা পরিচালনা করার সুযোগ দেয়। উদাহরণস্বরূপ, আপনি যদি ব্যবহারকারীকে মানচিত্রে কোনো অবস্থান দেখাতে চান, তাহলে আপনি একটি ইমপ্লিসিট ইন্টেন্ট ব্যবহার করে অন্য কোনো সক্ষম অ্যাপকে মানচিত্রে সেই নির্দিষ্ট অবস্থানটি দেখানোর জন্য অনুরোধ করতে পারেন।
চিত্র ১-এ দেখানো হয়েছে, একটি অ্যাক্টিভিটি শুরু করার সময় কীভাবে ইন্টেন্ট ব্যবহার করা হয়। যখন Intent অবজেক্টটি স্পষ্টভাবে কোনো নির্দিষ্ট অ্যাক্টিভিটি কম্পোনেন্টের নাম উল্লেখ করে, তখন সিস্টেম অবিলম্বে সেই কম্পোনেন্টটি চালু করে।

চিত্র 1. কিভাবে একটি ইমপ্লিসিট ইন্টেন্ট সিস্টেমের মাধ্যমে অন্য একটি অ্যাক্টিভিটি শুরু করার জন্য পাঠানো হয়: [1] অ্যাক্টিভিটি A একটি অ্যাকশন বর্ণনা সহ একটি Intent তৈরি করে এবং এটি startActivity() তে পাঠায়। [2] অ্যান্ড্রয়েড সিস্টেম ইন্টেন্টের সাথে মেলে এমন একটি ইন্টেন্ট ফিল্টারের জন্য সমস্ত অ্যাপ অনুসন্ধান করে। যখন একটি মিল পাওয়া যায়, [3] সিস্টেম মিলে যাওয়া অ্যাক্টিভিটি ( অ্যাক্টিভিটি B ) শুরু করে তার onCreate() পদ্ধতি কল করে এবং Intent পাঠায়।
যখন আপনি একটি ইমপ্লিসিট ইন্টেন্ট ব্যবহার করেন, তখন অ্যান্ড্রয়েড সিস্টেম ডিভাইসের অন্যান্য অ্যাপের ম্যানিফেস্ট ফাইলে ঘোষিত ইন্টেন্ট ফিল্টারগুলোর সাথে ইন্টেন্টটির বিষয়বস্তু তুলনা করে চালু করার জন্য উপযুক্ত কম্পোনেন্টটি খুঁজে বের করে। যদি ইন্টেন্টটি কোনো ইন্টেন্ট ফিল্টারের সাথে মিলে যায়, তবে সিস্টেম সেই কম্পোনেন্টটি চালু করে এবং সেটিকে Intent অবজেক্টটি সরবরাহ করে। যদি একাধিক ইন্টেন্ট ফিল্টার সামঞ্জস্যপূর্ণ হয়, তবে সিস্টেম একটি ডায়ালগ প্রদর্শন করে যাতে ব্যবহারকারী কোন অ্যাপটি ব্যবহার করবেন তা বেছে নিতে পারেন।
ইনটেন্ট ফিল্টার হলো একটি অ্যাপের ম্যানিফেস্ট ফাইলের একটি এক্সপ্রেশন, যা নির্দিষ্ট করে দেয় যে কম্পোনেন্টটি কোন ধরনের ইনটেন্ট গ্রহণ করতে চায়। উদাহরণস্বরূপ, কোনো অ্যাক্টিভিটির জন্য একটি ইনটেন্ট ফিল্টার ডিক্লেয়ার করার মাধ্যমে, আপনি অন্যান্য অ্যাপকে একটি নির্দিষ্ট ধরনের ইনটেন্ট দিয়ে সরাসরি আপনার অ্যাক্টিভিটিটি চালু করার সুযোগ করে দেন। একইভাবে, যদি আপনি কোনো অ্যাক্টিভিটির জন্য কোনো ইনটেন্ট ফিল্টার ডিক্লেয়ার না করেন, তবে সেটি শুধুমাত্র একটি সুস্পষ্ট ইনটেন্ট দিয়েই চালু করা যাবে।
সতর্কতা: আপনার অ্যাপের নিরাপত্তা নিশ্চিত করতে, একটি Service শুরু করার সময় সর্বদা একটি সুস্পষ্ট ইন্টেন্ট ব্যবহার করুন এবং আপনার সার্ভিসগুলোর জন্য ইন্টেন্ট ফিল্টার ঘোষণা করবেন না। একটি সার্ভিস শুরু করার জন্য অস্পষ্ট ইন্টেন্ট ব্যবহার করা একটি নিরাপত্তা ঝুঁকি, কারণ আপনি নিশ্চিত হতে পারবেন না কোন সার্ভিসটি ইন্টেন্টে সাড়া দেবে, এবং ব্যবহারকারীও দেখতে পারেন না কোন সার্ভিসটি শুরু হচ্ছে। অ্যান্ড্রয়েড ৫.০ (এপিআই লেভেল ২১) থেকে শুরু করে, আপনি যদি একটি অস্পষ্ট ইন্টেন্ট দিয়ে bindService() কল করেন, তাহলে সিস্টেম একটি এক্সেপশন থ্রো করে।
একটি উদ্দেশ্য তৈরি করা
একটি Intent অবজেক্ট এমন তথ্য বহন করে যা অ্যান্ড্রয়েড সিস্টেম কোন কম্পোনেন্টটি চালু করতে হবে তা নির্ধারণ করতে ব্যবহার করে (যেমন সঠিক কম্পোনেন্টের নাম বা কম্পোনেন্ট ক্যাটাগরি যা ইন্টেন্টটি গ্রহণ করবে), এবং সেইসাথে এমন তথ্যও বহন করে যা প্রাপক কম্পোনেন্টটি কাজটি সঠিকভাবে সম্পাদন করার জন্য ব্যবহার করে (যেমন কী কাজ করতে হবে এবং কোন ডেটার উপর ভিত্তি করে কাজ করতে হবে)।
একটি Intent অন্তর্ভুক্ত প্রাথমিক তথ্যগুলো হলো নিম্নরূপ:
- উপাদানের নাম
- যে কম্পোনেন্টটি চালু করতে হবে তার নাম।
এটি ঐচ্ছিক, কিন্তু এটিই সেই গুরুত্বপূর্ণ তথ্য যা একটি ইনটেন্টকে সুস্পষ্ট করে তোলে, যার অর্থ হলো ইনটেন্টটি শুধুমাত্র কম্পোনেন্টের নাম দ্বারা সংজ্ঞায়িত অ্যাপ কম্পোনেন্টেই পাঠানো উচিত। কম্পোনেন্টের নাম ছাড়া, ইনটেন্টটি অস্পষ্ট থাকে এবং সিস্টেম ইনটেন্টের অন্যান্য তথ্যের (যেমন অ্যাকশন, ডেটা এবং ক্যাটাগরি—যা নিচে বর্ণনা করা হয়েছে) উপর ভিত্তি করে সিদ্ধান্ত নেয় কোন কম্পোনেন্টটি ইনটেন্টটি গ্রহণ করবে। আপনার অ্যাপে যদি কোনো নির্দিষ্ট কম্পোনেন্ট চালু করার প্রয়োজন হয়, তবে আপনার কম্পোনেন্টের নামটি উল্লেখ করা উচিত।
দ্রষ্টব্য: কোনো
Serviceচালু করার সময়, সর্বদা কম্পোনেন্টের নামটি উল্লেখ করুন । অন্যথায়, কোন সার্ভিসটি ইন্টেন্টের সাড়া দেবে সে বিষয়ে আপনি নিশ্চিত হতে পারবেন না এবং ব্যবহারকারীও দেখতে পাবেন না কোন সার্ভিসটি চালু হচ্ছে।Intentএর এই ফিল্ডটি একটিComponentNameঅবজেক্ট, যা আপনি টার্গেট কম্পোনেন্টের একটি সম্পূর্ণ ক্লাস নেম ব্যবহার করে নির্দিষ্ট করতে পারেন। এর মধ্যে অ্যাপের প্যাকেজ নেমও অন্তর্ভুক্ত থাকবে, যেমন:com.example.ExampleActivity। আপনিsetComponent(),setClass(),setClassName()অথবাIntentকনস্ট্রাক্টরের মাধ্যমে কম্পোনেন্টের নামটি সেট করতে পারেন। - পদক্ষেপ
- একটি স্ট্রিং যা সম্পাদন করার জন্য সাধারণ ক্রিয়াটি নির্দিষ্ট করে (যেমন দেখা বা বাছাই করা )।
ব্রডকাস্ট ইন্টেন্টের ক্ষেত্রে, এটি হলো সেই কাজটি যা সংঘটিত হয়েছে এবং যার প্রতিবেদন দেওয়া হচ্ছে। এই কাজটিই মূলত নির্ধারণ করে দেয় যে ইন্টেন্টের বাকি অংশটি কীভাবে গঠিত হবে—বিশেষ করে ডেটা এবং এক্সট্রা-এর মধ্যে থাকা তথ্যগুলো।
আপনি আপনার অ্যাপের মধ্যে ইন্টেন্ট ব্যবহারের জন্য (অথবা অন্য অ্যাপ দ্বারা আপনার অ্যাপের কম্পোনেন্ট চালু করার জন্য) নিজস্ব অ্যাকশন নির্দিষ্ট করতে পারেন, কিন্তু সাধারণত আপনি
Intentক্লাস বা অন্যান্য ফ্রেমওয়ার্ক ক্লাস দ্বারা সংজ্ঞায়িত অ্যাকশন কনস্ট্যান্ট নির্দিষ্ট করে থাকেন। একটি অ্যাক্টিভিটি শুরু করার জন্য এখানে কিছু সাধারণ অ্যাকশন দেওয়া হলো:-
ACTION_VIEW - যখন কোনো অ্যাক্টিভিটি ব্যবহারকারীকে দেখানোর মতো কোনো তথ্য আপনার কাছে থাকে, যেমন গ্যালারি অ্যাপে দেখার জন্য কোনো ছবি, বা ম্যাপ অ্যাপে দেখার জন্য কোনো ঠিকানা, তখন একটি ইন্টেন্টের মধ্যে
startActivity()ফাংশনের সাথে এই অ্যাকশনটি ব্যবহার করুন। -
ACTION_SEND - এটি শেয়ার ইন্টেন্ট নামেও পরিচিত। যখন ব্যবহারকারীর শেয়ার করার মতো কোনো ডেটা অন্য কোনো অ্যাপ, যেমন ইমেল অ্যাপ বা সোশ্যাল শেয়ারিং অ্যাপের মাধ্যমে থাকে, তখন
startActivity()সহ একটি ইন্টেন্টের মধ্যে এটি ব্যবহার করা উচিত।
সাধারণ অ্যাকশনগুলো নির্ধারণকারী আরও কনস্ট্যান্টের জন্য
Intentক্লাস রেফারেন্স দেখুন। অন্যান্য অ্যাকশনগুলো অ্যান্ড্রয়েড ফ্রেমওয়ার্কের অন্যত্র সংজ্ঞায়িত করা হয়, যেমন সিস্টেমের সেটিংস অ্যাপে নির্দিষ্ট স্ক্রিন খোলার অ্যাকশনগুলোর জন্যSettingsএ সেগুলো সংজ্ঞায়িত করা থাকে।আপনি
setAction()অথবাIntentকনস্ট্রাক্টরের মাধ্যমে কোনো ইন্টেন্টের অ্যাকশন নির্দিষ্ট করতে পারেন।আপনি যদি নিজের অ্যাকশনগুলো নির্ধারণ করেন, তাহলে অবশ্যই আপনার অ্যাপের প্যাকেজ নামটি প্রিফিক্স হিসেবে অন্তর্ভুক্ত করবেন, যেমনটি নিচের উদাহরণে দেখানো হয়েছে:
কোটলিন
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 টাইপ উল্লেখ করা অ্যান্ড্রয়েড সিস্টেমকে আপনার ইন্টেন্টটি গ্রহণ করার জন্য সেরা কম্পোনেন্টটি খুঁজে পেতে সাহায্য করে। তবে, কখনও কখনও URI থেকে MIME টাইপ অনুমান করা যেতে পারে—বিশেষ করে যখন ডেটাটি একটি
content:URI হয়। একটিcontent:URI নির্দেশ করে যে ডেটাটি ডিভাইসে অবস্থিত এবং একটিContentProviderদ্বারা নিয়ন্ত্রিত, যা ডেটার MIME টাইপকে সিস্টেমের কাছে দৃশ্যমান করে তোলে।শুধুমাত্র ডেটা URI সেট করতে
setData()কল করুন। শুধুমাত্র MIME টাইপ সেট করতেsetType()কল করুন। প্রয়োজনে, আপনিsetDataAndType()ব্যবহার করে উভয়ই স্পষ্টভাবে সেট করতে পারেন।সতর্কতা: আপনি যদি URI এবং MIME টাইপ উভয়ই সেট করতে চান, তাহলে
setData()এবংsetType()কল করবেন না, কারণ এগুলো একে অপরের মান বাতিল করে দেয়। URI এবং MIME টাইপ উভয়ই সেট করার জন্য সর্বদাsetDataAndType()ব্যবহার করুন। - বিভাগ
- একটি স্ট্রিং, যা ইনটেন্টটি কোন ধরনের কম্পোনেন্ট দ্বারা পরিচালিত হবে সে সম্পর্কে অতিরিক্ত তথ্য ধারণ করে। একটি ইনটেন্টে যেকোনো সংখ্যক ক্যাটাগরির বিবরণ রাখা যেতে পারে, কিন্তু বেশিরভাগ ইনটেন্টের জন্য ক্যাটাগরির প্রয়োজন হয় না। এখানে কিছু প্রচলিত ক্যাটাগরি দেওয়া হলো:
-
CATEGORY_BROWSABLE - টার্গেট অ্যাক্টিভিটিটি একটি ওয়েব ব্রাউজার দ্বারা চালু হওয়ার সুযোগ দেয়, যার মাধ্যমে কোনো লিঙ্কের মাধ্যমে নির্দেশিত ডেটা, যেমন একটি ছবি বা একটি ই-মেইল বার্তা, প্রদর্শন করা যায়।
-
CATEGORY_LAUNCHER - এই অ্যাক্টিভিটিটি হলো কোনো টাস্কের প্রাথমিক কার্যকলাপ এবং এটি সিস্টেমের অ্যাপ্লিকেশন লঞ্চারে তালিকাভুক্ত থাকে।
ক্যাটাগরিগুলোর সম্পূর্ণ তালিকার জন্য
Intentক্লাসের বিবরণ দেখুন।আপনি
addCategory()ব্যবহার করে একটি বিভাগ নির্দিষ্ট করতে পারেন। -
উপরে তালিকাভুক্ত এই প্রোপার্টিগুলো (কম্পোনেন্টের নাম, অ্যাকশন, ডেটা এবং ক্যাটাগরি) একটি ইন্টেন্টের প্রধান বৈশিষ্ট্য। এই প্রোপার্টিগুলো পড়ার মাধ্যমে অ্যান্ড্রয়েড সিস্টেম নির্ধারণ করতে পারে যে কোন অ্যাপ কম্পোনেন্টটি চালু করা উচিত। তবে, একটি ইন্টেন্ট অতিরিক্ত তথ্যও বহন করতে পারে, যা অ্যাপ কম্পোনেন্ট হিসেবে এর নির্ধারণ প্রক্রিয়াকে প্রভাবিত করে না। একটি ইন্টেন্ট নিম্নলিখিত তথ্যও সরবরাহ করতে পারে:
- অতিরিক্ত
- কী-ভ্যালু পেয়ার যা অনুরোধকৃত কাজটি সম্পন্ন করার জন্য প্রয়োজনীয় অতিরিক্ত তথ্য বহন করে। যেমন কিছু কাজ নির্দিষ্ট ধরনের ডেটা ইউআরআই ব্যবহার করে, তেমনই কিছু কাজ নির্দিষ্ট অতিরিক্ত বৈশিষ্ট্যও ব্যবহার করে।
আপনি বিভিন্ন
putExtra()মেথড ব্যবহার করে অতিরিক্ত ডেটা যোগ করতে পারেন, যার প্রতিটি দুটি প্যারামিটার গ্রহণ করে: কী-এর নাম এবং ভ্যালু। এছাড়াও আপনি সমস্ত অতিরিক্ত ডেটা দিয়ে একটিBundleঅবজেক্ট তৈরি করতে পারেন, এবং তারপরputExtras()ব্যবহার করেIntentএBundleইনসার্ট করতে পারেন।উদাহরণস্বরূপ,
ACTION_SENDব্যবহার করে ইমেল পাঠানোর জন্য একটি ইন্টেন্ট তৈরি করার সময়, আপনিEXTRA_EMAILকী ব্যবহার করে প্রাপক এবংEXTRA_SUBJECTকী ব্যবহার করে বিষয় নির্দিষ্ট করতে পারেন।Intentক্লাসটি প্রমিত ডেটা টাইপগুলোর জন্য অনেকEXTRA_*কনস্ট্যান্ট নির্দিষ্ট করে। আপনার অ্যাপে আসা ইন্টেন্টগুলোর জন্য যদি নিজস্ব অতিরিক্ত কী (key) ঘোষণা করার প্রয়োজন হয়, তবে অবশ্যই আপনার অ্যাপের প্যাকেজ নামটি প্রিফিক্স হিসেবে অন্তর্ভুক্ত করবেন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:কোটলিন
const val EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS"
জাভা
static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";
সতর্কতা : এমন কোনো ইন্টেন্ট পাঠানোর সময়
ParcelableবাSerializableডেটা ব্যবহার করবেন না, যা অন্য কোনো অ্যাপ গ্রহণ করবে বলে আপনি আশা করেন। যদি কোনো অ্যাপ একটিBundleঅবজেক্টের ডেটা অ্যাক্সেস করার চেষ্টা করে কিন্তু সেই পার্সেল করা বা সিরিয়ালাইজ করা ক্লাসে তার অ্যাক্সেস না থাকে, তাহলে সিস্টেম একটিRuntimeExceptionতৈরি করে। - পতাকা
-
Intentক্লাসে ফ্ল্যাগ সংজ্ঞায়িত করা হয়, যা ইন্টেন্টের মেটাডেটা হিসেবে কাজ করে। এই ফ্ল্যাগগুলো অ্যান্ড্রয়েড সিস্টেমকে নির্দেশ দিতে পারে যে, কীভাবে একটি অ্যাক্টিভিটি চালু করতে হবে (যেমন, অ্যাক্টিভিটিটি কোন টাস্কের অন্তর্ভুক্ত হবে) এবং চালু হওয়ার পরে সেটির সাথে কেমন আচরণ করতে হবে (যেমন, এটি সাম্প্রতিক অ্যাক্টিভিটির তালিকায় থাকবে কি না)।আরও তথ্যের জন্য
setFlags()পদ্ধতিটি দেখুন।
সুস্পষ্ট অভিপ্রায়ের উদাহরণ
এক্সপ্লিসিট ইন্টেন্ট হলো এমন একটি ইন্টেন্ট যা আপনি আপনার অ্যাপের কোনো নির্দিষ্ট কম্পোনেন্ট, যেমন কোনো বিশেষ অ্যাক্টিভিটি বা সার্ভিস চালু করতে ব্যবহার করেন। একটি এক্সপ্লিসিট ইন্টেন্ট তৈরি করতে, Intent অবজেক্টের জন্য কম্পোনেন্টের নামটি নির্ধারণ করুন—ইন্টেন্টের অন্যান্য সমস্ত প্রোপার্টি ঐচ্ছিক।
উদাহরণস্বরূপ, যদি আপনি আপনার অ্যাপে DownloadService নামে একটি সার্ভিস তৈরি করেন, যা ওয়েব থেকে একটি ফাইল ডাউনলোড করার জন্য ডিজাইন করা হয়েছে, তাহলে আপনি নিম্নলিখিত কোড দিয়ে এটি চালু করতে পারেন:
কোটলিন
// Executed in an Activity, so 'this' is theContext// 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 theContext// 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() কল করবেন, তখন ব্যবহারকারী কন্টেন্টটি শেয়ার করার জন্য একটি অ্যাপ বেছে নিতে পারবেন।
কোটলিন
// 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() মেথডে পাস করা Intent-এ সাড়া দেওয়া অ্যাপগুলোর একটি তালিকা থাকে এবং সরবরাহ করা টেক্সটটি ডায়ালগের শিরোনাম হিসেবে ব্যবহৃত হয়।
কোটলিন
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); }
অনিরাপদ অভিপ্রায় লঞ্চ সনাক্ত করুন
আপনার অ্যাপ তার ভেতরের কম্পোনেন্টগুলোর মধ্যে নেভিগেট করতে, অথবা অন্য কোনো অ্যাপের হয়ে কোনো কাজ সম্পাদন করতে ইন্টেন্ট চালু করতে পারে। প্ল্যাটফর্মের নিরাপত্তা উন্নত করার জন্য, অ্যান্ড্রয়েড ১২ (এপিআই লেভেল ৩১) এবং এর পরবর্তী সংস্করণগুলোতে একটি ডিবাগিং ফিচার রয়েছে, যা আপনার অ্যাপ কোনো ইন্টেন্ট অনিরাপদভাবে চালু করলে আপনাকে সতর্ক করে। উদাহরণস্বরূপ, আপনার অ্যাপ একটি নেস্টেড ইন্টেন্ট অনিরাপদভাবে চালু করতে পারে, যা হলো এমন একটি ইন্টেন্ট যাকে অন্য একটি ইন্টেন্টের মধ্যে এক্সট্রা হিসেবে পাস করা হয়।
যদি আপনার অ্যাপ নিম্নলিখিত উভয় কাজই করে, তাহলে সিস্টেম একটি অনিরাপদ ইন্টেন্ট লঞ্চ শনাক্ত করে এবং একটি StrictMode লঙ্ঘন ঘটে:
- আপনার অ্যাপ একটি ডেলিভার করা ইন্টেন্টের এক্সট্রাগুলো থেকে একটি নেস্টেড ইন্টেন্টকে আনপার্সেল করে।
- আপনার অ্যাপ সেই নেস্টেড ইন্টেন্টটি ব্যবহার করে অবিলম্বে একটি অ্যাপ কম্পোনেন্ট চালু করে, যেমন
startActivity(),startService(), বাbindService()-এর মধ্যে ইন্টেন্টটি পাস করার মাধ্যমে।
এই পরিস্থিতিটি কীভাবে শনাক্ত করবেন এবং আপনার অ্যাপে কী পরিবর্তন আনবেন, সে সম্পর্কে আরও বিস্তারিত জানতে মিডিয়ামে অ্যান্ড্রয়েড নেস্টিং ইনটেন্টস (Android Nesting Intents) বিষয়ক ব্লগ পোস্টটি পড়ুন।
অনিরাপদ ইনটেন্ট লঞ্চের জন্য পরীক্ষা করুন
আপনার অ্যাপে অনিরাপদ ইন্টেন্ট লঞ্চ হচ্ছে কিনা তা পরীক্ষা করতে, আপনার VmPolicy কনফিগার করার সময় detectUnsafeIntentLaunch() কল করুন, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে। যদি আপনার অ্যাপ StrictMode লঙ্ঘন শনাক্ত করে, তাহলে সম্ভাব্য সংবেদনশীল তথ্য সুরক্ষিত রাখতে আপনি অ্যাপটি চালানো বন্ধ করে দিতে পারেন।
কোটলিন
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()); }
ইনটেন্ট আরও দায়িত্বশীলভাবে ব্যবহার করুন
অনিরাপদ ইনটেন্ট লঞ্চ এবং স্ট্রিক্টমোড লঙ্ঘনের সম্ভাবনা কমাতে, এই সর্বোত্তম অনুশীলনগুলো অনুসরণ করুন।
ইন্টেন্টের মধ্যে শুধুমাত্র অপরিহার্য এক্সট্রাগুলো কপি করুন এবং প্রয়োজনীয় স্যানিটেশন ও ভ্যালিডেশন সম্পন্ন করুন। আপনার অ্যাপ একটি নতুন কম্পোনেন্ট চালু করার জন্য ব্যবহৃত অন্য একটি ইন্টেন্টে এক্সট্রাগুলো কপি করতে পারে। এটি ঘটে যখন আপনার অ্যাপ putExtras(Intent) বা putExtras(Bundle) কল করে। যদি আপনার অ্যাপ এই অপারেশনগুলোর মধ্যে একটি সম্পাদন করে, তবে শুধুমাত্র সেই এক্সট্রাগুলো কপি করুন যা গ্রহণকারী কম্পোনেন্টটি আশা করে। যদি অন্য ইন্টেন্টটি (যেটি কপিটি গ্রহণ করে) এমন একটি কম্পোনেন্ট চালু করে যা এক্সপোর্ট করা হয়নি, তবে কম্পোনেন্টটি চালুকারী ইন্টেন্টে এক্সট্রাগুলো কপি করার আগে সেগুলোকে স্যানিটাইজ এবং ভ্যালিডেট করুন।
আপনার অ্যাপের কম্পোনেন্টগুলো অপ্রয়োজনীয়ভাবে এক্সপোর্ট করবেন না। উদাহরণস্বরূপ, যদি আপনি একটি অভ্যন্তরীণ নেস্টেড ইন্টেন্ট ব্যবহার করে কোনো অ্যাপ কম্পোনেন্ট চালু করতে চান, তাহলে সেই কম্পোনেন্টের android:exported অ্যাট্রিবিউটটি false সেট করুন।
নেস্টেড ইন্টেন্টের পরিবর্তে একটি PendingIntent ব্যবহার করুন। এর ফলে, যখন অন্য কোনো অ্যাপ তার ধারণকারী Intent PendingIntent আনপার্সেল করে, তখন সেই অ্যাপটি আপনার অ্যাপের আইডেন্টিটি ব্যবহার করে PendingIntent চালু করতে পারে। এই কনফিগারেশনটি অন্য অ্যাপটিকে আপনার অ্যাপের যেকোনো কম্পোনেন্ট, এমনকি নন-এক্সপোর্টেড কম্পোনেন্টও, নিরাপদে চালু করার সুযোগ দেয়।
চিত্র ২-এর ডায়াগ্রামটি দেখায়, কীভাবে সিস্টেমটি আপনার (ক্লায়েন্ট) অ্যাপ থেকে অন্য একটি (সার্ভিস) অ্যাপে এবং আবার আপনার অ্যাপে নিয়ন্ত্রণ হস্তান্তর করে:
- আপনার অ্যাপ একটি ইন্টেন্ট তৈরি করে যা অন্য একটি অ্যাপের একটি অ্যাক্টিভিটি চালু করে। সেই ইন্টেন্টের মধ্যে, আপনি একটি
PendingIntentঅবজেক্টকে এক্সট্রা হিসেবে যোগ করেন। এই পেন্ডিং ইন্টেন্টটি আপনার অ্যাপের একটি কম্পোনেন্ট চালু করে; এই কম্পোনেন্টটি এক্সপোর্ট করা নয়। - আপনার অ্যাপের ইন্টেন্ট পাওয়ার পর, অন্য অ্যাপটি নেস্টেড
PendingIntentঅবজেক্টটি এক্সট্র্যাক্ট করে। - অপর অ্যাপটি
PendingIntentঅবজেক্টেরsend()মেথডটি কল করে। - আপনার অ্যাপে নিয়ন্ত্রণ ফিরিয়ে দেওয়ার পর, সিস্টেম আপনার অ্যাপের কনটেক্সট ব্যবহার করে অপেক্ষাধীন ইন্টেন্টটি আহ্বান করে।
চিত্র ২. নেস্টেড পেন্ডিং ইন্টেন্ট ব্যবহার করার সময় অ্যাপগুলোর মধ্যকার যোগাযোগের ডায়াগ্রাম।
একটি অন্তর্নিহিত অভিপ্রায় গ্রহণ করা
আপনার অ্যাপ কোন কোন ইমপ্লিসিট ইন্টেন্ট গ্রহণ করতে পারবে তা জানানোর জন্য, আপনার ম্যানিফেস্ট ফাইলে একটি <intent-filter> এলিমেন্ট ব্যবহার করে অ্যাপের প্রতিটি কম্পোনেন্টের জন্য এক বা একাধিক ইন্টেন্ট ফিল্টার ডিক্লেয়ার করুন। প্রতিটি ইন্টেন্ট ফিল্টার, ইন্টেন্টের অ্যাকশন, ডেটা এবং ক্যাটাগরির উপর ভিত্তি করে এটি কোন ধরনের ইন্টেন্ট গ্রহণ করবে তা নির্দিষ্ট করে। সিস্টেম আপনার অ্যাপ কম্পোনেন্টে একটি ইমপ্লিসিট ইন্টেন্ট তখনই ডেলিভার করে, যখন ইন্টেন্টটি আপনার কোনো একটি ইন্টেন্ট ফিল্টারের মধ্য দিয়ে যেতে পারে।
দ্রষ্টব্য: কম্পোনেন্টটি কোনো ইনটেন্ট ফিল্টার ঘোষণা করলেও, একটি সুস্পষ্ট ইনটেন্ট সর্বদা তার টার্গেটে পৌঁছে দেওয়া হয়।
একটি অ্যাপ কম্পোনেন্টের প্রতিটি স্বতন্ত্র কাজের জন্য আলাদা ফিল্টার ঘোষণা করা উচিত। উদাহরণস্বরূপ, একটি ইমেজ গ্যালারি অ্যাপের একটি অ্যাক্টিভিটিতে দুটি ফিল্টার থাকতে পারে: একটি ছবি দেখার জন্য এবং অন্যটি ছবি সম্পাদনা করার জন্য। অ্যাক্টিভিটি শুরু হলে, এটি Intent পরীক্ষা করে এবং Intent তথ্যের উপর ভিত্তি করে এর আচরণ কেমন হবে তা স্থির করে (যেমন এডিটর কন্ট্রোলগুলো দেখানো হবে কি না)।
প্রতিটি ইনটেন্ট ফিল্টার অ্যাপের ম্যানিফেস্ট ফাইলে একটি <intent-filter> এলিমেন্ট দ্বারা সংজ্ঞায়িত করা হয়, যা সংশ্লিষ্ট অ্যাপ কম্পোনেন্টের (যেমন একটি <activity> এলিমেন্ট) ভিতরে নেস্ট করা থাকে।
প্রতিটি অ্যাপ কম্পোনেন্টে, যেখানে একটি <intent-filter> এলিমেন্ট অন্তর্ভুক্ত আছে, সেখানে android:exported এর জন্য স্পষ্টভাবে একটি মান সেট করুন। এই অ্যাট্রিবিউটটি নির্দেশ করে যে অ্যাপ কম্পোনেন্টটি অন্যান্য অ্যাপের কাছে অ্যাক্সেসযোগ্য কিনা। কিছু পরিস্থিতিতে, যেমন যেসব অ্যাক্টিভিটির ইন্টেন্ট ফিল্টারে LAUNCHER ক্যাটাগরি অন্তর্ভুক্ত থাকে, সেখানে এই অ্যাট্রিবিউটটি true সেট করা সুবিধাজনক। অন্যথায়, এই অ্যাট্রিবিউটটি false সেট করাই বেশি নিরাপদ।
সতর্কীকরণ: যদি আপনার অ্যাপের কোনো অ্যাক্টিভিটি, সার্ভিস বা ব্রডকাস্ট রিসিভার ইন্টেন্ট ফিল্টার ব্যবহার করে এবং android:exported এর ভ্যালু স্পষ্টভাবে সেট না করে, তাহলে আপনার অ্যাপটি অ্যান্ড্রয়েড ১২ বা তার উচ্চতর সংস্করণের কোনো ডিভাইসে ইনস্টল করা যাবে না।
<intent-filter> এর ভিতরে, আপনি এই তিনটি উপাদানের এক বা একাধিক ব্যবহার করে কোন ধরনের ইন্টেন্ট গ্রহণ করবেন তা নির্দিষ্ট করতে পারেন:
-
<action> -
nameঅ্যাট্রিবিউটে ইনটেন্ট অ্যাকশনটি গৃহীত হয়েছে বলে ঘোষণা করা হয়। এর ভ্যালুটি অবশ্যই কোনো অ্যাকশনের আক্ষরিক স্ট্রিং ভ্যালু হতে হবে, কোনো ক্লাস কনস্ট্যান্ট নয়। -
<data> - এক বা একাধিক অ্যাট্রিবিউট ব্যবহার করে গৃহীত ডেটার ধরন ঘোষণা করা হয়, যেগুলো ডেটা ইউআরআই (
scheme,host,port,path) এবং মাইম টাইপের বিভিন্ন দিক নির্দিষ্ট করে। -
<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> এর একাধিক ইনস্ট্যান্স অন্তর্ভুক্ত থাকে। যদি আপনি তা করেন, তবে আপনাকে নিশ্চিত করতে হবে যে কম্পোনেন্টটি ঐ ফিল্টার উপাদানগুলির যেকোনো এবং সমস্ত সংমিশ্রণ পরিচালনা করতে সক্ষম।
যখন আপনি একাধিক ধরনের ইনটেন্ট পরিচালনা করতে চান, কিন্তু শুধুমাত্র অ্যাকশন, ডেটা এবং ক্যাটাগরি টাইপের নির্দিষ্ট সংমিশ্রণে, তখন আপনাকে একাধিক ইনটেন্ট ফিল্টার তৈরি করতে হবে।
একটি ইমপ্লিসিট ইন্টেন্টকে তিনটি উপাদানের প্রতিটির সাথে তুলনা করে একটি ফিল্টারের বিপরীতে পরীক্ষা করা হয়। কম্পোনেন্টে ডেলিভার হওয়ার জন্য, ইন্টেন্টটিকে অবশ্যই তিনটি পরীক্ষাতেই উত্তীর্ণ হতে হবে। যদি এটি সেগুলোর মধ্যে একটির সাথেও মিলতে ব্যর্থ হয়, তবে অ্যান্ড্রয়েড সিস্টেম ইন্টেন্টটিকে কম্পোনেন্টে ডেলিভার করবে না। তবে, যেহেতু একটি কম্পোনেন্টের একাধিক ইন্টেন্ট ফিল্টার থাকতে পারে, তাই একটি ইন্টেন্ট যা কম্পোনেন্টের কোনো একটি ফিল্টারে উত্তীর্ণ হতে পারে না, সেটি অন্য কোনো ফিল্টারে উত্তীর্ণ হয়ে যেতে পারে। সিস্টেম কীভাবে ইন্টেন্টগুলো সমাধান করে সে সম্পর্কে আরও তথ্য নিচের 'ইন্টেন্ট রেজোলিউশন' বিভাগে দেওয়া আছে।
সতর্কতা: অন্য অ্যাপকে আপনার কম্পোনেন্ট চালু করা থেকে বিরত রাখার জন্য ইন্টেন্ট ফিল্টার ব্যবহার করা কোনো নিরাপদ উপায় নয়। যদিও ইন্টেন্ট ফিল্টার একটি কম্পোনেন্টকে শুধুমাত্র নির্দিষ্ট ধরনের ইমপ্লিসিট ইন্টেন্টে সাড়া দিতে সীমাবদ্ধ করে, কিন্তু ডেভেলপার যদি আপনার কম্পোনেন্টের নামগুলো নির্ধারণ করতে পারে, তবে অন্য কোনো অ্যাপ একটি এক্সপ্লিসিট ইন্টেন্ট ব্যবহার করে আপনার অ্যাপ কম্পোনেন্টটি চালু করে দিতে পারে। যদি এটা গুরুত্বপূর্ণ হয় যে শুধুমাত্র আপনার নিজের অ্যাপই আপনার কোনো একটি কম্পোনেন্ট চালু করতে পারবে, তাহলে আপনার ম্যানিফেস্টে ইন্টেন্ট ফিল্টার ঘোষণা করবেন না। এর পরিবর্তে, সেই কম্পোনেন্টের জন্য 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 , হলো একটি বিশেষ ডেটা টাইপ যা প্যানোরামিক ছবি নির্দিষ্ট করে, এবং আপনি গুগল প্যানোরামা এপিআই (API) ব্যবহার করে এটি পরিচালনা করতে পারেন।
অন্যান্য অ্যাপের ইন্টেন্ট ফিল্টারের সাথে ইন্টেন্টগুলো মেলান।
যদি অন্য কোনো অ্যাপ অ্যান্ড্রয়েড ১৩ (এপিআই লেভেল ৩৩) বা তার উচ্চতর সংস্করণকে টার্গেট করে, তবে সেটি আপনার অ্যাপের ইন্টেন্টটি কেবল তখনই হ্যান্ডেল করতে পারবে, যদি আপনার ইন্টেন্টটি সেই অন্য অ্যাপের একটি <intent-filter> এলিমেন্টের অ্যাকশন এবং ক্যাটাগরির সাথে মিলে যায়। যদি সিস্টেম কোনো মিল খুঁজে না পায়, তবে এটি একটি ActivityNotFoundException থ্রো করে। প্রেরক অ্যাপটিকে অবশ্যই এই এক্সেপশনটি হ্যান্ডেল করতে হবে।
একইভাবে, আপনি যদি আপনার অ্যাপটিকে অ্যান্ড্রয়েড ১৩ বা তার উচ্চতর সংস্করণকে টার্গেট করে আপডেট করেন, তাহলে বাইরের অ্যাপ থেকে আসা সমস্ত ইন্টেন্ট আপনার অ্যাপের কোনো এক্সপোর্টেড কম্পোনেন্টে তখনই ডেলিভার করা হবে, যদি সেই ইন্টেন্টটি আপনার অ্যাপ দ্বারা ঘোষিত কোনো <intent-filter> এলিমেন্টের অ্যাকশন এবং ক্যাটাগরির সাথে মিলে যায়। প্রেরক অ্যাপের টার্গেট SDK ভার্সন নির্বিশেষে এই আচরণটি ঘটে থাকে।
নিম্নলিখিত ক্ষেত্রগুলিতে ইনটেন্ট ম্যাচিং বলবৎ করা হয় না:
- যেসব কম্পোনেন্ট কোনো ইনটেন্ট ফিল্টার ঘোষণা করে না, সেগুলোতে ইনটেন্ট প্রেরণ করা হয়।
- একই অ্যাপের ভেতর থেকে উদ্ভূত ইনটেন্ট।
- সিস্টেম থেকে উদ্ভূত ইন্টেন্ট; অর্থাৎ, 'সিস্টেম ইউআইডি' (uid=1000) থেকে পাঠানো ইন্টেন্ট। সিস্টেম অ্যাপের মধ্যে
system_serverএবং সেইসব অ্যাপ অন্তর্ভুক্ত, যেগুলোandroid:sharedUserIdandroid.uid.systemএ সেট করে। - মূল থেকে উদ্ভূত অভিপ্রায়।
ইনটেন্ট ম্যাচিং সম্পর্কে আরও জানুন।
একটি অপেক্ষাধীন অভিপ্রায় ব্যবহার করে
একটি PendingIntent অবজেক্ট হলো একটি Intent অবজেক্টের র্যাপার। একটি PendingIntent এর প্রধান উদ্দেশ্য হলো অন্য কোনো অ্যাপ্লিকেশনকে এর অন্তর্ভুক্ত Intent ব্যবহার করার অনুমতি দেওয়া, যেন সেটি আপনার অ্যাপের নিজস্ব প্রসেস থেকে এক্সিকিউট করা হচ্ছে।
পেন্ডিং ইন্টেন্টের প্রধান ব্যবহারগুলো নিম্নরূপ:
- ব্যবহারকারী আপনার নোটিফিকেশন ব্যবহার করে কোনো কাজ করলে যে ইন্টেন্টটি কার্যকর হবে, তা ঘোষণা করা (অ্যান্ড্রয়েড সিস্টেমের
NotificationManagerIntentকার্যকর করে)। - ব্যবহারকারী যখন আপনার অ্যাপ উইজেট দিয়ে কোনো কাজ করেন, তখন কার্যকর হওয়ার জন্য একটি ইন্টেন্ট ঘোষণা করা (হোম স্ক্রিন অ্যাপটি
Intentকার্যকর করে)। - ভবিষ্যতের একটি নির্দিষ্ট সময়ে কার্যকর করার জন্য একটি ইন্টেন্ট ঘোষণা করা (অ্যান্ড্রয়েড সিস্টেমের
AlarmManagerIntentকার্যকর করে)।
ঠিক যেমন প্রতিটি Intent অবজেক্ট একটি নির্দিষ্ট ধরণের অ্যাপ কম্পোনেন্ট (যেমন Activity , Service , বা BroadcastReceiver ) দ্বারা হ্যান্ডেল করার জন্য ডিজাইন করা হয়, তেমনি একটি PendingIntent একই বিবেচনায় তৈরি করতে হবে। একটি পেন্ডিং ইন্টেন্ট ব্যবহার করার সময়, আপনার অ্যাপ startActivity() এর মতো কোনো কলের মাধ্যমে ইন্টেন্টটি এক্সিকিউট করে না। এর পরিবর্তে, PendingIntent তৈরি করার সময় আপনাকে অবশ্যই সংশ্লিষ্ট creator মেথডটি কল করে উদ্দিষ্ট কম্পোনেন্ট টাইপটি ডিক্লেয়ার করতে হবে।
- যে
IntentএকটিActivityশুরু করে, তার জন্যPendingIntent.getActivity()হয়। - যে
IntentএকটিServiceচালু করে, তার জন্যPendingIntent.getService()করা হয়। - যে
IntentএকটিBroadcastReceiverচালু করে, তার জন্যPendingIntent.getBroadcast()করা হয়।
যদি আপনার অ্যাপ অন্য অ্যাপ থেকে পেন্ডিং ইন্টেন্ট গ্রহণ না করে , তাহলে PendingIntent PendingIntent তৈরি করার জন্য উপরের পদ্ধতিগুলোই সম্ভবত আপনার প্রয়োজনীয় একমাত্র পদ্ধতি।
প্রতিটি মেথড বর্তমান অ্যাপ Context , যে Intent আপনি র্যাপ করতে চান, এবং এক বা একাধিক ফ্ল্যাগ গ্রহণ করে, যা নির্দিষ্ট করে দেয় ইনটেন্টটি কীভাবে ব্যবহার করা হবে (যেমন ইনটেন্টটি একাধিকবার ব্যবহার করা যাবে কি না)।
পেন্ডিং ইন্টেন্ট ব্যবহার সম্পর্কে আরও তথ্যের জন্য, নোটিফিকেশন এবং অ্যাপ উইজেট এপিআই গাইডের মতো প্রতিটি সংশ্লিষ্ট ব্যবহারের ক্ষেত্রের ডকুমেন্টেশন দেখুন।
পরিবর্তনশীলতা নির্দিষ্ট করুন
আপনার অ্যাপটি যদি অ্যান্ড্রয়েড ১২ বা তার উচ্চতর সংস্করণকে টার্গেট করে, তবে আপনার অ্যাপের তৈরি করা প্রতিটি PendingIntent অবজেক্টের পরিবর্তনযোগ্যতা (mutability) অবশ্যই নির্দিষ্ট করে দিতে হবে। কোনো একটি PendingIntent অবজেক্ট পরিবর্তনযোগ্য (mutable) নাকি অপরিবর্তনযোগ্য (immutable) তা ঘোষণা করতে, যথাক্রমে 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.
যখনই সম্ভব অপরিবর্তনীয় পেন্ডিং ইন্টেন্ট তৈরি করুন।
বেশিরভাগ ক্ষেত্রে, আপনার অ্যাপের অপরিবর্তনীয় (immutable) PendingIntent অবজেক্ট তৈরি করা উচিত, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে। যদি একটি PendingIntent অবজেক্ট অপরিবর্তনীয় হয়, তাহলে অন্য অ্যাপগুলো ইন্টেন্টটি কল করার ফলাফল পরিবর্তন করার জন্য সেটিকে পরিবর্তন করতে পারে না।
কোটলিন
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এর ইনস্ট্যান্স ব্যবহার করে অ্যান্ড্রয়েড অটো ফ্রেমওয়ার্কের সাথে নোটিফিকেশন যুক্ত করা। -
PendingIntentএর ইনস্ট্যান্স ব্যবহার করে কথোপকথনগুলোকে বাবলের মধ্যে রাখা হয়। একটি পরিবর্তনযোগ্যPendingIntentঅবজেক্ট সিস্টেমকে সঠিক ফ্ল্যাগগুলো, যেমনFLAG_ACTIVITY_MULTIPLE_TASKএবংFLAG_ACTIVITY_NEW_DOCUMENT, প্রয়োগ করার সুযোগ দেয়। -
requestLocationUpdates()বা অনুরূপ API কল করে ডিভাইসের অবস্থানের তথ্য অনুরোধ করা হয়। পরিবর্তনযোগ্যPendingIntentঅবজেক্টটি সিস্টেমকে ইন্টেন্ট এক্সট্রা যোগ করার সুযোগ দেয়, যা অবস্থানের জীবনচক্রের ঘটনাগুলোকে উপস্থাপন করে। এই ঘটনাগুলোর মধ্যে রয়েছে অবস্থানের পরিবর্তন এবং কোনো প্রোভাইডারের উপলব্ধ হওয়া। -
AlarmManagerব্যবহার করে অ্যালার্ম শিডিউল করা হয়। পরিবর্তনযোগ্যPendingIntentঅবজেক্টটি সিস্টেমকেEXTRA_ALARM_COUNTইন্টেন্ট এক্সট্রা যোগ করার সুযোগ দেয়। এই এক্সট্রাটি নির্দেশ করে যে একটি পুনরাবৃত্তিমূলক অ্যালার্ম কতবার ট্রিগার হয়েছে। এই এক্সট্রাটি অন্তর্ভুক্ত করার মাধ্যমে, ইন্টেন্টটি কোনো অ্যাপকে নির্ভুলভাবে জানাতে পারে যে একটি পুনরাবৃত্তিমূলক অ্যালার্ম একাধিকবার ট্রিগার হয়েছে কিনা, যেমন যখন ডিভাইসটি স্লিপ মোডে ছিল।
আপনার অ্যাপ যদি একটি পরিবর্তনযোগ্য PendingIntent অবজেক্ট তৈরি করে, তবে একটি সুস্পষ্ট ইন্টেন্ট ব্যবহার করার এবং ComponentName পূরণ করার জন্য দৃঢ়ভাবে সুপারিশ করা হচ্ছে। এর ফলে, যখনই অন্য কোনো অ্যাপ PendingIntent কল করবে এবং নিয়ন্ত্রণ আপনার অ্যাপে ফিরিয়ে দেবে, আপনার অ্যাপের সেই একই কম্পোনেন্টটি সর্বদা চালু হবে।
পেন্ডিং ইনটেন্টের মধ্যে সুস্পষ্ট ইনটেন্ট ব্যবহার করুন
অন্যান্য অ্যাপগুলো আপনার অ্যাপের পেন্ডিং ইন্টেন্টগুলো কীভাবে ব্যবহার করতে পারবে তা আরও ভালোভাবে সংজ্ঞায়িত করতে, সর্বদা একটি পেন্ডিং ইন্টেন্টকে একটি সুস্পষ্ট ইন্টেন্টের মধ্যে রাখুন। এই সর্বোত্তম অনুশীলনটি অনুসরণ করতে, নিম্নলিখিত কাজগুলো করুন:
- বেস ইন্টেন্টের অ্যাকশন, প্যাকেজ এবং কম্পোনেন্ট ফিল্ডগুলো সেট করা আছে কিনা তা যাচাই করুন।
পেন্ডিং ইন্টেন্ট তৈরি করতে অ্যান্ড্রয়েড ৬.০ (এপিআই লেভেল ২৩)-এ যুক্ত হওয়া
FLAG_IMMUTABLEব্যবহার করুন। এই ফ্ল্যাগটিPendingIntentগ্রহণকারী অ্যাপগুলোকে অপূরিত প্রোপার্টিগুলো পূরণ করা থেকে বিরত রাখে। যদি আপনার অ্যাপেরminSdkVersion22বা তার কম হয়, তাহলে আপনি নিম্নলিখিত কোডটি ব্যবহার করে সুরক্ষা এবং সামঞ্জস্যতা একসাথে নিশ্চিত করতে পারেন: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>
For an intent to pass the category test, every category in the Intent must match a category in the filter. The reverse is not necessary—the intent filter may declare more categories than are specified in the Intent and the Intent still passes. Therefore, an intent with no categories always passes this test, regardless of what categories are declared in the filter.
Note: Android automatically applies the CATEGORY_DEFAULT category to all implicit intents passed to startActivity() and startActivityForResult() . If you want your activity to receive implicit intents, it must include a category for "android.intent.category.DEFAULT" in its intent filters, as shown in the previous <intent-filter> example.
Data test
To specify accepted intent data, an intent filter can declare zero or more <data> elements, as shown in the following example:
<intent-filter> <data android:mimeType="video/mpeg" android:scheme="http" ... /> <data android:mimeType="audio/mpeg" android:scheme="http" ... /> ... </intent-filter>
Each <data> element can specify a URI structure and a data type (MIME media type). Each part of the URI is a separate attribute: scheme , host , port , and path :
<scheme>://<host>:<port>/<path>
The following example shows possible values for these attributes:
content://com.example.project:200/folder/subfolder/etc
In this URI, the scheme is content , the host is com.example.project , the port is 200 , and the path is folder/subfolder/etc .
Each of these attributes is optional in a <data> element, but there are linear dependencies:
- If a scheme is not specified, the host is ignored.
- If a host is not specified, the port is ignored.
- If both the scheme and host are not specified, the path is ignored.
When the URI in an intent is compared to a URI specification in a filter, it's compared only to the parts of the URI included in the filter. For example:
- If a filter specifies only a scheme, all URIs with that scheme match the filter.
- If a filter specifies a scheme and an authority but no path, all URIs with the same scheme and authority pass the filter, regardless of their paths.
- If a filter specifies a scheme, an authority, and a path, only URIs with the same scheme, authority, and path pass the filter.
Note: A path specification can contain a wildcard asterisk (*) to require only a partial match of the path name.
The data test compares both the URI and the MIME type in the intent to a URI and MIME type specified in the filter. The rules are as follows:
- An intent that contains neither a URI nor a MIME type passes the test only if the filter does not specify any URIs or MIME types.
- An intent that contains a URI but no MIME type (neither explicit nor inferable from the URI) passes the test only if its URI matches the filter's URI format and the filter likewise does not specify a MIME type.
- An intent that contains a MIME type but not a URI passes the test only if the filter lists the same MIME type and does not specify a URI format.
- An intent that contains both a URI and a MIME type (either explicit or inferable from the URI) passes the MIME type part of the test only if that type matches a type listed in the filter. It passes the URI part of the test either if its URI matches a URI in the filter or if it has a
content:orfile:URI and the filter does not specify a URI. In other words, a component is presumed to supportcontent:andfile:data if its filter lists only a MIME type.
Note: If an intent specifies a URI or MIME type, the data test will fail if there are no <data> elements in the <intent-filter> .
This last rule, rule (d), reflects the expectation that components are able to get local data from a file or content provider. Therefore, their filters can list just a data type and don't need to explicitly name the content: and file: schemes. The following example shows a typical case in which a <data> element tells Android that the component can get image data from a content provider and display it:
<intent-filter> <data android:mimeType="image/*" /> ... </intent-filter>
Filters that specify a data type but not a URI are perhaps the most common because most available data is dispensed by content providers.
Another common configuration is a filter with a scheme and a data type. For example, a <data> element like the following tells Android that the component can retrieve video data from the network in order to perform the action:
<intent-filter> <data android:scheme="http" android:mimeType="video/*" /> ... </intent-filter>
Intent matching
Intents are matched against intent filters not only to discover a target component to activate, but also to discover something about the set of components on the device. For example, the Home app populates the app launcher by finding all the activities with intent filters that specify the ACTION_MAIN action and CATEGORY_LAUNCHER category. A match is only successful if the actions and categories in the Intent match against the filter, as described in the documentation for the IntentFilter class.
Your application can use intent matching in a manner similar to what the Home app does. The PackageManager has a set of query...() methods that return all components that can accept a particular intent and a similar series of resolve...() methods that determine the best component to respond to an intent. For example, queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument, and queryIntentServices() returns a similar list of services. Neither method activates the components; they just list the ones that can respond. There's a similar method, queryBroadcastReceivers() , for broadcast receivers.