如何从我的应用程序的库(SD卡)中选择图像?

Pra*_*een 341 android android-gallery android-image

这个问题最初是针对Android 1.6提出的.

我在我的应用程序中处理照片选项.

我的Activity中有一个按钮和一个ImageView.当我点击按钮时,它会重定向到图库,我可以选择一个图像.所选图像将出现在我的ImageView中.

Ste*_*ley 415

近5年后更新的答案:

原始答案中的代码不再可靠,因为来自各种来源的图像有时会返回不同的内容URI,content://而不是file://.更好的解决方案是简单地使用context.getContentResolver().openInputStream(intent.getData()),因为它将返回您可以根据需要处理的InputStream.

例如,BitmapFactory.decodeStream()在这种情况下可以完美地工作,因为您还可以使用Options和inSampleSize字段对大图像进行下采样并避免内存问题.

但是,像Google云端硬盘这样的内容会将URI返回到尚未实际下载的图片.因此,您需要在后台线程上执行getContentResolver()代码.


原始答案:

其他答案解释了如何发送意图,但他们没有很好地解释如何处理响应.以下是有关如何执行此操作的示例代码:

protected void onActivityResult(int requestCode, int resultCode, 
       Intent imageReturnedIntent) {
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent); 

    switch(requestCode) { 
    case REQ_CODE_PICK_IMAGE:
        if(resultCode == RESULT_OK){  
            Uri selectedImage = imageReturnedIntent.getData();
            String[] filePathColumn = {MediaStore.Images.Media.DATA};

            Cursor cursor = getContentResolver().query(
                               selectedImage, filePathColumn, null, null, null);
            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String filePath = cursor.getString(columnIndex);
            cursor.close();


            Bitmap yourSelectedImage = BitmapFactory.decodeFile(filePath);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在此之后,您已将选定的图像存储在"yourSelectedImage"中,以执行您想要的任何操作.此代码通过在ContentResolver数据库中获取图像的位置来工作,但这本身是不够的.每个图像有大约18列信息,从其文件路径到"上次修改日期"到拍摄照片的GPS坐标,尽管实际上没有使用许多字段.

为了节省时间,因为您实际上不需要其他字段,光标搜索是使用过滤器完成的.过滤器通过指定所需列的名称MediaStore.Images.Media.DATA(路径),然后将该字符串[]指定给游标查询来工作.游标查询返回路径,但在使用columnIndex代码之前,您不知道它在哪个列中.这只是根据其名称获取列的编号,与过滤过程中使用的相同.一旦你有了这个,你终于能够用我给出的最后一行代码将图像解码成位图.

  • 您应该以这种方式获取图像而不是光标:位图b = MediaStore.Images.Media.getBitmap(this.getContentResolver(),selectedImage); (14认同)
  • 这对我不起作用,我从cursor.getString(columnIndex)得到一个null; (9认同)
  • 请谨慎使用此方法:当用户从picasa相册或Google+照片应用中选择照片时,文件名将为"空". (9认同)
  • 应该检查cursor.moveToFirst()是否存在:if(cursor.moveToFirst()){对游标数据执行某些操作} (4认同)
  • Luigi,如果Bitmap很大,MediaStore.Images.Media.getBitmap()会导致OutOfMemory异常.史蒂夫的方法允许在将图像加载到内存之前缩小图像. (4认同)

sia*_*mii 314

private static final int SELECT_PHOTO = 100;
Run Code Online (Sandbox Code Playgroud)

开始意图

Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);    
Run Code Online (Sandbox Code Playgroud)

处理结果

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { 
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent); 

    switch(requestCode) { 
    case SELECT_PHOTO:
        if(resultCode == RESULT_OK){  
            Uri selectedImage = imageReturnedIntent.getData();
            InputStream imageStream = getContentResolver().openInputStream(selectedImage);
            Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,您也可以对图像进行下采样以避免OutOfMemory错误.

private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException {

        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o);

        // The new size we want to scale to
        final int REQUIRED_SIZE = 140;

        // Find the correct scale value. It should be the power of 2.
        int width_tmp = o.outWidth, height_tmp = o.outHeight;
        int scale = 1;
        while (true) {
            if (width_tmp / 2 < REQUIRED_SIZE
               || height_tmp / 2 < REQUIRED_SIZE) {
                break;
            }
            width_tmp /= 2;
            height_tmp /= 2;
            scale *= 2;
        }

        // Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        return BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2);

    }
Run Code Online (Sandbox Code Playgroud)

  • 将1.5MB jpeg放入我的小型100px乘100px imageview导致VM内存不足错误.下采样修复了这个问题:-) (8认同)

Rob*_*ond 87

您必须为结果启动图库意图.

Intent i = new Intent(Intent.ACTION_PICK,
               android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, ACTIVITY_SELECT_IMAGE); 
Run Code Online (Sandbox Code Playgroud)

然后onActivityForResult,打电话intent.getData()来获取图像的Uri.然后,您需要从ContentProvider获取图像.

  • 使用ACTION_PICK指定特定URI,使用ACTION_GET_CONTENT指定mime_type.我使用了ACTION_PICK,因为问题特别是来自SDCARD的图像而不是所有图像. (4认同)
  • 凉.这正是我需要和工作的魅力:)不知道从哪里你们发现这个东西:) (2认同)

