问题描述
2019年开发安卓软件的过程中(API level 28),在测试时发现在小米手机上并未弹出“获取发送短信权限”窗口,经查是小米手机的MIUI系统的封闭限制了发送短信权限,需要用户进入设置中手动开启发送短信权限。
参考小米应用开发者文档,创建MIUI工具类,用于判断当前软件系统环境是否是MIUI系统,若是则通过弹窗提醒用户点击按钮跳转到本软件的权限管理界面,手动打开发送短信权限。
解决过程
判断是否是MIUI系统
- 首先判断当前设备是否是小米设备
使用android.os.Build对象,查询MANUFACTURER的值,当值为“Xiaomi”即为小米设备 - 进一步判断是否是MIUI系统
- 对于Android 8.0之前版本,利用Properties类获取Android系统配置文件build.prop,从配置文件中读取Key为“ro.miui.ui.version.code”、“ro.miui.ui.version.name”、“ro.miui.internal.storage”的值;
- 对于Android 8.0以及之后的版本,因为不允许读取build.prop文件,通过反射(Reflection)机制获取SystemProperties.get方法,再获取上述三个Key的值。若这三个Key对应值有一个不为null即可判断是MIUI系统
跳转至权限管理界面
通过Activity类的startActivity跳转至本软件的MIUI权限管理界面对应的activity。
在MIUI中该activity在包"com.miui.securitycenter"中,但从MIUI 5到MIUI 7与MIUI 8 及之后版本的activity名不同,为避免跳转activity失败导致软件崩溃,使用try-catch方法首先尝试跳转至“com.miui.permcenter.permissions.PermissionsEditorActivity”,若失败尝试跳转至“com.miui.permcenter.permissions.AppPermissionsEditorActivity”,若失败则跳转至Android的权限设置界面。
代码实现
package com.soft.zb.accidentwarning.utils;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.Settings;
import android.text.TextUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Properties;
public class MiuiUtil {
private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";
/**
* 判断是否是小米手机(MIUI系统)
*
* @return
*/
public boolean isMIUI() {
String device = Build.MANUFACTURER;
// if (device.equals("Xiaomi")) { // 是否是小米手机
// return true;
// }
if (device.equals("Xiaomi")) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) { // Android 8.0 及以上
return !TextUtils.isEmpty(getSystemProperty(KEY_MIUI_VERSION_CODE, ""))
|| !TextUtils.isEmpty(getSystemProperty(KEY_MIUI_VERSION_NAME, ""))
|| !TextUtils.isEmpty(getSystemProperty(KEY_MIUI_INTERNAL_STORAGE, ""));
} else {
Properties prop = new Properties();
try {
prop.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop"))); // build.prop系统配置文件在Android O上不可读
} catch (IOException e) {
e.printStackTrace();
return false;
}
return prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null
|| prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null
|| prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null;
}
} else {
return false;
}
}
private static String getSystemProperty(String key, String defaultValue) {
try {
Class<?> aClass = Class.forName("android.os.SystemProperties");
Method get = aClass.getMethod("get", String.class, String.class); // 使用反射来获取到该方法
return (String) get.invoke(aClass, key, defaultValue);
} catch (Exception e) {
}
return defaultValue;
}
/**
* 跳转到权限管理界面
* @param context
*/
public void goPermissionSettings(Activity context) {
Intent intent;
// MIUI8/9/10
try {
intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
intent.putExtra("extra_pkgname", context.getPackageName());
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
// MIUI5/6/7
try {
intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
intent.putExtra("extra_pkgname", context.getPackageName());
context.startActivity(intent);
} catch (ActivityNotFoundException e1) {
// 应用信息界面
intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", context.getPackageName(), null);
intent.setData(uri);
context.startActivity(intent);
}
}
}
}