Intent
הוא אובייקט שליחת הודעות שאפשר להשתמש בו כדי לבקש פעולה מרכיב אחר באפליקציה.
אובייקטים מסוג Intent מאפשרים תקשורת בין רכיבים בכמה דרכים, אבל יש שלושה תרחישי שימוש בסיסיים:
- התחלת פעילות
Activity
מייצג מסך יחיד באפליקציה. אפשר להתחיל שיחה חדשה שלActivity
על ידי העברת הערךIntent
אלstartActivity()
. השדהIntent
מתאר את הפעילות שרוצים להתחיל ומכיל את הנתונים הנדרשים.אם רוצים לקבל תוצאה מהפעילות כשהיא מסתיימת, קוראים לפונקציה
startActivityForResult()
. הפעילות מקבלת את התוצאה כאובייקטIntent
נפרד בקריאה החוזרתonActivityResult()
של הפעילות. מידע נוסף זמין במדריך הפעילויות. - הפעלת שירות
Service
הוא רכיב שמבצע פעולות ברקע בלי ממשק משתמש. ב-Android מגרסה 5.0 (רמת API 21) ואילך, אפשר להפעיל שירות באמצעותJobScheduler
. אפשר לקבל מידע נוסף מידע עלJobScheduler
, ראהAPI-reference documentation
.בגרסאות קודמות ל-Android 5.0 (רמת API 21), אפשר להפעיל שירות באמצעות שיטות של הכיתה
Service
. כדי להפעיל שירות לביצוע פעולה חד-פעמית (למשל, הורדת קובץ), מעביריםIntent
אלstartService()
.Intent
מתאר את השירות שצריך להפעיל ומעביר את כל הנתונים הנחוצים.אם השירות מיועד באמצעות ממשק לקוח לשרת, אפשר לקשר לשירות מרכיב אחר על ידי העברת
Intent
אלbindService()
. מידע נוסף זמין במדריך שירותים. - העברת שידור
שידור הוא הודעה שכל אפליקציה יכולה לקבל. המערכת מספקת מגוון שידורים לאירועי מערכת, למשל כאשר המערכת באתחול או כשהמכשיר מתחיל להיטען. כדי להעביר שידור לאפליקציות אחרות, מעבירים את הערך
Intent
ל-sendBroadcast()
או ל-sendOrderedBroadcast()
.
בהמשך הדף נסביר איך פועלות כוונות ואיך משתמשים בהן. מידע נוסף זמין במאמרים אינטראקציה עם אפליקציות אחרות ושיתוף תוכן.
סוגי Intent
יש שני סוגים של כוונות:
- כוונות מפורשות מציין איזה רכיב של האפליקציה יענה על הכוונה, על ידי ציון
ComponentName
מלא. בדרך כלל משתמשים ב-Intent מפורש כדי להפעיל רכיב באפליקציה שלכם, כי אתם יודעים את שם הכיתה של הפעילות או השירות שאתם רוצים להפעיל. עבור לדוגמה, אפשר להתחיל פעילות חדשה באפליקציה בתגובה לפעולת משתמש, או להתחיל פעילות שירות להורדת קובץ ברקע. - אובייקטים מסוג Intent מרומז לא מציינים רכיב ספציפי, אלא מגדירים פעולה כללית לביצוע, שמאפשרת לרכיב מאפליקציה אחרת לטפל בה. לדוגמה, אם רוצים להציג למשתמש מיקום במפה, אפשר להשתמש בכוונה משתמעת כדי לבקש מאפליקציה אחרת עם יכולת כזו להציג מיקום מסוים במפה.
באיור 1 מוצג אופן השימוש בכוונה כשמתחילים פעילות. כאשר
Intent
מציין שם של רכיב פעילות ספציפי באופן מפורש, המערכת
רכיב זה מפעיל מיד את הרכיב.

