如何在运行时请求位置权限

时间:2016-10-19 22:09:13

标签: java android

在清单文件中,我添加了粗略和精细的权限,当我在使用Android 6的设备上运行时,没有任何反应!我试试 一切,但无法获得位置更新......

我做错了什么?

public class MainActivity extends AppCompatActivity implements LocationListener {

    LocationManager locationManager;
    String provider;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        provider = locationManager.getBestProvider(new Criteria(), false);

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        Location location = locationManager.getLastKnownLocation(provider);

        if (location != null) {

            Log.i("Location Info", "Location achieved!");

        } else {

            Log.i("Location Info", "No location :(");

        }

    }


    @Override
    protected void onResume() {
        super.onResume();

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        locationManager.requestLocationUpdates(provider, 400, 1, this);

    }

    @Override
    protected void onPause() {
        super.onPause();

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        locationManager.removeUpdates(this);

    }

    @Override
    public void onLocationChanged(Location location) {

        Double lat = location.getLatitude();
        Double lng = location.getLongitude();

        Log.i("Location info: Lat", lat.toString());
        Log.i("Location info: Lng", lng.toString());

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    public void getLocation(View view) {

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        Location location = locationManager.getLastKnownLocation(provider);

        onLocationChanged(location);


    }

}

8 个答案:

答案 0 :(得分:84)

您需要在运行时实际请求位置权限(请注意代码中的注释,说明这一点。)

这是经过测试和运行的代码,可以请求位置权限。

请务必导入android.Manifest

import android.Manifest;

然后将此代码放入Activity:

public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;

public boolean checkLocationPermission() {
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION)) {

            // Show an explanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.
            new AlertDialog.Builder(this)
                    .setTitle(R.string.title_location_permission)
                    .setMessage(R.string.text_location_permission)
                    .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            //Prompt the user once explanation has been shown
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                    MY_PERMISSIONS_REQUEST_LOCATION);
                        }
                    })
                    .create()
                    .show();


        } else {
            // No explanation needed, we can request the permission.
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_LOCATION);
        }
        return false;
    } else {
        return true;
    }
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // location-related task you need to do.
                if (ContextCompat.checkSelfPermission(this,
                        Manifest.permission.ACCESS_FINE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED) {

                    //Request location updates:
                    locationManager.requestLocationUpdates(provider, 400, 1, this);
                }

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.

            }
            return;
        }

    }
}

然后在checkLocationPermission()中调用onCreate()方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //.........

    checkLocationPermission();
}

然后,您可以完全按照问题使用onResume()onPause()

这是一个更简洁的浓缩版本:

@Override
protected void onResume() {
    super.onResume();
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {

        locationManager.requestLocationUpdates(provider, 400, 1, this);
    }
}

@Override
protected void onPause() {
    super.onPause();
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {

        locationManager.removeUpdates(this);
    }
}

答案 1 :(得分:10)

Android 10 Android Q 中的位置权限隐私更改。

如果用户要在后台访问其当前位置,则我们必须定义其他 ACCESS_BACKGROUND_LOCATION 权限,因此用户也需要在{{1 }}

如果我们使用的是低于Android 10的设备,则 requestPermission() 权限具有ACCESS_BACKGROUND_LOCATIONACCESS_FINE_LOCATION权限会自动允许 >

如果我们未在清单文件中指定ACCESS_COARSE_LOCATION,该表格格式可能很容易理解。

enter image description here

AndroidManifest.xml

ACCESS_BACKGROUND_LOCATION

MainActivity.java
致电<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> // here we defined ACCESS_BACKGROUND_LOCATION for Android 10 device checkRunTimePermission()

中的onCreate()
onResume()

build.gradle(应用级)

public void checkRunTimePermission() {
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED || 
             ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED||
             ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                gpsTracker = new GPSTracker(context);

        } else {
                requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION},
                        10);
        }
   } else {
            gpsTracker = new GPSTracker(context); //GPSTracker is class that is used for retrieve user current location
   }
}

 @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 10) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            gpsTracker = new GPSTracker(context);
        } else {
            if (!ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.ACCESS_FINE_LOCATION)) {
                // If User Checked 'Don't Show Again' checkbox for runtime permission, then navigate user to Settings
                AlertDialog.Builder dialog = new AlertDialog.Builder(context);
                dialog.setTitle("Permission Required");
                dialog.setCancelable(false);
                dialog.setMessage("You have to Allow permission to access user location");
                dialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent i = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.fromParts("package",
                                context.getPackageName(), null));
                        //i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivityForResult(i, 1001);
                    }
                });
                AlertDialog alertDialog = dialog.create();
                alertDialog.show();
            }
            //code for deny
        }
    }
}

