ارسال کاربر به برنامه دیگر

یکی از مهم‌ترین ویژگی‌های Android توانایی برنامه برای فرستادن کاربر به برنامه دیگری براساس «کنشی» است که می‌خواهد انجام دهد. برای مثال، اگر برنامه‌تان نشانی کسب‌وکاری را دارد که می‌خواهید روی نقشه نشان دهید، لازم نیست فعالیتی در برنامه‌تان بسازید که نقشه را نشان دهد. درعوض، می‌توانید بااستفاده از Intent درخواستی برای مشاهده نشانی ایجاد کنید. سپس سیستم Android برنامه‌ای را راه‌اندازی می‌کند که می‌تواند نشانی را روی نقشه نشان دهد.

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

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

ساختن قصد ضمنی

هدف‌های ضمنی نام کلاس مؤلفه را برای شروع اعلام نمی‌کنند، بلکه درعوض کنشی را برای اجرا اعلام می‌کنند. کنش مشخص می‌کند که می‌خواهید چه کاری انجام دهید، مثلاً چیزی را مشاهده، ویرایش، ارسال، یا دریافت کنید.

مرتبط کردن کنش‌های قصد با داده‌ها

اغلب، هدف‌ها شامل داده‌های مرتبط با کنش نیز می‌شوند، مثل نشانی‌ای که می‌خواهید مشاهده کنید یا پیام ایمیلی که می‌خواهید ارسال کنید. بسته به قصدی که می‌خواهید ایجاد کنید، داده‌ها ممکن است Uri، یکی از چندین نوع داده دیگر باشد، یا ممکن است قصد اصلاً به داده نیاز نداشته باشد.

اگر داده‌هایتان Uri است، سازنده Intent() ساده‌ای وجود دارد که می‌توانید از آن برای تعریف کنش و داده‌ها استفاده کنید.

برای مثال، در اینجا نحوه ایجاد یک قصد برای شروع تماس تلفنی بااستفاده از داده‌های Uri برای مشخص کردن شماره تلفن آورده شده است:

کاتلین

val callIntent: Intent = Uri.parse("tel:5551234").let { number ->
    Intent(Intent.ACTION_DIAL, number)
}

جاوا

Uri number = Uri.parse("tel:5551234");
Intent callIntent = new Intent(Intent.ACTION_DIAL, number);

وقتی برنامه‌تان این هدف را با تماس با startActivity() فراخوانی می‌کند، برنامه «تلفن» تماسی با شماره تلفن ارائه‌شده برقرار می‌کند.

در اینجا چند قصد دیگر و جفت‌های کنش و داده Uri آن‌ها آورده شده است:

مشاهده نقشه

کاتلین

// Map point based on address
val mapIntent: Intent = Uri.parse(
        "geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"
).let { location ->
    // Or map point based on latitude/longitude
    // val location: Uri = Uri.parse("geo:37.422219,-122.08364?z=14") // z param is zoom level
    Intent(Intent.ACTION_VIEW, location)
}

جاوا

// Map point based on address
Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
// Or map point based on latitude/longitude
// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);

مشاهده صفحه وب

کاتلین

val webIntent: Intent = Uri.parse("https://www.android.com").let { webpage ->
    Intent(Intent.ACTION_VIEW, webpage)
}

جاوا

Uri webpage = Uri.parse("https://www.android.com");
Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);

افزودن موارد اضافی به قصد

انواع دیگر هدف‌های ضمنی به داده‌های «اضافی» نیاز دارند که انواع مختلف داده را ارائه می‌دهند، مانند رشته. بااستفاده از روش‌های مختلف putExtra() می‌توانید یک یا چند داده اضافی اضافه کنید.

به‌طور پیش‌فرض، سیستم نوع MIME مناسب موردنیاز برای قصد را براساس داده‌های Uri موجود تعیین می‌کند. اگر Uri را در قصد قرار ندهید، معمولاً باید از setType() برای مشخص کردن نوع داده مرتبط با قصد استفاده کنید. تنظیم نوع MIME مشخص می‌کند که کدام نوع فعالیت‌ها باید قصد را دریافت کنند.

