בשיעור הזה נסביר איך להשתמש ב-Intent כדי להוסיף איש קשר חדש או לשנות את הנתונים של איש קשר קיים. במקום לגשת ישירות לניהול אנשי הקשר, Intent מפעילה את אפליקציית "אנשי קשר", שמריצה את ה-Activity המתאים. בפעולות השינוי שמתוארות בשיעור הזה, אם שולחים נתונים מורחבים ב-Intent, הם מוזנים בממשק המשתמש של ה-Activity שמופעל.
השימוש ב-Intent כדי להוסיף או לעדכן איש קשר יחיד הוא הדרך המועדפת לשינוי של ניהול אנשי הקשר, מהסיבות הבאות:
- הוא חוסך לכם את הזמן והמאמץ הכרוכים בפיתוח ממשק משתמש וקוד משלכם.
- כך נמנעות שגיאות שנגרמות כתוצאה משינויים שלא תואמים לכללים של ספק אנשי הקשר.
- הוא מצמצם את מספר ההרשאות שצריך לבקש. לאפליקציה לא נדרשת הרשאה לכתוב לניהול אנשי הקשר, כי היא מקצה שינויים לאפליקציית אנשי הקשר, שכבר יש לה את ההרשאה הזו.
הוספת איש קשר חדש באמצעות Intent
במקרים רבים, כשהאפליקציה מקבלת נתונים חדשים, אתם רוצים לאפשר למשתמש להוסיף איש קשר חדש. לדוגמה, אפליקציה לביקורת על מסעדות יכולה לאפשר למשתמשים להוסיף את המסעדה כאיש קשר בזמן שהם כותבים עליה ביקורת. כדי לעשות את זה באמצעות Intent, יוצרים את ה-Intent עם כמה שיותר נתונים זמינים, ואז שולחים את ה-Intent לאפליקציית אנשי הקשר.
כשמוסיפים איש קשר באמצעות אפליקציית אנשי הקשר, נוספים נתונים גולמיים של איש קשר חדש לטבלה ContactsContract.RawContacts של ספק אנשי הקשר. אם צריך, אפליקציית אנשי הקשר מבקשת מהמשתמשים לבחור את סוג החשבון ואת החשבון שבו הם רוצים להשתמש כדי ליצור את הנתונים הגולמיים של איש הקשר. אפליקציית "אנשי קשר" גם מודיעה למשתמשים אם הנתונים הגולמיים של איש הקשר כבר קיימים. למשתמשים יש אפשרות לבטל את ההוספה, ובמקרה כזה לא נוצר איש קשר. מידע נוסף על נתונים גולמיים של אנשי קשר זמין במדריך ל-API של ניהול אנשי הקשר.
יצירת כוונה
כדי להתחיל, יוצרים אובייקט Intent חדש עם הפעולה Intents.Insert.ACTION.
מגדירים את סוג ה-MIME בתור RawContacts.CONTENT_TYPE. לדוגמה:
Kotlin
... // Creates a new Intent to insert a contact val intent = Intent(ContactsContract.Intents.Insert.ACTION).apply { // Sets the MIME type to match the Contacts Provider type = ContactsContract.RawContacts.CONTENT_TYPE }
Java
... // Creates a new Intent to insert a contact Intent intent = new Intent(ContactsContract.Intents.Insert.ACTION); // Sets the MIME type to match the Contacts Provider intent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
אם כבר יש לכם פרטים של איש הקשר, כמו מספר טלפון או כתובת אימייל, אתם יכולים להוסיף אותם ל-Intent כנתונים מורחבים. כדי להגדיר ערך מפתח, משתמשים בקבוע המתאים מ-Intents.Insert. אפליקציית אנשי הקשר מציגה את הנתונים במסך ההוספה שלה, והמשתמשים יכולים לבצע עריכות ותוספות נוספות.
Kotlin
private var emailAddress: EditText? = null private var phoneNumber: EditText? = null ... /* Assumes EditText fields in your UI contain an email address * and a phone number. * */ emailAddress = findViewById(R.id.email) phoneNumber = findViewById(R.id.phone) ... /* * Inserts new data into the Intent. This data is passed to the * contacts app's Insert screen */ intent.apply { // Inserts an email address putExtra(ContactsContract.Intents.Insert.EMAIL, emailAddress?.text) /* * In this example, sets the email type to be a work email. * You can set other email types as necessary. */ putExtra( ContactsContract.Intents.Insert.EMAIL_TYPE, ContactsContract.CommonDataKinds.Email.TYPE_WORK ) // Inserts a phone number putExtra(ContactsContract.Intents.Insert.PHONE, phoneNumber?.text) /* * In this example, sets the phone type to be a work phone. * You can set other phone types as necessary. */ putExtra( ContactsContract.Intents.Insert.PHONE_TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_WORK ) }
Java
private EditText emailAddress = null; private EditText phoneNumber = null; ... /* Assumes EditText fields in your UI contain an email address * and a phone number. * */ emailAddress = (EditText) findViewById(R.id.email); phoneNumber = (EditText) findViewById(R.id.phone); ... /* * Inserts new data into the Intent. This data is passed to the * contacts app's Insert screen */ // Inserts an email address intent.putExtra(ContactsContract.Intents.Insert.EMAIL, emailAddress.getText()) /* * In this example, sets the email type to be a work email. * You can set other email types as necessary. */ .putExtra(ContactsContract.Intents.Insert.EMAIL_TYPE, ContactsContract.CommonDataKinds.Email.TYPE_WORK) // Inserts a phone number .putExtra(ContactsContract.Intents.Insert.PHONE, phoneNumber.getText()) /* * In this example, sets the phone type to be a work phone. * You can set other phone types as necessary. */ .putExtra(ContactsContract.Intents.Insert.PHONE_TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_WORK);
אחרי שיוצרים את ה-Intent, שולחים אותו באמצעות קריאה ל-startActivity().
Kotlin
/* Sends the Intent */ startActivity(intent)
Java
/* Sends the Intent */ startActivity(intent);
הקריאה הזו פותחת מסך באפליקציית אנשי הקשר שמאפשר למשתמשים להזין איש קשר חדש. סוג החשבון ושם החשבון של איש הקשר מופיעים בחלק העליון של המסך. אחרי שהמשתמשים מזינים את הנתונים ולוחצים על סיום, מופיעה רשימת אנשי הקשר של אפליקציית אנשי הקשר. המשתמשים לוחצים על הקודם כדי לחזור לאפליקציה.
עריכת איש קשר קיים באמצעות Intent
עריכת איש קשר קיים באמצעות Intent שימושית אם המשתמש כבר בחר איש קשר רלוונטי. לדוגמה, אפליקציה שמוצאת אנשי קשר שיש להם כתובות דואר אבל אין להם מיקוד, יכולה לתת למשתמשים אפשרות לחפש את המיקוד ולהוסיף אותו לאיש הקשר.
כדי לערוך איש קשר קיים באמצעות Intent, משתמשים בהליך דומה להוספת איש קשר. יוצרים Intent כמו שמתואר בקטע הוספת איש קשר חדש באמצעות Intent, אבל מוסיפים ל-Intent את ה-Contacts.CONTENT_LOOKUP_URI של איש הקשר ואת סוג ה-MIME Contacts.CONTENT_ITEM_TYPE. אם רוצים לערוך את איש הקשר עם פרטים שכבר יש, אפשר להוסיף אותם לנתונים המורחבים של ה-Intent. שימו לב שאי אפשר לערוך חלק מעמודות השמות באמצעות Intent. העמודות האלה מפורטות בקטע הסיכום של מאמרי העזרה של ה-API למחלקה ContactsContract.Contacts, בכותרת Update.
בסיום, שולחים את ה-Intent. בתגובה, אפליקציית אנשי הקשר מציגה מסך עריכה. כשהמשתמש מסיים לערוך ושומר את השינויים, אפליקציית אנשי הקשר מציגה רשימת אנשי קשר. כשהמשתמש לוחץ על חזרה, האפליקציה מוצגת.
יצירת ה-intent
כדי לערוך איש קשר, צריך להפעיל את Intent(action) כדי ליצור Intent עם הפעולה ACTION_EDIT. מפעילים את setDataAndType() כדי להגדיר את ערך הנתונים של ה-Intent ל-Contacts.CONTENT_LOOKUP_URI של איש הקשר ואת סוג ה-MIME לסוג ה-MIME של Contacts.CONTENT_ITEM_TYPE. מכיוון שהפעלת setType() מחליפה את ערך הנתונים הנוכחי של Intent, צריך להגדיר את הנתונים ואת סוג ה-MIME בו-זמנית.
כדי לקבל את Contacts.CONTENT_LOOKUP_URI של איש קשר, מפעילים את הפונקציה Contacts.getLookupUri(id, lookupkey) עם הערכים Contacts._ID ו-Contacts.LOOKUP_KEY של איש הקשר כארגומנטים.
הערה: הערך של LOOKUP_KEY של איש קשר הוא המזהה שבו צריך להשתמש כדי לאחזר איש קשר. הוא נשאר קבוע, גם אם הספק משנה את מזהה השורה של איש הקשר כדי לטפל בפעולות פנימיות.
בקטע הקוד הבא אפשר לראות איך יוצרים Intent:
Kotlin
// The Cursor that contains the Contact row var mCursor: Cursor? = null // The index of the lookup key column in the cursor var lookupKeyIndex: Int = 0 // The index of the contact's _ID value var idIndex: Int = 0 // The lookup key from the Cursor var currentLookupKey: String? = null // The _ID value from the Cursor var currentId: Long = 0 // A content URI pointing to the contact var selectedContactUri: Uri? = null ... /* * Once the user has selected a contact to edit, * this gets the contact's lookup key and _ID values from the * cursor and creates the necessary URI. */ mCursor?.apply { // Gets the lookup key column index lookupKeyIndex = getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY) // Gets the lookup key value currentLookupKey = getString(lookupKeyIndex) // Gets the _ID column index idIndex = getColumnIndex(ContactsContract.Contacts._ID) currentId = getLong(idIndex) selectedContactUri = ContactsContract.Contacts.getLookupUri(currentId, mCurrentLookupKey) } // Creates a new Intent to edit a contact val editIntent = Intent(Intent.ACTION_EDIT).apply { /* * Sets the contact URI to edit, and the data type that the * Intent must match */ setDataAndType(selectedContactUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE) }
Java
// The Cursor that contains the Contact row public Cursor mCursor; // The index of the lookup key column in the cursor public int lookupKeyIndex; // The index of the contact's _ID value public int idIndex; // The lookup key from the Cursor public String currentLookupKey; // The _ID value from the Cursor public long currentId; // A content URI pointing to the contact Uri selectedContactUri; ... /* * Once the user has selected a contact to edit, * this gets the contact's lookup key and _ID values from the * cursor and creates the necessary URI. */ // Gets the lookup key column index lookupKeyIndex = mCursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY); // Gets the lookup key value currentLookupKey = mCursor.getString(lookupKeyIndex); // Gets the _ID column index idIndex = mCursor.getColumnIndex(ContactsContract.Contacts._ID); currentId = mCursor.getLong(idIndex); selectedContactUri = Contacts.getLookupUri(currentId, mCurrentLookupKey); ... // Creates a new Intent to edit a contact Intent editIntent = new Intent(Intent.ACTION_EDIT); /* * Sets the contact URI to edit, and the data type that the * Intent must match */ editIntent.setDataAndType(selectedContactUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE);
הוספת דגל הניווט
ב-Android מגרסה 4.0 (גרסת API 14) ואילך, בעיה באפליקציית אנשי הקשר גורמת לניווט שגוי. כשהאפליקציה שולחת Intent של עריכה לאפליקציית אנשי הקשר, והמשתמשים עורכים ושומרים איש קשר, כשהם לוחצים על חזרה הם רואים את מסך רשימת אנשי הקשר. כדי לחזור לאפליקציה, הם צריכים ללחוץ על אפליקציות אחרונות ולבחור את האפליקציה.
כדי לעקוף את הבעיה הזו ב-Android 4.0.3 (גרסת API 15) ואילך, מוסיפים את מפתח הנתונים המורחב finishActivityOnSaveCompleted ל-Intent, עם הערך true.
גרסאות Android שקודמות ל-Android 4.0 מקבלות את המפתח הזה, אבל אין לו השפעה. כדי להגדיר את הנתונים המורחבים:
Kotlin
// Sets the special extended data for navigation editIntent.putExtra("finishActivityOnSaveCompleted", true)
Java
// Sets the special extended data for navigation editIntent.putExtra("finishActivityOnSaveCompleted", true);
הוספת נתונים מורחבים אחרים
כדי להוסיף עוד נתונים מורחבים אל Intent, צריך להפעיל את putExtra() לפי הצורך.
אפשר להוסיף נתונים מורחבים לשדות נפוצים של אנשי קשר באמצעות ערכי המפתחות שצוינו ב-Intents.Insert. חשוב לזכור שאי אפשר לשנות חלק מהעמודות בטבלה ContactsContract.Contacts.
העמודות האלה מפורטות בקטע הסיכום של מאמרי העזרה של ה-API למחלקה ContactsContract.Contacts, בכותרת Update.
שליחת ה-intent
בסיום, שולחים את ה-Intent שיצרתם. לדוגמה:
Kotlin
// Sends the Intent startActivity(editIntent)
Java
// Sends the Intent startActivity(editIntent);
המשתמשים יכולים לבחור להוסיף או לערוך באמצעות כוונה
אתם יכולים לאפשר למשתמשים לבחור אם להוסיף איש קשר או לערוך איש קשר קיים על ידי שליחת
Intent עם הפעולה
ACTION_INSERT_OR_EDIT. לדוגמה, אפליקציה של תוכנת אימייל יכולה לאפשר למשתמשים להוסיף כתובת אימייל נכנסת לאיש קשר חדש, או להוסיף אותה ככתובת נוספת לאיש קשר קיים. מגדירים את סוג ה-MIME של ה-Intent הזה בתור Contacts.CONTENT_ITEM_TYPE, אבל לא מגדירים את ה-URI של הנתונים.
כששולחים את ה-Intent הזה, אפליקציית אנשי הקשר מציגה רשימה של אנשי קשר.
המשתמשים יכולים להוסיף איש קשר חדש או לבחור איש קשר קיים ולערוך אותו.
כל שדות הנתונים המורחבים שתוסיפו ל-Intent יאכלסו את המסך שיופיע. אפשר להשתמש בכל אחד מהערכים של המפתחות שצוינו ב-Intents.Insert. בקטע הקוד הבא מוצג איך ליצור ולשלוח את ה-Intent:
Kotlin
// Creates a new Intent to insert or edit a contact val intentInsertEdit = Intent(Intent.ACTION_INSERT_OR_EDIT).apply { // Sets the MIME type type = ContactsContract.Contacts.CONTENT_ITEM_TYPE } // Add code here to insert extended data, if desired // Sends the Intent with an request ID startActivity(intentInsertEdit)
Java
// Creates a new Intent to insert or edit a contact Intent intentInsertEdit = new Intent(Intent.ACTION_INSERT_OR_EDIT); // Sets the MIME type intentInsertEdit.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE); // Add code here to insert extended data, if desired ... // Sends the Intent with an request ID startActivity(intentInsertEdit);