במסמך הזה מוצגים כמה תרחישי שימוש נפוצים שבהם אפליקציה מקיימת אינטראקציה עם אפליקציות אחרות. בכל קטע מוסבר איך להשיג את הפונקציונליות של האפליקציה עם חשיפה מוגבלת לחבילות. חשוב לקרוא את ההסברים האלה אם האפליקציה מטרגטת ל-Android מגרסה 11 (רמת API 30) ואילך.
כשמשתמשים ב-Intent כדי להפעיל פעילות באפליקציה אחרת, באפליקציה שמיועדת ל-Android 11 ומעלה, הגישה הכי פשוטה היא להפעיל את ה-Intent ולטפל בחריגה ActivityNotFoundException
אם אין אפליקציה זמינה.
אם חלק מהאפליקציה שלכם תלוי בידיעה אם הקריאה אל startActivity()
יכולה להצליח, למשל הצגת ממשק משתמש, צריך להוסיף אלמנט לאלמנט <queries>
של המניפסט של האפליקציה. בדרך כלל זה רכיב <intent>
.
פתיחת כתובות URL
בקטע הזה מתוארות דרכים שונות לפתיחת כתובות URL באפליקציה שמיועדת ל-Android 11 ואילך.
פתיחת כתובות URL בדפדפן או באפליקציה אחרת
כדי לפתוח כתובת URL, משתמשים ב-Intent שמכיל את פעולת ה-Intent ACTION_VIEW
, כמו שמתואר במדריך בנושא טעינת כתובת URL של אתר. אחרי שמפעילים את startActivity()
באמצעות הכוונה הזו, קורה אחד מהדברים הבאים:
- כתובת ה-URL תיפתח באפליקציית דפדפן אינטרנט.
- כתובת ה-URL נפתחת באפליקציה שתומכת בכתובת ה-URL כקישור עומק.
- מופיעה תיבת דו-שיח שמאפשרת למשתמש לבחור באיזו אפליקציה כתובת ה-URL תיפתח.
ActivityNotFoundException
מתרחשת כי לא מותקנת במכשיר אפליקציה שיכולה לפתוח את כתובת ה-URL. (זה לא רגיל).מומלץ שהאפליקציה תזהה ותטפל ב-
ActivityNotFoundException
אם הוא מתרחש.
מכיוון שהשיטה startActivity()
לא דורשת הרשאת גישה של חבילה כדי להתחיל פעילות של אפליקציה אחרת, לא צריך להוסיף אלמנט <queries>
למניפסט של האפליקציה או לבצע שינויים באלמנט <queries>
קיים. זה נכון גם לגבי כוונות משתמש מרומזות וגם לגבי כוונות משתמש מפורשות שפותחות כתובת URL.
בדיקה אם דפדפן זמין
במקרים מסוימים, יכול להיות שהאפליקציה תרצה לוודא שיש לפחות דפדפן אחד במכשיר, או שדפדפן מסוים הוא דפדפן ברירת המחדל, לפני שתנסה לפתוח כתובת URL. במקרים כאלה, צריך לכלול את הרכיב <intent>
הבא כחלק מהרכיב <queries>
במניפסט:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" /> </intent>
כשמתקשרים אל queryIntentActivities()
ומעבירים כוונת אינטרנט כארגומנט, הרשימה שמוחזרת כוללת במקרים מסוימים את אפליקציות הדפדפן הזמינות. הרשימה לא כוללת אפליקציות דפדפן אם המשתמש הגדיר שכתובת ה-URL תיפתח באפליקציה שאינה דפדפן כברירת מחדל.
פתיחת כתובות URL בכרטיסיות מותאמות אישית
כרטיסיות מותאמות אישית מאפשרות לאפליקציה להתאים אישית את המראה והתחושה של הדפדפן. אתם יכולים לפתוח כתובת URL בכרטיסייה מותאמת אישית בלי להוסיף או לשנות את רכיב <queries>
במניפסט האפליקציה.
עם זאת, יכול להיות שתרצו לבדוק אם במכשיר יש דפדפן שתומך בכרטיסיות בהתאמה אישית או לבחור דפדפן ספציפי להפעלה עם כרטיסיות בהתאמה אישית באמצעות CustomTabsClient.getPackageName()
.
במקרים כאלה, צריך לכלול את רכיב <intent>
כחלק מרכיב <queries>
במניפסט:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.support.customtabs.action.CustomTabsService" /> </intent>
אפשר לאפליקציות שאינן דפדפן לטפל בכתובות URL
גם אם האפליקציה שלכם יכולה לפתוח כתובות URL באמצעות כרטיסיות בהתאמה אישית, מומלץ לאפשר לאפליקציה שאינה דפדפן לפתוח כתובת URL, אם אפשר. כדי לספק את היכולת הזו באפליקציה, צריך לנסות להתקשר אל startActivity()
באמצעות intent שמגדיר את דגל ה-intent FLAG_ACTIVITY_REQUIRE_NON_BROWSER
. אם המערכת מחזירה ActivityNotFoundException
, האפליקציה יכולה לפתוח את כתובת ה-URL בכרטיסייה בהתאמה אישית.
אם כוונת המשתמש כוללת את הדגל הזה, קריאה ל-startActivity()
גורמת להפעלת ActivityNotFoundException
כשמתקיים אחד מהתנאים הבאים:
- השיחה הייתה מפעילה אפליקציית דפדפן ישירות.
- בשיחה, למשתמש תוצג תיבת דו-שיח לביטול דו-משמעות, שבה האפשרויות היחידות הן אפליקציות לדפדפן.
קטע הקוד הבא מראה איך לעדכן את הלוגיקה כדי להשתמש בדגל הכוונה FLAG_ACTIVITY_REQUIRE_NON_BROWSER
:
Kotlin
try { val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply { // The URL should either launch directly in a non-browser app (if it's // the default) or in the disambiguation dialog. addCategory(CATEGORY_BROWSABLE) flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER } startActivity(intent) } catch (e: ActivityNotFoundException) { // Only browser apps are available, or a browser is the default. // So you can open the URL directly in your app, for example in a // Custom Tab. openInCustomTabs(url) }
Java
try { Intent intent = new Intent(ACTION_VIEW, Uri.parse(url)); // The URL should either launch directly in a non-browser app (if it's the // default) or in the disambiguation dialog. intent.addCategory(CATEGORY_BROWSABLE); intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER); startActivity(intent); } catch (ActivityNotFoundException e) { // Only browser apps are available, or a browser is the default. // So you can open the URL directly in your app, for example in a // Custom Tab. openInCustomTabs(url); }
איך להימנע מתיבת דו-שיח להסרת דו-משמעות
אם אתם רוצים להימנע מהצגת תיבת הדו-שיח לביטול דו-משמעות שמוצגת למשתמשים כשהם פותחים כתובת URL, ומעדיפים לטפל בכתובת ה-URL בעצמכם במקרים כאלה, אתם יכולים להשתמש ב-Intent שמגדיר את דגל ה-Intent FLAG_ACTIVITY_REQUIRE_DEFAULT
.
אם כוונת משתמש כוללת את הדגל הזה, קריאה ל-startActivity()
גורמת להפעלת ActivityNotFoundException
כשקריאה הייתה מציגה למשתמש תיבת דו-שיח לביטול דו-משמעות.
אם כוונת המשתמש כוללת גם את הדגל הזה וגם את הדגל FLAG_ACTIVITY_REQUIRE_NON_BROWSER
, קריאה ל-startActivity()
גורמת להפעלת ActivityNotFoundException
כשמתקיים אחד מהתנאים הבאים:
- השיחה הייתה מפעילה את אפליקציית הדפדפן ישירות.
- בשיחה הייתה מוצגת למשתמש תיבת דו-שיח להסרת עמימות.
קטע הקוד הבא מראה איך להשתמש בדגלים FLAG_ACTIVITY_REQUIRE_NON_BROWSER
ו-FLAG_ACTIVITY_REQUIRE_DEFAULT
ביחד:
Kotlin
val url = URL_TO_LOAD try { // For this intent to be invoked, the system must directly launch a // non-browser app. val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply { addCategory(CATEGORY_BROWSABLE) flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER or FLAG_ACTIVITY_REQUIRE_DEFAULT } startActivity(intent) } catch (e: ActivityNotFoundException) { // This code executes in one of the following cases: // 1. Only browser apps can handle the intent. // 2. The user has set a browser app as the default app. // 3. The user hasn't set any app as the default for handling this URL. openInCustomTabs(url) }
Java
String url = URL_TO_LOAD; try { // For this intent to be invoked, the system must directly launch a // non-browser app. Intent intent = new Intent(ACTION_VIEW, Uri.parse(url)); intent.addCategory(CATEGORY_BROWSABLE); intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER | FLAG_ACTIVITY_REQUIRE_DEFAULT); startActivity(intent); } catch (ActivityNotFoundException e) { // This code executes in one of the following cases: // 1. Only browser apps can handle the intent. // 2. The user has set a browser app as the default app. // 3. The user hasn't set any app as the default for handling this URL. openInCustomTabs(url); }
פתיחת קובץ
אם האפליקציה שלכם מטפלת בקבצים או בקבצים מצורפים, למשל בודקת אם מכשיר יכול לפתוח קובץ מסוים, בדרך כלל הכי קל לנסות להפעיל פעילות שיכולה לטפל בקובץ. כדי לעשות זאת, משתמשים ב-Intent שכולל את פעולת ה-Intent ACTION_VIEW
ואת ה-URI שמייצג את הקובץ הספציפי. אם אין אפליקציה זמינה במכשיר, האפליקציה שלכם יכולה לזהות את ActivityNotFoundException
. בלוגיקה של טיפול בחריגים, אפשר להציג שגיאה או לנסות לטפל בקובץ בעצמכם.
אם האפליקציה שלכם צריכה לדעת מראש אם אפליקציה אחרת יכולה לפתוח קובץ מסוים,
צריך לכלול את הרכיב <intent>
בקטע הקוד הבא כחלק מהרכיב <queries>
במניפסט. אם אתם כבר יודעים מה סוג הקובץ בזמן ההידור, כדאי לכלול אותו.
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.VIEW" /> <!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". --> <data android:mimeType="application/pdf" /> </intent>
אחרי כן תוכלו לבדוק אם אפליקציה זמינה על ידי התקשרות אל resolveActivity()
עם הכוונה שלכם.
הענקת גישה ל-URI
הערה: חובה להצהיר על הרשאות גישה ל-URI כמו שמתואר בקטע הזה באפליקציות שמטרגטות Android 11 (רמת API 30) ומעלה, ומומלץ להצהיר על הרשאות כאלה בכל האפליקציות, בלי קשר לגרסת ה-SDK שהן מטרגטות ולשאלה אם הן מייצאות את ספקי התוכן שלהן.
כדי לגשת ל-URI של התוכן באפליקציות שמטרגטות ל-Android 11 ואילך, צריך להצהיר על הרשאות גישה ל-URI ב-Intent של האפליקציה. לשם כך, צריך להגדיר את אחד מהדגלים הבאים של ה-Intent או את שניהם:
FLAG_GRANT_READ_URI_PERMISSION
ו-
FLAG_GRANT_WRITE_URI_PERMISSION
.
ב-Android 11 ואילך, הרשאות הגישה ל-URI מעניקות לאפליקציה שמקבלת את ה-Intent את היכולות הבאות:
- קריאה מהנתונים שה-URI של התוכן מייצג, או כתיבה לנתונים האלה, בהתאם להרשאות ה-URI שניתנו.
- קבלתם תובנות לגבי האפליקציה שמכילה את ספק התוכן שתואם לרשות ה-URI. יכול להיות שהאפליקציה שמכילה את ספק התוכן שונה מהאפליקציה ששולחת את הכוונה.
קטע הקוד הבא מדגים איך להוסיף דגל Intent של הרשאות URI כדי שאפליקציה אחרת שמיועדת ל-Android 11 ומעלה תוכל להציג את הנתונים ב-URI של התוכן:
Kotlin
val shareIntent = Intent(Intent.ACTION_VIEW).apply { flags = Intent.FLAG_GRANT_READ_URI_PERMISSION data = CONTENT_URI_TO_SHARE_WITH_OTHER_APP }
Java
Intent shareIntent = new Intent(Intent.ACTION_VIEW); shareIntent.setFlags(FLAG_GRANT_READ_URI_PERMISSION); shareIntent.setData(CONTENT_URI_TO_SHARE_WITH_OTHER_APP);
חיבור לשירותים
אם האפליקציה צריכה ליצור אינטראקציה עם שירות שלא גלוי באופן אוטומטי, אפשר להצהיר על פעולת היעד המתאימה בתוך רכיב <queries>
. בקטעים הבאים יש דוגמאות לשימוש בשירותים נפוצים.
חיבור למנוע המרת טקסט לדיבור (TTS)
אם האפליקציה שלכם מתקשרת עם מנוע להמרת טקסט לדיבור (TTS), צריך לכלול את הרכיב <intent>
הבא כחלק מהרכיב <queries>
במניפסט:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.TTS_SERVICE" /> </intent>
התחברות לשירות של זיהוי דיבור
אם האפליקציה שלכם מתקשרת עם שירות זיהוי דיבור, צריך לכלול את הרכיב <intent>
הבא כחלק מהרכיב <queries>
במניפסט:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.speech.RecognitionService" /> </intent>
חיבור לשירותים של דפדפן מדיה
אם האפליקציה שלכם היא אפליקציית דפדפן מדיה של לקוח, צריך לכלול את רכיב <intent>
הבא כחלק מרכיב <queries>
במניפסט:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.media.browse.MediaBrowserService" /> </intent>
הוספת פונקציונליות מותאמת אישית
אם האפליקציה שלכם צריכה לבצע פעולות שניתנות להתאמה אישית או להציג מידע שניתן להתאמה אישית על סמך האינטראקציות שלה עם אפליקציות אחרות, אתם יכולים לייצג את ההתנהגות המותאמת אישית הזו באמצעות חתימות של מסנני Intent כחלק מרכיב <queries>
במניפסט. בקטעים הבאים מפורטות הנחיות לכמה תרחישים נפוצים.
שאילתה לגבי אפליקציות ל-SMS
אם האפליקציה שלכם צריכה מידע על קבוצת אפליקציות ה-SMS שמותקנות במכשיר, למשל כדי לבדוק איזו אפליקציה היא ברירת המחדל לטיפול ב-SMS במכשיר, צריך לכלול את רכיב <intent>
כחלק מרכיב <queries>
במניפסט:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.SENDTO"/> <data android:scheme="smsto" android:host="*" /> </intent>
יצירת גיליון שיתוף בהתאמה אישית
כשאפשר, כדאי להשתמש בגיליון שיתוף שסופק על ידי המערכת. לחלופין, אפשר לכלול את רכיב <intent>
הבא כחלק מרכיב <queries>
במניפסט:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.SEND" /> <!-- Replace with the MIME type that your app works with, if needed. --> <data android:mimeType="image/jpeg" /> </intent>
תהליך יצירת גיליון השיתוף בלוגיקה של האפליקציה, כמו הקריאה ל-queryIntentActivities()
, נשאר ללא שינוי בהשוואה לגרסאות של Android מוקדמות יותר מ-Android 11.
הצגת פעולות מותאמות אישית לבחירת טקסט
כשמשתמשים בוחרים טקסט באפליקציה, סרגל הכלים לבחירת טקסט מציג את הפעולות האפשריות שאפשר לבצע על הטקסט שנבחר. אם סרגל הכלים הזה מציג פעולות בהתאמה אישית מאפליקציות אחרות, צריך לכלול את רכיב <intent>
הבא כחלק מרכיב <queries>
במניפסט:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.PROCESS_TEXT" /> <data android:mimeType="text/plain" /> </intent>
הצגת שורות של נתונים מותאמים אישית של איש קשר
אפליקציות יכולות להוסיף שורות של נתונים מותאמים אישית לספק אנשי הקשר. כדי שאפליקציית אנשי קשר תוכל להציג את הנתונים המותאמים אישית האלה, היא צריכה:
- קוראים את הקובץ
contacts.xml
מהאפליקציות האחרות. - טוענים סמל שתואם לסוג ה-MIME המותאם אישית.
אם האפליקציה שלכם היא אפליקציית אנשי קשר, צריך לכלול את רכיבי <intent>
הבאים כחלק מרכיב <queries>
במניפסט:
<!-- Place inside the <queries> element. --> <!-- Lets the app read the contacts.xml file from other apps. --> <intent> <action android:name="android.accounts.AccountAuthenticator" /> </intent> <!-- Lets the app load an icon corresponding to the custom MIME type. --> <intent> <action android:name="android.intent.action.VIEW" /> <data android:scheme="content" android:host="com.android.contacts" android:mimeType="vnd.android.cursor.item/*" /> </intent>