如何获取Android系统中最近使用应用的缩略图?
获取Android最近使用应用缩略图的可行方案
1. Android 5.0~9(API 21-28):直接调用系统API获取缓存缩略图
这个版本区间可通过系统API直接获取已缓存的最近应用缩略图,无需手动截图:
实现步骤:
- 声明权限:在
AndroidManifest.xml中添加
<uses-permission android:name="android.permission.GET_TASKS" />
- 代码实现:
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); // 获取最近10个任务,可按需调整数量 List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasks(10, ActivityManager.RECENT_WITH_EXCLUDED); for (ActivityManager.RecentTaskInfo task : recentTasks) { Bitmap thumbnail = task.thumbnail; if (thumbnail != null) { // 处理获取到的缩略图(比如展示到ImageView) } }
2. Android 10+(API 29及以上):替代方案
getRecentTasks()在API 29被官方废弃,普通应用无法直接获取系统缓存的最近应用缩略图,可采用以下两种方案:
方案A:唤起系统最近任务界面(无需自行展示缩略图)
如果核心需求是让用户快速切换应用,可直接调用系统自带的最近任务界面,无需自己处理缩略图:
Intent intent = new Intent(Intent.ACTION_RECENT_APPS); startActivity(intent);
方案B:通过屏幕截图获取(需用户授权)
若必须在自有应用中展示缩略图,只能通过MediaProjection API请求屏幕录制权限,截取当前前台应用画面,再结合UsageStatsManager获取的最近应用列表匹配:
实现步骤:
- 声明权限并引导开启应用使用统计权限:
在AndroidManifest.xml中添加
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
引导用户到设置页面开启权限:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); startActivity(intent);
- 请求屏幕录制权限并执行截图:
private static final int REQUEST_CODE_SCREEN_CAPTURE = 100; private MediaProjectionManager mediaProjectionManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE); } // 触发截图的方法 private void startScreenCapture() { Intent captureIntent = mediaProjectionManager.createScreenCaptureIntent(); startActivityForResult(captureIntent, REQUEST_CODE_SCREEN_CAPTURE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_SCREEN_CAPTURE && resultCode == RESULT_OK) { MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data); DisplayMetrics metrics = getResources().getDisplayMetrics(); int screenWidth = metrics.widthPixels; int screenHeight = metrics.heightPixels; int screenDensity = metrics.densityDpi; ImageReader imageReader = ImageReader.newInstance(screenWidth, screenHeight, PixelFormat.RGBA_8888, 1); VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay("AppThumbnailCapture", screenWidth, screenHeight, screenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, imageReader.getSurface(), null, null); // 延迟获取截图,确保画面渲染完成 new Handler(Looper.getMainLooper()).postDelayed(() -> { Image image = imageReader.acquireLatestImage(); if (image != null) { Bitmap bitmap = imageToBitmap(image); // 处理获取到的截图(作为当前前台应用的缩略图) image.close(); } virtualDisplay.release(); mediaProjection.stop(); }, 500); } } // 将Image转换为Bitmap的工具方法 private Bitmap imageToBitmap(Image image) { Image.Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(); int rowStride = planes[0].getRowStride(); int rowPadding = rowStride - pixelStride * image.getWidth(); Bitmap bitmap = Bitmap.createBitmap(image.getWidth() + rowPadding / pixelStride, image.getHeight(), Bitmap.Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return Bitmap.createBitmap(bitmap, 0, 0, image.getWidth(), image.getHeight()); }
3. 关键注意事项
- 权限限制:不同Android版本权限要求严格,API 21-28需
GET_TASKS,API 29+需用户手动开启应用使用权限和屏幕录制权限; - 系统兼容性:部分定制ROM可能限制
getRecentTasks()返回结果,或不保存最近应用缩略图缓存; - 性能问题:截图方案会消耗系统资源,建议仅在用户主动触发时执行,避免频繁操作。
内容的提问来源于stack exchange,提问作者Lien
相关产品推荐
相关产品推荐

