Google Play services और रनटाइम की अनुमतियां

Android 6.0 Marshmallow के बाद से, Android एक अनुमति मॉडल का इस्तेमाल करता है. इससे ऐप्लिकेशन इंस्टॉल करने और अपने-आप अपडेट होने की प्रोसेस आसान हो जाती है. ऐप्लिकेशन इंस्टॉल करने से पहले के बजाय, रनटाइम में अनुमतियों का अनुरोध किया जाता है. इसके अलावा, उपयोगकर्ता कुछ अनुमतियां अस्वीकार भी कर सकते हैं. उपयोगकर्ताओं को यह सुविधा देने के लिए, आपको यह पक्का करना होगा कि जब कोई उपयोगकर्ता किसी अनुमति को चालू या बंद करता है, तो आपका ऐप्लिकेशन उम्मीद के मुताबिक काम करे.

Google Play services के पास रनटाइम अनुमतियां होती हैं. उपयोगकर्ता, आपके ऐप्लिकेशन की ओर से अनुरोध की गई अनुमतियों से अलग इन अनुमतियों को अस्वीकार कर सकते हैं. Google Play services को अपने एपीआई के साथ काम करने के लिए ज़रूरी सभी अनुमतियां अपने-आप मिल जाती हैं. हालांकि, आपका ऐप्लिकेशन अब भी ज़रूरत के हिसाब से रनटाइम अनुमतियों की जांच करेगा और उनके लिए अनुरोध करेगा. साथ ही, उन मामलों में गड़बड़ियों को ठीक से हैंडल करेगा जहां किसी उपयोगकर्ता ने Google Play services को, आपके ऐप्लिकेशन के इस्तेमाल किए जा रहे एपीआई के लिए ज़रूरी अनुमति नहीं दी है.

अनुमतियां सेट करते समय, उपयोगकर्ता की उम्मीदों को मैनेज करना एक अच्छा तरीका है. ऐसा इसलिए, क्योंकि रनटाइम को इन अनुमतियों की ज़रूरत पड़ सकती है. यहां दिए गए सबसे सही तरीकों को अपनाकर, संभावित समस्याओं से बचा जा सकता है.

ज़रूरी शर्तें

आपको अपनी AndroidManifest.xml फ़ाइल में अनुमतियों का एलान करना होगा. उदाहरण के लिए:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

दिशा-निर्देश

एपीआई को कॉल करने से पहले अनुमतियों की पुष्टि करना

AndroidManifest.xml फ़ाइल में इस्तेमाल किए जाने वाले एपीआई का एलान करने के बाद, यह पुष्टि करें कि आपके पास एपीआई को कॉल करने की ज़रूरी अनुमति है. ऐसा ActivityCompat या ContextCompat के checkSelfPermission तरीके का इस्तेमाल करके किया जा सकता है.

अगर कॉल में 'गलत है' दिखता है, तो इसका मतलब है कि अनुमतियां नहीं दी गई हैं. इसलिए, आपको अनुमतियों का अनुरोध करने के लिए requestPermissions का इस्तेमाल करना चाहिए. इसका जवाब, कॉलबैक में मिलता है. यह आपको अगले चरण में दिखेगा.

उदाहरण के लिए:

Kotlin

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
        != PackageManager.PERMISSION_GRANTED) {
            // Request Permissions Now
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                REQUEST_LOCATION_PERMISSION_CODE)
    } else {
        // permission has been granted, continue as usual
        val locationResult = LocationServices
            .getFusedLocationProviderClient(this /* Context */)
            .lastLocation
    }

Java

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
        != PackageManager.PERMISSION_GRANTED) {
        // Request Permissions Now
        ActivityCompat.requestPermissions(
            this,
            new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
            REQUEST_LOCATION_PERMISSION_CODE);
    } else {
        // permission has been granted, continue as usual
        Task locationResult = LocationServices
            .getFusedLocationProviderClient(this /** Context */)
            .getLastLocation();
    }

अनुमति के लिए अनुरोध करने वाले कॉलबैक को लागू करना

