آشنایی با کلاس اینتنت(Intent) و فیلتر(Filter) در اندروید

intent به عنوان یک شی از کلاس Intent ساخته می شود و دارای ساختار داده ایی غیر فعال می باشد که توصیف انتزاعی از یک عملیات را در خود نگه می دارد.

برای مثال فرض می کنیم شما یک اکتیویتی دارید که نیاز دارد با یکی از کامپوننت هایی که توانایی ارسال ایمیل دارند، یک ایمیل ارسال کند. اکتیویتی باید برای انجام این عمل یک ACTION_SEND را همراه انتخابگر مناسب به تحلیلگر اینتنت های اندروید ارسال کند. پس از آن انتخابگر یک رابط کاربری را برای انتخاب کامپوننت ارسال ایمیل، به کاربر نمایش می دهد.

فراخوانی متد startActivity در کدهای بالا باعث شروع فرآیند ارسال ایمیل می شود و نتیجه ی آن مانند تصویر زیر خواهد بود :

به عنوان یک مثال دیگر فرض کنید اکتیویتی دیگری نیاز دارد لینکی را با یکی از مرورگرهای موجود در سیستم اندروید باز کند. به این منظور اکتیویتی باید یک ACTION_WEB_SEARCH را که یک شی اینتنت است، به تحلیلگر اینتنت های اندروید ارسال کند. تحلیلگر اینتنت ها برای انتخاب یک اکتیویتی که بیشترین مطابقت را با اینتنت ارسالی داشته باشد به تجزیه و بررسی لیست تمام اکتیویتی ها می پردازد؛ که در این جا هدف برای ما اکتیویتی مرورگر وب است. پس از آن تحلیلگر اینتنت، لینک ما را به مرورگر وب ارسال می کند که باعث شروع اکتیویتی مرورگر نیز خواهد شد.

به عنوان مثال قطعه کد بالا  oration را با موتور جستجوی گوگل جستجو کرده و نتیجه را در قالب یک اکتیویتی اعلام خواهد کرد.

در جدول زیر مکانیستم های جداگانه ی تحویل intentها، به هر نوع کامپوننت – اکتیویتی ها ، سرویس ها و یا گیرنده های اعلام – آورده شده است.

شماره متد و توضیحات
۱ ()Context.startActivity: شی Intent برای راه اندازی یک اکتیویتی جدید، و یا دستور انجام کار جدید توسط یک اکتیویتی موجود، با این متد ارسال می شود.
۲ ()Context.startService: شی Intent برای شروع یک سرویس، و یا تحویل دستورالعمل جدید به یک سرویس در حال فعالیت با این متد ارسال می شود.
۳ ()Context.sendBroadcast: شی Intent توسط این متد به گیرنده های اعلام ارسال می شود.

شی های Intent

یک شی Intent یک بسته ی اطلاعاتی است که کامپوننت دریافت کننده ی آن و همچنین سیستم اندروید، از اطلاعات موجود در آن استفاده می کنند.

یک شی Intent بر اساس ارتباطی که برقرار می کند و یا کاری که قصد انجام آن را دارد می تواند شامل قسمت های زیر باشد.

Action (عمل یا اقدام)

این یک بخش اجباری در شی اینتنت است و یک نام رشته ای از عملی است که باید انجام شود؛ و یا در اعلام کننده ها، اینتنت حاوی گزارش عملی است که انجام شده است؛ مثلا دانلود یک فایل. عملی که قرار است انجام شود و یا انجام شده تا حد زیادی تعیین کننده ی ساختار شی اینتنت است. کلاس اینتنت یک شماره ی ثابت را برای عمل مورد نظر تعریف می کند که با اینتنت های دیگر متفاوت است؛ شما می توانید لیست Android Intent Standard Actions را نیز مطالعه کنید.

Action در یک شی اینتنت با متد ()setAction تعیین و با متد ()getAction خوانده می شود.

Data(داده)

این قسمت ویژگی و خصوصیت داده را به یک فیلتر اینتنت اضافه می کند. این مشخصات می توانند تنها نوع داده باشند (mimeType)، یا فقط URI باشند، و یا ترکیبی از هر دوی این ها. یک URI به وسیله ی ویژگی های بخش هایش که از یکدیگر مجزا هستند مشخص می شود −

ویژگی هایی که با فرمت URI مشخص می شوند اختیاری هستند، اما وابستگی متقابل دارند −

