运行时权限不适用于真实设备
Runtime Permissions Not Working on Real Device
我已经在我的应用程序中实现了 RT 位置权限,并在牛轧糖设备上进行了测试。我已经检查了 logcat 但它看起来像 ContextCompat.checkSelfPermission() and ActivityCompat.requestPermission
不执行并且随后 onRequestPermissionRationale 永远不会被调用但是在应用程序的设备设置中,它总是显示为授予权限
我试过在代码中像下面这样记录:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client_home);
prefsHelper = new SharedPrefsHelper(this);
initViews();
setSupportActionBar(toolbar);
Log.d(TAG, "BEFORE CHECK");
checkPerms();
setUpDrawer();
prefsHelper.setLoggedOut(false);
getVehicles();
handlePlacesInput();
rideContinueLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (validate() && Utils.isNetwork(ClientHomeActivity.this)) {
Intent intent = new Intent(ClientHomeActivity.this, BookRideActivity.class);
intent.putExtra("start_addr", startAddr);
intent.putExtra("dest_addr", destAddr);
startActivity(intent);
clearInputs();
} else {
Snackbar.make(findViewById(android.R.id.content), "Enter Start and Drop Locations", Snackbar.LENGTH_LONG).show();
}
}
});
}
private void checkPerms() {
Log.d(TAG, "DO CHECK");
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "INSIDE CHECK");
reqPerms();
}
}
private void reqPerms() {
Log.d(TAG, "ASKING");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, AppConstants.LOC_PERMS_REQ_CODE);
}
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case AppConstants.LOC_PERMS_REQ_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "GRANTED");
} else {
if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
Log.d(TAG, "Permission Rationale");
} else {
reqPerms();
}
}
break;
}
}
日志在 "DO CHECK" tag and other tags after that don't execute
处停止。我正在尝试构建一个基于位置的应用程序。谁能告诉我为什么会这样,是我设备上的错误还是代码中的错误?谢谢
ActivityCompat.requestPermission dont execute and subsequently
onRequestPermissionRationale never gets called but in the device
settings for the app, it is always showing as permission granted
由于您的应用是旧应用并且您已经授予该应用必要的权限,ActivityCompat.checkSelfPermission
将 return PackageManager.PERMISSION_GRANTED
并且您不会再看到权限请求。
如果您想查看权限请求,请卸载旧应用并安装新应用。另一种方法是仅从设置中禁用权限。
也许您已经授予了权限。
尝试重新安装应用。
试试这个
确保你的 app level gradle 文件在编译 sdk 版本中是最新的。
喜欢
compileSdkVersion 27
然后在 android 清单文件中添加权限。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
然后像下面这样检查运行时权限后创建两个方法。
/**
* this method check permission and return current state of permission need.
*/
private boolean checkPermissions() {
int permissionState = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
return permissionState == PackageManager.PERMISSION_GRANTED;
}
/**
* this method request to permission asked.
*/
private void requestPermissions() {
boolean shouldProvideRationale =
ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION);
if (shouldProvideRationale) {
Log.i(TAG, "Displaying permission rationale to provide additional context.");
} else {
Log.i(TAG, "Requesting permission");
// previously and checked "Never ask again".
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
}
/**
* Callback received when a permissions request has been completed.
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
Log.i(TAG, "onRequestPermissionResult");
if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
if (grantResults.length <= 0) {
// If user interaction was interrupted, the permission request is cancelled and you
// receive empty arrays.
Log.i(TAG, "User interaction was cancelled.");
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission was granted. Kick off the process of building and connecting
// GoogleApiClient.
buildGoogleApiClient();
} else {
// Permission denied.
}
}
}
然后在调用 get location 方法时像下面这样检查
// Check if the user revoked runtime permissions.
if (!checkPermissions()) {
requestPermissions();
}
buildGoogleApiClient();
您的代码记录 "DO CHECK" 而不是 "INSIDE CHECK" 的唯一合乎逻辑的解释是权限已经被授予。
在申请权限之前,如果权限已经被授予,您可以直接进行您需要的操作。
您还可以利用我的库轻松处理运行时权限。
https://github.com/nabinbhandari/Android-Permissions
有两种可能在请求后不显示权限对话框,如下所示。
目标版本
请在您的构建中将您的 targetSdkVersion 设置为大于 23
声明权限清单
请不要错过在清单中声明您需要并在运行时请求的权限,
我已经在我的应用程序中实现了 RT 位置权限,并在牛轧糖设备上进行了测试。我已经检查了 logcat 但它看起来像 ContextCompat.checkSelfPermission() and ActivityCompat.requestPermission
不执行并且随后 onRequestPermissionRationale 永远不会被调用但是在应用程序的设备设置中,它总是显示为授予权限
我试过在代码中像下面这样记录:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client_home);
prefsHelper = new SharedPrefsHelper(this);
initViews();
setSupportActionBar(toolbar);
Log.d(TAG, "BEFORE CHECK");
checkPerms();
setUpDrawer();
prefsHelper.setLoggedOut(false);
getVehicles();
handlePlacesInput();
rideContinueLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (validate() && Utils.isNetwork(ClientHomeActivity.this)) {
Intent intent = new Intent(ClientHomeActivity.this, BookRideActivity.class);
intent.putExtra("start_addr", startAddr);
intent.putExtra("dest_addr", destAddr);
startActivity(intent);
clearInputs();
} else {
Snackbar.make(findViewById(android.R.id.content), "Enter Start and Drop Locations", Snackbar.LENGTH_LONG).show();
}
}
});
}
private void checkPerms() {
Log.d(TAG, "DO CHECK");
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "INSIDE CHECK");
reqPerms();
}
}
private void reqPerms() {
Log.d(TAG, "ASKING");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, AppConstants.LOC_PERMS_REQ_CODE);
}
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case AppConstants.LOC_PERMS_REQ_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "GRANTED");
} else {
if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
Log.d(TAG, "Permission Rationale");
} else {
reqPerms();
}
}
break;
}
}
日志在 "DO CHECK" tag and other tags after that don't execute
处停止。我正在尝试构建一个基于位置的应用程序。谁能告诉我为什么会这样,是我设备上的错误还是代码中的错误?谢谢
ActivityCompat.requestPermission dont execute and subsequently onRequestPermissionRationale never gets called but in the device settings for the app, it is always showing as permission granted
由于您的应用是旧应用并且您已经授予该应用必要的权限,ActivityCompat.checkSelfPermission
将 return PackageManager.PERMISSION_GRANTED
并且您不会再看到权限请求。
如果您想查看权限请求,请卸载旧应用并安装新应用。另一种方法是仅从设置中禁用权限。
也许您已经授予了权限。
尝试重新安装应用。
试试这个 确保你的 app level gradle 文件在编译 sdk 版本中是最新的。 喜欢
compileSdkVersion 27
然后在 android 清单文件中添加权限。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
然后像下面这样检查运行时权限后创建两个方法。
/**
* this method check permission and return current state of permission need.
*/
private boolean checkPermissions() {
int permissionState = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
return permissionState == PackageManager.PERMISSION_GRANTED;
}
/**
* this method request to permission asked.
*/
private void requestPermissions() {
boolean shouldProvideRationale =
ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION);
if (shouldProvideRationale) {
Log.i(TAG, "Displaying permission rationale to provide additional context.");
} else {
Log.i(TAG, "Requesting permission");
// previously and checked "Never ask again".
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
}
/**
* Callback received when a permissions request has been completed.
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
Log.i(TAG, "onRequestPermissionResult");
if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
if (grantResults.length <= 0) {
// If user interaction was interrupted, the permission request is cancelled and you
// receive empty arrays.
Log.i(TAG, "User interaction was cancelled.");
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission was granted. Kick off the process of building and connecting
// GoogleApiClient.
buildGoogleApiClient();
} else {
// Permission denied.
}
}
}
然后在调用 get location 方法时像下面这样检查
// Check if the user revoked runtime permissions.
if (!checkPermissions()) {
requestPermissions();
}
buildGoogleApiClient();
您的代码记录 "DO CHECK" 而不是 "INSIDE CHECK" 的唯一合乎逻辑的解释是权限已经被授予。
在申请权限之前,如果权限已经被授予,您可以直接进行您需要的操作。
您还可以利用我的库轻松处理运行时权限。 https://github.com/nabinbhandari/Android-Permissions
有两种可能在请求后不显示权限对话框,如下所示。
目标版本
请在您的构建中将您的 targetSdkVersion 设置为大于 23
声明权限清单
请不要错过在清单中声明您需要并在运行时请求的权限,