Android | 安卓动态申请权限,以蓝牙权限请求为例(使用 Android 的 `registerForActivityResult` API 简化权限请求)

Android | 安卓动态申请权限,以蓝牙权限请求为例(使用 Android 的 `registerForActivityResult` API 简化权限请求)

王先生
2025-06-10 / 0 评论 / 3 阅读 / 正在检测是否收录...

使用 Android 的 registerForActivityResult API 简化权限请求

在 Android 开发中,请求权限是一个常见的操作。从 Android 13 开始,Google 推出了新的 registerForActivityResult API,它让权限请求变得更简单。本文将展示如何用这个新 API 替换旧的 onRequestPermissionsResult 方法,并提供一个简单易懂的示例。

为什么要替换?

旧的 onRequestPermissionsResult 方法需要全局回调,用 requestCode 区分不同的权限请求,这使得代码复杂且难以维护。新的 registerForActivityResult API 让每个权限请求都有自己的回调,代码更清晰、更简洁。

示例代码

1. 权限请求工具类

我们先定义一个工具类 PermissionRequestHelper,封装权限请求的逻辑。

package net.moao.bluetoothuploader.utils;

import android.app.Activity;
import android.os.Build;

import androidx.annotation.RequiresApi;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;

import java.util.HashMap;
import java.util.Map;

public class PermissionRequestHelper {
    private static final Map<String, String> PERMISSION_NAME_MAP = new HashMap<String, String>() {{
        put("android.permission.ACCESS_FINE_LOCATION", "位置");
        put("android.permission.BLUETOOTH_SCAN", "蓝牙扫描");
        put("android.permission.BLUETOOTH_ADVERTISE", "蓝牙广告");
        put("android.permission.BLUETOOTH_CONNECT", "蓝牙连接");
    }};

    /**
     * 获取权限的显示名称
     *
     * @param permission 权限的英文名称
     * @return 权限的显示名称
     */
    public static String getPermissionDisplayName(String permission) {
        return PERMISSION_NAME_MAP.getOrDefault(permission, permission);
    }

    /**
     * 请求权限
     *
     * @param activity 当前的 Activity
     * @param permissions 请求的权限列表
     * @param callback 权限请求结果的回调
     */
    @RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
    public static void requestPermissions(Activity activity, String[] permissions, PermissionRequestCallback callback) {
        // 注册权限请求
        ActivityResultLauncher<String[]> launcher = activity.registerForActivityResult(
                new ActivityResultContracts.RequestMultiplePermissions(),
                result -> {
                    // 构建权限请求结果的字符串
                    StringBuilder resultBuilder = new StringBuilder();
                    for (String permission : permissions) {
                        String permissionName = getPermissionDisplayName(permission);
                        boolean isGranted = result.getOrDefault(permission, false);
                        String status = isGranted ? "已开启" : "未开启";
                        resultBuilder.append(permissionName).append(": ").append(status).append("\n");
                    }
                    // 调用回调方法
                    callback.onPermissionsResult(resultBuilder.toString());
                }
        );

        // 发起权限请求
        launcher.launch(permissions);
    }

    /**
     * 权限请求结果的回调接口
     */
    public interface PermissionRequestCallback {
        /**
         * 权限请求结果的回调方法
         *
         * @param result 权限请求的结果
         */
        void onPermissionsResult(String result);
    }
}

2. 在 Activity 中使用工具类

接下来,我们展示如何在 Activity 中使用 PermissionRequestHelper 类来请求权限。

package net.moao.bluetoothuploader;

import android.os.Bundle;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import net.moao.bluetoothuploader.utils.PermissionRequestHelper;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 定义需要请求的权限
        String[] requiredPermissions = {
                "android.permission.POST_NOTIFICATIONS",
                "android.permission.ACCESS_FINE_LOCATION",
                "android.permission.BLUETOOTH_SCAN",
                "android.permission.BLUETOOTH_CONNECT",
                "android.permission.BLUETOOTH_ADVERTISE"
        };

        // 请求权限
        PermissionRequestHelper.requestPermissions(this, requiredPermissions, new PermissionRequestHelper.PermissionRequestCallback() {
            @Override
            public void onPermissionsResult(String result) {
                // 处理权限请求的结果
                Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();
            }
        });
    }
}

代码解释

1. 权限名称映射

private static final Map<String, String> PERMISSION_NAME_MAP = new HashMap<String, String>() {{
    put("android.permission.ACCESS_FINE_LOCATION", "位置");
    put("android.permission.BLUETOOTH_SCAN", "蓝牙扫描");
    put("android.permission.BLUETOOTH_ADVERTISE", "蓝牙广告");
    put("android.permission.BLUETOOTH_CONNECT", "蓝牙连接");
}};
  • PERMISSION_NAME_MAP:一个静态的 HashMap,把权限的英文名称映射为中文名称。这样在用户界面中展示权限名称时更友好。

2. 获取权限的显示名称

public static String getPermissionDisplayName(String permission) {
    return PERMISSION_NAME_MAP.getOrDefault(permission, permission);
}
  • getPermissionDisplayName:根据权限的英文名称获取对应的中文名称。如果权限名称不在映射表中,就返回原始的英文名称。

3. 请求权限

public static void requestPermissions(Activity activity, String[] permissions, PermissionRequestCallback callback) {
    // 注册权限请求
    ActivityResultLauncher<String[]> launcher = activity.registerForActivityResult(
            new ActivityResultContracts.RequestMultiplePermissions(),
            result -> {
                // 构建权限请求结果的字符串
                StringBuilder resultBuilder = new StringBuilder();
                for (String permission : permissions) {
                    String permissionName = getPermissionDisplayName(permission);
                    boolean isGranted = result.getOrDefault(permission, false);
                    String status = isGranted ? "已开启" : "未开启";
                    resultBuilder.append(permissionName).append(": ").append(status).append("\n");
                }
                // 调用回调方法
                callback.onPermissionsResult(resultBuilder.toString());
            }
    );

    // 发起权限请求
    launcher.launch(permissions);
}
  • requestPermissions:这个方法用于请求权限。

    • activity:当前的 Activity 实例。
    • permissions:需要请求的权限列表。
    • callback:权限请求结果的回调接口。
    • ActivityResultLauncher:使用 registerForActivityResult 方法注册权限请求。
    • ActivityResultContracts.RequestMultiplePermissions:指定请求多个权限。
    • result:权限请求的结果,是一个 Map<String, Boolean>,键是权限名称,值是布尔值,表示权限是否被授予。
    • resultBuilder:构建权限请求结果的字符串,用于在回调中展示。
    • callback.onPermissionsResult:调用回调方法,把权限请求的结果传递给调用者。

4. 权限请求结果的回调接口

public interface PermissionRequestCallback {
    void onPermissionsResult(String result);
}
  • PermissionRequestCallback:一个回调接口,用于处理权限请求的结果。

    • onPermissionsResult:权限请求结果的回调方法,参数 result 是权限请求结果的字符串。

使用新 API 的好处

  • 代码更简洁:使用 registerForActivityResult API,代码更简洁,易于维护。
  • 避免全局回调:不再需要使用全局的 onRequestPermissionsResult 方法,避免了通过 requestCode 区分不同权限请求的复杂性。
  • 更直观:每个权限请求都有自己的回调,逻辑更清晰。

评论 (0)

取消