اگر هیچ رویه ای را برای فیلتر Intent تعیین نکنیم، تمام مشخصه های دیگر URI نیز نادیده گرفته می شوند.
اگر هیچ میزبانی برای فیلتر مشخص نشود، ویژگی پورت و تمام ویژگی های مسیر موجود در URI نادیده گرفته می شوند.

متد ()setData تنها URI را مشخص می کند، متد ()setType مشخص کننده ی نوع MIME بوده و متد ()setDataAndType هر دوی آن ها را مشخص می کند. URI با استفاده از متد ()getData و نوع با متد ()getType خوانده می شوند.

برخی از نمونه های action/data در جدول زیر آورده شده است.

شماره جفت Action/Data و توضیحات آن ها
۱ ACTION_VIEW content://contacts/people/1: اطلاعات مخاطبی که شناسه اش برابر “۱” است را نمایش می دهد.
۲ ACTION_DIAL content://contacts/people/1: صفحه ی شماره گیر را، درحالی که شماره ی مخاطبی که شناسه اش “۱” است در آن وارد شده، نمایش می دهد.
۳ ACTION_VIEW tel:123: صفحه ی شماره گیر را در حالی که با شماره ی “۱۲۳” پر شده است نمایش می دهد.
۴ ACTION_EDIT content://contacts/people/1: صفحه ی ویرایش اطلاعات را برای مخاطبی که شناسه اش برابر “۱” است نمایش می دهد.
۵ ACTION_VIEW content://contacts/people: لیست مخاطبان را نمایش می دهد.
۶ ACTION_SET_WALLPAPER: تنظیمات مربوط به انتخاب تصویر زمینه را نمایش می دهد.
۷ ACTION_SYNC: موجب همگام سازی داده ها می شود و مقدار ثابت android.intent.action.SYNC را دارد.
۸ ACTION_SYSTEM_TUTORIAL: پلت فرم آموزشی که در اولین راه اندازی دستگاه اجرا می شود را آغاز می کند.
۹ ACTION_TIMEZONE_CHANGED: تغییر منطقه ی زمانی (time zone) را گزارش می کند.
۱۰ ACTION_UNINSTALL_PACKAGEحذف کننده ی یک برنامه را اجرا می کند.

Category(دسته یا رده)

دسته یک بخش اختیاری از شی Intent است و حاوی اطلاعات اضافی، درباره ی نوع کامپوننتی که باید به intent رسیدگی کند می شود. متد ()addCategory یک دسته را برای شی intent تعیین می کند، متد ()removeCategory دسته ای را که قبلا اضافه شده است حذف کرده و ()getCategories نیز دسته هایی را که برای شی intent تعیین شده اند برمی گرداند. در Android Intent Standard Categories می توانید لیست دسته ها را مطالعه کنید.

در قسمت Intent Filters که در ادامه آمده است می توانید نحوه ی انتخاب و استفاده از یک دسته، که مناسب فعالیت یک Intent باشد را مورد بررسی قرار دهید.

Extras(سایر موارد)

این قسمت شامل اطلاعات اضافی درباره ی Intent می شود و باید به کامپوننتی که با intent در تعامل است تحویل داده شود. این اطلاعات می توانند با متد ()putExtras تعیین و با متد ()getExtrasخوانده شوند. در Android Intent Standard Extra Data می توانید لیست مربوط به اطلاعات اضافی را مطالعه کنید.

Flags(پرچم ها)

پرچم ها نیز یک بخش اختیاری در شی Intent هستند و برای سیستم اندروید مشخص می کنند که یک اکتیویتی را چگونه راه اندازی و پس از آن اداره کند؛ و کاربرد هایی از این قبیل.

