Java 在Android中获取所选图库图像的文件路径和文件名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20324155/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 01:04:50  来源:igfitidea点击:

Get filepath and filename of selected gallery image in Android

javaandroidfilepathandroid-gallery

提问by amburnside

I am creating an app which uploads a selected image from the gallery and uploads it to a web service. The webservice requires the filename of selected image plus a base64 encoding of the file contents. I have managed to achieve this with a hardcoded file path. However, I am struggling to get the real filepath of the image. I have read around the web and have this code, but it does not work for me:

我正在创建一个应用程序,它从图库上传选定的图像并将其上传到网络服务。Web 服务需要所选图像的文件名以及文件内容的 base64 编码。我设法通过硬编码的文件路径实现了这一点。但是,我正在努力获取图像的真实文件路径。我已经在网上阅读并拥有此代码,但它对我不起作用:

 public void onActivityResult(int requestCode, int resultCode, Intent data) {
   if (resultCode == RESULT_OK) {
     Uri selectedImageUri = data.getData();
     String[] projection = {MediaStore.Images.Media.DATA};

     try {
       Cursor cursor = getContentResolver().query(selectedImageUri, projection, null, null, null);
       cursor.moveToFirst();

       int columnIndex = cursor.getColumnIndex(projection[0]);
       String picturePath = cursor.getString(columnIndex);
       cursor.close();
       Log.d("Picture Path", picturePath);
     }
     catch(Exception e) {
       Log.e("Path Error", e.toString());
     }
   }
 }

I get this error:

我收到此错误:

java.lang.NullPointerException

EDIT

编辑

Forgot to mention I am using Kitkat. It looks like my problem is KitKat related. I found this (see below) which helped me get my app working:

忘了说我在用 Kitkat。看起来我的问题与 KitKat 相关。我发现这个(见下文)帮助我让我的应用程序正常工作:

Android Gallery on KitKat returns different Uri for Intent.ACTION_GET_CONTENT

KitKat 上的 Android Gallery 为 Intent.ACTION_GET_CONTENT 返回不同的 Uri

回答by Virag Brahme

Try this:

尝试这个:

Uri selectedImageURI = data.getData();
imageFile = new File(getRealPathFromURI(selectedImageURI));

And

    private String getRealPathFromURI(Uri contentURI) {
    Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
    if (cursor == null) { // Source is Dropbox or other similar local file path
        return contentURI.getPath();
    } else { 
        cursor.moveToFirst(); 
        int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
        return cursor.getString(idx); 
    }
}

回答by Murali Ganesan

Try this,

尝试这个,

 file = new File(getPath(outputFileUri));


 public String getPath(Uri uri) {
    String[] projection = { MediaStore.Images.Media.DATA };
    @SuppressWarnings("deprecation")
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    int column_index = cursor
            .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}

回答by InnocentKiller

Use below code,

使用下面的代码,

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

    if (resultCode == RESULT_OK) {

     Uri selectedImageUri = data.getData();
     String s = getRealPathFromURI(selectedImageUri);
     editText1.setText(s);
}
}

and below is your getRealPathFromURI function,

下面是你的 getRealPathFromURI 函数,

public String getRealPathFromURI(Uri uri) {
    String[] projection = { MediaStore.Images.Media.DATA };
    @SuppressWarnings("deprecation")
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    int column_index = cursor
            .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}

回答by Naveeen Kumar

Try this to get data as well as file path and insert into folder.

试试这个来获取数据以及文件路径并插入到文件夹中。

