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

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

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

  • Activity עם תג intent-filter תואם במניפסט
  • שיתוף קיצורי דרך שפורסמו על ידי האפליקציה.

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

סוגי MIME נתמכים

מומלץ שאפליקציה תוכל לקבל את הטווח הרחב ביותר האפשרי של סוגי MIME. לדוגמה, אפליקציית הודעות שנועדה לשליחת טקסט, תמונות וסרטונים, צריכה לתמוך באופן אידיאלי בקבלה של text/*, image/* ו-video/*. אלה כמה סוגים נפוצים של 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 ב-IANA.

יצירת יעדים לשיתוף ישיר

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

קבלת נתונים באמצעות פעילות

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

עדכון המניפסט

מסנני Intent מודיעים למערכת אילו אובייקטים מסוג Intent רכיב אפליקציה מקבל. בדומה לאופן שבו יצרתם כוונה עם פעולה ACTION_SEND בשיעור שליחת נתונים פשוטים לאפליקציות אחרות, אתם יוצרים מסנני כוונות כדי לקבל כוונות עם הפעולה הזו. מגדירים מסנן Intent במניפסט באמצעות הרכיב <intent-filter>. לדוגמה, אם האפליקציה שלכם מטפלת בקבלת תוכן טקסט, מניפסט שכולל תמונה אחת או יותר מכל סוג ייראה כמו הקטע הבא:

<activity android:name=".ui.MyActivity" >
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="image/*" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SEND_MULTIPLE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="image/*" />
    </intent-filter>
</activity>

כשמנסים לשתף משהו מאפליקציה אחרת על ידי יצירת intent והעברתו אל startActivity(), האפליקציה שלכם מופיעה כאפשרות בגיליון השיתוף או בכלי לפתרון בעיות של intents ב-Android. אם המשתמש בוחר באפליקציה שלכם, הפעילות המתאימה מתחילה (.ui.MyActivity בדוגמה הקודמת). לאחר מכן, עליכם לטפל בתוכן בצורה המתאימה בקוד ובממשק המשתמש.

טיפול בתוכן הנכנס

כדי לטפל בתוכן שמוצג על ידי Intent, צריך להתקשר אל getIntent() כדי לקבל את האובייקט Intent. אחרי שיש לכם את האובייקט, תוכלו לבדוק את התוכן שלו כדי להחליט מה לעשות הלאה. אם אפשר להתחיל את הפעילות הזו מחלקים אחרים במערכת (כמו מרכז האפליקציות), צריך לקחת את זה בחשבון כשבודקים את הכוונה.

חשוב לבדוק את הנתונים הנכנסים, כי אף פעם אי אפשר לדעת מה אפליקציה אחרת עשויה לשלוח לכם. לדוגמה, יכול להיות שהוגדר סוג MIME שגוי, או שהתמונה שנשלחת גדולה מאוד. בנוסף, חשוב לזכור לעבד נתונים בינאריים ב-thread נפרד ולא ב-thread הראשי ('ממשק המשתמש').

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    when {
        intent?.action == Intent.ACTION_SEND -> {
            if ("text/plain" == intent.type) {
                handleSendText(intent) // Handle text being sent
            } else if (intent.type?.startsWith("image/") == true) {
                handleSendImage(intent) // Handle single image being sent
            }
        }
        intent?.action == Intent.ACTION_SEND_MULTIPLE
                && intent.type?.startsWith("image/") == true -> {
                handleSendMultipleImages(intent) // Handle multiple images being sent
        }
        else -> {
            // Handle other intents, such as being started from the home screen
        }
    }
    ...
}

private fun handleSendText(intent: Intent) {
    intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
        // Update UI to reflect text being shared
    }
}

private fun handleSendImage(intent: Intent) {
    (intent.getParcelableExtra<Parcelable>(Intent.EXTRA_STREAM) as? Uri)?.let {
        // Update UI to reflect image being shared
    }
}

private fun handleSendMultipleImages(intent: Intent) {
    intent.getParcelableArrayListExtra<Parcelable>(Intent.EXTRA_STREAM)?.let {
        // Update UI to reflect multiple images being shared
    }
}

Java

void onCreate (Bundle savedInstanceState) {
    ...
    // Get intent, action and MIME type
    Intent intent = getIntent();
    String action = intent.getAction();
    String type = intent.getType();

    if (Intent.ACTION_SEND.equals(action) && type != null) {
        if ("text/plain".equals(type)) {
            handleSendText(intent); // Handle text being sent
        } else if (type.startsWith("image/")) {
            handleSendImage(intent); // Handle single image being sent
        }
    } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
        if (type.startsWith("image/")) {
            handleSendMultipleImages(intent); // Handle multiple images being sent
        }
    } else {
        // Handle other intents, such as being started from the home screen
    }
    ...
}

void handleSendText(Intent intent) {
    String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
    if (sharedText != null) {
        // Update UI to reflect text being shared
    }
}

void handleSendImage(Intent intent) {
    Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
    if (imageUri != null) {
        // Update UI to reflect image being shared
    }
}

void handleSendMultipleImages(Intent intent) {
    ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
    if (imageUris != null) {
        // Update UI to reflect multiple images being shared
    }
}

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

איך מוודאים שהמשתמשים יזהו את האפליקציה

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

החל מ-Android 10 (רמת API‏ 29), גיליון השיתוף של Android משתמש רק בסמלים שמוגדרים בתג application במניפסט. מערכת Android מתעלמת מסמלים שמוגדרים בתגים intent-filter ו-activity.