در اینجا چند هدف دیگر وجود دارد که داده‌های اضافی را برای مشخص کردن کنش موردنظر اضافه می‌کند:

ارسال ایمیل با پیوست

کاتلین

Intent(Intent.ACTION_SEND).apply {
    // The intent does not have a URI, so declare the "text/plain" MIME type
    type = "text/plain"
    putExtra(Intent.EXTRA_EMAIL, arrayOf("jan@example.com")) // recipients
    putExtra(Intent.EXTRA_SUBJECT, "Email subject")
    putExtra(Intent.EXTRA_TEXT, "Email message text")
    putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"))
    // You can also attach multiple items by passing an ArrayList of Uris
}

جاوا

Intent emailIntent = new Intent(Intent.ACTION_SEND);
// The intent does not have a URI, so declare the "text/plain" MIME type
emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jan@example.com"}); // recipients
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
// You can also attach multiple items by passing an ArrayList of Uris

ایجاد رویداد تقویم

توجه: این هدف برای رویداد تقویم فقط با سطح API‏ ۱۴ و بالاتر پشتیبانی می‌شود.

کاتلین

// Event is on January 23, 2021 -- from 7:30 AM to 10:30 AM.
Intent(Intent.ACTION_INSERT, Events.CONTENT_URI).apply {
    val beginTime: Calendar = Calendar.getInstance().apply {
        set(2021, 0, 23, 7, 30)
    }
    val endTime = Calendar.getInstance().apply {
        set(2021, 0, 23, 10, 30)
    }
    putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.timeInMillis)
    putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.timeInMillis)
    putExtra(Events.TITLE, "Ninja class")
    putExtra(Events.EVENT_LOCATION, "Secret dojo")
}

جاوا

// Event is on January 23, 2021 -- from 7:30 AM to 10:30 AM.
Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
Calendar beginTime = Calendar.getInstance();
beginTime.set(2021, 0, 23, 7, 30);
Calendar endTime = Calendar.getInstance();
endTime.set(2021, 0, 23, 10, 30);
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
calendarIntent.putExtra(Events.TITLE, "Ninja class");
calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");

