संपर्क उपलब्ध कराने वाला, 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
टेबल के अहम कॉलम
पहली टेबल में दिए गए हैं. कृपया टेबल के बाद दिए गए नोट पढ़ें:
कॉलम का नाम | इस्तेमाल करें | नोट |
---|---|---|
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
तक के चार सामान्य
कॉलम SYNC1
का इस्तेमाल किया जा सकता है. इनका इस्तेमाल सिर्फ़ सिंक अडैप्टर को करना चाहिए. कॉलम के नाम के सामान्य कॉन्सटेंट हमेशा काम करते हैं, चाहे पंक्ति में किसी भी तरह का
डेटा हो.
DATA1
कॉलम को इंडेक्स किया गया. संपर्कों की जानकारी देने वाली सेवा देने वाली कंपनी, इस कॉलम का इस्तेमाल हमेशा उस डेटा के लिए करती है जो क्वेरी का सबसे ज़्यादा टारगेट होता है. उदाहरण के लिए,
ईमेल लाइन में, इस कॉलम में असल ईमेल पता होता है.
नियमों के हिसाब से, DATA15
कॉलम को बाइनरी लार्ज ऑब्जेक्ट
(बीएलओबी) डेटा को सेव करने के लिए रिज़र्व रखा जाता है. जैसे, फ़ोटो थंबनेल.
टाइप के हिसाब से कॉलम के नाम
किसी खास तरह की पंक्ति के कॉलम के साथ काम करने के लिए, संपर्क सेवा देने वाली कंपनी, 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
पंक्तियों को क्वेरी किया जाता है, तो आपको एक Cursor
मिलता है, जिसमें हर ContactsContract.CommonDataKinds.Email
लाइन के लिए एक पंक्ति होती है.
इकाइयां, क्वेरी को आसान बनाती हैं. इकाई का इस्तेमाल करके, किसी एक संपर्क या रॉ संपर्क का सारा संपर्क डेटा एक साथ पाया जा सकता है. इसके लिए, आईडी पाने के लिए पहले पैरंट टेबल और फिर उस आईडी के साथ चाइल्ड टेबल को क्वेरी करने की ज़रूरत नहीं होती. साथ ही, संपर्कों की जानकारी देने वाली कंपनी, किसी इकाई के लिए एक ही लेन-देन में क्वेरी को प्रोसेस करती है. इससे यह पक्का होता है कि वापस पाया गया डेटा, इंटरनल तौर पर एक जैसा हो.
ध्यान दें: किसी इकाई में आम तौर पर, पैरंट और चाइल्ड टेबल के सभी कॉलम
शामिल नहीं होते. अगर किसी ऐसे कॉलम के नाम का इस्तेमाल किया जाता है जो इकाई के लिए कॉलम के नाम की सूची में मौजूद नहीं है, तो आपको 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()
को कॉल करके, कॉन्टैक्ट प्रोवाइडर में "बैच मोड" में डेटा डालना, अपडेट करना, और मिटाना चाहिए. संपर्क सेवा देने वाली कंपनी, 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
ऑब्जेक्ट के लिए,withValue()
को कॉल करें, ताकि आपVERSION
कॉलम की तुलना उस वर्शन नंबर से कर सकें जिसे आपने अभी-अभी हासिल किया है. -
उसी
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
|
यह इंटेंट, हमेशा संपर्क ऐप्लिकेशन की पिकर स्क्रीन दिखाता है. बदलाव करने के लिए, उपयोगकर्ता
कोई संपर्क चुन सकता है या नया संपर्क जोड़ सकता है. उपयोगकर्ता की पसंद के आधार पर, बदलाव या जोड़ें स्क्रीन दिखती है. इसके अलावा, इंटेंट में पास किया गया अतिरिक्त डेटा भी दिखता है. अगर आपका ऐप्लिकेशन ईमेल या फ़ोन नंबर जैसे संपर्क डेटा दिखाता है, तो उपयोगकर्ता को किसी मौजूदा संपर्क में डेटा जोड़ने की अनुमति देने के लिए, इस इंटेंट का इस्तेमाल करें.
संपर्क,
ध्यान दें: इस इंटेंट की अतिरिक्त चीज़ों में नाम की वैल्यू भेजने की ज़रूरत नहीं है, क्योंकि उपयोगकर्ता हमेशा मौजूदा नाम चुनता है या नया नाम जोड़ता है. इसके अलावा, अगर उपयोगकर्ता को कोई नाम भेजा जाता है और वह बदलाव करने का विकल्प चुनता है, तो संपर्क ऐप्लिकेशन वह नाम दिखाएगा जो आपने भेजा है. साथ ही, पिछली वैल्यू को ओवरराइट कर दिया जाएगा. अगर उपयोगकर्ता को इसकी जानकारी नहीं होती और वह बदलाव को सेव कर देता है, तो पुरानी वैल्यू मिट जाती है. |
डिवाइस के संपर्क ऐप्लिकेशन में, किसी रॉ संपर्क या उसके किसी भी डेटा को जान-बूझकर मिटाया नहीं जा सकता. इसके बजाय, रॉ संपर्क मिटाने के लिए, 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
वैल्यू के लिए इस्तेमाल किए जाते हैं. - इन कॉन्स्टेंट का इस्तेमाल करने से, गड़बड़ियों से बचा जा सकता है. अगर कोई भी कॉन्स्टेंट इस्तेमाल नहीं किया जा सकता, तो आपको कंपाइलर के साथ मिलने वाली चेतावनियों के बारे में भी सूचना दी जाएगी.
कस्टम डेटा लाइनें
अपने कस्टम MIME टाइप बनाकर और उनका इस्तेमाल करके, 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
कॉम्पोनेंट, जो सिंक अडैप्टर से लिंक करने के लिए सिस्टम से मिले अनुरोधों का जवाब देता है. -
जब सिस्टम को सिंक करना होता है, तो वह सेवा के
onBind()
तरीके को कॉल करता है, ताकि सिंक अडैप्टर के लिएIBinder
लिया जा सके. इससे सिस्टम को अडैप्टर के तरीकों से कॉल को क्रॉस-प्रोसेस करने की अनुमति मिलती है. -
असल सिंक अडैप्टर, जिसे
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.ContactsConcontent.StreamItemकॉलम#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.ContactsConडेट.StreamItemColumn#RES_ICON, android.provider.ContactsConcontact.StreamItemColumn#RES_LABEL, और android.provider.ContactsConcontact.Stream माहौलColumn#RES_PACKAGE का इस्तेमाल करें.
सिंक अडैप्टर के खास इस्तेमाल के लिए, android.provider.ContactsConcontact.Stream कोने वाले टेबल में android.provider.ContactsConcontent.Stream मौजूदकॉलम#SYNC1 से android.provider.ContactsContrack.Stream लगेColumn#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.Contact.StreamItemPhotosColumn#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.ContactsConcontact.Stream अंतिम#CONTENT_LIMIT_uri. कॉन्टेंट यूआरआई के अलावा, सभी आर्ग्युमेंट को
null
पर सेट किया जा सकता है. क्वेरी, एक कॉलम वाले कर्सर को दिखाती है. इसमें एक पंक्ति होती है, जिसका नाम android.provider.ContactsContract.StreamItems#MAX_ITEMS होता है.
क्लास android.provider.ContactsContracker.Stream मौजूद.StreamItemPhotos की एक सब-टेबल के बारे में जानकारी देता है. इस सब-टेबल में, android.provider.ContactsContrack.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 टेबल में सेव किया जाता है. इस टेबल के बारे में ज़्यादा जानकारी, सोशल स्ट्रीम की फ़ोटो सेक्शन में दी गई है.