LocationManager के लिए Android चेक अनुमति


97

जब मैं अपनी गतिविधि लेआउट में एक बटन पर क्लिक करता हूं, तो मैं प्रदर्शित करने के लिए जीपीएस निर्देशांक प्राप्त करने की कोशिश कर रहा हूं। निम्नलिखित वह विधि है जिसे बटन पर क्लिक करने पर मुझे बुलाया जाता है:

public void getLocation(View view) {
    TextView tv = (TextView) findViewById(R.id.gps_coord_view);
    LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
    Location loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    tv.setText("Latitude: " + loc.getLatitude() + "\nLongitude: " + loc.getLongitude());
}

मुझे एक त्रुटि मिल रही है जो कहती है

कॉल के लिए अनुमति की आवश्यकता होती है जिसे उपयोगकर्ता द्वारा अस्वीकार किया जा सकता है। अनुमति मिलने पर कोड को स्पष्ट रूप से देखना चाहिए।

मैं इन अनुमतियों को पहले ही अपने में अनुमति दे चुका हूं AndroidManifest। त्रुटि का ध्यान रखा जाता है और जब मैं कॉल करने से पहले निम्न जोड़ता हूं, तो ऐप संकलित करता है lm.getLastKnownLocation:

if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
        && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    return;
}

हालाँकि, जब मैं बटन पर क्लिक करता हूं तो ऐप क्रैश हो जाता है जब इसे क्लिक करने पर GetLocation कहते हैं। क्या हो रहा है? क्या डिवाइस के जीपीएस निर्देशांक को हथियाने के लिए बेहतर / सरल तरीका है?


संभवतः आप एक अपवाद लॉग संलग्न कर सकते हैं।
मिलन

1
ContextCompat.checkSelfPermission (संदर्भ, अनुमति) का उपयोग करें और सुनिश्चित करें कि आपने प्रकट में उपयुक्त अनुमतियों का उल्लेख किया है
स्नेहल सिपाहीकर

जवाबों:


149

Android API स्तर (23) के साथ, हमें अनुमतियों की जांच करनी होगी। https://developer.android.com/training/permissions/requesting.html

मुझे आपकी समान समस्या थी, लेकिन निम्नलिखित ने मेरे लिए काम किया और मैं स्थान डेटा को सफलतापूर्वक प्राप्त करने में सक्षम हूं:

(1) सुनिश्चित करें कि आपके पास मेनिफेस्ट में सूचीबद्ध अपनी अनुमतियां हैं:

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

(2) सुनिश्चित करें कि आप उपयोगकर्ता से अनुमति का अनुरोध करते हैं:

