检查用户位置的权限

时间:2018-01-11 11:47:48

标签: android android-permissions android-location

我一直在关注Android开发者教程,以获取用户的最后一个已知位置:https://developer.android.com/training/location/retrieve-current.html。我按照步骤操作,得到以下错误:Call requires permissions which may be reject by the user: code should explicitly check to see if the permission is available (with checkPermission) or explicitly handle a potential SecurityException

在研究了一下后,我决定创建一个checkPermissions方法来检查权限,但是我仍然得到上面提到的相同错误。

清单中的权限

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

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

getLocation方法

public class ImageGalleryFragment extends Fragment {
    // Instance variables
    private static final int REQUEST_READ_EXTERNAL_STORAGE = 2987;
    private static final int REQUEST_WRITE_EXTERNAL_STORAGE = 7829;
    private static final int REQUEST_COARSE_LOCATION = 200;
    private FusedLocationProviderClient mFusedLocationClient;

    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this.getActivity());

        checkPermissions(this.getContext());

        mFusedLocationClient.getLastLocation()
            .addOnSuccessListener(this.getActivity(), new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    // Got last known location. In some rare situations this can be null.
                    if (location != null) {
                        // Logic to handle location object
                    }
                }
    }

    ...
}

checkPermissions方法

public class ImageGalleryFragment extends Fragment {

    ...

    private void checkPermissions(final Context context) {
    int currentAPIVersion = Build.VERSION.SDK_INT;

    if (currentAPIVersion >= android.os.Build.VERSION_CODES.M) {
        // Access coarse location permission check
        if (ContextCompat.checkSelfPermission(this.getActivity(),
                Manifest.permission.ACCESS_COARSE_LOCATION) !=
                PackageManager.PERMISSION_GRANTED) {
            // Check if explanation required
            if (ActivityCompat.shouldShowRequestPermissionRationale(this.getActivity(),
                    Manifest.permission.ACCESS_COARSE_LOCATION)) {
                // Provide explanation
                AlertDialog.Builder alertBuilder = new android.support.v7.app.AlertDialog.Builder(context);
                alertBuilder.setCancelable(true);
                alertBuilder.setTitle("Permission necessary");
                alertBuilder.setMessage("Access coarse location permission is necessary to save location to images");
                alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_COARSE_LOCATION);
                    }
                });
                AlertDialog alert = alertBuilder.create();
                alert.show();
            }
            else {
                // No explanation required, request permission
                ActivityCompat.requestPermissions(this.getActivity(),
                        new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                        REQUEST_COARSE_LOCATION);
            }
        }


        if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)) {
                AlertDialog.Builder alertBuilder = new android.support.v7.app.AlertDialog.Builder(context);
                alertBuilder.setCancelable(true);
                alertBuilder.setTitle("Permission necessary");
                alertBuilder.setMessage("Reading external storage permission is necessary");
                alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_READ_EXTERNAL_STORAGE);
                    }
                });
                AlertDialog alert = alertBuilder.create();
                alert.show();

            } else {
                ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_READ_EXTERNAL_STORAGE);
            }

        }
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                android.support.v7.app.AlertDialog.Builder alertBuilder = new android.support.v7.app.AlertDialog.Builder(context);
                alertBuilder.setCancelable(true);
                alertBuilder.setTitle("Permission necessary");
                alertBuilder.setMessage("Writing external storage permission is necessary");
                alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_EXTERNAL_STORAGE);
                    }
                });
                android.support.v7.app.AlertDialog alert = alertBuilder.create();
                alert.show();

            } else {
                ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_EXTERNAL_STORAGE);
            }

        }

    }
}

    ...


}

1 个答案:

答案 0 :(得分:1)

您已经实施了检查权限代码但是您错了。这是一个很好的路线图。

  1. 当片段/活动开始时,请求用户或您需要访问用户位置的操作的位置。
  2. 当用户授予位置权限时,请获取位置(仅在此条件下,否则您将收到错误,如您所示)
  3. 当用户允许您获得位置权限时,您可以在 @Override中获得结果 public void onRequestPermissionsResult(int requestCode,     字符串权限[],int [] grantResults){ switch(requestCode){
  4. 我坚信您在以下一行中遇到错误

     mFusedLocationClient.getLastLocation()
                .addOnSuccessListener(this.getActivity(), new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        // Got last known location. In some rare situations this can be null.
                        if (location != null) {
                            // Logic to handle location object
                        }
                    }
    

    因此您必须向用户显示您必须允许位置以保持应用程序正常工作,如果需要该权限,您可以显示RequestPermissionRationale对话框,如果他取消它,您可以简单地退出活动。

    我也看到你对如何请求运行时权限没有明确的概念。我看到你已经立即检查了所有权限。

    这不是正确的方法。对于不同的权限,您必须逐个询问。例如,您可以询问位置,如果对于应用程序来说需要太多,如果用户不允许,您可以退出活动,或者如果用户允许,您可以继续请求读/写外部存储权限。

    所以这是请求权限的流程。这是一个link,看看他是如何获得许可的。在这里,您可以在本教程中看到多个权限。