前提:使用MediaProjectionManager录屏方案。
问题:会截入自定义悬浮框
解决方案
1.本质上得修改framework层代码surfaceflinger去除悬浮框,在画布中就去除该悬浮框。
优:自定义、有效,
缺:涉及底层,修改成本大,适配性差
2.如果不想修改framework层,那看看国内手机系统其实都是自带的录屏软件,方案一说白了就是匹配view的名字是不是在某个白名单里面,那我们可以适配各个手机系统,改成跟他们自带录屏软件同样的名字,这样又不用修改framework,而且对我们而言就是根据手机系统差异,构建不同的layoutparams。参考了这位大佬写的android 录屏不录制自身的悬浮框,下面把各个厂商的title差异写一下。
- miui——com.miui.screenrecorder
- emui——ScreenRecorderTimer
- oppo——com.coloros.screenrecorder.FloatView
- vivo——screen_record_menu
- oneplus——op_screenrecord
- flyme——SysScreenRecorder
- 红魔——NubiaScreenDecorOverlay
- 黑鲨——com.blackshark.screenrecorder
- ROG——com.asus.force.layer.transparent.SR.floatingpanel
- TODO:三星的暂时没有搜到,后续可能会补充
除了上面的title外,有些手机系统可能还得修改一下其他参数,
//小米:
try {
params.flags = params.flags | WindowManager.LayoutParams.FLAG_DITHER;
} catch (Exception e) {
e.printStackTrace();
}
//一加,并且Build.VERSION.SDK_INT == 30
try {
Field privateflagField = layoutParams.getClass().getDeclaredField("PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY");
privateflagField.setAccessible(true);
Field flagField = params.getClass().getDeclaredField("privateFlags");
flagField.setAccessible(true);
flagField.set(params, (int)privateflagField.get(layoutParams.getClass()));
} catch (Exception e) {
e.printStackTrace();
}
//三星
try {
Method semAddExtensionFlags = params.getClass().getMethod("semAddExtensionFlags", Integer.TYPE);
Method semAddPrivateFlags = params.getClass().getMethod("semAddPrivateFlags", Integer.TYPE);
semAddExtensionFlags.invoke(params, -2147352576);
semAddPrivateFlags.invoke(params, params.flags);
} catch (Exception e) {
e.printStackTrace();
}
//ROG
layoutParams.memoryType |= 0x10000000;
//魅族
try {
Class MeizuParamsClass = Class.forName("android.view.MeizuLayoutParams");
Field flagField = MeizuParamsClass.getDeclaredField("flags");
flagField.setAccessible(true);
Object MeizuParams = MeizuParamsClass.newInstance();
flagField.setInt(MeizuParams, flagValue);
Field mzParamsField = params.getClass().getField("meizuParams");
mzParamsField.set(params, MeizuParams);
} catch (IllegalAccessException | ClassNotFoundException | NoSuchFieldException | InstantiationException e) {
try{
Field mzParamsField = params.getClass().getDeclaredField("meizuFlags");
mzParamsField.setAccessible(true);
mzParamsField.setInt(params, flagValue);
} catch (Exception e) {
e.printStackTrace();
}
}