MIUI特有一个省电策略模式-神隐模式,如果你的APP需要在息屏情况下一定时间内使用网络、定位或者蓝牙等功能,则需要引导用户去关闭神隐模式或者将你的APP加入神隐模式白名单中,如何正确跳转正是本篇要进行分析的,分析方法是反编译系统神隐模式的APK。
一、分析出神隐模式是系统哪个APK
1.Android Studio中查看当前Activity
AS连接调试小米(红米)手机,在Logcat中输入过滤关键词”ActivityManager”或者”Display”,打开系统神隐模式相关界面,即可在Logcat中得知相应的包名和Activity名
2.使用ADB命令分析当前Activity
使用adb shell dumpsys activity命名查看Activity栈,亦可得知神隐模式相关包名和相关Activity名
二、反编译系统ROM包,得到相关APK
1.在MIUI官方下载相关ROM包,在这里采用的是MAX 2机型的MIUI 8(Android 6.0)版本,下载链接。
2.参考《去你妹的厂商改固件,看我逆向小米rom层应用做碎片化适配》进行反编译,这里提几个关键点。
MIUI 9(Android 7.0)的ROM包我还用那些工具还未成功。
ROM包解压后会是system.dat文件,需要用别的工具提取,该博文也在我评论后进行了更新并提供工具下载地址。
获取到APK后,dex2jar工具直接将class.dex转为class.jar,然后用jd-gui打开查看即可。直接apktool或者其他集成好的工具反编译APK有可能是失败的。
三、分析反编译后的源码,寻找跳转的正确姿势
1.分析出神隐模式的界面Activity名为HiddenAppsContainerManagementActivity
以及详细设置界面为HiddenAppsConfigActivity
,查看AndroidManifest.xml文件
<activity android:label="@string/power_hide_mode_title"
android:launchMode="singleTop"
android:name="com.miui.powerkeeper.ui.HiddenAppsContainerManagementActivity"
android:screenOrientation="portrait" android:theme="@269287447">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="miui.intent.action.POWER_HIDE_MODE_APP_LIST"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:label="@string/power_hide_mode_title"
android:launchMode="singleTop"
android:name="com.miui.powerkeeper.ui.HiddenAppsConfigActivity"
android:screenOrientation="portrait" android:theme="@269287447">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="miui.intent.action.HIDDEN_APPS_CONFIG_ACTIVITY"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
分析了AndroidManifest.xml文件后,就可以写出跳转代码啦!!!但是跳转神隐模式列表可以,跳转详细设置界面还是有点问题。
2.jd-gui查看分析源码
使用dex2java反编译一下class.dex文件,然后用jd-gui打开查看相应的类
神隐模式列表界面相对没有什么,直接是两个ListFragment,显示系统设置的APP以及自定义的APP,这也和手机截图相对应
神隐模式详细设置界面,在初始化View的时候,会获取传入参数package_name,package_label,然后设置标题为package_label。
3.分析完成后,写出完整工具类
public final class XiaomiDeviceUtil {
/**
* 跳转到神隐模式-应用配置列表
* @param context {@link Context}
* @return {@code true} 跳转成功,{@code false} 跳转失败
*/
public static boolean toHiddenAppList(Context context) {
try {
Intent intent = new Intent("miui.intent.action.POWER_HIDE_MODE_APP_LIST");
context.startActivity(intent);
return true;
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
/**
* 跳转到神隐模式-应用配置-给定包名应用详细配置界面
* 本方法不适合用{@link android.app.Activity#startActivityForResult(Intent, int)}方法,因为无论
* 用户如何选择,返回结果均为-1。
* 测试机型红米4X,MIUI 9 7.11.2开发板
* @param context {@link Context}
* @param packageName 包名
* @param label 应用名
* @return {@code true} 跳转成功,{@code false} 跳转失败
*/
public static boolean toConfigApp(Context context, String packageName, String label) {
try {
Intent intent = new Intent("miui.intent.action.HIDDEN_APPS_CONFIG_ACTIVITY");
// intent.setComponent(new ComponentName("com.miui.powerkeeper",
// "com.miui.powerkeeper.ui.HiddenAppsConfigActivity"));
intent.putExtra("package_name", packageName);
intent.putExtra("package_label", label);
context.startActivity(intent);
return true;
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
}