You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android无障碍服务截图返回错误码1的原因及解决方法

错误码1的原因分析

错误码1是Android辅助功能服务启动失败的常见标识,主要由以下几种情况导致:

  • 辅助功能服务未被系统启用:AccessibilityService必须由用户在系统设置的「辅助功能」页面手动开启,未启用状态下所有服务调用都会返回失败。
  • 权限声明不完整:Manifest文件中缺少android.permission.BIND_ACCESSIBILITY_SERVICE权限,或者辅助服务的配置文件(accessibility_service_config.xml)参数错误,导致系统无法绑定服务。
  • MediaProjection权限未获取:截图依赖MediaProjection的屏幕录制权限,若用户拒绝授权请求,或未正确发起授权流程,会导致截图服务启动失败。
  • 调用时机错误:在AccessibilityService未完成绑定(未触发onServiceConnected)时就调用截图逻辑,或在非服务上下文(如普通Activity)直接执行截图操作。
AccessibilityService实现截图的正确方式

1. 配置辅助功能服务

(1)Manifest注册服务

确保在AndroidManifest.xml中正确声明服务,包含必要权限和配置:

<service
    android:name=".ScreenshotAccessibilityService"
    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>

(2)创建辅助服务配置文件

在res/xml/目录下创建accessibility_service_config.xml,开启窗口内容获取权限:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true"
    android:description="@string/accessibility_service_desc" />

description需要在strings.xml中定义,用于系统设置中展示服务说明。

2. 获取MediaProjection权限

截图依赖屏幕录制权限,必须从Activity发起授权请求:

private static final int REQ_SCREEN_CAPTURE = 100;

private void requestScreenCapturePermission() {
    MediaProjectionManager manager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
    Intent captureIntent = manager.createScreenCaptureIntent();
    startActivityForResult(captureIntent, REQ_SCREEN_CAPTURE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQ_SCREEN_CAPTURE && resultCode == RESULT_OK) {
        // 将授权结果传递给AccessibilityService
        ScreenshotAccessibilityService.setCaptureParams(resultCode, data);
    }
}

3. 实现AccessibilityService截图逻辑

@AutoService(AccessibilityService.class)
public class ScreenshotAccessibilityService extends AccessibilityService {
    private static int sResultCode;
    private static Intent sCaptureData;
    private MediaProjection mMediaProjection;
    private ImageReader mImageReader;
    private DisplayMetrics mMetrics;

    public static void setCaptureParams(int resultCode, Intent data) {
        sResultCode = resultCode;
        sCaptureData = data;
    }

    @Override
    public void onServiceConnected() {
        super.onServiceConnected();
        // 初始化屏幕参数
        mMetrics = getResources().getDisplayMetrics();
        // 创建MediaProjection实例
        MediaProjectionManager manager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        mMediaProjection = manager.getMediaProjection(sResultCode, sCaptureData);
        // 初始化ImageReader用于接收截图数据
        mImageReader = ImageReader.newInstance(mMetrics.widthPixels, mMetrics.heightPixels,
                PixelFormat.RGBA_8888, 1);
    }

    // 对外提供的截图方法,可通过按钮点击触发
    public void takeScreenshot() {
        if (mMediaProjection == null || mImageReader == null) {
            return;
        }
        // 创建虚拟显示器,将屏幕内容投射到ImageReader的Surface
        mMediaProjection.createVirtualDisplay("ScreenshotDisplay",
                mMetrics.widthPixels, mMetrics.heightPixels, mMetrics.densityDpi,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                mImageReader.getSurface(), null, null);

        // 监听截图图像可用事件
        mImageReader.setOnImageAvailableListener(reader -> {
            try (Image image = reader.acquireLatestImage()) {
                if (image == null) return;
                // 将Image转换为Bitmap
                Image.Plane[] planes = image.getPlanes();
                ByteBuffer buffer = planes[0].getBuffer();
                int pixelStride = planes[0].getPixelStride();
                int rowStride = planes[0].getRowStride();
                int rowPadding = rowStride - pixelStride * mMetrics.widthPixels;

                Bitmap bitmap = Bitmap.createBitmap(mMetrics.widthPixels + rowPadding / pixelStride,
                        mMetrics.heightPixels, Bitmap.Config.ARGB_8888);
                bitmap.copyPixelsFromBuffer(buffer);
                // 裁剪掉多余的padding
                bitmap = Bitmap.createBitmap(bitmap, 0, 0, mMetrics.widthPixels, mMetrics.heightPixels);
                // 保存或处理截图
                saveScreenshot(bitmap);
            }
        }, null);
    }

    private void saveScreenshot(Bitmap bitmap) {
        // 示例:保存到应用私有目录
        File screenshotFile = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES),
                "screenshot_" + System.currentTimeMillis() + ".png");
        try (FileOutputStream fos = new FileOutputStream(screenshotFile)) {
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        // 可选:监听窗口事件,自动触发截图
    }

    @Override
    public void onInterrupt() {
        // 服务中断时清理资源
        if (mMediaProjection != null) {
            mMediaProjection.stop();
            mMediaProjection = null;
        }
        if (mImageReader != null) {
            mImageReader.close();
            mImageReader = null;
        }
    }
}

4. 引导用户开启辅助功能服务

在APP中添加引导逻辑,跳转到系统辅助功能设置页面:

private void openAccessibilitySettings() {
    Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
    startActivity(intent);
}

注意事项

  • Android 10及以上版本,保存截图到公共目录需要WRITE_EXTERNAL_STORAGE权限,或使用MediaStore API进行存储。
  • 必须确保AccessibilityService已启用且MediaProjection权限已获取,才能调用takeScreenshot方法。
  • 服务销毁时需及时清理MediaProjection和ImageReader资源,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Toby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 10:01:15