Android开发:如何将用户从图库选中的图片保存到SharedPreferences?
功能实现方案
SharedPreferences 是轻量级键值对存储组件,仅支持存储基础类型数据,无法直接存储图片文件,有两种可选实现方案,优先推荐存储图片Uri的方案,性能损耗更低。
第一步:接收图库选择结果
你已经完成了跳转图库的逻辑,接下来需要重写 onActivityResult 方法接收用户选中的图片返回:
// 统一定义常量 private static final int ACTIVITY_SELECT_IMAGE = 1234; private static final String SP_NAME = "app_local_config"; private static final String KEY_PIC_URI = "user_selected_pic_uri"; private static final String KEY_PIC_BASE64 = "user_selected_pic_base64"; @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK && requestCode == ACTIVITY_SELECT_IMAGE && data != null) { Uri selectedImageUri = data.getData(); if (selectedImageUri == null) return; // 二选一执行存储逻辑 saveUriToSp(selectedImageUri); // 或者 saveBase64ToSp(selectedImageUri); } }
方案1:存储图片Uri(推荐)
仅存储图片的Uri字符串,不处理图片本身,性能最优,适合绝大多数场景:
// 存储Uri到SharedPreferences private void saveUriToSp(Uri uri) { SharedPreferences sp = getSharedPreferences(SP_NAME, MODE_PRIVATE); sp.edit() .putString(KEY_PIC_URI, uri.toString()) .apply(); } // 读取存储的Uri private Uri getUriFromSp() { SharedPreferences sp = getSharedPreferences(SP_NAME, MODE_PRIVATE); String uriStr = sp.getString(KEY_PIC_URI, null); return uriStr == null ? null : Uri.parse(uriStr); }
方案2:存储图片Base64编码(仅适合极小尺寸图片,如头像)
将图片压缩后转成Base64字符串存储,仅适合100KB以内的小图片,否则会严重拖慢SharedPreferences的读写速度:
// 存储Base64到SharedPreferences private void saveBase64ToSp(Uri uri) { try { // Uri转Bitmap Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri); // 压缩图片,质量系数50可根据需求调整 ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos); byte[] picBytes = baos.toByteArray(); // 转Base64编码 String base64Str = Base64.encodeToString(picBytes, Base64.DEFAULT); // 存入SP SharedPreferences sp = getSharedPreferences(SP_NAME, MODE_PRIVATE); sp.edit() .putString(KEY_PIC_BASE64, base64Str) .apply(); // 回收Bitmap避免内存泄漏 bitmap.recycle(); baos.close(); } catch (IOException e) { e.printStackTrace(); } } // 读取Base64转成Bitmap private Bitmap getPicFromSp() { SharedPreferences sp = getSharedPreferences(SP_NAME, MODE_PRIVATE); String base64Str = sp.getString(KEY_PIC_BASE64, null); if (base64Str == null) return null; byte[] picBytes = Base64.decode(base64Str, Base64.DEFAULT); return BitmapFactory.decodeByteArray(picBytes, 0, picBytes.length); }
注意事项
- 权限适配:Android 13及以上需要申请
READ_MEDIA_IMAGES权限,Android 11-12需要申请READ_EXTERNAL_STORAGE权限,低于Android 11需要动态申请存储权限才能正常读取图库图片 - Uri持久化:如果存储的是content类型的系统Uri,需要在拿到Uri后执行以下代码申请长期访问权限,否则应用重启后可能无法访问该图片:
getContentResolver().takePersistableUriPermission(selectedImageUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); - 性能限制:不要用SharedPreferences存储超过100KB的Base64字符串,大体积图片请直接存储到应用私有目录,SharedPreferences仅存储对应文件路径即可
内容的提问来源于stack exchange,提问作者JudgeFudge
相关产品推荐
相关产品推荐