if ( ContextCompat.checkSelfPermission( this, android.Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED ) {

            ActivityCompat.requestPermissions( this, new String[] {  android.Manifest.permission.ACCESS_COARSE_LOCATION  },
                                                LocationService.MY_PERMISSION_ACCESS_COURSE_LOCATION );
        }

(3) सुनिश्चित करें कि आप ContextCompat का उपयोग करें क्योंकि इसमें पुराने API स्तरों के साथ संगतता है।

(4) आपके स्थान सेवा, या वर्ग में जो आपके स्थान प्रबंधक को आरंभ करता है और अंतिम ज्ञात स्थान प्राप्त करता है, हमें अनुमतियों की जाँच करने की आवश्यकता है:

if ( Build.VERSION.SDK_INT >= 23 &&
             ContextCompat.checkSelfPermission( context, android.Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED &&
             ContextCompat.checkSelfPermission( context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return  ;
        }

(५) यह तरीका मेरे लिए काम करने के बाद ही मैंने अपने initLocationService विधि के शीर्ष पर @TargetApi (२३) को शामिल किया।

(६) मैंने इसे अपने ग्रेडेल बिल्ड में भी जोड़ा:

compile 'com.android.support:support-v4:23.0.1'

यहाँ संदर्भ के लिए मेरा स्थान सेवा है:

public class LocationService implements LocationListener  {

    //The minimum distance to change updates in meters
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 10 meters

    //The minimum time between updates in milliseconds
    private static final long MIN_TIME_BW_UPDATES = 0;//1000 * 60 * 1; // 1 minute

    private final static boolean forceNetwork = false;

    private static LocationService instance = null;

    private LocationManager locationManager;
    public Location location;
    public double longitude;
    public double latitude; 


    /**
     * Singleton implementation
     * @return
     */
    public static LocationService getLocationManager(Context context)     {
        if (instance == null) {
            instance = new LocationService(context);
        }
        return instance;
    }

    /**
     * Local constructor
     */
    private LocationService( Context context )     {

        initLocationService(context); 
        LogService.log("LocationService created");
    }



    /**
     * Sets up location service after permissions is granted
     */
    @TargetApi(23)
    private void initLocationService(Context context) {


        if ( Build.VERSION.SDK_INT >= 23 &&
             ContextCompat.checkSelfPermission( context, android.Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED &&
             ContextCompat.checkSelfPermission( context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return  ;
        }

        try   {
            this.longitude = 0.0;
            this.latitude = 0.0;
            this.locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

            // Get GPS and network status
            this.isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            this.isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

            if (forceNetwork) isGPSEnabled = false;

            if (!isNetworkEnabled && !isGPSEnabled)    {
                // cannot get location
                this.locationServiceAvailable = false;
            }
            //else
            {
                this.locationServiceAvailable = true;

                if (isNetworkEnabled) {
                    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    if (locationManager != null)   {
                        location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        updateCoordinates();
                    }
                }//end if

                if (isGPSEnabled)  {
                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

                    if (locationManager != null)  {
                        location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        updateCoordinates();
                    }
                }
            }
        } catch (Exception ex)  {
            LogService.log( "Error creating location service: " + ex.getMessage() );

        }
    }       


    @Override
    public void onLocationChanged(Location location)     {
        // do stuff here with location object 
    }
}

मैंने अब तक केवल एक एंड्रॉइड लॉलीपॉप डिवाइस के साथ परीक्षण किया। उम्मीद है इससे आपका काम बनेगा।


2
मुझे आपका समाधान पसंद है, लेकिन आपको यह जांचना चाहिए कि क्या उसका उपयोग करने से पहले लोकेशन मैनेज अशक्त है या नहीं।
फेर

9
LocationService.MY_PERMISSION_ACCESS_COURSE_LOCATION इस पंक्ति में 23 से काम नहीं करता है

4
LocationService.MY_PERMISSION_ACCESS_COURSE_LOCATION मेरे लिए भी काम नहीं कर रहा है।
काइरी सैन

1
@delive, LocationService.MY_PERMISSION_ACCESS_COURSE_LOCATION -> आपको इस इंट कोड को अपनी स्वयं की गतिविधि में परिभाषित करना होगा (जो कि गतिविधिकंपनी लागू की गई। RnRestestPeaksResultCallback), विवरण के लिए कृपया इस लिंक की जाँच करें ।
डेविड चेउंग

11
COARSE नहीं COURSE
क्रिस कॉक्स

46

सरल समाधान

मैं एप प्री 23 का समर्थन करना चाहता था और इसके बजाय checkSelfPermissionमैंने कोशिश / कैच का इस्तेमाल किया

try {
   location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
} catch (SecurityException e) {
   dialogGPS(this.getContext()); // lets the user know there is a problem with the gps
}

39

आपके द्वारा उद्धृत त्रुटि संदेश का अंतिम भाग: ...with ("checkPermission") or explicitly handle a potential "SecurityException"

यदि आपके पास अनुमतियाँ हैं, तो जाँच करने का एक बहुत तेज़ / सरल तरीका try { ... } catch (SecurityException e) { [insert error handling code here] }। यदि आपके पास अनुमति है, तो 'कोशिश' भाग निष्पादित करेगा, यदि आप नहीं करते हैं, तो 'कैच' भाग होगा।


1
यदि आपके पास कोई गतिविधि या संदर्भ वस्तु नहीं है, तो आप इसके लिए अनुमतियों की जांच कर सकते हैं।
नूब्लोडेवलप्टर

5

परमिसन की जांच या अनुरोध करने के लिए मेरे कस्टोम वर्ग का उपयोग करें

public class Permissons {

        //Request Permisson
        public static void Request_STORAGE(Activity act,int code)
        {

            ActivityCompat.requestPermissions(act, new
                    String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},code);
        }
        public static void Request_CAMERA(Activity act,int code)
        {
            ActivityCompat.requestPermissions(act, new
                    String[]{Manifest.permission.CAMERA},code);
        }
        public static void Request_FINE_LOCATION(Activity act,int code)
        {
            ActivityCompat.requestPermissions(act, new
                    String[]{Manifest.permission.ACCESS_FINE_LOCATION},code);
        }
        public static void Request_READ_SMS(Activity act,int code)
        {
            ActivityCompat.requestPermissions(act, new
                    String[]{Manifest.permission.READ_SMS},code);
        }
        public static void Request_READ_CONTACTS(Activity act,int code)
        {
            ActivityCompat.requestPermissions(act, new
                    String[]{Manifest.permission.READ_CONTACTS},code);
        }
        public static void Request_READ_CALENDAR(Activity act,int code)
        {
            ActivityCompat.requestPermissions(act, new
                    String[]{Manifest.permission.READ_CALENDAR},code);
        }
        public static void Request_RECORD_AUDIO(Activity act,int code)
        {
            ActivityCompat.requestPermissions(act, new
                    String[]{Manifest.permission.RECORD_AUDIO},code);
        }

        //Check Permisson
        public static boolean Check_STORAGE(Activity act)
        {
            int result = ContextCompat.checkSelfPermission(act,android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
            return result == PackageManager.PERMISSION_GRANTED;
        }
        public static boolean Check_CAMERA(Activity act)
        {
            int result = ContextCompat.checkSelfPermission(act, Manifest.permission.CAMERA);
            return result == PackageManager.PERMISSION_GRANTED;
        }
        public static boolean Check_FINE_LOCATION(Activity act)
        {
            int result = ContextCompat.checkSelfPermission(act, Manifest.permission.ACCESS_FINE_LOCATION);
            return result == PackageManager.PERMISSION_GRANTED;
        }
        public static boolean Check_READ_SMS(Activity act)
        {
            int result = ContextCompat.checkSelfPermission(act, Manifest.permission.READ_SMS);
            return result == PackageManager.PERMISSION_GRANTED;
        }
        public static boolean Check_READ_CONTACTS(Activity act)
        {
            int result = ContextCompat.checkSelfPermission(act, Manifest.permission.READ_CONTACTS);
            return result == PackageManager.PERMISSION_GRANTED;
        }
        public static boolean Check_READ_CALENDAR(Activity act)
        {
            int result = ContextCompat.checkSelfPermission(act, Manifest.permission.READ_CALENDAR);
            return result == PackageManager.PERMISSION_GRANTED;
        }
        public static boolean Check_RECORD_AUDIO(Activity act)
        {
            int result = ContextCompat.checkSelfPermission(act, Manifest.permission.RECORD_AUDIO);
            return result == PackageManager.PERMISSION_GRANTED;
        }
    }

उदाहरण

if(!Permissons.Check_STORAGE(MainActivity.this))
{
   //if not permisson granted so request permisson with request code
   Permissons.Request_STORAGE(MainActivity.this,22);
}

धन्यवाद, लेकिन मैं पूछना चाहता हूं, "int code" का क्या कार्य है?
हेंड्रो प्रमोनो

इस कोड का उपयोग करने के लिए अनुमति दी गई है या गतिविधि के परिणाम पर गिरावट आई है
मिल्टन पिथडिया

4

यदि आप डायनामिक अनुमतियों पर काम कर रहे हैं और ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION देने में कोई त्रुटि "पद्धति PERMISSION_NAME को हल नहीं कर सकता है" तो इस मामले में आप अनुमति नाम के साथ कोड लिखते हैं और फिर अपनी परियोजना का पुनर्निर्माण करते हैं यह प्रकट (Manifest.permission) फ़ाइल को फिर से बनाएगा।


0

यदि आप केवल अनुमति के लिए जांच करना चाहते हैं (अनुमति के लिए अनुरोध के बजाय), तो मैंने एक सरल एक्सटेंशन लिखा है:

fun BaseActivity.checkPermission(permissionName: String): Boolean {
        return if (Build.VERSION.SDK_INT >= 23) {
            val granted =
                ContextCompat.checkSelfPermission(this, permissionName)
            granted == PackageManager.PERMISSION_GRANTED
        } else {
            val granted =
                PermissionChecker.checkSelfPermission(this, permissionName)
            granted == PermissionChecker.PERMISSION_GRANTED
        }
    }

अब, अगर मैं एक अनुमति के लिए जाँच करना चाहता हूँ तो मैं बस एक अनुमति में पास कर सकता हूँ जैसे:

checkPermission(Manifest.permission.READ_CONTACTS)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.