在Android中获取选定的图像文件位置

时间:2010-07-31 02:51:50

标签: android image file-io gallery

我目前正在制作适用于图片的应用。我需要实现用户选择存储在SD卡上的文件的功能。一旦他们选择图片(使用Android图库),图像的文件位置将被发送到另一个活动,其中将完成其他工作。

我在SO上看过类似的帖子,但没有人特别回答我的问题。基本上这是我在用户点击“加载图片”按钮时所做的代码:

// Create a new Intent to open the picture selector:
Intent loadPicture = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

// To start it, run the startActivityForResult() method:
startActivityForResult(loadPicture, SELECT_IMAGE);

从那段代码开始,我有一个onActivityResult()方法来收听回叫:

// If the user tried to select an image:
if(requestCode == SELECT_IMAGE)
{
    // Check if the user actually selected an image:
    if(resultCode == Activity.RESULT_OK)
    {
        // This gets the URI of the image the user selected:
        Uri selectedImage = data.getData();

        // Create a new Intent to send to the next Activity:
        Intent i = new Intent(currentActivty.this, nextActivity.class);

        // ----------------- Problem Area -----------------
        // I would like to send the filename to the Intent object, and send it over.
        // However, the selectedImage.toString() method will return a
        // "content://" string instead of a file location.  How do I get a file
        // location from that URI object?
        i.putExtra("PICTURE_LOCATION", selectedImage.toString());

        // Start the activity outlined with the Intent above:
        startActivity(i);

如上面的代码所述,uri.toString()将返回content://字符串,而不是所选图片的文件位置。如何获取文件位置?

注意:另一种可能的解决方案是通过content://字符串发送并将其转换为Bitmap(这是下一个活动中发生的情况)。但是,我不知道该怎么做。

2 个答案:

答案 0 :(得分:2)

我找到了自己问题的答案。在做了一些搜索后,我终于偶然发现了SO上的一篇帖子,在这里提出了同样的问题:android get real path by Uri.getPath()

不幸的是,答案的链接断了。在Google搜索之后,我在此处找到了指向该网站的正确链接:http://www.androidsnippets.org/snippets/130/(我已经确认此代码确实有效。)

然而,我决定采取不同的路线。由于我的下一个Activity使用ImageView来显示图片,因此我将使用Uri内容字符串来链接到下一个Activity的所有方法。

在下一个Activity中,我使用的是ImageView.setImageUri()方法。

以下是我在下一个Activity中执行的代码,用于显示content://字符串中的图片:

// Get the content string from the previous Activity:
picLocation = getIntent().getStringExtra("PICTURE_LOCATION");

// Instantiate the ImageView object:
ImageView imageViewer = (ImageView)findViewById(R.id.ImageViewer);

// Convert the Uri string into a usable Uri:
Uri temp = Uri.parse(picLocation);
imageViewer.setImageURI(temp);

我希望这个问题和答案对未来的Android开发者有所帮助。

答案 1 :(得分:2)

这是我希望有人发现有用的另一个答案:

您可以对MediaStore中的任何内容执行此操作。在我的应用程序中,我必须从URI获取路径并从路径获取URI。前者:

/**
 * Gets the corresponding path to a file from the given content:// URI
 * @param selectedVideoUri The content:// URI to find the file path from
 * @param contentResolver The content resolver to use to perform the query.
 * @return the file path as a string
 */
private String getFilePathFromContentUri(Uri selectedVideoUri,
        ContentResolver contentResolver) {
    String filePath;
    String[] filePathColumn = {MediaColumns.DATA};

    Cursor cursor = contentResolver.query(selectedVideoUri, filePathColumn, null, null, null);
    cursor.moveToFirst();

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

后者(我为视频做的,但也可以通过将MediaStore.Audio(等)替换为MediaStore.Video来用于音频或文件或其他类型的存储内容:

/**
 * Gets the MediaStore video ID of a given file on external storage
 * @param filePath The path (on external storage) of the file to resolve the ID of
 * @param contentResolver The content resolver to use to perform the query.
 * @return the video ID as a long
 */
private long getVideoIdFromFilePath(String filePath,
        ContentResolver contentResolver) {


    long videoId;
    Log.d(TAG,"Loading file " + filePath);

            // This returns us content://media/external/videos/media (or something like that)
            // I pass in "external" because that's the MediaStore's name for the external
            // storage on my device (the other possibility is "internal")
    Uri videosUri = MediaStore.Video.Media.getContentUri("external");

    Log.d(TAG,"videosUri = " + videosUri.toString());

    String[] projection = {MediaStore.Video.VideoColumns._ID};

    // TODO This will break if we have no matching item in the MediaStore.
    Cursor cursor = contentResolver.query(videosUri, projection, MediaStore.Video.VideoColumns.DATA + " LIKE ?", new String[] { filePath }, null);
    cursor.moveToFirst();

    int columnIndex = cursor.getColumnIndex(projection[0]);
    videoId = cursor.getLong(columnIndex);

    Log.d(TAG,"Video ID is " + videoId);
    cursor.close();
    return videoId;
}

基本上,DATA的{​​{1}}列(或您要查询的任何子部分)都会存储文件路径,因此您可以使用所了解的内容来查找数据,或者您在MediaStore字段上查询以选择您关注的内容。