شماره پرچم و توضیحات
۱ FLAG_ACTIVITY_CLEAR_TASK: اگر این پرچم با استفاده از متد ()Context.startActivity برای یک Intent تعیین شود، باعث خواهد شد قبل از شروع اکتیویتی، تمام واحد های سیستمی که تا قبل از تعیین پرچم مشغول پردازش این نوع اکتیویتی بوده اند آزاد شوند؛ سپس برای اکتیویتی یک واحد سیستمی جدید اختصاص داده می شود و اگر تمام واحد ها مشغول باشند، یک واحد خالی شده و نهایتا تمام اکتیویتی های قدیمی مرتبط پایان می یابند. این پرچم باید همراه با پرچم FLAG_ACTIVITY_NEW_TASK استفاده شود.
۲ FLAG_ACTIVITY_CLEAR_TOPدر صورت استفاده از این پرچم، هنگام شروع اکتیویتی، اگر یک واحد سیستمی مشغول پردازش این نوع اکتیویتی باشد، به جای راه اندازی یک نمونه ی جدید در یک واحد سیستمی دیگر، تمام اکتیویتی های موجود که قبل از این بوده اند بسته می شوند و این اینتنت به عنوان یک اینتنت جدید به آن ها واگذار می شود.
۳ FLAG_ACTIVITY_NEW_TASK: به طور کلی این پرچم به صورت پیش فرض توسط اکتیویتی هایی که می خواهند راه اندازی شوند استفاده می شود.

Component Name

این فیلد اختیاری یک شی ComponentName است و می تواند نماینده ی هر کدام از کلاس های اکتیویتی، سرویس و یا گیرنده های اعلام باشد. در صورت تنظیم بودن این فیلد شی Intent، به نمونه کلاس تعیین شده تحویل داده می شود، در غیر اینصورت سیستم اندروید با استفاده از سایر اطلاعات موجود در شی اینتنت یک موقعیت مناسب را به عنوان مقصد شی تعیین می کند.

نام کامپوننت مقصد می تواند با هر یک از متد های ()setComponent()، setClass یا ()setClassName تنظیم شود و با متد ()getComponent خوانده می شود.

انواع اینتنت ها

در زیر دو نوع اینتنت که سیستم اندروید از آن ها پشتیبانی می کند آورده شده است.

intent

اینتنت های صریح

اینتنت های صریح برای برقراری ارتباط بین قسمت های داخلی یک نرم افزار استفاده می شوند. مثلا فرض کنید می خواهید از یک اکتیویتی با اکتویتی دیگری ارتباط برقرار کنید، ما می توانیم این ارتباط را با یک اینتنت صریح انجام دهیم. تصویر زیر ارتباط بین اکتیویتی اول با اکتیویتی دوم را پس از کلیک کردن روی دکمه نشان می دهد.

این اینتنت ها، کامپوننت هدف را با نام تعیین می کنند و معمولا برای ارتباط بین کامپوننت های داخلی نرم افزار استفاده می شوند. مانند یک اکتیویتی که می تواند یک سرویس تابعه و یا یک اکتیویتی خواهر را با استفاده از اینتنت های صریح شروع کند. به عنوان مثال

اینتنت های ضمنی

این اینتنت ها هدف خود را با نام مشخص نمی کنند و فیلد مشخص کننده ی مقصد در آن ها خالی است. به همین دلیل به آن ها Intent ضمنی می گویند و معمولا برای فعال کردن کامپوننت های سایر نرم افزار ها استفاده می شود. به عنوان مثال

نتیجه ی قطعه کد بالا مانند تصویر زیر خواهد بود.

کامپوننت مقصد که دریافت کننده ی Intent است می تواند برای دریافت داده های اضافیِ ارسال شده توسط کامپوننت منبع از متد ()getExtras استفاده کند. به عنوان مثال

مثال

مثال زیر قابلیت های یک Intent را در راه اندازی کامپوننت های سایر نرم افزارها نشان می دهد. حال انجام مثال را طبق مراحل جدول زیر دنبال می کنیم .

مرحله توضیحات
۱ با استفاده از اندروید استودیو یک پروژه ی جدید با نام Android Intents تحت بسته ی com.example.android.intents ایجاد کنید.
۲ محتوای فایل java/com.example.android.intents/MainActivity.java را مانند آنچه در ادامه آمده تغییر دهید.
۳ محتوای فایل res/layout/activity_main.xml را با افزودن دو دکمه تغییر دهید.
۴ ثابت های رشته ای مورد نیاز را در فایل res/values/strings.xml تعریف کنید.
۵ نرم افزار را با شبیه ساز اندروید اجرا کنید و نتیجه را مورد بررسی قرار دهید.

در زیر محتوای تغییر یافته ی فایل java/com.example.android.intents/MainActivity.java آورده شده است.

در زیر محتوای تغییر یافته ی فایل res/layout/activity_main.xml آورده شده است.

در زیر محتوای فایل res/values/strings.xml آورده شده است.

