it-swarm.com.de

IllegalArgumentException: Spalte '_data' ist nicht vorhanden

In Nougat funktioniert diese Funktion nicht.

String path = getRealPathFromURI(this, getIntent().getParcelableExtra(Intent.EXTRA_STREAM));


public String getRealPathFromURI(Context context, Uri contentUri) {
    Cursor cursor = null;
    try {
        String[] proj = {MediaStore.Images.Media.DATA};
        cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
        if (cursor == null) return contentUri.getPath();
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}

Absturzprotokoll:

Java.lang.RuntimeException: Unable to start activity ComponentInfo{class path}: Java.lang.IllegalArgumentException: column '_data' does not exist
   at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2659)
   at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2724)
   at Android.app.ActivityThread.-wrap12(ActivityThread.Java)
   at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1473)
   at Android.os.Handler.dispatchMessage(Handler.Java:102)
   at Android.os.Looper.loop(Looper.Java:154)
   at Android.app.ActivityThread.main(ActivityThread.Java:6123)
   at Java.lang.reflect.Method.invoke(Method.Java)
   at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:867)
   at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:757)
Caused by Java.lang.IllegalArgumentException: column '_data' does not exist
   at Android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.Java:333)
   at Android.database.CursorWrapper.getColumnIndexOrThrow(CursorWrapper.Java:87)
   at com.package.SaveImageActivity.getRealPathFromURI()
   at com.package.SaveImageActivity.onCreate()
   at Android.app.Activity.performCreate(Activity.Java:6672)
   at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1140)
   at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2612)
   at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2724)
   at Android.app.ActivityThread.-wrap12(ActivityThread.Java)
   at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1473)
   at Android.os.Handler.dispatchMessage(Handler.Java:102)
   at Android.os.Looper.loop(Looper.Java:154)
   at Android.app.ActivityThread.main(ActivityThread.Java:6123)
   at Java.lang.reflect.Method.invoke(Method.Java)
   at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:867)
   at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:757)

Diese Funktion funktioniert einwandfrei in Geräten vor Android N. Ich habe den Artikel file: // Schema gelesen und darf jetzt nicht mit Intent auf targetSdkVersion 24 (Android Nougat) verbunden werden. Kann aber keine Lösung finden. Also bitte helfen.

17
vidha

Diese Funktion funktioniert in Geräten vor Android N einwandfrei

Es funktioniert für sehr wenige Uri-Werte, hat möglicherweise kein Ergebnis (z. B. für von MediaStore indizierte Dinge, die keine lokalen Dateien sind) und hat möglicherweise kein brauchbares Ergebnis (z. B. für Dateien auf einem Wechselspeicher).

Also bitte helfen.

Verwenden Sie eine ContentResolver und openInputStream(), um eine InputStream für den durch die Uri identifizierten Inhalt abzurufen. Verwenden Sie diesen Stream im Idealfall direkt für alles, was Sie zu tun versuchen. Oder verwenden Sie InputStream und einige FileOutputStream in einer von Ihnen kontrollierten Datei, um eine Kopie des Inhalts zu erstellen, und verwenden Sie dann diese Datei.

24
CommonsWare

Der Lösungscode laut CommonsWare lautet:

public static String getFilePathFromURI(Context context, Uri contentUri) {
    //copy file and send new file path 
    String fileName = getFileName(contentUri);
    if (!TextUtils.isEmpty(fileName)) {
        File copyFile = new File(TEMP_DIR_PATH + File.separator + fileName);
        copy(context, contentUri, copyFile);
        return copyFile.getAbsolutePath();
    }
    return null;
}

public static String getFileName(Uri uri) {
    if (uri == null) return null;
    String fileName = null;
    String path = uri.getPath();
    int cut = path.lastIndexOf('/');
    if (cut != -1) {
        fileName = path.substring(cut + 1);
    }
    return fileName;
}

public static void copy(Context context, Uri srcUri, File dstFile) {
    try {
        InputStream inputStream = context.getContentResolver().openInputStream(srcUri);
        if (inputStream == null) return;
        OutputStream outputStream = new FileOutputStream(dstFile);
        IOUtils.copyStream(inputStream, outputStream);
        inputStream.close();
        outputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Ich hoffe das hilft dir.

Der Ursprung von IOUtils.copy stammt von dieser Website: https://www.developerfeed.com/copy-bytes-inputstream-outputstream-Android/ (Möglicherweise muss die Ausnahme etwas geändert werden, sie funktioniert jedoch nach Bedarf.)

29
vidha

@Redturbo Ich kann keinen Kommentar schreiben, ich schreibe hier

IOUtils.copyStream(inputStream, outputStream);

TEMP_DIR_PATH - ein beliebiger Verzeichnispfad, etwa so

 File rootDataDir = context.getFilesDir();
 File copyFile = new File( rootDataDir + File.separator + fileName + ".jpg");
2
kalmahik

// Der folgende Code funktioniert in Android N:

private static String getFilePathForN(Uri uri, Context context) {
    Uri returnUri = uri;
    Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null);
    /*
     * Get the column indexes of the data in the Cursor,
     *     * move to the first row in the Cursor, get the data,
     *     * and display it.
     * */
    int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
    int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
    returnCursor.moveToFirst();
    String name = (returnCursor.getString(nameIndex));
    String size = (Long.toString(returnCursor.getLong(sizeIndex)));
    File file = new File(context.getFilesDir(), name);
    try {
        InputStream inputStream = context.getContentResolver().openInputStream(uri);
        FileOutputStream outputStream = new FileOutputStream(file);
        int read = 0;
        int maxBufferSize = 1 * 1024 * 1024;
        int bytesAvailable = inputStream.available();

        //int bufferSize = 1024;
        int bufferSize = Math.min(bytesAvailable, maxBufferSize);

        final byte[] buffers = new byte[bufferSize];
        while ((read = inputStream.read(buffers)) != -1) {
            outputStream.write(buffers, 0, read);
        }
        Log.e("File Size", "Size " + file.length());
        inputStream.close();
        outputStream.close();
        Log.e("File Path", "Path " + file.getPath());
        Log.e("File Size", "Size " + file.length());
    } catch (Exception e) {
        Log.e("Exception", e.getMessage());
    }
    return file.getPath();
}
0
satyawan hajare