اگر برنامهتان میتواند کنشی را انجام دهد که ممکن است برای برنامه دیگری مفید باشد، آن را برای پاسخ دادن به درخواستهای کنش آماده کنید. برای این کار، فیلتر قصد مناسب را در فعالیتتان مشخص کنید.
برای مثال، اگر
برنامه اجتماعیای میسازید که میتواند پیامها یا عکسها را با دوستان کاربر همرسانی کند،
از هدف ACTION_SEND پشتیبانی کنید.
سپس، وقتی کاربران کنش «همرسانی» را از برنامه دیگری شروع میکنند، برنامه شما بهعنوان گزینهای در
چارگوش گفتگوی انتخابگر (که بهعنوان چارگوش گفتگوی ابهامزدایی نیز شناخته میشود) ظاهر میشود، همانطور که در شکل ۱ نشان داده شده است.
شکل ۱. کادر گفتگوی انتخابگر.
برای اینکه به برنامههای دیگر اجازه دهید فعالیت شما را به این روش شروع کنند، باید عنصر <intent-filter> را در فایل مانیفست خود برای عنصر <activity> مربوطه اضافه کنید.
وقتی برنامهتان در دستگاهی نصب میشود، سیستم فیلترهای قصد شما را شناسایی میکند و اطلاعات را به کاتالوگ داخلی قصدهای پشتیبانیشده توسط همه برنامههای نصبشده اضافه میکند.
وقتی برنامهای startActivity() یا startActivityForResult() را با هدف ضمنی فراخوانی میکند، سیستم فعالیتهایی را که میتوانند به این هدف پاسخ دهند بررسی میکند.
افزودن فیلتر قصد
برای تعریف صحیح اینکه فعالیت شما کدام قصدها را میتواند مدیریت کند، هر فیلتر قصدی را که اضافه میکنید ازنظر نوع کنش و دادههایی که فعالیت میپذیرد تا حد امکان خاص کنید.
سیستم ممکن است یک Intent مشخص را به فعالیتی ارسال کند اگر آن فعالیت دارای
فیلتر قصدی باشد که معیارهای زیر را برای شیء Intent برآورده کند:
- کنش
- رشتهای که کنش موردنظر برای اجرا را نامگذاری میکند. معمولاً یکی از مقادیر تعریفشده پلاتفرم، مانند
ACTION_SENDیاACTION_VIEW.این را در فیلتر قصد خود با عنصر
<action>مشخص کنید. مقداری که در این عنصر مشخص میکنید باید نام رشته کامل برای کنش باشد، نه ثابت API، همانطور که در مثالهای این صفحه نشان داده شده است. - داده
- شرحی از دادههای مرتبط با هدف.
این را در فیلتر قصد خود با عنصر
<data>مشخص کنید. بااستفاده از یک یا چند مشخصه در این عنصر، میتوانید نوع MIME، پیشوند URI، طرحواره URI، یا ترکیبی از اینها و موارد دیگر را که نشاندهنده نوع داده پذیرفتهشده است مشخص کنید.توجه: اگر نیازی به اعلام جزئیات مربوط به دادهها ندارید
Uri، مثلاً وقتی فعالیت شما نوع دیگری از دادههای «اضافی» را بهجای URI مدیریت میکند، فقط ویژگیandroid:mimeTypeرا برای اعلام نوع دادهای که فعالیت شما مدیریت میکند، مانندtext/plainیاimage/jpeg، مشخص کنید. - دسته
- روش دیگری برای توصیف فعالیت مدیریت هدف ارائه میدهد که معمولاً به اشاره کاربر یا مکانی که از آن شروع شده است مربوط میشود. چندین دسته مختلف وجود دارد که توسط سیستم پشتیبانی میشود، اما اکثر آنها بهندرت استفاده میشوند. اما همه هدفهای ضمنی بهطور پیشفرض با
CATEGORY_DEFAULTتعریف میشوند.این را در فیلتر قصد خود با عنصر
<category>مشخص کنید.
در فیلتر قصد، میتوانید با اعلام هریک از معیارها با عناصر XML متناظر که در عنصر <intent-filter>
تودرتو شدهاند، اعلام کنید که فعالیت شما کدام معیارها را میپذیرد.
برای مثال، در اینجا فعالیتی با فیلتر قصد وجود دارد که قصد ACTION_SEND را وقتی نوع داده نوشتار یا تصویر است مدیریت میکند:
<activity android:name="ShareActivity"> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> <data android:mimeType="image/*"/> </intent-filter> </activity>
نکته: اگر میخواهید نماد موجود در کادر گفتگوی انتخابگر با نماد پیشفرض فعالیتتان متفاوت باشد، android:icon را در عنصر <intent-filter> اضافه کنید.
هر هدف ورودی فقط یک کنش و یک نوع داده را مشخص میکند، اما اعلام چند نمونه از عناصر <action>، <category>، و <data> در هر <intent-filter> اشکالی ندارد.
اگر هر دو جفت کنش و داده در رفتارهایشان مانعهالجمع هستند، فیلترهای قصد جداگانهای ایجاد کنید تا مشخص شود کدام کنشها هنگام جفت شدن با کدام نوع داده قابلقبول هستند.
برای مثال، فرض کنید فعالیت شما هم نوشتار و هم تصاویر را برای هر دو هدف ACTION_SEND و ACTION_SENDTO مدیریت میکند. در این حالت، باید دو فیلتر قصد جداگانه برای دو کنش تعریف کنید، زیرا قصد ACTION_SENDTO باید از دادههای Uri برای مشخص کردن نشانی گیرنده بااستفاده از طرحواره URI send یا sendto استفاده کند. این موضوع در مثال زیر نشان داده شده است:
<activity android:name="ShareActivity"> <!-- Filter for sending text; accepts SENDTO action with sms URI schemes --> <intent-filter> <action android:name="android.intent.action.SENDTO"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="sms" /> <data android:scheme="smsto" /> </intent-filter> <!-- Filter for sending text or images; accepts SEND action and text or image data --> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="image/*"/> <data android:mimeType="text/plain"/> </intent-filter> </activity>
توجه: برای دریافت کردن قصد ضمنی، باید دسته
CATEGORY_DEFAULT را در فیلتر قصد بگنجانید. روشهای startActivity() و startActivityForResult() با همه هدفها بهگونهای رفتار میکنند که انگار
دسته CATEGORY_DEFAULT را اعلام کردهاند. اگر آن را در فیلتر قصد خود اعلام نکنید، هیچ قصد ضمنیای به فعالیت شما منتهی نمیشود.
برای اطلاعات بیشتر درباره ارسال و دریافت ACTION_SEND
هدفهایی که رفتارهای همرسانی اجتماعی را انجام میدهند، به دریافت دادههای ساده از برنامههای دیگر مراجعه کنید.
همچنین میتوانید اطلاعات مفیدی درباره همرسانی دادهها در
همرسانی دادههای ساده و
همرسانی فایلها پیدا کنید.
مدیریت کردن هدف در فعالیت
برای تصمیمگیری درباره اینکه چه اقدامی در فعالیتتان انجام دهید،
Intent را که برای شروع آن استفاده میشود بخوانید.
وقتی فعالیتتان شروع شد، با getIntent() تماس بگیرید تا
Intent را که فعالیت را شروع کرده است بازیابی کنید. میتوانید این کار را در هر زمانی درطول چرخه حیات فعالیت انجام دهید، اما معمولاً این کار را درطول فراخوانیهای برگشتی اولیه، مانند onCreate() یا onStart()، انجام میدهید.
این موضوع در مثال زیر نشان داده شده است:
کاتلین
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) val data: Uri? = intent?.data // Figure out what to do based on the intent type if (intent?.type?.startsWith("image/") == true) { // Handle intents with image data } else if (intent?.type == "text/plain") { // Handle intents with text } }
جاوا
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Get the intent that started this activity Intent intent = getIntent(); Uri data = intent.getData(); // Figure out what to do based on the intent type if (intent.getType().indexOf("image/") != -1) { // Handle intents with image data } else if (intent.getType().equals("text/plain")) { // Handle intents with text } }
برگرداندن نتیجه
اگر میخواهید نتیجهای را به فعالیتی که فعالیت شما را فراخوانی کرده است برگردانید، setResult() را فراخوانی کنید تا کد نتیجه و نتیجه Intent را مشخص کنید. وقتی عملیاتتان انجام شد و کاربر به فعالیت اصلی برمیگردد،
finish() را فراخوانی کنید تا
فعالیتتان بسته و نابود شود. این موضوع در مثال زیر نشان داده شده است:
کاتلین
// Create intent to deliver some kind of result data Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")).also { result -> setResult(Activity.RESULT_OK, result) } finish()
جاوا
// Create intent to deliver some kind of result data Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")); setResult(Activity.RESULT_OK, result); finish();
همیشه باید کد نتیجه را با نتیجه مشخص کنید. معمولاً RESULT_OK یا RESULT_CANCELED است. سپس میتوانید
درصورت لزوم، دادههای تکمیلی را با Intent ارائه دهید.
توجه: نتیجه بهطور پیشفرض روی
RESULT_CANCELED
تنظیم شده است. بنابراین، اگر کاربر قبلاز تکمیل کنش و قبلاز اینکه شما نتیجه را تنظیم کنید، روی دکمه «برگشتن»
تکضرب بزند، فعالیت اصلی نتیجه
«لغوشده» را دریافت میکند.
اگر فقط لازم است عدد صحیحی را برگردانید که یکی از چند گزینه نتیجه را نشان میدهد، میتوانید
کد نتیجه را روی هر مقداری بالاتر از ۰ تنظیم کنید. اگر از کد نتیجه برای ارائه عدد صحیح استفاده میکنید و
نیازی به گنجاندن Intent ندارید،
میتوانید setResult() را فراخوانی کنید
و فقط کد نتیجه را ارسال کنید:
کاتلین
setResult(RESULT_COLOR_RED) finish()
جاوا
setResult(RESULT_COLOR_RED); finish();
در این حالت، ممکن است فقط چند نتیجه ممکن وجود داشته باشد، بنابراین کد نتیجه یک عدد صحیح تعریفشده محلی (بزرگتر از ۰) است. این روش زمانی خوب کار میکند که نتیجهای را به فعالیتی در برنامه خودتان برمیگردانید، زیرا فعالیتی که نتیجه را دریافت میکند میتواند به ثابت عمومی ارجاع دهد تا مقدار کد نتیجه را تعیین کند.
توجه: نیازی نیست بررسی کنید که آیا فعالیتتان با startActivity() یا startActivityForResult() شروع شده است یا نه. اگر قصدی که فعالیتتان را شروع کرده است ممکن است نتیجهای را انتظار داشته باشد،
کافی است setResult() را فراخوانی کنید. اگر فعالیت مبدأ startActivityForResult() را فراخوانی کرده باشد، سیستم نتیجهای را که به setResult() ارائه میدهید به آن تحویل میدهد؛ درغیراینصورت، نتیجه نادیده گرفته میشود.