文章目录
Android读取相册
读取相册
说明: 方法有许多,我也尝试了许多,但好像就下面这个方法可行,其他的方法也有可能是可以的,毕竟我也是初学者
1. 使用onActivityResult读取图片并保存
虽然已经弃用了,但是应该还能用 (至少我用了貌似没问题) ,别看弃用,但挺管用哈哈 接下来就是看代码吧!
布局就不展示了
private Uri imageUri;
private String imagePath;
btnAlbum.setOnClickListener(v -> {
Intent intent = new Intent(Intent.ACTION_PICK,null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
startActivityForResult(intent,1);
});
然后就是重写onActivityResult
方法
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == Activity.RESULT_OK && data != null) {
imageUri = data.getData();
if (imageUri != null) {
//把该图片单独保存下,其他地方还要使用
saveImageToPrivateDirectory(imageUri);
ivPhoto.setImageURI(Uri.fromFile(new File(imagePath)));
}
}
}
private void saveImageToPrivateDirectory(Uri imageUri) {
try {
InputStream inputStream = requireContext().getContentResolver().openInputStream(imageUri);
if (inputStream == null) return;
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
File imageFile = new File(requireContext().getExternalFilesDir(null), "saved_image.jpg");
FileOutputStream outputStream = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.flush();
outputStream.close();
inputStream.close();
imagePath = imageFile.getAbsolutePath();
Log.d("TAG", "Image saved to: " + imagePath);
} catch (IOException e) {
Toast.makeText(requireContext(), "图片保存失败", Toast.LENGTH_SHORT).show();
}
}
-
通过
ContentResolver
使用给定的imageUri
打开输入流InputStream
。imageUri
是从相册选择的图片的路径。requireContext()
用于获取 Context 对象。 -
通过
BitmapFactory.decodeStream()
方法将InputStream
转换为Bitmap
对象 -
File
对象,指定图片的保存路径和文件名。getExternalFilesDir(null)
返回应用的私有外部存储目录路径(该路径在应用卸载时会被系统自动清除)saved_image.jpg
是要保存的图片文件名。 -
创建一个
FileOutputStream
对象,关联刚才创建的imageFile
文件,用于将图片数据写入到该文件中。 -
将
Bitmap
对象中的图片数据压缩为JPEG
格式,并写入到outputStream
中。100 表示最高质量的压缩,值范围为 0 到 100,其中 100 表示无损压缩。
注: 为什么要使用私有外部存储目录而不使用共有存储目录?
- 首先使用共有存储目录需要申请权限才能访问,并且如果是Android 6.0以上需要动态申请,比较麻烦,而且还不一定能行,官方也建议不使用该方法.
官方的解释:
- 在API级别29中不赞成使用此方法 (Environment.getExternalStorageDirectory()) 。为了提高用户隐私,不建议直接访问共享/外部存储设备。
- 应用程序可以继续访问内容通过迁移到替代品,如存储在私有目录 getExternalFilesDir()
- 在 Android 10(API 级别 29)及更高版本中,直接访问外部存储路径 /storage/emulated/0/ 的方式已经被限制。Android 推荐使用应用私有目录来保存文件,这样无需额外的存储权限 (不需要访问权限)。
2. 其他地方展示保存后的图片
imageView.setImageBitmap(BitmapFactory.decodeFile(imagePath));
imagePath
是在 saveImageToPrivateDirectory
方法中获得的.
3. 图片展示异常解决办法
1. 路径错误
通过 BitmapFactory.decodeFile(realPath)
来加载图片。如果 realPath
不正确,或者路径对应的文件不存在,图片加载就会失败。
2. 权限问题
AndroidManifest
中添加权限
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />
3. 图片太大
如果图片过大,加载时可能导致内存问题,甚至导致加载失败。
解决办法:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2; // 将图片缩小一半
Bitmap bitmap = BitmapFactory.decodeFile(realPath, options);
ivCommodity.setImageBitmap(bitmap);
4. 报错 java.io.FileNotFoundException: /storage/emulated/0/ (Permission denied)
参考解决办法, 上面的可行代码也使用了该办法
上述问题只是我遇到过的,也可能有其他问题,仅供参考