在关于录屏权限的问题一文中,通过与 Launcher 的结合,实现了权限无感自动申请的功能。这没过几天,就有反馈说有问题:开始录屏的时候会有权限申请弹窗一闪而过。
最初怀疑是平板性能差,会打开一个 activity,然后马上消失,由于性能问题导致这样的“一闪而过”。但研究下来发现这个怀疑不成立。通过调试知道了MediaProjectionManager.createScreenCaptureIntent()
返回的 intent 对应的 activity 是 MediaProjectionPermissionActivity。于是查看其代码,在 onCreate 方法中有这样的片段:
1 | try { |
即如果有权限,则直接设置 RESULT_OK 并且 finish 掉。
如果没权限,则走到下面了:
1 | View dialogTitleView = View.inflate(this, R.layout.media_projection_dialog_title, null); |
会展示一个弹窗,这个弹窗便是权限申请的弹窗。并且这个弹窗默认是可以外部点击消失的。
所以这个逻辑便是这样的:如果有权限则直接返回结果,是不会弹窗的。如果弹窗了,则一定是判断没权限。
那为什么这个弹窗出来后马上就消失了?起初怀疑发送模拟点击坐标不对,导致点到了外面的部分,弹窗便消失了。可后面检查代码,压根就没有发送模拟点击的广播(只会在启屏的时候发送一次广播,真正录制的时候不会发送)。可这个弹窗为什么就消失了呢?
排查了很久也没找到原因,而且办公室无法复现,这就很尴尬了,可问题还是需要解决的。
由上面的分析可知,肯定是打开了权限申请的 activity 才会导致弹窗展示出来。那如果我不申请权限了呢?利用上文末尾说到的 clone 的方式。于是改造了一下代码,在启屏页申请权限,然后将 intent 保存起来,真正要录屏时再使用 clone 方法重新生成一个 intent 传入进去。
1 | public void onActivityResult(int requestCode, int resultCode, Intent data) { |
注意每次 mp 的创建,使用完之后一定要注意调用 stop 方法,不然下次再使用时会导致崩溃:
1 | java.lang.IllegalStateException: Cannot start already started MediaProjection |
字面意思很明显了,所以用完一定要记得 stop,下次才能继续 clone 进行使用。这种方式需要至少同意一次录屏权限,如果没有 Launcher 的帮助,做不到自动授权的情况下,在 App 启动的时候只申请一次问题应该也不大,后续使用就利用 clone 的方式即可。