权限:调用需要权限,用户可能会拒绝
Permission: Call requires permission which may be rejected by user
在 Android Studio 下编译时,我收到了此 post 标题中指定的警告。我尝试使用以下代码获取 GPS 更新:
try {
LocMgr = (LocationManager)getSystemService( LOCATION_SERVICE );
LocMgr.requestLocationUpdates( K.GPS_PROVIDER, 0, 0, this );
//LocMgr.addNmeaListener( this ); // NMEA
}
catch(Exception e) {
UI.warningBox( this, "GPS appears to be either absent or disabled" );
}
奇怪的是,我的应用程序在没有任何 run-time 许可请求的情况下仍然 工作正常。我做了但是在清单中请求权限。
uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
我并不不高兴,但我期待失败或至少是安全异常。
为什么 Android Studio 如此(出乎意料地)宽容?
顺便说一下,我模块的 gradle 脚本包括
defaultConfig {
applicationId "MY_APP_ID"
minSdkVersion 11
targetSdkVersion 26
}
您 运行 您的应用程序使用的 android 是什么版本?在 marshmallow(api 级别 23)之前,您可以在不实际征求用户许可的情况下访问许多服务,例如 LocationService。
您甚至可以在不征求许可的情况下使用 wifi 和蓝牙。那时候是权限的狂野西部。从那以后这已经改变了,因为你的最高级别 api 可能会请求权限(你没有处理),这就是你收到警告
的原因
另外,如果您有权访问 google 服务,您应该改用 fusedlocationprovider,locationservice 在不创建服务以持续轮询它的情况下不会提供有效结果。
您的应用在 运行 时间内没有请求权限,因为您没有添加代码。此外,最近 Android 添加了 运行 时间权限(我猜是从 Android M 开始的)。
因此,在之前的 Android 版本中,您的应用将正常运行,因为您只需要将权限添加到清单中。
在新版本上,您必须在 运行 时额外请求权限。缺少权限并不总是会导致崩溃。它们只能在日志等方面生成警告。
无论如何,要消除该警告,您必须在 运行 时请求许可。下面,你可以找到一个小例子:
public class MainActivity extends AppCompatActivity implements LocationListener {
private final static int LOCATION_PERMISSION_CODE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....
try {
LocMgr = (LocationManager) getSystemService(LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// Missing both permissions. User didn't accept them yet. Request
ActivityCompat.requestPermissions(this, new String[] {permission.ACCESS_FINE_LOCATION, permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_CODE);
} else {
// Have permissions. Don't need to request. Just request location
LocMgr.requestLocationUpdates( K.GPS_PROVIDER, 0, 0, this );
}
} catch(Exception e) {
UI.warningBox( this, "GPS appears to be either absent or disabled" );
}
....
}
@Override
public void onRequestPermissionsResult(final int requestCode,
@NonNull final String[] permissions,
@NonNull final int[] grantResults) {
if(requestCode == LOCATION_PERMISSION_CODE) {
if(grantResults.length > 1
&& grantResults[0] == PackageManager.PERMISSION_GRANTED /* ACCESS_FINE_LOCATION */
&& grantResults[1] == PackageManager.PERMISSION_GRANTED /* ACCESS_COARSE_LOCATION */) {
// User accepted both permissions. request location updates
LocMgr.requestLocationUpdates( K.GPS_PROVIDER, 0, 0, this );
}
}
}
}
在 Android Studio 下编译时,我收到了此 post 标题中指定的警告。我尝试使用以下代码获取 GPS 更新:
try {
LocMgr = (LocationManager)getSystemService( LOCATION_SERVICE );
LocMgr.requestLocationUpdates( K.GPS_PROVIDER, 0, 0, this );
//LocMgr.addNmeaListener( this ); // NMEA
}
catch(Exception e) {
UI.warningBox( this, "GPS appears to be either absent or disabled" );
}
奇怪的是,我的应用程序在没有任何 run-time 许可请求的情况下仍然 工作正常。我做了但是在清单中请求权限。
uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
我并不不高兴,但我期待失败或至少是安全异常。
为什么 Android Studio 如此(出乎意料地)宽容?
顺便说一下,我模块的 gradle 脚本包括
defaultConfig {
applicationId "MY_APP_ID"
minSdkVersion 11
targetSdkVersion 26
}
您 运行 您的应用程序使用的 android 是什么版本?在 marshmallow(api 级别 23)之前,您可以在不实际征求用户许可的情况下访问许多服务,例如 LocationService。
您甚至可以在不征求许可的情况下使用 wifi 和蓝牙。那时候是权限的狂野西部。从那以后这已经改变了,因为你的最高级别 api 可能会请求权限(你没有处理),这就是你收到警告
的原因另外,如果您有权访问 google 服务,您应该改用 fusedlocationprovider,locationservice 在不创建服务以持续轮询它的情况下不会提供有效结果。
您的应用在 运行 时间内没有请求权限,因为您没有添加代码。此外,最近 Android 添加了 运行 时间权限(我猜是从 Android M 开始的)。
因此,在之前的 Android 版本中,您的应用将正常运行,因为您只需要将权限添加到清单中。
在新版本上,您必须在 运行 时额外请求权限。缺少权限并不总是会导致崩溃。它们只能在日志等方面生成警告。
无论如何,要消除该警告,您必须在 运行 时请求许可。下面,你可以找到一个小例子:
public class MainActivity extends AppCompatActivity implements LocationListener {
private final static int LOCATION_PERMISSION_CODE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....
try {
LocMgr = (LocationManager) getSystemService(LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// Missing both permissions. User didn't accept them yet. Request
ActivityCompat.requestPermissions(this, new String[] {permission.ACCESS_FINE_LOCATION, permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_CODE);
} else {
// Have permissions. Don't need to request. Just request location
LocMgr.requestLocationUpdates( K.GPS_PROVIDER, 0, 0, this );
}
} catch(Exception e) {
UI.warningBox( this, "GPS appears to be either absent or disabled" );
}
....
}
@Override
public void onRequestPermissionsResult(final int requestCode,
@NonNull final String[] permissions,
@NonNull final int[] grantResults) {
if(requestCode == LOCATION_PERMISSION_CODE) {
if(grantResults.length > 1
&& grantResults[0] == PackageManager.PERMISSION_GRANTED /* ACCESS_FINE_LOCATION */
&& grantResults[1] == PackageManager.PERMISSION_GRANTED /* ACCESS_COARSE_LOCATION */) {
// User accepted both permissions. request location updates
LocMgr.requestLocationUpdates( K.GPS_PROVIDER, 0, 0, this );
}
}
}
}