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

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

我的Activity中有一个按钮和一个ImageView。当我点击按钮,它会重定向到图库,我将能够选择一个图像。所选的图像将出现在我的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坐标,不过很多字段实际上并没有被使用。

To save time as you don't actually need the other fields, cursor search is done with a filter. The filter works by specifying the name of the column you want, MediaStore.Images.Media.DATA, which is the path, and then giving that string[] to the cursor query. The cursor query returns with the path, but you don't know which column it's in until you use the columnIndex code. That simply gets the number of the column based on its name, the same one used in the filtering process. Once you've got that, you're finally able to decode the image into a bitmap with the last line of code I gave.

其他回答

近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坐标,不过很多字段实际上并没有被使用。

To save time as you don't actually need the other fields, cursor search is done with a filter. The filter works by specifying the name of the column you want, MediaStore.Images.Media.DATA, which is the path, and then giving that string[] to the cursor query. The cursor query returns with the path, but you don't know which column it's in until you use the columnIndex code. That simply gets the number of the column based on its name, the same one used in the filtering process. Once you've got that, you're finally able to decode the image into a bitmap with the last line of code I gave.

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

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

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

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

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中获取图像。

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


}

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