Android Studio如何将Bitmap及QR码保存到系统相册
保存Bitmap(含Zxing生成二维码、网络加载图)到系统相册实现步骤
1. 配置对应权限
在AndroidManifest.xml的<manifest>标签下添加分版本的权限声明:
- API 33及以上版本:
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
- API 29-32版本:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
- API 28及以下版本:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
注意:涉及到危险权限时,需要在调用保存逻辑前先判断权限是否已授予,未授予时走动态权限申请流程,拿到权限后再执行保存
2. 编写通用Bitmap保存方法
该方法同时兼容Zxing生成的二维码Bitmap、网络请求获取的任意Bitmap对象,不需要针对不同来源做额外修改:
/** * 保存Bitmap到系统相册 * @param context 上下文 * @param bitmap 待保存的Bitmap对象 * @param fileName 保存的文件名(不含后缀) * @param description 图片备注信息 * @return 保存成功返回图片Uri,失败返回null */ private Uri saveBitmapToAlbum(Context context, Bitmap bitmap, String fileName, String description) { if (bitmap == null || bitmap.isRecycled()) { return null; } ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName + ".jpg"); values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); // 适配Android 10+分区存储,指定图片保存到公共相册目录的Pictures子文件夹 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/QRCodeImages"); values.put(MediaStore.Images.Media.IS_PENDING, 1); } ContentResolver resolver = context.getContentResolver(); Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); if (uri == null) { return null; } try (OutputStream os = resolver.openOutputStream(uri)) { // 压缩质量为90,兼顾清晰度和文件体积 bitmap.compress(Bitmap.CompressFormat.JPEG, 90, os); os.flush(); // Android 10+完成写入后移除IS_PENDING标记,让图片对其他应用可见 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { values.clear(); values.put(MediaStore.Images.Media.IS_PENDING, 0); resolver.update(uri, values, null, null); } return uri; } catch (Exception e) { // 写入失败时移除未完成的媒体记录 resolver.delete(uri, null, null); return null; } }
3. 嵌入下载按钮的点击逻辑
直接在现有R.id.qrindir点击分支里插入保存逻辑,补充判空和保存结果提示:
@Override public void onClick(View view) { Intent i; switch (view.getId()) { case R.id.qrindir: String inputContent = texttt.getText().toString().trim(); Bitmap imageResult = stringToBitmap(inputContent); // 直接调用通用保存方法即可,不管是Zxing生成的图还是从URL加载的图都能复用 Uri saveResult = saveBitmapToAlbum( this, imageResult, "QR_" + System.currentTimeMillis(), // 用时间戳做文件名避免重名 "用户生成的二维码图片" ); if (saveResult != null) { Toast.makeText(this, "已保存到系统相册", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "保存失败,请检查权限", Toast.LENGTH_SHORT).show(); } break; } }
补充说明
- 原有
stringToBitmap生成二维码的逻辑不需要修改,直接把返回的Bitmap传入保存方法即可 - 如果是从网络URL加载Bitmap的场景,只要把网络请求拿到的Bitmap对象传给
saveBitmapToAlbum方法,整套逻辑完全复用,不需要额外改写 - 保存的图片会统一出现在系统相册的
QRCodeImages文件夹下,不会和其他应用的图片混杂 - 代码中原本在
olustur点击事件里生成的Bitmap,也可以直接调用该保存方法,不需要重复写存储逻辑
内容的提问来源于stack exchange,提问作者ogi_plus
相关产品推荐
相关产品推荐