Muh*_*que 22

这是一个经过测试的图像和视频代码.它适用于所有小于19且大于19的API.

图片:

if (Build.VERSION.SDK_INT <= 19) {
                        Intent i = new Intent();
                        i.setType("image/*");
                        i.setAction(Intent.ACTION_GET_CONTENT);
                        i.addCategory(Intent.CATEGORY_OPENABLE);
                        startActivityForResult(i, 10);
                    } else if (Build.VERSION.SDK_INT > 19) {
                        Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                        startActivityForResult(intent, 10);
                    }
Run Code Online (Sandbox Code Playgroud)

视频:

if (Build.VERSION.SDK_INT <= 19) {
                        Intent i = new Intent();
                        i.setType("video/*");
                        i.setAction(Intent.ACTION_GET_CONTENT);
                        i.addCategory(Intent.CATEGORY_OPENABLE);
                        startActivityForResult(i, 20);
                    } else if (Build.VERSION.SDK_INT > 19) {
                        Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
                        startActivityForResult(intent, 20);
                    }    
Run Code Online (Sandbox Code Playgroud)

.

         @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (resultCode == Activity.RESULT_OK) {

                if (requestCode == 10) {
                    Uri selectedImageUri = data.getData();
                    String selectedImagePath = getRealPathFromURI(selectedImageUri);
                } else if (requestCode == 20) {
                    Uri selectedVideoUri = data.getData();
                    String selectedVideoPath = getRealPathFromURI(selectedVideoUri);
                }
    }
}
         public String getRealPathFromURI(Uri uri) {
                if (uri == null) {
                    return null;
                }
                String[] projection = {MediaStore.Images.Media.DATA};
                Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, null);
                if (cursor != null) {
                    int column_index = cursor
                            .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                    cursor.moveToFirst();
                    return cursor.getString(column_index);
                }
                return uri.getPath();
            }
Run Code Online (Sandbox Code Playgroud)


Mar*_*k B 14

这样做是为了启动图库并允许用户选择图像:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, IMAGE_PICK);
Run Code Online (Sandbox Code Playgroud)

然后在您onActivityResult()使用中返回的图像的URI以在ImageView上设置图像.

  • 这不适用于Android 4.4设备.它将启动最近的文档屏幕. (3认同)
  • 以下是KitKat的修复:stackoverflow.com/a/26690628/860488 (2认同)

She*_*ore 11

public class EMView extends Activity {
ImageView img,img1;
int column_index;
  Intent intent=null;
// Declare our Views, so we can access them later
String logo,imagePath,Logo;
Cursor cursor;
//YOU CAN EDIT THIS TO WHATEVER YOU WANT
private static final int SELECT_PICTURE = 1;

 String selectedImagePath;
//ADDED
 String filemanagerstring;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    img= (ImageView)findViewById(R.id.gimg1);



    ((Button) findViewById(R.id.Button01))
    .setOnClickListener(new OnClickListener() {

        public void onClick(View arg0) {

            // in onCreate or any event where your want the user to
            // select a file
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent,
                    "Select Picture"), SELECT_PICTURE);


        }
    });
}

//UPDATED
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == Activity.RESULT_OK) {
        if (requestCode == SELECT_PICTURE) {
            Uri selectedImageUri = data.getData();

            //OI FILE Manager
            filemanagerstring = selectedImageUri.getPath();

            //MEDIA GALLERY
            selectedImagePath = getPath(selectedImageUri);


            img.setImageURI(selectedImageUri);

           imagePath.getBytes();
           TextView txt = (TextView)findViewById(R.id.title);
           txt.setText(imagePath.toString());


           Bitmap bm = BitmapFactory.decodeFile(imagePath);

          // img1.setImageBitmap(bm);



        }

    }

}

//UPDATED!
public String getPath(Uri uri) {
String[] projection = { MediaColumns.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
column_index = cursor
        .getColumnIndexOrThrow(MediaColumns.DATA);
cursor.moveToFirst();
 imagePath = cursor.getString(column_index);

return cursor.getString(column_index);
}

}
Run Code Online (Sandbox Code Playgroud)


Muh*_*ani 8

public class BrowsePictureActivity extends Activity {
private static final int SELECT_PICTURE = 1;

private String selectedImagePath;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ((Button) findViewById(R.id.Button01))
            .setOnClickListener(new OnClickListener() {

                public void onClick(View arg0) {

                    Intent intent = new Intent();
                    intent.setType("image/*");
                    intent.setAction(Intent.ACTION_GET_CONTENT);
                    startActivityForResult(Intent.createChooser(intent,
                            "Select Picture"), SELECT_PICTURE);
                }
            });
}

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        if (requestCode == SELECT_PICTURE) {
            Uri selectedImageUri = data.getData();
            selectedImagePath = getPath(selectedImageUri);
        }
    }
}

public String getPath(Uri uri) {

        if( uri == null ) {
            return null;
        }

        // this will only work for images selected from gallery
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = managedQuery(uri, projection, null, null, null);
        if( cursor != null ){
            int column_index = cursor
            .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        }

        return uri.getPath();
}

}
Run Code Online (Sandbox Code Playgroud)