在应用申请权限时,如果用户选择了禁止后不再提示(不再询问),那么未来再次向用户请求该权限时,系统将会默认禁止该权限。这时候只能靠用户手动去授予权限,通过设计一个提示选择框来让用户选择,如果用户的确是想要授予该权限,那么就跳转至该应用的权限设置界面。

1、判断该权限是否处于禁止后不再提示(不再询问)
2、提醒用户我们需要该权限,是否前往设置
3、跳转当前应用的权限设置页面
1、检查权限状态
使用 ContextCompat.checkSelfPermission() 方法来检查权限的授予状态。它将返回一个常量值,这个在 上篇文章 中有提到过。然后再使用 ActivityCompat.shouldShowRequestPermissionRationale() 方法判断该权限是否能够弹出带有请求权限的弹窗,这个是判断权限是否处于不再询问状态的重要方法。
根据上面两个方法,结合其逻辑则需要 checkSelfPermission() 方法返回“权限未被授予的状态常量”,同时 shouldShowRequestPermissionRationale() 方法判断该权限为“无法弹出权限申请框”,也就是返回布尔值 false。
同时满足上面这两个条件就表示该权限处于不再询问的状态。判断权限是否处于不再询问状态的代码有点小BUG,它必须申请过一次权限并且用户做出了选择之后判断才能够准确。
// 判断权限是否处于不再询问状态
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED){
if(!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE)){
Toast.makeText(this, "该权限已被用户选择了不再询问!", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "权限未被授予!", Toast.LENGTH_SHORT).show();
}
}else{
Toast.makeText(this, "权限已被授予!", Toast.LENGTH_SHORT).show();
}
2、创建 AlertDialog 对话框
使用 AlertDialog.Builder 构造器来创建一个对话框对象,然后再使用 setTitle、setMessage 等方法构造对话框的标题及信息等。
// 创建一个对话框
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setTitle("权限设置") // 设置标题
.setMessage("应用缺乏必要的权限,是否前往手动授予该权限?") // 设置内容
// 添加一个确认按钮并设置点击按钮后执行的代码
.setPositiveButton("前往", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 点击按钮后执行的代码...
}
})
.setNegativeButton("取消", null) // 添加一个取消按钮,无命令执行
.create(); // 创建对话框
alertDialog.show(); // 显示对话框
3、跳转权限设置页面
使用 Intent 和 startActivity() 等方法跳转到当前应用的详情页面进行权限设置。
// 跳转至当前应用的详情页面
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
或者你也可以根据包名和类名来打开指定机型的权限管理界面的 Activity,不同的机型打开权限管理界面的方法都不同,所以你需要一个一个去适配其包名和类名。可以通过 ADB 命令来获取不同手机机型里权限界面的包名和类名(具体方法这里就不介绍了)。
// 华为机型手机权限管理界面跳转示例
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ComponentName comp = new ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity");
intent.setComponent(comp);
startActivity(intent);
4、完整代码示例
【代码文件】activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:onClick="requestPermission"
android:text="请求该权限"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:onClick="checkPermission"
android:text="检查该权限"
app:layout_constraintStart_toEndOf="@+id/button"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:onClick="getPermission"
android:text="快速前往设置"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />
</androidx.constraintlayout.widget.ConstraintLayout>
【代码文件】AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.myapplication">
<!--获取手机状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
【代码文件】MainActivity.java
package com.android.myapplication;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermission(null);
}
// 请求权限
public void requestPermission(View view){
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.READ_PHONE_STATE
},1);
}
// 判断权限是否处于不再询问状态
public void checkPermission(View view){
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED){
if(!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE)){
Toast.makeText(this, "该权限已被用户选择了不再询问!", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "权限未被授予!", Toast.LENGTH_SHORT).show();
}
}else{
Toast.makeText(this, "权限已被授予!", Toast.LENGTH_SHORT).show();
}
}
// 跳转至当前应用的详情页面
public void getPermission(View view){
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setTitle("权限设置")
.setMessage("应用缺乏必要的权限,是否前往手动授予该权限?")
.setPositiveButton("前往", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
/* 华为机型手机权限管理界面跳转示例
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ComponentName comp = new ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity");
intent.setComponent(comp);
startActivity(intent);*/
}
})
.setNegativeButton("取消", null)
.create();
alertDialog.show();
}
}
// ContextCompat.checkSelfPermission(Activity, permission);
// ActivityCompat.shouldShowRequestPermissionRationale(Activity, permission);
// 特别注意:判断权限是否处于不再询问状态的代码有点小BUG,它必须申请过一次权限并且用户做出了选择之后判断才能够准确
如果文章中含有某些错误或其它问题,欢迎在下方评论留言,我会及时修改。
当Android用户选择禁止应用的权限并不再提示时,应用需引导用户手动授权。本文介绍如何检查权限状态,创建 AlertDialog 提醒用户,并跳转至权限设置页面。关键步骤包括使用 ContextCompat.checkSelfPermission() 和 ActivityCompat.shouldShowRequestPermissionRationale() 判断权限状态,以及使用 Intent 跳转至权限设置。
591

被折叠的 条评论
为什么被折叠?