איור 1. איך הכוונה מרומזת
שהועברה באמצעות המערכת כדי להתחיל פעילות נוספת: [1] פעילות א' יוצרת
Intent
עם תיאור פעולה ומעביר אותו אל startActivity()
. [2] מערכת Android מחפשת בכל האפליקציות מסנן Intent שמתאים ל-Intent. כשנמצאת התאמה, [3] המערכת
מתחילה את פעילות ההתאמה (פעילות ב') על ידי הפעלת השיטה onCreate()
שלה והעברת הערך Intent
.
כשמשתמשים ב-intent משתמע, מערכת Android מוצאת את הרכיב המתאים להפעלה על ידי השוואת התוכן של ה-intent למסנני ה-intent שהוגדרו בקובץ המניפסט של אפליקציות אחרות במכשיר. אם ה-Intent תואם למסנן Intent, המערכת מפעילה את הרכיב הזה ומספקת אותו
את האובייקט Intent
. אם יש כמה מסנני כוונות תואמים, המערכת מציגה תיבת דו-שיח כדי שהמשתמש יוכל לבחור באפליקציה שבה הוא רוצה להשתמש.
מסנן Intent הוא ביטוי בקובץ המניפסט של האפליקציה. מציין את סוג ה-Intent שהרכיב שרוצים לקבל. לדוגמה, הכרזה על מסנן כוונה לפעילות מאפשרת לאפליקציות אחרות להתחיל את הפעילות ישירות עם סוג מסוים של כוונה. באופן דומה, אם לא הצהרתם על מסנני Intent בפעילות מסוימת, תוכלו להפעיל את התכונה הזו. רק מתוך כוונה מפורשת.
זהירות: כדי לוודא שהאפליקציה מאובטחת, תמיד צריך להשתמש בכוונה מפורשת כשמפעילים Service
ולא להצהיר על מסנני כוונה לשירותים. שימוש מתוך כוונה מרומזת להפעלת שירות הוא
מכיוון שלא ניתן להיות בטוחים איזה שירות יגיב לכוונה,
והמשתמש לא יכול לראות איזה שירות מתחיל. החל מ-Android 5.0 (רמת API 21), המערכת
מקפיצה הודעת שגיאה (throw) לחריגה אם מתקשרים ל-bindService()
מתוך כוונה מרומזת.
בניית כוונה
אובייקט Intent
נושא מידע שמערכת Android משתמשת בו
כדי לקבוע איזה רכיב להפעיל (למשל: השם או הרכיב המדויק של הרכיב)
הקטגוריה שבה צריך לקבל את הכוונה), וגם מידע שבו רכיב הנמען משתמש
כדי לבצע את הפעולה בצורה תקינה (למשל: הפעולה שצריך לבצע והנתונים שצריך לפעול לפיהם).
המידע העיקרי שמופיע ב-Intent
הוא:
- שם הרכיב
- השם של הרכיב שרוצים להפעיל.
זה מידע אופציונלי, אבל זה המידע הקריטי שיוצר את הכוונה expitit: כלומר, יש לספק את הכוונה רק לרכיב האפליקציה מוגדר על ידי שם הרכיב. בלי שם רכיב, הכוונה היא משתמעת המערכת מחליטה איזה רכיב יקבל את הכוונה על סמך הפרטים האחרים של Intent (כמו הפעולה, הנתונים והקטגוריה, כפי שמתואר בהמשך). אם אתם צריכים להפעיל רכיב ספציפי באפליקציה, עליכם לציין את שם הרכיב.
הערה: כשמתחילים ב-
Service
, יש לציין תמיד את שם הרכיב. אחרת, לא תוכלו להיות בטוחים איזה שירות יגיב לכוונה, והמשתמש לא יוכל לראות איזה שירות מופעל.השדה הזה של
Intent
הוא אובייקטComponentName
, שאפשר לציין באמצעות שם מחלקה מלא ומשויך של רכיב היעד, כולל שם החבילה של האפליקציה. לדוגמה,com.example.ExampleActivity
. אפשר להגדיר את שם הרכיב עםsetComponent()
,setClass()
,setClassName()
, או באמצעותIntent
constructor. - פעולה
- מחרוזת שמציינת את הפעולה הגנרית לביצוע (למשל view או pick).
במקרה של כוונה לשידור, זו הפעולה שהתרחשה ועליהן מדווחים. הפעולה קובעת במידה רבה את המבנה של שאר הכוונה, במיוחד את המידע שנכלל בנתונים ובתוספות.
אתם יכולים לציין פעולות משלכם לשימוש על ידי כוונות באפליקציה (או לשימוש על ידי אפליקציות אחרות כדי להפעיל רכיבים באפליקציה), אבל בדרך כלל מציינים ערכי קבועים של פעולות שמוגדרים על ידי הכיתה
Intent
או על ידי כיתות אחרות של המסגרת. הנה כמה דוגמאות פעולות נפוצות להתחלת פעילות:ACTION_VIEW
- השתמשו בפעולה הזו בכוונה עם
startActivity()
כשיש לכם מידע מסוים פעילות יכולה להופיע למשתמש, כמו תמונה לצפייה באפליקציית גלריה, או כתובת להציג באפליקציית מפה. ACTION_SEND
- הכוונה הזו נקראת גם שיתוף. צריך להשתמש בה בכוונה עם
startActivity()
כשיש נתונים שהמשתמש יכול לשתף דרך אפליקציה אחרת, כמו אפליקציית אימייל או אפליקציית שיתוף ברשתות חברתיות.
במסמך העזרה של הכיתה
Intent
מפורטים עוד קבועים שמגדירים פעולות כלליות. פעולות אחרות מוגדרות במקומות אחרים במסגרת Android, למשלSettings
לפעולות שפותחות מסכים ספציפיים באפליקציית ההגדרות של המערכת.אפשר לציין את הפעולה של הכוונה באמצעות
setAction()
או באמצעות קונסטרוקטור שלIntent
.אם הגדרת פעולות משלך, חשוב לכלול את שם החבילה של האפליקציה כקידומת, כמו בדוגמה הבאה:
- נתונים
- ה-URI (אובייקט
Uri
) שמפנה את הנתונים אל ייעשה בו ו/או סוג ה-MIME של הנתונים האלה. סוג הנתונים שמסופקים בדרך כלל נקבע על ידי הפעולה של הכוונה. עבור לדוגמה, אם הפעולה היאACTION_EDIT
, הנתונים צריכים להכיל את הפונקציה ה-URI של המסמך לעריכה.כשיוצרים כוונה, לעיתים קרובות חשוב לציין את סוג הנתונים (סוג ה-MIME שלו) בנוסף ל-URI שלהם. לדוגמה, פעילות שיכולה להציג תמונות לא תוכל להפעיל קובץ אודיו, גם אם פורמטים ה-URI שלהם דומים. ציון סוג ה-MIME של הנתונים עוזר למערכת Android למצוא את הרכיב הטוב ביותר לקבלת ה-intent. עם זאת, לפעמים אפשר להסיק את סוג ה-MIME מה-URI, במיוחד כשהנתונים הם URI מסוג
content:
. URI מסוגcontent:
מציין שהנתונים נמצאים במכשיר ושיש להםContentProvider
, כך שסוג ה-MIME של הנתונים גלוי למערכת.כדי להגדיר רק את ה-URI של הנתונים, צריך לבצע קריאה ל-
setData()
. כדי להגדיר רק את סוג ה-MIME, קוראים לפונקציהsetType()
. אם צריך, אפשר להגדיר את שניהם באופן מפורש באמצעותsetDataAndType()
.זהירות: אם רוצים להגדיר גם את ה-URI וגם את סוג ה-MIME, לא צריך להפעיל את
setData()
ואתsetType()
כי כל אחת מהן מבטלת את הערך של השנייה. יש להשתמש תמיד ב-setDataAndType()
כדי להגדיר את שתי האפשרויות URI וסוג MIME. - קטגוריה
- מחרוזת שמכילה מידע נוסף על סוג הרכיב שצריך לטפל בכוונה. אפשר להוסיף לכל כוונה מספר בלתי מוגבל של תיאורי קטגוריות, אבל ברוב הכוונות אין צורך בקטגוריה.
לפניכם כמה קטגוריות נפוצות:
CATEGORY_BROWSABLE
- דפדפן אינטרנט יכול להפעיל את פעילות היעד כדי להציג נתונים מקישור, כמו תמונה או הודעת אימייל.
CATEGORY_LAUNCHER
- הפעילות היא הפעילות הראשונית של משימה, והיא מופיעה ברשימה מרכז האפליקציות של המערכת.
אפשר לעיין בתיאורי הכיתה ב
Intent
כדי לראות את הרשימה המלאה של קטגוריות.אפשר לציין קטגוריה באמצעות
addCategory()
.
המאפיינים שצוינו למעלה (שם הרכיב, הפעולה, הנתונים והקטגוריה) מייצגים את המאפיינים המגדירים של הכוונה. על ידי קריאת המאפיינים האלה, מערכת Android מסוגל לפתור את רכיב האפליקציה שהוא צריך להפעיל. עם זאת, כוונה יכולה להכיל מידע נוסף שלא משפיע על האופן שבו היא מנותבת לרכיב של האפליקציה. Intent יכול גם לספק את המידע הבא:
- Extras
- צמדי מפתח/ערך שמכילים מידע נוסף שנחוץ לביצוע הפעולה המבוקשת.
בדיוק כמו שפעולות מסוימות משתמשות בסוגים מסוימים של URI של נתונים, פעולות מסוימות כוללות גם תוספות מסוימות.
אפשר להוסיף עוד נתונים בשיטות שונות של
putExtra()
, שכל אחד מהם מקבל שני פרמטרים: שם המפתח והערך. אפשר גם ליצור אובייקטBundle
עם כל הנתונים הנוספים, ואז להוסיף אתBundle
ל-Intent
באמצעותputExtras()
.לדוגמה, כשיוצרים כוונה לשלוח אימייל עם
ACTION_SEND
, אפשר לציין את הנמען אל עם מקשEXTRA_EMAIL
, ומציינים את הנושא עם מקשEXTRA_SUBJECT
.המחלקה
Intent
מציינת קבועים רבים שלEXTRA_*
לסוגי נתונים סטנדרטיים. אם תצטרכו להצהיר על מפתחות נוספים משלכם (למטרות Intent, שהאפליקציה שלך מקבלת), צריך לכלול את שם החבילה של האפליקציה כקידומת, כמו בדוגמה הבאה:const val EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS"
static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";
זהירות: אין להשתמש באפשרויות
Parcelable
או נתוניSerializable
כששולחים Intent שציפיתם לקבל אפליקציה אחרת. אם האפליקציה מנסה לגשת לנתונים באובייקטBundle
אבל לא לקבל גישה למחלקה המחולקת או למחלקה בסדרה, המערכת מעלהRuntimeException
. - דגלים
- דגלים מוגדרים במחלקה
Intent
שמתפקדים כמטא-נתונים של בכוונה טובה. הדגלים עשויים להורות למערכת Android איך להפעיל פעילות (לדוגמה, משימה הפעילות צריכה להיות שייכת ל) ואיך לטפל בו לאחר ההשקה (לדוגמה, אם הוא נכלל ברשימת ).למידע נוסף, אפשר לעיין ב-method
setFlags()
.
דוגמה לאובייקט Intent מפורש
כוונה מפורשת היא כוונה שמשמשת להפעלת רכיב ספציפי באפליקציה, כמו פעילות או שירות מסוימים באפליקציה. כדי ליצור כוונה מפורשת, מגדירים את שם הרכיב לאובייקט Intent
– כל שאר מאפייני הכוונה הם אופציונליים.
לדוגמה, אם יצרתם באפליקציה שירות בשם DownloadService
,
שנועד להוריד קובץ מהאינטרנט, אפשר להתחיל אותו עם הקוד הבא:
// Executed in an Activity, so 'this' is theContext
// The fileUrl is a string URL, such as "http://www.example.com/image.png" val downloadIntent = Intent(this, DownloadService::class.java).apply { data =Uri.parse
(fileUrl) } startService(downloadIntent)
// Executed in an Activity, so 'this' is theContext
// The fileUrl is a string URL, such as "http://www.example.com/image.png" Intent downloadIntent = new Intent(this, DownloadService.class); downloadIntent.setData(Uri.parse
(fileUrl)); startService(downloadIntent);
המבנה Intent(Context, Class)
מספק לאפליקציה Context
ולאובייקט רכיב אובייקט Class
. לכן, ה-intent הזה מפעיל במפורש את הכיתה DownloadService
באפליקציה.
מידע נוסף על פיתוח והפעלה של שירותים זמין במדריך Services.
דוגמה לאובייקט Intent מרומז
כוונה משתמעת מציינת פעולה שיכולה להפעיל כל אפליקציה במכשיר שיכולה לבצע את הפעולה. כדאי להשתמש בכוונה משתמעת כשהאפליקציה לא יכולה לבצע את הפעולה, אבל סביר להניח שאפליקציות אחרות יכולות, ואתם רוצים שהמשתמש יבחר באפליקציה שבה הוא רוצה להשתמש.
לדוגמה, אם יש לכם תוכן שאתם רוצים שהמשתמש ישתף עם אנשים אחרים, תוכלו ליצור כוונה עם הפעולה ACTION_SEND
ולהוסיף פרטים נוספים שמציינים את התוכן שרוצים לשתף. כשמפעילים את האירוע startActivity()
עם הכוונה הזו, המשתמש יכול לבחור אפליקציה שבאמצעותה לשתף את התוכן.
// Create the text message with a string. val sendIntent = Intent().apply { action = Intent.ACTION_SEND putExtra(Intent.EXTRA_TEXT, textMessage) type = "text/plain" } // Try to invoke the intent. try { startActivity(sendIntent) } catch (e: ActivityNotFoundException) { // Define what your app should do if no activity can handle the intent. }
// Create the text message with a string. Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage); sendIntent.setType("text/plain"); // Try to invoke the intent. try { startActivity(sendIntent); } catch (ActivityNotFoundException e) { // Define what your app should do if no activity can handle the intent. }
כשמתבצעת קריאה אל startActivity()
, המערכת
ובוחן את כל האפליקציות המותקנות כדי לקבוע אילו מהן יכולות להתמודד עם כוונה כזו (
Intent עם הפעולה ACTION_SEND
ושכוללת "טקסט/פשוט"
). אם יש רק אפליקציה אחת שיכולה לטפל בעניין, היא תיפתח מיד ותקבל את ההרשאה
בכוונה טובה. אם אפליקציות אחרות לא יכולות לטפל באירוע, האפליקציה שלכם יכולה לקלוט את האירוע ActivityNotFoundException
. אם יש כמה פעילויות שמקבלות את הכוונה, המערכת
מציגה תיבת דו-שיח כמו זו שמוצגת באיור 2, כך שהמשתמש יכול לבחור באיזו אפליקציה להשתמש.
מידע נוסף על הפעלת אפליקציות אחרות זמין גם במדריך בנושא שליחת המשתמש לאפליקציה אחרת.

