Android读取相册图片并显示

本文最后更新于:2024年3月18日 晚上

Android根据Uri访问图片

在新的Android版本中,startActivityForResult方法被启用了,取而代之的是registerForActivityResult方法,registerForActivityResult方法需要在Activity中注册。
注册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Override  
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
intentActivityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),new ActivityResultCallback<ActivityResult>(){
@Override
public void onActivityResult(ActivityResult result) {
if(result.getResultCode() == Activity.RESULT_OK) {
Uri uri = result.getData().getData();
if(imageProduct!=null && editTextImagePath!= null){
Picasso.with(getContext()).load(uri).into(imageProduct);
editTextImagePath.setText(uri.toString());
}
adapter.setImage(uri);
}
}
});
}

其中intentActivityResultLauncher变量是ActivityResultLauncher<Intent>,这里在之前进行了声明,所以直接使用了。
给按钮添加点击事件进行访问

1
2
3
4
5
imageProduct.setOnClickListener(imageView->{  
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
intentActivityResultLauncher.launch(intent);
});

修改,改进

这种方式可以正确的读取相册图片,并显示在imageView上,但是有一个问题,在通过这一方式打开相册并选取文件后,照片能够正常显示,但是当第一次打开软件时,这些图片并不能正常显示,只有当执行“打开相册,并选择照片”这一操作后才能正常显示。

不过问题并不出现在这里,而是读取的链接问题,通过log输出日志可以发现,读取到的Uri地址为content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2Ftest.jpg,这种content Uri无法直接通过Picasso或setImageUri方法来设置图片,需要转化为文件路径,代码如下:
获取文件路径

1
2
3
4
5
6
7
8
9
10
11
12
private String getImagePath(Uri uri, String selection) {  
String path = null;
// 通过Uri和selection来获取真实的图片路径
Cursor cursor = getContext().getContentResolver().query(uri, null, selection, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
}
cursor.close();
}
return path;
}

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Override  
protected void convert(@NonNull MyProductViewHolder holder, Product product) {
//填充数值
String TAG = "Test: file";
try{
if(!product.getImage().equals("")){
if(DocumentsContract.isDocumentUri(getContext(),Uri.parse(product.getImage()))){
Uri uri = Uri.parse(product.getImage());
String imagePath = "";
String docId = DocumentsContract.getDocumentId(uri);
Log.d(TAG, "docId: " + docId);
if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
if (docId.startsWith("raw:")) {
imagePath = docId.replaceFirst("raw:", "");
} else {
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.parseLong(docId));
imagePath = getImagePath(contentUri, null);
}
Log.d(TAG, imagePath);
}
//Picasso.with(getContext()).load(Uri.parse(imagePath)).into(holder.imageView);
holder.imageView.setImageURI(Uri.parse(imagePath));
}
else {
Picasso.with(getContext()).load(product.getImage()).into(holder.imageView);
}
}
else
throw new Exception();
}catch (Exception exception){
holder.imageView.setImageDrawable(getContext().getDrawable(R.drawable.product_placeholder));
}
holder.name.setText(product.getName());
holder.model.setText(product.getModel());
holder.material.setText(product.getUsedMaterial());
holder.price.setText("¥"+ String.valueOf(product.getPrice()));
}

最后得到的,可以通过setImageURI方法设置,并直接访问的文件路径格式为/storage/emulated/0/Download/wallhaven-wyzd56.png


Android 调用相册返回路径以及返回Uri的总结 - carry莫奈 - 博客园 (cnblogs.com)
Android uri转真实路径。_androidzmm的博客-CSDN博客_android uri转路径


Android读取相册图片并显示
http://starnight.top/2022/05/03/Android读取相册图片并显示/
作者
Cardy Xie
发布于
2022年5月3日
许可协议