public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    try {
        if (resultCode == RESULT_OK)
        {
            nav = data.getData();
            String[] projection = { MediaStore.Images.Media.DATA };
            Cursor cursor = managedQuery(nav, projection, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            String path= cursor.getString(column_index);
            Toast.makeText(getApplicationContext(), path, 500).show();
            mBitmap = android.provider.MediaStore.Images.Media.getBitmap(getContentResolver(), nav);
            insert(mBitmap);

            if (mBitmap != null) {  
                mBitmap.recycle();  
                mBitmap = null;  
            } 
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
private void insert(Bitmap finalBitmap) {
    File myDir=new File("/sdcard/saved_images");
    myDir.mkdirs();

    Random generator = new Random();
    int n = 10000;
    n = generator.nextInt(n);
    String fname = "Image-"+ n +".jpg";
    File file = new File (myDir, fname);
    if (file.exists ()) file.delete (); 
    try {
        FileOutputStream out = new FileOutputStream(file);
        finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
        out.flush();
        out.close();
        File dstFile = new File(file.getParent(), "." + file.getName());
        file.renameTo(dstFile);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

回答by Peter Gruppelaar

If you are like me and you dont have a local file ready, for instance you want to give user a chance to take a picture and then upload the picture this is how to do it. I am a noob in java but i have allot of experience in coding. Stackoverflow helped me allot so now it is my time to do something back.

如果你像我一样没有准备好本地文件,比如你想让用户有机会拍照然后上传图片,这就是这样做的方法。我是 Java 的菜鸟,但我在编码方面有很多经验。Stackoverflow 帮我分配了所以现在是我做点什么的时候了。

Under class activity you have to declare these two items. asuming you have a working upload class and php script.

在课堂活动下,您必须申报这两项。假设您有一个有效的上传类和 php 脚本。

NOTE i am not taking any consideration about all the different API's out there. I am using java compiler 1.7 and a API range of 10 to 18.

注意我没有考虑所有不同的 API。我正在使用 java 编译器 1.7 和 10 到 18 的 API 范围。

public class Yourproject extends Activity {
File imageFile;
File imageFileName;

//This part is needed for decoding the path adres.

 private String getRealPathFromURI(Uri contentURI) {
            String result;
            Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
            if (cursor == null) { // Source is Dropbox or other similar local file path
                result = contentURI.getPath();
            } else { 
                cursor.moveToFirst(); 
                int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME); 
                result = cursor.getString(idx);
                cursor.close();
            }
            return result;
        }

//This is needed for the path name, now you might just want to use one decoding script depending on //your class in total.
//In my case this was the way to go.
//To use one single addres use this line ImageColumns.DATA in the int idx declaration.

        private String getRealPathFromNAME(Uri contentNAME) {
            String result;
            Cursor cursor = getContentResolver().query(contentNAME, null, null, null, null);
            if (cursor == null) { // Source is Dropbox or other similar local file path
                result = contentNAME.getPath();
            } else { 
                cursor.moveToFirst(); 
                int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DISPLAY_NAME); 
                result = cursor.getString(idx);
                cursor.close();
            }
            return result;
        }

//Then under protected void onCreate(Bundle savedInstanceState) you place this code to get 
//the image and process it.
@Override
protected void onCreate(Bundle savedInstanceState) {
        //declare the ImageView
        final ImageView inputPicture = (ImageView) findViewById(R.id.imageView2);

        inputPicture.setImageURI((Uri) getIntent().getExtras().get("picture"));
        //here where recieve the image from last page "Putextra" method


        try {
            //here we will get the data and proces it trough to get the real 
            //address for uploading.
            //This is send from a other activity with a Intent.EXTRA_STREAM
            //The code looks like this:
            /*********"Putextra"*********/
            //final ImageView iv = (ImageView) findViewById(R.id.imageView1);
            //final Uri thumb = (Uri) getIntent().getExtras().get(Intent.EXTRA_STREAM);
            //iv.setImageURI(thumb);

            //Sending it to the next activity

            //it.putExtra("picture", thumb);    
            /*********"Putextra"*********/

            Uri fileUri = (Uri) getIntent().getExtras().get("picture");
            //get 
            //Uri fileName = (Uri) getIntent().getExtras().get("picture");
            //get
            imageFile = new File(getRealPathFromURI(fileUri));
            //send
            imageFileName = new File(getRealPathFromNAME(fileUri));
            //send
            //i got a exeption Uri fileName, use fileUri twice..
        } catch (Exception e2) {
            // TODO Auto-generated catch block
            e2.printStackTrace();
        }
        //here we will declare the name for furter processing.
        final File uploadFilePath = imageFile;
        final File uploadFileName = imageFileName;


}

And the rest i will leave up to u, if you got this far, I am pretty sure you will finish.

剩下的我会留给你,如果你走到这一步,我很确定你会完成。

回答by Matthew Carpenter

A little late to the party but here's my code, hope this helps.

聚会有点晚了,但这是我的代码,希望这会有所帮助。

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        Uri selectedImageUri = data.getData( );
        String picturePath = getPath( getActivity( ).getApplicationContext( ), selectedImageUri );
        Log.d("Picture Path", picturePath);
    }
}

public static String getPath( Context context, Uri uri ) {
    String result = null;
    String[] proj = { MediaStore.Images.Media.DATA };
    Cursor cursor = context.getContentResolver( ).query( uri, proj, null, null, null );
    if(cursor != null){
        if ( cursor.moveToFirst( ) ) {
            int column_index = cursor.getColumnIndexOrThrow( proj[0] );
            result = cursor.getString( column_index );
        }
        cursor.close( );
    }
    if(result == null) {
        result = "Not found";
    }
    return result;
}

回答by saeed

Hope this helps you

希望这对你有帮助

 if (Build.VERSION.SDK_INT <19){

    Intent intent = new Intent(); 
    intent.setType("image/jpeg");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, 
    getResources().getString(R.string.select_picture)),GALLERY_INTENT_CALLED);

 }else{

      Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
      intent.addCategory(Intent.CATEGORY_OPENABLE);
      intent.setType("image/jpeg");
      startActivityForResult(intent, GALLERY_KITKAT_INTENT_CALLED);
 }

 @Override
 public void onActivityResult(int requestCode, int resultCode, Intent data)
 {

      super.onActivityResult(requestCode, resultCode, data);
      if (resultCode != Activity.RESULT_OK) return;
      if (null == data) return;
      Uri originalUri = null;

      if (requestCode == GALLERY_INTENT_CALLED) {
           originalUri = data.getData();
      } 
      else if (requestCode == GALLERY_KITKAT_INTENT_CALLED) {
           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);
      }
      loadSomeStreamAsynkTask(originalUri);
}

