如何从画廊(SD卡)为我的应用程序选择一个图像?

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

我正在我的应用程序中的照片选项。

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

279338 次浏览

你必须为一个结果开始画廊意图。

Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, ACTIVITY_SELECT_IMAGE);

然后在onActivityForResult中调用intent.getData()来获取图像的Uri。然后你需要从ContentProvider中获取图像。

这样做可以启动图库,并允许用户选择一张图片:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, IMAGE_PICK);

然后在onActivityResult()中使用返回的图像的URI来设置ImageView上的图像。

近5年后的最新答案:

原始答案中的代码不再可靠地工作,因为来自不同来源的图像有时返回的内容URI不同,即content://而不是file://。更好的解决方案是简单地使用context.getContentResolver().openInputStream(intent.getData()),因为它将返回一个你可以选择处理的InputStream。

例如,BitmapFactory.decodeStream()在这种情况下工作得很好,因为你也可以使用Options和inSampleSize字段来减少大图像的采样,避免内存问题。

但是,像谷歌Drive之类的东西会返回尚未实际下载的图像的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);
}
}
}

在此之后,您已经将选中的图像存储在“yourSelectedImage”中,可以做任何您想做的事情。这段代码通过在ContentResolver数据库中获取图像的位置来工作,但这本身是不够的。每张图片大约有18列信息,从文件路径到“最后修改日期”,再到照片拍摄地点的GPS坐标,不过很多字段实际上并没有被使用。

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

private static final int SELECT_PHOTO = 100;

开始的目的

Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);

过程的结果

@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);
}
}
}

或者,你也可以降低你的图像样本,以避免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);


}
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);
}


}
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();
}


}
#initialize in main activity
path = Environment.getExternalStorageDirectory()
+ "/images/make_machine_example.jpg"; #
ImageView image=(ImageView)findViewById(R.id.image);
//--------------------------------------------------||


public void FromCamera(View) {


Log.i("camera", "startCameraActivity()");
File file = new File(path);
Uri outputFileUri = Uri.fromFile(file);
Intent intent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 1);


}


public void FromCard() {
Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, 2);
}


protected void onActivityResult(int requestCode, int resultCode, Intent data) {


super.onActivityResult(requestCode, resultCode, data);


if (requestCode == 2 && resultCode == RESULT_OK
&& null != data) {


Uri selectedImage = data.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 picturePath = cursor.getString(columnIndex);
cursor.close();


bitmap = BitmapFactory.decodeFile(picturePath);
image.setImageBitmap(bitmap);


if (bitmap != null) {
ImageView rotate = (ImageView) findViewById(R.id.rotate);


}


} else {


Log.i("SonaSys", "resultCode: " + resultCode);
switch (resultCode) {
case 0:
Log.i("SonaSys", "User cancelled");
break;
case -1:
onPhotoTaken();
break;


}


}


}


protected void onPhotoTaken() {
// Log message
Log.i("SonaSys", "onPhotoTaken");
taken = true;
imgCapFlag = true;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
bitmap = BitmapFactory.decodeFile(path, options);
image.setImageBitmap(bitmap);




}

像-一样调用chooseImage方法

public void chooseImage(ImageView v)
{
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, SELECT_PHOTO);
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);


if(imageReturnedIntent != null)
{
Uri selectedImage = imageReturnedIntent.getData();
switch(requestCode) {
case SELECT_PHOTO:
if(resultCode == RESULT_OK)
{
Bitmap datifoto = null;
temp.setImageBitmap(null);
Uri picUri = null;
picUri = imageReturnedIntent.getData();//<- get Uri here from data intent
if(picUri !=null){
try {
datifoto = android.provider.MediaStore.Images.Media.getBitmap(this.getContentResolver(),                                 picUri);
temp.setImageBitmap(datifoto);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (OutOfMemoryError e) {
Toast.makeText(getBaseContext(), "Image is too large. choose other", Toast.LENGTH_LONG).show();
}


}
}
break;


}
}
else
{
//Toast.makeText(getBaseContext(), "data null", Toast.LENGTH_SHORT).show();
}
}

由于某些原因,这个线程中的所有答案,在onActivityResult()中尝试对接收到的Uri进行后处理,例如获取图像的真实路径,然后使用BitmapFactory.decodeFile(path)获取Bitmap

此步骤无需执行。ImageView类有一个名为setImageURI(uri)的方法。将您的uri传递给它,您就应该完成了。

Uri imageUri = data.getData();
imageView.setImageURI(imageUri);

完整的工作示例可以在这里查看:http://androidbitmaps.blogspot.com/2015/04/loading-images-in-android-part-iii-pick.html

PS: < p > < br > 在要加载的图像太大而无法装入内存的情况下,在一个单独的变量中获取Bitmap是有意义的,并且需要一个缩小操作来防止OurOfMemoryError,如@siamii答案所示

这是一个图像和视频的测试代码。它也适用于所有小于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);
}

视频:

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);
}

     @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();
}