在我的Android应用程序中,我使用 EXTRA_ALLOW_MULTIPLE 的意图,从图库中选择一个或多个图片,然后所选图片将显示在 RecyclerView 中用户,通常我没有问题发生功能是按预期的,但有时,当加载 RecyclerView 图片时,图像出现两次,当这发生时,它取代了另一个图片。以下是我用于转到图库的代码,以及 OnActivityResult 方法和相关方法。
GalleryIntent :
private void galleryIntent()
{
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);//
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(Intent.createChooser(intent, "Select File"),SELECT_FILE);
}
OnActivityResult :
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
int dataCount=0;
Uri tempUri;
List<Uri> multiUri=null;
if (resultCode == Activity.RESULT_OK) {
if(data!=null){
if(data.getClipData()==null){
//Solo una foto seleccionada
onSelectFromGalleryResults(data.getData());
}else{
//Mas de una foto seleccionada
dataCount=data.getClipData().getItemCount();
multiUri=new ArrayList<>();
for(int y=0; y<dataCount;y++){
tempUri=data.getClipData().getItemAt(y).getUri();
multiUri.add(tempUri);
}
onSelectFromGalleryMultiResults(multiUri);
}
}
}
}
从这些我觉得有必要为了清楚起见,以便在填写 RecyclerView 时添加,我向适配器传递真实路径的列表< / strong>这些图片,我通过以下代码获得这些真实路径,给它相应的 URI 图片:
public class PathUtil {
/*
* Gets the file path of the given Uri.
*/
@SuppressLint("NewApi")
public static String getPath(Context context, Uri uri) throws URISyntaxException {
final boolean needToCheckUri = Build.VERSION.SDK_INT >= 19;
String selection = null;
String[] selectionArgs = null;
// Uri is different in versions after KITKAT (Android 4.4), we need to
// deal with different Uris.
if (needToCheckUri && DocumentsContract.isDocumentUri(context.getApplicationContext(), uri)) {
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
return Environment.getExternalStorageDirectory() + "/" + split[1];
} else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
uri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
} else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("image".equals(type)) {
uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
selection = "_id=?";
selectionArgs = new String[]{ split[1] };
}
}
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
}
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
}
然后,在适配器中,我使用这些路径加载图片,然后填写 RecyclerView (我这样做是因为需要检索这些图片在应用程序的后面部分)
最后,这是我用来获取真实路径的位图的方法:
public static Bitmap getSampleBitmapFromFile(String bitmapFilePath, int reqWidth, int reqHeight) throws FileNotFoundException {
// calculating image size
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(new File(bitmapFilePath)), null, options);
int scale = calculateInSampleSize(options, reqWidth, reqHeight);
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(new File(bitmapFilePath)), null, o2);
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Alto y ancho original de la imagen
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
//Calculo de relacion entre ancho y alto para obtener una escala apropiada
final int heightRatio = Math.round((float)height / (float)reqHeight);
final int widthRatio = Math.round((float)width / (float)reqWidth);
// EScoger la relacion mas pequeña en inSamplesize, esto garantiza el tamaño correcto deseado
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
好吧,正如我已经提到的,大多数时候一切都运行正常,但在某些测试中,即使使用不同的路径,它们也会加载相同的图像,如果其他任何东西可能需要我的部分作为附加信息以便解决这个问题我也会尝试编辑它。
编辑: 这是OnSelectFromGalleryResults方法,以及MultiResults,它们基本相同。设置图像和多图像也基本相同
private void onSelectFromGalleryResults(Uri fotoUri) {
if (fotoUri!=null){
String filePath="";
try {
filePath= PathUtil.getPath(getActivity(),fotoUri);
} catch (URISyntaxException e) {
e.printStackTrace();
}
//Se agrega a la lista de fotos para el adaptador
setupImage(filePath);
}else {
Toast.makeText(getContext(), "Archivo no encontrado.", Toast.LENGTH_SHORT).show();
}
}
public void onSelectFromGalleryMultiResults(List<Uri> myImagesUris){
List<String> multiRealPaths=new ArrayList<>();
if(myImagesUris==null)
return;
for(int h=0; h<myImagesUris.size();h++){
if (myImagesUris.get(h)!=null){
String filePath="";
try {
filePath= PathUtil.getPath(getActivity(),myImagesUris.get(h));
} catch (URISyntaxException e) {
e.printStackTrace();
}
//Se agrega a la lista de fotos tomadas
multiRealPaths.add(filePath);
}else {
Toast.makeText(getContext(), "Archivo no encontrado.", Toast.LENGTH_SHORT).show();
}
}
setupMultiImage(multiRealPaths);
}
private void setupMultiImage(List<String> realPaths) {
mCallBack.PhotoSetPhotoInspection(true);
takenUris.addAll(realPaths);
photosTakenCounter=takenUris.size();
photosTaken.clear();
photosTaken.addAll(takenUris);
if(gVA==null){
gVA= new GridViewAdapter(getContext(), R.layout.grid_item_layout, photosTaken);
gV.setAdapter(gVA);
gVA.notifyDataSetChanged();
}else{
gVA.notifyDataSetChanged();
}
//Se actualiza la lista de imagenes en la actividad controladora
mCallBack.sendPhotoPaths(takenUris);
}