איור 2. תיבת דו-שיח לבחירה.
איך מאלצים את המערכת להציג בורר אפליקציות
אם יש יותר מאפליקציה אחת שתגיב לכוונה המשתמעת שלכם, המשתמש יוכל לבחור באפליקציה שבה הוא רוצה להשתמש ולהגדיר אותה כברירת המחדל לביצוע הפעולה. היכולת לבחור ברירת מחדל שימושית כשמבצעים פעולה שבה המשתמש רוצה להשתמש באותה אפליקציה בכל פעם, למשל פתיחת דף אינטרנט (לרוב המשתמשים מעדיפים להשתמש רק בדפדפן אינטרנט אחד).
עם זאת, אם כמה אפליקציות יכולות להגיב לכוונה, והמשתמש עשוי לרצות להשתמש באפליקציה אחרת בכל פעם, צריך להציג תיבת דו-שיח לבחירה באופן מפורש. בתיבת הדו-שיח של הבורר, המשתמש יתבקש לבחור באפליקציה שבה יתבצע הפעולה (המשתמש לא יכול לבחור אפליקציית ברירת מחדל לפעולה). לדוגמה, כשהאפליקציה מבצעת פעולת 'שיתוף' באמצעות הפעולה ACTION_SEND
, יכול להיות שהמשתמשים ירצו לשתף באמצעות אפליקציה אחרת, בהתאם למצב הנוכחי שלהם. לכן, תמיד צריך להשתמש בתיבת הדו-שיח לבחירה, כפי שמוצג באיור 2.
כדי להציג את ה-Selecter, צריך ליצור Intent
באמצעות createChooser()
ולהעביר אותו אל startActivity()
, כמו בדוגמה הבאה.
בדוגמה הזו מוצגת תיבת דו-שיח עם רשימה של אפליקציות שתגובה לכוונה (intent) שהועברה לשיטה createChooser()
, והטקסט שסופק משמש ככותרת של תיבת הדו-שיח.
val sendIntent = Intent(Intent.ACTION_SEND) ... // Always use string resources for UI text. // This says something like "Share this photo with" val title: String = resources.getString(R.string.chooser_title) // Create intent to show the chooser dialog val chooser: Intent = Intent.createChooser(sendIntent, title) // Verify the original intent will resolve to at least one activity if (sendIntent.resolveActivity(packageManager) != null) { startActivity(chooser) }
Intent sendIntent = new Intent(Intent.ACTION_SEND); ... // Always use string resources for UI text. // This says something like "Share this photo with" String title = getResources().getString(R.string.chooser_title); // Create intent to show the chooser dialog Intent chooser = Intent.createChooser(sendIntent, title); // Verify the original intent will resolve to at least one activity if (sendIntent.resolveActivity(getPackageManager()) != null) { startActivity(chooser); }
זיהוי הפעלות של כוונת רכישה לא בטוחה
האפליקציה עשויה להפעיל כוונות כדי לנווט בין רכיבים בתוך האפליקציה, או כדי לבצע פעולה בשם אפליקציה אחרת. כדי לשפר את אבטחת הפלטפורמה, ב-Android 12 (רמת API 31 ואילך) יש תכונת ניפוי באגים שמזהירה אם האפליקציה מבצעת הפעלה לא בטוחה של כוונה. לדוגמה, יכול להיות שהאפליקציה תפעיל באופן לא בטוח כוונת שימוש בתצוגת עץ, שהיא כוונת שימוש שמועברת כפריט נוסף בכוונת שימוש אחרת.
אם האפליקציה מבצעת את שתי הפעולות הבאות, המערכת מזהה הפעלה לא בטוחה של כוונה, ומתרחשת הפרה של StrictMode:
- האפליקציה מפרקת את ה-intent המוטמע מהפרטים הנוספים של ה-intent שנשלח.
- האפליקציה שלך מפעילה אפליקציה באופן מיידי
ברכיב מסוים באמצעות ה-Intent הפנימי הזה,
כמו העברת הכוונה אל
startActivity()
,startService()
, אוbindService()
.
בפוסט בבלוג בנושא Android Nesting Intents ב-Medium מוסבר בהרחבה איך לזהות את המצב הזה ולבצע שינויים באפליקציה.
בדיקה אם יש הפעלות של Intent לא בטוח
כדי לבדוק אם מתבצעות באפליקציה הפעלות לא בטוחות של כוונות, צריך להפעיל את detectUnsafeIntentLaunch()
כשמגדירים את VmPolicy
, כפי שמתואר בקטע הקוד הבא. אם המיקום
שהאפליקציה מזהה הפרה של StrictMode. כדאי להפסיק את הפעלת האפליקציה כדי
להגן על מידע שעשוי להיות רגיש.
fun onCreate() { StrictMode.setVmPolicy(VmPolicy.Builder() // Other StrictMode checks that you've previously added. // ... .detectUnsafeIntentLaunch() .penaltyLog() // Consider also adding penaltyDeath() .build()) }
protected void onCreate() { StrictMode.setVmPolicy(new VmPolicy.Builder() // Other StrictMode checks that you've previously added. // ... .detectUnsafeIntentLaunch() .penaltyLog() // Consider also adding penaltyDeath() .build()); }
שימוש בכוונות בצורה אחראית יותר
כדי לצמצם את הסיכויים להשקת Intent לא בטוחה ולהפרה של StrictMode, כדאי לפעול לפי השיטות המומלצות האלו.
מעתיקים רק את התוספות החיוניות מתוך Intent, ומבצעים את כל מה שצריך
תברואה ואימות. האפליקציה שלך עשויה להעתיק את התוספות מהפניה אחת אל
כוונה אחרת שמשמשת להשקת רכיב חדש. המצב הזה מתרחש כשהאפליקציה מבצעת קריאה ל-putExtras(Intent)
או ל-putExtras(Bundle)
.
אם האפליקציה מבצעת אחת מהפעולות האלה, צריך להעתיק רק את הנתונים הנוספים שהרכיב המקבל מצפה להם. אם כוונת המשתמש האחרת (שמקבלת את העותק)
מפעיל רכיב
לייצא, לחיטוי
לאמת את התוספות לפני שמעתיקים אותן אל הכוונה שמפעילה את
לרכיב הזה.
לא מייצאים את הרכיבים של האפליקציה ללא צורך. לדוגמה, אם
מתכוונים להפעיל רכיב אפליקציה באמצעות Intent פנימי מקונן,
המאפיין android:exported
של הרכיב ל-false
.
שימוש ב-PendingIntent
במקום ב-
Intent בתצוגת עץ. כך, כשאפליקציה אחרת פותחת את החבילה של PendingIntent
ב-Intent
שמכיל אותה, האפליקציה האחרת יכולה להפעיל את PendingIntent
באמצעות הזהות של האפליקציה שלכם. ההגדרה הזו מאפשרת לאפליקציה האחרת להפעיל בבטחה כל רכיב באפליקציה שלכם, כולל רכיב שלא יוצאו.
בתרשים באיור 2 ניתן לראות איך המערכת מעבירה את השליטה מהלקוח (לקוח) לאפליקציה אחרת (שירות) וחזרה לאפליקציה:
- האפליקציה שלכם יוצרת כוונה שמובילה לפעילות באפליקציה אחרת. בטווח של
את הכוונה הזו, מוסיפים אובייקט
PendingIntent
כתוספת. Intent בהמתנה מפעיל רכיב באפליקציה. הרכיב הזה לא מיוצא. - כשהאפליקציה השנייה מקבלת את ה-Intent של האפליקציה שלכם, היא מחלצת את האובייקט
PendingIntent
המוטמע. - האפליקציה האחרת מפעילה את השיטה
send()
באובייקטPendingIntent
. - אחרי שהשליטה מועברת חזרה לאפליקציה, המערכת מפעילה את בכוונה טובה, באמצעות ההקשר של האפליקציה.
איור 2. תרשים של תקשורת בין אפליקציות כשמשתמשים בכוונה מושהית בתצוגת עץ.
קבלת הכוונה מרומזת
כדי לפרסם את הכוונות המשתמעות שהאפליקציה יכולה לקבל, מגדירים מסנן אחד או יותר של כוונות לכל אחד מרכיבי האפליקציה באמצעות רכיב <intent-filter>
בקובץ המניפסט.
כל מסנן Intent מציין את סוג ה-Intents שהוא מקבל על סמך הפעולה של Intent,
לפי נתונים וקטגוריה. המערכת מספקת כוונה מרומזת לרכיב האפליקציה רק אם
Intent יכול לעבור דרך אחד ממסנני Intent שלכם.
הערה: כוונה מפורשת תמיד מועברת ליעד שלה, ללא קשר למסנני הכוונה שהרכיב מצהיר עליהם.
רכיב אפליקציה צריך להצהיר על מסננים נפרדים לכל משימה ייחודית שהוא יכול לבצע.
לדוגמה, פעילות אחת באפליקציה של גלריית התמונות עשויה לכלול שני מסננים: מסנן אחד
כדי להציג תמונה, ומסנן נוסף לעריכת תמונה. כשהפעילות מתחילה,
הוא בודק את Intent
ומחליטים איך לפעול על סמך המידע
ב-Intent
(למשל, כדי להציג או לא להציג את פקדי העריכה).
כל מסנן Intent מוגדר באמצעות רכיב <intent-filter>
בקובץ המניפסט של האפליקציה, שמוטמע ברכיב האפליקציה התואם (למשל, רכיב <activity>
).
בכל רכיב אפליקציה שכולל רכיב <intent-filter>
,
להגדיר במפורש ערך עבור
android:exported
.
המאפיין הזה מציין אם יש לאפליקציות אחרות גישה לרכיב של האפליקציה. בחלק מהמקרים
מצבים כאלה, כמו פעילויות שמסנני הכוונה שלהן כוללים
LAUNCHER
מומלץ להגדיר את המאפיין הזה כ-true
. אחרת,
בטוח יותר להגדיר את המאפיין הזה ל-false
.
אזהרה: אם פעילות, שירות או מקלט שידורים באפליקציה שלכם משתמשים במסנני Intent ולא מגדירים באופן מפורש את הערך של android:exported
, לא תוכלו להתקין את האפליקציה במכשיר עם Android מגרסה 12 ואילך.
בתוך <intent-filter>
, אפשר לציין את סוג הכוונות לקבלה באמצעות אחד או יותר משלושת הרכיבים הבאים:
<action>
- מצהירה על פעולת ה-Intent שהתקבלה, במאפיין
name
. הערך חייב להיות ערך המחרוזת המילולית של פעולה, ולא קבוע הכיתה. <data>
- מציין את סוג הנתונים הקבילים, באמצעות מאפיין אחד או יותר שמציינים ערכים שונים
היבטים שונים של ה-URI של הנתונים (
scheme
,host
,port
,path
) וסוג MIME. <category>
- הצהרה על קטגוריית הכוונה שאושרה, במאפיין
name
. הערך חייב להיות ערך המחרוזת המילולית של פעולה, ולא קבוע הכיתה.הערה: כדי לקבל כוונות מרומזות, חייבת לכלול את הקטע בקטגוריה
CATEGORY_DEFAULT
במסנן Intent. השיטותstartActivity()
ו-startActivityForResult()
מתייחסות לכל הכוונות כאילו הן הצהירו על הקטגוריהCATEGORY_DEFAULT
. אם לא תצהירו על הקטגוריה הזו במסנן ה-Intent, לא יתבצע תיקוף של כוונות משתמשים מרומזות לפעילות שלכם.
לדוגמה, הנה הצהרת פעילות עם מסנן כוונה כדי לקבל כוונה מסוג ACTION_SEND
כשסוג הנתונים הוא טקסט:
<activity android:name="ShareActivity" android:exported="false"> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> </intent-filter> </activity>
אפשר ליצור מסנן שכולל יותר ממופעים אחדים של <action>
, <data>
או <category>
.
אם כן, צריך לוודא שהרכיב יכול לטפל בכל השילובים של רכיבי המסנן האלה.
כשרוצים לטפל בכמה סוגים של כוונות, אבל רק בשילובים ספציפיים של פעולה, נתונים וסוג קטגוריה, עליכם ליצור מספר מסנני Intent.
כדי לבדוק את הכוונה המשתמעת מול מסנן, משווים את הכוונה לכל אחד משלושת הרכיבים. כדי להימסר לרכיב, הכוונה חייבת לעבור את כל שלושת הבדיקות. אם לא תהיה התאמה לאחד מהם, מערכת Android לא תעביר את ה-intent לרכיב. עם זאת, מכיוון שלרכיב יכולים להיות כמה מסנני כוונה, כוונה שלא עוברת דרך אחד מהמסננים של הרכיב עשויה לעבור דרך מסנן אחר. מידע נוסף על האופן שבו המערכת מזהה כוונות זמין בקטע שבהמשך על פתרון של Intent.
זהירות: שימוש במסנן Intent אינו דרך מאובטחת למנוע מאפליקציות אחרות להפעיל
הרכיבים שלך. למרות שמסנני Intent מגבילים רכיב להגיב רק לרכיב מסוים.
סוגים מסוימים של כוונות מרומזות, אפליקציה אחרת יכולה להפעיל את רכיב האפליקציה שלכם
באמצעות שימוש בכוונת רכישה מפורשת אם המפתח קובע את שמות הרכיבים שלך.
אם חשוב לכם שרק האפליקציה שלכם תוכל להפעיל אחד מהרכיבים, אל תצהירו על מסנני כוונה במניפסט. במקום זאת, צריך להגדיר את המאפיין exported
לערך "false"
ברכיב הזה.
באופן דומה, כדי להימנע מהפעלה בטעות של Service
של אפליקציה אחרת, תמיד צריך להשתמש בכוונה מפורשת כדי להפעיל את השירות שלכם.
הערה:
עבור כל הפעילויות, עליכם להצהיר על מסנני Intent בקובץ המניפסט.
עם זאת, ניתן לרשום מסננים למקלטי שידורים באופן דינמי באמצעות קריאה
registerReceiver()
לאחר מכן תוכלו לבטל את הרישום של הנמען ב-unregisterReceiver()
. כך האפליקציה תוכל להאזין לשידורים ספציפיים רק במהלך פרק זמן מסוים בזמן שהיא פועלת.
דוגמאות למסננים
כדי להמחיש חלק מההתנהגויות של מסנן הכוונה, הנה דוגמה מתוך קובץ המניפסט של אפליקציית שיתוף באינטרנט:
<activity android:name="MainActivity" android:exported="true"> <!-- This activity is the main entry, should appear in app launcher --> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="ShareActivity" android:exported="false"> <!-- This activity handles "SEND" actions with text data --> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> </intent-filter> <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data --> <intent-filter> <action android:name="android.intent.action.SEND"/> <action android:name="android.intent.action.SEND_MULTIPLE"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="application/vnd.google.panorama360+jpg"/> <data android:mimeType="image/*"/> <data android:mimeType="video/*"/> </intent-filter> </activity>
הפעילות הראשונה, MainActivity
, היא נקודת הכניסה הראשית של האפליקציה – הפעילות ש
נפתח כשהמשתמש מפעיל לראשונה את האפליקציה בעזרת סמל מרכז האפליקציות:
- הפעולה
ACTION_MAIN
מציין שזו נקודת הכניסה העיקרית ולא מצפה לנתונים לגבי כוונת רכישה. - הקטגוריה
CATEGORY_LAUNCHER
מציינת שצריך להציב את הסמל של הפעילות הזו במרכז האפליקציות של המערכת. אם הרכיב<activity>
לא מציין סמל עםicon
, המערכת משתמשת בסמל מ-<application>
לרכיב מסוים.
יש לחבר בין שני הסוגים האלה כדי שהפעילות תופיע במרכז האפליקציות.
הפעילות השנייה, ShareActivity
, נועדה לאפשר שיתוף של טקסט ומדיה
תוכן. למרות שמשתמשים יכולים להיכנס לפעילות הזו על ידי ניווט אליה מ-MainActivity
,
הם יכולים גם להזין את ShareActivity
ישירות מאפליקציה אחרת שגורמת להטמעה משתמעת
שתואם לאחד משני מסנני ה-Intent.
הערה: סוג ה-MIME, application/vnd.google.panorama360+jpg
, הוא סוג נתונים מיוחד שמציין תמונות פנורמיות. אפשר לטפל בתמונות כאלה באמצעות ממשקי ה-API של Google Panorama.
התאמת כוונות לאפליקציות אחרות מסנני Intent
אם אפליקציה אחרת מטרגטת ל-Android 13 (רמת API 33) ואילך, היא יכולה לטפל בכוונה של האפליקציה שלכם רק אם הכוונה תואמת לפעולות ולקטגוריות של רכיב <intent-filter>
באפליקציה האחרת. אם המערכת לא מוצאת התאמה, היא גורמת להפעלת השגיאה ActivityNotFoundException
.
האפליקציה השולחת חייבת לטפל
במקרה הזה.
באופן דומה, אם מעדכנים את האפליקציה כך שהיא תטרגט את Android 13
ומעלה, כל הכוונות שמקורן באפליקציות חיצוניות מועברות אל
שמיוצא את הרכיב של האפליקציה שלך רק אם הכוונה הזו תואמת את הפעולות
קטגוריות של רכיב <intent-filter>
שהאפליקציה שלך מצהירה עליהן. ההתנהגות הזו
מתרחשת ללא קשר לגרסת היעד של ה-SDK של האפליקציה השולח.
במקרים הבאים לא מתבצעת אכיפה של התאמת Intent:
- אובייקטים מסוג Intent נשלחים לרכיבים שלא מוצהרים בהם מסנני Intent.
- כוונות שמקורן באותה אפליקציה.
- מנגנוני Intent שמקורם במערכת. כלומר, כוונות שנשלחות
'UID של המערכת' (uid=1000). אפליקציות המערכת כוללות את
system_server
ואפליקציות שהוגדרוandroid:sharedUserId
עדandroid.uid.system
. - Intents שמקורם מהרמה הבסיסית (root).
מידע נוסף על התאמה לפי כוונת החיפוש
שימוש ב-Intent בהמתנה
אובייקט PendingIntent
הוא מעטפת של אובייקט Intent
. המטרה העיקרית של PendingIntent
הוא להעניק אישור לבקשה זרה
כדי להשתמש ב-Intent
הכלול כאילו הוא בוצע מתוך
התהליך של האפליקציה עצמה.
תרחישי שימוש עיקריים עבור Intent בהמתנה כוללים את אלה:
- הצהרת כוונה לביצוע פעולה כשהמשתמש מבצע פעולה עם ההתראה (ה-
NotificationManager
של מערכת Android מפעיל את ה-Intent
). - הצהרה על כוונה להוציא לפועל כשהמשתמש מבצע פעולה עם
ווידג'ט לאפליקציה
(אפליקציית מסך הבית מפעילה את
Intent
). - הצהרה על כוונה להוציא לפועל בזמן עתידי מסוים (ה-Android
AlarmManager
של המערכת יריץ אתIntent
).
בדיוק כמו שכל אובייקט Intent
מיועד לטיפול על ידי מודל אבטחה ספציפי
הסוג של רכיב האפליקציה (Activity
, Service
או
a BroadcastReceiver
), ולכן גם PendingIntent
צריך להיות
שנוצר עם אותו שיקול דעת. כשמשתמשים ב-Intent בהמתנה, האפליקציה לא
לבצע את ה-Intent באמצעות קריאה כמו startActivity()
. במקום זאת, עליכם להצהיר על סוג הרכיב המיועד כשיוצרים את הרכיב
PendingIntent
באמצעות קריאה לשיטה המתאימה של היוצר:
PendingIntent.getActivity()
עבורIntent
שמתחילActivity
.PendingIntent.getService()
עבורIntent
שמתחילService
.PendingIntent.getBroadcast()
עבורIntent
שמתחיל ב-BroadcastReceiver
.
אלא אם האפליקציה מקבלת כוונות בהמתנה מאפליקציות אחרות,
השיטות שלמעלה ליצירת PendingIntent
הן ככל הנראה השיטה היחידה
PendingIntent
שיטות להשתמש בהן.
כל שיטה מקבלת את האפליקציה הנוכחית Context
, את ה-Intent
שרוצים לעטוף ודגל אחד או יותר שמציינים איך להשתמש בכוונה (למשל, אם אפשר להשתמש בכוונה יותר מפעם אחת).
מידע נוסף על שימוש בכוונות בהמתנה זמין במסמכי העזרה של כל תרחיש לדוגמה, למשל במדריכי ה-API של התראות ושל ווידג'טים של אפליקציות.
ציון יכולת ההשתנות
אם האפליקציה שלכם מטרגטת ל-Android מגרסה 12 ואילך, עליכם לציין את יכולת ההשתנות של כל אובייקט PendingIntent
שנוצר על ידי האפליקציה. כדי להצהיר על אובייקט PendingIntent
מסוים כמשתנה או לא משתנה, משתמשים בדגל PendingIntent.FLAG_MUTABLE
או בדגל PendingIntent.FLAG_IMMUTABLE
, בהתאמה.
אם האפליקציה תנסה ליצור אובייקט PendingIntent
בלי להגדיר את אחת מסמלי היכולת לשינוי, המערכת תשליך IllegalArgumentException
וההודעה הבאה תופיע ב-Logcat:
PACKAGE_NAME: Targeting S+ (version 31 and above) requires that one of \
FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if \
some functionality depends on the PendingIntent being mutable, e.g. if \
it needs to be used with inline replies or bubbles.
ככל האפשר, כדאי ליצור כוונות בהמתנה שלא ניתן לשנות
ברוב המקרים, האפליקציה צריכה ליצור אובייקטים מסוג PendingIntent
שלא ניתנים לשינוי, כמו
שמוצגת בקטע הקוד הבא. אם אובייקט PendingIntent
לא ניתן לשינוי,
אפליקציות אחרות לא יוכלו לשנות את הכוונה ולהתאים את התוצאה של הפעלת
בכוונה טובה.
val pendingIntent = PendingIntent.getActivity(applicationContext,REQUEST_CODE , intent, /* flags */ PendingIntent.FLAG_IMMUTABLE)
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),REQUEST_CODE , intent, /* flags */ PendingIntent.FLAG_IMMUTABLE);
אבל בתרחישי שימוש מסוימים יש צורך באובייקטים PendingIntent
שניתנים לשינוי במקום זאת:
- תמיכה בפעולות של תשובה ישירה במסגרת
התראות.
כדי להשיב הישירה צריך לשנות את נתוני הקליפ באובייקט PendingIntent
שמשויכים לתשובה. בדרך כלל, כדי לבקש את השינוי הזה,
FILL_IN_CLIP_DATA
כדגלfillIn()
. - שיוך התראות למסגרת של Android Auto באמצעות מכונות של
CarAppExtender
. - הצגת שיחות בבועות באמצעות מכונות של
PendingIntent
. אובייקטPendingIntent
שניתן לשינוי מאפשר למערכת להחיל את הדגלים הנכונים, כמוFLAG_ACTIVITY_MULTIPLE_TASK
ו-FLAG_ACTIVITY_NEW_DOCUMENT
. - שליחת בקשה לקבלת פרטי מיקום המכשיר באמצעות קריאה ל-
requestLocationUpdates()
או לממשקי API דומים. אובייקטPendingIntent
הניתן לשינוי מאפשר למערכת להוסיף תוספות Intent שמייצגות אירועים במחזור החיים של המיקום. האירועים האלה כוללים שינוי במיקום וספק שזמין. - תזמון התראות באמצעות
AlarmManager
. אובייקטPendingIntent
שאפשר לשנות מאפשר למערכת להוסיף את התוסף של הכוונהEXTRA_ALARM_COUNT
. הפרמטר הזה מייצג את מספר הפעמים שהתעוררתם מהתראה חוזרת. הכללת התוספת הזו תאפשר ל-Intent להודיע באופן מדויק אפליקציה שמציינת אם התראה חוזרת הופעלה כמה פעמים, למשל כשהמכשיר היה במצב שינה.
אם האפליקציה יוצרת אובייקט PendingIntent
שניתן לשינוי, מומלץ מאוד להשתמש בכוונת (intent) מפורשת ולמלא את השדה ComponentName
. כך, בכל פעם שאפליקציה אחרת מפעילה את PendingIntent
ומעבירה את השליטה בחזרה לאפליקציה שלכם, תמיד מופעל אותו הרכיב באפליקציה.
שימוש באובייקטים מפורשים של Intent בתוך כוונות בהמתנה
כדי להגדיר טוב יותר איך אפליקציות אחרות יכולות להשתמש בכוונות בהמתנה של האפליקציה, תמיד רכיב של Intent בהמתנה סביב אובייקט Intent מפורש. כדי לפעול בהתאם לשיטה המומלצת הזו, כדאי לבצע את הפעולות הבאות:
- צריך לבדוק את השדות 'פעולה', 'חבילה' ו'רכיב' של Intent הבסיס מוגדרות.
-
שימוש ב-
FLAG_IMMUTABLE
, שנוספו ב-Android 6.0 (רמת API 23), כדי ליצור אובייקטים מסוג Intent בהמתנה. הדגל הזה מונעת מאפליקציות שקיבלוPendingIntent
למלא נכסים שלא מולאו. אםminSdkVersion
של האפליקציה הוא22
ומטה, אפשר לספק בטיחות ותאימות ביחד באמצעות הקוד הבא:if (Build.VERSION.SDK_INT >= 23) { // Create a PendingIntent using FLAG_IMMUTABLE. } else { // Existing code that creates a PendingIntent. }
זיהוי Intent
כשהמערכת מקבלת כוונה מרומזת להתחיל פעילות, היא מחפשת הפעילות הטובה ביותר עבור הכוונה, על ידי השוואתה למסנני Intent על סמך שלושה היבטים:
- פעולה.
- נתונים (גם URI וגם סוג הנתונים).
- קטגוריה.
בקטעים הבאים מוסבר איך מתבצעת ההתאמה של כוונות לרכיבים המתאימים בהתאם להצהרה על מסנן ה-Intent בקובץ המניפסט של האפליקציה.
בדיקת פעולה
כדי לציין פעולות קבילות של Intent, מסנן Intent יכול להצהיר על אפס או יותר
רכיבי <action>
, כמו בדוגמה הבאה:
<intent-filter> <action android:name="android.intent.action.EDIT" /> <action android:name="android.intent.action.VIEW" /> ... </intent-filter>
כדי לעבור את המסנן הזה, הפעולה שצוינה ב-Intent
חייבת להתאים לאחת מהפעולות שמפורטות במסנן.
אם המסנן לא מציג פעולות כלשהן, אין
כוונה להתאים, כך שכל הכוונות נכשלות במבחן. אבל אם Intent
אינו מציין פעולה, הוא עובר את הבדיקה כל עוד
מכיל פעולה אחת לפחות.
בדיקת קטגוריה
כדי לציין את קטגוריות הכוונה המקובלות, מסנן הכוונה יכול להצהיר על אפס או יותר רכיבי <category>
, כפי שמוצג בדוגמה הבאה:
<intent-filter> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> ... </intent-filter>
כדי לעבור את בדיקת הקטגוריה, כל קטגוריה בIntent
חייבת להתאים לקטגוריה במסנן. ההפך לא נכון – מסנן ה-Intent יכול להצהיר על יותר קטגוריות ממה שצוין ב-Intent
, ו-Intent
עדיין עובר. לכן, כוונה ללא קטגוריות תמיד עוברת את הבדיקה הזו, ללא קשר לקטגוריות שצוינו במסנן.
הערה: מערכת Android מחילה באופן אוטומטי את הקטגוריה CATEGORY_DEFAULT
על כל כוונת השימוש המשתמעת שמועברת אל startActivity()
ו-startActivityForResult()
.
אם אתם רוצים שהפעילות תקבל כוונות מרומזות, היא צריכה לכלול קטגוריה עבור "android.intent.category.DEFAULT"
במסנני ה-Intent שלה, כפי שמוצג בדוגמה הקודמת של <intent-filter>
.
בדיקת נתונים
כדי לציין את נתוני הכוונה המותרים, מסנן הכוונה יכול להצהיר על אפס או יותר רכיבי <data>
, כפי שמתואר בדוגמה הבאה:
<intent-filter> <data android:mimeType="video/mpeg" android:scheme="http" ... /> <data android:mimeType="audio/mpeg" android:scheme="http" ... /> ... </intent-filter>
כל רכיב <data>
יכול לציין מבנה URI וסוג נתונים (סוג מדיה של MIME).
כל חלק ב-URI הוא
מאפיין: scheme
, host
, port
,
ו-path
:
<scheme>://<host>:<port>/<path>
בדוגמה הבאה מוצגים ערכים אפשריים למאפיינים האלה:
content://com.example.project:200/folder/subfolder/etc
ב-URI הזה, הסכמה היא content
, המארח הוא com.example.project
,
היציאה היא 200
והנתיב הוא folder/subfolder/etc
.
כל אחד מהמאפיינים האלה הוא אופציונלי ברכיב <data>
,
אבל יש יחסי תלות לינאריים:
- אם לא מצוינת סכמה, המערכת מתעלמת מהמארח.
- אם לא מצוין מארח, המערכת תתעלם מהיציאה.
- אם לא מציינים גם את הסכימה וגם את המארח, המערכת מתעלמת מהנתיב.
כשמשווים את ה-URI בכוונה לתיאור של URI במסנן, ההשוואה מתבצעת רק לחלקים של ה-URI שכלולים במסנן. לדוגמה:
- אם מסנן מציין רק סכימה, כל מזהי ה-URI עם אותה סכימה תואמים למסנן.
- אם מסנן מציין סכמה ורשות אבל לא נתיב, כל מזהי ה-URI בעלי אותה הסכמה וסמכות מעבירים את המסנן, בלי קשר לנתיבים שלהם.
- אם מסנן מציין סכמה, סמכות ונתיב, רק מזהי URI עם אותה סכימה, ונתיב מעבירים את המסנן.
הערה: מפרט נתיב להכיל כוכבית עם תו כללי לחיפוש (*), כדי לדרוש רק התאמה חלקית של שם הנתיב.
בבדיקה של הנתונים מתבצעת השוואה בין ה-URI וסוג ה-MIME בכוונה לבין ה-URI וסוג ה-MIME שצוינו במסנן. אלה הכללים:
- כוונה שאינה מכילה URI או סוג MIME עוברים את רק אם המסנן לא מציין URI או סוגי MIME.
- כוונה שמכילה URI אבל לא סוג MIME (לא מפורש ולא ניתן להסיק ממנו מה-URI) עוברת את הבדיקה רק אם ה-URI שלה תואם לפורמט ה-URI של המסנן, וגם המסנן לא מציין סוג MIME.
- כוונה שמכילה סוג MIME אבל לא URI עוברת את הבדיקה רק אם המסנן מציג את אותו סוג MIME ולא מציין פורמט URI.
- Intent שמכיל גם URI וגם סוג MIME (מבוטאת או מסיק
URI) מעביר את החלק מסוג MIME בבדיקה רק אם
הסוג תואם לסוג שמצוין במסנן. היא מעבירה את חלק ה-URI של הבדיקה
אם ה-URI שלו תואם ל-URI במסנן או אם יש לו
content:
אוfile:
URI והמסנן לא מציין URI. במילים אחרות, הנחה שרכיב מסוים תומך בנתונים שלcontent:
ו-file:
אם המסנן מפרט רק סוג MIME.
הערה: אם ה-Intent מציין סוג URI או MIME, בדיקת הנתונים
תיכשל אם אין רכיבי <data>
ב-<intent-filter>
.
הכלל האחרון, (ד), משקף את הציפייה שהרכיבים יוכלו לקבל נתונים מקומיים מקובץ או מספק תוכן.
לכן, המסננים שלהם יכולים לכלול רק סוג נתונים, ולא צריך לציין במפורש את השמות של הסכימות content:
ו-file:
.
הדוגמה הבאה מציגה מקרה אופייני שבו הרכיב <data>
מנחה את Android שהרכיב יכול לקבל נתוני תמונה מתוכן
הספק ומציג אותו:
<intent-filter> <data android:mimeType="image/*" /> ... </intent-filter>
מסננים שמציינים סוג נתונים אבל לא URI הם כנראה הנפוצים ביותר, כי רוב הנתונים הזמינים ניתנים על ידי ספקי תוכן.
הגדרה נפוצה נוספת היא מסנן עם סכימה וסוג נתונים. לדוגמה, אלמנט <data>
כמו זה הבא מאפשר ל-Android לדעת שהרכיב יכול לאחזר נתוני וידאו מהרשת כדי לבצע את הפעולה:
<intent-filter> <data android:scheme="http" android:mimeType="video/*" /> ... </intent-filter>
התאמה של כוונת רכישה
מתבצעת התאמה בין הכוונות לבין מסנני Intent לא רק כדי לגלות יעד
להפעיל, אבל גם לגלות משהו על קבוצת
הרכיבים במכשיר. לדוגמה, אפליקציית Home מאכלסת את מרכז האפליקציות
על ידי מציאת כל הפעילויות עם מסנני Intent שמציינים את
פעולה אחת (ACTION_MAIN
) ו
הקטגוריה CATEGORY_LAUNCHER
.
ההתאמה מתבצעת רק אם הפעולות והקטגוריות ב-Intent תואמות למסנן, כפי שמתואר במסמכים של הכיתה IntentFilter
.
האפליקציה שלך יכולה להשתמש בהתאמת כוונות באופן דומה לאופן הפעולה של אפליקציית Home.
ל-PackageManager
יש קבוצה של שיטות query...()
שמחזירות את כל הרכיבים שיכולים לקבל כוונת שימוש מסוימת, וקבוצה דומה של שיטות resolve...()
שמגדירות את הרכיב הטוב ביותר להגיב לכוונת השימוש. לדוגמה,
הפונקציה queryIntentActivities()
מחזירה רשימה של כל הפעילויות שיכולות לבצע
את Intent שהועבר כארגומנט, ו-queryIntentServices()
מחזירה רשימה דומה של שירותים.
אף שיטה לא מפעילה את הרכיבים. הם פשוט מציינים את התוצאות
יכול להגיב. יש שיטה דומה, queryBroadcastReceivers()
, למקלטי שידורים.