Contacts Provider एक बेहतर और सुविधाजनक Android कॉम्पोनेंट है. यह डिवाइस में लोगों के डेटा के मुख्य डेटाबेस को मैनेज करता है. डिवाइस के संपर्क ऐप्लिकेशन में दिखने वाले डेटा का सोर्स, संपर्कों की जानकारी देने वाली कंपनी होती है. साथ ही, अपने ऐप्लिकेशन में भी इस डेटा को ऐक्सेस किया जा सकता है. इसके अलावा, डिवाइस और ऑनलाइन सेवाओं के बीच डेटा ट्रांसफ़र भी किया जा सकता है. सेवा देने वाली कंपनी, कई तरह के डेटा सोर्स का इस्तेमाल करती है. साथ ही, हर व्यक्ति के लिए ज़्यादा से ज़्यादा डेटा मैनेज करने की कोशिश करती है. इस वजह से, उसका संगठन जटिल हो जाता है. इस वजह से, सेवा देने वाले के एपीआई में, कॉन्ट्रैक्ट क्लास और इंटरफ़ेस का एक बड़ा सेट शामिल होता है. इससे डेटा को वापस पाने और उसमें बदलाव करने, दोनों में मदद मिलती है.
इस गाइड में इनके बारे में बताया गया है:
- सेवा देने वाली कंपनी का बुनियादी स्ट्रक्चर.
- डेटा उपलब्ध कराने वाली कंपनी से डेटा पाने का तरीका.
- सेवा देने वाली कंपनी के डेटा में बदलाव करने का तरीका.
- अपने सर्वर से, संपर्कों की सेवा देने वाली कंपनी के साथ डेटा सिंक करने के लिए, सिंक करने वाला अडैप्टर लिखने का तरीका.
इस गाइड में यह माना गया है कि आपको Android पर कॉन्टेंट उपलब्ध कराने वाली कंपनियों के बारे में बुनियादी जानकारी है. Android कॉन्टेंट की सेवा देने वाली कंपनियों के बारे में ज़्यादा जानने के लिए, कॉन्टेंट की सेवा देने वाली कंपनियों के बारे में बुनियादी बातें गाइड पढ़ें.
संपर्क सूची की सेवा देने वाली कंपनी
संपर्क सूची, Android पर कॉन्टेंट उपलब्ध कराने वाला कॉम्पोनेंट है. इसमें किसी व्यक्ति के बारे में तीन तरह का डेटा सेव होता है. हर डेटा, सेवा देने वाली कंपनी की टेबल से जुड़ा होता है. इस बारे में ज़्यादा जानकारी, पहले चित्र में दी गई है:
इन तीन टेबल को आम तौर पर, उनकी कॉन्ट्रैक्ट क्लास के नाम से जाना जाता है. क्लास, टेबल में इस्तेमाल किए जाने वाले कॉन्टेंट यूआरआई, कॉलम के नाम, और कॉलम की वैल्यू के लिए कॉन्सटेंट तय करती हैं:
-
ContactsContract.Contacts
टेबल - अलग-अलग लोगों की जानकारी दिखाने वाली पंक्तियां. ये पंक्तियां, रॉ संपर्क पंक्तियों के एग्रीगेशन के आधार पर बनती हैं.
-
ContactsContract.RawContacts
टेबल - उपयोगकर्ता खाते और टाइप के हिसाब से, किसी व्यक्ति के डेटा की खास जानकारी देने वाली पंक्तियां.
-
ContactsContract.Data
टेबल - रॉ संपर्क की जानकारी वाली लाइनें, जैसे कि ईमेल पते या फ़ोन नंबर.
ContactsContract
में कॉन्ट्रैक्ट क्लास से दिखाई गई अन्य टेबल, सहायक टेबल होती हैं. इनका इस्तेमाल, कॉन्टैक्ट की सेवा देने वाली कंपनी अपने कामों को मैनेज करने या डिवाइस के संपर्कों या टेलीफ़ोन ऐप्लिकेशन में खास फ़ंक्शन के लिए करती है.
रॉ कॉन्टैक्ट
रॉ संपर्क, किसी व्यक्ति के डेटा को दिखाता है. यह डेटा, एक ही तरह के खाते और खाते के नाम से मिलता है. संपर्कों की जानकारी देने वाली सेवा, किसी व्यक्ति के डेटा के सोर्स के तौर पर एक से ज़्यादा ऑनलाइन सेवाओं को अनुमति देती है. इसलिए, संपर्कों की जानकारी देने वाली सेवा, एक ही व्यक्ति के लिए कई रॉ संपर्कों की अनुमति देती है. एक से ज़्यादा रॉ संपर्कों की मदद से, उपयोगकर्ता एक ही तरह के एक से ज़्यादा खातों में मौजूद किसी व्यक्ति के डेटा को भी जोड़ सकता है.
किसी रॉ संपर्क का ज़्यादातर डेटा,
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 है. अपने खाते के टाइप की पुष्टि करने के लिए, हमेशा अपने मालिकाना हक वाले या कंट्रोल किए जा रहे डोमेन के लिए डोमेन आइडेंटिफ़ायर का इस्तेमाल करें. इससे यह पक्का होगा कि आपका
खाता टाइप यूनीक है.
|
संपर्कों का डेटा देने वाले खाते में आम तौर पर, एक सिंक अडैप्टर होता है. यह अडैप्टर, संपर्कों की जानकारी देने वाली कंपनी के साथ सिंक करता है. |
DELETED
|
किसी रॉ संपर्क के लिए "मिटाया गया" फ़्लैग. | इस फ़्लैग की मदद से, संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी, पंक्ति को तब तक अपने पास रख सकती है, जब तक सिंक करने वाले एडेप्टर, अपने सर्वर से पंक्ति को मिटा नहीं देते. इसके बाद, पंक्ति को रिपॉज़िटरी से मिटा दिया जाता है. |
नोट
ContactsContract.RawContacts
टेबल के बारे में ये अहम बातें ध्यान रखें:
-
रॉ संपर्क का नाम,
ContactsContract.RawContacts
में उसकी लाइन में सेव नहीं किया जाता. इसके बजाय, इसेContactsContract.Data
टेबल में,ContactsContract.CommonDataKinds.StructuredName
लाइन में सेव किया जाता है. किसी रॉ संपर्क कीContactsContract.Data
टेबल में, इस तरह की सिर्फ़ एक लाइन होती है. -
चेतावनी: रॉ संपर्क पंक्ति में अपने खाते के डेटा का इस्तेमाल करने के लिए, उसे सबसे पहले
AccountManager
के साथ रजिस्टर करना होगा. ऐसा करने के लिए, उपयोगकर्ताओं को खातों की सूची में खाता टाइप और अपने खाते का नाम जोड़ने के लिए कहें. ऐसा न करने पर, कॉन्टैक्ट की जानकारी देने वाली सेवा देने वाली कंपनी, आपकी रॉ कॉन्टैक्ट लाइन को अपने-आप मिटा देगी.उदाहरण के लिए, अगर आपको अपने ऐप्लिकेशन में, डोमेन
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 में लॉग इन किया, 'संपर्क' खोला, और "थॉमस हिगिन्सन" जोड़ा. बाद में, वह emilyd@gmail.com
के तौर पर Gmail में लॉग इन करती है और "थॉमस हिगिन्सन" को एक ईमेल भेजती है. इससे, वह अपने-आप संपर्क के तौर पर जुड़ जाता है. वह Twitter पर "colonel_tom" (थॉमस हिगिन्सन का Twitter आईडी) को भी फ़ॉलो करती हैं.
इस काम की वजह से, संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी तीन रॉ संपर्क बनाती है:
-
emily.dickinson@gmail.com
से जुड़े "Thomas Higginson" का रॉ कॉन्टैक्ट. उपयोगकर्ता का खाता Google है. -
emilyd@gmail.com
से जुड़े "Thomas Higginson" का दूसरा रॉ संपर्क. उपयोगकर्ता खाते का टाइप भी Google है. रॉ संपर्क की सूची में एक दूसरा संपर्क है, फिर भी नाम पहले वाले नाम से मेल खाता है. ऐसा इसलिए है, क्योंकि उस व्यक्ति को किसी दूसरे उपयोगकर्ता खाते के लिए जोड़ा गया था. - "belle_of_amherst" से जुड़े "थॉमस हिगिन्सन" का तीसरा रॉ संपर्क. उपयोगकर्ता का खाता, Twitter खाता है.
डेटा
जैसा कि पहले बताया गया है, रॉ संपर्क का डेटा,
ContactsContract.Data
लाइन में सेव किया जाता है. यह लाइन, रॉ संपर्क की
_ID
वैल्यू से लिंक होती है. इससे, किसी एक रॉ संपर्क में एक ही तरह के डेटा के कई उदाहरण हो सकते हैं, जैसे कि ईमेल पते या फ़ोन नंबर. उदाहरण के लिए, अगर emilyd@gmail.com
के लिए "थॉमस हिगिन्सन" (emilyd@gmail.com
Google खाते से जुड़े थॉमस हिगिन्सन के लिए रॉ संपर्क पंक्ति) का घर का ईमेल पता thigg@gmail.com
और ऑफ़िस का ईमेल पता thomas.higginson@gmail.com
है, तो संपर्कों की जानकारी देने वाली कंपनी, दोनों ईमेल पतों की पंक्तियों को सेव करती है और दोनों को रॉ संपर्क से लिंक करती है.
ध्यान दें कि इस एक टेबल में अलग-अलग तरह का डेटा सेव किया गया है. डिसप्ले नेम,
फ़ोन नंबर, ईमेल, डाक पता, फ़ोटो, और वेबसाइट की जानकारी वाली सभी पंक्तियां,
ContactsContract.Data
टेबल में मिलती हैं. इसे मैनेज करने के लिए,
ContactsContract.Data
टेबल में कुछ कॉलम में जानकारी देने वाले नाम और कुछ कॉलम में सामान्य नाम होते हैं. जानकारी वाले कॉलम के कॉन्टेंट का मतलब एक जैसा होता है, भले ही पंक्ति में डेटा का टाइप कुछ भी हो. वहीं, सामान्य नाम वाले कॉलम के कॉन्टेंट का मतलब, डेटा के टाइप के हिसाब से अलग-अलग होता है.
कॉलम के नाम के बारे में जानकारी
जानकारी देने वाले कॉलम के नामों के कुछ उदाहरण:
-
RAW_CONTACT_ID
-
इस डेटा के लिए, रॉ संपर्क के
_ID
कॉलम की वैल्यू. -
MIMETYPE
-
इस पंक्ति में सेव किए गए डेटा का टाइप, जिसे कस्टम MIME टाइप के तौर पर दिखाया जाता है. संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी,
ContactsContract.CommonDataKinds
के सबक्लास में बताए गए MIME टाइप का इस्तेमाल करती है. ये एमआईएम टाइप ओपन सोर्स हैं. साथ ही, इनका इस्तेमाल Contacts Provider के साथ काम करने वाले किसी भी ऐप्लिकेशन या सिंक अडैप्टर में किया जा सकता है. -
IS_PRIMARY
-
अगर किसी रॉ संपर्क के लिए, इस तरह की डेटा लाइन एक से ज़्यादा बार दिख सकती है, तो
IS_PRIMARY
कॉलम उस डेटा लाइन को फ़्लैग करता है जिसमें टाइप का प्राइमरी डेटा होता है. उदाहरण के लिए, अगर उपयोगकर्ता किसी संपर्क के फ़ोन नंबर को दबाकर रखता है और डिफ़ॉल्ट के तौर पर सेट करें को चुनता है, तो उस नंबर वालीContactsContract.Data
लाइन केIS_PRIMARY
कॉलम की वैल्यू, शून्य के अलावा किसी और वैल्यू पर सेट हो जाती है.
कॉलम के सामान्य नाम
DATA1
से लेकर
DATA15
तक के नाम वाले 15 सामान्य कॉलम आम तौर पर उपलब्ध होते हैं. साथ ही, SYNC1
से लेकर
SYNC4
तक के चार सामान्य कॉलम भी होते हैं. इनका इस्तेमाल सिर्फ़ सिंक करने वाले एडेप्टर को करना चाहिए. कॉलम के सामान्य नाम वाले कॉन्स्टेंट हमेशा काम करते हैं. भले ही, पंक्ति में किसी भी तरह का डेटा हो.
DATA1
कॉलम को इंडेक्स किया गया हो. संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी, हमेशा इस कॉलम का इस्तेमाल उस डेटा के लिए करती है जो क्वेरी का सबसे ज़्यादा टारगेट होगा. उदाहरण के लिए,
ईमेल लाइन में, इस कॉलम में असल ईमेल पता होता है.
आम तौर पर, कॉलम DATA15
को बड़ी डेटा फ़ाइल (BLOB) के डेटा को सेव करने के लिए रिज़र्व किया जाता है. जैसे, फ़ोटो के थंबनेल.
टाइप के हिसाब से कॉलम के नाम
किसी खास तरह की लाइन के कॉलम के साथ काम करने की सुविधा देने के लिए, कॉन्टैक्ट की जानकारी देने वाला प्रोवाइडर, कॉलम के नाम के लिए अलग-अलग तरह के कॉन्स्टेंट भी उपलब्ध कराता है. ये कॉन्स्टेंट, 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 |
ऐसा आइडेंटिफ़ायर जो रॉ संपर्क को संपर्कों की जानकारी देने वाली सेवा के किसी ग्रुप से जोड़ता है. | ग्रुप, खाता टाइप और खाते के नाम की वैकल्पिक सुविधा है. इनके बारे में ज़्यादा जानकारी, संपर्क ग्रुप सेक्शन में दी गई है. |
संपर्क
संपर्क सूची की सुविधा देने वाली कंपनी, सभी तरह के खातों और खाते के नामों के हिसाब से, रॉ संपर्क पंक्तियों को संपर्क बनाने के लिए जोड़ती है. इससे, किसी व्यक्ति के लिए उपयोगकर्ता के इकट्ठा किए गए सभी डेटा को दिखाने और उसमें बदलाव करने में मदद मिलती है. संपर्कों की जानकारी देने वाली सेवा, नई संपर्क पंक्तियों को बनाने और किसी मौजूदा संपर्क पंक्ति के साथ रॉ संपर्कों को इकट्ठा करने की सुविधा को मैनेज करती है. ऐप्लिकेशन और सिंक अडैप्टर, दोनों को ही संपर्क जोड़ने की अनुमति नहीं है. साथ ही, संपर्क की लाइन में मौजूद कुछ कॉलम सिर्फ़ पढ़ने के लिए होते हैं.
ध्यान दें: अगर आपने insert()
के साथ संपर्क की जानकारी देने वाली सेवा देने वाली कंपनी को कोई संपर्क जोड़ने की कोशिश की, तो आपको UnsupportedOperationException
अपवाद दिखेगा. अगर "रीड-ओनली" के तौर पर सूची में शामिल किसी कॉलम को अपडेट करने की कोशिश की जाती है, तो अपडेट को अनदेखा कर दिया जाता है.
Contacts Provider, किसी नए रॉ संपर्क को जोड़ने के जवाब में एक नया संपर्क बनाता है. ऐसा तब होता है, जब वह नया संपर्क किसी मौजूदा संपर्क से मेल न खाता हो. सेवा देने वाली कंपनी ऐसा तब भी करती है, जब किसी मौजूदा रॉ संपर्क का डेटा इस तरह बदल जाए कि वह अब उस संपर्क से मैच न करता हो जिससे वह पहले जुड़ा था. अगर कोई ऐप्लिकेशन या सिंक अडैप्टर, ऐसा नया रॉ संपर्क बनाता है जो किसी मौजूदा संपर्क से मैच करता है, तो नया रॉ संपर्क मौजूदा संपर्क में जोड़ दिया जाता है.
संपर्कों की जानकारी देने वाली सेवा, किसी संपर्क की पंक्ति को उसकी रॉ संपर्क पंक्तियों से लिंक करती है. इसके लिए, Contacts
टेबल में मौजूद संपर्क की पंक्ति के _ID
कॉलम का इस्तेमाल किया जाता है. रॉ संपर्क टेबल के CONTACT_ID
कॉलम
ContactsContract.RawContacts
में, हर रॉ संपर्क पंक्ति से जुड़ी संपर्क पंक्ति के लिए
_ID
वैल्यू होती हैं.
ContactsContract.Contacts
टेबल में एक कॉलम
LOOKUP_KEY
भी होता है, जो संपर्क पंक्ति का
"स्थायी" लिंक होता है. Contacts की सेवा देने वाली कंपनी, संपर्कों को अपने-आप मैनेज करती है. इसलिए, एग्रीगेशन या सिंक करने पर, यह संपर्क की लाइन की _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
सिंक अडैप्टर से मिला डेटा
उपयोगकर्ता, संपर्कों का डेटा सीधे डिवाइस में डालते हैं. हालांकि, सिंक करने वाले अडैप्टर की मदद से, वेब सेवाओं से भी संपर्कों के डेटा को संपर्कों की सेवा देने वाली कंपनी में भेजा जाता है. इससे, डिवाइस और सेवाओं के बीच डेटा अपने-आप ट्रांसफ़र हो जाता है. सिंक करने वाले अडैप्टर, सिस्टम के कंट्रोल में बैकग्राउंड में चलते हैं. साथ ही, वे डेटा मैनेज करने के लिए ContentResolver
तरीकों को कॉल करते हैं.
Android में, सिंक अडैप्टर जिस वेब सेवा के साथ काम करता है उसकी पहचान खाता टाइप से की जाती है. हर सिंक अडैप्टर, एक तरह के खाते के साथ काम करता है. हालांकि, वह उस तरह के खाते के लिए कई खाता नामों के साथ काम कर सकता है. रॉ संपर्क डेटा के सोर्स सेक्शन में, खाते के टाइप और नाम के बारे में कम शब्दों में बताया गया है. यहां दी गई परिभाषाओं में, इस बारे में ज़्यादा जानकारी दी गई है कि सिंक करने वाले अडैप्टर और सेवाओं के साथ, खाते का टाइप और नाम कैसे जुड़ा है.
- खाता टाइप
-
उस सेवा की पहचान करता है जिसमें उपयोगकर्ता ने डेटा सेव किया है. ज़्यादातर मामलों में, उपयोगकर्ता को सेवा के साथ अपनी पहचान की पुष्टि करनी पड़ती है. उदाहरण के लिए, Google Contacts एक खाता टाइप है, जिसकी पहचान कोड
google.com
से की जाती है. यह वैल्यू,AccountManager
के इस्तेमाल किए गए खाते के टाइप से मेल खाती है. - खाते का नाम
- किसी खाता टाइप के लिए, किसी खास खाते या लॉगिन की पहचान करता है. Google Contacts खाते और Google खाते एक जैसे होते हैं. इनमें खाते के नाम के तौर पर ईमेल पता होता है. अन्य सेवाएं, एक शब्द वाले उपयोगकर्ता नाम या अंकों वाले आईडी का इस्तेमाल कर सकती हैं.
खाते के टाइप यूनीक होने ज़रूरी नहीं हैं. कोई उपयोगकर्ता, Google Contacts के कई खातों को कॉन्फ़िगर कर सकता है और उनका डेटा, संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी के पास डाउनलोड कर सकता है. ऐसा तब हो सकता है, जब उपयोगकर्ता के पास किसी निजी खाते के नाम के लिए, निजी संपर्कों का एक सेट और काम के लिए एक सेट हो. खाते के नाम आम तौर पर अलग-अलग होते हैं. साथ मिलकर, ये संपर्कों की जानकारी देने वाली सेवा और किसी बाहरी सेवा के बीच डेटा फ़्लो की पहचान करते हैं.
अगर आपको अपनी सेवा का डेटा, संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी को ट्रांसफ़र करना है, तो आपको खुद का सिंक अडैप्टर लिखना होगा. इस बारे में ज़्यादा जानकारी के लिए, संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी के सिंक एडैप्टर सेक्शन देखें.
चौथे चित्र में दिखाया गया है कि लोगों के डेटा के फ़्लो में, संपर्क की जानकारी देने वाली सेवा कैसे काम करती है. "सिंक करने वाले अडैप्टर" के तौर पर मार्क किए गए बॉक्स में, हर अडैप्टर को उसके खाता टाइप के हिसाब से लेबल किया जाता है.
ज़रूरी अनुमतियां
जिन ऐप्लिकेशन को संपर्कों की जानकारी देने वाली सेवा को ऐक्सेस करना है उन्हें इन अनुमतियों का अनुरोध करना होगा:
- एक या उससे ज़्यादा टेबल का रीड ऐक्सेस
-
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
क्लास में कॉन्स्टेंट उपलब्ध होते हैं.
उपयोगकर्ता की प्रोफ़ाइल को ऐक्सेस करने के लिए, खास अनुमतियों की ज़रूरत होती है. उपयोगकर्ता प्रोफ़ाइल को ऐक्सेस करने के लिए, रीड और लिखने की अनुमति के साथ-साथ, रीड और लिखने के लिए, क्रमशः android.Manifest.permission#READ_PROFILE और android.Manifest.permission#WRITE_PROFILE की अनुमतियां भी ज़रूरी हैं.READ_CONTACTS
WRITE_CONTACTS
याद रखें कि आपको किसी उपयोगकर्ता की प्रोफ़ाइल को संवेदनशील मानना चाहिए. 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" पर सेट होता है.
संपर्क सूची की सेवा देने वाली कंपनी का मेटाडेटा
संपर्क सूची की सेवा देने वाली कंपनी, उस डेटा को मैनेज करती है जो रिपॉज़िटरी में मौजूद संपर्कों के डेटा की स्थिति का ट्रैक रखता है. रिपॉज़िटरी का यह मेटाडेटा, कई जगहों पर सेव किया जाता है. इनमें,
रॉ संपर्क, डेटा, और संपर्क टेबल की पंक्तियां,
ContactsContract.Settings
टेबल, और
ContactsContract.SyncState
टेबल शामिल हैं. नीचे दी गई टेबल में, मेटाडेटा के इन हर हिस्से का असर दिखाया गया है:
टेबल | कॉलम | वैल्यू | मतलब |
---|---|---|---|
ContactsContract.RawContacts |
DIRTY |
"0" - पिछले सिंक के बाद से कोई बदलाव नहीं हुआ है. |
उन रॉ संपर्कों को मार्क करता है जिन्हें डिवाइस पर बदला गया था और जिन्हें फिर से सर्वर से सिंक करना है. जब Android ऐप्लिकेशन किसी पंक्ति को अपडेट करते हैं, तो संपर्क की जानकारी देने वाली सेवा देने वाली कंपनी, वैल्यू को अपने-आप सेट कर देती है.
रॉ संपर्क या डेटा टेबल में बदलाव करने वाले सिंक एडैप्टर को, इस्तेमाल किए जाने वाले कॉन्टेंट यूआरआई में हमेशा |
"1" - पिछली बार सिंक करने के बाद बदला गया, इसे सर्वर से फिर से सिंक करना होगा. | |||
ContactsContract.RawContacts |
VERSION |
इस लाइन का वर्शन नंबर. | जब भी लाइन या उससे जुड़ा डेटा बदलता है, तो संपर्कों की जानकारी देने वाली सेवा, इस वैल्यू को अपने-आप बढ़ा देती है. |
ContactsContract.Data |
DATA_VERSION |
इस लाइन का वर्शन नंबर. | जब भी डेटा लाइन में बदलाव होता है, तो संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी, इस वैल्यू को अपने-आप बढ़ा देती है. |
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 |
(सभी) | सिंक अडैप्टर के लिए मेटाडेटा सेव करने के लिए, इस टेबल का इस्तेमाल करें. | इस टेबल की मदद से, सिंक की स्थिति और सिंक से जुड़ा अन्य डेटा, डिवाइस पर लगातार सेव किया जा सकता है. |
संपर्कों की सूची को ऐक्सेस करने की सुविधा देने वाली कंपनी
इस सेक्शन में, संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी से डेटा ऐक्सेस करने के दिशा-निर्देशों के बारे में बताया गया है. इनमें इन पर फ़ोकस किया गया है:
- इकाई से जुड़ी क्वेरी.
- एक साथ कई प्रॉडक्ट में बदलाव करना.
- इंटेंट की मदद से डेटा को वापस लाना और उसमें बदलाव करना.
- डेटा का रखरखाव.
सिंक एडैप्टर से बदलाव करने के बारे में ज़्यादा जानकारी, संपर्क सेवा देने वाली कंपनी के सिंक एडैप्टर सेक्शन में दी गई है.
इकाइयों के बारे में क्वेरी करना
संपर्कों की जानकारी देने वाली टेबल, हैरारकी के हिसाब से व्यवस्थित की जाती हैं. इसलिए, अक्सर किसी पंक्ति और उससे जुड़ी सभी "चाइल्ड" पंक्तियों को फिर से पाना मददगार होता है. उदाहरण के लिए, किसी व्यक्ति की सभी जानकारी दिखाने के लिए, हो सकता है कि आप किसी एक ContactsContract.Contacts
पंक्ति के लिए सभी ContactsContract.RawContacts
पंक्तियां या किसी एक ContactsContract.RawContacts
पंक्ति के लिए सभी ContactsContract.CommonDataKinds.Email
पंक्तियां वापस पाना चाहें. इसकी सुविधा देने के लिए, संपर्कों की जानकारी देने वाली कंपनी इकाई के कॉन्स्ट्रक्ट उपलब्ध कराती है. ये कॉन्स्ट्रक्ट, टेबल के बीच डेटाबेस जॉइन की तरह काम करते हैं.
इकाई, एक टेबल की तरह होती है. यह पैरंट टेबल और उसकी चाइल्ड टेबल के चुने गए कॉलम से बनी होती है.
किसी इकाई के बारे में क्वेरी करते समय, इकाई के उपलब्ध कॉलम के आधार पर प्रोजेक्शन और खोज की शर्तें दी जाती हैं. इसका नतीजा एक Cursor
होता है, जिसमें
ढूंढी गई हर चाइल्ड टेबल लाइन के लिए एक लाइन होती है. उदाहरण के लिए, अगर किसी संपर्क के नाम के लिए ContactsContract.Contacts.Entity
और उस नाम के सभी रॉ संपर्कों के लिए सभी ContactsContract.CommonDataKinds.Email
पंक्तियों की क्वेरी की जाती है, तो आपको हर ContactsContract.CommonDataKinds.Email
पंक्ति के लिए एक पंक्ति वाला Cursor
मिलता है.
इकाइयां, क्वेरी को आसान बनाती हैं. इकाई का इस्तेमाल करके, किसी एक संपर्क या रॉ संपर्क का सारा संपर्क डेटा एक साथ पाया जा सकता है. इसके लिए, आईडी पाने के लिए पहले पैरंट टेबल और फिर उस आईडी के साथ चाइल्ड टेबल को क्वेरी करने की ज़रूरत नहीं होती. साथ ही, संपर्कों की जानकारी देने वाली कंपनी, किसी इकाई के लिए एक ही लेन-देन में क्वेरी को प्रोसेस करती है. इससे यह पक्का होता है कि वापस पाया गया डेटा, इंटरनल तौर पर एक जैसा हो.
ध्यान दें: आम तौर पर, किसी इकाई में पैरंट और चाइल्ड टेबल के सभी कॉलम शामिल नहीं होते. अगर किसी ऐसे कॉलम के नाम का इस्तेमाल किया जाता है जो इकाई के लिए, कॉलम के नाम की सूची में मौजूद नहीं है, तो आपको Exception
दिखेगा.
नीचे दिए गए स्निपेट में, किसी संपर्क की सभी रॉ संपर्क पंक्तियां वापस पाने का तरीका बताया गया है. स्निपेट,
बड़े ऐप्लिकेशन का हिस्सा है. इसमें दो गतिविधियां हैं, "मुख्य" और "जानकारी". मुख्य गतिविधि, संपर्क पंक्तियों की सूची दिखाती है. जब उपयोगकर्ता कोई पंक्ति चुनता है, तो गतिविधि, ज़्यादा जानकारी वाली गतिविधि को अपना आईडी भेजती है. ज़्यादा जानकारी वाली गतिविधि, चुने गए संपर्क से जुड़े सभी रॉ संपर्कों की सभी डेटा पंक्तियां दिखाने के लिए, 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
से डेटा पाकर उसे दिखाया जा सकता है या उस पर आगे काम किया जा सकता है.
एक साथ कई बदलाव करना
जब भी संभव हो, आपको ContentProviderOperation
ऑब्जेक्ट का ArrayList
बनाकर और applyBatch()
को कॉल करके, कॉन्टैक्ट प्रोवाइडर में "बैच मोड" में डेटा डालना, अपडेट करना, और मिटाना चाहिए. Contacts की सेवा देने वाली कंपनी, एक ही लेन-देन में applyBatch()
में सभी कार्रवाइयां करती है. इसलिए, आपके बदलावों की वजह से संपर्कों के डेटाबेस में कभी भी कोई गड़बड़ी नहीं होगी. एक साथ कई बदलाव करने की सुविधा का इस्तेमाल करके, एक ही समय पर रॉ संपर्क और उसकी ज़्यादा जानकारी वाला डेटा डाला जा सकता है.
ध्यान दें: किसी एक रॉ संपर्क में बदलाव करने के लिए, अपने ऐप्लिकेशन में बदलाव करने के बजाय, डिवाइस के संपर्क ऐप्लिकेशन को एक इंटेंट भेजें. ऐसा करने के बारे में ज़्यादा जानकारी, इंटेंट की मदद से संपर्कों को वापस लाना और उनमें बदलाव करना सेक्शन में दी गई है.
YielD पॉइंट
एक साथ कई बदलाव करने की सुविधा का इस्तेमाल करके, एक साथ कई बदलाव करने पर, अन्य प्रोसेस ब्लॉक हो सकती हैं. इससे, उपयोगकर्ता को खराब अनुभव मिल सकता है. आपको जिन बदलावों को करना है उन्हें व्यवस्थित करने के लिए, उन्हें कम से कम अलग-अलग सूचियों में रखें. साथ ही, उन्हें सिस्टम को ब्लॉक करने से रोकने के लिए, एक या उससे ज़्यादा ऑपरेशन के लिए यील्ड पॉइंट सेट करें.
यील्ड पॉइंट एक ContentProviderOperation
ऑब्जेक्ट होता है, जिसकी
isYieldAllowed()
वैल्यू को
true
पर सेट किया गया हो. जब संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी को कोई समस्या आती है, तो वह अपना काम रोक देती है, ताकि अन्य प्रोसेस चल सकें. साथ ही, वह मौजूदा लेन-देन को बंद कर देती है. जब सेवा देने वाली कंपनी फिर से शुरू होती है, तो वह 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
कॉलम भी वापस पाएं. -
newAssertQuery(Uri)
तरीके का इस्तेमाल करके,ContentProviderOperation.Builder
ऑब्जेक्ट बनाएं. यह ऑब्जेक्ट, किसी शर्त को लागू करने के लिए सही होता है. कॉन्टेंट यूआरआई के लिए,RawContacts.CONTENT_URI
का इस्तेमाल करें. साथ ही, रॉ संपर्क के_ID
को उसमें जोड़ें. -
ContentProviderOperation.Builder
ऑब्जेक्ट के लिए,VERSION
कॉलम की तुलना उस वर्शन नंबर से करने के लिए,withValue()
को कॉल करें जिसे आपने अभी हासिल किया है. -
उसी
ContentProviderOperation.Builder
के लिए,withExpectedCount()
को कॉल करें, ताकि यह पक्का किया जा सके कि इस दावे से सिर्फ़ एक लाइन की जांच की गई है. -
ContentProviderOperation
ऑब्जेक्ट बनाने के लिए,build()
को कॉल करें. इसके बाद, इस ऑब्जेक्ट कोArrayList
में पहले ऑब्जेक्ट के तौर पर जोड़ें, जिसेapplyBatch()
को पास किया जाता है. - एक साथ कई लेन-देन करने की सुविधा लागू करें.
अगर रॉ संपर्क पंक्ति को पढ़ने और उसमें बदलाव करने के बीच, किसी अन्य कार्रवाई से अपडेट किया जाता है, तो "दावा करें" ContentProviderOperation
काम नहीं करेगा और कार्रवाइयों का पूरा बैच वापस ले लिया जाएगा. इसके बाद, आपके पास बैच को फिर से शुरू करने या कोई दूसरी कार्रवाई करने का विकल्प होता है.
नीचे दिए गए स्निपेट में, CursorLoader
का इस्तेमाल करके किसी एक रॉ संपर्क के लिए क्वेरी करने के बाद, "असर्ट"
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 }
इंटेंट की मदद से डेटा को वापस लाना और उसमें बदलाव करना
डिवाइस के संपर्क ऐप्लिकेशन को इंटेंट भेजने से, आपको संपर्क सेवा देने वाली कंपनी को सीधे तौर पर ऐक्सेस करने की अनुमति मिलती है. इंटेंट, डिवाइस के संपर्क ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) को शुरू करता है. इसमें उपयोगकर्ता, संपर्क से जुड़े काम कर सकते हैं. इस तरह के ऐक्सेस की मदद से, उपयोगकर्ता ये काम कर सकते हैं:
- सूची में से कोई संपर्क चुनें और उसे आगे के काम के लिए अपने ऐप्लिकेशन में वापस लाएं.
- किसी मौजूदा संपर्क के डेटा में बदलाव करना.
- उनके किसी भी खाते के लिए, नया रॉ संपर्क डालें.
- किसी संपर्क या संपर्कों का डेटा मिटाना.
अगर उपयोगकर्ता डेटा डाल रहा है या अपडेट कर रहा है, तो पहले डेटा इकट्ठा किया जा सकता है और उसे इंटेंट के हिस्से के तौर पर भेजा जा सकता है.
डिवाइस के संपर्कों वाले ऐप्लिकेशन के ज़रिए संपर्कों की जानकारी देने वाली सेवा को ऐक्सेस करने के लिए, इंटेंट का इस्तेमाल करने पर, आपको सेवा को ऐक्सेस करने के लिए अपना यूज़र इंटरफ़ेस (यूआई) या कोड लिखने की ज़रूरत नहीं होती. आपको सेवा देने वाली कंपनी से, डेटा पढ़ने या उसमें बदलाव करने की अनुमति भी नहीं लेनी पड़ती. डिवाइस का संपर्कों का ऐप्लिकेशन, किसी संपर्क को पढ़ने की अनुमति आपको दे सकता है. साथ ही, किसी दूसरे ऐप्लिकेशन की मदद से, सेवा देने वाली कंपनी के डेटा में बदलाव किया जा रहा है. इसलिए, आपके पास डेटा में बदलाव करने की अनुमतियां नहीं होनी चाहिए.
किसी सेवा देने वाली कंपनी को ऐक्सेस करने के लिए, इंटेंट भेजने की सामान्य प्रोसेस के बारे में ज़्यादा जानकारी, "इंटेंट की मदद से डेटा ऐक्सेस करना" सेक्शन में,
कॉन्टेंट उपलब्ध कराने वाली कंपनी के बारे में बुनियादी जानकारी गाइड में दी गई है. टेबल 4 में, उपलब्ध टास्क के लिए इस्तेमाल की जाने वाली कार्रवाई, MIME टाइप, और डेटा वैल्यू की खास जानकारी दी गई है. वहीं, putExtra()
के साथ इस्तेमाल की जा सकने वाली अतिरिक्त वैल्यू, ContactsContract.Intents.Insert
के रेफ़रंस दस्तावेज़ में दी गई हैं:
टास्क | कार्रवाई | डेटा | MIME प्रकार | नोट |
---|---|---|---|---|
सूची में से कोई संपर्क चुनना | ACTION_PICK |
इनमें से कोई एक:
|
प्रयुक्त नहीं |
आपके दिए गए कॉन्टेंट यूआरआई टाइप के आधार पर, रॉ संपर्कों की सूची या रॉ संपर्क के डेटा की सूची दिखाता है.
|
नया रॉ संपर्क डालना | Insert.ACTION |
लागू नहीं |
RawContacts.CONTENT_TYPE , रॉ संपर्कों के सेट के लिए MIME टाइप.
|
डिवाइस के संपर्क ऐप्लिकेशन की संपर्क जोड़ें स्क्रीन दिखाता है. इंटेंट में जोड़ी गई
अतिरिक्त वैल्यू दिखती हैं. अगर इसे
startActivityForResult() के साथ भेजा जाता है, तो
हाल ही में जोड़े गए रॉ संपर्क का कॉन्टेंट यूआरआई, आपकी गतिविधि के
onActivityResult()
कॉलबैक तरीके में वापस भेज दिया जाता है. यह यूआरआई, Intent आर्ग्युमेंट में,
"डेटा" फ़ील्ड में होता है. वैल्यू पाने के लिए, getData() को कॉल करें.
|
संपर्क में बदलाव करना | ACTION_EDIT |
CONTENT_LOOKUP_URI से संपर्क करें. एडिटर गतिविधि की मदद से, उपयोगकर्ता इस संपर्क से जुड़े किसी भी डेटा में बदलाव कर सकता है.
|
Contacts.CONTENT_ITEM_TYPE , एक संपर्क. |
Contacts ऐप्लिकेशन में, 'संपर्क में बदलाव करें' स्क्रीन दिखाता है. इंटेंट में जोड़ी गई अतिरिक्त वैल्यू दिखती हैं. जब उपयोगकर्ता बदलावों को सेव करने के लिए हो गया पर क्लिक करता है, तो आपकी गतिविधि फ़ोरग्राउंड पर वापस आ जाती है. |
ऐसा पिकर दिखाएं जिसमें डेटा भी जोड़ा जा सके. | ACTION_INSERT_OR_EDIT |
लागू नहीं |
CONTENT_ITEM_TYPE
|
यह इंटेंट, हमेशा संपर्क ऐप्लिकेशन की पिकर स्क्रीन दिखाता है. उपयोगकर्ता, बदलाव करने के लिए किसी संपर्क को चुन सकता है या नया संपर्क जोड़ सकता है. उपयोगकर्ता की पसंद के आधार पर, बदलाव करें या जोड़ें स्क्रीन दिखती है. साथ ही, इंटेंट में पास किया गया अतिरिक्त डेटा दिखता है. अगर आपका ऐप्लिकेशन ईमेल या फ़ोन नंबर जैसे संपर्क डेटा दिखाता है, तो उपयोगकर्ता को किसी मौजूदा संपर्क में डेटा जोड़ने की अनुमति देने के लिए, इस इंटेंट का इस्तेमाल करें.
संपर्क,
ध्यान दें: इस इंटेंट के एक्सट्रा में नाम की वैल्यू भेजने की ज़रूरत नहीं है, क्योंकि उपयोगकर्ता हमेशा कोई मौजूदा नाम चुनता है या नया नाम जोड़ता है. इसके अलावा, अगर आपने कोई नाम भेजा है और उपयोगकर्ता ने उसमें बदलाव करने का विकल्प चुना है, तो 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);
डेटा का रखरखाव
संपर्कों के डेटाबेस में अहम और संवेदनशील डेटा होता है. उपयोगकर्ताओं को उम्मीद होती है कि यह डेटा सही और अप-टू-डेट हो. इसलिए, संपर्कों की जानकारी देने वाली कंपनी के पास डेटा की सुरक्षा के लिए खास नियम होते हैं. संपर्कों के डेटा में बदलाव करते समय, इन नियमों का पालन करना आपकी ज़िम्मेदारी है. यहां कुछ ज़रूरी नियम दिए गए हैं:
-
जोड़ी गई हर
ContactsContract.RawContacts
लाइन के लिए, हमेशा एकContactsContract.CommonDataKinds.StructuredName
लाइन जोड़ें. -
ContactsContract.Data
टेबल मेंContactsContract.CommonDataKinds.StructuredName
पंक्ति के बिनाContactsContract.RawContacts
पंक्ति होने पर, एग्रीगेशन के दौरान समस्याएं आ सकती हैं. -
नई
ContactsContract.Data
पंक्तियों को हमेशा अपनी पैरंटContactsContract.RawContacts
पंक्ति से लिंक करें. -
ContactsContract.Data
लाइन, डिवाइस केContactsContract.RawContacts
से लिंक न होने पर, डिवाइस के संपर्क ऐप्लिकेशन में नहीं दिखेगी. साथ ही, इससे सिंक एडैप्टर में समस्याएं आ सकती हैं. - सिर्फ़ उन रॉ संपर्कों के डेटा में बदलाव करें जिनका मालिकाना हक आपके पास है.
- याद रखें कि संपर्कों की जानकारी देने वाली कंपनी, आम तौर पर कई अलग-अलग तरह के खातों/ऑनलाइन सेवाओं का डेटा मैनेज करती है. आपको यह पक्का करना होगा कि आपका ऐप्लिकेशन सिर्फ़ उन पंक्तियों के डेटा में बदलाव करे या उसे मिटाए जिनका मालिकाना हक आपके पास है. साथ ही, यह भी पक्का करना होगा कि वह सिर्फ़ उस खाता टाइप और नाम के साथ डेटा डाले जिसका कंट्रोल आपके पास है.
-
हमेशा
ContactsContract
और उसके सबक्लास में तय की गई कॉन्स्टेंट का इस्तेमाल करें. ये कॉन्स्टेंट, ऐथॉरिटी, कॉन्टेंट यूआरआई, यूआरआई पाथ, कॉलम के नाम, MIME टाइप, औरTYPE
वैल्यू के लिए इस्तेमाल किए जाते हैं. - इन कॉन्स्टेंट का इस्तेमाल करने से, गड़बड़ियों से बचा जा सकता है. अगर कोई भी कॉन्स्टेंट इस्तेमाल नहीं किया जा सकता, तो आपको कंपाइलर के साथ मिलने वाली चेतावनियों के बारे में भी सूचना दी जाएगी.
कस्टम डेटा लाइनें
अपने कस्टम एमआईएम टाइप बनाकर और उनका इस्तेमाल करके, ContactsContract.Data
टेबल में अपनी डेटा लाइनें डाली जा सकती हैं, उनमें बदलाव किया जा सकता है, उन्हें मिटाया जा सकता है, और उन्हें वापस पाया जा सकता है. आपकी पंक्तियां,
ContactsContract.DataColumns
में तय किए गए कॉलम का इस्तेमाल करने तक सीमित हैं. हालांकि, आपके पास अपने टाइप के हिसाब से कॉलम के नामों को डिफ़ॉल्ट कॉलम के नामों से मैप करने का विकल्प है. डिवाइस के संपर्क ऐप्लिकेशन में, आपकी पंक्तियों का डेटा दिखता है. हालांकि, उसमें बदलाव नहीं किया जा सकता या उसे मिटाया नहीं जा सकता. साथ ही, उपयोगकर्ता कोई और डेटा भी नहीं जोड़ सकते. उपयोगकर्ताओं को आपकी कस्टम डेटा पंक्तियों में बदलाव करने की अनुमति देने के लिए, आपको अपने ऐप्लिकेशन में एडिटर ऐक्टिविटी देनी होगी.
अपना कस्टम डेटा दिखाने के लिए, ऐसी contacts.xml
फ़ाइल दें जिसमें एक
<ContactsAccountType>
एलिमेंट और उसके एक या एक से ज़्यादा
<ContactsDataKind>
चाइल्ड एलिमेंट शामिल हों. इस बारे में ज़्यादा जानकारी,
सेक्शन <ContactsDataKind> element
में दी गई है.
कस्टम एमआईएम टाइप के बारे में ज़्यादा जानने के लिए, कॉन्टेंट प्रोवाइडर बनाना गाइड पढ़ें.
संपर्क सूची की सेवा देने वाली कंपनी के सिंक अडैप्टर
संपर्कों की जानकारी देने वाली सेवा को खास तौर पर, किसी डिवाइस और ऑनलाइन सेवा के बीच संपर्कों के डेटा को सिंक करने के लिए डिज़ाइन किया गया है. इससे उपयोगकर्ताओं को किसी नए डिवाइस पर मौजूदा डेटा डाउनलोड करने और मौजूदा डेटा को किसी नए खाते में अपलोड करने की सुविधा मिलती है. सिंक करने से यह भी पक्का होता है कि उपयोगकर्ताओं के पास सबसे नया डेटा हो. भले ही, डेटा में बदलाव और जोड़ने का सोर्स कुछ भी हो. सिंक करने का एक और फ़ायदा यह है कि इससे डिवाइस के नेटवर्क से कनेक्ट न होने पर भी, संपर्कों का डेटा उपलब्ध रहता है.
सिंक करने की सुविधा को कई तरीकों से लागू किया जा सकता है. हालांकि, Android सिस्टम में एक प्लग-इन सिंक करने का फ़्रेमवर्क होता है, जो इन टास्क को अपने-आप पूरा करता है:
- नेटवर्क की उपलब्धता की जांच की जा रही है.
- उपयोगकर्ता की प्राथमिकताओं के आधार पर, सिंक करने की प्रोसेस को शेड्यूल करना और उसे लागू करना.
- रुके हुए सिंक को फिर से शुरू करना.
इस फ़्रेमवर्क का इस्तेमाल करने के लिए, आपको सिंक अडैप्टर प्लग-इन देना होगा. हर सिंक अडैप्टर, किसी सेवा और कॉन्टेंट की सेवा देने वाली कंपनी के लिए यूनीक होता है. हालांकि, यह एक ही सेवा के लिए कई खातों के नामों को मैनेज कर सकता है. फ़्रेमवर्क, एक ही सेवा और प्रोवाइडर के लिए कई सिंक अडैप्टर की भी अनुमति देता है.
अडैप्टर क्लास और फ़ाइलें सिंक करना
आपने सिंक अडैप्टर को AbstractThreadedSyncAdapter
के सबक्लास के तौर पर लागू किया है और उसे Android ऐप्लिकेशन के हिस्से के तौर पर इंस्टॉल किया है. सिस्टम, आपके ऐप्लिकेशन के मेनिफ़ेस्ट में मौजूद एलिमेंट और मेनिफ़ेस्ट से मिली खास एक्सएमएल फ़ाइल से, सिंक एडैप्टर के बारे में जानता है. एक्सएमएल फ़ाइल में, ऑनलाइन सेवा के लिए खाता टाइप और कॉन्टेंट उपलब्ध कराने वाली कंपनी की अनुमति के बारे में जानकारी होती है. इन दोनों से अडैप्टर की यूनीक पहचान की जाती है. सिंक एडैप्टर तब तक चालू नहीं होता, जब तक उपयोगकर्ता सिंक एडैप्टर के खाता टाइप के लिए कोई खाता नहीं जोड़ता और उस कॉन्टेंट की सेवा देने वाली कंपनी के लिए सिंक करने की सुविधा चालू नहीं करता जिसके साथ सिंक एडैप्टर सिंक करता है. इसके बाद, सिस्टम अडैप्टर को मैनेज करना शुरू कर देता है. साथ ही, कॉन्टेंट देने वाली कंपनी और सर्वर के बीच सिंक करने के लिए, ज़रूरत के हिसाब से अडैप्टर को कॉल करता है.
ध्यान दें: सिंक एडैप्टर की पहचान करने के लिए खाता टाइप का इस्तेमाल करने से, सिस्टम को एक ही संगठन की अलग-अलग सेवाओं को ऐक्सेस करने वाले सिंक एडैप्टर का पता लगाने और उन्हें एक साथ ग्रुप करने में मदद मिलती है. उदाहरण के लिए, Google की ऑनलाइन सेवाओं के लिए सिंक करने वाले सभी अडैप्टर का एक ही खाता टाइप com.google
होता है. जब उपयोगकर्ता अपने डिवाइसों में Google खाता जोड़ते हैं, तो Google की सेवाओं के लिए इंस्टॉल किए गए सभी सिंक अडैप्टर एक साथ दिखते हैं. सूची में मौजूद हर सिंक अडैप्टर, डिवाइस पर कॉन्टेंट उपलब्ध कराने वाली किसी अलग कंपनी के साथ सिंक होता है.
ज़्यादातर सेवाओं के लिए, डेटा ऐक्सेस करने से पहले उपयोगकर्ताओं को अपनी पहचान की पुष्टि करनी होती है. इसलिए, Android सिस्टम पुष्टि करने का एक फ़्रेमवर्क उपलब्ध कराता है. यह फ़्रेमवर्क, सिंक अडैप्टर फ़्रेमवर्क से मिलता-जुलता है और अक्सर इसका इस्तेमाल सिंक अडैप्टर फ़्रेमवर्क के साथ किया जाता है. पुष्टि करने वाला फ़्रेमवर्क,
AbstractAccountAuthenticator
के सबक्लास वाले प्लग-इन ऑथेंटिकेटर का इस्तेमाल करता है. पुष्टि करने वाला टूल, इन चरणों में उपयोगकर्ता की पहचान की पुष्टि करता है:
- उपयोगकर्ता का नाम, पासवर्ड या ऐसी ही जानकारी इकट्ठा करता है (उपयोगकर्ता के क्रेडेंशियल).
- सेवा को क्रेडेंशियल भेजता है
- सेवा के जवाब की जांच करता है.
अगर सेवा, क्रेडेंशियल स्वीकार करती है, तो पुष्टि करने वाला ऐप्लिकेशन, क्रेडेंशियल को बाद में इस्तेमाल करने के लिए स्टोर कर सकता है. प्लग-इन Authenticator फ़्रेमवर्क की वजह से, AccountManager
उन सभी ऑथटॉकन का ऐक्सेस दे सकता है जिनका इस्तेमाल Authenticator करता है और जिन्हें वह दिखाने का विकल्प चुनता है. जैसे, OAuth2 ऑथटॉकन.
पुष्टि करना ज़रूरी नहीं है, लेकिन ज़्यादातर संपर्क सेवाएं इसका इस्तेमाल करती हैं. हालांकि, पुष्टि करने के लिए, आपको Android के पुष्टि करने वाले फ़्रेमवर्क का इस्तेमाल करने की ज़रूरत नहीं है.
सिंक अडैप्टर लागू करना
Contacts Provider के लिए सिंक अडैप्टर लागू करने के लिए, सबसे पहले ऐसा Android ऐप्लिकेशन बनाएं जिसमें ये चीज़ें शामिल हों:
-
एक
Service
कॉम्पोनेंट, जो सिंक एडैप्टर से बाइंड करने के लिए, सिस्टम के अनुरोधों का जवाब देता है. -
जब सिस्टम को सिंक करना होता है, तो वह सिंक एडेप्टर के लिए
IBinder
पाने के लिए, सेवा केonBind()
तरीके को कॉल करता है. इससे सिस्टम, अडैप्टर के तरीकों पर क्रॉस-प्रोसेस कॉल कर सकता है. -
असल सिंक अडैप्टर, जिसे
AbstractThreadedSyncAdapter
के कंक्रीट सबक्लास के तौर पर लागू किया गया है. -
यह क्लास, सर्वर से डेटा डाउनलोड करने, डिवाइस से डेटा अपलोड करने, और विरोधों को हल करने का काम करती है. अडैप्टर का मुख्य काम,
onPerformSync()
तरीके से किया जाता है. इस क्लास को सिंगलटन के तौर पर इंस्टैंशिएट किया जाना चाहिए. -
Application
की सब-क्लास. -
यह क्लास, सिंक अडैप्टर सिंगलटन के लिए फ़ैक्ट्री के तौर पर काम करती है. सिंक अडैप्टर को इंस्टैंशिएट करने के लिए,
onCreate()
तरीके का इस्तेमाल करें. साथ ही, सिंक अडैप्टर की सेवा केonBind()
तरीके में सिंगलटन को वापस लाने के लिए, स्टैटिक "गेटर" तरीका दें. -
ज़रूरी नहीं: यह एक
Service
कॉम्पोनेंट है, जो उपयोगकर्ता की पुष्टि करने के लिए, सिस्टम से मिले अनुरोधों का जवाब देता है. -
AccountManager
, पुष्टि की प्रोसेस शुरू करने के लिए, इस सेवा को शुरू करता है. सेवा काonCreate()
तरीका, authenticator ऑब्जेक्ट को इंस्टैंशिएट करता है. जब सिस्टम को ऐप्लिकेशन के सिंक अडैप्टर के लिए किसी उपयोगकर्ता खाते की पुष्टि करनी होती है, तो वह पुष्टि करने वाले टूल के लिएIBinder
पाने के लिए, सेवा केonBind()
तरीके को कॉल करता है. इससे सिस्टम को पुष्टि करने वाले तरीकों के लिए, क्रॉस-प्रोसेस कॉल करने में मदद मिलती है. -
ज़रूरी नहीं:
AbstractAccountAuthenticator
का एक कंसक्रिट सबक्लास, जो पुष्टि करने के अनुरोधों को मैनेज करता है. -
यह क्लास ऐसे तरीके उपलब्ध कराती है जिनका इस्तेमाल
AccountManager
, सर्वर पर उपयोगकर्ता के क्रेडेंशियल की पुष्टि करने के लिए करता है. इस्तेमाल की जा रही सर्वर टेक्नोलॉजी के आधार पर, पुष्टि करने की प्रोसेस की जानकारी अलग-अलग होती है. पुष्टि करने के बारे में ज़्यादा जानने के लिए, आपको अपने सर्वर सॉफ़्टवेयर के दस्तावेज़ देखना चाहिए. - एक्सएमएल फ़ाइलें, जो सिस्टम के लिए सिंक अडैप्टर और पुष्टि करने वाले टूल के बारे में बताती हैं.
-
सिंक एडैप्टर और पुष्टि करने वाली सेवा के कॉम्पोनेंट, ऐप्लिकेशन मेनिफ़ेस्ट में
<service>
के एलिमेंट में बताए गए हैं. इन एलिमेंट में ऐसे<meta-data>
चाइल्ड एलिमेंट होते हैं जो सिस्टम को खास डेटा देते हैं:-
सिंक एडैप्टर सेवा के लिए,
<meta-data>
एलिमेंट, एक्सएमएल फ़ाइलres/xml/syncadapter.xml
पर ले जाता है. इस फ़ाइल में, वेब सेवा के लिए एक यूआरआई और खाता टाइप की जानकारी दी जाती है. इस यूआरआई को संपर्कों की जानकारी देने वाली सेवा के साथ सिंक किया जाएगा. -
ज़रूरी नहीं: पुष्टि करने वाले प्रोग्राम के लिए,
<meta-data>
एलिमेंट, एक्सएमएल फ़ाइलres/xml/authenticator.xml
पर ले जाता है. इस फ़ाइल से, पुष्टि करने वाले इस ऐप्लिकेशन के साथ काम करने वाले खाते के टाइप के साथ-साथ, पुष्टि करने की प्रोसेस के दौरान दिखने वाले यूज़र इंटरफ़ेस (यूआई) संसाधनों के बारे में पता चलता है. इस एलिमेंट में बताए गए खाता टाइप और सिंक एडैप्टर के लिए बताए गए खाता टाइप एक ही होने चाहिए.
-
सिंक एडैप्टर सेवा के लिए,
सोशल स्ट्रीम का डेटा
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
- यह एक टेक्स्ट स्ट्रिंग है, जिसमें स्ट्रीम आइटम को डालने या अपडेट करने का समय होता है. यह समय, मिलीसेकंड में, एपिक के बाद के समय के तौर पर दिया जाता है. स्ट्रीम आइटम डालने या अपडेट करने वाले ऐप्लिकेशन, इस कॉलम को मैनेज करने के लिए ज़िम्मेदार होते हैं. यह कॉलम, संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी के ज़रिए अपने-आप मैनेज नहीं होता.
अपने स्ट्रीम आइटम की पहचान करने वाली जानकारी दिखाने के लिए, अपने ऐप्लिकेशन में संसाधनों से लिंक करने के लिए, android.provider.ContactsContract.StreamItemsColumns#RES_ICON, android.provider.ContactsContract.StreamItemsColumns#RES_LABEL, और android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE का इस्तेमाल करें.
android.provider.ContactsContract.StreamItems टेबल में, सिंक करने वाले एडैप्टर के खास इस्तेमाल के लिए, 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 के उन पिछले वर्शन के साथ काम करता है जिनमें फ़ोटो सेव करने के लिए इसका इस्तेमाल किया गया था. हालांकि, मौजूदा वर्शन में, फ़ोटो सेव करने के लिए इस कॉलम का इस्तेमाल नहीं किया जाना चाहिए. इसके बजाय, फ़ोटो को फ़ाइल में सेव करने के लिए, 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()
को कॉल करें.
सोशल स्ट्रीम टेबल का इस्तेमाल करना
ये टेबल, संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी की अन्य मुख्य टेबल की तरह ही काम करती हैं. हालांकि, इनमें ये अंतर हैं:
- इन टेबल को ऐक्सेस करने के लिए, अन्य अनुमतियां भी चाहिए. इनसे डेटा पढ़ने के लिए, आपके ऐप्लिकेशन के पास 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 टेबल में सेव किया जा सकता है.
- नियमित सिंक करने के अलावा, सिंक करने वाले एडैप्टर को ट्रिगर करके, ज़्यादा डेटा हासिल किया जा सकता है. ऐसा तब किया जा सकता है, जब उपयोगकर्ता किसी संपर्क को देखने के लिए चुनता है. इससे, सिंक करने वाले आपके अडैप्टर को, संपर्क की हाई रिज़ॉल्यूशन वाली फ़ोटो और हाल ही में स्ट्रीम किए गए आइटम वापस पाने में मदद मिलती है.
- डिवाइस के संपर्क ऐप्लिकेशन और संपर्क सेवा देने वाली कंपनी के साथ सूचना रजिस्टर करके, किसी संपर्क को देखने पर आपको एक इंटेंट मिल सकता है. इसके बाद, अपनी सेवा से संपर्क की स्थिति को अपडेट किया जा सकता है. सिंक अडैप्टर की मदद से पूरा डेटा सिंक करने के मुकाबले, यह तरीका तेज़ हो सकता है और कम बैंडविड्थ का इस्तेमाल कर सकता है.
- उपयोगकर्ता, डिवाइस के संपर्क ऐप्लिकेशन में संपर्क देखकर, आपकी सोशल नेटवर्किंग सेवा में संपर्क जोड़ सकते हैं. "संपर्क को न्योता भेजें" सुविधा की मदद से, इसे चालू किया जा सकता है. इसे चालू करने के लिए, नेटवर्क में किसी मौजूदा संपर्क को जोड़ने वाली गतिविधि और डिवाइस के संपर्क ऐप्लिकेशन और संपर्क सेवा देने वाली कंपनी को आपके ऐप्लिकेशन की जानकारी देने वाली एक्सएमएल फ़ाइल का इस्तेमाल किया जाता है.
संपर्कों की जानकारी देने वाली सेवा के साथ स्ट्रीम आइटम को नियमित तौर पर सिंक करने का तरीका, अन्य सिंक करने के तरीकों जैसा ही है. सिंक करने के बारे में ज़्यादा जानने के लिए, संपर्कों की जानकारी देने वाली कंपनी के सिंक एडैप्टर सेक्शन देखें. सूचनाएं रजिस्टर करने और संपर्कों को न्योता भेजने के बारे में अगले दो सेक्शन में बताया गया है.
सोशल नेटवर्किंग साइटों पर वीडियो के व्यू मैनेज करने के लिए रजिस्टर करना
जब उपयोगकर्ता आपके सिंक अडैप्टर से मैनेज किए जा रहे किसी संपर्क को देखे, तब सूचनाएं पाने के लिए, अपने सिंक अडैप्टर को रजिस्टर करने के लिए:
-
अपने प्रोजेक्ट की
res/xml/
डायरेक्ट्री में,contacts.xml
नाम की फ़ाइल बनाएं. अगर आपके पास यह फ़ाइल पहले से मौजूद है, तो इस चरण को छोड़ा जा सकता है. -
इस फ़ाइल में, एलिमेंट
<ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android">
जोड़ें. अगर यह एलिमेंट पहले से मौजूद है, तो इस चरण को छोड़ा जा सकता है. -
ऐसी सेवा को रजिस्टर करने के लिए जिसकी सूचना तब दी जाती है, जब उपयोगकर्ता डिवाइस के संपर्क ऐप्लिकेशन में किसी संपर्क की जानकारी वाला पेज खोलता है, एलिमेंट में एट्रिब्यूट
viewContactNotifyService="serviceclass"
जोड़ें. यहांserviceclass
, उस सेवा का पूरी तरह से सही क्लासनेम है जिसे डिवाइस के संपर्क ऐप्लिकेशन से इंटेंट मिलना चाहिए. सूचना देने वाली सेवा के लिए,IntentService
को एक्सटेंड करने वाली क्लास का इस्तेमाल करें, ताकि सेवा को इंटेंट मिल सकें. इनकमिंग इंटेंट के डेटा में, उपयोगकर्ता के क्लिक किए गए रॉ कॉन्टैक्ट का कॉन्टेंट यूआरआई शामिल होता है. नोटिफ़ायर सेवा से, रॉ संपर्क के डेटा को अपडेट करने के लिए, अपने सिंक अडैप्टर को बांधें और फिर उसे कॉल करें.
उपयोगकर्ता किसी स्ट्रीम आइटम या फ़ोटो या दोनों पर क्लिक करने पर, कॉल की जाने वाली गतिविधि को रजिस्टर करने के लिए:
-
अपने प्रोजेक्ट की
res/xml/
डायरेक्ट्री में,contacts.xml
नाम की फ़ाइल बनाएं. अगर आपके पास यह फ़ाइल पहले से मौजूद है, तो इस चरण को छोड़ा जा सकता है. -
इस फ़ाइल में, एलिमेंट
<ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android">
जोड़ें. अगर यह एलिमेंट पहले से मौजूद है, तो इस चरण को छोड़ा जा सकता है. -
डिवाइस के संपर्क सूची वाले ऐप्लिकेशन में, स्ट्रीम आइटम पर उपयोगकर्ता के क्लिक को मैनेज करने के लिए, अपनी किसी गतिविधि को रजिस्टर करने के लिए, एलिमेंट में एट्रिब्यूट
viewStreamItemActivity="activityclass"
जोड़ें. यहांactivityclass
, उस गतिविधि का पूरी तरह से सही क्लास नाम है जिसे डिवाइस के संपर्क सूची वाले ऐप्लिकेशन से इंटेंट मिलना चाहिए. -
डिवाइस के संपर्क ऐप्लिकेशन में स्ट्रीम फ़ोटो पर उपयोगकर्ता के क्लिक करने की जानकारी को मैनेज करने के लिए, अपनी किसी गतिविधि को रजिस्टर करने के लिए एलिमेंट में
viewStreamItemPhotoActivity="activityclass"
एट्रिब्यूट जोड़ें. यहांactivityclass
, उस गतिविधि का पूरी तरह से सही क्लासनेम है जिसे डिवाइस के संपर्क ऐप्लिकेशन से इंटेंट मिलना चाहिए.
<ContactsAccountType>
एलिमेंट के बारे में ज़्यादा जानकारी,
सेक्शन <ContactsAccountType> एलिमेंट में दी गई है.
इनकमिंग इंटेंट में, उस आइटम या फ़ोटो का कॉन्टेंट यूआरआई होता है जिस पर उपयोगकर्ता ने क्लिक किया है. टेक्स्ट आइटम और फ़ोटो के लिए अलग-अलग गतिविधियां बनाने के लिए, एक ही फ़ाइल में दोनों एट्रिब्यूट का इस्तेमाल करें.
आपकी सोशल नेटवर्किंग सेवा से इंटरैक्ट करना
उपयोगकर्ताओं को आपकी सोशल नेटवर्किंग साइट पर किसी संपर्क को न्योता देने के लिए, डिवाइस के संपर्क ऐप्लिकेशन से बाहर निकलने की ज़रूरत नहीं होती. इसके बजाय, डिवाइस के संपर्क ऐप्लिकेशन से किसी संपर्क को अपनी किसी गतिविधि में शामिल होने का न्योता भेजा जा सकता है. इसका सेट अप करने के लिए:
-
अपने प्रोजेक्ट की
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
वैल्यू एक टेक्स्ट स्ट्रिंग होती है, जो डिवाइस के संपर्क ऐप्लिकेशन में कनेक्शन जोड़ें मेन्यू में दिखती है.
ध्यान दें: ContactsSource
, ContactsAccountType
के लिए इस्तेमाल नहीं किया जाने वाला टैग है.
contacts.xml का रेफ़रंस
contacts.xml
फ़ाइल में ऐसे एक्सएमएल एलिमेंट होते हैं जो आपके सिंक अडैप्टर और ऐप्लिकेशन के इंटरैक्शन को कंट्रोल करते हैं. साथ ही, ये संपर्क ऐप्लिकेशन और संपर्क सेवा देने वाली कंपनी के साथ भी इंटरैक्ट करते हैं. इन एलिमेंट के बारे में, नीचे दिए गए सेक्शन में बताया गया है.
<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
- आपके ऐप्लिकेशन में मौजूद किसी ऐसी गतिविधि की पूरी तरह क्वालिफ़ाइड क्लास का नाम जो ग्रुप की जानकारी दिखा सकती है. जब उपयोगकर्ता डिवाइस के संपर्क ऐप्लिकेशन में ग्रुप लेबल पर क्लिक करता है, तो इस गतिविधि के लिए यूज़र इंटरफ़ेस (यूआई) दिखता है.
viewGroupActionLabel
-
वह लेबल जो संपर्कों के ऐप्लिकेशन में, यूज़र इंटरफ़ेस (यूआई) कंट्रोल के लिए दिखता है. इससे उपयोगकर्ता को आपके ऐप्लिकेशन में ग्रुप देखने की अनुमति मिलती है.
इस एट्रिब्यूट के लिए, स्ट्रिंग रिसॉर्स आइडेंटिफ़ायर का इस्तेमाल किया जा सकता है.
viewStreamItemActivity
- आपके ऐप्लिकेशन में मौजूद किसी ऐक्टिविटी का पूरा नाम, जिसे डिवाइस का संपर्क ऐप्लिकेशन तब लॉन्च करता है, जब उपयोगकर्ता किसी रॉ संपर्क के लिए स्ट्रीम आइटम पर क्लिक करता है.
viewStreamItemPhotoActivity
- आपके ऐप्लिकेशन में मौजूद किसी गतिविधि का फ़ुल-क्वालिफ़ाइड क्लास नेम. जब उपयोगकर्ता किसी रॉ संपर्क के लिए स्ट्रीम आइटम में मौजूद फ़ोटो पर क्लिक करता है, तो डिवाइस का संपर्क ऐप्लिकेशन इसे लॉन्च करता है.
<ContactsDataKind> एलिमेंट
<ContactsDataKind>
एलिमेंट, संपर्क ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) में आपके ऐप्लिकेशन के कस्टम डेटा की पंक्तियों के डिसप्ले को कंट्रोल करता है. इसका सिंटैक्स यह है:
<ContactsDataKind android:mimeType="MIMEtype" android:icon="icon_resources" android:summaryColumn="column_name" android:detailColumn="column_name">
इसमें शामिल है:
<ContactsAccountType>
जानकारी:
इस एलिमेंट का इस्तेमाल करके, Contacts ऐप्लिकेशन को कस्टम डेटा लाइन का कॉन्टेंट, किसी रॉ संपर्क की जानकारी के हिस्से के तौर पर दिखाने के लिए कहें. <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
भी देखें.
संपर्क सूची उपलब्ध कराने वाली सेवा की अन्य सुविधाएं
पिछले सेक्शन में बताई गई मुख्य सुविधाओं के अलावा, संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी, संपर्कों के डेटा के साथ काम करने के लिए ये काम की सुविधाएं भी उपलब्ध कराती है:
- संपर्क ग्रुप
- फ़ोटो को बेहतर बनाने के लिए सुविधाएं
संपर्क ग्रुप
संपर्कों की जानकारी देने वाली कंपनी, मिलते-जुलते संपर्कों के कलेक्शन को ग्रुप डेटा के साथ लेबल कर सकती है. हालांकि, ऐसा करना ज़रूरी नहीं है. अगर किसी उपयोगकर्ता खाते से जुड़े सर्वर को ग्रुप मैनेज करने हैं, तो खाते के टाइप के लिए सिंक अडैप्टर को ग्रुप का डेटा, संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी और सर्वर के बीच ट्रांसफ़र करना चाहिए. जब उपयोगकर्ता किसी नए संपर्क को
सर्वर में जोड़ते हैं और फिर इस संपर्क को किसी नए ग्रुप में डालते हैं, तो सिंक करने वाले अडैप्टर को ContactsContract.Groups
टेबल में नया ग्रुप जोड़ना होगा. किसी रॉ संपर्क के ग्रुप, ContactsContract.Data
टेबल में सेव किए जाते हैं. इसके लिए, ContactsContract.CommonDataKinds.GroupMembership
MIME टाइप का इस्तेमाल किया जाता है.
अगर आपको ऐसा सिंक अडैप्टर डिज़ाइन करना है जो सर्वर से रॉ संपर्क डेटा को कॉन्टैक्ट की सेवा देने वाली कंपनी के पास जोड़ेगा और ग्रुप का इस्तेमाल नहीं किया जा रहा है, तो आपको कॉन्टैक्ट की सेवा देने वाली कंपनी को यह बताना होगा कि आपका डेटा दिखे. जब कोई उपयोगकर्ता डिवाइस में कोई खाता जोड़ता है, तो उस समय लागू होने वाले कोड में, ContactsContract.Settings
लाइन को अपडेट करें. यह लाइन, संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी, खाते के लिए जोड़ती है. इस लाइन में, Settings.UNGROUPED_VISIBLE
कॉलम की वैल्यू को 1 पर सेट करें. ऐसा करने पर, संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी, आपके संपर्कों का डेटा हमेशा दिखाएगी. भले ही, आपने ग्रुप का इस्तेमाल न किया हो.
संपर्क सूची में शामिल लोगों की फ़ोटो
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 टेबल में सेव किया जाता है. इस टेबल के बारे में ज़्यादा जानकारी, सोशल स्ट्रीम की फ़ोटो सेक्शन में दी गई है.