يوفّر Android طريقتَين تتيحان للمستخدمين مشاركة البيانات بين التطبيقات:
- تم تصميم "قائمة مشاركة البيانات من Android" بشكل أساسي لإرسال المحتوى خارج تطبيقك أو مباشرةً إلى مستخدم آخر. على سبيل المثال، مشاركة عنوان URL مع صديق.
- يُعدّ محلّل الأهداف في Android الأنسب لتمرير البيانات إلى المرحلة التالية من مهمة محدّدة جيدًا. على سبيل المثال، فتح ملف PDF من تطبيقك والسماح للمستخدمين باختيار عارض الملفات المفضّل لديهم.
أهمية استخدام "قائمة مشاركة البيانات من Android"
استخدِم "قائمة مشاركة البيانات من Android" لتقديم تجربة متّسقة للمستخدمين في جميع التطبيقات. لا تعرض قائمة التطبيق الخاصة بالجهات المستهدفة للمشاركة ولا تنشئ صيغًا خاصة بك من قائمة مشاركة البيانات.
تتيح "قائمة مشاركة البيانات من Android" للمستخدمين مشاركة المعلومات مع الشخص المناسب، مع اقتراحات التطبيقات ذات الصلة، وكل ذلك بنقرة واحدة. يمكن أن تقترح Sharesheet جهات اتصال غير متاحة للحلول المخصّصة، وتستخدم ترتيبًا متسقًا. وذلك لأنّ Sharesheet يمكنه مراعاة المعلومات حول نشاط التطبيق والمستخدم المتاحة للنظام فقط.
تتضمّن "قائمة مشاركة البيانات من Android" أيضًا العديد من الميزات المفيدة للمطوّرين. على سبيل المثال، يمكنك إجراء ما يلي:
- معرفة متى يكمل المستخدمون عملية مشاركة وإلى أين
- إضافة أهداف مخصّصة وأهداف التطبيقات
- تقديم معاينات للمحتوى النصي المنسَّق، بدءًا من الإصدار Android 10 (المستوى 29 من واجهة برمجة التطبيقات)
- استبعاد الأهداف التي تتطابق مع أسماء مكوّنات معيّنة
استخدام "قائمة مشاركة البيانات من Android"
بالنسبة إلى جميع أنواع المشاركة، أنشئ نية واضبط الإجراء على
Intent.ACTION_SEND.
لعرض "قائمة مشاركة البيانات من Android"، يمكنك استدعاء
Intent.createChooser()،
وتمرير عنصر Intent إليه.
وتعرض هذه الطريقة نسخة من نيتك تعرض دائمًا "قائمة مشاركة البيانات من Android".
إرسال محتوى نصي
إنّ الاستخدام الأكثر بساطة وشيوعًا لـ "قائمة مشاركة البيانات من Android" هو إرسال محتوى نصي من نشاط إلى آخر. على سبيل المثال، يمكن لمعظم المتصفحات مشاركة عنوان URL للصفحة المعروضة حاليًا كنص مع تطبيق آخر. وهذا مفيد لمشاركة مقالة أو موقع ويب مع الأصدقاء من خلال البريد الإلكتروني أو الشبكات الاجتماعية. في Jetpack Compose، يمكنك استرداد السياق الحالي باستخدام
LocalContext.current واستدعاء context.startActivity().
في ما يلي مثال على كيفية إجراء ذلك:
fun shareText(context: Context) { val sendIntent: Intent = Intent().apply { action = ACTION_SEND putExtra(Intent.EXTRA_TEXT, "This is my text to send.") type = "text/plain" } val shareIntent = Intent.createChooser(sendIntent, null) context.startActivity(shareIntent) }
يمكنك اختياريًا إضافة عناصر إضافية لتضمين المزيد من المعلومات، مثل مستلمي الرسائل الإلكترونية
(EXTRA_EMAIL أو
EXTRA_CC أو
EXTRA_BCC)
أو موضوع الرسالة الإلكترونية
(EXTRA_SUBJECT).
ملاحظة: تتوقّع بعض تطبيقات البريد الإلكتروني، مثل Gmail، استخدام
String[] لإضافات مثل
EXTRA_EMAIL وEXTRA_CC. استخدِم
putExtra(String, String[])
لإضافة هذه العناصر إلى هدفك.
إرسال محتوى ثنائي
يمكنك مشاركة البيانات الثنائية باستخدام الإجراء ACTION_SEND.
اضبط نوع MIME المناسب وضَع معرّف موارد منتظم (URI) للبيانات في السمة الإضافية EXTRA_STREAM، كما هو موضّح في المثال التالي.
يُستخدم هذا الإجراء شائع الاستخدام لمشاركة صورة، ولكن يمكن استخدامه لمشاركة أي نوع من المحتوى الثنائي.
fun shareBinaryContent(context: Context) { val shareIntent: Intent = Intent().apply { action = ACTION_SEND // Example: content://com.google.android.apps.photos.contentprovider/... val imageUri: Uri = Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/1") putExtra(Intent.EXTRA_STREAM, imageUri) type = "image/jpeg" } context.startActivity(Intent.createChooser(shareIntent, null)) }
يحتاج التطبيق المستلِم إلى إذن للوصول إلى البيانات التي يشير إليها Uri. هناك طريقتان مقترَحتان لإجراء ذلك:
- يمكنك تخزين البيانات في
ContentProviderالخاص بك، مع التأكّد من أنّ التطبيقات الأخرى لديها الإذن الصحيح للوصول إلى موفّر المحتوى. الآلية المفضّلة لمنح إذن الوصول هي استخدام أذونات لكل معرّف موارد منتظم (URI)، وهي أذونات مؤقتة تمنح إذن الوصول إلى التطبيق المستلِم فقط. لإنشاءContentProviderمثل هذا، استخدِم فئة المساعدFileProvider. - استخدِم نظام
MediaStore. يُستخدمMediaStoreبشكل أساسي لأنواع MIME للفيديو والصوت والصور. ومع ذلك، بدءًا من الإصدار Android 3.0 (المستوى 11 من واجهة برمجة التطبيقات)، يمكنه أيضًا تخزين أنواع غير الوسائط. لمزيد من المعلومات، يُرجى الاطّلاع علىMediaStore.Files. يمكن إدراج الملفات فيMediaStoreباستخدامscanFile()، وبعد ذلك يتم تمريرUriعلى نمطcontent://مناسب للمشاركة إلى دالة الاستدعاءonScanCompleted()المقدَّمة. يُرجى العِلم أنّه بعد إضافة المحتوى إلى نظام "MediaStore"، يمكن لأي تطبيق على الجهاز الوصول إليه.
استخدام نوع MIME الصحيح
يُرجى تقديم نوع MIME الأكثر تحديدًا والمتاح للبيانات التي يتم إرسالها. على سبيل المثال، استخدِم text/plain عند مشاركة نص عادي. في ما يلي بعض أنواع MIME الشائعة
عند إرسال البيانات في Android:
| يسجّل المستلِمون في | يرسل المرسِلون |
|---|---|
text/* |
|
image/* |
|
video/* |
|
| امتدادات الملفات المتوافقة | application/pdf |
لتحديد نوع MIME ديناميكيًا في وقت التشغيل بدلاً من ترميزه بشكل ثابت، استخدِم الطرق التالية:
- بالنسبة إلى معرّفات الموارد المنتظمة (URI) من النوع
content://(مثل تلك التي يوفّرهاFileProviderأوMediaStore)، يمكنك استدعاءContentResolver.getType(). - بالنسبة إلى امتدادات الملفات، يمكنك استدعاء
MimeTypeMap.getSingleton().getMimeTypeFromExtension(). - إذا كنت تستخدم Storage Access Framework، يمكنك أيضًا طلب البحث عن
DocumentFile.getType().
إذا لم تتمكّن من تحديد نوع MIME معيّن، استخدِم application/octet-stream للبيانات الثنائية العامة أو */* كحلّ أخير.
لمزيد من المعلومات حول أنواع MIME، يُرجى الاطّلاع على السجلّ الرسمي لأنواع وسائط MIME في هيئة الأرقام المخصصة للإنترنت (IANA).
قد تعرض "قائمة مشاركة البيانات من Android" معاينة للمحتوى، استنادًا إلى نوع MIME المقدَّم. لا تتوفّر بعض الميزات المسبقة إلا لأنواع معيّنة.
مشاركة عدة أجزاء من المحتوى
لمشاركة عدة أجزاء من المحتوى، استخدِم الإجراء ACTION_SEND_MULTIPLE مع قائمة بمعرّفات الموارد المنتظمة (URI) التي تشير إلى المحتوى. يختلف نوع MIME وفقًا
لمزيج المحتوى الذي تشاركه. على سبيل المثال، إذا شاركت ثلاث صور بتنسيق JPEG، يمكنك استخدام النوع
"image/jpg". بالنسبة إلى مزيج من أنواع الصور، استخدِم "image/*" لمطابقة
نشاط يتعامل مع أي نوع من الصور. على الرغم من إمكانية مشاركة مزيج من الأنواع، تجنَّب
القيام بذلك، لأنّه
ليس واضحًا للمستلِم ما هو المقصود إرساله. إذا كان من الضروري إرسال أنواع متعددة، استخدِم
"*/*". ويعود الأمر إلى التطبيق المستلِم لتحليل
بياناتك ومعالجتها. وفي ما يلي مثال لذلك:
fun shareMultiple(context: Context) { val imageUris: ArrayList<Uri> = arrayListOf( Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/1"), Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/2") ) val shareIntent = Intent().apply { action = Intent.ACTION_SEND_MULTIPLE putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris) type = "image/*" } context.startActivity(Intent.createChooser(shareIntent, null)) }
تأكَّد من أنّ عناصر Uri المقدَّمة تشير إلى بيانات يمكن لتطبيق مستلِم الوصول إليها.
إضافة محتوى وافٍ إلى معاينات النصوص
بدءًا من الإصدار 10 من نظام التشغيل Android (المستوى 29 من واجهة برمجة التطبيقات)، تعرض "قائمة مشاركة البيانات" من Android معاينة للنص الذي تتم مشاركته. في بعض الحالات، قد يصعب فهم النص الذي تتم مشاركته. لنفترض أنّك تريد مشاركة عنوان URL
معقّد مثل https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4 ويمكن أن تمنح المعاينة الأكثر ثراءً المستخدمين الثقة بشأن ما تتم مشاركته.
إذا كنت تعرض معاينة للنص، يمكنك ضبط عنوان أو صورة مصغّرة أو كليهما. أضِف وصفًا إلى
Intent.EXTRA_TITLE قبل الاتصال بالرقم Intent.createChooser()، وأضِف
صورة مصغّرة ذات صلة باستخدام ClipData.
ملاحظة: يتم توفير معرّف الموارد المنتظم لمحتوى الصورة من خلال
FileProvider، عادةً من <cache-path> تم ضبطه.
لمزيد من المعلومات، يُرجى الاطّلاع على مشاركة الملفات. تأكَّد من منح Sharesheet الأذونات المناسبة لقراءة أي صورة تريد استخدامها كصورة مصغّرة. لمزيد من المعلومات، يُرجى الاطّلاع على Intent.FLAG_GRANT_READ_URI_PERMISSION.
وفي ما يلي مثال لذلك:
fun richContentToTextPreviewShares(context: Context) { val share = Intent.createChooser( Intent().apply { action = ACTION_SEND putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/") // (Optional) Here you're setting the title of the content putExtra(Intent.EXTRA_TITLE, "Introducing content previews") // (Optional) Here you're passing a content URI to an image to be displayed data = Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/A123456789") flags = Intent.FLAG_GRANT_READ_URI_PERMISSION }, null ) context.startActivity(share) }
تبدو المعاينة على النحو التالي:
إضافة إجراءات مخصّصة إلى قائمة المشاركة
في الإصدار 14 من Android (المستوى 34 لواجهة برمجة التطبيقات) والإصدارات الأحدث، يمكن للتطبيقات إضافة إجراءات مخصّصة إلى قائمة مشاركة البيانات من Android.
تظهر الإجراءات المخصّصة كرموز إجراءات صغيرة في أعلى "قائمة مشاركة البيانات من Android"، ويمكن للتطبيقات
تحديد أي Intent كالإجراء الذي يتم تنفيذه عند النقر على الرمز.
لإضافة إجراءات مخصّصة في "قائمة مشاركة البيانات من Android"، عليك أولاً إنشاء
ChooserAction باستخدام ChooserAction.Builder.
يمكنك تحديد PendingIntent كالإجراء الذي يتم تنفيذه عند النقر على الرمز. أنشئ مصفوفة تحتوي على جميع الإجراءات المخصّصة وحدِّدها على أنّها
EXTRA_CHOOSER_CUSTOM_ACTIONS
للمشاركة Intent.
fun sharesheetCustomActions(context: Context, previewText: String) { val sendIntent = Intent(ACTION_SEND) .setType("text/plain") .putExtra(Intent.EXTRA_TEXT, previewText) val shareIntent = Intent.createChooser(sendIntent, null) val customActions = arrayOf( ChooserAction.Builder( Icon.createWithResource(context, R.drawable.ic_logo), "Custom", PendingIntent.getBroadcast( context, 1, Intent(Intent.ACTION_VIEW), PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT ) ).build() ) shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions) context.startActivity(shareIntent) }
إضافة أهداف مخصّصة
تتيح لك "قائمة مشاركة البيانات من Android" تحديد ما يصل إلى هدفَين مخصّصَين للنشاط
يتم إدراجهما قبل التطبيقات المقترَحة باستخدام Intent.EXTRA_INITIAL_INTENTS.
بالنسبة إلى أهداف "المشاركة المباشرة" (مثل المحادثات أو جهات الاتصال)، يمكنك نشر الاختصارات الديناميكية باستخدام
ShortcutManagerCompat بدلاً من ذلك
(يُرجى الاطّلاع على توفير أهداف "المشاركة المباشرة"):
أضِف Intent.EXTRA_INITIAL_INTENTS إلى
Intent المشاركة بعد استدعاء
Intent.createChooser():
val sendIntent = Intent(ACTION_SEND).apply { type = "text/plain" putExtra(Intent.EXTRA_TEXT, previewText) } val customIntent = Intent().apply { component = ComponentName(context.packageName, "${context.packageName}.CustomActivity") } val shareIntent = Intent.createChooser(sendIntent, null).apply { putExtra( Intent.EXTRA_INITIAL_INTENTS, arrayOf(customIntent) ) } context.startActivity(shareIntent)
استخدِم هذه الميزة بحذر. كل Intent مخصّص تضيفه يقلّل من العدد الذي يقترحه النظام. بشكل عام، تجنَّب إضافة أهداف مخصّصة. من الأمثلة الشائعة المناسبة لإضافة
Intent.EXTRA_INITIAL_INTENTS هو توفير إجراءات إضافية يمكن للمستخدمين اتخاذها بشأن المحتوى
المشترَك. على سبيل المثال، يشارك مستخدم صورًا ويتم استخدام Intent.EXTRA_INITIAL_INTENTS
للسماح له بإرسال رابط بدلاً من ذلك.
استبعاد أهداف معيّنة حسب المكوّن
يمكنك استبعاد أهداف معيّنة من خلال تقديم Intent.EXTRA_EXCLUDE_COMPONENTS.
يُرجى تنفيذ هذا الإجراء فقط لإزالة الأهداف التي يمكنك التحكّم فيها. من حالات الاستخدام الشائعة إخفاء أهداف المشاركة في تطبيقك عندما يشارك المستخدمون المحتوى من داخل تطبيقك، لأنّهم على الأرجح ينوون مشاركة المحتوى خارج تطبيقك.
أضِف Intent.EXTRA_EXCLUDE_COMPONENTS إلى intent بعد استدعاء Intent.createChooser():
fun excludeSpecificTargets(context: Context) { val share = Intent.createChooser(Intent(ACTION_SEND), null).apply { // Only use for components you have control over val excludedComponentNames = arrayOf(ComponentName("com.example.android", "ExampleClass")) putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames) } context.startActivity(share) }
الحصول على معلومات حول المشاركة
قد يكون من المفيد معرفة متى يشارك المستخدمون المحتوى والهدف الذي يختارونه. تتيح لك "قائمة مشاركة البيانات من Android" الحصول على هذه المعلومات من خلال توفير ComponentName للوجهات التي يختارها المستخدمون باستخدام IntentSender.
أولاً، أنشئ PendingIntent لـ BroadcastReceiver وقدِّم
IntentSender في Intent.createChooser():
fun infoAboutSharing(context: Context, requestCode: Int) { var share = Intent(ACTION_SEND) // ... val pi = PendingIntent.getBroadcast( context, requestCode, Intent(context, ShareBroadcastReceiver::class.java), PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) share = Intent.createChooser(share, null, pi.intentSender) context.startActivity(share) }
تلقّي معاودة الاتصال في MyBroadcastReceiver والبحث في
Intent.EXTRA_CHOOSER_RESULT:
override fun onReceive(context: Context?, intent: Intent) { val TAG = ShareBroadcastReceiver::class.simpleName val chooserResult: ChooserResult? = IntentCompat.getParcelableExtra( intent, Intent.EXTRA_CHOOSER_RESULT, ChooserResult::class.java, ) chooserResult?.let { Log.i(TAG, "Share callback: isShortcut: ${it.isShortcut}, type: ${typeToString(it.type)}, componentName: ${it.selectedComponent}", ) } ?: Log.i(TAG, "chooserResult is null") }
لمزيد من المعلومات، يُرجى الاطّلاع على نموذج مشاركة المنصة.
استخدام أداة Android intent resolver
ACTION_SENDمن الأفضل استخدام أداة حلّ الأهداف في Android عند إرسال البيانات إلى تطبيق آخر كجزء من عملية محدّدة جيدًا لإنجاز المهام.
لاستخدام أداة حلّ الأهداف في Android، أنشئ هدفًا وأضِف عناصر إضافية كما تفعل عند استدعاء
قائمة مشاركة البيانات من Android. ومع ذلك، لا تتصل بالرقم
Intent.createChooser().
إذا كانت هناك عدة تطبيقات مثبَّتة تتضمّن فلاتر تتطابق مع
ACTION_SEND
ونوع MIME، يعرض النظام مربّع حوار لإزالة الغموض يُعرف باسم محلِّل الأهداف
يتيح للمستخدم اختيار وجهة للمشاركة معها. إذا تطابق تطبيق واحد، يتم تشغيله.
إليك مثال على كيفية استخدام أداة Android intent resolver لإرسال نص:
fun intentResolver(context: Context) { val sendIntent: Intent = Intent().apply { action = ACTION_SEND putExtra(Intent.EXTRA_TEXT, "This is my text to send.") type = "text/plain" } context.startActivity(sendIntent) }
مزيد من المعلومات
لمزيد من المعلومات حول إرسال البيانات، يُرجى الاطّلاع على الطلبات وفلاتر الطلبات.