To start a virtual display and use the AccessibilityService's takeScreenshot method over it in Android, you need to combine the MediaProjection API (for virtual display creation) and the AccessibilityService API (for taking screenshots). Here’s a step-by-step guide:
In your AndroidManifest.xml, declare the necessary permissions:
xml<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- Optional, if needed --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- If saving screenshots -->
Use MediaProjectionManager to create a virtual display. You need user permission to capture the screen.
javaMediaProjectionManager mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE); Intent permissionIntent = mProjectionManager.createScreenCaptureIntent(); startActivityForResult(permissionIntent, REQUEST_CODE);
After getting permission, create a virtual display:
javaMediaProjection mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data); DisplayMetrics metrics = getResources().getDisplayMetrics(); int width = metrics.widthPixels; int height = metrics.heightPixels; int dpi = metrics.densityDpi; ImageReader mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 2); VirtualDisplay mVirtualDisplay = mMediaProjection.createVirtualDisplay( "ScreenCapture", width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader.getSurface(), null, null);
Extend AccessibilityService and use takeScreenshot (API 30+).
xml<service android:name=".MyAccessibilityService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> </intent-filter> <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibility_service_config" /> </service>
accessibility_service_config.xmlxml<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/accessibility_service_description" android:accessibilityEventTypes="typeAllMask" android:accessibilityFlags="flagDefault" android:canRetrieveWindowContent="true" android:settingsActivity="com.example.MainActivity" />
takeScreenshotjavapublic class MyAccessibilityService extends AccessibilityService { @Override public void onAccessibilityEvent(AccessibilityEvent event) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { takeScreenshot( /* displayId */ Display.DEFAULT_DISPLAY, /* exec */ new ScreenshotCallback() { @Override public void onSuccess(ScreenshotResult result) { // Handle screenshot result } @Override public void onFailure(int errorCode) { // Handle error } }); } } @Override public void onInterrupt() {} }
AccessibilityService.takeScreenshot on the virtual display’s ID (if supported) or the default display.Release resources when done:
javamVirtualDisplay.release(); mMediaProjection.stop();
takeScreenshot requires API 30 (Android 11).MediaProjection and AccessibilityService require explicit user consent.