简体   繁体   English

从gallery kitkat android中选择图像时检索绝对路径

[英]retrieve absolute path when select image from gallery kitkat android

As I am supporting my app to Kitkat version, now in this the way of retrieve file from gallery was different. 由于我支持我的应用程序到Kitkat版本,现在在这里从库中检索文件的方式是不同的。

I have preferred this Android Gallery on KitKat returns different Uri for Intent.ACTION_GET_CONTENT for retrieving file from gallery and successfully work but I required Absolute path of that file, I am getting 我更喜欢KitKat上的这个Android Gallery为Intent.ACTION_GET_CONTENT返回不同的Uri,用于从库中检索文件并成功工作但是我需要该文件的绝对路径,我得到了

content://com.android.providers.media.documents/document/image:2505

For 19 below version we used uri different by using that I am getting path this way 对于19以下版本我们使用uri不同使用我这样得到路径

Cursor cursor = this.getContentResolver().query(originalUri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String fpath = cursor.getString(column_index);

but in 19 version it will give me null value how to get absolute path of image file which was selected by user. 但是在19版本中它会给我null值如何获得用户选择的图像文件的绝对路径。

Thanks 谢谢

Here is one way to access the Absolute path after selecting file. 这是选择文件后访问绝对路径的一种方法。

After getting data in new URI format for KK(KitKat) like this way 以这种方式获取KK(KitKat)的新URI格式的数据之后

content://com.android.providers.media.documents/document/image:2505

Just extract ID of your document 只需提取文档的ID即可

if(requestCode == GALLERY_KITKAT_INTENT_CALLED && resultCode == RESULT_OK){

    Uri originalUri = data.getData();

    final int takeFlags = data.getFlags()
                        & (Intent.FLAG_GRANT_READ_URI_PERMISSION
                        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    // Check for the freshest data.
    getContentResolver().takePersistableUriPermission(originalUri, takeFlags);

    /* now extract ID from Uri path using getLastPathSegment() and then split with ":"
    then call get Uri to for Internal storage or External storage for media I have used getUri()
    */

    String id = originalUri.getLastPathSegment().split(":")[1]; 
    final String[] imageColumns = {MediaStore.Images.Media.DATA };
    final String imageOrderBy = null;

    Uri uri = getUri();
    String selectedImagePath = "path";

    Cursor imageCursor = managedQuery(uri, imageColumns,
          MediaStore.Images.Media._ID + "="+id, null, imageOrderBy);

    if (imageCursor.moveToFirst()) {
        selectedImagePath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
    }
    Log.e("path",selectedImagePath ); // use selectedImagePath 
}else if() {
      // for older version use existing code here
}

// By using this method get the Uri of Internal/External Storage for Media
private Uri getUri() {
    String state = Environment.getExternalStorageState();
    if(!state.equalsIgnoreCase(Environment.MEDIA_MOUNTED))
        return MediaStore.Images.Media.INTERNAL_CONTENT_URI;

    return MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}

Pratik's solution helped me alot. Pratik的解决方案帮助了我很多。 Following is the version which works for me in Kitkat 4.4.2. 以下是适用于Kitkat 4.4.2的版本。 Three things which i changed are 我改变的三件事是
1) Using content resolver to get the path 1)使用内容解析器获取路径
2) originalUri.getLastPathSegment().split(":")[1] gives me index out of bound so i'm using index 0 instead.Its been working so far 2)originalUri.getLastPathSegment()。split(“:”)[1]给我索引越界,所以我用的是索引0。到目前为止一直在工作
3) Removed takeflags and check for freshest data as we are filtering the cursor with id. 3)删除了takeflags并检查最新的数据,因为我们正在使用id过滤光标。

try {
        Uri originalUri = data.getData();
        String pathsegment[] = originalUri.getLastPathSegment().split(":");
        String id = pathsegment[0];
        final String[] imageColumns = { MediaStore.Images.Media.DATA };
        final String imageOrderBy = null;

        Uri uri = getUri();
        Cursor imageCursor = activity.getContentResolver().query(uri, imageColumns,
                                MediaStore.Images.Media._ID + "=" + id, null, null);

        if (imageCursor.moveToFirst()) {
            value = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
        }

    } catch (Exception e) {
        Toast.makeText(activity, "Failed to get image", Toast.LENGTH_LONG).show();
    }
Bitmap bitmap = MediaStore.Images.Media
.getBitmap(getActivity().getContentResolver(), uri);

I hope that this will help you. 我希望这会对你有所帮助。

Perfectly working solution: 完美的解决方案:

package utils;

/**
 * Created by layer on 4/21/2015.
 */
import android.annotation.TargetApi;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

public class ImageFilePath {

    /**
     * Method for return file path of Gallery image
     *
     * @param context
     * @param uri
     * @return path of the selected image file from gallery
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public static String getPath(final Context context, final Uri uri) {

        // check here to KITKAT or new version
        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {

            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/"
                            + split[1];
                }
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"),
                        Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[] { split[1] };

                return getDataColumn(context, contentUri, selection,
                        selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context
     *            The context.
     * @param uri
     *            The Uri to query.
     * @param selection
     *            (Optional) Filter used in the query.
     * @param selectionArgs
     *            (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     */
    public static String getDataColumn(Context context, Uri uri,
                                       String selection, String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = { column };

        try {
            cursor = context.getContentResolver().query(uri, projection,
                    selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        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());
    }

    /**
     * @param uri
     *            The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri
                .getAuthority());
    }
}

https://github.com/layerlre/Android-Utility-Class/blob/master/utils/ImageFilePath.java https://github.com/layerlre/Android-Utility-Class/blob/master/utils/ImageFilePath.java

Hope works for you. 希望对你有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM