Android 位置运行时权限
Android Location runtime permissions
我知道这类题经常出现在stack overflow上。我看了很多有类似问题的帖子,阅读了官方文档,但最终我还是无法理解 android 中的运行时权限是如何工作的。
首先我得到以下错误:
Call requires permissions which may be rejected by user
当我生成 Android Studio 建议的代码时,我得到:
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.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;
}
我的第一个问题是:如果我只想使用精确定位,我是否还要检查粗略定位权限?
接下来我该做什么?我应该在生成的代码的括号中包含什么?我如何以及在哪里请求权限?
这是我必须包含权限的代码部分(mLastLocation 行):
private void displayLocation() {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
lblLocation.setText(latitude + ", " + longitude);
} else {
lblLocation.setText("(Couldn't get the location. Make sure location is enabled on the device)");
}
}
Android清单中定义的权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
非常感谢!
if I want to use only fine location, do I have anyway to check the Coarse Location permissions also?
没有。请理解 IDE 快速修复是没有很多智能的模板。
What should I include in the brackets of the generated code? How and where do I request the permissions?
好吧,生成的代码注释中对此进行了解释。在该块中,调用 ActivityCompat.requestPermissions()
请求您的许可。在用户授予或拒绝权限后,您将在 onRequestPermissionsResult()
中被调用。
然后,您将在两个地方调用您的 displayLocation()
方法:
代码为您生成的 if
的 else
块
在onRequestPermissionsResult()
中,如果用户授予了权限
This sample app 演示了请求权限和处理 Play 服务集成作为查找设备位置的一部分。
此外,关于您的 displayLocation()
方法,不要假设 getLastLocation()
总是 return 一个位置。即使可能启用了提供程序,设备目前也可能无法跟踪其位置。
好位置:
Fine 位置提供更好和准确的 locations.It 允许同时使用 GPS_PROVIDER 和 NETWORK_PROVIDER
粗略定位:
粗略定位提供的精度较低 locations.It 允许使用两者 NETWORK_PROVIDER 仅用于确定位置。
上下文:
上下文允许访问特定于应用程序的资源和 classes,以及向上调用应用程序级操作,例如启动活动、广播和接收意图等。
您可以使用以下 class
启用权限
UtilityLocation.Java
public class UtilityLocation {
public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 123;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static boolean checkPermission(final Context context)
{
int currentAPIVersion = Build.VERSION.SDK_INT;
if(currentAPIVersion>= Build.VERSION_CODES.M)
{
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.ACCESS_FINE_LOCATION)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Permission necessary");
alertBuilder.setMessage("Camera 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.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
} else {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
return false;
} else {
return true;
}
} else {
return true;
}
}
}
MainActivity.Java
检查权限是否启用
Private Context mContext;
mContext=MainActivty.this;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// only for gingerbread and newer versions
boolean resultLocation = UtilityLocation.checkPermission(mContext);
if (resultLocation) {
//Allow Permission and Call your Location Activity.
}
} else {
//Call your Location Activity
}
}
我知道这类题经常出现在stack overflow上。我看了很多有类似问题的帖子,阅读了官方文档,但最终我还是无法理解 android 中的运行时权限是如何工作的。
首先我得到以下错误:
Call requires permissions which may be rejected by user
当我生成 Android Studio 建议的代码时,我得到:
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.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;
}
我的第一个问题是:如果我只想使用精确定位,我是否还要检查粗略定位权限?
接下来我该做什么?我应该在生成的代码的括号中包含什么?我如何以及在哪里请求权限?
这是我必须包含权限的代码部分(mLastLocation 行):
private void displayLocation() {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
lblLocation.setText(latitude + ", " + longitude);
} else {
lblLocation.setText("(Couldn't get the location. Make sure location is enabled on the device)");
}
}
Android清单中定义的权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
非常感谢!
if I want to use only fine location, do I have anyway to check the Coarse Location permissions also?
没有。请理解 IDE 快速修复是没有很多智能的模板。
What should I include in the brackets of the generated code? How and where do I request the permissions?
好吧,生成的代码注释中对此进行了解释。在该块中,调用 ActivityCompat.requestPermissions()
请求您的许可。在用户授予或拒绝权限后,您将在 onRequestPermissionsResult()
中被调用。
然后,您将在两个地方调用您的 displayLocation()
方法:
代码为您生成的
if
的else
块在
onRequestPermissionsResult()
中,如果用户授予了权限
This sample app 演示了请求权限和处理 Play 服务集成作为查找设备位置的一部分。
此外,关于您的 displayLocation()
方法,不要假设 getLastLocation()
总是 return 一个位置。即使可能启用了提供程序,设备目前也可能无法跟踪其位置。
好位置:
Fine 位置提供更好和准确的 locations.It 允许同时使用 GPS_PROVIDER 和 NETWORK_PROVIDER
粗略定位:
粗略定位提供的精度较低 locations.It 允许使用两者 NETWORK_PROVIDER 仅用于确定位置。
上下文:
上下文允许访问特定于应用程序的资源和 classes,以及向上调用应用程序级操作,例如启动活动、广播和接收意图等。
您可以使用以下 class
启用权限UtilityLocation.Java
public class UtilityLocation {
public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 123;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static boolean checkPermission(final Context context)
{
int currentAPIVersion = Build.VERSION.SDK_INT;
if(currentAPIVersion>= Build.VERSION_CODES.M)
{
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.ACCESS_FINE_LOCATION)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Permission necessary");
alertBuilder.setMessage("Camera 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.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
} else {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
return false;
} else {
return true;
}
} else {
return true;
}
}
}
MainActivity.Java
检查权限是否启用
Private Context mContext;
mContext=MainActivty.this;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// only for gingerbread and newer versions
boolean resultLocation = UtilityLocation.checkPermission(mContext);
if (resultLocation) {
//Allow Permission and Call your Location Activity.
}
} else {
//Call your Location Activity
}
}