@Override
public void startActivityForResult(Intent intent, int requestCode) {
    super.startActivityForResult(intent, requestCode);
    switch (requestCode) {
        case 1001:
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED ||
                        ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED 
                        || ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    gpsTracker = new GPSTracker(context);
                    if (gpsTracker.canGetLocation()) {
                        latitude = gpsTracker.getLatitude();
                        longitude = gpsTracker.getLongitude();
                    }
                } else {
                    requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_BACKGROUND_LOCATION},10);
                }
            }
            break;
        default:
            break;
    }
}

Here您可以找到android { compileSdkVersion 29 //should be >= 29 buildToolsVersion "29.0.2" useLibrary 'org.apache.http.legacy' defaultConfig { applicationId "com.example.runtimepermission" minSdkVersion 21 targetSdkVersion 29 //should be >= 29 versionCode 1 versionName "1.0" multiDexEnabled true testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true } } 文件代码

答案 2 :(得分:8)

Google创建了一个用于轻松进行权限管理的库。它叫EasyPermissions

这是使用此库请求位置权限的简单示例。

public class MainActivity extends AppCompatActivity {

    private final int REQUEST_LOCATION_PERMISSION = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        requestLocationPermission();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        // Forward results to EasyPermissions
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    @AfterPermissionGranted(REQUEST_LOCATION_PERMISSION)
    public void requestLocationPermission() {
        String[] perms = {Manifest.permission.ACCESS_FINE_LOCATION};
        if(EasyPermissions.hasPermissions(this, perms)) {
            Toast.makeText(this, "Permission already granted", Toast.LENGTH_SHORT).show();
        }
        else {
            EasyPermissions.requestPermissions(this, "Please grant the location permission", REQUEST_LOCATION_PERMISSION, perms);
        }
    }
}

@AfterPermissionsGranted(REQUEST_CODE)用于指示在授予带有请求代码REQUEST_CODE的权限请求后需要执行的方法。

在上述情况下,如果用户授予访问位置服务的权限,则调用方法requestLocationPermission()。因此,该方法既充当回调,又充当请求权限的方法。

您可以为授予的权限和拒绝的权限分别实现回调。在github页面中有解释。

答案 3 :(得分:3)

我喜欢短代码。我使用RxPermission获得许可。

首先在manifest.xml中添加这些权限(或您需要的权限)。

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

然后在您的活动中向用户询问运行时权限。

RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions
.request(Manifest.permission.ACCESS_FINE_LOCATION,
         Manifest.permission.ACCESS_COARSE_LOCATION) // ask single or multiple permission once
.subscribe(granted -> {
    if (granted) {
       // All requested permissions are granted
    } else {
       // At least one permission is denied
    }
});

将此库添加到您的build.gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

dependencies {
    implementation 'com.github.tbruyelle:rxpermissions:0.10.1'
    implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
}

这不容易吗?

答案 4 :(得分:0)

此代码对我有用。我还处理了案件“从不问我”

在AndroidManifest.xml

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

在build.gradle中(模块:应用)

dependencies {
    ....
    implementation "com.google.android.gms:play-services-location:16.0.0"
}

这是CurrentLocationManager.kt

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.IntentSender
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.os.Bundle
import android.os.CountDownTimer
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.util.Log
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.common.api.CommonStatusCodes
import com.google.android.gms.common.api.ResolvableApiException
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.LocationSettingsRequest
import com.google.android.gms.location.LocationSettingsStatusCodes
import java.lang.ref.WeakReference


object CurrentLocationManager : LocationListener {

    const val REQUEST_CODE_ACCESS_LOCATION = 123

    fun checkLocationPermission(activity: Activity) {
        if (ContextCompat.checkSelfPermission(
                activity,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(
                activity,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                REQUEST_CODE_ACCESS_LOCATION
            )
        } else {
            Thread(Runnable {
                // Moves the current Thread into the background
                android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND)
                //
                requestLocationUpdates(activity)
            }).start()
        }
    }

    /**
     * be used in HomeActivity.
     */
    const val REQUEST_CHECK_SETTINGS = 55
    /**
     * The number of millis in the future from the call to start().
     * until the countdown is done and onFinish() is called.
     *
     *
     * It is also the interval along the way to receive onTick(long) callbacks.
     */
    private const val TWENTY_SECS: Long = 20000
    /**
     * Timer to get location from history when requestLocationUpdates don't return result.
     */
    private var mCountDownTimer: CountDownTimer? = null
    /**
     * WeakReference of current activity.
     */
    private var mWeakReferenceActivity: WeakReference<Activity>? = null
    /**
     * user's location.
     */
    var currentLocation: Location? = null

    @Synchronized
    fun requestLocationUpdates(activity: Activity) {
        if (mWeakReferenceActivity == null) {
            mWeakReferenceActivity = WeakReference(activity)
        } else {
            mWeakReferenceActivity?.clear()
            mWeakReferenceActivity = WeakReference(activity)
        }
        //create location request: https://developer.android.com/training/location/change-location-settings.html#prompt
        val mLocationRequest = LocationRequest()
        // Which your app prefers to receive location updates. Note that the location updates may be
        // faster than this rate, or slower than this rate, or there may be no updates at all
        // (if the device has no connectivity)
        mLocationRequest.interval = 20000
        //This method sets the fastest rate in milliseconds at which your app can handle location updates.
        // You need to set this rate because other apps also affect the rate at which updates are sent
        mLocationRequest.fastestInterval = 10000
        mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY

        //Get Current Location Settings
        val builder = LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest)
        //Next check whether the current location settings are satisfied
        val client = LocationServices.getSettingsClient(activity)
        val task = client.checkLocationSettings(builder.build())
        //Prompt the User to Change Location Settings
        task.addOnSuccessListener(activity) {
            Log.d("CurrentLocationManager", "OnSuccessListener")
            // All location settings are satisfied. The client can initialize location requests here.
            // If it's failed, the result after user updated setting is sent to onActivityResult of HomeActivity.
            val activity1 = mWeakReferenceActivity?.get()
            if (activity1 != null) {
                startRequestLocationUpdate(activity1.applicationContext)
            }
        }

        task.addOnFailureListener(activity) { e ->
            Log.d("CurrentLocationManager", "addOnFailureListener")
            val statusCode = (e as ApiException).statusCode
            when (statusCode) {
                CommonStatusCodes.RESOLUTION_REQUIRED ->
                    // Location settings are not satisfied, but this can be fixed
                    // by showing the user a dialog.
                    try {
                        val activity1 = mWeakReferenceActivity?.get()
                        if (activity1 != null) {
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            val resolvable = e as ResolvableApiException
                            resolvable.startResolutionForResult(
                                activity1, REQUEST_CHECK_SETTINGS
                            )
                        }
                    } catch (sendEx: IntentSender.SendIntentException) {
                        // Ignore the error.
                        sendEx.printStackTrace()
                    }

                LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
                    // Location settings are not satisfied. However, we have no way
                    // to fix the settings so we won't show the dialog.
                }
            }
        }
    }

    fun startRequestLocationUpdate(appContext: Context) {
        val mLocationManager = appContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
        if (ActivityCompat.checkSelfPermission(
                appContext.applicationContext,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED
        ) {
            //Utilities.showProgressDialog(mWeakReferenceActivity.get());
            if (mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
                mLocationManager.requestLocationUpdates(
                    LocationManager.NETWORK_PROVIDER, 10000, 0f, this
                )
            } else {
                mLocationManager.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER, 10000, 0f, this
                )
            }
        }

        /*Timer to call getLastKnownLocation() when requestLocationUpdates don 't return result*/
        countDownUpdateLocation()
    }

    override fun onLocationChanged(location: Location?) {
        if (location != null) {
            stopRequestLocationUpdates()
            currentLocation = location
        }
    }

    override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {

    }

    override fun onProviderEnabled(provider: String) {

    }

    override fun onProviderDisabled(provider: String) {

    }

    /**
     * Init CountDownTimer to to get location from history when requestLocationUpdates don't return result.
     */
    @Synchronized
    private fun countDownUpdateLocation() {
        mCountDownTimer?.cancel()
        mCountDownTimer = object : CountDownTimer(TWENTY_SECS, TWENTY_SECS) {
            override fun onTick(millisUntilFinished: Long) {}

            override fun onFinish() {
                if (mWeakReferenceActivity != null) {
                    val activity = mWeakReferenceActivity?.get()
                    if (activity != null && ActivityCompat.checkSelfPermission(
                            activity,
                            Manifest.permission.ACCESS_FINE_LOCATION
                        ) == PackageManager.PERMISSION_GRANTED
                    ) {
                        val location = (activity.applicationContext
                            .getSystemService(Context.LOCATION_SERVICE) as LocationManager)
                            .getLastKnownLocation(LocationManager.PASSIVE_PROVIDER)
                        stopRequestLocationUpdates()
                        onLocationChanged(location)
                    } else {
                        stopRequestLocationUpdates()
                    }
                } else {
                    mCountDownTimer?.cancel()
                    mCountDownTimer = null
                }
            }
        }.start()
    }

    /**
     * The method must be called in onDestroy() of activity to
     * removeUpdateLocation and cancel CountDownTimer.
     */
    fun stopRequestLocationUpdates() {
        val activity = mWeakReferenceActivity?.get()
        if (activity != null) {
            /*if (ActivityCompat.checkSelfPermission(activity,
                    Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {*/
            (activity.applicationContext
                .getSystemService(Context.LOCATION_SERVICE) as LocationManager).removeUpdates(this)
            /*}*/
        }
        mCountDownTimer?.cancel()
        mCountDownTimer = null
    }
}

在MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
...
CurrentLocationManager.checkLocationPermission(this@LoginActivity)
}

override fun onDestroy() {
        CurrentLocationManager.stopRequestLocationUpdates()
        super.onDestroy()
    }


    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == CurrentLocationManager.REQUEST_CODE_ACCESS_LOCATION) {
            if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
                //denied
                val builder = AlertDialog.Builder(this)
                builder.setMessage("We need permission to use your location for the purpose of finding friends near you.")
                    .setTitle("Device Location Required")
                    .setIcon(com.eswapp.R.drawable.ic_info)
                    .setPositiveButton("OK") { _, _ ->
                        if (ActivityCompat.shouldShowRequestPermissionRationale(
                                this,
                                Manifest.permission.ACCESS_FINE_LOCATION
                            )
                        ) {
                            //only deny
                            CurrentLocationManager.checkLocationPermission(this@LoginActivity)
                        } else {
                            //never ask again
                            val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                            val uri = Uri.fromParts("package", packageName, null)
                            intent.data = uri
                            startActivityForResult(intent, CurrentLocationManager.REQUEST_CHECK_SETTINGS)
                        }
                    }
                    .setNegativeButton("Ask Me Later") { _, _ ->

                    }
                // Create the AlertDialog object and return it
                val dialog = builder.create()
                dialog.show()
            } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                CurrentLocationManager.requestLocationUpdates(this)
            }
        }
    }

    //Forward Login result to the CallBackManager in OnActivityResult()
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        when (requestCode) {
            //case 1. After you allow the app access device location, Another dialog will be displayed to request you to turn on device location
            //case 2. Or You chosen Never Ask Again, you open device Setting and enable location permission
            CurrentLocationManager.REQUEST_CHECK_SETTINGS -> when (resultCode) {
                RESULT_OK -> {
                    Log.d("REQUEST_CHECK_SETTINGS", "RESULT_OK")
                    //case 1. You choose OK
                    CurrentLocationManager.startRequestLocationUpdate(applicationContext)
                }
                RESULT_CANCELED -> {
                    Log.d("REQUEST_CHECK_SETTINGS", "RESULT_CANCELED")
                    //case 1. You choose NO THANKS
                    //CurrentLocationManager.requestLocationUpdates(this)

                    //case 2. In device Setting screen: user can enable or not enable location permission,
                    // so when user back to this activity, we should re-call checkLocationPermission()
                    CurrentLocationManager.checkLocationPermission(this@LoginActivity)
                }
                else -> {
                    //do nothing
                }
            }
            else -> {
                super.onActivityResult(requestCode, resultCode, data)
            }
        }
    }

答案 5 :(得分:0)

从MainActivity检查此代码

 // Check location permission is granted - if it is, start
// the service, otherwise request the permission
fun checkOrAskLocationPermission(callback: () -> Unit) {
    // Check GPS is enabled
    val lm = getSystemService(Context.LOCATION_SERVICE) as LocationManager
    if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        Toast.makeText(this, "Please enable location services", Toast.LENGTH_SHORT).show()
        buildAlertMessageNoGps(this)
        return
    }

    // Check location permission is granted - if it is, start
    // the service, otherwise request the permission
    val permission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
    if (permission == PackageManager.PERMISSION_GRANTED) {
        callback.invoke()
    } else {
        // callback will be inside the activity's onRequestPermissionsResult(
        ActivityCompat.requestPermissions(
            this,
            arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
            PERMISSIONS_REQUEST
        )
    }
}

   override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == PERMISSIONS_REQUEST) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
              // Permission ok. Do work.
         }
    }
}

 fun buildAlertMessageNoGps(context: Context) {
    val builder = AlertDialog.Builder(context);
    builder.setMessage("Your GPS is disabled. Do you want to enable it?")
        .setCancelable(false)
        .setPositiveButton("Yes") { _, _ -> context.startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)) }
        .setNegativeButton("No") { dialog, _ -> dialog.cancel(); }
    val alert = builder.create();
    alert.show();
}

用法

checkOrAskLocationPermission() {
            // Permission ok. Do work.
        }

答案 6 :(得分:0)

在清单文件中定义它之后,可以使用Aaper:https://github.com/LikeTheSalad/aaper来代替本机解决方案,这是一种更友好的选择:

@EnsurePermissions(permissions = [Manifest.permission.ACCESS_FINE_LOCATION])
private fun scanForLocation() {
    // Your code that needs the location permission granted.
}

免责声明,我是Aaper的创建者。

答案 7 :(得分:0)

正在寻找更简单的代码?试试这个!

if (ContextCompat.checkSelfPermission(LoginActivity.this,
            Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(LoginActivity.this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CALL);
    }

另外,别忘了明确请求权限