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

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

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

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

یک قصد ضمنی بسازید

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

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

Intent ها اغلب شامل داده های مرتبط با عملکرد هستند، مانند آدرسی که می خواهید مشاهده کنید یا پیام ایمیلی که می خواهید ارسال کنید. بسته به هدفی که می‌خواهید ایجاد کنید، داده‌ها ممکن است یک 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() این هدف را فراخوانی می کند، برنامه Phone تماسی را با شماره تلفن داده شده آغاز می کند.

در اینجا چند هدف دیگر و عملکرد آنها و جفت داده های 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);

موارد اضافی را به یک intent اضافه کنید

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

به طور پیش‌فرض، سیستم نوع MIME مناسب مورد نیاز یک intent را بر اساس داده‌های Uri که شامل می‌شود، تعیین می‌کند. اگر Uri در intent وارد نکنید، معمولاً باید setType() برای تعیین نوع داده مرتبط با intent استفاده کنید. تنظیم نوع 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 14 و بالاتر پشتیبانی می شود.

کاتلین

// 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);

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

اگرچه بسیاری از اهداف با موفقیت توسط برنامه دیگری که روی دستگاه نصب شده است - مانند تلفن، ایمیل یا برنامه تقویم مدیریت می شود - برنامه شما باید برای شرایطی آماده شود که هیچ فعالیتی نتواند هدف برنامه شما را مدیریت کند. هر زمان که یک 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 بیشتر بیاموزید.

گفتگوی ابهام زدایی

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

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

شکل 1. نمونه ای از گفتگوی انتخاب که زمانی ظاهر می شود که بیش از یک برنامه بتواند یک intent را مدیریت کند.

مثال کامل

در اینجا یک مثال کامل آورده شده است که نشان می‌دهد چگونه یک intent برای مشاهده نقشه ایجاد کنید، تأیید کنید که یک برنامه برای رسیدگی به این هدف وجود دارد، سپس آن را شروع کنید:

کاتلین

// 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.
}

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

شکل 2. گفتگوی انتخابگر.

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

با این حال، اگر عملکردی که باید انجام شود می تواند توسط چندین برنامه مدیریت شود و کاربر ممکن است هر بار یک برنامه متفاوت را ترجیح دهد - مانند یک اقدام "اشتراک گذاری"، که برای آن کاربران ممکن است چندین برنامه داشته باشند که از طریق آنها ممکن است یک مورد را به اشتراک بگذارند - باید به صراحت یک گفتگوی انتخابگر را همانطور که در شکل 2 نشان داده شده است نشان دهید. گفتگوی انتخابگر کاربر را مجبور می کند هر بار از کدام برنامه برای عمل استفاده کند (کاربر نمی تواند یک برنامه پیش فرض را برای عمل انتخاب کند).

برای نشان دادن انتخابگر، با استفاده از 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 ارائه شود