מערכת Android משתמשת בכוונות (Intents) ובתוספות המשויכות שלהם כדי לאפשר למשתמשים לשתף מידע במהירות ובקלות באמצעות האפליקציות המועדפות עליהם.
ב-Android יש שתי דרכים שבהן משתמשים יכולים לשתף נתונים בין אפליקציות:
- הקובץ לשיתוף ב-Android מיועד בעיקר לשליחת תוכן מחוץ לאפליקציה או ישירות למשתמש אחר. לדוגמה, שיתוף כתובת URL עם חבר.
- מקודד הכוונות ב-Android מתאים במיוחד להעברת נתונים לשלב הבא של משימה מוגדרת היטב. לדוגמה, פתיחת קובץ PDF מהאפליקציה ומתן אפשרות למשתמשים לבחור את הכלי המועדף לצפייה בקובץ.
כשיוצרים כוונה, מציינים את הפעולה שהכוונה צריכה לבצע.
מערכת Android משתמשת בפעולה ACTION_SEND
כדי לשלוח נתונים מפעילות אחת לאחרת,
גם אם הן נמצאות בגבולות של תהליכים שונים. צריך לציין את הנתונים ואת הסוג שלהם. המערכת מזהה באופן אוטומטי את הפעילויות התואמות שיכולות לקבל את הנתונים ומציגה אותן למשתמש. במקרה של מקודד הכוונות,
אם רק פעילות אחת יכולה לטפל בכוונת המשתמש, הפעילות הזו מתחילה באופן מיידי.
למה כדאי להשתמש בקובץ לשיתוף ב-Android
מומלץ מאוד להשתמש בקובץ לשיתוף ב-Android כדי לספק חוויה עקבית למשתמשים באפליקציות שונות. אל תציגו רשימה משלכם של יעדי שיתוף באפליקציה, ואל תיצרו וריאציות משלכם של הקובץ לשיתוף.
הקובץ לשיתוף ב-Android מאפשר למשתמשים לשתף מידע עם האדם הנכון, עם הצעות רלוונטיות לאפליקציות, והכול בלחיצה אחת. הקובץ לשיתוף יכול להציע יעדים שלא זמינים לפתרונות מותאמים אישית, והוא משתמש בדירוג עקבי. הסיבה לכך היא שהקובץ לשיתוף יכול לקחת בחשבון מידע על פעילות באפליקציות ופעילות של משתמשים שזמין רק למערכת.
בנוסף, יש בקובץ לשיתוף ב-Android הרבה תכונות שימושיות למפתחים. לדוגמה, אתם יכולים:
- לבדוק מתי ועם מי המשתמשים משתפים
- להוסיף
ChooserTargetמותאם אישית ויעדי אפליקציה - לראות תצוגות מקדימות של תוכן בפורמט טקסט עשיר, החל מ-Android 10 (רמת API 29)
- להחריג יעדים שתואמים לשמות רכיבים ספציפיים
שימוש בקובץ לשיתוף ב-Android
לכל סוגי השיתוף, צריך ליצור כוונה ולהגדיר את הפעולה שלה ל-Intent.ACTION_SEND.
כדי להציג את הקובץ לשיתוף ב-Android, קוראים ל-Intent.createChooser() ומעבירים לו את האובייקט Intent.
הוא יחזיר גרסה של הכוונה שלכם שתמיד מציגה את הקובץ לשיתוף ב-Android.
שליחת תוכן טקסט
השימוש הכי פשוט ונפוץ בקובץ לשיתוף ב-Android הוא שליחת תוכן טקסט מפעילות אחת לפעילות אחרת. לדוגמה, ברוב הדפדפנים אפשר לשתף את כתובת ה-URL של הדף שמוצג כרגע כטקסט עם אפליקציה אחרת. זה שימושי לשיתוף מאמר או אתר עם חברים באמצעות אימייל או רשת חברתית. דוגמה:
Kotlin
val sendIntent: Intent = Intent().apply { action = Intent.ACTION_SEND putExtra(Intent.EXTRA_TEXT, "This is my text to send.") type = "text/plain" } val shareIntent = Intent.createChooser(sendIntent, null) startActivity(shareIntent)
Java
Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send."); sendIntent.setType("text/plain"); Intent shareIntent = Intent.createChooser(sendIntent, null); 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, כמו בדוגמה הבאה.
השימוש הנפוץ הוא לשיתוף תמונה, אבל אפשר להשתמש בשיטה הזו לשיתוף של כל סוג של תוכן בינארי.
Kotlin
val shareIntent: Intent = Intent().apply { action = Intent.ACTION_SEND // Example: content://com.google.android.apps.photos.contentprovider/... putExtra(Intent.EXTRA_STREAM, uriToImage) type = "image/jpeg" } startActivity(Intent.createChooser(shareIntent, null))
Java
Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); // Example: content://com.google.android.apps.photos.contentprovider/... shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage); shareIntent.setType("image/jpeg"); startActivity(Intent.createChooser(shareIntent, null));
לאפליקציה המקבלת נדרשת הרשאה לגשת לנתונים שאליהם מצביע Uri. יש שתי דרכים מומלצות לעשות את זה:
- לאחסן את הנתונים ב
ContentProviderשלכם ולהקפיד שלאפליקציות אחרות תהיה הרשאה מתאימה לגשת לספק. הדרך המומלצת להעניק גישה היא באמצעות הרשאות לפי URI, כי הן זמניות ומעניקות גישה רק לאפליקציה המקבלת. דרך קלה ליצורContentProviderכזה היא להשתמש במחלקה המסייעתFileProvider. - להשתמש ב-
MediaStoreשל המערכת. MediaStoreמיועד בעיקר לסוגי MIME של סרטונים, אודיו ותמונות. עם זאת, החל מ-Android 3.0 (רמת API 11), אפשר גם לאחסן בו סוגים שאינם מדיה. מידע נוסף זמין במאמרMediaStore.Files. אפשר להוסיף קבצים ל-MediaStoreבאמצעותscanFile(), ואז קובץUriבסגנוןcontent://שמתאים לשיתוף מועבר אל הקריאה החוזרת (callback) שצוינה ב-onScanCompleted(). חשוב לדעת שאחרי שהתוכן נוסף למערכתMediaStore, כל אפליקציה במכשיר יכולה לגשת אליו.
שימוש בסוג ה-MIME הנכון
ציינן את סוג ה-MIME הספציפי ביותר שזמין לנתונים שאתם שולחים. לדוגמה, משתמשים ב-text/plain כשמשתפים טקסט פשוט. אלה כמה סוגי MIME נפוצים כששולחים נתונים פשוטים ב-Android:
| למה הנמענים נרשמים | מה שולחים |
|---|---|
text/* |
|
`image/*` |
|
video/* |
|
| סיומות קבצים נתמכות | application/pdf |
מידע נוסף על סוגי MIME זמין במאגר הרשמי של סוגי מדיה של MIME ב-IANA.
יכול להיות שהקובץ לשיתוף ב-Android יציג תצוגה מקדימה של התוכן, בהתאם לסוג ה-MIME שסופק. חלק מהתכונות בגרסת טרום-השקה זמינות רק לסוגים מסוימים.
שיתוף של כמה פריטי תוכן
כדי לשתף כמה פריטי תוכן, משתמשים בפעולה ACTION_SEND_MULTIPLE יחד עם רשימה של ביטויי URI שמפנים לתוכן. סוג ה-MIME משתנה בהתאם לשילוב התוכן שמשתפים. לדוגמה, אם משתפים שלוש תמונות בפורמט JPEG, משתמשים בסוג "image/jpg". אם רוצים לבחור תמונות מסוגים שונים, צריך להשתמש ב-"image/*" כדי להתאים פעילות שמטפלת בכל סוג של תמונה. אתם יכולים לשתף שילוב של סוגים, אבל אנחנו לא ממליצים על כך, כי לא יהיה ברור לנמען מה אתם רוצים לשלוח. אם צריך לשלוח כמה סוגים, משתמשים ב-"*/*". האפליקציה המקבלת תנתח ותעבד את הנתונים. הנה דוגמה:
Kotlin
val imageUris: ArrayList<Uri> = arrayListOf( // Add your image URIs here imageUri1, imageUri2 ) val shareIntent = Intent().apply { action = Intent.ACTION_SEND_MULTIPLE putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris) type = "image/*" } startActivity(Intent.createChooser(shareIntent, null))
Java
ArrayList<Uri> imageUris = new ArrayList<Uri>(); imageUris.add(imageUri1); // Add your image URIs here imageUris.add(imageUri2); Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE); shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris); shareIntent.setType("image/*"); startActivity(Intent.createChooser(shareIntent, null));
חשוב לוודא שהאובייקטים של Uri שסופקו מפנים לנתונים שאפליקציה מקבלת יכולה לגשת אליהם.
הוספת תוכן עשיר לתצוגות מקדימות של טקסט
החל מ-Android 10 (רמת API 29), הקובץ לשיתוף ב-Android מציג תצוגה מקדימה של הטקסט שמשותף. במקרים מסוימים, קשה להבין את הטקסט שמשותף. כדאי לשתף כתובת URL מורכבת כמו https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4. תצוגה מקדימה מפורטת יותר יכולה להבהיר למשתמשים מה אתם משתפים.
אם אתם צופים בתצוגה מקדימה של טקסט, אתם יכולים להגדיר כותרת, תמונה ממוזערת או גם וגם. מוסיפים תיאור ל-Intent.EXTRA_TITLE לפני ששולחים קריאה ל-Intent.createChooser(), וגם מוסיפים תמונה ממוזערת רלוונטית באמצעות ClipData.
הערה: ה-URI של תוכן התמונה מסופק מ-FileProvider, בדרך כלל מ-<cache-path> מוגדר.
מידע נוסף זמין במאמר בנושא שיתוף קבצים. חשוב לוודא שהקובץ לשיתוף קיבל את ההרשאות המתאימות כדי לקרוא כל תמונה שרוצים להשתמש בה כתמונה ממוזערת. מידע נוסף זמין ב-Intent.FLAG_GRANT_READ_URI_PERMISSION.
הנה דוגמה:
Kotlin
val share = Intent.createChooser(Intent().apply { action = Intent.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 = contentUri flags = Intent.FLAG_GRANT_READ_URI_PERMISSION }, null) startActivity(share)
Java
Intent sendIntent = new Intent(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/"); // (Optional) Here you're setting the title of the content sendIntent.putExtra(Intent.EXTRA_TITLE, "Introducing content previews"); // (Optional) Here you're passing a content URI to an image to be displayed sendIntent.setData(contentUri); sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // Show the Sharesheet startActivity(Intent.createChooser(sendIntent, null));
תצוגה מקדימה לדוגמה:
הוספת פעולות מותאמות אישית לקובץ לשיתוף
צילום מסך של פעולות מותאמות אישית בקובץ לשיתוף ב-Android.
ב-Android 14 (רמת API 34) ומעלה, אפליקציות יכולות להוסיף פעולות מותאמות אישית לקובץ לשיתוף של Android.
הפעולות המותאמות אישית מוצגות כסמלי פעולה קטנים בחלק העליון של הקובץ לשיתוף ב-Android, ואפליקציות יכולות לציין כל Intent כפעולה שמופעלת כשלוחצים על הסמל.
כדי להוסיף פעולות מותאמות אישית לקובץ לשיתוף ב-Android, קודם צריך ליצור ChooserAction עם ChooserAction.Builder.
אפשר לציין PendingIntent כפעולה שמופעלת כשלוחצים על הסמל. יוצרים מערך שמכיל את כל הפעולות המותאמות אישית ומציינים אותו כ-EXTRA_CHOOSER_CUSTOM_ACTIONS
של השיתוף Intent.
Kotlin
val sendIntent = Intent(Intent.ACTION_SEND) .setType("text/plain") .putExtra(Intent.EXTRA_TEXT, text) val shareIntent = Intent.createChooser(sendIntent, null) val customActions = arrayOf( ChooserAction.Builder( Icon.createWithResource(context, R.drawable.ic_custom_action), "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)
Java
Intent sendIntent = new Intent(Intent.ACTION_SEND) .setType("text.plain") .putExtra(Intent.EXTRA_TEXT, text); Intent shareIntent = Intent.createChooser(sendIntent, null); ChooserAction[] actions = new ChooserAction[]{ new ChooserAction.Builder( Icon.createWithResource(context, R.drawable.ic_custom_action), "Custom", PendingIntent.getBroadcast( context, 1, new Intent(Intent.ACTION_VIEW), PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT ) ).build() }; shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, actions); context.startActivity(shareIntent);
הוספת יעדים בהתאמה אישית
בקובץ לשיתוף ב-Android אפשר לציין עד שני אובייקטים של ChooserTarget שמוצגים לפני קיצורי הדרך לשיתוף והיעדים לבחירה שנטענו מ-ChooserTargetServices. אפשר גם לציין עד שתי כוונות שמפנות לפעילויות שמופיעות לפני ההצעות לאפליקציות:
מוסיפים את Intent.EXTRA_CHOOSER_TARGETS ואת Intent.EXTRA_INITIAL_INTENTS ל-Intent של השיתוף אחרי הקריאה ל-Intent.createChooser():
Kotlin
val share = Intent.createChooser(myShareIntent, null).apply { putExtra(Intent.EXTRA_CHOOSER_TARGETS, myChooserTargetArray) putExtra(Intent.EXTRA_INITIAL_INTENTS, myInitialIntentArray) }
Java
Intent shareIntent = Intent.createChooser(sendIntent, null); share.putExtra(Intent.EXTRA_CHOOSER_TARGETS, myChooserTargetArray); share.putExtra(Intent.EXTRA_INITIAL_INTENTS, myInitialIntentArray);
חשוב להשתמש בתכונה הזו בזהירות. כל Intent ו-ChooserTarget מותאמים אישית שתוסיפו יקטינו את המספר שהמערכת מציעה. בדרך כלל אנחנו לא ממליצים להוסיף יעדים בהתאמה אישית. דוגמה נפוצה לשימוש ב-Intent.EXTRA_INITIAL_INTENTS היא הוספה של פעולות נוספות שהמשתמשים יכולים לבצע בתוכן משותף. לדוגמה, משתמש משתף תמונות ו-Intent.EXTRA_INITIAL_INTENTS משמש כדי לאפשר לו לשלוח קישור במקום. דוגמה נפוצה לשימוש מתאים ב-Intent.EXTRA_CHOOSER_TARGETS
היא הצגה של אנשים או מכשירים רלוונטיים שהאפליקציה מספקת.
החרגה של יעדים ספציפיים לפי רכיב
אפשר להחריג יעדים ספציפיים על ידי ציון Intent.EXTRA_EXCLUDE_COMPONENTS.
מומלץ שתעשו את זה רק כדי להסיר יעדים שיש לכם שליטה עליהם. תרחיש נפוץ לשימוש הוא הסתרת יעדי השיתוף של האפליקציה כשמשתמשים משתפים מתוך האפליקציה, כי סביר להניח שהם רוצים לשתף מחוץ לאפליקציה.
מוסיפים Intent.EXTRA_EXCLUDE_COMPONENTS לכוונה אחרי הקריאה ל-Intent.createChooser():
Kotlin
val share = Intent.createChooser(Intent(), null).apply { // Only use for components you have control over val excludedComponentNames = arrayOf(ComponentName("com.example.android", "ExampleClass")) putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames) }
Java
Intent shareIntent = Intent.createChooser(new Intent(), null); // Only use for components you have control over ComponentName[] excludedComponentNames = { new ComponentName("com.example.android", "ExampleClass") }; shareIntent.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames);
מידע על שיתוף
יכול להיות שימושי לדעת מתי המשתמשים משתפים ואיזה יעד הם בוחרים. הקובץ לשיתוף ב-Android מאפשר לקבל את המידע הזה עם ComponentName של יעדים שהמשתמשים בוחרים באמצעות IntentSender.
קודם יוצרים PendingIntent בשביל BroadcastReceiver ומזינים את IntentSender ב-Intent.createChooser():
Kotlin
var share = Intent(Intent.ACTION_SEND) // ... val pi = PendingIntent.getBroadcast( myContext, requestCode, Intent(myContext, MyBroadcastReceiver::class.java), PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) share = Intent.createChooser(share, null, pi.intentSender)
Java
Intent share = new Intent(ACTION_SEND); ... PendingIntent pi = PendingIntent.getBroadcast(myContext, requestCode, new Intent(myContext, MyBroadcastReceiver.class), PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); share = Intent.createChooser(share, null, pi.getIntentSender());
קריאה חוזרת התקבלה ב-MyBroadcastReceiver. אפשר לבדוק ב-Intent.EXTRA_CHOOSER_RESULT:
Kotlin
override fun onReceive(context: Context, intent: Intent) { ... 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") }
Java
@Override public void onReceive(Context context, Intent intent) { ... ChooserResult chooserResult = intent.getParcelableExtra(EXTRA_CHOOSER_RESULT); Log.i( TAG, "Share callback: isShortcut: " + chooserResult.isShortcut() + ", type: " + chooserResult.getType() + ", componentName: " + chooserResult.getSelectedComponent() ); }
הוספת פעולות מותאמות אישית לקובץ לשיתוף
ב-Android 14 (רמת API 34) ומעלה, אפליקציות יכולות להוסיף פעולות מותאמות אישית לקובץ לשיתוף של Android.
יצירת ChooserAction
עם
ChooserAction.Builder.
אפשר לציין PendingIntent כפעולה שמופעלת כשלוחצים על הסמל. יוצרים מערך שמכיל את כל הפעולות המותאמות אישית ומציינים אותו כ-EXTRA_CHOOSER_CUSTOM_ACTIONS
של השיתוף Intent.
Kotlin
val sendIntent = Intent(Intent.ACTION_SEND) .setType("text/plain") .putExtra(Intent.EXTRA_TEXT, text) val shareIntent = Intent.createChooser(sendIntent, null) val customActions = arrayOf( ChooserAction.Builder( Icon.createWithResource(context, R.drawable.ic_custom_action), "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)
Java
Intent sendIntent = new Intent(Intent.ACTION_SEND) .setType("text.plain") .putExtra(Intent.EXTRA_TEXT, text); Intent shareIntent = Intent.createChooser(sendIntent, null); ChooserAction[] actions = new ChooserAction[]{ new ChooserAction.Builder( Icon.createWithResource(context, R.drawable.ic_custom_action), "Custom", PendingIntent.getBroadcast( context, 1, new Intent(Intent.ACTION_VIEW), PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT ) ).build() }; shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, actions); context.startActivity(shareIntent);
שימוש במקודד הכוונות ב-Android
צילום מסך של מקודד הכוונות של ACTION_SEND.
השימוש במקודד הכוונות של Android מומלץ כששולחים נתונים לאפליקציה אחרת כחלק מתהליך מוגדר היטב.
כדי להשתמש במקודד הכוונות של Android, יוצרים כוונה עם תוספות כמו בהפעלה של קובץ לשיתוף ב-Android. עם זאת, אל תשלחו קריאה אל Intent.createChooser().
אם יש כמה אפליקציות מותקנות עם מסננים שתואמים ל-ACTION_SEND ולסוג ה-MIME, המערכת מציגה תיבת דו-שיח לביטול דו-משמעות שנקראת מקודד הכוונות, שמאפשרת למשתמש לבחור את היעד לשיתוף. אם יש התאמה לאפליקציה אחת, היא מופעלת.
דוגמה לשימוש במקודד הכוונת של Android לשליחת טקסט:
Kotlin
val sendIntent: Intent = Intent().apply { action = Intent.ACTION_SEND putExtra(Intent.EXTRA_TEXT, "This is my text to send.") type = "text/plain" } startActivity(sendIntent)
Java
Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send."); sendIntent.setType("text/plain"); startActivity(sendIntent);
מידע נוסף
מידע נוסף על שליחת נתונים זמין במאמר בנושא כוונות ומסנני כוונות.