Android 通过反射获取后台应用的快照
都在代码里了,如果无效注意反射要判断sdk版本
/**
* 获取应用快照
*/
public class SnapShotUtil {
@RequiresApi(api = Build.VERSION_CODES.Q)
public static Bitmap getTargetTaskShot(Activity activity, String pkgName) {
PackageManager packageManager = activity.getPackageManager();
ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RecentTaskInfo> recentTasks = activityManager.getRecentTasks(100, 1);
for (ActivityManager.RecentTaskInfo recentTaskInfo : recentTasks) {
ResolveInfo resolveActivity =
packageManager.resolveActivity(recentTaskInfo.baseIntent, 0);
if (resolveActivity == null || resolveActivity.activityInfo == null) {
continue;
}
String str = resolveActivity.activityInfo.packageName;
if (!Objects.equals(str, pkgName)) {
continue;
}
try {
Object activityTaskManagerService = getActivityTaskManagerService();
Object taskSnapshot = getTaskSnapshot(activityTaskManagerService, recentTaskInfo);
Object snapshot = getSnapshot(taskSnapshot);
Object hardwareBuffer = getHardwareBuffer(snapshot);
Object colorSpace = getColorSpace(taskSnapshot);
return Bitmap.wrapHardwareBuffer((HardwareBuffer) hardwareBuffer, (ColorSpace) colorSpace);
} catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException |
IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
}
return null;
}
@SuppressLint("PrivateApi")
private static Object getActivityTaskManagerService() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class<?> clazz = Class.forName("android.app.ActivityTaskManager");
Method getServiceMethod = clazz.getMethod("getService");
getServiceMethod.setAccessible(true);
return getServiceMethod.invoke(null);
}
@RequiresApi(api = Build.VERSION_CODES.Q)
private static Object getTaskSnapshot(Object object, ActivityManager.RecentTaskInfo recentTaskInfo) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class<?> clazz = object.getClass();
Method getTaskSnapshotMethod = clazz.getMethod("getTaskSnapshot", int.class, boolean.class);
getTaskSnapshotMethod.setAccessible(true);
return getTaskSnapshotMethod.invoke(object, recentTaskInfo.taskId, true);
}
private static Object getSnapshot(Object taskSnapshot) throws NoSuchFieldException, IllegalAccessException {
Class<?> clazz = taskSnapshot.getClass();
Field mSnapshotField = clazz.getDeclaredField("mSnapshot");
mSnapshotField.setAccessible(true);
return mSnapshotField.get(taskSnapshot);
}
private static Object getColorSpace(Object taskSnapshot) throws NoSuchFieldException, IllegalAccessException {
Class<?> clazz = taskSnapshot.getClass();
Field mColorSpaceField = clazz.getDeclaredField("mColorSpace");
mColorSpaceField.setAccessible(true);
return mColorSpaceField.get(taskSnapshot);
}
private static Object getHardwareBuffer(Object graphicBuffer) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class<?> clazz = HardwareBuffer.class;
Method createFromGraphicBufferMethod = clazz.getMethod("createFromGraphicBuffer", graphicBuffer.getClass());
return createFromGraphicBufferMethod.invoke(null, graphicBuffer);
}