繁体   English   中英

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

[英]Get path to image chosen from gallery(on SD card)

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

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

我也试过这个这个这个这个这个这个 ,没有工作。 许多这样的答案导致调用BitmapFactory#decodeStream() ,问题是,我不太关心显示图像,我只需要路径!!

请帮忙!

到目前为止的代码:

 @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卡中的任何内容。 因此,即使您可以获得某种“路径”,您的应用程序也无法从该位置读取任何内容。

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

您绝对可以将文件复制到自己的缓存目录 ,然后对映像执行任何操作。

如果您使用的是API 24,则应该使用FileProvide(简介的官方网站):https://developer.android.com/reference/android/support/v4/content/FileProvider.html您应该这样编写:

  1. 使用元素的子元素指定XML存储区域和路径的内容。 例如,以下pathmann告诉FileProvider您打算为私有文件区域的images /子目录请求内容URI。

     <Manifest>    <Application>        <Provider            Android: name = "android.support.v4.content.FileProvider"            Android: authorities = "com.mydomain.fileprovider"            Android: exported = "false"            Android: grantUriPermissions = "true"           <Meta-data           Android: name = "android.support.FILE_PROVIDER_PATHS"           Android: resource = "@ xml / file_paths" />        </ Provider>    </ Application> </ Manifest> <? Xml version = "1.0" encoding = "utf-8"?> <Resources>    <Paths>        <External-path            Name = "external_files"            Path = "." />        <Root-path            Name = "external_files"            Path = "/ storage /" />    </ Paths> `enter code here` </ Resources> 
  2. 第三步:文件就是你的路径

     Uri contentUri = getUriForFile (getContext (), getPackageName () + ".provider", file); 

不同的手机具有一些不同的行为。 经过大量研究并尝试了不同的可能性,我提出了一个解决方案,该解决方案可在我测试过的所有手机上使用(LG G2,Nexus 5,ZTE,Note 5,Nexus 6,Infinix Note 3 Pro以及其他一些我不记得了) 如果可行,请尝试此操作。 根据您的需要服用。 它还包括从相机捕获图片,将其复制并获取其路径。

//SELECT PICTURE FROM GALLERY OR CAPTURE FROM CAMERA
private void selectPicture(View view) {
    tempView = view;
    final CharSequence[] items;
    if(view.getClass().getName().equalsIgnoreCase("android.widget.ImageView"))
            items = new CharSequence[]{ "Take Photo", "Choose from Library", "Remove Photo", "Cancel" };
    else items = new CharSequence[]{ "Take Photo", "Choose from Library", "Cancel" };

    AlertDialog.Builder builder = new AlertDialog.Builder(ActivityAddMemory.this);
    builder.setTitle("Add Image");
    builder.setItems(items, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int item) {
            if (items[item].equals("Take Photo")) {
                showCamera();
            } else if (items[item].equals("Choose from Library")) {
                Intent intent = new Intent(
                        Intent.ACTION_PICK,
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                intent.setType("image/*");
                startActivityForResult(
                        Intent.createChooser(intent, "Select File"),
                        SELECT_FILE);
            } else if(items[item].equals("Remove Photo")) {
                imgLinearLayout.removeView(tempView);
                imagesList.remove(tempView.getId());
                if(imagesList.size() < 1) {
                    imgLinearLayout.setVisibility(View.GONE);
                }

                if(btnAddPhoto.getVisibility() == View.GONE)
                    btnAddPhoto.setVisibility(View.VISIBLE);
            } else if (items[item].equals("Cancel")) {
                dialog.dismiss();
            }
        }
    });
    builder.show();
}


//OPEN CAMERA IF WANT TO CAPTURE
private void showCamera() {

    try {
        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "DCIM");
        if (!file.exists()) {
            file.mkdirs();
        }

        File localFile2 = new File(file + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
        imageUri = Uri.fromFile(localFile2);

        Intent cameraIntent = new Intent("android.media.action.IMAGE_CAPTURE");

        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            cameraIntent.setClipData(ClipData.newRawUri(null, Uri.fromFile(localFile2)));
        }

        startActivityForResult(cameraIntent, REQUEST_CAMERA);
    } catch (Exception localException) {
        Toast.makeText(ActivityAddMemory.this, "Exception:" + localException, Toast.LENGTH_SHORT).show();
    }
}


//GET PATH FROM URI IF SELECTED FROM GALLERY
public String getRealPathFromURI(Uri uri){
    String filePath = "";
    String[] filePahColumn = {MediaStore.Images.Media.DATA};
    Cursor cursor = getContentResolver().query(uri, filePahColumn, null, null, null);
    if (cursor != null) {
        if(cursor.moveToFirst()){
            int columnIndex = cursor.getColumnIndex(filePahColumn[0]);
            filePath = cursor.getString(columnIndex);
        }
        cursor.close();
    }
    return filePath;
}


//DO WHAT YOU WANT WHEN RESULT IS RETURNED
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);

    if(resultCode == RESULT_OK) {

        String path=null;
        Uri uri;

        if (intent == null || intent.getData() == null)
            uri = this.imageUri;
        else
            uri = intent.getData();

        if(requestCode == SELECT_FILE) {
            path = getRealPathFromURI(uri);
        } else if(requestCode == REQUEST_CAMERA){
            path = uri.getEncodedPath();
        }

        //THIS IS THE PATH YOU WOULD NEED

    }

}

暂无
暂无

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

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