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
相关产品推荐
相关产品推荐