حال نوبت آن رسیده تا با استفاده از اندروید استودیو برنامه را اجرا کنیم. برای این منظور روی آیکون Run که در نوار ابزار قرار دارد کلیک کنید.اگر همه چیز بدون مشکل پیش برود پنجره ی شبیه ساز شما مانند تصویر زیر خواهد بود.

حال روی دکمه ی شروع مرورگر کلیک کنید که در اثر آن مرورگر در حالی که به آدرس http://oration.ir/education-android رفته است مانند تصویر زیر نمایش داده می شود

به روش مشابه می توانید صفحه ی شماره گیر قسمت تماس ها را با فشردن دکمه ی شروع تماس اجرا کنید.

Intent Filters

تا اینجا دیدید که چطور با استفاده از اینتنت یک اکتیویتی را از یک برنامه ی دیگر فراخوانی کردیم. سیستم عامل اندروید با استفاده از فیلتر ها می تواند مجموعه ای از اکتیویتی ها، سرویس ها و گیرنده های اعلام را مشخص کند تا با کمک action، categories و data scheme ی مرتبط با یک اینتنت تعامل برقرار کنند. با استفاده از تگ <intent-filter> در فایل مانیفست می توانید لیستی از actionها، categoryها و نوع dataهایی که با هر کدام از کامپوننت های اکتیویتی، سرویس یا گیرنده ی اعلام مرتبط هستند را تعریف کنید.

برای مثال قسمتی از یک فایل مانیفست در زیر آورده شده که در آن با استفاده از action یک اکتیویتی تعیین شده است که می تواند با هر دو روش صریح و ضمنی مورد دستیابی قرار بگیرد و یک category و نوع data نیز در آن تعریف گردیده

هنگامی که برای یک اکتیویتی مانند قطعه کد بالا فیلتر تعریف شود، اکتیویتی های دیگری که category آن ها android.intent.category.DEFAULT تعریف شده باشد، می توانند با استفاده از android.intent.action.VIEW یا com.example.ApplicationName.LAUNCH این اکتیویتی را فراخوانی کنند.

تگ <data> نیز نوع داده هایی را که اکتیویتی انتظار دارد آن ها را دریافت کند مشخص می کند که در قطعه کد بالا اکتیویتی سفارشی (custom) ما انتظار دارد داده هایی که دریافت می کند با “://http” آغاز شوند؛ یعنی یک آدرس وب.

ممکن است در وضعیتی که ارائه ی یک اینتنت با فیلترهای بیش از یک اکتیویتی یا سرویس هم خوانی پیدا کند، از کاربر پرسیده شود که مایل است کارش با کامپوننت کدام برنامه که فیلترش با این Intent هم خوانی داشته انجام شود. یک استثنا نیز وجود دارد و آن زمانی است که Intent نتواند هیچ فیلتر مناسبی را پیدا کند.

در زیر لیست بررسی های انجام شده توسط اندروید، قبل از فراخوانی یک اکتیویتی آورده شده است.

• ممکن است یک تگ <intent-filter> مانند مثال بالا بیشتر از یک action را در داخل لیست خود بیاورد، اما این لیست نمی تواند خالی باشد؛ یک فیلتر حداقل باید یک تگ <action> را در لیست خود داشته باشد، در غیر این صورت تمام اینتنت های دیگر را نیز مسدود خواهد کرد. اگر بیش از یک action در لیست داخل <intent-filter> ذکر شود، سیستم اندروید قبل از فراخوانی اکتیویتی برای مطابقت دادن یکی از آن ها تلاش خواهد کرد.

• ممکن است یک تگ <intent-filter> صفر، یک یا بیشتر از یک catgory را در خود لیست کند. اگر هیچ category ذکر نشده باشد سیستم اندروید به طور پیش فرض تطابق این category را موفقیت آمیز در نظر خواهد گرفت، اما اگر بیش از یک category ذکر شده باشد، سیستم اندروید تک تک آن ها را تست کرده و باید هر category در شی Intent با یک category در فیلتر مطابقت داشته باشد.

• هر تگ <data> می تواند یک URI و یک نوع داده(MIME media type) را مشخص کند. ویژگی های مجزایی نیز شبیه scheme، host، port و path برای هر قسمت از URI وجود دارد. یک شی اینتنت که شامل هر دو بخش URI و نوع داده می شود، در صورتی آزمون تطابق را قبول می شود که نوع داده اش با یکی از داده های ذکر شده در فیلتر مطابقت داشته باشد.

مثال

