कॉन्टेंट देने वाला, एक ही जगह पर डेटा स्टोर करने की जगह के ऐक्सेस को मैनेज करता है. सेवा देने वाली कंपनी एक ऐसे Android ऐप्लिकेशन का हिस्सा है जो अक्सर काम करने के लिए अपना खुद का यूज़र इंटरफ़ेस (यूआई) उपलब्ध कराता है के लिए इस्तेमाल किया जा सकता है. हालांकि, कॉन्टेंट देने वालों को मुख्य रूप से अन्य ऐसे ऐप्लिकेशन जो प्रोवाइडर के क्लाइंट ऑब्जेक्ट का इस्तेमाल करके, सेवा देने वाली कंपनी को ऐक्सेस करते हैं. सेवा देने वाली कंपनियों और लोगों को साथ में रखकर, और सेवा देने वाले क्लाइंट, डेटा को एक जैसा और स्टैंडर्ड इंटरफ़ेस देते हैं. यह इंटरफ़ेस इंटरप्रोसेस कम्यूनिकेशन और सुरक्षित डेटा ऐक्सेस है.
आम तौर पर, इन दो में से किसी एक स्थिति में कॉन्टेंट देने वालों के साथ काम किया जाता है: लागू करना किसी अन्य ऐप्लिकेशन में मौजूदा कॉन्टेंट प्रोवाइडर को ऐक्सेस करने या किसी नए वर्शन को बनाने के लिए अन्य ऐप्लिकेशन के साथ डेटा शेयर करने के लिए आपके ऐप्लिकेशन में एक नया सामग्री कंपनी है.
यह पेज मौजूदा कॉन्टेंट देने वालों के साथ काम करने से जुड़ी बुनियादी बातें कवर करती हैं. लागू करने के बारे में जानने के लिए अपने ऐप्लिकेशन में कॉन्टेंट उपलब्ध कराने वालों के लिए, कॉन्टेंट देने वाला कोई प्लैटफ़ॉर्म बनाएं.
यह विषय इन चीज़ों के बारे में बताता है:
- कॉन्टेंट देने वाले लोग कैसे काम करते हैं.
- वह एपीआई जिसका इस्तेमाल, कॉन्टेंट देने वाले से डेटा वापस पाने के लिए किया जाता है.
- वह एपीआई जिसका इस्तेमाल, कॉन्टेंट देने वाले किसी ऐप्लिकेशन में डेटा डालने, उसे अपडेट करने या मिटाने के लिए किया जाता है.
- एपीआई की अन्य सुविधाएं, जो सेवा देने वाली कंपनियों के साथ काम करने में मदद करती हैं.
खास जानकारी
कॉन्टेंट देने वाला, बाहरी ऐप्लिकेशन को डेटा को एक या एक से ज़्यादा ऐसी टेबल के तौर पर दिखाता है जिन्हें ये मिलते-जुलते डेटाबेस में मौजूद टेबल से मिलते-जुलते हैं. पंक्ति किसी तरह का एक उदाहरण दिखाती है डेटा होता है जिसे सेवा देने वाली कंपनी इकट्ठा करती है और पंक्ति का हर कॉलम किसी इंस्टेंस के लिए इकट्ठा किया गया डेटा.
कॉन्टेंट उपलब्ध कराने वाला, आपके ऐप्लिकेशन में डेटा स्टोरेज लेयर के ऐक्सेस का अलग-अलग एपीआई और कॉम्पोनेंट की संख्या डालें. जैसा कि पहली इमेज में दिखाया गया है, इनमें ये चीज़ें शामिल हैं:
- अन्य ऐप्लिकेशन के साथ अपने ऐप्लिकेशन के डेटा का ऐक्सेस शेयर करना
- किसी विजेट को डेटा भेजना
- खोज के ज़रिए आपके ऐप्लिकेशन के लिए कस्टम खोज सुझाव लौटाना
SearchRecentSuggestionsProvider
का इस्तेमाल करने वाला फ़्रेमवर्क - को लागू करने के
AbstractThreadedSyncAdapter
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है CursorLoader
का इस्तेमाल करके, आपके यूज़र इंटरफ़ेस (यूआई) में डेटा लोड करना
![कॉन्टेंट देने वाले और दूसरे कॉम्पोनेंट के बीच संबंध.](https://developer.android.com/static/guide/topics/providers/images/content-provider-tech-stack.png?authuser=9&hl=hi)
पहला डायग्राम. कॉन्टेंट देने वाले के नेटवर्क और अन्य कॉम्पोनेंट के बीच का संबंध.
सेवा देने वाली कंपनी को ऐक्सेस करना
जब आपको किसी कॉन्टेंट देने वाले का डेटा ऐक्सेस करना हो, तो
आपके ऐप्लिकेशन में ContentResolver
ऑब्जेक्ट
सेवा देने वाली कंपनी से क्लाइंट के तौर पर संपर्क करने के लिए, Context
. कॉन्टेंट बनाने
ContentResolver
ऑब्जेक्ट, प्रोवाइडर ऑब्जेक्ट के साथ कम्यूनिकेट करता है,
ContentProvider
को लागू करने वाली क्लास का इंस्टेंस.
सेवा देने वाली कंपनी
ऑब्जेक्ट को क्लाइंट से डेटा अनुरोध मिलता है, वह अनुरोध की गई कार्रवाई करता है, और
नतीजे. इस ऑब्जेक्ट में ऐसे तरीके हैं जो प्रोवाइडर ऑब्जेक्ट में एक जैसे नाम वाले तरीकों को कॉल करते हैं,
ContentProvider
की कंक्रीट सब-क्लास का एक इंस्टेंस. कॉन्टेंट बनाने
ContentResolver
तरीके बुनियादी जानकारी देते हैं
"सीआरयूडी" परसिस्टेंट स्टोरेज के फ़ंक्शन (बनाएं, वापस पाएं, अपडेट करें, और मिटाएं).
आपके यूज़र इंटरफ़ेस (यूआई) से ContentProvider
को ऐक्सेस करने के लिए, सामान्य पैटर्न
बैकग्राउंड में एसिंक्रोनस क्वेरी चलाने के लिए CursorLoader
. कॉन्टेंट बनाने
आपके यूज़र इंटरफ़ेस (यूआई) में Activity
या Fragment
CursorLoader
जोड़कर क्वेरी का जवाब दिया जाता है, जो
ContentResolver
का इस्तेमाल करके ContentProvider
.
इससे, क्वेरी के दौरान भी उपयोगकर्ता को यूज़र इंटरफ़ेस (यूआई) दिखता है. यह पैटर्न में कई अलग-अलग ऑब्जेक्ट के इंटरैक्शन के साथ-साथ, स्टोरेज मैकेनिज़्म, जैसा कि दूसरी इमेज में दिखाया गया है.
![ContentProvider, अन्य क्लास, और स्टोरेज के बीच इंटरैक्शन.](https://developer.android.com/static/guide/topics/providers/images/content-provider-interaction.png?authuser=9&hl=hi)
दूसरा डायग्राम. ContentProvider
, अन्य क्लास, और स्टोरेज के बीच इंटरैक्शन.
ध्यान दें: सेवा देने वाली किसी कंपनी का ऐक्सेस पाने के लिए, आपके ऐप्लिकेशन को आम तौर पर अनुमतियां शामिल हैं. इस डेवलपमेंट पैटर्न के बारे में ज़्यादा जानकारी यहां दी गई है कॉन्टेंट देने वाले के लिए अनुमतियां सेक्शन.
Android प्लैटफ़ॉर्म में पहले से मौजूद सेवा देने वालों में से एक है यूज़र डिक्शनरी प्रोवाइडर, जो उन गैर-मानक शब्दों को संग्रहित करता है, जिन्हें उपयोगकर्ता रखना चाहता है. टेबल 1 में बताया गया है कि क्या डेटा इस तरह से दिख सकता है:
पहली टेबल: उपयोगकर्ता डिक्शनरी की सैंपल टेबल.
शब्दों वाले गेम | ऐप्स id | फ़्रीक्वेंसी | स्थान-भाषा | आईडी |
---|---|---|---|---|
mapreduce |
उपयोगकर्ता1 | 100 | en_US | 1 |
precompiler |
उपयोगकर्ता14 | 200 | fr_FR | 2 |
applet |
उपयोगकर्ता2 | 225 | fr_CA | 3 |
const |
उपयोगकर्ता1 | 255 | pt_BR | 4 |
int |
उपयोगकर्ता5 | 100 | hi | 5 |
टेबल 1 की हर पंक्ति में एक ऐसे शब्द का उदाहरण दिया गया है जो
जो स्टैंडर्ड डिक्शनरी में मिलती हैं. हर कॉलम उस शब्द के लिए डेटा का एक हिस्सा दिखाता है, जैसे कि
वह स्थान-भाषा जिसमें यह पहली बार मिला था. कॉलम हेडर, कॉलम के नाम होते हैं. ये नाम यहां सेव किए जाते हैं
. उदाहरण के लिए, किसी पंक्ति की स्थान-भाषा देखने के लिए, उसके locale
कॉलम को देखें. इसके लिए
यह सेवा देने वाली कंपनी, _ID
कॉलम एक प्राथमिक कुंजी कॉलम के तौर पर काम करता है,
सेवा देने वाली कंपनी अपने-आप मैनेज करती है.
उपयोगकर्ता डिक्शनरी की सेवा देने वाली कंपनी से शब्दों और उनकी स्थान-भाषाओं की सूची पाने के लिए,
आप ContentResolver.query()
को कॉल करते हैं.
query()
तरीका
ContentProvider.query()
तरीका
उपयोगकर्ता डिक्शनरी की सेवा देने वाली कंपनी. कोड की ये लाइनें,
ContentResolver.query()
कॉल:
Kotlin
// Queries the UserDictionary and returns results cursor = contentResolver.query( UserDictionary.Words.CONTENT_URI, // The content URI of the words table projection, // The columns to return for each row selectionClause, // Selection criteria selectionArgs.toTypedArray(), // Selection criteria sortOrder // The sort order for the returned rows )
Java
// Queries the UserDictionary and returns results cursor = getContentResolver().query( UserDictionary.Words.CONTENT_URI, // The content URI of the words table projection, // The columns to return for each row selectionClause, // Selection criteria selectionArgs, // Selection criteria sortOrder); // The sort order for the returned rows
दूसरी टेबल में दिखाया गया है कि
query(Uri,projection,selection,selectionArgs,sortOrder)
का मिलान SQL SELECT स्टेटमेंट से होता है:
टेबल 2: एसक्यूएल क्वेरी की तुलना में query()
.
query() आर्ग्युमेंट |
कीवर्ड/पैरामीटर चुनें | नोट |
---|---|---|
Uri |
FROM table_name |
Uri , table_name नाम की सेवा देने वाली कंपनी की टेबल पर मैप करता है. |
projection |
col,col,col,... |
projection , कॉलम का कलेक्शन है जो हर लाइन में शामिल होता है
वापस लाया गया.
|
selection |
WHERE col = value |
selection पंक्तियों को चुनने के मानदंड के बारे में बताता है. |
selectionArgs |
कोई सटीक मिलता-जुलता डेटा नहीं है. चुनने के आर्ग्युमेंट, इसमें ? प्लेसहोल्डर की जगह लेंगे
चुनने का क्लॉज़.
|
|
sortOrder |
ORDER BY col,col,... |
sortOrder से पता चलता है कि दिखाई जाने वाली पंक्तियों में कौनसी पंक्तियां दिखती हैं
Cursor .
|
कॉन्टेंट यूआरआई
कॉन्टेंट यूआरआई एक यूआरआई है, जिससे सेवा देने वाली कंपनी में डेटा की पहचान की जाती है. कॉन्टेंट यूआरआई इसमें पूरी कंपनी का सिम्बॉलिक नाम—उसकी प्राधिकारी—और एक टेबल पर ले जाने वाला नाम—पाथ. आपके कॉल करने पर किसी प्रोवाइडर में टेबल ऐक्सेस करने का क्लाइंट तरीका है, टेबल का कॉन्टेंट यूआरआई इनमें से एक है तर्क के साथ इस्तेमाल करें.
कोड की पिछली पंक्तियों में, कॉन्स्टेंट
CONTENT_URI
में इसका कॉन्टेंट यूआरआई शामिल है
यूज़र डिक्शनरी प्रोवाइडर की Words
टेबल. ContentResolver
ऑब्जेक्ट, यूआरआई की जानकारी को पार्स करता है और इसका इस्तेमाल करके, सेवा देने वाली कंपनी का समाधान होता है
सर्टिफ़िकेट देने वाली संस्था की सिस्टम टेबल से, सर्टिफ़िकेट देने वाली कंपनी के डेटा की तुलना करना. कॉन्टेंट बनाने
इसके बाद ContentResolver
, क्वेरी आर्ग्युमेंट को सही
कंपनी.
ContentProvider
कॉन्टेंट यूआरआई के पाथ वाले हिस्से का इस्तेमाल करके
ऐक्सेस करने के लिए तालिका. आम तौर पर, सेवा देने वाली कंपनी के पास हर उस टेबल के लिए एक पाथ होता है जिसे वह दिखाती है.
कोड की पिछली लाइनों में, Words
टेबल का पूरा यूआरआई इस तरह है:
content://user_dictionary/words
content://
स्ट्रिंग, स्कीम होती है, जो हमेशा मौजूद होती है और इसकी पहचान कॉन्टेंट यूआरआई के तौर पर करता है.user_dictionary
स्ट्रिंग, सेवा देने वाली कंपनी का अधिकार होती है.words
स्ट्रिंग, टेबल का पाथ होती है.
कई कंपनियां आपको टेबल में आईडी वैल्यू जोड़कर, एक पंक्ति ऐक्सेस करने की सुविधा देती हैं
करके यूआरआई के आखिर में रखें. उदाहरण के लिए, किसी पंक्ति को वापस पाने के लिए जिसका _ID
यूज़र डिक्शनरी प्रोवाइडर की ओर से 4
, आप इस कॉन्टेंट यूआरआई का इस्तेमाल कर सकते हैं:
Kotlin
val singleUri: Uri = ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI, 4)
Java
Uri singleUri = ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI,4);
आम तौर पर, आईडी वैल्यू का इस्तेमाल तब किया जाता है, जब पंक्तियों का सेट फिर से पाने के बाद, आपको पंक्तियों को अपडेट करना या मिटाना हो उनमें से एक है.
ध्यान दें: Uri
और Uri.Builder
क्लास
स्ट्रिंग से अच्छी तरह से बने यूआरआई ऑब्जेक्ट बनाने के लिए आसान तरीके शामिल हैं. कॉन्टेंट बनाने
ContentUris
क्लास में, आईडी वैल्यू को आसानी से जोड़ने के तरीके शामिल हैं
यूआरआई. पिछला स्निपेट, यूज़र डिक्शनरी प्रोवाइडर के कॉन्टेंट यूआरआई में एक आईडी जोड़ने के लिए withAppendedId()
का इस्तेमाल करता है.
सेवा देने वाली कंपनी से डेटा वापस पाएं
इस सेक्शन में बताया गया है कि यूज़र डिक्शनरी प्रोवाइडर का इस्तेमाल करके, सेवा देने वाली किसी कंपनी का डेटा कैसे वापस पाया जा सकता है पर जाएं.
साफ़ तौर पर कहा जाए, तो इस सेक्शन में मौजूद कोड स्निपेट को
यूज़र इंटरफ़ेस (यूआई) थ्रेड पर ContentResolver.query()
. तय सीमा में
हालांकि, असल कोड किसी अलग थ्रेड पर एसिंक्रोनस तरीके से क्वेरी करता है. आप
CursorLoader
क्लास का इस्तेमाल करें. इसके बारे में जानकारी दी गई है
लोडर गाइड. साथ ही, कोड की लाइनें सिर्फ़ स्निपेट होती हैं. पूरी जानकारी नहीं दिखती
का इस्तेमाल करें.
किसी कंपनी से डेटा वापस पाने के लिए, यह तरीका अपनाएं:
- सेवा देने वाली कंपनी के लिए, पढ़ने का ऐक्सेस देने का अनुरोध करें.
- वह कोड तय करें जो सेवा देने वाली कंपनी को क्वेरी भेजता है.
पढ़ने के ऐक्सेस का अनुरोध करें
किसी कंपनी से डेटा वापस पाने के लिए, आपके ऐप्लिकेशन को
कंपनी. रनटाइम के दौरान, इस अनुमति का अनुरोध नहीं किया जा सकता. इसके बजाय, आपको वह
आपको अपने मेनिफ़ेस्ट में यह अनुमति चाहिए, तो
<uses-permission>
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
एलिमेंट और अनुमति का सटीक नाम
कंपनी.
जब आप अपने मेनिफ़ेस्ट में इस एलिमेंट को शामिल करते हैं, तो इसका अनुरोध किया जाता है अनुमति नहीं है. जब उपयोगकर्ता आपका ऐप्लिकेशन इंस्टॉल करते हैं, तो वे साफ़ तौर पर इस अनुरोध को स्वीकार करना ज़रूरी है.
ऐप्लिकेशन का इस्तेमाल करने वाली कंपनी के लिए, पढ़ने का ऐक्सेस देने की अनुमति का सही नाम जानने के लिए का इस्तेमाल करते हुए ऐक्सेस की अनुमतियों का इस्तेमाल करने के लिए, दस्तावेज़.
ऐक्सेस देने वाली कंपनियों को ऐक्सेस करने में अनुमतियों की भूमिका के बारे में यहां ज़्यादा बताया गया है कॉन्टेंट देने वाले के लिए अनुमतियां सेक्शन.
उपयोगकर्ता डिक्शनरी की सेवा देने वाली कंपनी, अनुमति के बारे में बताती है
android.permission.READ_USER_DICTIONARY
की मेनिफ़ेस्ट फ़ाइल में दी गई है, इसलिए
जो ऐप्लिकेशन सेवा देने वाली कंपनी से पढ़ना चाहता है उसे इस अनुमति का अनुरोध करना होगा.
क्वेरी बनाएं
सेवा देने वाली कंपनी से डेटा वापस पाने के लिए अगला कदम है क्वेरी बनाना. नीचे दिया गया स्निपेट उपयोगकर्ता डिक्शनरी की सेवा देने वाली कंपनी को ऐक्सेस करने के लिए, कुछ वैरिएबल के बारे में बताता है:
Kotlin
// A "projection" defines the columns that are returned for each row private val mProjection: Array<String> = arrayOf( UserDictionary.Words._ID, // Contract class constant for the _ID column name UserDictionary.Words.WORD, // Contract class constant for the word column name UserDictionary.Words.LOCALE // Contract class constant for the locale column name ) // Defines a string to contain the selection clause private var selectionClause: String? = null // Declares an array to contain selection arguments private lateinit var selectionArgs: Array<String>
Java
// A "projection" defines the columns that are returned for each row String[] mProjection = { UserDictionary.Words._ID, // Contract class constant for the _ID column name UserDictionary.Words.WORD, // Contract class constant for the word column name UserDictionary.Words.LOCALE // Contract class constant for the locale column name }; // Defines a string to contain the selection clause String selectionClause = null; // Initializes an array to contain selection arguments String[] selectionArgs = {""};
अगले स्निपेट में,
उपयोगकर्ता डिक्शनरी का इस्तेमाल करने वाला ContentResolver.query()
उदाहरण के लिए, प्रोवाइडर. सेवा देने वाली कंपनी की क्लाइंट क्वेरी, SQL क्वेरी की तरह ही होती है और इसमें
लौटाने के लिए कॉलम का सेट, चुनने के लिए ज़रूरी शर्तों का सेट, और क्रम से लगाने का तरीका.
क्वेरी से मिलने वाले कॉलम के सेट को प्रोजेक्शन कहा जाता है और
वैरिएबल mProjection
है.
जिस एक्सप्रेशन को वापस लाना है उसे एक सेलेक्शन क्लॉज़ में बांटा जाता है और
चुनने के लिए आर्ग्युमेंट. सेलेक्शन क्लॉज़, लॉजिकल और बूलियन एक्सप्रेशन का कॉम्बिनेशन होता है,
कॉलम नाम, और मान. वैरिएबल mSelectionClause
है. अगर आप
वैल्यू के बजाय, बदले जा सकने वाले पैरामीटर ?
का इस्तेमाल करने पर, क्वेरी का तरीका वैल्यू को हासिल करता है
को चुनने के लिए आर्ग्युमेंट के कलेक्शन से निकालें. यह वैरिएबल mSelectionArgs
है.
अगले स्निपेट में, अगर उपयोगकर्ता कोई शब्द नहीं डालता है, तो सेलेक्शन क्लॉज़ इस पर सेट हो जाता है
null
और क्वेरी, प्रोवाइडर के सभी शब्द दिखाती है. अगर उपयोगकर्ता यह जानकारी डालता है
कोई शब्द है, तो सेलेक्शन क्लॉज़ UserDictionary.Words.WORD + " = ?"
पर सेट है और
चुने गए आर्ग्युमेंट की अरे का पहला एलिमेंट, उपयोगकर्ता के डाले गए शब्द पर सेट होता है.
Kotlin
/* * This declares a String array to contain the selection arguments. */ private lateinit var selectionArgs: Array<String> // Gets a word from the UI searchString = searchWord.text.toString() // Insert code here to check for invalid or malicious input // If the word is the empty string, gets everything selectionArgs = searchString?.takeIf { it.isNotEmpty() }?.let { selectionClause = "${UserDictionary.Words.WORD} = ?" arrayOf(it) } ?: run { selectionClause = null emptyArray<String>() } // Does a query against the table and returns a Cursor object mCursor = contentResolver.query( UserDictionary.Words.CONTENT_URI, // The content URI of the words table projection, // The columns to return for each row selectionClause, // Either null or the word the user entered selectionArgs, // Either empty or the string the user entered sortOrder // The sort order for the returned rows ) // Some providers return null if an error occurs, others throw an exception when (mCursor?.count) { null -> { /* * Insert code here to handle the error. Be sure not to use the cursor! * You might want to call android.util.Log.e() to log this error. */ } 0 -> { /* * Insert code here to notify the user that the search is unsuccessful. This isn't * necessarily an error. You might want to offer the user the option to insert a new * row, or re-type the search term. */ } else -> { // Insert code here to do something with the results } }
Java
/* * This defines a one-element String array to contain the selection argument. */ String[] selectionArgs = {""}; // Gets a word from the UI searchString = searchWord.getText().toString(); // Remember to insert code here to check for invalid or malicious input // If the word is the empty string, gets everything if (TextUtils.isEmpty(searchString)) { // Setting the selection clause to null returns all words selectionClause = null; selectionArgs[0] = ""; } else { // Constructs a selection clause that matches the word that the user entered selectionClause = UserDictionary.Words.WORD + " = ?"; // Moves the user's input string to the selection arguments selectionArgs[0] = searchString; } // Does a query against the table and returns a Cursor object mCursor = getContentResolver().query( UserDictionary.Words.CONTENT_URI, // The content URI of the words table projection, // The columns to return for each row selectionClause, // Either null or the word the user entered selectionArgs, // Either empty or the string the user entered sortOrder); // The sort order for the returned rows // Some providers return null if an error occurs, others throw an exception if (null == mCursor) { /* * Insert code here to handle the error. Be sure not to use the cursor! You can * call android.util.Log.e() to log this error. * */ // If the Cursor is empty, the provider found no matches } else if (mCursor.getCount() < 1) { /* * Insert code here to notify the user that the search is unsuccessful. This isn't necessarily * an error. You can offer the user the option to insert a new row, or re-type the * search term. */ } else { // Insert code here to do something with the results }
यह क्वेरी इस एसक्यूएल स्टेटमेंट की तरह है:
SELECT _ID, word, locale FROM words WHERE word = <userinput> ORDER BY word ASC;
इस SQL स्टेटमेंट में, कॉन्ट्रैक्ट क्लास कॉन्सटेंट के बजाय, कॉलम के असल नाम इस्तेमाल किए गए हैं.
नुकसान पहुंचाने वाले इनपुट से सुरक्षित रखें
अगर कॉन्टेंट देने वाले की ओर से मैनेज किया जाने वाला डेटा, SQL डेटाबेस में मौजूद है, तो इसमें बाहरी गैर-भरोसेमंद डेटा भी शामिल है रॉ एसक्यूएल स्टेटमेंट में मौजूद डेटा से एसक्यूएल इंजेक्शन बन सकता है.
इस चुने गए क्लॉज़ का इस्तेमाल करें:
Kotlin
// Constructs a selection clause by concatenating the user's input to the column name var selectionClause = "var = $mUserInput"
Java
// Constructs a selection clause by concatenating the user's input to the column name String selectionClause = "var = " + userInput;
ऐसा करने पर, उपयोगकर्ता आपके एसक्यूएल स्टेटमेंट में नुकसान पहुंचाने वाले एसक्यूएल को जोड़ सकता है.
उदाहरण के लिए, उपयोगकर्ता "कुछ नहीं; टेबल ड्रॉप करें *; mUserInput
के लिए, जो
नतीजे के तौर पर, चुना गया क्लॉज़ var = nothing; DROP TABLE *;
आता है.
क्योंकि सेलेक्शन क्लॉज़ को SQL स्टेटमेंट के तौर पर माना जाता है. इस वजह से, प्रोवाइडर हमेशा के लिए मौजूदा SQLite डेटाबेस में टेबल देख सकते हैं. ऐसा तब तक होगा, जब तक सर्वर को एसक्यूएल इंजेक्शन की कोशिश.
इस समस्या से बचने के लिए, ऐसे सेलेक्शन क्लॉज़ का इस्तेमाल करें जिसमें ?
को रिप्लेसबल के तौर पर इस्तेमाल किया गया हो
पैरामीटर और चुनने के लिए आर्ग्युमेंट की एक अलग सूची का इस्तेमाल करें. इस तरह, उपयोगकर्ता इनपुट
एसक्यूएल स्टेटमेंट के हिस्से के रूप में समझने के बजाय, सीधे क्वेरी से जुड़ा होता है.
इसे एसक्यूएल नहीं माना जाता, इसलिए उपयोगकर्ता का इनपुट, नुकसान पहुंचाने वाले एसक्यूएल को इंजेक्ट नहीं कर सकता. का उपयोग करने के बजाय
उपयोगकर्ता के इनपुट को शामिल करने के लिए, इस सेलेक्शन क्लॉज़ का इस्तेमाल करें:
Kotlin
// Constructs a selection clause with a replaceable parameter var selectionClause = "var = ?"
Java
// Constructs a selection clause with a replaceable parameter String selectionClause = "var = ?";
इस तरह से चुने गए आर्ग्युमेंट का अरे सेट अप करें:
Kotlin
// Defines a mutable list to contain the selection arguments var selectionArgs: MutableList<String> = mutableListOf()
Java
// Defines an array to contain the selection arguments String[] selectionArgs = {""};
चयन तर्क श्रेणी में इस तरह से कोई मान रखें:
Kotlin
// Adds the user's input to the selection argument selectionArgs += userInput
Java
// Sets the selection argument to the user's input selectionArgs[0] = userInput;
ऐसा सेलेक्शन क्लॉज़ जो ?
का इस्तेमाल बदले जा सकने वाले पैरामीटर और इसके कलेक्शन के तौर पर करता है
चयन तर्क श्रेणी चयन तय करने का पसंदीदा तरीका है, भले ही कंपनी न हो
जो एसक्यूएल डेटाबेस के हिसाब से तय होती है.
क्वेरी के नतीजे दिखाएं
ContentResolver.query()
क्लाइंट तरीका हमेशा
क्वेरी के कॉलम से तय किए गए कॉलम वाला Cursor
दिखाता है
उन पंक्तियों का प्रोजेक्शन जिनके लिए क्वेरी को चुनने की शर्तें पूरी होती हैं. ऐप्लिकेशन
Cursor
ऑब्जेक्ट, पंक्तियों और कॉलम को बिना किसी क्रम के पढ़ने का ऐक्सेस देता है
शामिल हैं.
Cursor
तरीके का इस्तेमाल करके,
नतीजे देख सकते हैं, हर कॉलम का डेटा टाइप पता कर सकते हैं, कॉलम से डेटा निकाल सकते हैं, और दूसरे कॉलम के डेटा की जांच कर सकते हैं
प्रॉपर्टी पर क्लिक करें.
कुछ Cursor
अपने-आप लागू हो जाते हैं
सेवा देने वाली कंपनी के डेटा में बदलाव होने पर, ऑब्जेक्ट को अपडेट करें. इसके अलावा, ऑब्ज़र्वर ऑब्जेक्ट में तरीके ट्रिगर करें
Cursor
या दोनों में बदलाव होने पर.
ध्यान दें: सेवा देने वाली कंपनी, ऑब्जेक्ट जो क्वेरी बना रहा है. उदाहरण के लिए, संपर्क कंपनी कुछ कॉलम को सिंक अडैप्टर को सिंक करता है, ताकि वह उन्हें किसी गतिविधि या सेवा पर वापस न करे.
अगर कोई भी पंक्ति चुने जाने के मानदंड से मेल नहीं खाती है, तो सेवा देने वाली कंपनी
इसके लिए Cursor
ऑब्जेक्ट दिखाता है
Cursor.getCount()
है
0—यानी, खाली कर्सर.
अगर कोई अंदरूनी गड़बड़ी होती है, तो क्वेरी के नतीजे, सेवा देने वाली कंपनी के हिसाब से अलग-अलग होते हैं. यह हो सकता है
null
दे सकता है या Exception
दे सकता है.
चूंकि Cursor
पंक्तियों की एक सूची है, इसलिए
Cursor
का कॉन्टेंट, इसे ListView
से लिंक करने के लिए है
SimpleCursorAdapter
का इस्तेमाल करके.
निम्न स्निपेट पिछले स्निपेट से कोड जारी रखता है. इससे एक
SimpleCursorAdapter
ऑब्जेक्ट में Cursor
है
डाउनलोड करता है और इस ऑब्जेक्ट को
ListView
.
Kotlin
// Defines a list of columns to retrieve from the Cursor and load into an output row val wordListColumns : Array<String> = arrayOf( UserDictionary.Words.WORD, // Contract class constant containing the word column name UserDictionary.Words.LOCALE // Contract class constant containing the locale column name ) // Defines a list of View IDs that receive the Cursor columns for each row val wordListItems = intArrayOf(R.id.dictWord, R.id.locale) // Creates a new SimpleCursorAdapter cursorAdapter = SimpleCursorAdapter( applicationContext, // The application's Context object R.layout.wordlistrow, // A layout in XML for one row in the ListView mCursor, // The result from the query wordListColumns, // A string array of column names in the cursor wordListItems, // An integer array of view IDs in the row layout 0 // Flags (usually none are needed) ) // Sets the adapter for the ListView wordList.setAdapter(cursorAdapter)
Java
// Defines a list of columns to retrieve from the Cursor and load into an output row String[] wordListColumns = { UserDictionary.Words.WORD, // Contract class constant containing the word column name UserDictionary.Words.LOCALE // Contract class constant containing the locale column name }; // Defines a list of View IDs that receive the Cursor columns for each row int[] wordListItems = { R.id.dictWord, R.id.locale}; // Creates a new SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter( getApplicationContext(), // The application's Context object R.layout.wordlistrow, // A layout in XML for one row in the ListView mCursor, // The result from the query wordListColumns, // A string array of column names in the cursor wordListItems, // An integer array of view IDs in the row layout 0); // Flags (usually none are needed) // Sets the adapter for the ListView wordList.setAdapter(cursorAdapter);
ध्यान दें: ListView
के साथ बैक अप लेने के लिए
Cursor
, कर्सर में _ID
नाम का कॉलम होना चाहिए.
इस वजह से, पहले दिखाई गई क्वेरी_ID
Words
टेबल का इस्तेमाल करें, भले ही ListView
इसे न दिखाता हो.
इस पाबंदी से यह भी पता चलता है कि सेवा देने वाली ज़्यादातर कंपनियों के पास, हर एक सेवा के लिए _ID
कॉलम क्यों है
सेवाएं शामिल कर सकती हैं.
क्वेरी के नतीजों से डेटा हासिल करना
क्वेरी के नतीजों को दिखाने के अलावा, उनका इस्तेमाल दूसरे कामों के लिए भी किया जा सकता है. इसके लिए
उदाहरण के लिए, यूज़र डिक्शनरी प्रोवाइडर से स्पेलिंग वापस पाई जा सकती है और
अन्य प्रोवाइडर. ऐसा करने के लिए, Cursor
में पंक्तियों को दोहराएं, जैसा कि इस उदाहरण में दिखाया गया है:
Kotlin
/* * Only executes if the cursor is valid. The User Dictionary Provider returns null if * an internal error occurs. Other providers might throw an Exception instead of returning null. */ mCursor?.apply { // Determine the column index of the column named "word" val index: Int = getColumnIndex(UserDictionary.Words.WORD) /* * Moves to the next row in the cursor. Before the first movement in the cursor, the * "row pointer" is -1, and if you try to retrieve data at that position you get an * exception. */ while (moveToNext()) { // Gets the value from the column newWord = getString(index) // Insert code here to process the retrieved word ... // End of while loop } }
Java
// Determine the column index of the column named "word" int index = mCursor.getColumnIndex(UserDictionary.Words.WORD); /* * Only executes if the cursor is valid. The User Dictionary Provider returns null if * an internal error occurs. Other providers might throw an Exception instead of returning null. */ if (mCursor != null) { /* * Moves to the next row in the cursor. Before the first movement in the cursor, the * "row pointer" is -1, and if you try to retrieve data at that position you get an * exception. */ while (mCursor.moveToNext()) { // Gets the value from the column newWord = mCursor.getString(index); // Insert code here to process the retrieved word ... // End of while loop } } else { // Insert code here to report an error if the cursor is null or the provider threw an exception }
Cursor
लागू करने के तरीके में कई "get" शामिल हैं तरीके
ऑब्जेक्ट से अलग-अलग तरह का डेटा वापस पाने के लिए. उदाहरण के लिए, पिछला स्निपेट
getString()
का इस्तेमाल करता है. उनके पास
getType()
तरीका, जो संकेत देने वाली वैल्यू दिखाता है
कॉलम का डेटा टाइप.
क्वेरी के नतीजे वाले संसाधन रिलीज़ करें
Cursor
ऑब्जेक्ट होने चाहिए
अगर अब उनकी ज़रूरत न हो, तो उन्हें बंद कर दिया जाता है, ताकि उनसे जुड़े संसाधनों को रिलीज़ किया जा सके
तय करें. ऐसा करने के लिए, कॉल करें
close()
या इसका इस्तेमाल करके
Java प्रोग्रामिंग भाषा में एक try-with-resources
स्टेटमेंट या
Kotlin प्रोग्रामिंग लैंग्वेज में use()
फ़ंक्शन.
कॉन्टेंट देने वाले के लिए अनुमतियां
सेवा देने वाले का ऐप्लिकेशन वे अनुमतियां तय कर सकता है जो दूसरे ऐप्लिकेशन के पास होनी चाहिए कंपनी के डेटा को ऐक्सेस करें. इन अनुमतियों से उपयोगकर्ता को यह पता चलता है कि कौनसा डेटा जब कोई ऐप्लिकेशन ऐक्सेस करने की कोशिश करता है. सेवा देने वाली कंपनी की शर्तों के आधार पर, अन्य ऐप्लिकेशन सेवा देने वाली कंपनी को ऐक्सेस करने के लिए उनकी ज़रूरत की अनुमतियों का अनुरोध करें. असली उपयोगकर्ताओं को वे प्रॉडक्ट दिखेंगे जिनका अनुरोध किया गया है अनुमतियां दी जाती हैं, जब वे ऐप्लिकेशन इंस्टॉल करते हैं.
अगर सेवा देने वाली कंपनी का ऐप्लिकेशन कोई अनुमति तय नहीं करता है, तो दूसरे ऐप्लिकेशन के पास सेवा देने वाली कंपनी के डेटा को ऐक्सेस करने की अनुमति देती है, जब तक कि सेवा देने वाली कंपनी को एक्सपोर्ट नहीं किया जाता. इसके अलावा, कॉम्पोनेंट को हमेशा पूरा पढ़ने और लिखने की ऐक्सेस होती है, चाहे बताई गई अनुमतियां शामिल हैं.
उपयोगकर्ता डिक्शनरी सेवा देने वाली कंपनी के लिए ज़रूरी है कि
android.permission.READ_USER_DICTIONARY
से डेटा वापस पाने की अनुमति.
सेवा देने वाली कंपनी के पास एक अलग android.permission.WRITE_USER_DICTIONARY
है
डेटा डालने, अपडेट करने या मिटाने की अनुमति.
सेवा देने वाली किसी कंपनी को ऐक्सेस करने के लिए ज़रूरी अनुमतियां पाने के लिए, ऐप्लिकेशन एक अनुरोध के साथ
<uses-permission>
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
एलिमेंट फ़ाइल की मेनिफ़ेस्ट फ़ाइल में दी गई है. जब Android पैकेज मैनेजर यह ऐप्लिकेशन इंस्टॉल करता है, तो उपयोगकर्ता
को ऐप्लिकेशन के अनुरोधों की सभी अनुमतियों को मंज़ूरी देनी होगी. अगर उपयोगकर्ता उन्हें अनुमति देता है, तो
पैकेज मैनेजर इंस्टॉलेशन जारी रखता है. अगर उपयोगकर्ता उन्हें अनुमति नहीं देता है, तो पैकेज मैनेजर
इंस्टॉलेशन को रोकता है.
नीचे दिया गया सैंपल
<uses-permission>
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
एलिमेंट रिक्वेस्ट, उपयोगकर्ता डिक्शनरी सेवा देने वाली कंपनी को पढ़ने का ऐक्सेस:
<uses-permission android:name="android.permission.READ_USER_DICTIONARY">
सेवा देने वाली कंपनी के ऐक्सेस पर अनुमतियों का असर सुरक्षा से जुड़ी सलाह.
डेटा डालें, अपडेट करें, और मिटाएं
जिस तरह किसी कंपनी से डेटा वापस लाया जाता है उसी तरह, दोनों के बीच इंटरैक्शन का इस्तेमाल भी किया जा सकता है
डेटा में बदलाव करने के लिए, सेवा देने वाली कंपनी के क्लाइंट और सेवा देने वाली कंपनी के ContentProvider
का इस्तेमाल करें.
ContentResolver
वाले तरीके को उन आर्ग्युमेंट के साथ कॉल किया जाता है जिन्हें पास किया जाता है
ContentProvider
का संबंधित तरीका. मैसेज देने वाली कंपनी और कंपनी
क्लाइंट अपने-आप सुरक्षा और इंटरप्रोसेस कम्यूनिकेशन को मैनेज करता है.
डेटा डालें
सेवा देने वाली किसी कंपनी में डेटा डालने के लिए,
ContentResolver.insert()
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
तरीका. यह तरीका, प्रोवाइडर में एक नई लाइन जोड़ता है और उस लाइन के लिए कॉन्टेंट यूआरआई दिखाता है.
नीचे दिए गए स्निपेट में, उपयोगकर्ता डिक्शनरी की सेवा देने वाली कंपनी में नया शब्द डालने का तरीका बताया गया है:
Kotlin
// Defines a new Uri object that receives the result of the insertion lateinit var newUri: Uri ... // Defines an object to contain the new values to insert val newValues = ContentValues().apply { /* * Sets the values of each column and inserts the word. The arguments to the "put" * method are "column name" and "value". */ put(UserDictionary.Words.APP_ID, "example.user") put(UserDictionary.Words.LOCALE, "en_US") put(UserDictionary.Words.WORD, "insert") put(UserDictionary.Words.FREQUENCY, "100") } newUri = contentResolver.insert( UserDictionary.Words.CONTENT_URI, // The UserDictionary content URI newValues // The values to insert )
Java
// Defines a new Uri object that receives the result of the insertion Uri newUri; ... // Defines an object to contain the new values to insert ContentValues newValues = new ContentValues(); /* * Sets the values of each column and inserts the word. The arguments to the "put" * method are "column name" and "value". */ newValues.put(UserDictionary.Words.APP_ID, "example.user"); newValues.put(UserDictionary.Words.LOCALE, "en_US"); newValues.put(UserDictionary.Words.WORD, "insert"); newValues.put(UserDictionary.Words.FREQUENCY, "100"); newUri = getContentResolver().insert( UserDictionary.Words.CONTENT_URI, // The UserDictionary content URI newValues // The values to insert );
नई लाइन का डेटा, एक ContentValues
ऑब्जेक्ट में जाता है, जिससे
एक पंक्ति कर्सर के रूप में होता है. इस ऑब्जेक्ट के कॉलम में
डेटा प्रकार का उपयोग कर रहे हैं, और यदि आप कोई मान दर्ज नहीं करना चाहते तो आप
ContentValues.putNull()
का इस्तेमाल करके null
तक.
पिछला स्निपेट _ID
कॉलम को नहीं जोड़ता, क्योंकि इस कॉलम में कोई बदलाव नहीं किया गया है
स्वचालित रूप से. सेवा देने वाली कंपनी हर पंक्ति के लिए, _ID
की एक यूनीक वैल्यू असाइन करती है
जोड़ा गया. सेवा देने वाली कंपनियां आम तौर पर, इस वैल्यू का इस्तेमाल टेबल की प्राथमिक कुंजी के तौर पर करती हैं.
newUri
में दिया गया कॉन्टेंट यूआरआई, जोड़ी गई नई पंक्ति की पहचान करता है
निम्न प्रारूप:
content://user_dictionary/words/<id_value>
नई लाइन के लिए, _ID
का कॉन्टेंट <id_value>
होता है.
ज़्यादातर कंपनियां, कॉन्टेंट यूआरआई के इस फ़ॉर्मैट का अपने-आप पता लगा सकती हैं और फिर अनुरोध की गई कार्रवाई कर सकती हैं
कोई कार्रवाई न करें.
लौटाए गए Uri
से _ID
की वैल्यू पाने के लिए, कॉल करें
ContentUris.parseId()
.
डेटा अपडेट करना
लाइन को अपडेट करने के लिए, अपडेट किए गए वर्शन के साथ ContentValues
ऑब्जेक्ट का इस्तेमाल करें
वैल्यू, जैसे किसी इंसर्शन और चुनने की शर्त के साथ की जाती हैं, जैसा कि किसी क्वेरी के साथ किया जाता है.
आपने जिस तरीके का इस्तेमाल किया है वह
ContentResolver.update()
. आपको सिर्फ़ यह जोड़ना होगा
जिन कॉलम को अपडेट किया जा रहा है उनके लिए, ContentValues
ऑब्जेक्ट की वैल्यू. अगर आपको
अगर आपको किसी कॉलम के कॉन्टेंट को मिटाना है, तो वैल्यू को null
पर सेट करें.
नीचे दिया गया स्निपेट उन सभी पंक्तियों को बदल देता है जिनकी स्थान-भाषा की भाषा "en"
null
की स्थान-भाषा है. रिटर्न वैल्यू, अपडेट की गई लाइनों की संख्या होती है.
Kotlin
// Defines an object to contain the updated values val updateValues = ContentValues().apply { /* * Sets the updated value and updates the selected words. */ putNull(UserDictionary.Words.LOCALE) } // Defines selection criteria for the rows you want to update val selectionClause: String = UserDictionary.Words.LOCALE + "LIKE ?" val selectionArgs: Array<String> = arrayOf("en_%") // Defines a variable to contain the number of updated rows var rowsUpdated: Int = 0 ... rowsUpdated = contentResolver.update( UserDictionary.Words.CONTENT_URI, // The UserDictionary content URI updateValues, // The columns to update selectionClause, // The column to select on selectionArgs // The value to compare to )
Java
// Defines an object to contain the updated values ContentValues updateValues = new ContentValues(); // Defines selection criteria for the rows you want to update String selectionClause = UserDictionary.Words.LOCALE + " LIKE ?"; String[] selectionArgs = {"en_%"}; // Defines a variable to contain the number of updated rows int rowsUpdated = 0; ... /* * Sets the updated value and updates the selected words. */ updateValues.putNull(UserDictionary.Words.LOCALE); rowsUpdated = getContentResolver().update( UserDictionary.Words.CONTENT_URI, // The UserDictionary content URI updateValues, // The columns to update selectionClause, // The column to select on selectionArgs // The value to compare to );
कॉल करते समय उपयोगकर्ता के इनपुट को साफ़ करें
ContentResolver.update()
. इस बारे में ज़्यादा जानने के लिए
इसके बाद, नुकसान पहुंचाने वाले इनपुट से सुरक्षा सेक्शन को पढ़ें.
डेटा मिटाएं
पंक्तियां मिटाना, पंक्ति का डेटा वापस पाने जैसा ही है. आप पंक्तियों के लिए चुनने का मानदंड तय करते हैं
से पहले, डेटा दिखाता है और क्लाइंट तरीका मिटाई गई पंक्तियों की संख्या दिखाता है.
नीचे दिया गया स्निपेट उन पंक्तियों को मिटाता है जिनका ऐप्लिकेशन आईडी "user"
से मेल खाता है. यह तरीका नतीजे के तौर पर
मिटाई गई पंक्तियों की संख्या.
Kotlin
// Defines selection criteria for the rows you want to delete val selectionClause = "${UserDictionary.Words.APP_ID} LIKE ?" val selectionArgs: Array<String> = arrayOf("user") // Defines a variable to contain the number of rows deleted var rowsDeleted: Int = 0 ... // Deletes the words that match the selection criteria rowsDeleted = contentResolver.delete( UserDictionary.Words.CONTENT_URI, // The UserDictionary content URI selectionClause, // The column to select on selectionArgs // The value to compare to )
Java
// Defines selection criteria for the rows you want to delete String selectionClause = UserDictionary.Words.APP_ID + " LIKE ?"; String[] selectionArgs = {"user"}; // Defines a variable to contain the number of rows deleted int rowsDeleted = 0; ... // Deletes the words that match the selection criteria rowsDeleted = getContentResolver().delete( UserDictionary.Words.CONTENT_URI, // The UserDictionary content URI selectionClause, // The column to select on selectionArgs // The value to compare to );
कॉल करते समय उपयोगकर्ता के इनपुट को साफ़ करें
ContentResolver.delete()
. इस बारे में ज़्यादा जानने के लिए
इसके बाद, नुकसान पहुंचाने वाले इनपुट से सुरक्षा करें सेक्शन को पढ़ें.
सेवा देने वाली कंपनी के डेटा के टाइप
कॉन्टेंट देने वाली कंपनियां, कई अलग-अलग तरह के डेटा टाइप की सुविधा दे सकती हैं. उपयोगकर्ता डिक्शनरी की सेवा देने वाली कंपनी सिर्फ़ ये ऑफ़र उपलब्ध कराती है टेक्स्ट की मदद से, विज्ञापन देने वाले लोग या कंपनियां इन्हें नीचे दिए गए फ़ॉर्मैट में भी ऑफ़र कर सकती हैं:
- पूर्णांक
- लंबा पूर्णांक (लंबा)
- फ़्लोटिंग पॉइंट
- लंबा फ़्लोटिंग पॉइंट (डबल)
दूसरा डेटा टाइप जिसे सेवा देने वाली कंपनियां अक्सर इस्तेमाल करती हैं, वह है बाइनरी लार्ज ऑब्जेक्ट (बीएलओबी) जिसे
64 KB बाइट का अरे. यह जानने के लिए कि कौनसा डेटा टाइप उपलब्ध है
Cursor
क्लास "पाएं" तरीकों का इस्तेमाल करना होगा.
आम तौर पर, सेवा देने वाली कंपनी के हर कॉलम का डेटा टाइप, उसके दस्तावेज़ में दिया जाता है.
उपयोगकर्ता डिक्शनरी सेवा देने वाली कंपनी के डेटा टाइप, रेफ़रंस दस्तावेज़ में दिए गए हैं
अपनी कॉन्ट्रैक्ट क्लास, UserDictionary.Words
के लिए. अनुबंध की क्लास
कॉन्ट्रैक्ट क्लास सेक्शन में बताया गया है.
Cursor.getType()
पर कॉल करके भी यह पता लगाया जा सकता है कि डेटा किस तरह का है.
सेवा देने वाली कंपनियां, अपने तय किए गए हर कॉन्टेंट यूआरआई के लिए MIME डेटा टाइप की जानकारी भी संभालकर रखती हैं. आप MIME प्रकार की जानकारी का उपयोग करके यह पता करें कि आपका ऐप्लिकेशन ऐसे डेटा को प्रबंधित कर सकता है या नहीं या MIME टाइप के आधार पर हैंडलिंग का टाइप चुन सकती है. आम तौर पर, आपको इसकी ज़रूरत होती है MIME प्रकार जब आप किसी ऐसे कंपनी के साथ काम करते है जिसमें जटिल डेटा स्ट्रक्चर या फ़ाइलें.
उदाहरण के लिए, ContactsContract.Data
संपर्क सूची में मौजूद टेबल में, MIME टाइप का इस्तेमाल किया जाता है, ताकि हर रिपोर्ट में सेव किए गए संपर्क डेटा के टाइप को लेबल किया जा सके
लाइन. कॉन्टेंट यूआरआई से जुड़ा MIME टाइप पाने के लिए, कॉल करें
ContentResolver.getType()
.
MIME टाइप रेफ़रंस सेक्शन में सिंटैक्स का इस्तेमाल स्टैंडर्ड और कस्टम MIME टाइप, दोनों के लिए किया जा सकता है.
सेवा देने वाली कंपनी को ऐक्सेस देने के अन्य तरीके
ऐप्लिकेशन डेवलपमेंट में सेवा देने वाले के लिए ऐक्सेस के तीन विकल्प ज़रूरी हैं:
-
बैच ऐक्सेस: इसमें दिए गए तरीकों की मदद से, बैच ऐक्सेस कॉल तैयार किए जा सकते हैं
ContentProviderOperation
क्लास को स्कैन करें और फिर उन्हेंContentResolver.applyBatch()
. -
एसिंक्रोनस क्वेरी: क्वेरी को अलग थ्रेड में करें. आप
CursorLoader
ऑब्जेक्ट का इस्तेमाल करें. यहां दिए गए उदाहरण लोडर गाइड इसे कैसे किया जा सकता है. - इंटेंट का इस्तेमाल करके डेटा ऐक्सेस करना: हालांकि, आप इंटेंट नहीं भेज सकते तो आप सेवा देने वाली कंपनी के ऐप्लिकेशन पर इंटेंट भेज सकते हैं, जो कि आम तौर पर, प्रोवाइडर के डेटा में बदलाव करने के लिए बेहतर तरीके से उपलब्ध होती है.
इंटेंट का इस्तेमाल करके, बैच को ऐक्सेस करने और उसमें बदलाव करने के बारे में यहां दिए गए सेक्शन में बताया गया है.
बैच ऐक्सेस
बड़ी संख्या में पंक्तियां शामिल करने के लिए, प्रोवाइडर का बैच ऐक्सेस करने से मदद मिलती है पंक्तियों को उसी मेथड कॉल में अनेक टेबल में और आम तौर पर किसी लेन-देन के तौर पर अलग-अलग प्रोसेस की सीमाओं के अंदर की जाने वाली कार्रवाइयों को ऐटॉमिक ऑपरेशन कहते हैं.
सेवा देने वाली किसी कंपनी को बैच मोड में ऐक्सेस करने के लिए,
ContentProviderOperation
ऑब्जेक्ट का कलेक्शन बनाएं और फिर
उन्हें इस तरह से कॉन्टेंट उपलब्ध कराने वाले प्लैटफ़ॉर्म पर भेजें
ContentResolver.applyBatch()
. आप
कॉन्टेंट देने वाले की ऑथरिटी को ध्यान में रखते हुए, किसी खास कॉन्टेंट यूआरआई के बजाय इस तरीके का इस्तेमाल करें.
इससे अरे में मौजूद हर ContentProviderOperation
ऑब्जेक्ट काम कर पाता है
का इस्तेमाल करें. ContentResolver.applyBatch()
को कॉल करने पर, नतीजों की कैटगरी तय होती है.
ContactsContract.RawContacts
कॉन्ट्रैक्ट क्लास का ब्यौरा
में एक कोड स्निपेट शामिल है, जो बैच इंसर्शन दिखाता है.
इंटेंट का इस्तेमाल करके डेटा ऐक्सेस करना
इंटेंट, कॉन्टेंट देने वाले को सीधे तौर पर ऐक्सेस नहीं दे सकते. आपके पास उस व्यक्ति को इसे ऐक्सेस करने की अनुमति देने का विकल्प है डेटा ट्रांसफ़र करना शुरू करें, भले ही आपके ऐप्लिकेशन के पास किसी ऐसे ऐप्लिकेशन से नतीजे पाने के लिए जिसे अनुमति मिली हो या ऐसा ऐप्लिकेशन जिसमें अनुमतियां हों और जो उपयोगकर्ता को उसमें काम करने देती हो.
कुछ समय के लिए दी जाने वाली अनुमतियों के साथ ऐक्सेस पाएं
ज़रूरी ऐक्सेस न होने पर भी, कॉन्टेंट देने वाले की साइट पर डेटा ऐक्सेस किया जा सकता है अनुमतियां पर क्लिक करें. ऐसा उस ऐप्लिकेशन को इंटेंट भेजकर किया जाएगा जिसके पास ये अनुमतियां हैं और यूआरआई की अनुमतियों वाले नतीजे के इंटेंट को वापस पाना. ये उस खास कॉन्टेंट यूआरआई के लिए अनुमतियां हैं जो मिलने वाली गतिविधि तक बनी रहती हैं उन्हें पूरा कर लिया जाता है. स्थायी अनुमतियां वाला ऐप्लिकेशन अस्थायी रूप से अनुमति देता है परिणाम इंटेंट में फ़्लैग सेट करके अनुमतियाँ:
-
पढ़ने की अनुमति:
FLAG_GRANT_READ_URI_PERMISSION
-
लिखने की अनुमति:
FLAG_GRANT_WRITE_URI_PERMISSION
ध्यान दें: इन फ़्लैग से, सेवा देने वाली कंपनी को पढ़ने या उसमें बदलाव करने का सामान्य ऐक्सेस नहीं मिलता जिसकी अनुमति कॉन्टेंट यूआरआई में शामिल है. इसका ऐक्सेस सिर्फ़ यूआरआई के लिए है.
जब आप किसी दूसरे ऐप्लिकेशन को कॉन्टेंट यूआरआई भेजते हैं, तो इनमें से कम से कम एक को शामिल करें फ़्लैग. फ़्लैग की मदद से, किसी भी ऐप्लिकेशन को ये सुविधाएं मिलती हैं यह इंटेंट और Android 11 (एपीआई लेवल 30) या उसके बाद के वर्शन को टारगेट करता है:
- कॉन्टेंट यूआरआई जिस डेटा का प्रतिनिधित्व करता है उसे पढ़ें या उसमें लिखें, तय करें.
- पैकेज पाएं उस ऐप्लिकेशन में विज़िबिलिटी जिसमें यूआरआई अथॉरिटी. इंटेंट भेजने वाला ऐप्लिकेशन और वह ऐप्लिकेशन जो कॉन्टेंट देने वाले दो अलग-अलग ऐप्लिकेशन हो सकते हैं.
सेवा देने वाली कंपनी, कॉन्टेंट यूआरआई के लिए अपने मेनिफ़ेस्ट में यूआरआई अनुमतियां तय करती है. इसके लिए इसका इस्तेमाल किया जाता है:
android:grantUriPermissions
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
एट्रिब्यूट
<provider>
एलिमेंट और
<grant-uri-permission>
चाइल्ड एलिमेंट
<provider>
एलिमेंट. यूआरआई अनुमतियों के बारे में ज़्यादा जानकारी यहां दी गई है
Android पर अनुमतियों से जुड़ी गाइड.
उदाहरण के लिए, आप संपर्क की सेवा देने वाली कंपनी में किसी संपर्क का डेटा वापस पा सकते हैं, भले ही आप
READ_CONTACTS
की अनुमति होनी चाहिए. ऐसा हो सकता है कि
को एक ऐसे ऐप्लिकेशन में भेज दिया जाता है जो संपर्क के जन्मदिन पर उन्हें ई-शुभकामनाएं भेजता है. इसके बजाय
READ_CONTACTS
का अनुरोध कर रहा है, जिससे आप सभी
उपयोगकर्ता के संपर्क और उनकी सभी जानकारी की मदद से, उपयोगकर्ता यह कंट्रोल कर सकते हैं कि
आपके ऐप्लिकेशन में इस्तेमाल होने वाले संपर्क. ऐसा करने के लिए, नीचे दी गई प्रक्रिया का इस्तेमाल करें:
-
अपने ऐप्लिकेशन में, कार्रवाई वाला इंटेंट भेजें
ACTION_PICK
और "संपर्क" MIME प्रकारCONTENT_ITEM_TYPE
को इसकी मदद सेstartActivityForResult()
तरीका. - क्योंकि यह इंटेंट लोगों के ऐप्लिकेशन का "चुनना" गतिविधि, फ़ोरग्राउंड पर आती है.
-
चुनी गई गतिविधि में, उपयोगकर्ता किसी
अपडेट करने के लिए संपर्क करें. ऐसा होने पर, चुनी गई गतिविधि के लिए कॉल
setResult(resultcode, intent)
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है आपके ऐप्लिकेशन को वापस देने के लिए कोई इंटेंट सेट अप करना होगा. इंटेंट में कॉन्टेंट यूआरआई शामिल है उपयोगकर्ता के चुने गए संपर्क और "अतिरिक्त" फ़्लैगFLAG_GRANT_READ_URI_PERMISSION
. ये फ़्लैग, यूआरआई की अनुमति देते हैं आपके ऐप्लिकेशन को उस संपर्क का डेटा पढ़ने की अनुमति दें जिसके बारे में आपके ऐप्लिकेशन को बताया गया है कॉन्टेंट यूआरआई. इसके बाद, चुने गए विकल्प सेfinish()
को इस नंबर पर कॉल किया जाता है वापस जाकर अपने ऐप्लिकेशन पर नियंत्रण वापस कर सकते हैं. -
आपकी गतिविधि फ़ोरग्राउंड पर वापस आ जाती है और सिस्टम आपकी गतिविधि की
onActivityResult()
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है तरीका. इस तरीके को यहां की चुनी गई गतिविधि से बनाया गया नतीजा इंटेंट मिलता है लोग ऐप्लिकेशन. - नतीजे के इंटेंट से मिले कॉन्टेंट यूआरआई की मदद से, संपर्क का डेटा पढ़ा जा सकता है अपने Google खाते से स्थायी तौर पर ऐक्सेस करने के लिए कहें. अपने मेनिफ़ेस्ट में प्रोवाइडर को भेजा जा सकता है. इसके बाद, आपको संपर्क के जन्मदिन की जानकारी मिल सकती है या ईमेल पता दर्ज करें और फिर ई-ग्रीटिंग भेजें.
किसी दूसरे ऐप्लिकेशन का इस्तेमाल करें
जिस डेटा के लिए आपके पास ऐक्सेस की अनुमति नहीं है उसमें बदलाव करने के लिए, उपयोगकर्ता को अनुमति देने का एक और तरीका है उस ऐप्लिकेशन को चालू करें जिसके पास अनुमतियां हों और उपयोगकर्ता को वहां काम करने दें.
उदाहरण के लिए, Calendar ऐप्लिकेशन
ACTION_INSERT
इंटेंट की मदद से,
ऐप्लिकेशन का इंसर्ट यूज़र इंटरफ़ेस (यूआई) है. "अतिरिक्त" शब्द को पास किया जा सकता है इस इंटेंट में मौजूद डेटा, जिसे ऐप्लिकेशन
का इस्तेमाल, यूज़र इंटरफ़ेस (यूआई) में अपने-आप जानकारी भरने के लिए करता है. बार-बार होने वाले इवेंट का सिंटैक्स मुश्किल होता है. इसलिए,
कैलेंडर प्रोवाइडर में इवेंट शामिल करने का तरीका यह है कि Calendar ऐप्लिकेशन को
ACTION_INSERT
और फिर उपयोगकर्ता को वहां इवेंट डालने की अनुमति दें.
हेल्पर ऐप्लिकेशन का इस्तेमाल करके डेटा दिखाएं
अगर आपके ऐप्लिकेशन के पास ऐक्सेस की अनुमतियां है, तो भी आप
अन्य ऐप्लिकेशन में डेटा दिखाने के लिए इंटेंट कर देते हैं. उदाहरण के लिए, Calendar ऐप्लिकेशन
ACTION_VIEW
इंटेंट, जो किसी खास तारीख या इवेंट को दिखाता है.
इससे आपको अपना यूज़र इंटरफ़ेस (यूआई) बनाए बिना कैलेंडर की जानकारी दिखाने में मदद मिलती है.
इस सुविधा के बारे में ज़्यादा जानने के लिए, यहां देखें:
कैलेंडर की सेवा देने वाली कंपनी की खास जानकारी.
जिस ऐप्लिकेशन को आप इंटेंट भेज रहे हैं, उसका ऐप्लिकेशन होना ज़रूरी नहीं है
सेवा देने वाली कंपनी से जुड़ा हुआ है. उदाहरण के लिए, आप
सेवा देने वाली कंपनी से संपर्क करें, फिर ACTION_VIEW
इंटेंट भेजें
में इमेज व्यूअर के लिए संपर्क की इमेज का कॉन्टेंट यूआरआई शामिल है.
कॉन्ट्रैक्ट क्लास
कॉन्ट्रैक्ट क्लास में ऐसे कॉन्सटेंट के बारे में बताया जाता है जो कॉन्टेंट यूआरआई, कॉलम के साथ ऐप्लिकेशन को काम करने में मदद करते हैं
कॉन्टेंट देने वाले के नाम, इंटेंट कार्रवाइयों, और अन्य सुविधाओं की जानकारी शामिल होती है. कॉन्ट्रैक्ट क्लास
किसी कंपनी के साथ अपने-आप शामिल हो जाता है. सेवा देने वाली कंपनी के डेवलपर को इन्हें तय करना होगा और फिर
उन्हें अन्य डेवलपर को उपलब्ध कराया जा सके. Android के साथ शामिल कई कंपनियां
प्लैटफ़ॉर्म के पास android.provider
पैकेज में इससे जुड़ी कॉन्ट्रैक्ट क्लास हैं.
उदाहरण के लिए, यूज़र डिक्शनरी देने वाली कंपनी के पास कॉन्ट्रैक्ट क्लास है
UserDictionary
में कॉन्टेंट यूआरआई और कॉलम के नाम के कॉन्सटेंट शामिल हैं. कॉन्टेंट बनाने
Words
टेबल के लिए कॉन्टेंट यूआरआई को कॉन्स्टेंट (कॉन्सटेंट) में तय किया गया है
UserDictionary.Words.CONTENT_URI
.
UserDictionary.Words
क्लास में कॉलम के नाम के कॉन्सटेंट भी होते हैं,
जिनका इस्तेमाल इस गाइड में, उदाहरण स्निपेट में किया गया है. उदाहरण के लिए, क्वेरी प्रोजेक्शन
इस तरह परिभाषित किया गया है:
Kotlin
val projection : Array<String> = arrayOf( UserDictionary.Words._ID, UserDictionary.Words.WORD, UserDictionary.Words.LOCALE )
Java
String[] projection = { UserDictionary.Words._ID, UserDictionary.Words.WORD, UserDictionary.Words.LOCALE };
संपर्क सेवा देने वाली कंपनी के लिए एक अन्य कॉन्ट्रैक्ट क्लास ContactsContract
है.
इस क्लास के रेफ़रंस दस्तावेज़ में, कोड स्निपेट के उदाहरण शामिल हैं. इसका एक
ContactsContract.Intents.Insert
सब-क्लास एक कॉन्ट्रैक्ट है
क्लास, जिसमें इंटेंट और इंटेंट डेटा के लिए कॉन्सटेंट शामिल हैं.
MIME प्रकार संदर्भ
कॉन्टेंट देने वाले लोग, स्टैंडर्ड MIME मीडिया टाइप, कस्टम MIME टाइप वाली स्ट्रिंग या दोनों दिखा सकते हैं.
MIME प्रकारों के निम्न फ़ॉर्मेट होते हैं:
type/subtype
उदाहरण के लिए, जाने-माने MIME टाइप text/html
में text
टाइप और
html
सब-टाइप. अगर सेवा देने वाली कंपनी यूआरआई के लिए इस तरह की जानकारी देती है, तो इसका मतलब है कि
यूआरआई का इस्तेमाल करने वाली क्वेरी, एचटीएमएल टैग वाला टेक्स्ट दिखाती है.
कस्टम MIME टाइप वाली स्ट्रिंग को वेंडर के हिसाब से MIME टाइप भी कहा जाता है. इनमें अन्य कॉम्प्लेक्स type और subtype वैल्यू. एक से ज़्यादा पंक्तियों के लिए, टाइप की वैल्यू हमेशा यहां दी गई होती है:
vnd.android.cursor.dir
किसी एक पंक्ति के लिए, टाइप की वैल्यू हमेशा यहां दी गई होती है:
vnd.android.cursor.item
subtype, सेवा देने वाली कंपनी के हिसाब से अलग-अलग होता है. Android में पहले से मौजूद कंपनियों में आम तौर पर, उप-प्रकार. उदाहरण के लिए, जब संपर्क ऐप्लिकेशन किसी टेलीफ़ोन नंबर के लिए एक पंक्ति बनाता है, तो यह पंक्ति में नीचे दिया गया MIME टाइप सेट करता है:
vnd.android.cursor.item/phone_v2
सब-टाइप की वैल्यू phone_v2
है.
अन्य कंपनी डेवलपर, सेवा देने वाली कंपनी की
अधिकार और टेबल के नाम. उदाहरण के लिए, सेवा देने वाली किसी ऐसी कंपनी के बारे में सोचें जिसके पास ट्रेन की समय-सारणी है.
सेवा देने वाली कंपनी का अधिकार com.example.trains
है और इसमें टेबल शामिल होती हैं
Line1, Line2, और Line3. तालिका Line1 के लिए नीचे दिए गए कॉन्टेंट यूआरआई के जवाब में:
content://com.example.trains/Line1
प्रोवाइडर इस तरह का MIME टाइप देता है:
vnd.android.cursor.dir/vnd.example.line1
तालिका Line2 में पंक्ति 5 के लिए नीचे दिए गए सामग्री यूआरआई के जवाब में:
content://com.example.trains/Line2/5
प्रोवाइडर इस तरह का MIME टाइप देता है:
vnd.android.cursor.item/vnd.example.line2
कॉन्टेंट देने वाले ज़्यादातर लोग या कंपनियां, MIME टाइप के लिए कॉन्ट्रैक्ट क्लास कॉन्सटेंट तय करती हैं. कॉन्टेंट बनाने
संपर्क कंपनी अनुबंध श्रेणी ContactsContract.RawContacts
,
उदाहरण के लिए, कॉन्सटेंट को
इसके MIME प्रकार के लिए CONTENT_ITEM_TYPE
संपर्क करने के लिए एक
रॉ संपर्क लाइन दिखेगी.
एक लाइन के कॉन्टेंट यूआरआई की जानकारी इसमें दी गई है कॉन्टेंट यूआरआई सेक्शन.