Android动态申请权限,让你的应用更加安全和用户友好

一、为什么需要动态申请权限?

在Android移动设备上,权限是一项非常重要的安全特性。应用需要获得用户授权才能访问特定的设备功能或用户信息。根据不同的功能,权限可分为正常权限和危险权限两种。

正常权限通常是指运行应用所必需的权限,如访问网络状态等。这些权限会在安装应用时自动授予,用户不需要进行确认。

而危险权限则是指对用户个人信息和设备重要功能进行访问的权限,比如读取联系人、读取短信等。这些权限需要用户明确授权才能使用。Android 6.0(API 23)引入了动态权限模型,允许用户在应用运行时动态地授权这些危险权限。

使用动态权限申请,能保护用户隐私安全,提高应用用户友好度,避免用户对应用的不信任感,增加用户与应用的互动,提高应用的用户活跃度,从而提高应用评分和推广度。

二、如何执行动态申请权限

Android虽然提供了权限管理,但是某些应用运行时可能需要并未在manifest文件中包含的新权限,因此需要动态申请权限。

如下是一个运用动态权限申请的应用示例,其实现为让用户在使用应用期间打开相机并捕捉照片的功能。

public class MainActivity extends AppCompatActivity {

private static final int REQUEST_CAMERA_PERMISSION = 1;
private static final int REQUEST_CAMERA = 2;

private Camera mCamera;

private boolean hasCameraPermission() {
// Check if the Camera permission has been granted
return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
}

private void requestCameraPermission() {
// Request the Camera permission
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
new ConfirmationDialog().show(getFragmentManager(), FRAGMENT_DIALOG);
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
}

private void requestCamera() {
// Request to launch the Camera
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_CAMERA);
}

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (hasCameraPermission()) {
requestCamera();
} else {
requestCameraPermission();
}
}
});

// Open the camera when the app is launched
if (hasCameraPermission()) {
requestCamera();
} else {
requestCameraPermission();
}
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_CAMERA_PERMISSION:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
requestCamera();
} else {
Toast.makeText(this, "You need to grant permission to use the camera", Toast.LENGTH_SHORT).show();
}
break;
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CAMERA:
if (resultCode == RESULT_OK) {
// Save the captured image
Bundle bundle = data.getExtras();
Bitmap bitmap = (Bitmap) bundle.get("data");
ImageView imageView = findViewById(R.id.image_view);
imageView.setImageBitmap(bitmap);
}
break;
}
}

public static class ConfirmationDialog extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Fragment parent = getParentFragment();
return new AlertDialog.Builder(getActivity())
.setMessage("Need permission to use the camera")
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
FragmentCompat.requestPermissions(parent, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
})
.setNegativeButton(android.R.string.cancel, null)
.create();
}
}
}

上述代码中,首先定义了应用所需的危险权限“CAMERA”和requestCode,然后使用hasCameraPermission()判断是否获得授权。如果未获得权限,则使用requestCameraPermission()方法向系统发出权限请求,如果已获得授权,则使用requestCamera()方法请求打开相机。
当用户按下拍照按钮后,onActivityResult()会接收请求的结果。如果结果是OK,表示照片已捕捉到。否则,用户可能取消了该动作或者出现了问题。

三、优化动态申请权限的用户体验

尽管动态权限申请提升了应用的用户体验,但是在用户授权的途中,用户可能会遇到多次重复授权的问题,这会降低用户对应用的满意度。为了缓解用户对弹出请求的强烈反感及让用户更好的理解对应用所需授权的必要性,我们可以采取如下几种方式来优化用户体验。

1. 显示完整的证明

为了更好地避免用户对应用的不信任感,设备令生产商和厂商提供了“应用设置”中关于应用所需权限的描述。为了提高用户对权限描述的理解和透明度,我们可以在弹出框中显示完整的证明。

public class MainActivity extends AppCompatActivity {

private void requestCameraPermission() {
// Request the Camera permission
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
// Explain to the user why we need permission
Snackbar.make(findViewById(android.R.id.content), "Need permission to use the camera for taking pictures", Snackbar.LENGTH_LONG).setAction("OK", new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
}).show();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
}
}

上述代码中,使用Snackbar进行证明说明,将对话框内容从简单的“A“更新为有用的描述。同时,添加了一个”OK”按钮来开始授权请求。

2. 在请求过程中展示进度

当系统请求权限时,等待是不可避免的。但是,我们可以在会话过程中显示一个进度条,以便用户有时间了解发生了什么。

