संपर्क जानकारी देने वाला ऐप्लिकेशन, Android का एक असरदार और आसानी से इस्तेमाल किया जा सकने वाला कॉम्पोनेंट है. यह लोगों के बारे में जानकारी के लिए, डिवाइस के सेंट्रल रिपॉज़िटरी को मैनेज करता है. संपर्क की जानकारी देने वाला ऐप्लिकेशन, डिवाइस के संपर्क ऐप्लिकेशन में दिखने वाले डेटा का सोर्स होता है. साथ ही, अपने ऐप्लिकेशन में भी इस डेटा को ऐक्सेस किया जा सकता है. इसके अलावा, डिवाइस और ऑनलाइन सेवाओं के बीच डेटा ट्रांसफ़र किया जा सकता है. यह सेवा देने वाली कंपनी, कई तरह के डेटा सोर्स से डेटा इकट्ठा करती है. साथ ही, यह हर व्यक्ति के लिए ज़्यादा से ज़्यादा डेटा मैनेज करने की कोशिश करती है. इस वजह से, इसका संगठन जटिल है. इस वजह से, सेवा देने वाली कंपनी के एपीआई में कॉन्ट्रैक्ट क्लास और इंटरफ़ेस का एक बड़ा सेट शामिल होता है. इससे डेटा को वापस पाने और उसमें बदलाव करने में मदद मिलती है.
इस गाइड में इनके बारे में बताया गया है:
- सेवा देने वाली कंपनी का बुनियादी स्ट्रक्चर.
- डेटा देने वाली कंपनी से डेटा वापस पाने का तरीका.
- सेवा देने वाली कंपनी के डेटा में बदलाव करने का तरीका.
- अपने सर्वर से Contacts Provider में डेटा सिंक करने के लिए, सिंक अडैप्टर लिखने का तरीका.
हम मानते हैं कि आपको Android कॉन्टेंट प्रोवाइडर की बुनियादी बातों के बारे में पता है. Android कॉन्टेंट प्रोवाइडर के बारे में ज़्यादा जानने के लिए, कॉन्टेंट प्रोवाइडर की बुनियादी बातें गाइड पढ़ें.
संपर्क सूची उपलब्ध कराने वाला संगठन
संपर्क सूची, Android कॉन्टेंट उपलब्ध कराने वाली कंपनी का एक कॉम्पोनेंट है. यह किसी व्यक्ति के बारे में तीन तरह का डेटा सेव करता है. इनमें से हर डेटा, सेवा देने वाली कंपनी की ओर से उपलब्ध कराई गई टेबल से जुड़ा होता है. इसे पहले फ़िगर में दिखाया गया है:

पहली इमेज. संपर्क सूची की टेबल का स्ट्रक्चर.
इन तीनों टेबल को आम तौर पर, उनकी कॉन्ट्रैक्ट क्लास के नाम से जाना जाता है. क्लास, कॉन्टेंट यूआरआई, कॉलम के नाम, और कॉलम की वैल्यू के लिए कॉन्सटेंट तय करती हैं. इनका इस्तेमाल टेबल में किया जाता है:
-
ContactsContract.Contacts
टेबल - कच्चे संपर्क डेटा की पंक्तियों के एग्रीगेशन के आधार पर, अलग-अलग लोगों को दिखाने वाली पंक्तियां.
-
ContactsContract.RawContacts
टेबल - ऐसी लाइनें जिनमें किसी व्यक्ति के डेटा की खास जानकारी होती है. यह जानकारी, उपयोगकर्ता खाते और टाइप के हिसाब से होती है.
-
ContactsContract.Data
टेबल - इन पंक्तियों में रॉ संपर्क की जानकारी होती है. जैसे, ईमेल पते या फ़ोन नंबर.
ContactsContract
में कॉन्ट्रैक्ट क्लास से दिखाई गई अन्य टेबल, सहायक टेबल होती हैं. इनका इस्तेमाल Contacts Provider, अपने ऑपरेशनों को मैनेज करने या डिवाइस के संपर्क या टेलिफ़ोनी ऐप्लिकेशन में कुछ खास फ़ंक्शन को सपोर्ट करने के लिए करता है.
रॉ कॉन्टैक्ट
रॉ संपर्क, किसी व्यक्ति के डेटा को दिखाता है. यह डेटा, एक ही तरह के खाते और खाते के नाम से आता है. संपर्क की जानकारी देने वाली सेवा, किसी व्यक्ति के डेटा के सोर्स के तौर पर एक से ज़्यादा ऑनलाइन सेवाओं को अनुमति देती है. इसलिए, यह सेवा एक ही व्यक्ति के लिए कई रॉ संपर्क की अनुमति देती है. एक से ज़्यादा रॉ संपर्क होने पर, उपयोगकर्ता एक ही तरह के खाते से किसी व्यक्ति का डेटा, एक से ज़्यादा खातों से जोड़ सकता है.
किसी रॉ संपर्क का ज़्यादातर डेटा, ContactsContract.RawContacts
टेबल में सेव नहीं किया जाता. इसके बजाय, इसे ContactsContract.Data
टेबल में एक या उससे ज़्यादा लाइनों में सेव किया जाता है. डेटा की हर लाइन में एक कॉलम Data.RAW_CONTACT_ID
होता है. इसमें, इसकी पैरंट ContactsContract.RawContacts
लाइन की RawContacts._ID
वैल्यू होती है.
रॉ संपर्क के अहम कॉलम
ContactsContract.RawContacts
टेबल में मौजूद ज़रूरी कॉलम की जानकारी, टेबल 1 में दी गई है. कृपया टेबल के बाद दिए गए नोट पढ़ें:
पहली टेबल. कच्चे संपर्क के अहम कॉलम.
कॉलम का नाम | इस्तेमाल करें | नोट |
---|---|---|
ACCOUNT_NAME
|
उस खाते का नाम जो इस रॉ संपर्क का सोर्स है.
उदाहरण के लिए, Google खाते का नाम, डिवाइस के मालिक के Gmail पतों में से एक होता है. ज़्यादा जानकारी के लिए, ACCOUNT_TYPE की अगली एंट्री देखें.
|
इस नाम का फ़ॉर्मैट, खाते के टाइप के हिसाब से तय होता है. यह ज़रूरी नहीं है कि यह ईमेल पता हो. |
ACCOUNT_TYPE
|
यह उस खाते का टाइप है जिससे यह रॉ संपर्क मिला है. उदाहरण के लिए, Google खाते का खाता टाइप com.google है. अपने खाते के टाइप के साथ हमेशा उस डोमेन का आइडेंटिफ़ायर जोड़ें जिसका मालिकाना हक आपके पास है या जिसे कंट्रोल करने का अधिकार आपके पास है. इससे यह पक्का होगा कि आपके खाते का टाइप यूनीक हो.
|
संपर्कों का डेटा उपलब्ध कराने वाले खाते में, आम तौर पर एक सिंक अडैप्टर जुड़ा होता है. यह Contacts Provider के साथ सिंक करता है. |
DELETED
|
किसी रॉ संपर्क के लिए "मिटाया गया" फ़्लैग. | इस फ़्लैग की मदद से, Contacts Provider, पंक्ति को अंदरूनी तौर पर तब तक बनाए रख सकता है, जब तक कि सिंक अडैप्टर अपने सर्वर से पंक्ति को मिटा न दें. इसके बाद, वे रिपॉज़िटरी से पंक्ति को मिटा सकते हैं. |
नोट
ContactsContract.RawContacts
टेबल के बारे में यहां कुछ ज़रूरी बातें दी गई हैं:
-
किसी रॉ संपर्क का नाम,
ContactsContract.RawContacts
में उसकी लाइन में सेव नहीं किया जाता. इसके बजाय, इसेContactsContract.Data
टेबल मेंContactsContract.CommonDataKinds.StructuredName
लाइन में सेव किया जाता है. रॉ संपर्क में,ContactsContract.Data
टेबल में इस तरह की सिर्फ़ एक लाइन होती है. -
चेतावनी: रॉ संपर्क की लाइन में अपने खाते का डेटा इस्तेमाल करने के लिए, यह ज़रूरी है कि उसे पहले
AccountManager
में रजिस्टर किया गया हो. इसके लिए, उपयोगकर्ताओं को खाते के टाइप और खाते के नाम को खातों की सूची में जोड़ने के लिए कहें. ऐसा न करने पर, Contacts Provider आपके रॉ कॉन्टैक्ट की लाइन को अपने-आप मिटा देगा.उदाहरण के लिए, अगर आपको अपने ऐप्लिकेशन के ज़रिए, वेब पर उपलब्ध सेवा
com.example.dataservice
के लिए संपर्क डेटा बनाए रखना है और आपकी सेवा के लिए उपयोगकर्ता का खाताbecky.sharp@dataservice.example.com
है, तो आपके ऐप्लिकेशन को संपर्क की रॉ पंक्तियां जोड़ने से पहले, उपयोगकर्ता को खाते का "टाइप" (com.example.dataservice
) और खाते का "नाम" (becky.smart@dataservice.example.com
) जोड़ना होगा. दस्तावेज़ में, उपयोगकर्ता को इस ज़रूरी शर्त के बारे में बताया जा सकता है. इसके अलावा, उपयोगकर्ता को टाइप और नाम या दोनों जोड़ने के लिए कहा जा सकता है. खाते के टाइप और खाते के नामों के बारे में ज़्यादा जानकारी अगले सेक्शन में दी गई है.
कच्चे संपर्क डेटा के सोर्स
रॉ कॉन्टैक्ट के काम करने का तरीका समझने के लिए, "एमिली डिकिंसन" नाम के उपयोगकर्ता का उदाहरण लें. उसके डिवाइस पर ये तीन उपयोगकर्ता खाते हैं:
emily.dickinson@gmail.com
emilyd@gmail.com
- Twitter खाता "belle_of_amherst"
इस उपयोगकर्ता ने खाते की सेटिंग में जाकर, इन तीनों खातों के लिए संपर्क सिंक करें सुविधा चालू की है.
मान लें कि एमिली डिकिंसन ने ब्राउज़र विंडो खोली, emily.dickinson@gmail.com
के तौर पर Gmail में लॉग इन किया, Contacts खोला, और "थॉमस हिगिंसन" को जोड़ा. बाद में, वह emilyd@gmail.com
के तौर पर Gmail में लॉग इन करती है और "थॉमस हिगिंसन" को एक ईमेल भेजती है. इससे वह अपने-आप संपर्क के तौर पर जुड़ जाता है. वह Twitter पर "colonel_tom" (थॉमस हिगिंसन का Twitter आईडी) को भी फ़ॉलो करती है.
संपर्क सूची की सेवा देने वाली कंपनी, इस काम के बाद तीन रॉ संपर्क बनाती है:
-
emily.dickinson@gmail.com
से जुड़ा "Thomas Higginson" का रॉ कॉन्टैक्ट. उपयोगकर्ता खाते का टाइप Google है. -
emilyd@gmail.com
से जुड़ा "थॉमस हिगिंसन" का दूसरा रॉ संपर्क. उपयोगकर्ता खाते का टाइप भी Google है. यहां दूसरा रॉ संपर्क मौजूद है. भले ही, नाम पिछले नाम जैसा ही हो, लेकिन व्यक्ति को किसी दूसरे उपयोगकर्ता खाते के लिए जोड़ा गया था. - "belle_of_amherst" से जुड़ा "थॉमस हिगिंसन" का तीसरा रॉ संपर्क. उपयोगकर्ता खाते का टाइप Twitter है.
डेटा
जैसा कि पहले बताया गया है, रॉ संपर्क का डेटा, ContactsContract.Data
लाइन में सेव होता है. यह लाइन, रॉ संपर्क की _ID
वैल्यू से लिंक होती है. इससे एक ही रॉ संपर्क में, एक ही तरह के डेटा के कई इंस्टेंस हो सकते हैं. जैसे, ईमेल पते या फ़ोन नंबर. उदाहरण के लिए, अगर emilyd@gmail.com
के लिए "थॉमस हिगिंसन" (थॉमस हिगिंसन के लिए, Google खाते emilyd@gmail.com
से जुड़ी रॉ संपर्क पंक्ति) के पास घर का ईमेल पता thigg@gmail.com
और ऑफ़िस का ईमेल पता thomas.higginson@gmail.com
है, तो Contacts Provider, दोनों ईमेल पते की पंक्तियों को सेव करता है और उन्हें रॉ संपर्क से लिंक करता है.
ध्यान दें कि इस एक टेबल में अलग-अलग तरह का डेटा सेव किया गया है. डिस्प्ले नेम, फ़ोन नंबर, ईमेल, डाक पता, फ़ोटो, और वेबसाइट की ज़्यादा जानकारी वाली लाइनें, सभी ContactsContract.Data
टेबल में मिलती हैं. इसे मैनेज करने के लिए, ContactsContract.Data
टेबल में कुछ कॉलम के नाम जानकारी देने वाले हैं और कुछ के नाम सामान्य हैं. ब्यौरे वाले नाम के कॉलम में मौजूद कॉन्टेंट का मतलब एक ही होता है. इससे कोई फ़र्क़ नहीं पड़ता कि लाइन में किस तरह का डेटा है. वहीं, सामान्य नाम वाले कॉलम में मौजूद कॉन्टेंट का मतलब, डेटा के टाइप के हिसाब से अलग-अलग होता है.
कॉलम के बारे में जानकारी देने वाले नाम
जानकारी देने वाले कॉलम के नामों के कुछ उदाहरण यहां दिए गए हैं:
-
RAW_CONTACT_ID
-
इस डेटा के लिए, रॉ संपर्क के
_ID
कॉलम की वैल्यू. -
MIMETYPE
-
इस लाइन में सेव किए गए डेटा का टाइप, जिसे कस्टम MIME टाइप के तौर पर दिखाया जाता है. संपर्क की जानकारी देने वाला ऐप्लिकेशन,
ContactsContract.CommonDataKinds
की सबक्लास में तय किए गए MIME टाइप का इस्तेमाल करता है. ये MIME टाइप ओपन सोर्स हैं. इनका इस्तेमाल, Contacts Provider के साथ काम करने वाला कोई भी ऐप्लिकेशन या सिंक अडैप्टर कर सकता है. -
IS_PRIMARY
-
अगर किसी रॉ संपर्क के लिए इस तरह की डेटा लाइन एक से ज़्यादा बार दिख सकती है, तो
IS_PRIMARY
कॉलम, उस डेटा लाइन को फ़्लैग करता है जिसमें टाइप के लिए प्राइमरी डेटा होता है. उदाहरण के लिए, अगर कोई उपयोगकर्ता किसी संपर्क के फ़ोन नंबर को दबाकर रखता है और डिफ़ॉल्ट के तौर पर सेट करें चुनता है, तो उस नंबर वालीContactsContract.Data
लाइन केIS_PRIMARY
कॉलम को शून्य से अलग वैल्यू पर सेट किया जाता है.
सामान्य कॉलम के नाम
सामान्य तौर पर उपलब्ध 15 सामान्य कॉलम हैं, जिनके नाम DATA1
से लेकर DATA15
तक हैं. इसके अलावा, चार अन्य सामान्य कॉलम SYNC1
से लेकर SYNC4
तक हैं. इनका इस्तेमाल सिर्फ़ सिंक अडैप्टर को करना चाहिए. कॉलम के नाम के सामान्य कॉन्सटेंट हमेशा काम करते हैं. इससे कोई फ़र्क़ नहीं पड़ता कि लाइन में किस तरह का डेटा है.
DATA1
कॉलम को इंडेक्स किया गया है. संपर्क की जानकारी देने वाली कंपनी, इस कॉलम का इस्तेमाल हमेशा उस डेटा के लिए करती है जिसे वह क्वेरी का सबसे ज़्यादा बार टारगेट किए जाने वाला डेटा मानती है. उदाहरण के लिए,
ईमेल वाली लाइन में, इस कॉलम में असली ईमेल पता होता है.
परंपरा के मुताबिक, कॉलम DATA15
को बाइनरी लार्ज ऑब्जेक्ट (बीएलओबी) डेटा सेव करने के लिए रिज़र्व किया जाता है. जैसे, फ़ोटो थंबनेल.
टाइप के हिसाब से कॉलम के नाम
किसी खास तरह की लाइन के लिए कॉलम के साथ काम करने की सुविधा देने के लिए, Contacts Provider, टाइप के हिसाब से कॉलम के नाम के कॉन्स्टेंट भी उपलब्ध कराता है. ये कॉन्स्टेंट, ContactsContract.CommonDataKinds
के सबक्लास में तय किए जाते हैं. कॉन्स्टेंट, कॉलम के एक ही नाम को अलग-अलग कॉन्स्टेंट के नाम देते हैं. इससे आपको किसी खास तरह की लाइन में मौजूद डेटा को ऐक्सेस करने में मदद मिलती है.
उदाहरण के लिए, ContactsContract.CommonDataKinds.Email
क्लास, ContactsContract.Data
लाइन के लिए टाइप के हिसाब से कॉलम के नाम के कॉन्स्टेंट तय करती है. इस लाइन का MIME टाइप Email.CONTENT_ITEM_TYPE
है. क्लास में ईमेल पते वाले कॉलम के लिए, कॉन्स्टेंट ADDRESS
मौजूद है. ADDRESS
की असल वैल्यू "data1" है, जो कॉलम के सामान्य नाम के बराबर है.
चेतावनी: ऐसी लाइन का इस्तेमाल करके ContactsContract.Data
टेबल में अपना कस्टम डेटा न जोड़ें जिसमें प्रोवाइडर के पहले से तय किए गए MIME टाइप में से कोई एक MIME टाइप मौजूद हो. ऐसा करने से, आपका डेटा मिट सकता है या सेवा देने वाली कंपनी की सेवा ठीक से काम नहीं कर सकती. उदाहरण के लिए, आपको ऐसी लाइन नहीं जोड़नी चाहिए जिसमें MIME टाइप Email.CONTENT_ITEM_TYPE
हो. साथ ही, कॉलम DATA1
में ईमेल पते के बजाय उपयोगकर्ता का नाम हो. अगर आपने लाइन के लिए, अपने हिसाब से कस्टम MIME टाइप का इस्तेमाल किया है, तो आपके पास टाइप के हिसाब से कॉलम के नाम तय करने का विकल्प होता है. साथ ही, अपनी ज़रूरत के हिसाब से कॉलम का इस्तेमाल किया जा सकता है.
दूसरी इमेज में दिखाया गया है कि जानकारी देने वाले कॉलम और डेटा कॉलम, ContactsContract.Data
लाइन में कैसे दिखते हैं. साथ ही, टाइप के हिसाब से कॉलम के नाम, सामान्य कॉलम के नामों पर "ओवरले" कैसे होते हैं

