إرسال المستخدم إلى تطبيق آخر

إحدى أهم ميزات Android هي قدرة التطبيق على إرسال المستخدم إلى تطبيق آخر. بناءً على "إجراء" التي يرغب في تنفيذها. على سبيل المثال، إذا تطبيقك يحتوي على عنوان نشاط تجاري تريد عرضه على الخريطة، وليس عليك إنشاء نشاط في التطبيق يعرض خريطة. وبدلاً من ذلك، يمكنك إنشاء طلب للاطّلاع على العنوان. باستخدام Intent. بعد ذلك، يشغّل نظام Android تطبيقًا يمكنه عرض العنوان على الخريطة.

وكما هو موضح في الدرجة الأولى، فإن إنشاء تطبيقك الأول، يجب استخدام عناصر intent للتنقّل بين الأنشطة في تطبيقك. إِنْتَ تفعل ذلك بشكل عام بهدف صريح، وهي تحدد اسم الفئة بدقة المكون الذي تريد تشغيله. ومع ذلك، إذا كنت تريد أن ينفّذ أحد الإجراءات على تطبيق منفصل، مثل باسم "عرض خريطة" عليك استخدام هدف ضمني.

يشرح لك هذا الدرس كيفية إنشاء هدف ضمني لإجراء معيّن، وكيفية استخدامه. لبدء نشاط ينفّذ الإجراء في تطبيق آخر شاهد الفيديو المضمن هنا أيضًا لفهم سبب أهمية تضمين عمليات تحقُّق أثناء التشغيل للأغراض الضمنية.

بناء هدف ضمني

لا تعلن الأغراض الضمنية عن اسم فئة المكوِّن عند البدء، وإنما تعلن بدلاً من ذلك عن الإجراء المطلوب تنفيذه. يحدد الإجراء الإجراء الذي تريد تنفيذه، مثل view (عرض) تعديل أو إرسال أو الحصول على عنصر.

ربط إجراءات النية بالشراء بالبيانات

غالبًا ما تتضمن النوايا أيضًا البيانات المرتبطة مع الإجراء، مثل العنوان الذي تريد عرضه أو الرسالة الإلكترونية التي تريد إرسالها. واستنادًا إلى الغرض الذي تريد إنشاءه، قد تكون البيانات عبارة عن Uri أو أحد أنواع البيانات العديدة الأخرى، أو قد لا يحتاج القصد إلى بيانات على الإطلاق.

إذا كانت بياناتك هي Uri، هناك دالة إنشاء Intent() بسيطة يمكنك استخدامها لتحديد الإجراء البيانات.

على سبيل المثال، إليك كيفية إنشاء نية لبدء مكالمة هاتفية باستخدام بيانات Uri لتحديد رقم الهاتف:

Kotlin

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

Java

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

عندما يستدعي تطبيقك هذه النية من خلال الاتصال بالرقم startActivity()، يبدأ تطبيق "الهاتف" مكالمة إلى رقم الهاتف المحدّد.

في ما يلي نقطتان أخريان والإجراءات التي يتخذانها وبيانات Uri الأزواج:

عرض خريطة

Kotlin

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

Java

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

عرض صفحة ويب

Kotlin

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

Java

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

إضافة عناصر إضافية إلى هدف

تتطلب الأنواع الأخرى من الأهداف الضمنية "إضافية" البيانات التي توفر أنواع بيانات مختلفة، مثل السلسلة. يمكنك إضافة جزء واحد أو أكثر من البيانات الإضافية باستخدام طرق putExtra() المختلفة.

بشكل افتراضي، يحدد النظام نوع MIME المناسب الذي يتطلبه نية بناءً على وتشمل بيانات Uri. إذا لم يتم تضمين Uri في السمة النية، عليك عادةً استخدام setType() لتحديد النوع. من البيانات المرتبطة بالغرض. يؤدي تعيين نوع MIME إلى تحديد أنواع أن تحصل الأنشطة على القصد.

في ما يلي بعض الأغراض التي تضيف بيانات إضافية لتحديد الإجراء المطلوب:

إرسال رسالة إلكترونية تحتوي على مرفق

Kotlin

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
}

Java

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

إنشاء حدث في التقويم

