获取设备注册邮箱的权限适配问题(API 16到Android O)
这个权限适配的坑我之前也踩过,给你梳理清楚不同API等级对应的权限要求和适配方案:
不同API级别对应的权限配置
1. API 16 ~ API 25(Android 4.1 到 Android 7.1)
- 需要在
AndroidManifest.xml中声明GET_ACCOUNTS权限:<uses-permission android:name="android.permission.GET_ACCOUNTS" /> - 注意:从API 23(Android 6.0)开始,这个权限属于危险权限,除了在Manifest声明,还需要在代码中动态请求用户授权。
2. API 26 及以上(Android 8.0+)
GET_ACCOUNTS权限被官方废弃,取而代之的是READ_CONTACTS权限,同样需要在Manifest中声明:<uses-permission android:name="android.permission.READ_CONTACTS" />- 该权限也属于危险权限,必须动态请求用户授权才能使用。
权限请求的适配代码示例
你可以通过判断当前设备的API版本,来决定请求对应的权限,同时处理权限申请结果,示例代码如下:
private static final int REQUEST_ACCOUNT_PERMISSION = 100; private void requestRequiredPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Android 8.0及以上,请求READ_CONTACTS权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_ACCOUNT_PERMISSION); } else { // 权限已授予,执行获取邮箱的逻辑 fetchRegisteredEmail(); } } else { // API 25及以下,请求GET_ACCOUNTS权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.GET_ACCOUNTS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.GET_ACCOUNTS}, REQUEST_ACCOUNT_PERMISSION); } else { fetchRegisteredEmail(); } } } // 处理权限申请结果回调 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_ACCOUNT_PERMISSION) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限通过,执行邮箱获取逻辑 fetchRegisteredEmail(); } else { // 权限被拒绝,提示用户 Toast.makeText(this, "需要授予权限才能获取设备注册邮箱", Toast.LENGTH_SHORT).show(); } } } // 你原来的获取邮箱逻辑(优化后找到第一个匹配后跳出循环) private void fetchRegisteredEmail() { String registeredEmail = null; Pattern emailPattern = Patterns.EMAIL_ADDRESS; Account[] accounts = AccountManager.get(this).getAccounts(); for (Account account : accounts) { if (emailPattern.matcher(account.name).matches()) { registeredEmail = account.name; break; // 找到第一个匹配的邮箱就停止遍历,提升效率 } } // 这里处理获取到的邮箱,比如显示或后续业务逻辑 }
额外注意事项
- 你可以在
AndroidManifest.xml中同时声明两个权限,低版本系统会自动忽略不认识的READ_CONTACTS,高版本系统会废弃GET_ACCOUNTS,这样不会有冲突:<uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> - 你的邮箱获取逻辑在所有API级别上都是通用的,只要权限正确就能正常运行。
内容的提问来源于stack exchange,提问作者user9555243
相关产品推荐
相关产品推荐