दूसरी इमेज. टाइप के हिसाब से कॉलम के नाम और सामान्य कॉलम के नाम.
टाइप के हिसाब से कॉलम के नाम की क्लास
दूसरी टेबल में, टाइप के हिसाब से कॉलम के नाम की सबसे ज़्यादा इस्तेमाल की जाने वाली क्लास दी गई हैं:
टेबल 2. टाइप के हिसाब से कॉलम के नाम की क्लास
मैपिंग क्लास | डेटा का टाइप | नोट |
---|---|---|
ContactsContract.CommonDataKinds.StructuredName |
इस डेटा लाइन से जुड़े रॉ संपर्क का नाम. | रॉ संपर्क में इनमें से सिर्फ़ एक लाइन होती है. |
ContactsContract.CommonDataKinds.Photo |
इस डेटा लाइन से जुड़े रॉ संपर्क की मुख्य फ़ोटो. | रॉ संपर्क में इनमें से सिर्फ़ एक लाइन होती है. |
ContactsContract.CommonDataKinds.Email |
इस डेटा लाइन से जुड़े रॉ संपर्क का ईमेल पता. | किसी रॉ संपर्क के कई ईमेल पते हो सकते हैं. |
ContactsContract.CommonDataKinds.StructuredPostal |
इस डेटा लाइन से जुड़े रॉ संपर्क का डाक पता. | किसी रॉ संपर्क के कई डाक पते हो सकते हैं. |
ContactsContract.CommonDataKinds.GroupMembership |
यह एक आइडेंटिफ़ायर है, जो रॉ संपर्क को Contacts Provider के किसी ग्रुप से लिंक करता है. | ग्रुप, खाते के टाइप और खाते के नाम की एक वैकल्पिक सुविधा है. इनके बारे में ज़्यादा जानकारी, संपर्क ग्रुप सेक्शन में दी गई है. |
संपर्क
संपर्क सूची, सभी तरह के खातों और खाता नामों में मौजूद संपर्क की रॉ फ़ाइलों को मिलाकर एक संपर्क बनाती है. इससे, किसी व्यक्ति के लिए उपयोगकर्ता के इकट्ठा किए गए सभी डेटा को दिखाने और उसमें बदलाव करने में मदद मिलती है. संपर्क की नई पंक्तियां बनाने और किसी मौजूदा संपर्क की पंक्ति में रॉ कॉन्टैक्ट इकट्ठा करने का काम, Contacts Provider करता है. ऐप्लिकेशन और सिंक अडैप्टर, दोनों को संपर्क जोड़ने की अनुमति नहीं है. साथ ही, संपर्क की लाइन में मौजूद कुछ कॉलम सिर्फ़ पढ़े जा सकते हैं.
ध्यान दें: अगर आपने Contacts Provider में insert()
वाला कोई संपर्क जोड़ने की कोशिश की, तो आपको UnsupportedOperationException
अपवाद मिलेगा. अगर "सिर्फ़ पढ़ने के लिए" के तौर पर लिस्ट किए गए कॉलम को अपडेट करने की कोशिश की जाती है, तो अपडेट को अनदेखा कर दिया जाता है.
जब कोई नया रॉ संपर्क जोड़ा जाता है और वह किसी मौजूदा संपर्क से मैच नहीं करता है, तो Contacts Provider एक नया संपर्क बनाता है. अगर किसी मौजूदा रॉ संपर्क का डेटा इस तरह से बदलता है कि वह अब उस संपर्क से मेल नहीं खाता जिससे वह पहले जुड़ा था, तो डेटा उपलब्ध कराने वाली कंपनी भी ऐसा करती है. अगर कोई ऐप्लिकेशन या सिंक अडैप्टर ऐसा नया रॉ संपर्क बनाता है जो किसी मौजूदा संपर्क से मेल खाता है, तो नए रॉ संपर्क को मौजूदा संपर्क में जोड़ दिया जाता है.
संपर्क जानकारी देने वाला ऐप्लिकेशन, संपर्क पंक्ति को उसकी रॉ संपर्क पंक्तियों से लिंक करता है. इसके लिए, वह Contacts
टेबल में संपर्क पंक्ति के _ID
कॉलम का इस्तेमाल करता है. कच्चे संपर्क की टेबल के CONTACT_ID
कॉलम में, _ID
वैल्यू होती हैं. ये वैल्यू, कच्चे संपर्क की हर लाइन से जुड़ी संपर्क लाइन के लिए होती हैं.ContactsContract.RawContacts
ContactsContract.Contacts
टेबल में LOOKUP_KEY
कॉलम भी होता है. यह कॉलम, संपर्क की लाइन से "स्थायी" तौर पर लिंक होता है. संपर्क की जानकारी देने वाला ऐप्लिकेशन, संपर्कों की जानकारी अपने-आप अपडेट करता है. इसलिए, यह एग्रीगेशन या सिंक के जवाब में, संपर्क की लाइन की _ID
वैल्यू बदल सकता है. ऐसा होने पर भी, कॉन्टेंट यूआरआई
CONTENT_LOOKUP_URI
के साथ संपर्क का LOOKUP_KEY
अब भी
संपर्क वाली लाइन पर ले जाएगा. इसलिए, "पसंदीदा" संपर्कों के लिंक बनाए रखने के लिए, LOOKUP_KEY
का इस्तेमाल किया जा सकता है. इस कॉलम का अपना फ़ॉर्मैट है, जो _ID
कॉलम के फ़ॉर्मैट से अलग है.
तीसरी इमेज में दिखाया गया है कि तीन मुख्य टेबल एक-दूसरे से कैसे जुड़ी हैं.

तीसरी इमेज. संपर्क, रॉ कॉन्टैक्ट, और जानकारी वाली टेबल के बीच संबंध.
चेतावनी: अगर आपने अपने ऐप्लिकेशन को Google Play Store पर पब्लिश किया है या आपका ऐप्लिकेशन Android 10 (एपीआई लेवल 29) या उसके बाद के वर्शन पर चल रहे डिवाइस पर है, तो ध्यान रखें कि संपर्क डेटा फ़ील्ड और तरीकों का सीमित सेट अब काम नहीं करता.
यहां बताई गई शर्तों के तहत, सिस्टम इन डेटा फ़ील्ड में लिखी गई वैल्यू को समय-समय पर मिटा देता है:
-
ContactsContract.ContactOptionsColumns.LAST_TIME_CONTACTED
-
ContactsContract.ContactOptionsColumns.TIMES_CONTACTED
-
ContactsContract.DataUsageStatColumns.LAST_TIME_USED
-
ContactsContract.DataUsageStatColumns.TIMES_USED
ऊपर दिए गए डेटा फ़ील्ड को सेट करने के लिए इस्तेमाल किए जाने वाले एपीआई भी अब काम नहीं करते:
इसके अलावा, अब इन फ़ील्ड में अक्सर इस्तेमाल किए जाने वाले संपर्क नहीं दिखते. ध्यान दें कि इनमें से कुछ फ़ील्ड, संपर्कों की रैंकिंग पर तब ही असर डालते हैं, जब संपर्क किसी खास डेटा टाइप का हिस्सा हों.
-
ContactsContract.Contacts.CONTENT_FREQUENT_URI
-
ContactsContract.Contacts.CONTENT_STREQUENT_URI
-
ContactsContract.Contacts.CONTENT_STREQUENT_FILTER_URI
-
CONTENT_FILTER_URI
(सिर्फ़ ईमेल, फ़ोन, कॉल किए जा सकने वाले, और संपर्क किए जा सकने वाले डेटा टाइप पर असर डालता है) -
ENTERPRISE_CONTENT_FILTER_URI
(सिर्फ़ ईमेल, फ़ोन, और कॉल किए जा सकने वाले डेटा टाइप पर लागू होता है)
अगर आपके ऐप्लिकेशन इन फ़ील्ड या एपीआई को ऐक्सेस या अपडेट कर रहे हैं, तो अन्य तरीकों का इस्तेमाल करें. उदाहरण के लिए, निजी कॉन्टेंट उपलब्ध कराने वाली कंपनियों का इस्तेमाल करके या अपने ऐप्लिकेशन या बैकएंड सिस्टम में सेव किए गए अन्य डेटा का इस्तेमाल करके, इस्तेमाल के कुछ उदाहरणों को पूरा किया जा सकता है.
यह पुष्टि करने के लिए कि इस बदलाव से आपके ऐप्लिकेशन के फ़ंक्शन पर कोई असर नहीं पड़ा है, इन डेटा फ़ील्ड को मैन्युअल तरीके से मिटाया जा सकता है. इसके लिए, Android 4.1 (एपीआई लेवल 16) या इसके बाद के वर्शन पर चलने वाले डिवाइस पर, नीचे दी गई ADB कमांड चलाएं:
adb shell content delete \ --uri content://com.android.contacts/contacts/delete_usage
सिंक अडैप्टर से मिला डेटा
उपयोगकर्ता, संपर्कों का डेटा सीधे डिवाइस में डालते हैं. हालांकि, डेटा को वेब सेवाओं से Contacts Provider में भी ट्रांसफ़र किया जाता है. इसके लिए, सिंक अडैप्टर का इस्तेमाल किया जाता है. ये डिवाइस और सेवाओं के बीच डेटा ट्रांसफ़र की प्रोसेस को अपने-आप पूरा करते हैं. सिंक अडैप्टर, सिस्टम के कंट्रोल में बैकग्राउंड में काम करते हैं. ये डेटा को मैनेज करने के लिए, ContentResolver
तरीकों का इस्तेमाल करते हैं.
Android में, सिंक अडैप्टर जिस वेब सेवा के साथ काम करता है उसकी पहचान खाते के टाइप से होती है. हर सिंक अडैप्टर, एक तरह के खाते के साथ काम करता है. हालांकि, यह उस तरह के खाते के लिए कई खाता नामों के साथ काम कर सकता है. खाते के टाइप और खाते के नामों के बारे में, संपर्क जानकारी के रॉ डेटा के सोर्स सेक्शन में बताया गया है. यहां दी गई परिभाषाओं में ज़्यादा जानकारी दी गई है. साथ ही, यह बताया गया है कि खाते का टाइप और नाम, सिंक अडैप्टर और सेवाओं से कैसे जुड़ा होता है.
- खाता टाइप
-
इस कुकी से उस सेवा की पहचान होती है जिसमें उपयोगकर्ता ने डेटा सेव किया है. ज़्यादातर मामलों में, उपयोगकर्ता को सेवा के लिए पुष्टि करनी होती है. उदाहरण के लिए, Google Contacts एक तरह का खाता है. इसकी पहचान
google.com
कोड से होती है. यह वैल्यू,AccountManager
के लिए इस्तेमाल किए गए खाते के टाइप से मेल खाती है. - खाते का नाम
- यह किसी खाता टाइप के लिए, किसी खास खाते या लॉगिन की पहचान करता है. Google Contacts खाते, Google खातों की तरह ही होते हैं. इनमें खाते के नाम के तौर पर ईमेल पते का इस्तेमाल किया जाता है. अन्य सेवाएं, एक शब्द वाले उपयोगकर्ता नाम या संख्या वाले आईडी का इस्तेमाल कर सकती हैं.
खाते के टाइप यूनीक होने ज़रूरी नहीं हैं. कोई उपयोगकर्ता, एक से ज़्यादा Google Contacts खाते कॉन्फ़िगर कर सकता है. साथ ही, Contacts Provider में उनका डेटा डाउनलोड कर सकता है. ऐसा तब हो सकता है, जब उपयोगकर्ता के पास निजी खाते के लिए निजी संपर्कों का एक सेट और काम के लिए दूसरा सेट हो. खातों के नाम आम तौर पर अलग-अलग होते हैं. ये दोनों मिलकर, Contacts Provider और किसी बाहरी सेवा के बीच डेटा के फ़्लो की पहचान करते हैं.
अगर आपको अपनी सेवा का डेटा, Contacts Provider को ट्रांसफ़र करना है, तो आपको अपना खुद का सिंक अडैप्टर लिखना होगा. इस बारे में ज़्यादा जानकारी, संपर्क की जानकारी देने वाले ऐप्लिकेशन के सिंक अडैप्टर सेक्शन में दी गई है.
चौथे फ़िगर में दिखाया गया है कि Contacts Provider, लोगों के डेटा के फ़्लो में कैसे काम करता है. "सिंक अडैप्टर" के तौर पर मार्क किए गए बॉक्स में, हर अडैप्टर को उसके खाते के टाइप के हिसाब से लेबल किया जाता है.

