Не удалось прочитать строку 0, col -1 из окна курсора при запросе из uri в Android


Я знаю, что есть много подобных вопросов, и я прочитал большинство из них, и они относятся к чему-то другому. У меня есть эта ошибка:

 java.lang.RuntimeException: Failure delivering result ResultInfo{who=android:fragment:1, request=2, result=-1, data=Intent { dat=content://com.google.android.gallery3d.provider/picasa/item/5953655552200168930 flg=0x1 }} to activity {std.app/std.app.activity.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.
Проблема в том, что он работает на некоторых устройствах, а на некоторых нет. Например, он работает на SGS2, но не на Nexus 7. Другие журналы:
 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:434)
    at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
    at android.database.CursorWrapper.getString(CursorWrapper.java:114)
    at std.app.util.PhotoUtils.getRealPathFromURI(PhotoUtils.java:124)
    at std.app.fragments.DayFragment.onActivityResult(DayFragment.java:167)
    at android.app.Activity.dispatchActivityResult(Activity.java:5427)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:3347)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:3394)
    at android.app.ActivityThread.access$1300(ActivityThread.java:135)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5001)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
    at dalvik.system.NativeStart.main(Native Method)

И вот код, который делает ошибку:

    public static String getRealPathFromURI(Context context, Uri contentURI) {
    String result;
    Cursor cursor = context.getContentResolver().query(contentURI, null, null, null, null);
    if (cursor == null) {
        result = contentURI.getPath();
    } else {
        cursor.moveToFirst();
        int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
        result = cursor.getString(idx); // this line
        cursor.close();
    }
    return result;
}

Отличается ли MediaStore.Images.ImageColumns.DATA в разных версиях? Как это исправить?

Править : Я заметил, что это не проблема версии, но проблема источника. Эта ошибка появляется только тогда, когда я выбираю картинку из папок Picassa.

1 2

1 ответ:

Это потому, что облачные синхронизированные фотографии (папка Picassa) не имеют физического адреса на SD-карте или во внутренней памяти, это не физический файл на устройстве. Столбец MediaStore.Images.ImageColumns.DATA предназначен для физических файлов на устройстве.

Способ "захватить" это изображение-открыть поток и скопировать изображение в папку, которой вы управляете (временную папку в вашем приложении, возможно, из Метода Context.getCacheDir()).

     InputStream is = context.getContentResolver().openInputStream(uri);
     OutputStream os = new BufferedOutputStream(new FileOutputStream(tempFile));

А затем приступили к копированию с входа на выход и закрыли потоки по адресу конец. Помните, что этот процесс является сетевой операцией, то есть вы никогда не должны делать это из потока пользовательского интерфейса.

Если вы используете библиотеку изображений, такую как Picasso (которую вы всегда должны использовать), вы можете просто позволить ей делать ВСЮ работу за вас и просто передать Uri непосредственно ему, как это Picasso.with(context).load(uri).into(target); эта цель может быть либо ImageView, либо любым объектом, который implements Target