توجه: مهم است که Intent خود را تا حد امکان دقیق تعریف کنید. برای مثال، اگر می‌خواهید تصویری را بااستفاده از قصد ACTION_VIEW نمایش دهید، باید نوع MIME را image/* مشخص کنید. این کار مانع از آن می‌شود که برنامه‌هایی که می‌توانند انواع دیگر داده‌ها را «مشاهده کنند» (مانند برنامه نقشه) توسط هدف راه‌اندازی شوند.

شروع فعالیت با هدف

پس‌از ایجاد Intent و تنظیم اطلاعات اضافی، startActivity() را فراخوانی کنید تا آن را به سیستم ارسال کنید:

کاتلین

startActivity(intent)

جاوا

startActivity(intent);

مدیریت شرایطی که هیچ برنامه‌ای نمی‌تواند هدف را دریافت کند

اگرچه بسیاری‌از هدف‌ها با موفقیت توسط برنامه دیگری که در دستگاه نصب شده است (مانند برنامه تلفن، ایمیل، یا تقویم) مدیریت می‌شوند، برنامه شما باید برای شرایطی که هیچ فعالیتی نمی‌تواند هدف برنامه شما را مدیریت کند آماده باشد. هرگاه قصدی را فراخوانی می‌کنید، آماده باشید تا ActivityNotFoundException را دریافت کنید، که اگر فعالیت دیگری وجود نداشته باشد که بتواند قصد برنامه شما را مدیریت کند، رخ می‌دهد:

کاتلین

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

جاوا

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

پس‌از دریافت این استثنا، تصمیم بگیرید که برنامه‌تان در مرحله بعد چه کاری باید انجام دهد. این مرحله بعدی به ویژگی‌های خاص قصدی که سعی کردید فراخوانی کنید بستگی دارد. برای مثال، اگر برنامه خاصی را می‌شناسید که می‌تواند هدف را مدیریت کند، پیوندی برای کاربر ارائه دهید تا برنامه را بارگیری کند. درباره نحوه پیوند دادن به محصولتان در Google Play بیشتر بدانید.

کادر گفتگوی ابهام‌زدایی

اگر سیستم بیش‌از یک فعالیت را شناسایی کند که می‌تواند هدف را مدیریت کند، کادر گفتگویی (که گاهی‌اوقات «کادر گفتگوی ابهام‌زدایی» نامیده می‌شود) برای کاربر نمایش می‌دهد تا انتخاب کند از کدام برنامه استفاده شود، همان‌طور که در شکل ۱ نشان داده شده است. اگر فقط یک فعالیت وجود داشته باشد که هدف را مدیریت کند، سیستم بلافاصله آن را شروع می‌کند.

پانلی نزدیک پایین صفحه ظاهر می‌شود. این پانل برنامه‌های مختلفی را که می‌توانند
  هدف را مدیریت کنند فهرست می‌کند.

شکل ۱. نمونه‌ای از کادر گفتگوی انتخاب که وقتی بیش‌از یک برنامه می‌تواند قصد را مدیریت کند ظاهر می‌شود.

نمونه کامل

در اینجا نمونه کاملی آورده شده است که نحوه ایجاد قصد برای مشاهده نقشه، تأیید وجود برنامه‌ای برای مدیریت قصد، و سپس شروع آن را نشان می‌دهد:

کاتلین

// Build the intent.
val location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California")
val mapIntent = Intent(Intent.ACTION_VIEW, location)

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

جاوا

// Build the intent.
Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);

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

نمایش انتخاب‌گر برنامه

شکل ۲. کادر گفتگوی انتخاب‌گر.

توجه داشته باشید که وقتی فعالیتی را با ارسال Intent به startActivity() شروع می‌کنید و بیش‌از یک برنامه به هدف پاسخ می‌دهد، کاربر می‌تواند انتخاب کند که کدام برنامه به‌طور پیش‌فرض استفاده شود (با انتخاب چارگوش انتخاب در پایین کادر گفتگو؛ شکل ۱ را ببینید). این حالت زمانی مناسب است که کنشی انجام می‌شود که کاربر معمولاً می‌خواهد هربار از همان برنامه استفاده کند، مثلاً هنگام باز کردن صفحه وب (کاربران احتمالاً فقط از یک مرورگر وب استفاده می‌کنند) یا گرفتن عکس (کاربران احتمالاً یک دوربین را ترجیح می‌دهند).

بااین‌حال، اگر کنشی که باید انجام شود توسط چندین برنامه قابل‌مدیریت باشد و کاربر ممکن است هر بار برنامه متفاوتی را ترجیح دهد—مانند کنش «هم‌رسانی»، که برای آن کاربران ممکن است چندین برنامه داشته باشند که ازطریق آن‌ها می‌توانند موردی را هم‌رسانی کنند—باید به‌طور صریح یک کادر گفتگوی انتخاب‌کننده نشان دهید، همان‌طور که در شکل ۲ نشان داده شده است. کادر گفتگوی انتخابگر کاربر را مجبور می‌کند هربار انتخاب کند از کدام برنامه برای کنش استفاده شود (کاربر نمی‌تواند برنامه پیش‌فرضی برای کنش انتخاب کند).

برای نشان دادن انتخاب‌گر، بااستفاده از createChooser() یک Intent ایجاد کنید و آن را به startActivity() ارسال کنید. برای مثال:

کاتلین

val intent = Intent(Intent.ACTION_SEND)

// Create intent to show chooser
val chooser = Intent.createChooser(intent, /* title */ null)

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

جاوا

Intent intent = new Intent(Intent.ACTION_SEND);

// Create intent to show chooser
Intent chooser = Intent.createChooser(intent, /* title */ null);

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

با این کار، کادر گفتگویی با فهرستی از برنامه‌هایی که به هدف ارسال‌شده به روش createChooser() پاسخ می‌دهند نمایش داده می‌شود. اگر کنش ACTION_SEND یا ACTION_SEND_MULTIPLE نباشد، پارامتر title ممکن است ارائه شود