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

Android开发如何实现点击按钮后截图并保存到本地的功能?

具体实现步骤

1. 权限适配补充

你已经在清单中声明了基础权限,但是Android 6.0及以上版本需要动态申请存储权限,Android 10及以上版本推荐使用MediaStore实现分区存储适配,不需要额外申请WRITE_EXTERNAL_STORAGE权限。

2. 完整功能实现代码

public class MainActivity extends AppCompatActivity {
    // 权限请求标识码
    private static final int PERMISSION_REQ_CODE = 1001;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ViewGroup viewgroup = new LinearLayout(this);
        viewgroup.setOrientation(LinearLayout.VERTICAL);

        Button btn = new Button(this);
        btn.setId(1);
        btn.setLayoutParams(new LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        ));
        btn.setText("截图保存");
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 权限校验通过后执行截图逻辑
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ||
                    checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                    takeScreenshotAndSave();
                } else {
                    // 动态申请存储权限
                    requestPermissions(new String[]{
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.READ_EXTERNAL_STORAGE
                    }, PERMISSION_REQ_CODE);
                }
            }
        });

        viewgroup.addView(btn);
        viewgroup.addView(new PaintView(this));
        setContentView(viewgroup);
    }

    // 权限申请结果回调
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQ_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                takeScreenshotAndSave();
            } else {
                Toast.makeText(this, "需要存储权限才能保存截图", Toast.LENGTH_SHORT).show();
            }
        }
    }

    // 截图+保存核心方法
    private void takeScreenshotAndSave() {
        // 获取当前页面根View(如果只需要截取PaintView内容,替换为对应的PaintView实例即可)
        View rootView = getWindow().getDecorView().getRootView();
        // 开启绘图缓存
        rootView.setDrawingCacheEnabled(true);
        // 从缓存生成截图Bitmap
        Bitmap screenshot = Bitmap.createBitmap(rootView.getDrawingCache());
        // 关闭缓存避免内存泄漏
        rootView.setDrawingCacheEnabled(false);

        if (screenshot == null) {
            Toast.makeText(this, "截图生成失败", Toast.LENGTH_SHORT).show();
            return;
        }

        // 配置存储参数
        String fileName = "screenshot_" + System.currentTimeMillis() + ".png";
        ContentValues saveParams = new ContentValues();
        saveParams.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);
        saveParams.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // Android 10+指定存储路径
            saveParams.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/MyScreenshots");
            saveParams.put(MediaStore.Images.Media.IS_PENDING, 1);
        }

        // 写入文件到系统相册
        Uri saveUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, saveParams);
        if (saveUri != null) {
            try {
                OutputStream outputStream = getContentResolver().openOutputStream(saveUri);
                screenshot.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
                if (outputStream != null) {
                    outputStream.close();
                }
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    saveParams.clear();
                    saveParams.put(MediaStore.Images.Media.IS_PENDING, 0);
                    getContentResolver().update(saveUri, saveParams, null, null);
                }
                Toast.makeText(this, "截图已保存到相册", Toast.LENGTH_SHORT).show();
                // 回收Bitmap释放内存
                screenshot.recycle();
            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(this, "保存失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
            }
        }
    }
}

3. 版本适配提示

  • 若目标版本为Android 13(API 33)及以上,存储权限需要替换为READ_MEDIA_IMAGES,不再使用旧版读写存储权限
  • 可通过修改RELATIVE_PATH参数自定义截图的存储目录

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 06:36:03