ملاحظة: لا يتوافق هذا الغرض من حدث في التقويم إلا مع واجهة برمجة التطبيقات. من المستوى 14 والأعلى.

Kotlin

// 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")
}

Java

// 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() لإرساله إلى النظام:

Kotlin

startActivity(intent)

Java

startActivity(intent);

التعامل مع الحالة التي لا يتلقّى فيها أي تطبيق هدفًا

على الرغم من أنّه تم التعامل مع العديد من الأهداف بنجاح من خلال تطبيق آخر مثبَّت. على الجهاز، مثل الهاتف أو البريد الإلكتروني أو تطبيق التقويم، ومن المفترض أن يتم تجهيز تطبيقك للحالات التي لا يتمكن فيها أي نشاط من معالجة الغرض من التطبيق. كلما استدعاء النية، وكن مستعدًا للقبض على ActivityNotFoundException، الذي يحدث في حال عدم توفّر نشاط آخر يمكنه معالجة الغرض من تطبيقك:

Kotlin

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

Java

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

بعد اكتشاف هذا الاستثناء، حدِّد الإجراء الذي يجب أن ينفِّذه تطبيقك بعد ذلك. هذا التالي على الخصائص المحددة للغرض الذي حاولت استدعاء. على سبيل المثال، إذا كنت تعرف تطبيقًا معيّنًا يمكنه معالجة الغرض من التطبيق، توفِّر رابطًا للمستخدم لتنزيل التطبيق. يُرجى الاطّلاع على مزيد من المعلومات حول كيفية إلى منتجك على Google Play.

مربّع حوار التوضيح

وإذا حدد النظام أكثر من نشاط واحد يمكنه معالجة الهدف، فسيعمل على عرض مربع حوار (يُشار إليه أحيانًا بـ "مربع حوار التوضيح") المستخدم في تحديد التطبيق المراد استخدامه، كما هو موضح في الشكل 1. إذا لم يكن هناك سوى أي نشاط يعالج الهدف، يبدأه النظام على الفور.

تظهر لوحة
  بالقرب من أسفل الشاشة. تسرد هذه اللوحة التطبيقات المختلفة التي يمكن
  التعامل مع المقصد.

الشكل 1. مثال على التحديد يظهر مربّع الحوار الذي يظهر عندما يتمكّن أكثر من تطبيق من تنفيذ هدف.

المثال الكامل

إليك مثال كامل يوضح كيفية إنشاء نية لعرض خريطة، تحقق من أن الحالي لمعالجة الغرض، ثم تشغيله:

Kotlin

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

Java

// 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() وهناك أكثر من تطبيق يستجيب لـ الغرض، يمكن للمستخدم اختيار التطبيق الذي سيتم استخدامه تلقائيًا (عن طريق وضع علامة في مربّع اختيار في أسفل الصفحة مربع الحوار انظر الرسم 1). يكون هذا رائعًا عند تنفيذ إجراء يحتاج المستخدم بشكل عام استخدام التطبيق نفسه في كل مرة، مثلما هو الحال عند فتح صفحة ويب (يحاول المستخدمون يستخدمون متصفح ويب واحدًا فقط) أو تلتقط صورة (على الأرجح يفضل المستخدمون كاميرا واحدة).

ومع ذلك، إذا كان من الممكن معالجة الإجراء الذي سيتم تنفيذه بواسطة تطبيقات متعددة ويمكن للمستخدم تطبيق مختلف في كل مرة - على سبيل المثال "مشاركة" إجراء، والذي قد يكون لدى المستخدمين العديد من التطبيقات التي قد يشاركون من خلالها عنصرًا ما—يجب عليك إظهار مربع حوار أداة الاختيار بوضوح كما هو موضح في الشكل 2. مربع حوار أداة الاختيار تفرض على المستخدم اختيار التطبيق الذي سيستخدمه لتنفيذ الإجراء في كل مرة (لا يمكن للمستخدم اختيار التطبيق الافتراضي للإجراء).

لإظهار أداة الاختيار، أنشِئ Intent باستخدام createChooser() ومرِّرها إلى startActivity(). مثلاً:

Kotlin

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

Java

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(). قد تكون المعلمة title يتم تقديمه إذا لم يكن الإجراء ACTION_SEND أو ACTION_SEND_MULTIPLE