获取从图库中选择的图像的路径(在SD卡上)

问题描述:

我只是无法获得从SD卡上的图库中选择的图像的路径,但是存储在设备上的图像没有问题.有许多类似或重复的问题,但没有一个起作用.

I simply CANNOT get the path to an image chosen from the gallery thats on the SD card, but there is no problem with images stored on the device. There are dozens of similar or duplicate questions like this, but none of them are working.

(@ Commonsware)最推荐的方法是使用 ContentResolver 并调用 openInputStream(),因此我尝试从 openInputStream()中读取字节,然后创建一个临时文件并使用该路径,没有运气.我的读取的字节数:" System.err.println 调用显示读取的0字节.

The most recommended approach (by @Commonsware) is to use a ContentResolver and call openInputStream(), so I tried reading the bytes from openInputStream() then creating a temp file and using that path, no luck. My "bytes read: " System.err.println call shows 0 bytes read.

我还尝试了此,

I also tried this, this, this, this, this, and this, none work. A lot of these answers lead to calling BitmapFactory#decodeStream(), problem is, I couldn't care less about displaying the image, I JUST NEED THE PATH!!.

请帮助!

代码:

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

    if(resultCode == Activity.RESULT_OK){

        switch(requestCode){

            case SELECT_FROM_GALLERY:
                fromGallery = true;
                path = getRealPathFromURI(data.getData());
                System.err.println("*******path: " + path + "*********");

                break;

        }

    }

}

public String getRealPathFromURI(Uri contentUri) {
    String thePath = null;
    String[] filePathColumn = {MediaStore.Images.Media.DATA};
    Cursor cursor = getContext().getContentResolver().query(contentUri, filePathColumn, null, null, null);
    if(cursor.moveToFirst()){
        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        thePath = cursor.getString(columnIndex);
    }
    cursor.close();

    if(thePath == null){
        return getImagePathExternal(contentUri);
    }else {
        return thePath;
    }
}

public String getImagePathExternal(Uri uri){
    Cursor cursor = getContext().getContentResolver().query(uri, null, null, null, null);
    cursor.moveToFirst();
    String document_id = cursor.getString(0);
    document_id = document_id.substring(document_id.lastIndexOf(":")+1);
    cursor.close();

    cursor = getContext().getContentResolver().query(
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
    cursor.moveToFirst();
    String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
    cursor.close();

    if(path == null){

        System.err.println("****************trying bytes route******************");
        try{

            InputStream in = getContext().getContentResolver().openInputStream(uri);

            byte[] resultBuff = new byte[0];
            byte[] buff = new byte[1024];
            int k ;
            while((k = in.read(buff, 0, buff.length)) > -1) {
                byte[] tbuff = new byte[resultBuff.length + k]; // temp buffer size = bytes already read + bytes last read
                System.arraycopy(resultBuff, 0, tbuff, 0, resultBuff.length); // copy previous bytes
                System.arraycopy(buff, 0, tbuff, resultBuff.length, k);  // copy current lot
                resultBuff = tbuff; // call the temp buffer as your result buff
            }

            System.err.println("****************bytes read: "+resultBuff.length+" ******************");

            File tem = new File(_tempImageDir, "temp.jpg");

            FileOutputStream out = new FileOutputStream(tem);

            out.write(resultBuff, 0, resultBuff.length);

            return tem.getAbsolutePath();

        }catch(Exception e){
            e.printStackTrace();
            return null;
        }

    }

    return path;
}

Logcat(无论我使用哪种方法,此异常都不会改变):

E/AndroidRuntime: FATAL EXCEPTION: main
                                                                  Process: com.venon.nakomangsp, PID: 20610
                                                                  java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=132074, result=-1, data=Intent { dat=content://media/external/images/media/4147 (has extras) }} to activity {com.venon.nakomangsp/com.venon.nakomangsp.SignUpActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
                                                                      at android.app.ActivityThread.deliverResults(ActivityThread.java:4058)
                                                                      at android.app.ActivityThread.handleSendResult(ActivityThread.java:4101)
                                                                      at android.app.ActivityThread.access$1400(ActivityThread.java:177)
                                                                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1497)
                                                                      at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                      at android.os.Looper.loop(Looper.java:145)
                                                                      at android.app.ActivityThread.main(ActivityThread.java:5942)
                                                                      at java.lang.reflect.Method.invoke(Native Method)
                                                                      at java.lang.reflect.Method.invoke(Method.java:372)
                                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
                                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
                                                                   Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
                                                                      at id.zelory.compressor.ImageUtil.getScaledBitmap(ImageUtil.java:62)
                                                                      at id.zelory.compressor.ImageUtil.compressImage(ImageUtil.java:161)
                                                                      at id.zelory.compressor.Compressor.compressToFile(Compressor.java:48)
                                                                      at com.venon.nakomangsp.SignUpFragment.preparePicture(SignUpFragment.java:870)
                                                                      at com.venon.nakomangsp.SignUpFragment.onActivityResult(SignUpFragment.java:783)
                                                                      at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:165)
                                                                      at com.venon.nakomangsp.SignUpActivity.onActivityResult(SignUpActivity.java:37)
                                                                      at android.app.Activity.dispatchActivityResult(Activity.java:6549)
                                                                      at android.app.ActivityThread.deliverResults(ActivityThread.java:4054)
                                                                      at android.app.ActivityThread.handleSendResult(ActivityThread.java:4101) 
                                                                      at android.app.ActivityThread.access$1400(ActivityThread.java:177) 
                                                                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1497) 
                                                                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                      at android.os.Looper.loop(Looper.java:145) 
                                                                      at android.app.ActivityThread.main(ActivityThread.java:5942) 
                                                                      at java.lang.reflect.Method.invoke(Native Method) 
                                                                      at java.lang.reflect.Method.invoke(Method.java:372) 
                                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399) 
                                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194) 

应用无法直接访问SD卡中的任何内容.因此,即使您可以获得某种路径",您的应用也无法从该位置读取任何内容.

Apps do not have direct file access to any of the contents of the SD card. Therefore even if you could get a 'path' of some sort, your app would not have the ability to read anything from that location.

可靠访问这些文件内容的唯一方法是通过 ContentResolver.openInputStream()(如果需要 AssetFileDescriptor 等,也可以使用其他 open 方法).

The only way to reliably access the contents of these files is through ContentResolver.openInputStream() (or the other open methods if you need an AssetFileDescriptor, etc).

您绝对可以将文件复制到您的自己的缓存中目录,然后对图像进行任何操作.

You can most definitely copy the file to your own cache directory and then do whatever you want with the image.