שליחת נתונים פשוטים לאפליקציות אחרות

מערכת Android משתמשת ב-Intents ובתוספים המשויכים שלהם כדי לאפשר למשתמשים לשתף מידע במהירות ובקלות באמצעות האפליקציות המועדפות עליהם.

ב-Android יש שתי דרכים שבהן משתמשים יכולים לשתף נתונים בין אפליקציות:

  • גיליון השיתוף ב-Android מיועד בעיקר לשליחת תוכן מחוץ לאפליקציה ו/או ישירות למשתמש אחר. לדוגמה, שיתוף כתובת URL עם חבר.
  • הכלי לפתרון כוונות ב-Android מתאים במיוחד להעברת נתונים לשלב הבא של משימה מוגדרת היטב. לדוגמה, פתיחת קובץ PDF מהאפליקציה ומתן אפשרות למשתמשים לבחור את הכלי המועדף לצפייה בקובץ.

כשיוצרים כוונה, מציינים את הפעולה שהכוונה צריכה לבצע. מערכת Android משתמשת בפעולה ACTION_SEND כדי לשלוח נתונים מפעילות אחת לאחרת, גם אם הן נמצאות בגבולות של תהליכים שונים. צריך לציין את הנתונים ואת הסוג שלהם. המערכת מזהה באופן אוטומטי את הפעילויות התואמות שיכולות לקבל את הנתונים ומציגה אותן למשתמש. במקרה של פותר הכוונות, אם רק פעילות אחת יכולה לטפל בכוונת המשתמש, הפעילות הזו מתחילה באופן מיידי.

למה כדאי להשתמש בקובץ לשיתוף ב-Android

מומלץ מאוד להשתמש בגיליון השיתוף של Android כדי ליצור עקביות למשתמשים באפליקציות שונות. אל תציגו רשימה משלכם של יעדי שיתוף באפליקציה, ואל תיצרו וריאציות משלכם של גיליון השיתוף.

גיליון השיתוף ב-Android מאפשר למשתמשים לשתף מידע עם האדם הנכון, עם הצעות רלוונטיות לאפליקציות, והכול בהקשה אחת. גיליון השיתוף יכול להציע יעדים שלא זמינים לפתרונות מותאמים אישית, והוא משתמש בדירוג עקבי. הסיבה לכך היא שגיליון השיתוף יכול לקחת בחשבון מידע על פעילות באפליקציות ופעילות של משתמשים שזמין רק למערכת.

בנוסף, יש בגיליון השיתוף של Android הרבה תכונות שימושיות למפתחים. לדוגמה, אתם יכולים:

איך משתמשים בקובץ לשיתוף ב-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 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(), ואז מועבר אל פונקציית ה-callback שצוינה onScanCompleted(), קובץ Uri בסגנון content:// שמתאים לשיתוף. חשוב לדעת שאחרי שהתוכן נוסף למערכת MediaStore, כל אפליקציה במכשיר יכולה לגשת אליו.

שימוש בסוג ה-MIME הנכון

צריך לציין את סוג ה-MIME הספציפי ביותר שזמין לנתונים שאתם שולחים. לדוגמה, משתמשים ב-text/plain כשמשתפים טקסט פשוט. אלה כמה סוגי MIME נפוצים כששולחים נתונים פשוטים ב-Android:

הנמענים נרשמים ל השולחים שולחים
text/*
  • text/plain
  • text/rtf
  • text/html
  • text/json
`image/*`
  • image/jpg
  • image/png
  • image/gif
video/*
  • video/mp4
  • video/3gp
סיומות קבצים נתמכות 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_CHOSEN_COMPONENT:

Kotlin

override fun onReceive(context: Context, intent: Intent) {
  ...
  val clickedComponent : ComponentName = intent.getParcelableExtra(EXTRA_CHOSEN_COMPONENT);
}

Java

@Override public void onReceive(Context context, Intent intent) {
  ...
  ComponentName clickedComponent = intent.getParcelableExtra(EXTRA_CHOSEN_COMPONENT);
}

הוספת פעולות מותאמות אישית לגיליון השיתוף

ב-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

צילום מסך של כלי לפתרון בעיות שקשורות ל-Intent‏ ACTION_SEND.

השימוש ב-Android intent resolver מומלץ כששולחים נתונים לאפליקציה אחרת כחלק מתהליך מוגדר היטב.

כדי להשתמש ב-Android intent resolver, יוצרים intent ומוסיפים extras כמו שמוסיפים כדי להפעיל את Android Sharesheet. עם זאת, אין להתקשר אל Intent.createChooser().

אם יש כמה אפליקציות מותקנות עם מסננים שתואמים ל-ACTION_SEND ולסוג ה-MIME, המערכת מציגה תיבת דו-שיח לביטול דו-משמעות שנקראת intent resolver, שמאפשרת למשתמש לבחור את היעד לשיתוף. אם יש התאמה לאפליקציה אחת, היא מופעלת.

דוגמה לשימוש ב-Android intent resolver לשליחת טקסט:

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

מידע נוסף

מידע נוסף על שליחת נתונים זמין במאמר בנושא כוונות ומסנני כוונות.