public class MainActivity extends AppCompatActivity {

private ProgressDialog mProgressDialog;

private void requestCameraPermission() {
// Show a progress bar while the app requests permission
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
// Explain to the user why we need permission
showCameraPermissionExplanation();
} else {
showProgressBar();
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
}

private void showProgressBar() {
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Requesting permission");
mProgressDialog.setCancelable(false);
mProgressDialog.setIndeterminate(true);
mProgressDialog.show();
}

private void cancelProgressBar() {
mProgressDialog.cancel();
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
cancelProgressBar();
switch (requestCode) {
case REQUEST_CAMERA_PERMISSION:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
requestCamera();
} else {
Toast.makeText(this, "You need to grant permission to use the camera", Toast.LENGTH_SHORT).show();
}
break;
}
}
}

上述代码中,使用ProgressDialog来显示进度条。在permission请求结束后,使用cancelProgressBar()方法取消进度条,展示授权请求结果。同时,在onRequestPermissionsResult()中使用cancelProgressBar()取消进度条。

3. 向用户解释为什么需要特定的权限

当用户拒绝授权时,可以向用户展示为什么需要该权限,以便帮助解释需要的原因。

public class MainActivity extends AppCompatActivity {

private void requestCameraPermission() {
// Request the Camera permission
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
// Explain to the user why we need permission
showCameraPermissionExplanation();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
}

private void showCameraPermissionExplanation() {
new AlertDialog.Builder(this).setTitle("Need permission to use the camera").setMessage("This app needs the camera permission in order to take pictures.").setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
}).setNegativeButton("Cancel", null)
.show();
}
}

上述代码中,在shouldShowRequestPermissionRationale()返回true时,首先创建一个AlertDialog以向用户解释为什么需要权限,然后提供一个“OK”按钮,以便用户开始授权请求。

四、总结

采用动态权限申请方式,可以保护用户隐私安全,提高应用用户友好度,避免用户对应用的不信任感,增加用户与应用的互动,提高应用的用户活跃度,
从而提高应用评分和推广度。优化动态权限申请的用户体验,能缓解用户对弹出请求的反感,提高用户对应用的满意度。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/232085.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-11 12:50
下一篇 2024-12-11 12:50

相关推荐

  • Python官网中文版:解决你的编程问题

    Python是一种高级编程语言,它可以用于Web开发、科学计算、人工智能等领域。Python官网中文版提供了全面的资源和教程,可以帮助你入门学习和进一步提高编程技能。 一、Pyth…

    编程 2025-04-29
  • QML 动态加载实践

    探讨 QML 框架下动态加载实现的方法和技巧。 一、实现动态加载的方法 QML 支持从 JavaScript 中动态指定需要加载的 QML 组件,并放置到运行时指定的位置。这种技术…

    编程 2025-04-29
  • 掌握magic-api item.import,为你的项目注入灵魂

    你是否曾经想要导入一个模块,但却不知道如何实现?又或者,你是否在使用magic-api时遇到了无法导入的问题?那么,你来到了正确的地方。在本文中,我们将详细阐述magic-api的…

    编程 2025-04-29
  • Python爱心代码动态

    本文将从多个方面详细阐述Python爱心代码动态,包括实现基本原理、应用场景、代码示例等。 一、实现基本原理 Python爱心代码动态使用turtle模块实现。在绘制一个心形的基础…

    编程 2025-04-29
  • Codemaid插件——让你的代码优美整洁

    你是否曾为了混杂在代码里的冗余空格、重复代码而感到烦恼?你是否曾因为代码缺少注释而陷入困境?为了解决这些问题,今天我要为大家推荐一款Visual Studio扩展插件——Codem…

    编程 2025-04-28
  • t3.js:一个全能的JavaScript动态文本替换工具

    t3.js是一个非常流行的JavaScript动态文本替换工具,它是一个轻量级库,能够很容易地实现文本内容的递增、递减、替换、切换以及其他各种操作。在本文中,我们将从多个方面探讨t…

    编程 2025-04-28
  • 使用easypoi创建多个动态表头

    本文将详细介绍如何使用easypoi创建多个动态表头,让表格更加灵活和具有可读性。 一、创建单个动态表头 easypoi是一个基于POI操作Excel的Java框架,支持通过注解的…

    编程 2025-04-28
  • Python动态输入: 从基础使用到应用实例

    Python是一种高级编程语言,因其简单易学和可读性而备受欢迎。Python允许程序员通过标准输入或命令行获得用户输入,这使得Python语言无法预测或控制输入。在本文中,我们将详…

    编程 2025-04-28
  • 如何选择MySQL服务器文件权限

    MySQL是一种流行的关系型数据库管理系统。在安装MySQL时,选择正确的文件权限是保证安全和性能的重要步骤。以下是一些指导您选择正确权限的建议。 一、权限选择 MySQL服务器需…

    编程 2025-04-27
  • Python左补0,让你的数据更美观

    本文将从以下几个方面,详细阐述Python左补0的作用及使用方法: 一、什么是Python左补0 在Python中,数据在输出时如果希望达到一定的美观效果,就需要对数字进行左补0,…

    编程 2025-04-27

发表回复

登录后才能评论