चौथी इमेज. संपर्क सूची के डेटा का फ़्लो.
ज़रूरी अनुमतियां
संपर्क की जानकारी देने वाले ऐप्लिकेशन को ये अनुमतियां मांगनी होंगी:
- एक या उससे ज़्यादा टेबल का डेटा देखने का ऐक्सेस
-
READ_CONTACTS
,AndroidManifest.xml
में<uses-permission>
एलिमेंट के साथ<uses-permission android:name="android.permission.READ_CONTACTS">
के तौर पर तय किया गया है. - एक या उससे ज़्यादा टेबल में डेटा लिखने का ऐक्सेस
-
WRITE_CONTACTS
,AndroidManifest.xml
में<uses-permission>
एलिमेंट के साथ<uses-permission android:name="android.permission.WRITE_CONTACTS">
के तौर पर तय किया गया है.
ये अनुमतियां, उपयोगकर्ता की प्रोफ़ाइल के डेटा पर लागू नहीं होती हैं. उपयोगकर्ता की प्रोफ़ाइल और इसके लिए ज़रूरी अनुमतियों के बारे में यहां बताया गया है: उपयोगकर्ता की प्रोफ़ाइल.
ध्यान रखें कि उपयोगकर्ता के संपर्कों का डेटा निजी और संवेदनशील होता है. उपयोगकर्ता अपनी निजता को लेकर चिंतित हैं. इसलिए, वे नहीं चाहते कि ऐप्लिकेशन उनका या उनके संपर्कों का डेटा इकट्ठा करें. अगर यह साफ़ तौर पर नहीं बताया गया है कि आपको उनके संपर्कों के डेटा को ऐक्सेस करने की अनुमति क्यों चाहिए, तो वे आपके ऐप्लिकेशन को कम रेटिंग दे सकते हैं या उसे इंस्टॉल करने से मना कर सकते हैं.
उपयोगकर्ता की प्रोफ़ाइल
ContactsContract.Contacts
टेबल में एक लाइन होती है. इसमें डिवाइस के उपयोगकर्ता का प्रोफ़ाइल डेटा होता है. इस डेटा में, उपयोगकर्ता के किसी संपर्क के बजाय डिवाइस के user
के बारे में बताया गया है. प्रोफ़ाइल के संपर्कों की लाइन, प्रोफ़ाइल का इस्तेमाल करने वाले हर सिस्टम के लिए, रॉ कॉन्टैक्ट की लाइन से जुड़ी होती है.
हर प्रोफ़ाइल के रॉ कॉन्टैक्ट की लाइन में, डेटा की कई लाइनें हो सकती हैं. उपयोगकर्ता की प्रोफ़ाइल को ऐक्सेस करने के लिए कॉन्स्टेंट, ContactsContract.Profile
क्लास में उपलब्ध हैं.
उपयोगकर्ता की प्रोफ़ाइल को ऐक्सेस करने के लिए, खास अनुमतियों की ज़रूरत होती है. पढ़ने और लिखने के लिए, READ_CONTACTS
और WRITE_CONTACTS
अनुमतियों के अलावा, उपयोगकर्ता की प्रोफ़ाइल को ऐक्सेस करने के लिए, android.Manifest.permission#READ_PROFILE और android.Manifest.permission#WRITE_PROFILE अनुमतियों की ज़रूरत होती है. ये अनुमतियां, पढ़ने और लिखने के ऐक्सेस के लिए होती हैं.
ध्यान रखें कि आपको किसी उपयोगकर्ता की प्रोफ़ाइल को संवेदनशील मानना चाहिए. android.Manifest.permission#READ_PROFILE अनुमति से, आपको डिवाइस के उपयोगकर्ता का निजी पहचान डेटा ऐक्सेस करने की अनुमति मिलती है. अपने ऐप्लिकेशन के ब्यौरे में, उपयोगकर्ता को यह ज़रूर बताएं कि आपको उपयोगकर्ता की प्रोफ़ाइल ऐक्सेस करने की अनुमतियां क्यों चाहिए.
उपयोगकर्ता की प्रोफ़ाइल वाली संपर्क लाइन को वापस पाने के लिए, ContentResolver.query()
को कॉल करें. कॉन्टेंट यूआरआई को CONTENT_URI
पर सेट करें और चुनने की कोई शर्त न दें. इस कॉन्टेंट यूआरआई का इस्तेमाल, प्रोफ़ाइल के लिए रॉ संपर्क या डेटा पाने के लिए, बेस यूआरआई के तौर पर भी किया जा सकता है. उदाहरण के लिए, यह स्निपेट इस प्रोफ़ाइल के लिए डेटा वापस लाता है:
Kotlin
// Sets the columns to retrieve for the user profile projection = arrayOf( ContactsContract.Profile._ID, ContactsContract.Profile.DISPLAY_NAME_PRIMARY, ContactsContract.Profile.LOOKUP_KEY, ContactsContract.Profile.PHOTO_THUMBNAIL_URI ) // Retrieves the profile from the Contacts Provider profileCursor = contentResolver.query( ContactsContract.Profile.CONTENT_URI, projection, null, null, null )
Java
// Sets the columns to retrieve for the user profile projection = new String[] { Profile._ID, Profile.DISPLAY_NAME_PRIMARY, Profile.LOOKUP_KEY, Profile.PHOTO_THUMBNAIL_URI }; // Retrieves the profile from the Contacts Provider profileCursor = getContentResolver().query( Profile.CONTENT_URI, projection , null, null, null);
ध्यान दें: अगर आपको संपर्क जानकारी वाली कई लाइनें मिलती हैं और आपको यह पता लगाना है कि इनमें से कोई लाइन उपयोगकर्ता की प्रोफ़ाइल है या नहीं, तो लाइन के IS_USER_PROFILE
कॉलम की जांच करें. अगर संपर्क, उपयोगकर्ता प्रोफ़ाइल है, तो इस कॉलम की वैल्यू "1" पर सेट होती है.
संपर्क सूची की सेवा देने वाली कंपनी का मेटाडेटा
संपर्क सूची, ऐसे डेटा को मैनेज करती है जो रिपॉज़िटरी में मौजूद संपर्कों के डेटा की स्थिति को ट्रैक करता है. रिपॉज़िटरी के बारे में यह मेटाडेटा, अलग-अलग जगहों पर सेव किया जाता है. जैसे, Raw Contacts, Data, और Contacts टेबल की लाइनों में, ContactsContract.Settings
टेबल में, और ContactsContract.SyncState
टेबल में. इस टेबल में, मेटाडेटा के हर हिस्से का असर दिखाया गया है:
टेबल 3. संपर्क सूची में मौजूद मेटाडेटा
टेबल | कॉलम | वैल्यू | मतलब |
---|---|---|---|
ContactsContract.RawContacts |
DIRTY |
"0" - पिछली बार सिंक करने के बाद से कोई बदलाव नहीं हुआ है. |
यह उन रॉ संपर्कों को मार्क करता है जिन्हें डिवाइस पर बदला गया है और जिन्हें सर्वर पर वापस सिंक करना है. जब Android ऐप्लिकेशन किसी लाइन को अपडेट करते हैं, तब Contacts Provider इस वैल्यू को अपने-आप सेट करता है.
कच्चे संपर्क या डेटा टेबल में बदलाव करने वाले सिंक अडैप्टर को हमेशा उस कॉन्टेंट यूआरआई में |
"1" - इसका मतलब है कि पिछली बार सिंक करने के बाद बदलाव किया गया है. इसे सर्वर के साथ फिर से सिंक करना होगा. | |||
ContactsContract.RawContacts |
VERSION |
इस लाइन का वर्शन नंबर. | जब भी पंक्ति या उससे जुड़ा डेटा बदलता है, तो Contacts Provider इस वैल्यू को अपने-आप बढ़ा देता है. |
ContactsContract.Data |
DATA_VERSION |
इस लाइन का वर्शन नंबर. | डेटा लाइन में बदलाव होने पर, Contacts Provider इस वैल्यू को अपने-आप बढ़ा देता है. |
ContactsContract.RawContacts |
SOURCE_ID |
यह स्ट्रिंग वैल्यू, उस खाते में इस रॉ संपर्क की खास पहचान करती है जिसमें इसे बनाया गया था. |
जब कोई सिंक अडैप्टर नया रॉ संपर्क बनाता है, तो इस कॉलम को रॉ संपर्क के लिए सर्वर के यूनीक आईडी पर सेट किया जाना चाहिए. जब कोई Android ऐप्लिकेशन नया रॉ संपर्क बनाता है, तो ऐप्लिकेशन को इस कॉलम को खाली छोड़ देना चाहिए. इससे सिंक अडैप्टर को यह सिग्नल मिलता है कि उसे सर्वर पर एक नया रॉ संपर्क बनाना चाहिए और SOURCE_ID के लिए वैल्यू लेनी चाहिए.
खास तौर पर, सोर्स आईडी हर खाते के टाइप के लिए यूनीक होना चाहिए. साथ ही, सिंक किए गए सभी खातों में एक जैसा होना चाहिए:
|
ContactsContract.Groups |
GROUP_VISIBLE |
"0" - इस ग्रुप के संपर्क, Android ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) में नहीं दिखने चाहिए. | यह कॉलम, उन सर्वर के साथ काम करने के लिए है जो उपयोगकर्ता को कुछ ग्रुप में संपर्क छिपाने की अनुमति देते हैं. |
"1" - इस ग्रुप में मौजूद संपर्कों को ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) में दिखने की अनुमति है. | |||
ContactsContract.Settings |
UNGROUPED_VISIBLE |
"0" - इस खाते और खाते के टाइप के लिए, ऐसे संपर्क जो किसी ग्रुप से नहीं जुड़े हैं वे Android ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) में नहीं दिखते. |
डिफ़ॉल्ट रूप से, अगर किसी संपर्क का कोई भी रॉ संपर्क किसी ग्रुप का हिस्सा नहीं है, तो वह संपर्क नहीं दिखता
(किसी रॉ संपर्क के ग्रुप का सदस्य होने की जानकारी, ContactsContract.Data टेबल में एक या उससे ज़्यादा
ContactsContract.CommonDataKinds.GroupMembership लाइनों से मिलती है).
खाते के टाइप और खाते के लिए, ContactsContract.Settings टेबल की लाइन में यह फ़्लैग सेट करके, उन संपर्कों को दिखने के लिए मजबूर किया जा सकता है जिनके पास ग्रुप नहीं हैं.
इस फ़्लैग का इस्तेमाल, उन सर्वर के संपर्कों को दिखाने के लिए किया जाता है जो ग्रुप का इस्तेमाल नहीं करते.
|
"1" - इस खाते और खाते के टाइप के लिए, ऐसे संपर्क ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) को दिखते हैं जो किसी ग्रुप से नहीं जुड़े हैं. | |||
ContactsContract.SyncState |
(सभी) | इस टेबल का इस्तेमाल, सिंक अडैप्टर के मेटाडेटा को सेव करने के लिए करें. | इस टेबल की मदद से, सिंक की स्थिति और सिंक से जुड़ा अन्य डेटा, डिवाइस पर लगातार सेव किया जा सकता है. |
संपर्क सूची का ऐक्सेस
इस सेक्शन में, Contacts Provider से डेटा ऐक्सेस करने के दिशा-निर्देशों के बारे में बताया गया है. इसमें इन बातों पर फ़ोकस किया गया है:
- इकाई के बारे में क्वेरी.
- एक साथ कई बदलाव करना.
- इरादे के हिसाब से जानकारी पाना और उसमें बदलाव करना.
- डेटा का रखरखाव.
सिंक अडैप्टर से बदलाव करने के बारे में ज़्यादा जानकारी, संपर्क की जानकारी देने वाले सिंक अडैप्टर सेक्शन में दी गई है.
क्वेरी करने वाली इकाइयां
संपर्क की जानकारी देने वाली सेवा की टेबल को हैरारकी में व्यवस्थित किया जाता है. इसलिए, अक्सर किसी लाइन और उससे जुड़ी सभी "चाइल्ड" लाइनों को वापस पाने के लिए, इस तरीके का इस्तेमाल करना फ़ायदेमंद होता है. उदाहरण के लिए, किसी व्यक्ति की पूरी जानकारी दिखाने के लिए, आपको किसी एक ContactsContract.Contacts
लाइन की सभी ContactsContract.RawContacts
लाइनें या किसी एक ContactsContract.RawContacts
लाइन की सभी ContactsContract.CommonDataKinds.Email
लाइनें वापस लानी पड़ सकती हैं. इसके लिए, Contacts Provider entity कंस्ट्रक्ट उपलब्ध कराता है. ये टेबल के बीच डेटाबेस जॉइन की तरह काम करते हैं.
इकाई, पैरंट टेबल और उसकी चाइल्ड टेबल के चुने गए कॉलम से बनी टेबल की तरह होती है.
किसी इकाई के बारे में क्वेरी करते समय, आपको इकाई से उपलब्ध कॉलम के आधार पर प्रोजेक्शन और खोज की शर्तें देनी होती हैं. नतीजा एक Cursor
होता है. इसमें, फ़ेच की गई हर चाइल्ड टेबल लाइन के लिए एक लाइन होती है. उदाहरण के लिए, अगर आपने किसी संपर्क के नाम के लिए ContactsContract.Contacts.Entity
क्वेरी की है और उस नाम के सभी रॉ संपर्कों के लिए सभी ContactsContract.CommonDataKinds.Email
पंक्तियां क्वेरी की हैं, तो आपको Cursor
वापस मिलेगा. इसमें हर ContactsContract.CommonDataKinds.Email
पंक्ति के लिए एक पंक्ति होगी.
इकाइयों की मदद से क्वेरी को आसान बनाया जा सकता है. किसी इकाई का इस्तेमाल करके, किसी संपर्क या रॉ संपर्क का पूरा डेटा एक साथ वापस पाया जा सकता है. इसके लिए, पहले पैरंट टेबल से आईडी पाने और फिर उस आईडी से चाइल्ड टेबल को क्वेरी करने की ज़रूरत नहीं होती. इसके अलावा, Contacts Provider एक ही लेन-देन में किसी इकाई के ख़िलाफ़ क्वेरी को प्रोसेस करता है. इससे यह पक्का होता है कि वापस पाया गया डेटा, अंदरूनी तौर पर एक जैसा हो.
ध्यान दें: आम तौर पर, किसी इकाई में पैरंट और चाइल्ड टेबल के सभी कॉलम शामिल नहीं होते हैं. अगर आपने किसी ऐसे कॉलम के नाम का इस्तेमाल किया है जो इकाई के लिए कॉलम के नाम वाले कॉन्स्टेंट की सूची में शामिल नहीं है, तो आपको Exception
मिलेगा.
नीचे दिए गए स्निपेट में, किसी संपर्क के लिए सभी रॉ संपर्क लाइनें वापस पाने का तरीका बताया गया है. यह स्निपेट, किसी बड़े ऐप्लिकेशन का हिस्सा है. इसमें दो गतिविधियां हैं: "main" और "detail". मुख्य गतिविधि में, संपर्क की पंक्तियों की सूची दिखती है. जब उपयोगकर्ता किसी पंक्ति को चुनता है, तो गतिविधि उसका आईडी, जानकारी वाली गतिविधि को भेजती है. ज़्यादा जानकारी वाली गतिविधि, ContactsContract.Contacts.Entity
का इस्तेमाल करके, चुने गए संपर्क से जुड़े सभी रॉ कॉन्टैक्ट की सभी डेटा लाइनें दिखाती है.
यह स्निपेट, "जानकारी" गतिविधि से लिया गया है:
Kotlin
... /* * Appends the entity path to the URI. In the case of the Contacts Provider, the * expected URI is content://com.google.contacts/#/entity (# is the ID value). */ contactUri = Uri.withAppendedPath( contactUri, ContactsContract.Contacts.Entity.CONTENT_DIRECTORY ) // Initializes the loader identified by LOADER_ID. loaderManager.initLoader( LOADER_ID, // The identifier of the loader to initialize null, // Arguments for the loader (in this case, none) this // The context of the activity ) // Creates a new cursor adapter to attach to the list view cursorAdapter = SimpleCursorAdapter( this, // the context of the activity R.layout.detail_list_item, // the view item containing the detail widgets mCursor, // the backing cursor fromColumns, // the columns in the cursor that provide the data toViews, // the views in the view item that display the data 0) // flags // Sets the ListView's backing adapter. rawContactList.adapter = cursorAdapter ... override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor> { /* * Sets the columns to retrieve. * RAW_CONTACT_ID is included to identify the raw contact associated with the data row. * DATA1 contains the first column in the data row (usually the most important one). * MIMETYPE indicates the type of data in the data row. */ val projection: Array<String> = arrayOf( ContactsContract.Contacts.Entity.RAW_CONTACT_ID, ContactsContract.Contacts.Entity.DATA1, ContactsContract.Contacts.Entity.MIMETYPE ) /* * Sorts the retrieved cursor by raw contact id, to keep all data rows for a single raw * contact collated together. */ val sortOrder = "${ContactsContract.Contacts.Entity.RAW_CONTACT_ID} ASC" /* * Returns a new CursorLoader. The arguments are similar to * ContentResolver.query(), except for the Context argument, which supplies the location of * the ContentResolver to use. */ return CursorLoader( applicationContext, // The activity's context contactUri, // The entity content URI for a single contact projection, // The columns to retrieve null, // Retrieve all the raw contacts and their data rows. null, // sortOrder // Sort by the raw contact ID. ) }
Java
... /* * Appends the entity path to the URI. In the case of the Contacts Provider, the * expected URI is content://com.google.contacts/#/entity (# is the ID value). */ contactUri = Uri.withAppendedPath( contactUri, ContactsContract.Contacts.Entity.CONTENT_DIRECTORY); // Initializes the loader identified by LOADER_ID. getLoaderManager().initLoader( LOADER_ID, // The identifier of the loader to initialize null, // Arguments for the loader (in this case, none) this); // The context of the activity // Creates a new cursor adapter to attach to the list view cursorAdapter = new SimpleCursorAdapter( this, // the context of the activity R.layout.detail_list_item, // the view item containing the detail widgets mCursor, // the backing cursor fromColumns, // the columns in the cursor that provide the data toViews, // the views in the view item that display the data 0); // flags // Sets the ListView's backing adapter. rawContactList.setAdapter(cursorAdapter); ... @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { /* * Sets the columns to retrieve. * RAW_CONTACT_ID is included to identify the raw contact associated with the data row. * DATA1 contains the first column in the data row (usually the most important one). * MIMETYPE indicates the type of data in the data row. */ String[] projection = { ContactsContract.Contacts.Entity.RAW_CONTACT_ID, ContactsContract.Contacts.Entity.DATA1, ContactsContract.Contacts.Entity.MIMETYPE }; /* * Sorts the retrieved cursor by raw contact id, to keep all data rows for a single raw * contact collated together. */ String sortOrder = ContactsContract.Contacts.Entity.RAW_CONTACT_ID + " ASC"; /* * Returns a new CursorLoader. The arguments are similar to * ContentResolver.query(), except for the Context argument, which supplies the location of * the ContentResolver to use. */ return new CursorLoader( getApplicationContext(), // The activity's context contactUri, // The entity content URI for a single contact projection, // The columns to retrieve null, // Retrieve all the raw contacts and their data rows. null, // sortOrder); // Sort by the raw contact ID. }
डेटा लोड होने के बाद, LoaderManager
, onLoadFinished()
को कॉलबैक शुरू करता है. इस तरीके के लिए, आने वाले आर्ग्युमेंट में से एक Cursor
है. इसमें क्वेरी के नतीजे शामिल होते हैं. अपने ऐप्लिकेशन में, इस Cursor
से डेटा पाया जा सकता है, ताकि उसे दिखाया जा सके या उस पर आगे काम किया जा सके.
बैच में बदलाव करने की सुविधा
जब भी हो सके, आपको Contacts Provider में डेटा डालने, अपडेट करने, और मिटाने के लिए "बैच मोड" का इस्तेमाल करना चाहिए. इसके लिए, ArrayList
के ContentProviderOperation
ऑब्जेक्ट बनाएं और applyBatch()
को कॉल करें. ऐसा इसलिए होता है, क्योंकि Contacts Provider, applyBatch()
में सभी कार्रवाइयां एक ही लेन-देन में करता है. इसलिए, आपके बदलाव कभी भी संपर्कों के डेटा स्टोर में अलग-अलग स्थिति में नहीं दिखेंगे. बैच मॉडिफ़िकेशन की मदद से, एक साथ रॉ संपर्क और उसके बारे में जानकारी वाला डेटा भी डाला जा सकता है.
ध्यान दें: किसी एक रॉ संपर्क में बदलाव करने के लिए, अपने ऐप्लिकेशन में बदलाव करने के बजाय, डिवाइस के Contacts ऐप्लिकेशन को इंटेंट भेजें. ऐसा करने के बारे में ज़्यादा जानकारी, इंटेंट की मदद से डेटा पाना और उसमें बदलाव करना सेक्शन में दी गई है.
ईल्ड पॉइंट
बदलाव के ऐसे बैच में कई कार्रवाइयां शामिल हो सकती हैं जो अन्य प्रोसेस को ब्लॉक कर सकती हैं. इससे उपयोगकर्ता को खराब अनुभव मिल सकता है. आपको जितने भी बदलाव करने हैं उन्हें कम से कम अलग-अलग सूचियों में व्यवस्थित करने के लिए, एक या उससे ज़्यादा कार्रवाइयों के लिए यील्ड पॉइंट सेट करें. इससे सिस्टम को ब्लॉक होने से भी बचाया जा सकेगा.
यील्ड पॉइंट एक ContentProviderOperation
ऑब्जेक्ट होता है, जिसकी isYieldAllowed()
वैल्यू true
पर सेट होती है. जब Contacts Provider को यिल्ड पॉइंट मिलता है, तो वह अपना काम रोक देता है, ताकि अन्य प्रोसेस चल सकें. साथ ही, वह मौजूदा लेन-देन को बंद कर देता है. जब प्रोवाइडर फिर से शुरू होता है, तो वह ArrayList
में मौजूद अगले ऑपरेशन को जारी रखता है और एक नया लेन-देन शुरू करता है.
यील्ड पॉइंट की वजह से, applyBatch()
को किए गए हर कॉल पर एक से ज़्यादा लेन-देन होते हैं. इस वजह से, आपको मिलती-जुलती लाइनों के सेट के लिए, आखिरी ऑपरेशन के लिए यील्ड पॉइंट सेट करना चाहिए.
उदाहरण के लिए, आपको ऐसे सेट में आखिरी ऑपरेशन के लिए यील्ड पॉइंट सेट करना चाहिए जो रॉ संपर्क वाली पंक्तियों और उनसे जुड़ी डेटा पंक्तियों को जोड़ता है. इसके अलावा, आपको किसी एक संपर्क से जुड़ी पंक्तियों के सेट के लिए आखिरी ऑपरेशन के लिए भी यील्ड पॉइंट सेट करना चाहिए.
यील्ड पॉइंट भी ऐटॉमिक ऑपरेशन की एक यूनिट है. दो यिल्ड पॉइंट के बीच के सभी ऐक्सेस, एक यूनिट के तौर पर या तो पूरे होंगे या फ़ेल हो जाएंगे. अगर आपने कोई यिल्ड पॉइंट सेट नहीं किया है, तो सबसे छोटी एटॉमिक कार्रवाई, कार्रवाइयों का पूरा बैच होती है. अगर यिल्ड पॉइंट का इस्तेमाल किया जाता है, तो सिस्टम की परफ़ॉर्मेंस को खराब होने से रोका जा सकता है. साथ ही, यह भी पक्का किया जा सकता है कि कुछ ऑपरेशन ऐटॉमिक हों.
बदलाव के बैक रेफ़रंस
जब आपको नई रॉ संपर्क पंक्ति और उससे जुड़ी डेटा पंक्तियों को ContentProviderOperation
ऑब्जेक्ट के सेट के तौर पर डालना होता है, तो आपको डेटा पंक्तियों को रॉ संपर्क पंक्ति से लिंक करना होता है. इसके लिए, रॉ संपर्क की _ID
वैल्यू को RAW_CONTACT_ID
वैल्यू के तौर पर डालें. हालांकि, डेटा लाइन के लिए ContentProviderOperation
बनाते समय, यह वैल्यू उपलब्ध नहीं होती. ऐसा इसलिए, क्योंकि आपने अब तक संपर्क की रॉ लाइन के लिए ContentProviderOperation
लागू नहीं किया है. इस समस्या को हल करने के लिए, ContentProviderOperation.Builder
क्लास में withValueBackReference()
तरीका है.
इस तरीके से, पिछले ऑपरेशन के नतीजे वाले कॉलम को डाला या बदला जा सकता है.
withValueBackReference()
मेथड में दो तर्क होते हैं:
-
key
- की-वैल्यू पेयर की कुंजी. इस आर्ग्युमेंट की वैल्यू, उस टेबल के कॉलम का नाम होना चाहिए जिसमें बदलाव किया जा रहा है.
-
previousResult
-
यह
applyBatch()
से मिलेContentProviderResult
ऑब्जेक्ट के कलेक्शन में मौजूद किसी वैल्यू का 0 से शुरू होने वाला इंडेक्स है. बैच ऑपरेशन लागू होने पर, हर ऑपरेशन का नतीजा, नतीजों के इंटरमीडिएट ऐरे में सेव हो जाता है.previousResult
वैल्यू, इनमें से किसी एक नतीजे का इंडेक्स होती है. इसेkey
वैल्यू के साथ सेव किया जाता है. इससे आपको नई रॉ संपर्क रिकॉर्ड डालने और उसकी_ID
वैल्यू वापस पाने की अनुमति मिलती है. इसके बाद,ContactsContract.Data
लाइन जोड़ते समय, वैल्यू का "बैक रेफ़रंस" बनाया जा सकता है.जब पहली बार
applyBatch()
को कॉल किया जाता है, तब पूरी नतीजे वाली अरे बनाई जाती है. इसका साइज़, आपके दिए गएContentProviderOperation
ऑब्जेक्ट केArrayList
के साइज़ के बराबर होता है. हालांकि, नतीजे के ऐरे में मौजूद सभी एलिमेंट कोnull
पर सेट किया जाता है. साथ ही, अगर आपने किसी ऐसी कार्रवाई के लिए नतीजे का बैक रेफ़रंस देने की कोशिश की है जिसे अभी तक लागू नहीं किया गया है, तोwithValueBackReference()
,Exception
दिखाता है.
यहां दिए गए स्निपेट में, बैच में नया रॉ संपर्क और डेटा डालने का तरीका बताया गया है. इनमें ऐसा कोड शामिल होता है जो यील्ड पॉइंट सेट करता है और बैक रेफ़रंस का इस्तेमाल करता है.
पहले स्निपेट में, यूज़र इंटरफ़ेस (यूआई) से संपर्क डेटा वापस पाने का तरीका बताया गया है. इस समय, उपयोगकर्ता ने उस खाते को पहले ही चुन लिया है जिसमें नया रॉ संपर्क जोड़ना है.
Kotlin
// Creates a contact entry from the current UI values, using the currently-selected account. private fun createContactEntry() { /* * Gets values from the UI */ val name = contactNameEditText.text.toString() val phone = contactPhoneEditText.text.toString() val email = contactEmailEditText.text.toString() val phoneType: String = contactPhoneTypes[mContactPhoneTypeSpinner.selectedItemPosition] val emailType: String = contactEmailTypes[mContactEmailTypeSpinner.selectedItemPosition]
Java
// Creates a contact entry from the current UI values, using the currently-selected account. protected void createContactEntry() { /* * Gets values from the UI */ String name = contactNameEditText.getText().toString(); String phone = contactPhoneEditText.getText().toString(); String email = contactEmailEditText.getText().toString(); int phoneType = contactPhoneTypes.get( contactPhoneTypeSpinner.getSelectedItemPosition()); int emailType = contactEmailTypes.get( contactEmailTypeSpinner.getSelectedItemPosition());
अगला स्निपेट, ContactsContract.RawContacts
टेबल में रॉ संपर्क पंक्ति डालने के लिए एक ऑपरेशन बनाता है:
Kotlin
/* * Prepares the batch operation for inserting a new raw contact and its data. Even if * the Contacts Provider does not have any data for this person, you can't add a Contact, * only a raw contact. The Contacts Provider will then add a Contact automatically. */ // Creates a new array of ContentProviderOperation objects. val ops = arrayListOf<ContentProviderOperation>() /* * Creates a new raw contact with its account type (server type) and account name * (user's account). Remember that the display name is not stored in this row, but in a * StructuredName data row. No other data is required. */ var op: ContentProviderOperation.Builder = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, selectedAccount.name) .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, selectedAccount.type) // Builds the operation and adds it to the array of operations ops.add(op.build())
Java
/* * Prepares the batch operation for inserting a new raw contact and its data. Even if * the Contacts Provider does not have any data for this person, you can't add a Contact, * only a raw contact. The Contacts Provider will then add a Contact automatically. */ // Creates a new array of ContentProviderOperation objects. ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); /* * Creates a new raw contact with its account type (server type) and account name * (user's account). Remember that the display name is not stored in this row, but in a * StructuredName data row. No other data is required. */ ContentProviderOperation.Builder op = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, selectedAccount.getType()) .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, selectedAccount.getName()); // Builds the operation and adds it to the array of operations ops.add(op.build());
इसके बाद, कोड डिसप्ले नेम, फ़ोन, और ईमेल पते की पंक्तियों के लिए डेटा लाइनें बनाता है.
हर ऑपरेशन बिल्डर ऑब्जेक्ट, RAW_CONTACT_ID
पाने के लिए withValueBackReference()
का इस्तेमाल करता है. रेफ़रंस पॉइंट, पहले ऑपरेशन से ContentProviderResult
ऑब्जेक्ट पर वापस जाता है. इससे रॉ संपर्क वाली लाइन जुड़ जाती है और उसकी नई _ID
वैल्यू दिखती है. इस वजह से, हर डेटा लाइन अपने RAW_CONTACT_ID
के हिसाब से, उस नई ContactsContract.RawContacts
लाइन से अपने-आप लिंक हो जाती है जिससे वह जुड़ी है.
ईमेल वाली लाइन जोड़ने वाले ContentProviderOperation.Builder
ऑब्जेक्ट को withYieldAllowed()
के तौर पर फ़्लैग किया गया है. इससे यील्ड पॉइंट सेट होता है:
Kotlin
// Creates the display name for the new raw contact, as a StructuredName data row. op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) /* * withValueBackReference sets the value of the first argument to the value of * the ContentProviderResult indexed by the second argument. In this particular * call, the raw contact ID column of the StructuredName data row is set to the * value of the result returned by the first operation, which is the one that * actually adds the raw contact row. */ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) // Sets the data row's MIME type to StructuredName .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) // Sets the data row's display name to the name in the UI. .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name) // Builds the operation and adds it to the array of operations ops.add(op.build()) // Inserts the specified phone number and type as a Phone data row op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) /* * Sets the value of the raw contact id column to the new raw contact ID returned * by the first operation in the batch. */ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) // Sets the data row's MIME type to Phone .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) // Sets the phone number and type .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone) .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType) // Builds the operation and adds it to the array of operations ops.add(op.build()) // Inserts the specified email and type as a Phone data row op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) /* * Sets the value of the raw contact id column to the new raw contact ID returned * by the first operation in the batch. */ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) // Sets the data row's MIME type to Email .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) // Sets the email address and type .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, email) .withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType) /* * Demonstrates a yield point. At the end of this insert, the batch operation's thread * will yield priority to other threads. Use after every set of operations that affect a * single contact, to avoid degrading performance. */ op.withYieldAllowed(true) // Builds the operation and adds it to the array of operations ops.add(op.build())
Java
// Creates the display name for the new raw contact, as a StructuredName data row. op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) /* * withValueBackReference sets the value of the first argument to the value of * the ContentProviderResult indexed by the second argument. In this particular * call, the raw contact ID column of the StructuredName data row is set to the * value of the result returned by the first operation, which is the one that * actually adds the raw contact row. */ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) // Sets the data row's MIME type to StructuredName .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) // Sets the data row's display name to the name in the UI. .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name); // Builds the operation and adds it to the array of operations ops.add(op.build()); // Inserts the specified phone number and type as a Phone data row op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) /* * Sets the value of the raw contact id column to the new raw contact ID returned * by the first operation in the batch. */ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) // Sets the data row's MIME type to Phone .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) // Sets the phone number and type .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone) .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType); // Builds the operation and adds it to the array of operations ops.add(op.build()); // Inserts the specified email and type as a Phone data row op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) /* * Sets the value of the raw contact id column to the new raw contact ID returned * by the first operation in the batch. */ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) // Sets the data row's MIME type to Email .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) // Sets the email address and type .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, email) .withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType); /* * Demonstrates a yield point. At the end of this insert, the batch operation's thread * will yield priority to other threads. Use after every set of operations that affect a * single contact, to avoid degrading performance. */ op.withYieldAllowed(true); // Builds the operation and adds it to the array of operations ops.add(op.build());
आखिरी स्निपेट में, applyBatch()
को कॉल करने का तरीका दिखाया गया है. यह नया रॉ संपर्क और डेटा लाइनें डालता है.
Kotlin
// Ask the Contacts Provider to create a new contact Log.d(TAG, "Selected account: ${mSelectedAccount.name} (${mSelectedAccount.type})") Log.d(TAG, "Creating contact: $name") /* * Applies the array of ContentProviderOperation objects in batch. The results are * discarded. */ try { contentResolver.applyBatch(ContactsContract.AUTHORITY, ops) } catch (e: Exception) { // Display a warning val txt: String = getString(R.string.contactCreationFailure) Toast.makeText(applicationContext, txt, Toast.LENGTH_SHORT).show() // Log exception Log.e(TAG, "Exception encountered while inserting contact: $e") } }
Java
// Ask the Contacts Provider to create a new contact Log.d(TAG,"Selected account: " + selectedAccount.getName() + " (" + selectedAccount.getType() + ")"); Log.d(TAG,"Creating contact: " + name); /* * Applies the array of ContentProviderOperation objects in batch. The results are * discarded. */ try { getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops); } catch (Exception e) { // Display a warning Context ctx = getApplicationContext(); CharSequence txt = getString(R.string.contactCreationFailure); int duration = Toast.LENGTH_SHORT; Toast toast = Toast.makeText(ctx, txt, duration); toast.show(); // Log exception Log.e(TAG, "Exception encountered while inserting contact: " + e); } }
बैच ऑपरेशन की मदद से, ऑप्टिमिस्टिक कंकरेंसी कंट्रोल लागू किया जा सकता है. यह बदलाव वाले लेन-देन को लागू करने का एक तरीका है. इसके लिए, आपको मूल रिपॉज़िटरी को लॉक करने की ज़रूरत नहीं होती. इस तरीके का इस्तेमाल करने के लिए, लेन-देन लागू करें. इसके बाद, उसी समय किए गए अन्य बदलावों की जांच करें. अगर आपको लगता है कि बदलाव सही तरीके से नहीं हुआ है, तो लेन-देन को पहले जैसा करें और फिर से कोशिश करें.
ऑप्टिमिस्टिक कंकरेंसी कंट्रोल, मोबाइल डिवाइस के लिए फ़ायदेमंद होता है. ऐसा इसलिए, क्योंकि मोबाइल डिवाइस पर एक समय में सिर्फ़ एक उपयोगकर्ता होता है. साथ ही, डेटा रिपॉज़िटरी को एक साथ ऐक्सेस करने की घटनाएं कम होती हैं. लॉक करने की सुविधा का इस्तेमाल नहीं किया जाता. इसलिए, लॉक सेट करने या अन्य लेन-देन के लॉक रिलीज़ होने का इंतज़ार करने में समय बर्बाद नहीं होता.
किसी एक ContactsContract.RawContacts
लाइन को अपडेट करते समय, ऑप्टिमिस्टिक कंकरेंसी कंट्रोल का इस्तेमाल करने के लिए, यह तरीका अपनाएं:
-
संपर्क की जानकारी के साथ-साथ,
VERSION
कॉलम में मौजूद डेटा भी वापस पाएं. -
ContentProviderOperation.Builder
ऑब्जेक्ट बनाएं, जोnewAssertQuery(Uri)
तरीके का इस्तेमाल करके, किसी शर्त को लागू करने के लिए सही हो. कॉन्टेंट यूआरआई के लिए,RawContacts.CONTENT_URI
का इस्तेमाल करें. इसमें रॉ कॉन्टैक्ट का_ID
जोड़ा गया हो. -
ContentProviderOperation.Builder
ऑब्जेक्ट के लिए, कॉलwithValue()
करें, ताकिVERSION
कॉलम की तुलना अभी-अभी पाए गए वर्शन नंबर से की जा सके. -
उसी
ContentProviderOperation.Builder
के लिए,withExpectedCount()
पर कॉल करें. इससे यह पक्का किया जा सकेगा कि इस दावे से सिर्फ़ एक लाइन की जांच की गई है. -
ContentProviderOperation
ऑब्जेक्ट बनाने के लिए,build()
को कॉल करें. इसके बाद, इस ऑब्जेक्ट कोArrayList
में पहले ऑब्जेक्ट के तौर पर जोड़ें. इसArrayList
कोapplyBatch()
को पास करें. - बैच लेन-देन लागू करें.
अगर आपने किसी रॉ संपर्क की लाइन को पढ़ा है और उसके बाद किसी अन्य ऑपरेशन से उसे अपडेट किया गया है, तो "assert" ContentProviderOperation
काम नहीं करेगा. साथ ही, ऑपरेशन का पूरा बैच वापस ले लिया जाएगा. इसके बाद, आपके पास बैच को फिर से प्रोसेस करने या कोई अन्य कार्रवाई करने का विकल्प होता है.
यहाँ दिए गए स्निपेट में, CursorLoader
का इस्तेमाल करके किसी एक रॉ संपर्क के लिए क्वेरी करने के बाद, "assert"
ContentProviderOperation
बनाने का तरीका बताया गया है:
Kotlin
/* * The application uses CursorLoader to query the raw contacts table. The system calls this method * when the load is finished. */ override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor) { // Gets the raw contact's _ID and VERSION values rawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID)) mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.VERSION)) } ... // Sets up a Uri for the assert operation val rawContactUri: Uri = ContentUris.withAppendedId( ContactsContract.RawContacts.CONTENT_URI, rawContactID ) // Creates a builder for the assert operation val assertOp: ContentProviderOperation.Builder = ContentProviderOperation.newAssertQuery(rawContactUri).apply { // Adds the assertions to the assert operation: checks the version withValue(SyncColumns.VERSION, mVersion) // and count of rows tested withExpectedCount(1) } // Creates an ArrayList to hold the ContentProviderOperation objects val ops = arrayListOf<ContentProviderOperation>() ops.add(assertOp.build()) // You would add the rest of your batch operations to "ops" here ... // Applies the batch. If the assert fails, an Exception is thrown try { val results: Array<ContentProviderResult> = contentResolver.applyBatch(AUTHORITY, ops) } catch (e: OperationApplicationException) { // Actions you want to take if the assert operation fails go here }
Java
/* * The application uses CursorLoader to query the raw contacts table. The system calls this method * when the load is finished. */ public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { // Gets the raw contact's _ID and VERSION values rawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID)); mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.VERSION)); } ... // Sets up a Uri for the assert operation Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactID); // Creates a builder for the assert operation ContentProviderOperation.Builder assertOp = ContentProviderOperation.newAssertQuery(rawContactUri); // Adds the assertions to the assert operation: checks the version and count of rows tested assertOp.withValue(SyncColumns.VERSION, mVersion); assertOp.withExpectedCount(1); // Creates an ArrayList to hold the ContentProviderOperation objects ArrayList ops = new ArrayList<ContentProviderOperation>; ops.add(assertOp.build()); // You would add the rest of your batch operations to "ops" here ... // Applies the batch. If the assert fails, an Exception is thrown try { ContentProviderResult[] results = getContentResolver().applyBatch(AUTHORITY, ops); } catch (OperationApplicationException e) { // Actions you want to take if the assert operation fails go here }
इंटेंट के साथ डेटा वापस पाना और उसमें बदलाव करना
डिवाइस के Contacts ऐप्लिकेशन को इंटेंट भेजने से, Contacts Provider को परोक्ष रूप से ऐक्सेस किया जा सकता है. इस इंटेंट से, डिवाइस के Contacts ऐप्लिकेशन का यूज़र इंटरफ़ेस (यूआई) खुल जाता है. इसमें लोग, संपर्क से जुड़े काम कर सकते हैं. इस तरह के ऐक्सेस से, उपयोगकर्ता ये काम कर सकते हैं:
- किसी सूची से कोई संपर्क चुनें और उसे अपने ऐप्लिकेशन पर वापस भेजें, ताकि उस पर आगे काम किया जा सके.
- किसी मौजूदा संपर्क के डेटा में बदलाव करें.
- उनके किसी भी खाते के लिए, नया रॉ संपर्क डालें.
- किसी संपर्क या संपर्कों का डेटा मिटाना.
अगर उपयोगकर्ता डेटा डाल रहा है या अपडेट कर रहा है, तो पहले डेटा इकट्ठा करें और उसे इंटेंट के हिस्से के तौर पर भेजें.
डिवाइस के Contacts ऐप्लिकेशन के ज़रिए Contacts Provider को ऐक्सेस करने के लिए इंटेंट का इस्तेमाल करने पर, आपको प्रोवाइडर को ऐक्सेस करने के लिए अपना यूज़र इंटरफ़ेस (यूआई) या कोड लिखने की ज़रूरत नहीं होती. आपको सेवा देने वाली कंपनी से, डेटा को पढ़ने या उसमें बदलाव करने की अनुमति का अनुरोध भी नहीं करना पड़ता. डिवाइस का Contacts ऐप्लिकेशन, आपको किसी संपर्क को ऐक्सेस करने की अनुमति दे सकता है. साथ ही, किसी दूसरे ऐप्लिकेशन के ज़रिए, डेटा उपलब्ध कराने वाली कंपनी के डेटा में बदलाव करने पर, आपके पास बदलाव करने की अनुमतियां नहीं होनी चाहिए.
किसी प्रोवाइडर को ऐक्सेस करने का अनुरोध भेजने की सामान्य प्रोसेस के बारे में ज़्यादा जानकारी,
Content Provider की बुनियादी बातें गाइड में दी गई है. यह जानकारी "इंटेंट के ज़रिए डेटा ऐक्सेस करना" सेक्शन में दी गई है. उपलब्ध टास्क के लिए इस्तेमाल की जाने वाली कार्रवाई, एमआईएमई टाइप, और डेटा वैल्यू की खास जानकारी टेबल 4 में दी गई है. वहीं, putExtra()
के साथ इस्तेमाल की जा सकने वाली अतिरिक्त वैल्यू की जानकारी, ContactsContract.Intents.Insert
के रेफ़रंस दस्तावेज़ में दी गई है:
चौथी टेबल. संपर्क सूची ऐक्सेस करने से जुड़े इंटेंट.
टास्क | कार्रवाई | डेटा | MIME प्रकार | नोट |
---|---|---|---|---|
सूची से कोई संपर्क चुनना | ACTION_PICK |
इनमें से कोई एक:
|
उपयोग नहीं किया गया |
आपके दिए गए कॉन्टेंट यूआरआई टाइप के आधार पर, यह रॉ कॉन्टैक्ट की सूची या रॉ कॉन्टैक्ट से मिले डेटा की सूची दिखाता है.
कॉल
|
नया रॉ संपर्क डालना | Insert.ACTION |
लागू नहीं |
RawContacts.CONTENT_TYPE , रॉ संपर्क के सेट के लिए एमआईएमई टाइप.
|
इससे डिवाइस के संपर्क ऐप्लिकेशन की संपर्क जोड़ें स्क्रीन दिखती है. आपने इंटेंट में जो अतिरिक्त वैल्यू जोड़ी हैं वे दिखती हैं. अगर इसे startActivityForResult() के साथ भेजा जाता है, तो नए जोड़े गए रॉ संपर्क का कॉन्टेंट यूआरआई, आपकी गतिविधि के onActivityResult() कॉलबैक तरीके में Intent आर्ग्युमेंट में "data" फ़ील्ड में वापस भेज दिया जाता है. वैल्यू पाने के लिए, getData() को कॉल करें.
|
संपर्क में बदलाव करना | ACTION_EDIT |
संपर्क के लिए CONTENT_LOOKUP_URI . एडिटर की गतिविधि से, उपयोगकर्ता इस संपर्क से जुड़े किसी भी डेटा में बदलाव कर पाएगा.
|
Contacts.CONTENT_ITEM_TYPE , एक संपर्क. |
इससे संपर्क ऐप्लिकेशन में, संपर्क में बदलाव करने की स्क्रीन दिखती है. आपने इंटेंट में जो अतिरिक्त वैल्यू जोड़ी हैं वे दिखती हैं. जब उपयोगकर्ता, बदलावों को सेव करने के लिए हो गया पर क्लिक करता है, तब आपकी गतिविधि फ़ोरग्राउंड में वापस आ जाती है. |
ऐसा पिकर दिखाएं जो डेटा भी जोड़ सके. | ACTION_INSERT_OR_EDIT |
लागू नहीं |
CONTENT_ITEM_TYPE
|
इस इंटेंट से, संपर्क ऐप्लिकेशन की पिकर स्क्रीन हमेशा दिखती है. उपयोगकर्ता के पास, किसी संपर्क में बदलाव करने या नया संपर्क जोड़ने का विकल्प होता है. उपयोगकर्ता के चुने गए विकल्प के आधार पर, बदलाव करने या जोड़ने वाली स्क्रीन दिखती है. साथ ही, इंटेंट में पास किया गया अतिरिक्त डेटा दिखता है. अगर आपका ऐप्लिकेशन, ईमेल या फ़ोन नंबर जैसे संपर्क डेटा को दिखाता है, तो इस इंटेंट का इस्तेमाल करें. इससे उपयोगकर्ता, मौजूदा संपर्क में डेटा जोड़ पाएगा.
संपर्क करें,
ध्यान दें: इस इंटेंट के अतिरिक्त पैरामीटर में, नाम की वैल्यू भेजने की ज़रूरत नहीं है, क्योंकि उपयोगकर्ता हमेशा कोई मौजूदा नाम चुनता है या नया नाम जोड़ता है. इसके अलावा, अगर आपने कोई नाम भेजा है और उपयोगकर्ता उसमें बदलाव करता है, तो Contacts ऐप्लिकेशन आपके भेजे गए नाम को दिखाएगा. इससे पहले से मौजूद नाम हट जाएगा. अगर उपयोगकर्ता को इस बारे में पता नहीं चलता और वह बदलाव को सेव कर देता है, तो पुरानी वैल्यू मिट जाती है. |
डिवाइस का Contacts ऐप्लिकेशन, आपको किसी रॉ संपर्क या उसके किसी भी डेटा को मिटाने की अनुमति नहीं देता. इसके बजाय, रॉ संपर्क को मिटाने के लिए, ContentResolver.delete()
या ContentProviderOperation.newDelete()
का इस्तेमाल करें.
यहां दिए गए स्निपेट में, नया रॉ संपर्क और डेटा डालने वाले इंटेंट को बनाने और भेजने का तरीका दिखाया गया है:
Kotlin
// Gets values from the UI val name = contactNameEditText.text.toString() val phone = contactPhoneEditText.text.toString() val email = contactEmailEditText.text.toString() val company = companyName.text.toString() val jobtitle = jobTitle.text.toString() /* * Demonstrates adding data rows as an array list associated with the DATA key */ // Defines an array list to contain the ContentValues objects for each row val contactData = arrayListOf<ContentValues>() /* * Defines the raw contact row */ // Sets up the row as a ContentValues object val rawContactRow = ContentValues().apply { // Adds the account type and name to the row put(ContactsContract.RawContacts.ACCOUNT_TYPE, selectedAccount.type) put(ContactsContract.RawContacts.ACCOUNT_NAME, selectedAccount.name) } // Adds the row to the array contactData.add(rawContactRow) /* * Sets up the phone number data row */ // Sets up the row as a ContentValues object val phoneRow = ContentValues().apply { // Specifies the MIME type for this data row (all data rows must be marked by their type) put(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) // Adds the phone number and its type to the row put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone) } // Adds the row to the array contactData.add(phoneRow) /* * Sets up the email data row */ // Sets up the row as a ContentValues object val emailRow = ContentValues().apply { // Specifies the MIME type for this data row (all data rows must be marked by their type) put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) // Adds the email address and its type to the row put(ContactsContract.CommonDataKinds.Email.ADDRESS, email) } // Adds the row to the array contactData.add(emailRow) // Creates a new intent for sending to the device's contacts application val insertIntent = Intent(ContactsContract.Intents.Insert.ACTION).apply { // Sets the MIME type to the one expected by the insertion activity type = ContactsContract.RawContacts.CONTENT_TYPE // Sets the new contact name putExtra(ContactsContract.Intents.Insert.NAME, name) // Sets the new company and job title putExtra(ContactsContract.Intents.Insert.COMPANY, company) putExtra(ContactsContract.Intents.Insert.JOB_TITLE, jobtitle) /* * Adds the array to the intent's extras. It must be a parcelable object in order to * travel between processes. The device's contacts app expects its key to be * Intents.Insert.DATA */ putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData) } // Send out the intent to start the device's contacts app in its add contact activity. startActivity(insertIntent)
Java
// Gets values from the UI String name = contactNameEditText.getText().toString(); String phone = contactPhoneEditText.getText().toString(); String email = contactEmailEditText.getText().toString(); String company = companyName.getText().toString(); String jobtitle = jobTitle.getText().toString(); // Creates a new intent for sending to the device's contacts application Intent insertIntent = new Intent(ContactsContract.Intents.Insert.ACTION); // Sets the MIME type to the one expected by the insertion activity insertIntent.setType(ContactsContract.RawContacts.CONTENT_TYPE); // Sets the new contact name insertIntent.putExtra(ContactsContract.Intents.Insert.NAME, name); // Sets the new company and job title insertIntent.putExtra(ContactsContract.Intents.Insert.COMPANY, company); insertIntent.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, jobtitle); /* * Demonstrates adding data rows as an array list associated with the DATA key */ // Defines an array list to contain the ContentValues objects for each row ArrayList<ContentValues> contactData = new ArrayList<ContentValues>(); /* * Defines the raw contact row */ // Sets up the row as a ContentValues object ContentValues rawContactRow = new ContentValues(); // Adds the account type and name to the row rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_TYPE, selectedAccount.getType()); rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_NAME, selectedAccount.getName()); // Adds the row to the array contactData.add(rawContactRow); /* * Sets up the phone number data row */ // Sets up the row as a ContentValues object ContentValues phoneRow = new ContentValues(); // Specifies the MIME type for this data row (all data rows must be marked by their type) phoneRow.put( ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE ); // Adds the phone number and its type to the row phoneRow.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone); // Adds the row to the array contactData.add(phoneRow); /* * Sets up the email data row */ // Sets up the row as a ContentValues object ContentValues emailRow = new ContentValues(); // Specifies the MIME type for this data row (all data rows must be marked by their type) emailRow.put( ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE ); // Adds the email address and its type to the row emailRow.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email); // Adds the row to the array contactData.add(emailRow); /* * Adds the array to the intent's extras. It must be a parcelable object in order to * travel between processes. The device's contacts app expects its key to be * Intents.Insert.DATA */ insertIntent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData); // Send out the intent to start the device's contacts app in its add contact activity. startActivity(insertIntent);
डेटा का रखरखाव
संपर्क जानकारी के डेटाबेस में अहम और संवेदनशील डेटा होता है. उपयोगकर्ता चाहते हैं कि यह डेटा सही और अप-टू-डेट हो. इसलिए, Contacts Provider के पास डेटा की सुरक्षा के लिए अच्छी तरह से तय किए गए नियम हैं. संपर्कों के डेटा में बदलाव करते समय, इन नियमों का पालन करना आपकी ज़िम्मेदारी है. यहाँ कुछ ज़रूरी नियम दिए गए हैं:
-
जोड़ी गई हर
ContactsContract.RawContacts
लाइन के लिए, हमेशा एकContactsContract.CommonDataKinds.StructuredName
लाइन जोड़ें. -
ContactsContract.Data
टेबल मेंContactsContract.CommonDataKinds.StructuredName
लाइन के बिनाContactsContract.RawContacts
लाइन होने पर, एग्रीगेशन के दौरान समस्याएं आ सकती हैं. -
हमेशा नई
ContactsContract.Data
लाइनों को उनकी पैरंटContactsContract.RawContacts
लाइन से लिंक करें. -
ContactsContract.Data
पंक्ति कोContactsContract.RawContacts
से लिंक नहीं किया गया है. इसलिए, यह डिवाइस के संपर्क ऐप्लिकेशन में नहीं दिखेगी. साथ ही, इससे सिंक अडैप्टर में समस्याएं आ सकती हैं. - सिर्फ़ उन रॉ कॉन्टैक्ट का डेटा बदलें जिनका मालिकाना हक आपके पास है.
- ध्यान रखें कि संपर्क की जानकारी देने वाली कंपनी, आम तौर पर कई तरह के खातों/ऑनलाइन सेवाओं से डेटा मैनेज करती है. आपको यह पक्का करना होगा कि आपका ऐप्लिकेशन, सिर्फ़ उन लाइनों के डेटा में बदलाव करे या उन्हें मिटाए जो आपकी हैं. साथ ही, वह सिर्फ़ ऐसे खाते के टाइप और नाम का डेटा डाले जिसे आपने कंट्रोल किया है.
-
अधिकारों, कॉन्टेंट यूआरआई, यूआरआई पाथ, कॉलम के नाम, MIME टाइप, और
ContactsContract
वैल्यू के लिए,ContactsContract
और इसकी सबक्लास में तय किए गए कॉन्स्टेंट का हमेशा इस्तेमाल करें.TYPE
- इन कॉन्स्टेंट का इस्तेमाल करने से, गड़बड़ियों से बचा जा सकता है. अगर कोई कॉन्स्टेंट बंद कर दिया गया है, तो आपको कंपाइलर की चेतावनियों के साथ इसकी सूचना भी दी जाएगी.
कस्टम डेटा लाइनें
अपनी पसंद के मुताबिक बनाए गए MIME टाइप बनाकर और उनका इस्तेमाल करके, ContactsContract.Data
टेबल में अपनी डेटा लाइनें डाली जा सकती हैं. साथ ही, उनमें बदलाव किया जा सकता है, उन्हें मिटाया जा सकता है, और वापस लाया जा सकता है. आपकी लाइनों में, ContactsContract.DataColumns
में तय किए गए कॉलम का इस्तेमाल किया जा सकता है. हालांकि, आपके पास टाइप के हिसाब से कॉलम के नामों को डिफ़ॉल्ट कॉलम के नामों से मैप करने का विकल्प होता है. डिवाइस के Contacts ऐप्लिकेशन में,
आपकी लाइनों का डेटा दिखता है. हालांकि, इसमें बदलाव नहीं किया जा सकता और इसे मिटाया भी नहीं जा सकता. साथ ही, उपयोगकर्ता इसमें
ज़्यादा डेटा नहीं जोड़ सकते. अगर आपको उपयोगकर्ताओं को कस्टम डेटा की पंक्तियों में बदलाव करने की अनुमति देनी है, तो आपको अपने ऐप्लिकेशन में एडिटर गतिविधि की सुविधा देनी होगी.
अपने कस्टम डेटा को दिखाने के लिए, contacts.xml
फ़ाइल उपलब्ध कराएं. इसमें <ContactsAccountType>
एलिमेंट और उसके एक या उससे ज़्यादा <ContactsDataKind>
चाइल्ड एलिमेंट शामिल होने चाहिए. इस बारे में ज़्यादा जानकारी, <ContactsDataKind> element
सेक्शन में दी गई है.
कस्टम MIME टाइप के बारे में ज़्यादा जानने के लिए, Content Provider बनाना गाइड पढ़ें.
संपर्क सूची के सिंक अडैप्टर
संपर्क की जानकारी देने वाले ऐप्लिकेशन को खास तौर पर, किसी डिवाइस और ऑनलाइन सेवा के बीच संपर्कों के डेटा को सिंक करने के लिए डिज़ाइन किया गया है. इससे उपयोगकर्ता, मौजूदा डेटा को किसी नए डिवाइस पर डाउनलोड कर सकते हैं. साथ ही, मौजूदा डेटा को किसी नए खाते में अपलोड कर सकते हैं. सिंक करने की सुविधा यह भी पक्का करती है कि उपयोगकर्ताओं के पास सबसे नया डेटा हो. भले ही, डेटा में बदलाव किसी भी सोर्स से किया गया हो. सिंक करने का एक और फ़ायदा यह है कि इससे डिवाइस के नेटवर्क से कनेक्ट न होने पर भी, संपर्कों का डेटा उपलब्ध रहता है.
सिंक करने की सुविधा को कई तरीकों से लागू किया जा सकता है. हालांकि, Android सिस्टम एक प्लग-इन सिंक्रनाइज़ेशन फ़्रेमवर्क उपलब्ध कराता है. यह फ़्रेमवर्क इन कामों को अपने-आप करता है:
- नेटवर्क की उपलब्धता की जांच की जा रही है.
- उपयोगकर्ता की प्राथमिकताओं के आधार पर, सिंक करने की प्रोसेस को शेड्यूल और पूरा करना.
- सिंक करने की उन प्रोसेस को फिर से शुरू करना जो रुक गई हैं.
इस फ़्रेमवर्क का इस्तेमाल करने के लिए, आपको सिंक अडैप्टर प्लग-इन देना होगा. हर सिंक अडैप्टर, सेवा और कॉन्टेंट देने वाली कंपनी के लिए यूनीक होता है. हालांकि, यह एक ही सेवा के लिए कई खातों के नाम मैनेज कर सकता है. इस फ़्रेमवर्क में, एक ही सेवा और प्रोवाइडर के लिए कई सिंक अडैप्टर इस्तेमाल किए जा सकते हैं.
सिंक अडैप्टर क्लास और फ़ाइलें
सिंक अडैप्टर को AbstractThreadedSyncAdapter
की सबक्लास के तौर पर लागू किया जाता है. साथ ही, इसे Android ऐप्लिकेशन के हिस्से के तौर पर इंस्टॉल किया जाता है. सिस्टम, सिंक अडैप्टर के बारे में आपके ऐप्लिकेशन मेनिफ़ेस्ट में मौजूद एलिमेंट से जानकारी इकट्ठा करता है. साथ ही, मेनिफ़ेस्ट में मौजूद खास एक्सएमएल फ़ाइल से भी जानकारी इकट्ठा करता है. एक्सएमएल फ़ाइल, ऑनलाइन सेवा के लिए खाते का टाइप और कॉन्टेंट उपलब्ध कराने वाली कंपनी के अधिकार तय करती है. ये दोनों मिलकर, अडैप्टर की यूनीक पहचान करते हैं. सिंक अडैप्टर तब तक चालू नहीं होता, जब तक उपयोगकर्ता सिंक अडैप्टर के खाता टाइप के लिए कोई खाता नहीं जोड़ता. साथ ही, जब तक वह उस कॉन्टेंट प्रोवाइडर के लिए सिंक्रनाइज़ेशन चालू नहीं करता जिसके साथ सिंक अडैप्टर सिंक करता है. इसके बाद, सिस्टम अडैप्टर को मैनेज करना शुरू कर देता है. साथ ही, कॉन्टेंट उपलब्ध कराने वाली कंपनी और सर्वर के बीच डेटा को सिंक करने के लिए, ज़रूरत के हिसाब से अडैप्टर को कॉल करता है.
ध्यान दें: सिंक अडैप्टर की पहचान के लिए खाते के टाइप का इस्तेमाल करने से, सिस्टम को एक ही संगठन की अलग-अलग सेवाओं को ऐक्सेस करने वाले सिंक अडैप्टर का पता लगाने और उन्हें एक साथ ग्रुप करने की अनुमति मिलती है. उदाहरण के लिए, Google की ऑनलाइन सेवाओं के लिए सिंक अडैप्टर में एक ही तरह का खाता com.google
होता है. जब उपयोगकर्ता अपने डिवाइसों में कोई Google खाता जोड़ते हैं, तो Google की सेवाओं के लिए इंस्टॉल किए गए सभी सिंक अडैप्टर एक साथ दिखते हैं. सूची में शामिल हर सिंक अडैप्टर, डिवाइस पर मौजूद किसी दूसरे कॉन्टेंट प्रोवाइडर के साथ सिंक होता है.
ज़्यादातर सेवाओं के लिए, उपयोगकर्ताओं को डेटा ऐक्सेस करने से पहले अपनी पहचान की पुष्टि करनी होती है. इसलिए, Android सिस्टम एक ऐसा पुष्टि करने वाला फ़्रेमवर्क उपलब्ध कराता है जो सिंक अडैप्टर फ़्रेमवर्क जैसा ही होता है. साथ ही, इसका इस्तेमाल अक्सर सिंक अडैप्टर फ़्रेमवर्क के साथ किया जाता है. पुष्टि करने वाला फ़्रेमवर्क, प्लग-इन ऑथेंटिकेटर का इस्तेमाल करता है. ये AbstractAccountAuthenticator
की सबक्लास होती हैं. पुष्टि करने वाला ऐप्लिकेशन, इन चरणों में उपयोगकर्ता की पहचान की पुष्टि करता है:
- यह कुकी, उपयोगकर्ता का नाम, पासवर्ड या इसी तरह की जानकारी (उपयोगकर्ता के क्रेडेंशियल) इकट्ठा करती है.
- यह कुकी, सेवा को क्रेडेंशियल भेजती है
- यह कुकी, सेवा के जवाब की जांच करती है.
अगर सेवा क्रेडेंशियल स्वीकार करती है, तो पुष्टि करने वाला ऐप्लिकेशन, क्रेडेंशियल को बाद में इस्तेमाल करने के लिए सेव कर सकता है. प्लग-इन ऑथेंटिकेटर फ़्रेमवर्क की वजह से, AccountManager
किसी भी ऐसे ऑथटोकन का ऐक्सेस दे सकता है जिसे ऑथेंटिकेटर इस्तेमाल करता है और जिसे वह सार्वजनिक तौर पर उपलब्ध कराता है. जैसे, OAuth2 ऑथटोकन.
पुष्टि करना ज़रूरी नहीं है, लेकिन ज़्यादातर संपर्क सेवाएं इसका इस्तेमाल करती हैं. हालांकि, पुष्टि करने के लिए Android authentication framework का इस्तेमाल करना ज़रूरी नहीं है.
सिंक अडैप्टर लागू करना
Contacts Provider के लिए सिंक अडैप्टर लागू करने के लिए, आपको एक Android ऐप्लिकेशन बनाना होगा. इसमें ये चीज़ें शामिल होनी चाहिए:
-
यह
Service
कॉम्पोनेंट, सिस्टम से मिले उन अनुरोधों का जवाब देता है जिनमें सिंक अडैप्टर से बाइंड करने के लिए कहा गया हो. -
जब सिस्टम को सिंक करने की प्रोसेस शुरू करनी होती है, तब वह सेवा के
onBind()
तरीके को कॉल करता है, ताकि सिंक अडैप्टर के लिएIBinder
मिल सके. इससे सिस्टम, अडैप्टर के तरीकों को क्रॉस-प्रोसेस कॉल कर सकता है. -
असल सिंक अडैप्टर, जिसे
AbstractThreadedSyncAdapter
के कॉन्क्रीट सबक्लास के तौर पर लागू किया जाता है. -
यह क्लास, सर्वर से डेटा डाउनलोड करने, डिवाइस से डेटा अपलोड करने, और टकरावों को हल करने का काम करती है. अडैप्टर का मुख्य काम,
onPerformSync()
तरीके से किया जाता है. इस क्लास को सिंगलटन के तौर पर इंस्टैंटिएट किया जाना चाहिए. -
यह
Application
की सबक्लास है. -
यह क्लास, सिंक अडैप्टर सिंग्लेटन के लिए फ़ैक्ट्री के तौर पर काम करती है. सिंक अडैप्टर को इंस्टैंशिएट करने के लिए,
onCreate()
तरीके का इस्तेमाल करें. साथ ही, सिंक अडैप्टर की सेवा केonBind()
तरीके को सिंगलटन वापस करने के लिए, स्टैटिक "getter" तरीका उपलब्ध कराएं. -
ज़रूरी नहीं: यह एक
Service
कॉम्पोनेंट है, जो उपयोगकर्ता की पुष्टि करने के लिए सिस्टम से मिले अनुरोधों का जवाब देता है. -
AccountManager
इस सेवा को शुरू करता है, ताकि पुष्टि करने की प्रक्रिया शुरू की जा सके. सेवा काonCreate()
तरीका, पुष्टि करने वाले ऑब्जेक्ट को इंस्टैंटिएट करता है. जब सिस्टम को ऐप्लिकेशन के सिंक अडैप्टर के लिए किसी उपयोगकर्ता खाते की पुष्टि करनी होती है, तो वह सेवा केonBind()
तरीके को कॉल करता है, ताकि पुष्टि करने वाले व्यक्ति के लिएIBinder
मिल सके. इससे सिस्टम, पुष्टि करने वाले व्यक्ति के तरीकों के लिए क्रॉस-प्रोसेस कॉल कर पाता है.. -
ज़रूरी नहीं: यह
AbstractAccountAuthenticator
का एक कॉंक्रीट सबक्लास है. यह पुष्टि करने के अनुरोधों को हैंडल करता है. -
यह क्लास ऐसे तरीके उपलब्ध कराती है जिन्हें
AccountManager
, सर्वर के साथ उपयोगकर्ता के क्रेडेंशियल की पुष्टि करने के लिए लागू करता है. पुष्टि करने की प्रक्रिया की जानकारी, इस्तेमाल की जा रही सर्वर टेक्नोलॉजी के हिसाब से अलग-अलग होती है. पुष्टि करने के बारे में ज़्यादा जानने के लिए, आपको अपने सर्वर सॉफ़्टवेयर के दस्तावेज़ देखने चाहिए. - एक्सएमएल फ़ाइलें, जो सिस्टम के लिए सिंक अडैप्टर और पुष्टि करने वाले टूल को तय करती हैं.
-
सिंक अडैप्टर और पुष्टि करने वाली सेवा के कॉम्पोनेंट, ऐप्लिकेशन मेनिफ़ेस्ट में
<service>
एलिमेंट में तय किए जाते हैं. इन एलिमेंट में<meta-data>
चाइल्ड एलिमेंट होते हैं, जो सिस्टम को खास डेटा देते हैं:-
सिंक अडैप्टर सेवा के लिए
<meta-data>
एलिमेंट,res/xml/syncadapter.xml
एक्सएमएल फ़ाइल की ओर इशारा करता है. बदले में, यह फ़ाइल वेब सेवा के लिए एक यूआरआई तय करती है, जिसे Contacts Provider के साथ सिंक किया जाएगा. साथ ही, यह वेब सेवा के लिए खाते का टाइप भी तय करती है. -
ज़रूरी नहीं: पुष्टि करने वाले व्यक्ति के लिए
<meta-data>
एलिमेंट, एक्सएमएल फ़ाइलres/xml/authenticator.xml
की ओर इशारा करता है. बदले में, यह फ़ाइल उस खाते के टाइप के बारे में बताती है जिस पर यह Authenticator काम करता है. साथ ही, यह उन यूज़र इंटरफ़ेस (यूआई) संसाधनों के बारे में भी बताती है जो पुष्टि करने की प्रोसेस के दौरान दिखते हैं. इस एलिमेंट में बताया गया खाता टाइप, सिंक अडैप्टर के लिए बताए गए खाता टाइप के जैसा होना चाहिए.
-
सिंक अडैप्टर सेवा के लिए
सोशल स्ट्रीम का डेटा
android.provider.ContactsContract.StreamItems और android.provider.ContactsContract.StreamItemPhotos टेबल, सोशल नेटवर्क से आने वाले डेटा को मैनेज करती हैं. सिंक अडैप्टर लिखा जा सकता है. यह अडैप्टर, आपके नेटवर्क से स्ट्रीम किए गए डेटा को इन टेबल में जोड़ता है. इसके अलावा, इन टेबल से स्ट्रीम किए गए डेटा को पढ़ा जा सकता है और उसे अपने ऐप्लिकेशन में दिखाया जा सकता है. इन दोनों कामों को एक साथ भी किया जा सकता है. इन सुविधाओं की मदद से, सोशल नेटवर्किंग की सेवाओं और ऐप्लिकेशन को Android के सोशल नेटवर्किंग अनुभव में इंटिग्रेट किया जा सकता है.
सोशल स्ट्रीम टेक्स्ट
स्ट्रीम आइटम हमेशा किसी रॉ संपर्क से जुड़े होते हैं. android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID, रॉ संपर्क के लिए _ID
वैल्यू से लिंक होता है. रॉ संपर्क के खाते का टाइप और खाते का नाम भी स्ट्रीम आइटम की लाइन में सेव किया जाता है.
अपनी स्ट्रीम का डेटा इन कॉलम में सेव करें:
- android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_TYPE
- ज़रूरी है. इस स्ट्रीम आइटम से जुड़े रॉ संपर्क के लिए, उपयोगकर्ता के खाते का टाइप. स्ट्रीम आइटम डालते समय, इस वैल्यू को सेट करना न भूलें.
- android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_NAME
- ज़रूरी है. इस स्ट्रीम आइटम से जुड़े रॉ संपर्क के लिए, उपयोगकर्ता के खाते का नाम. स्ट्रीम आइटम डालते समय, इस वैल्यू को सेट करना न भूलें.
- आइडेंटिफ़ायर कॉलम
-
ज़रूरी है. स्ट्रीम आइटम डालते समय, आपको आइडेंटिफ़ायर के ये कॉलम डालने होंगे:
- android.provider.ContactsContract.StreamItemsColumns#CONTACT_ID: यह उस संपर्क की android.provider.BaseColumns#_ID वैल्यू होती है जिससे यह स्ट्रीम आइटम जुड़ा है.
- android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY: यह उस संपर्क का android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY वैल्यू है जिससे यह स्ट्रीम आइटम जुड़ा है.
- android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID: यह उस रॉ कॉन्टैक्ट की android.provider.BaseColumns#_ID वैल्यू होती है जिससे यह स्ट्रीम आइटम जुड़ा होता है.
- android.provider.ContactsContract.StreamItemsColumns#COMMENTS
- ज़रूरी नहीं. यह कुकी, खास जानकारी को सेव करती है. इसे स्ट्रीम आइटम की शुरुआत में दिखाया जा सकता है.
- android.provider.ContactsContract.StreamItemsColumns#TEXT
-
स्ट्रीम आइटम का टेक्स्ट. इसमें आइटम के सोर्स से पोस्ट किया गया कॉन्टेंट या स्ट्रीम आइटम जनरेट करने वाली किसी कार्रवाई का ब्यौरा शामिल होता है. इस कॉलम में, किसी भी तरह की फ़ॉर्मैटिंग और एम्बेड की गई रिसॉर्स इमेज शामिल हो सकती हैं. इन्हें
fromHtml()
रेंडर कर सकता है. ऐसा हो सकता है कि सेवा देने वाली कंपनी, लंबे कॉन्टेंट को छोटा कर दे या उसमें कुछ शब्दों को हटाकर उनकी जगह पर तीन बिंदु लगा दे. हालांकि, वह टैग को तोड़ने से बचने की कोशिश करेगी. - android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP
- यह एक टेक्स्ट स्ट्रिंग है. इसमें स्ट्रीम आइटम को शामिल करने या अपडेट करने का समय होता है. यह समय, Epoch के बाद के मिलीसेकंड के तौर पर होता है. स्ट्रीम आइटम डालने या अपडेट करने वाले ऐप्लिकेशन, इस कॉलम को बनाए रखने के लिए ज़िम्मेदार होते हैं. इसे संपर्क की जानकारी देने वाली कंपनी अपने-आप बनाए नहीं रखती.
अपने स्ट्रीम आइटम की पहचान करने वाली जानकारी दिखाने के लिए, अपने ऐप्लिकेशन में मौजूद संसाधनों से लिंक करने के लिए, android.provider.ContactsContract.StreamItemsColumns#RES_ICON, android.provider.ContactsContract.StreamItemsColumns#RES_LABEL, और android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE का इस्तेमाल करें.
android.provider.ContactsContract.StreamItems टेबल में, sync adapter के लिए खास तौर पर इस्तेमाल किए जाने वाले ये कॉलम भी होते हैं: android.provider.ContactsContract.StreamItemsColumns#SYNC1 से लेकर android.provider.ContactsContract.StreamItemsColumns#SYNC4 तक.
सोशल स्ट्रीम की फ़ोटो
android.provider.ContactsContract.StreamItemPhotos टेबल में, स्ट्रीम आइटम से जुड़ी फ़ोटो सेव की जाती हैं. टेबल के android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID कॉलम में मौजूद वैल्यू, android.provider.ContactsContract.StreamItems टेबल के _ID
कॉलम में मौजूद वैल्यू से लिंक होती हैं. फ़ोटो के रेफ़रंस, टेबल में इन कॉलम में सेव किए जाते हैं:
- android.provider.ContactsContract.StreamItemPhotos#PHOTO कॉलम (एक BLOB).
- यह फ़ोटो का बाइनरी फ़ॉर्मैट है. इसे स्टोरेज और डिसप्ले के लिए, सेवा देने वाली कंपनी ने रीसाइज़ किया है. यह कॉलम, Contacts Provider के पिछले वर्शन के साथ काम करने की सुविधा के लिए उपलब्ध है. इसका इस्तेमाल फ़ोटो सेव करने के लिए किया जाता था. हालांकि, मौजूदा वर्शन में आपको फ़ोटो सेव करने के लिए इस कॉलम का इस्तेमाल नहीं करना चाहिए. इसके बजाय, फ़ाइल में फ़ोटो सेव करने के लिए, android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID या android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI का इस्तेमाल करें. इन दोनों के बारे में यहां बताया गया है. इस कॉलम में अब फ़ोटो का थंबनेल मौजूद है. इसे पढ़ा जा सकता है.
- android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID
-
यह किसी रॉ संपर्क के लिए फ़ोटो का संख्यात्मक आइडेंटिफ़ायर होता है. इस वैल्यू को कॉन्स्टेंट
DisplayPhoto.CONTENT_URI
में जोड़कर, एक फ़ोटो फ़ाइल की ओर ले जाने वाला कॉन्टेंट यूआरआई पाएं. इसके बाद,openAssetFileDescriptor()
को कॉल करके फ़ोटो फ़ाइल का हैंडल पाएं. - android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI
-
यह कॉन्टेंट यूआरआई, इस लाइन में मौजूद फ़ोटो की फ़ोटो फ़ाइल की ओर सीधे तौर पर ले जाता है.
फ़ोटो फ़ाइल का हैंडल पाने के लिए, इस यूआरआई के साथ
openAssetFileDescriptor()
पर कॉल करें.
सोशल स्ट्रीम टेबल का इस्तेमाल करना
ये टेबल, Contacts Provider की अन्य मुख्य टेबल की तरह ही काम करती हैं. हालांकि, इनमें ये अंतर होते हैं:
- इन टेबल को ऐक्सेस करने के लिए, अतिरिक्त अनुमतियों की ज़रूरत होती है. इनसे डेटा पढ़ने के लिए, आपके ऐप्लिकेशन के पास android.Manifest.permission#READ_SOCIAL_STREAM की अनुमति होनी चाहिए. इनमें बदलाव करने के लिए, आपके ऐप्लिकेशन के पास android.Manifest.permission#WRITE_SOCIAL_STREAM की अनुमति होनी चाहिए.
-
android.provider.ContactsContract.StreamItems टेबल के लिए, हर रॉ संपर्क के लिए सेव की गई लाइनों की संख्या सीमित होती है. यह सीमा पूरी होने के बाद, Contacts Provider नई स्ट्रीम आइटम लाइनों के लिए जगह बनाता है. इसके लिए, वह android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP वाली सबसे पुरानी लाइनों को अपने-आप मिटा देता है. सीमा पाने के लिए, कॉन्टेंट यूआरआई android.provider.ContactsContract.StreamItems#CONTENT_LIMIT_URI को क्वेरी जारी करें. कॉन्टेंट यूआरआई के अलावा, अन्य सभी आर्ग्युमेंट को
null
पर सेट किया जा सकता है. क्वेरी, कर्सर दिखाती है. इसमें एक लाइन होती है. साथ ही, इसमें android.provider.ContactsContract.StreamItems#MAX_ITEMS वाला एक कॉलम होता है.
android.provider.ContactsContract.StreamItems.StreamItemPhotos क्लास, android.provider.ContactsContract.StreamItemPhotos की सब-टेबल को तय करती है. इसमें एक स्ट्रीम आइटम के लिए फ़ोटो की लाइनें होती हैं.
सोशल स्ट्रीम के साथ इंटरैक्शन
संपर्क सेवा देने वाली कंपनी, सोशल स्ट्रीम के डेटा को मैनेज करती है. साथ ही, डिवाइस के संपर्कों के ऐप्लिकेशन के साथ मिलकर काम करती है. इससे, आपके सोशल नेटवर्किंग सिस्टम को मौजूदा संपर्कों से कनेक्ट करने का एक बेहतर तरीका मिलता है. ये सुविधाएं उपलब्ध हैं:
- सिंक अडैप्टर की मदद से, सोशल नेटवर्किंग सेवा को Contacts Provider के साथ सिंक करके, किसी उपयोगकर्ता के संपर्कों की हाल ही की गतिविधि को वापस पाया जा सकता है. साथ ही, इसे android.provider.ContactsContract.StreamItems और android.provider.ContactsContract.StreamItemPhotos टेबल में सेव किया जा सकता है, ताकि बाद में इसका इस्तेमाल किया जा सके.
- नियमित तौर पर सिंक करने के अलावा, सिंक अडैप्टर को ट्रिगर करके अतिरिक्त डेटा भी वापस पाया जा सकता है. ऐसा तब किया जा सकता है, जब उपयोगकर्ता किसी संपर्क को देखने के लिए चुनता है. इससे आपका सिंक अडैप्टर, संपर्क के लिए ज़्यादा रिज़ॉल्यूशन वाली फ़ोटो और स्ट्रीम के सबसे नए आइटम वापस पा सकता है.
- डिवाइस के Contacts ऐप्लिकेशन और Contacts Provider के साथ सूचना रजिस्टर करके, किसी संपर्क को देखे जाने पर इंटेंट पाया जा सकता है. इसके बाद, अपनी सेवा से संपर्क की स्थिति को अपडेट किया जा सकता है. यह तरीका, सिंक अडैप्टर के साथ पूरा सिंक करने की तुलना में ज़्यादा तेज़ हो सकता है. साथ ही, इसमें कम बैंडविड्थ का इस्तेमाल होता है.
- उपयोगकर्ता, डिवाइस के Contacts ऐप्लिकेशन में किसी संपर्क को देखते समय, उसे आपकी सोशल नेटवर्किंग सेवा में जोड़ सकते हैं. इसे "संपर्क को न्योता दें" सुविधा की मदद से चालू किया जाता है. इस सुविधा को चालू करने के लिए, आपको दो चीज़ों की ज़रूरत होती है. पहली, ऐसी गतिविधि जो आपके नेटवर्क में मौजूद किसी संपर्क को जोड़ती है. दूसरी, एक ऐसी XML फ़ाइल जो डिवाइस के Contacts ऐप्लिकेशन और Contacts Provider को आपके ऐप्लिकेशन की जानकारी देती है.
स्ट्रीम आइटम को Contacts Provider के साथ नियमित तौर पर सिंक करने की प्रोसेस, अन्य सिंक प्रोसेस की तरह ही होती है. सिंक्रनाइज़ेशन के बारे में ज़्यादा जानने के लिए, संपर्क की जानकारी देने वाले ऐप्लिकेशन के सिंक अडैप्टर सेक्शन देखें. सूचनाएं पाने के लिए रजिस्टर करने और संपर्कों को न्योता भेजने के बारे में जानकारी, अगले दो सेक्शन में दी गई है.
इस कुकी का इस्तेमाल, सोशल नेटवर्किंग व्यू को मैनेज करने के लिए रजिस्टर करने के लिए किया जाता है
जब उपयोगकर्ता ऐसे संपर्क को देखता है जिसे आपका सिंक अडैप्टर मैनेज करता है, तब सूचनाएं पाने के लिए अपने सिंक अडैप्टर को रजिस्टर करें:
-
अपने प्रोजेक्ट की
res/xml/
डायरेक्ट्री में,contacts.xml
नाम की फ़ाइल बनाएं. अगर आपके पास यह फ़ाइल पहले से मौजूद है, तो इस चरण को छोड़ा जा सकता है. -
इस फ़ाइल में,
<ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android">
एलिमेंट जोड़ें. अगर यह एलिमेंट पहले से मौजूद है, तो इस चरण को छोड़ा जा सकता है. -
अगर आपको ऐसी सेवा रजिस्टर करनी है जिसे तब सूचना मिलती है, जब उपयोगकर्ता डिवाइस के Contacts ऐप्लिकेशन में किसी संपर्क की ज़्यादा जानकारी वाला पेज खोलता है, तो एलिमेंट में
viewContactNotifyService="serviceclass"
एट्रिब्यूट जोड़ें. यहांserviceclass
, उस सेवा का पूरी तरह से क्वालिफ़ाइड क्लासनेम है जिसे डिवाइस के Contacts ऐप्लिकेशन से इंटेंट मिलना चाहिए. सूचना देने वाली सेवा के लिए,IntentService
को बढ़ाने वाली क्लास का इस्तेमाल करें, ताकि सेवा को इंटेंट मिल सकें. इनकमिंग इंटेंट में मौजूद डेटा में, उस रॉ संपर्क का कॉन्टेंट यूआरआई होता है जिस पर उपयोगकर्ता ने क्लिक किया था. सूचना देने वाली सेवा से, अपने सिंक अडैप्टर को बाइंड किया जा सकता है. इसके बाद, रॉ संपर्क के डेटा को अपडेट करने के लिए, उसे कॉल किया जा सकता है.
जब उपयोगकर्ता किसी स्ट्रीम आइटम या फ़ोटो या दोनों पर क्लिक करे, तब कॉल की जाने वाली गतिविधि को रजिस्टर करने के लिए:
-
अपने प्रोजेक्ट की
res/xml/
डायरेक्ट्री में,contacts.xml
नाम की फ़ाइल बनाएं. अगर आपके पास यह फ़ाइल पहले से मौजूद है, तो इस चरण को छोड़ा जा सकता है. -
इस फ़ाइल में,
<ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android">
एलिमेंट जोड़ें. अगर यह एलिमेंट पहले से मौजूद है, तो इस चरण को छोड़ा जा सकता है. -
अगर आपको डिवाइस के Contacts ऐप्लिकेशन में स्ट्रीम आइटम पर क्लिक करने वाले उपयोगकर्ता को हैंडल करने के लिए, अपनी किसी गतिविधि को रजिस्टर करना है, तो एलिमेंट में
viewStreamItemActivity="activityclass"
एट्रिब्यूट जोड़ें. यहांactivityclass
, उस गतिविधि का पूरी तरह से क्वालिफ़ाइड क्लासनेम है जिसे डिवाइस के Contacts ऐप्लिकेशन से इंटेंट मिलना चाहिए. -
अगर आपको डिवाइस के Contacts ऐप्लिकेशन में स्ट्रीम फ़ोटो पर क्लिक करने वाले उपयोगकर्ता को हैंडल करने के लिए, अपनी किसी गतिविधि को रजिस्टर करना है, तो एलिमेंट में
viewStreamItemPhotoActivity="activityclass"
एट्रिब्यूट जोड़ें. यहांactivityclass
, उस गतिविधि का पूरा क्लासनेम है जिसे डिवाइस के Contacts ऐप्लिकेशन से इंटेंट मिलना चाहिए.
<ContactsAccountType>
एलिमेंट के बारे में ज़्यादा जानकारी, <ContactsAccountType> एलिमेंट सेक्शन में दी गई है.
आने वाले इंटेंट में, उस आइटम या फ़ोटो का कॉन्टेंट यूआरआई होता है जिस पर उपयोगकर्ता ने क्लिक किया था. अगर आपको टेक्स्ट आइटम और फ़ोटो के लिए अलग-अलग गतिविधियां चाहिए, तो एक ही फ़ाइल में दोनों एट्रिब्यूट का इस्तेमाल करें.
सोशल नेटवर्किंग सेवा से इंटरैक्ट करना
उपयोगकर्ताओं को किसी संपर्क को आपकी सोशल नेटवर्किंग साइट पर न्योता देने के लिए, डिवाइस के संपर्क ऐप्लिकेशन को छोड़ने की ज़रूरत नहीं होती. इसके बजाय, डिवाइस के Contacts ऐप्लिकेशन से, किसी संपर्क को आपकी किसी गतिविधि में शामिल होने का न्योता भेजा जा सकता है. इसका सेट अप करने के लिए:
-
अपने प्रोजेक्ट की
res/xml/
डायरेक्ट्री में,contacts.xml
नाम की फ़ाइल बनाएं. अगर आपके पास यह फ़ाइल पहले से मौजूद है, तो इस चरण को छोड़ा जा सकता है. -
इस फ़ाइल में,
<ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android">
एलिमेंट जोड़ें. अगर यह एलिमेंट पहले से मौजूद है, तो इस चरण को छोड़ा जा सकता है. -
ये एट्रिब्यूट जोड़ें:
inviteContactActivity="activityclass"
-
inviteContactActionLabel="@string/invite_action_label"
activityclass
वैल्यू, उस गतिविधि का पूरी तरह क्वालिफ़ाइड क्लासनेम है जिसे इंटेंट मिलना चाहिए.invite_action_label
वैल्यू एक टेक्स्ट स्ट्रिंग होती है. यह डिवाइस के Contacts ऐप्लिकेशन में कनेक्शन जोड़ें मेन्यू में दिखती है.
ध्यान दें: ContactsSource
, ContactsAccountType
के लिए इस्तेमाल किया जाने वाला टैग का पुराना नाम है.
contacts.xml का रेफ़रंस
contacts.xml
फ़ाइल में ऐसे एक्सएमएल एलिमेंट होते हैं जो संपर्कों वाले ऐप्लिकेशन और Contacts Provider के साथ, आपके सिंक अडैप्टर और ऐप्लिकेशन के इंटरैक्शन को कंट्रोल करते हैं. इन
एलिमेंट के बारे में, यहां दिए गए सेक्शन में बताया गया है.
<ContactsAccountType> एलिमेंट
<ContactsAccountType>
एलिमेंट, आपके ऐप्लिकेशन के संपर्कों के साथ इंटरैक्शन को कंट्रोल करता है. इसका सिंटैक्स यह है:
<ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android" inviteContactActivity="activity_name" inviteContactActionLabel="invite_command_text" viewContactNotifyService="view_notify_service" viewGroupActivity="group_view_activity" viewGroupActionLabel="group_action_text" viewStreamItemActivity="viewstream_activity_name" viewStreamItemPhotoActivity="viewphotostream_activity_name">
इसमें शामिल है:
res/xml/contacts.xml
में यह जानकारी शामिल हो सकती है:
<ContactsDataKind>
जानकारी:
यह कुकी, Android कॉम्पोनेंट और यूज़र इंटरफ़ेस (यूआई) लेबल के बारे में जानकारी देती है. इनकी मदद से, उपयोगकर्ता अपने किसी संपर्क को सोशल नेटवर्क पर न्योता दे सकते हैं. साथ ही, जब उनकी किसी सोशल नेटवर्किंग स्ट्रीम को अपडेट किया जाता है, तब उन्हें सूचना मिलती है. इसके अलावा, और भी कई काम किए जा सकते हैं.
ध्यान दें कि <ContactsAccountType>
एट्रिब्यूट के लिए, android:
एट्रिब्यूट प्रीफ़िक्स का इस्तेमाल करना ज़रूरी नहीं है.
एट्रिब्यूट:
inviteContactActivity
- आपके ऐप्लिकेशन में मौजूद गतिविधि का पूरा क्लास नेम. जब उपयोगकर्ता डिवाइस के संपर्क ऐप्लिकेशन में जाकर कनेक्शन जोड़ें को चुनता है, तब आपको इस गतिविधि को चालू करना होता है.
inviteContactActionLabel
-
यह एक टेक्स्ट स्ट्रिंग है. इसे
inviteContactActivity
में बताई गई गतिविधि के लिए दिखाया जाता है. यह कनेक्शन जोड़ें मेन्यू में दिखता है. उदाहरण के लिए, "मेरे नेटवर्क में फ़ॉलो करें" स्ट्रिंग का इस्तेमाल किया जा सकता है. इस लेबल के लिए, स्ट्रिंग रिसॉर्स आइडेंटिफ़ायर का इस्तेमाल किया जा सकता है. viewContactNotifyService
- आपके ऐप्लिकेशन में मौजूद किसी ऐसी सेवा का पूरी तरह क्वालिफ़ाइड क्लास नेम जिसे उपयोगकर्ता के संपर्क देखने पर सूचनाएं मिलनी चाहिए. यह सूचना, डिवाइस के संपर्क ऐप्लिकेशन से भेजी जाती है. इससे आपका ऐप्लिकेशन, डेटा का ज़्यादा इस्तेमाल करने वाली कार्रवाइयों को तब तक के लिए रोक सकता है, जब तक उनकी ज़रूरत न हो. उदाहरण के लिए, आपका ऐप्लिकेशन इस सूचना का जवाब दे सकता है. इसके लिए, वह संपर्क की ज़्यादा रिज़ॉल्यूशन वाली फ़ोटो और सोशल मीडिया पर की गई उसकी हाल ही की पोस्ट को पढ़ सकता है और दिखा सकता है. इस सुविधा के बारे में ज़्यादा जानकारी, सोशल स्ट्रीम इंटरैक्शन सेक्शन में दी गई है.
viewGroupActivity
- आपके ऐप्लिकेशन में मौजूद किसी ऐसी गतिविधि की क्लास का पूरी तरह क्वालिफ़ाइड नाम जो ग्रुप की जानकारी दिखा सकती है. जब उपयोगकर्ता डिवाइस के Contacts ऐप्लिकेशन में ग्रुप के लेबल पर क्लिक करता है, तब इस गतिविधि के लिए यूज़र इंटरफ़ेस (यूआई) दिखता है.
viewGroupActionLabel
-
यह वह लेबल है जिसे Contacts ऐप्लिकेशन, यूज़र इंटरफ़ेस (यूआई) कंट्रोल के लिए दिखाता है. इससे उपयोगकर्ता को आपके ऐप्लिकेशन में ग्रुप देखने की अनुमति मिलती है.
इस एट्रिब्यूट के लिए, स्ट्रिंग रिसॉर्स आइडेंटिफ़ायर का इस्तेमाल किया जा सकता है.
viewStreamItemActivity
- आपके ऐप्लिकेशन में मौजूद किसी ऐसी ऐक्टिविटी का पूरा क्लास नेम जिसे डिवाइस का संपर्क ऐप्लिकेशन तब लॉन्च करता है, जब उपयोगकर्ता किसी रॉ संपर्क के लिए स्ट्रीम आइटम पर क्लिक करता है.
viewStreamItemPhotoActivity
- आपके ऐप्लिकेशन में मौजूद किसी गतिविधि का पूरा क्लास नेम. जब उपयोगकर्ता, रॉ संपर्क के लिए स्ट्रीम आइटम में मौजूद किसी फ़ोटो पर क्लिक करता है, तब डिवाइस का संपर्क ऐप्लिकेशन इस गतिविधि को लॉन्च करता है.
<ContactsDataKind> एलिमेंट
<ContactsDataKind>
एलिमेंट, संपर्क ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) में, आपके ऐप्लिकेशन की कस्टम डेटा लाइनें दिखाने की सुविधा को कंट्रोल करता है. इसका सिंटैक्स यह है:
<ContactsDataKind android:mimeType="MIMEtype" android:icon="icon_resources" android:summaryColumn="column_name" android:detailColumn="column_name">
इसमें शामिल है:
<ContactsAccountType>
जानकारी:
इस एलिमेंट का इस्तेमाल करके, संपर्क ऐप्लिकेशन को कस्टम डेटा लाइन का कॉन्टेंट दिखाने के लिए कहा जा सकता है. यह कॉन्टेंट, रॉ संपर्क की जानकारी के तौर पर दिखाया जाता है. <ContactsAccountType>
का हर <ContactsDataKind>
चाइल्ड एलिमेंट, कस्टम डेटा की एक लाइन को दिखाता है. सिंक अडैप्टर, इस लाइन को ContactsContract.Data
टेबल में जोड़ता है. इस्तेमाल किए जाने वाले हर कस्टम MIME टाइप के लिए, एक <ContactsDataKind>
एलिमेंट जोड़ें. अगर आपके पास कस्टम डेटा लाइन है और आपको उसके लिए डेटा नहीं दिखाना है, तो आपको एलिमेंट जोड़ने की ज़रूरत नहीं है.
एट्रिब्यूट:
android:mimeType
-
ContactsContract.Data
टेबल में, कस्टम डेटा की लाइन के किसी टाइप के लिए आपने कस्टम MIME टाइप तय किया है. उदाहरण के लिए, वैल्यूvnd.android.cursor.item/vnd.example.locationstatus
, डेटा की उस लाइन के लिए कस्टम MIME टाइप हो सकती है जो किसी संपर्क की आखिरी बार देखी गई जगह की जानकारी रिकॉर्ड करती है. android:icon
- यह एक Android ड्रॉएबल रिसॉर्स है. संपर्क ऐप्लिकेशन इसे आपके डेटा के बगल में दिखाता है. इसका इस्तेमाल करके, उपयोगकर्ता को यह बताया जाता है कि डेटा आपकी सेवा से मिला है.
android:summaryColumn
- डेटा लाइन से मिली दो वैल्यू में से पहली वैल्यू के लिए कॉलम का नाम. यह वैल्यू, इस डेटा लाइन की एंट्री की पहली लाइन के तौर पर दिखती है. पहली लाइन का इस्तेमाल, डेटा की खास जानकारी के तौर पर किया जाता है. हालांकि, ऐसा करना ज़रूरी नहीं है. यह भी देखें android:detailColumn.
android:detailColumn
-
यह डेटा लाइन से मिली दो वैल्यू में से दूसरी वैल्यू के कॉलम का नाम है. यह वैल्यू, इस डेटा लाइन की एंट्री की दूसरी लाइन के तौर पर दिखती है.
android:summaryColumn
भी देखें.
संपर्क सूची की सुविधा देने वाली अन्य कंपनियों की अतिरिक्त सुविधाएं
पिछले सेक्शन में बताई गई मुख्य सुविधाओं के अलावा, Contacts Provider, संपर्क डेटा के साथ काम करने के लिए ये काम की सुविधाएं देता है:
- संपर्क ग्रुप
- फ़ोटो को बेहतर बनाने के लिए सुविधाएं
संपर्क ग्रुप
संपर्क की जानकारी देने वाली कंपनी, एक जैसे संपर्कों के कलेक्शन को group डेटा के साथ लेबल कर सकती है. हालांकि, ऐसा करना ज़रूरी नहीं है. अगर किसी उपयोगकर्ता खाते से जुड़ा सर्वर ग्रुप बनाए रखना चाहता है, तो खाते के टाइप के लिए सिंक अडैप्टर को Contacts Provider और सर्वर के बीच ग्रुप का डेटा ट्रांसफ़र करना चाहिए. जब उपयोगकर्ता सर्वर में कोई नया संपर्क जोड़ते हैं और फिर इस संपर्क को किसी नए ग्रुप में डालते हैं, तो सिंक अडैप्टर को ContactsContract.Groups
टेबल में नया ग्रुप जोड़ना होगा. किसी रॉ संपर्क से जुड़े ग्रुप या ग्रुप की जानकारी, ContactsContract.Data
टेबल में सेव की जाती है. इसके लिए, ContactsContract.CommonDataKinds.GroupMembership
MIME टाइप का इस्तेमाल किया जाता है.
अगर आपको एक ऐसा सिंक अडैप्टर डिज़ाइन करना है जो सर्वर से Contacts Provider में संपर्क का रॉ डेटा जोड़ेगा और आपको ग्रुप का इस्तेमाल नहीं करना है, तो आपको Provider को यह बताना होगा कि आपका डेटा दिखे. जब कोई उपयोगकर्ता डिवाइस में खाता जोड़ता है, तब एक्ज़ीक्यूट होने वाले कोड में, ContactsContract.Settings
की उस लाइन को अपडेट करें जिसे Contacts Provider ने खाते के लिए जोड़ा है. इस लाइन में, Settings.UNGROUPED_VISIBLE
कॉलम की वैल्यू को 1 पर सेट करें. ऐसा करने पर, Contacts Provider हमेशा आपके संपर्कों का डेटा दिखाएगा. भले ही, आपने ग्रुप का इस्तेमाल न किया हो.
संपर्क की फ़ोटो
ContactsContract.Data
टेबल में फ़ोटो को पंक्तियों के तौर पर सेव किया जाता है. इनका MIME टाइप Photo.CONTENT_ITEM_TYPE
होता है. लाइन के CONTACT_ID
कॉलम को उस रॉ संपर्क के _ID
कॉलम से लिंक किया जाता है जिससे वह जुड़ा है.
क्लास ContactsContract.Contacts.Photo
, ContactsContract.Contacts
की एक सब-टेबल तय करती है. इसमें किसी संपर्क की मुख्य फ़ोटो की जानकारी होती है. यह संपर्क की मुख्य रॉ फ़ोटो होती है. इसी तरह, क्लास ContactsContract.RawContacts.DisplayPhoto
, ContactsContract.RawContacts
की एक सब-टेबल तय करती है. इसमें किसी रॉ संपर्क की मुख्य फ़ोटो की जानकारी होती है.
ContactsContract.Contacts.Photo
और ContactsContract.RawContacts.DisplayPhoto
के रेफ़रंस दस्तावेज़ में, फ़ोटो की जानकारी पाने के उदाहरण दिए गए हैं. किसी रॉ संपर्क के मुख्य थंबनेल को वापस पाने के लिए, कोई सुविधा क्लास नहीं है. हालांकि, ContactsContract.Data
टेबल को क्वेरी भेजी जा सकती है. इसके लिए, रॉ संपर्क के _ID
, Photo.CONTENT_ITEM_TYPE
, और IS_PRIMARY
कॉलम को चुनें, ताकि रॉ संपर्क की मुख्य फ़ोटो वाली लाइन मिल सके.
किसी व्यक्ति के सोशल स्ट्रीम डेटा में फ़ोटो भी शामिल हो सकती हैं. इन्हें android.provider.ContactsContract.StreamItemPhotos टेबल में सेव किया जाता है. इसके बारे में ज़्यादा जानकारी, सोशल स्ट्रीम फ़ोटो सेक्शन में दी गई है.