简体   繁体   中英

android app crashes after picking a image from gallery - cursor.getColumnIndex returns -1

I am trying to get the absolute path to the images in the gallery or camera.

After the camera intent opens up, I click on a image & am trying to fetch the file path from URI. Please see the code bit.

//In the OnActivityResult:

Uri uri = data.getData();
File myFile = new File(uri.getPath());
File imageFilePath = new File(getRealPathFromURI(uri));

//The method to fetch path:

private String getRealPathFromURI(Uri contentURI) {
    String result;
    Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
    Log.d("", "cursor = " +cursor);
    if (cursor == null) { // Source is Dropbox or other similar local file path
        result = contentURI.getPath();

    } else {
        int idx = cursor.getColumnIndex(MediaStore.Images.Media.DATA ); // Is this the wrong way to get the image cursor?
        Log.d("", "came here = " +idx); // Here idx us -1!!!
        cursor.moveToFirst();
        result = cursor.getString(idx);
        cursor.close();
    }
    return result;
}

// image pick intent

public void imageFromGallery() {
    Intent intent = new Intent();
// Show only images, no videos or anything else
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
// Always show the chooser (if there are multiple options available)
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);


}

Adding the logCat:

 721-4721/com.coolhydro.copy E/CursorWindow﹕ Failed to read row 0, column -1    from a CursorWindow which has 1 rows, 6 columns.
10-11 18:53:55.495    4721-4721/com.coolhydro.copy D/AndroidRuntime﹕ Shutting down VM
10-11 18:53:55.495    4721-4721/com.coolhydro.copy E/AndroidRuntime﹕ FATAL  EXCEPTION: main
    Process: com.coolhydro.copy, PID: 4721    
    java.lang.RuntimeException: Failure delivering result    ResultInfo{who=null, request=1, result=-1, data=Intent {     dat=content://com.android.providers.media.documents/document/image:49 flg=0x1 }}    to activity {com.coolhydro.copy/com.coolhydro.copy.MainActivity}:    java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.      Make sure the Cursor is initialized correctly before accessing data from it.
            at    android.app.ActivityThread.deliverResults(ActivityThread.java:3699)
            at     android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
            at android.app.ActivityThread.-wrap16(ActivityThread.java)   
        at    android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
            at android.os.Handler.dispatchMessage(Handler.java:102)  
            at android.os.Looper.loop(Looper.java:148) 
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            at java.lang.reflect.Method.invoke(Native Method)
            at   com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
     Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1   from CursorWindow.  Make sure the Cursor is initialized correctly before    accessing data from it.
            at android.database.CursorWindow.nativeGetString(Native Method)
            at  android.database.CursorWindow.getString(CursorWindow.java:438)
            at   android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51    )
            at  android.database.CursorWrapper.getString(CursorWrapper.java:137)
            at com.coolhydro.copy.MainActivity.getRealPathFromURI(MainActivity.java:80)
            at com.coolhydro.copy.MainActivity.onActivityResult(MainActivity.java:52)
            at android.app.Activity.dispatchActivityResult(Activity.java:6428)
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3695)
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
            at android.app.ActivityThread.-wrap16(ActivityThread.java)
            at    android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            at java.lang.reflect.Method.invoke(Native Method)
            at   com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
10-11 18:54:01.237    4721-4730/com.coolhydro.copy W/CursorWrapperInner﹕   Cursor finalized without prior close()
10-11 18:58:55.523    4721-4721/? I/Process﹕ Sending signal. PID: 4721 SIG: 9

Thanks!

You need to pass a projection into your query call. As is, you return a cursor with no columns, and so when you try to find the index of a certain column you return -1. Try using

String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(contentURI, projection, null, null, null);

Then when you want to retrieve data, you already know the column index (it's the index of that column in the projection array) so you can just set

int idx = 0;

I have this code when i request images from both gallery and camera:

     Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        pickIntent.setType("image/*");



        Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(fileCameraCapturedImage));

        String pickTitle = "Select or take a new Picture"; // Or get from strings.xml
        Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
        chooserIntent.putExtra
                (
                        Intent.EXTRA_INITIAL_INTENTS,
                        new Intent[]{captureIntent}
                );


        startActivityForResult(chooserIntent, REQUEST_CODE_ADD_PHOTO);

and on my onActivityResult() i check of the returned data came from gallery or camera then i use it:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(resultCode == RESULT_OK){
            if(requestCode == REQUEST_CODE_ADD_PHOTO) {
                Log.v(TAG, "Photo ok! " + data);
                boolean isCamera;


                //getclip data requires API 16
                if (Build.VERSION.SDK_INT >= 16){

                    if (data == null || (data.getData() == null && data.getClipData() == null)) {
                        isCamera = true;
                    } else {
                        final String action = data.getAction();
                        if (action == null) {
                            isCamera = false;
                        } else {
                            isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                        }
                    }
                }
                else{
                    if (data == null || data.getData() == null) {
                        isCamera = true;
                    } else {
                        final String action = data.getAction();
                        if (action == null) {
                            isCamera = false;
                        } else {
                            isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                        }
                    }
                }

                Log.v(TAG, "is camera: " + isCamera);
                if(!isCamera) {
                    //gallery result

                    Uri selectedImageUri = data.getData();
                    String[] filePathColumn = {MediaStore.Images.Media.DATA};

                    Cursor cursor = getContentResolver().query(selectedImageUri, filePathColumn, null, null, null);
                    cursor.moveToFirst();

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


                    Log.v(TAG,"Path: "+filePath);
                    if(filePath !=null) {
                        if(!filePath.equalsIgnoreCase("")) {
                            imagePath = filePath;
                            Picasso.with(getApplicationContext()).load("file://" + imagePath).into(ivPhotoContainer);
                            btnAddChange.setText("Change");
                        }
                    }
                }
                else {
                    //is camera result
                    Log.v(TAG, "is camera result");

                    String path = fileCameraCapturedImage.getAbsolutePath();

                    imagePath = path;
//                    ivPhotoContainer.setImageBitmap(thumbnail);
                    Picasso.with(getApplicationContext()).load("file://"+imagePath).into(ivPhotoContainer);
                    btnAddChange.setText("Change");




                }
            }
        }
    }

Note: fileCameraCapturedImage is of type file which references the file where the captured image will be saved on the device. private File fileCameraCapturedImage = new File(Environment.getExternalStorageDirectory()+File.separator+"capturedImage.jpg");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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