अगर उपयोगकर्ता ने आपके ऐप्लिकेशन को ज़रूरी अनुमति नहीं दी है, तो requestPermissions तरीके को कॉल करके, उपयोगकर्ता से अनुमति देने के लिए कहा जाना चाहिए. उपयोगकर्ता के जवाब को onRequestPermissionsResult कॉलबैक में कैप्चर किया जाता है. आपके ऐप्लिकेशन को इस सुविधा को लागू करना चाहिए. साथ ही, हमेशा रिटर्न वैल्यू की जांच करनी चाहिए, क्योंकि अनुरोध अस्वीकार किया जा सकता है या रद्द किया जा सकता है. एक साथ कई अनुमतियों का अनुरोध किया जा सकता है और उन्हें देखा जा सकता है. यहां दिए गए सैंपल में, सिर्फ़ एक अनुमति की जांच की गई है.

Kotlin

    fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array,
        grantResults: IntArray
    ) {
        if (requestCode == REQUEST_LOCATION_PERMISSION_CODE) {
            if (grantResults.singleOrNull() == PackageManager.PERMISSION_GRANTED) {
               // We can now safely use the API we requested access to
               val locationResult: Task = LocationServices
                    .getFusedLocationProviderClient(this /* Context */)
                    .lastLocation // Request the last known location.
            } else {
                // Permission was denied or request was cancelled
            }
        }
    }

Java

    public void onRequestPermissionsResult(int requestCode,
                                            String[] permissions,
                                            int[] grantResults) {
        if (requestCode == REQUEST_LOCATION_PERMISSION_CODE) {
            if(grantResults.length == 1
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // We can now safely use the API we requested access to
                Task locationResult = LocationServices
                    .getFusedLocationProviderClient(this /** Context */)
                    .getLastLocation(); // Request the last known location.
            } else {
                // Permission was denied or request was cancelled
            }
        }
    }

अनुमति के बारे में तर्क दिखाएं

अगर आपके ऐप्लिकेशन की मुख्य सुविधाओं के लिए, मांगी गई अनुमतियां ज़रूरी हैं और उपयोगकर्ता ने पहले अनुमति के अनुरोध को अस्वीकार कर दिया है, तो आपके ऐप्लिकेशन को अनुमति का अनुरोध दोबारा करने से पहले, अतिरिक्त जानकारी दिखानी चाहिए. उपयोगकर्ता, अनुमतियां तब देते हैं, जब उन्हें यह पता हो कि अनुमति क्यों मांगी जा रही है और इससे उन्हें क्या फ़ायदा होगा.

इस मामले में, requestPermissions को कॉल करने से पहले, आपको shouldShowRequestPermissionRationale को कॉल करना चाहिए. अगर यह true दिखाता है, तो आपको अनुमति के बारे में अतिरिक्त जानकारी दिखाने के लिए कुछ यूज़र इंटरफ़ेस (यूआई) बनाना चाहिए.

उदाहरण के लिए, आपका कोड कुछ ऐसा दिख सकता है:

Kotlin

    private const val REQUEST_LOCATION_PERMISSION_CODE = 2
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
        != PackageManager.PERMISSION_GRANTED) {
        // Check Permissions Now
        if ActivityCompat.shouldShowRequestPermissionRationale(
            this,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) {
            // Display UI and wait for user interaction
        } else {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                REQUEST_LOCATION_PERMISSION_CODE)
        }
    } else {
        // Permission has already been granted, continue as usual
        val locationResult: Task = LocationServices
            .getFusedLocationProviderClient(this /* Context */)
            .lastLocation
    }

Java

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
        != PackageManager.PERMISSION_GRANTED) {
        // Check Permissions Now
        private static final int REQUEST_LOCATION_PERMISSION_CODE = 2;
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION)) {
            // Display UI and wait for user interaction
        } else {
            ActivityCompat.requestPermissions(
                this, new String[]{Manifest.permission.LOCATION_FINE},
                REQUEST_LOCATION_PERMISSION_CODE);
        }
    } else {
        // permission has been granted, continue as usual
        Task locationResult = LocationServices
            .getFusedLocationProviderClient(this /** Context */)
            .getLastLocation();
    }

Google Play services API कॉल, अपने-आप एक डायलॉग (अगर क्लाइंट को Activity के साथ इंस्टैंटिएट किया गया है) या सिस्टम ट्रे सूचना (अगर क्लाइंट को Context के साथ इंस्टैंटिएट किया गया है) दिखाएंगे. उपयोगकर्ता इस पर टैप करके, अनुमतियों से जुड़ी समस्या को हल करने का इरादा शुरू कर सकता है. अनुमति मिलने के बाद, कॉल को कतार में रखा जाएगा और फिर से कॉल करने की कोशिश की जाएगी.