问题:我有一个屏幕截图应用程序,该应用程序使用 float 叠加层控件进行控制,并使用屏幕投射API Media Project Manager来访问屏幕。有时,当设备内存不足时,Android将重新启动服务,而我的媒体投影会丢失。
我知道要重新获得新的媒体投影的唯一方法是重新打开一个请求权限的 Activity ,这将是一个结局,除了一个问题。某些应用程序,特别是游戏,似乎在失去前台进程,暂停或以其他方式重置时会监听。真烦人
这是我理想的场景。服务打开,如果用户在权限请求对话框中选择了“选中不再询问我”,它将以不干扰当前前台 Activity 的方式获取媒体投影。
如何获得媒体投影经理,而又不打扰当前的前台流程?
有没有办法从直接服务中获取媒体投影,或者有办法从服务中在后台打开 Activity ?
目前,我在“ Activity ”中使用此代码来获取媒体投影管理器
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
protected void getScreenShotPermission() {
if(isLollipopOrNewer) {
mediaProjectionManager = (MediaProjectionManager) getContext().getSystemService(MEDIA_PROJECTION_SERVICE);
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), 1);
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (resultCode == Activity.RESULT_OK) {
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
this.finish();
}
}
}
最佳答案
所以我回到这里,是因为它愚蠢,它困扰着我,我想通了!
在另一个类(在我的类中是应用程序类)中,输入以下代码:
private static Intent screenshotPermission = null;
protected static void getScreenshotPermission() {
try {
if (hasScreenshotPermission()) {
if(null != mediaProjection) {
mediaProjection.stop();
mediaProjection = null;
}
mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, (Intent) screenshotPermission.clone());
} else {
openScreenshotPermissionRequester();
}
} catch (final RuntimeException ignored) {
openScreenshotPermissionRequester();
}
}
protected static void openScreenshotPermissionRequester(){
final Intent intent = new Intent(context, AcquireScreenshotPermissionIntent.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
protected static void setScreenshotPermission(final Intent permissionIntent) {
screenshotPermission = permissionIntent;
}
在处理初始请求的 Activity 类中(以我的情况为例:AcquireScreenshotPermissionIntent),将此代码放入onactivityresult中:
@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (1 == requestCode) {
if (Activity.RESULT_OK == resultCode) {
setScreenshotPermission((Intent) data.clone());
}
} else if (Activity.RESULT_CANCELED == resultCode) {
setScreenshotPermission(null);
log("no access");
}
finish();
只需在需要权限时调用getScreenShotPermission(),然后使用生成的mediaProjection对象。
它是这样工作的:魔术 token 是Intent中包含的一些数据。我最初尝试的是将结果意图用作全局变量,并使用它从非 Activity 类创建媒体投影。问题是它将失败。我最终弄清楚的是,当您使用它创建媒体投影时, token 会被消耗掉。将其作为参数传递或分配给新变量只是将指针传递给它,并且仍然被消耗。
您需要做的是使用object.clone();。这将创建 token 的新副本,新副本将被使用,并且您可以根据需要创建其他 token ,只要不使用原始 token 即可。作为奖励,您的应用程序每次启动仅需请求屏幕截图权限。如果其他事情接管了截屏视频,或者Android内存管理器找到了您,那么您一定会感到满意。您可以创建新的虚拟屏幕,而无需将onPause或onStop事件发送到其他应用。