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

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

משתמשים באפליקציות אחרות שולחים נתונים לאפליקציה שלכם לעיתים קרובות דרך Android Sharesheet או פותר הכוונות. אפליקציות ששולחות נתונים לאפליקציה שלכם צריכות להגדיר סוג 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 מעדכנים את המערכת אילו כוונות (intents) רכיב של אפליקציה מקבל. בדומה לאופן שבו יצרתם כוונה עם פעולה 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>

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

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

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

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

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.