回答by Arpit Patel

Add this class in your project

在你的项目中添加这个类

ImageFilePath.java

图像文件路径

import android.annotation.SuppressLint;
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;

//import android.provider.<span id="IL_AD11" class="IL_AD">MediaStore</span>;

@SuppressLint("NewApi")
@TargetApi(Build.VERSION_CODES.KITKAT)
public class ImageFilePath {

    /**
     * Method for return file path of Gallery image
     *
     * @param context
     * @param uri
     * @return path of the selected image file from gallery
     */
    static String nopath = "Select Video Only";

    @TargetApi(Build.VERSION_CODES.KITKAT)
    @SuppressLint("NewApi")
    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 nopath;
    }

    /**
     * Get the value of the data column for this Uri. This is <span id="IL_AD2"
     * class="IL_AD">useful</span> 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 nopath;
    }

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

In your onActivityResult

在你的onActivityResult

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

        if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {

            Uri uri = data.getData();


            realPath = ImageFilePath.getPath(SignupActivity.this, data.getData());
//                realPath = RealPathUtil.getRealPathFromURI_API19(this, data.getData());

            Log.i(TAG, "onActivityResult: file path : " + realPath);
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
                // Log.d(TAG, String.valueOf(bitmap));

                ImageView imageView = (ImageView) findViewById(R.id.img_profile);
                imageView.setImageBitmap(bitmap);
                imageView.setVisibility(View.VISIBLE);

            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            Toast.makeText(this, "Something Went Wrong", Toast.LENGTH_SHORT).show();
        }

    }

回答by manas.abrol

public class RealFilePath {
    /**
     * Get a file path from a Uri. This will get the the path for Storage Access
     * Framework Documents, as well as the _data field for the MediaStore and
     * other file-based ContentProviders.
     *
     * @param context The context.
     * @param uri     The Uri to query
     */
    public static String getPath(final Context context, final Uri uri) {

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

                // TODO handle non-primary volumes
            }
            // 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());
    }
}