【发布时间】:2026-01-29 08:10:02
【问题描述】:
我一直在按照 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);
}
}
}
}
...
}
【问题讨论】:
-
您是否在 AndroidManifest.xml 文件中添加了位置权限?
-
@hardartcore 是的,刚刚编辑了我的问题以包含清单权限
-
对不起,我刚刚看到......你做错了。您正在检查权限状态,但实际上您并不真正关心是否可以使用该位置并直接调用“getLastLocation”。您在这里有几个选项,但您可以尝试编辑“checkPermissions”并使其返回布尔值(如果已授予权限),如果为真,则尝试获取最后一个位置。
-
啊,好吧,我将如何创建一个布尔 checkLocationPermission() 方法以在授予权限后返回 true?
-
'ContextCompat.checkSelfPermission' 已经在这样做了。如果您的应用程序可以使用该位置,它会返回。也许从该方法返回布尔值并不是一个很好的选择,这只是一个想法。您可以创建不同的场景如何正确处理这种情况:) 这完全取决于您
标签: android android-permissions android-location