一、方案说明
方案对比:
Overlay方案:
1、 <> overlay悬浮窗功能比较强大,支持很多交互。
2、部分手机(如小米)不支持指纹识别等安全校验,因为有悬浮窗权限的app对需要指纹识别的app存在安全风险。
3、需要申请权限overlay权限、存在兼容问题,没有权限只能使用Toast去兼容,弹窗会自动消失。
4、支持多级弹窗
TransparentActivity方案:
1、支持场景有限,一般用于app权限引导
2、不支持事件穿透,悬浮窗下面的view无法被点击
3、支持指纹识别等安全校验
4、只支持单一弹窗。
二、TransparentActivity方案实现
本方案存在普通方案和升级方案
普通方案:
需要权限,该权限不需要申请,只需要在清单中申明
核心代码就是将activity所在的task栈移动到最前面。
代码如下
private void moveToFrontTask() {
try {
ActivityManager am = (ActivityManager)TransparentActivity.this.getSystemService(Context.ACTIVITY_SERVICE);
am.moveTaskToFront(FixToastTransparentActivity.this.getTaskId(), 0);
TransparentActivity.this.showMyView(); //展示要展示的view
} catch (Exception var2) {
var2.printStackTrace();
}
}
方法使用步骤:
1、启动TransparentActivity
2、启动设置页或回到主界面
3、调用moveTaskToFront
注意:
为了避免和UI进程的其他Activity干扰,建议使用一个单独的进程来启动TransparentActivity
android:name="com.smartian.ui.TransparentActivity"
android:configChanges="keyboardHidden|screenLayout|screenSize|smallestScreenSize"
android:launchMode="singleTask"
android:process=":transparent"
android:theme="@style/Transparent"
/>
三、增强方案
增强方案可以简化启动逻辑,但是这种方案需要“从后台启动activity”的权限,这种方案不需要movetask就能实现activity覆盖。
优点:
相比普通方案简单易用,但是总体上差于Overlay方案
缺点:
需要后台启动权限、目前仅小米手机可以判断是否存在该权限,其他手机都是盲区。
碎片化严重,有些手机可以启动有些不可以,适配比较费时费力。
private boolean isAllowedStartActivityInBackground() {
AppOpsManager ops = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
try {
int op = 10021;
Method method = ops.getClass().getMethod("checkOpNoThrow", new Class[]{int.class, int.class, String.class});
Integer result = (Integer) method.invoke(ops, op, Process.myUid(), getPackageName());
return result == AppOpsManager.MODE_ALLOWED;
} catch (Exception e) {
Log.e(TAG, "not support");
}
return false;
}