در این مثال می بینیم که سیستم اندروید چگونه تعارض تطابق یک اینتنت با دو اکتیوی را حل می کند؛ و پس از آن چطور یک اکتیویتی سفارشی را با یک فیلتر فراخوانی می کند و در نهایت به سراغ مورد استثنا می رویم، هنگامی که هیچ اکتیوتی مناسبی برای اینتنت تعریف نشده باشد.

مرحله توضیحات
۱ با استفاده از اندروید استودیو یک پروژه ی جدید با نام Android Filters تحت بسته ی com.example.android.filters ایجاد کنید.
۲ فایل java/com.example.android.filters/MainActivity.java را با افزودن گیرنده های تلنگر برای سه دکمه تغییر دهید.
۳ فایل java/com.example.android.filters/CustomActivity.java را برای تعریف یک اکتیویتی که توسط intetnهای مختلف اجرا خواهد شد، ایجاد کنید.
۴ فایل res/layout/activity_main.xml را با افزودن سه دکمه و دو متن تغییر دهید.
۵ فایل لایه ای res/layout/custom_view.xml را با یک <TextView> ایجاد کنید که نشان دهنده ی اطلاعات ارسال شده از طریق intent خواهد بود.
۶ ثابت های رشته ای مورد نیاز را در فایل res/values/strings.xml تعریف کنید.
۷ محتوای فایل AndroidManifest.xml را با افزودن تگ <intent-filter> که معرف intent شما در اجرای اکتیویتی سفارشی است، تغییر دهید.
۸ نرم افزار را با استفاده از شبیه ساز سیستم اندروید اجرا و نتیجه را بررسی نمایید.

در زیر محتوای تغییر یافته ی فایل java/com.example.android.filters/MainActivity.java آورده شده است.

در زیر محتوای فایل java/com.example.android.filters/CustomActivity.java آورده شده است.

در زبر محتوای فایل res/layout/activity_main.xml آورده شده است.

در زیر محتوای فایل res/layout/custom_view.xml آورده شده است.

در زیر محتوای تغییر یافته ی فایل res/values/strings.xml را مشاهد می کنید.

و اما در نهایت محتوای فایل AndroidManifest.xml به شرح زیر است.

حال نوبت آن رسیده تا با استفاده از اندروید استودیو برنامه را اجرا کنیم. برای این منظور روی آیکون Run که در نوار ابزار قرار دارد کلیک کنید.اگر همه چیز بدون مشکل پیش برود پنجره ی شبیه ساز شما مانند تصویر زیر خواهد بود.

اجازه دهید با اولین دکمه یعنی “شروع مرورگر با ACTION VIEW” کار را آغاز کنیم. در اینجا ما اکتیویتی سفارشی خودمان را با فیلتر ” android.intent.action.VIEW” تعریف کرده ایم، اما برای “ACTION_VIEW” یک اکتیویتی دیگر نیز به صورت پیش فرض توسط سیستم اندروید تعریف شده است که باعث راه اندازی مرورگر می شود. بنابراین اندروید با استفاده از قاب زیر از ما می خواهد یک اکتیویتی را برای اجرا شدن انتخاب کنیم.

حال اگر مرورگر را انتخاب کنیم، اندروید مرورگر وب را راه اندازی و سایت oration.ir را باز خواهد کرد؛ اما اگر IndentDemo را انتخاب کنید اندروید CustomActivity را راه اندازی خواهد کرد که تنها داده ارسالی را دریافت و مانند تصویر زیر نمایش خواهد داد.

حال با استفاده از دکمه ی بازگشت به عقب بر می گردیم و روی دکمه ی “شروع مرورگر با LAUNCH” کلیک می کنیم، در اینجا سیستم اندرود فیلتری را که برای انتخاب اکتیویتی تعریف شده است تطابق می دهد و در نتیجه اکتیویتی سفارشیِ ما راه اندازی می شود.

دوباره با استفاده از دکمه ی بازگشت به عقب برگردید و روی دکمه ی “شرایط استثنا” کلیک کنید. در اینجا سیستم اندروید سعی می کند یک فیلتر معتبر برای اینتنت داده شده پیدا کند که موفق نمی شود؛ زیرا به جای استفاده از داده ی http از https استفاده کرده ایم؛ با این وجود اکتیویتی ما درست است، بنابراین سیستم اندروید آن را یک استثنا در نظر گرفته و پیام زیر را نمایش می دهد.

Intent Filter

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *