Android content URI Datei einlesen

Lucaaa

Bekanntes Mitglied
Hallo!
Ich möchte eine content URI einlesen, und das Bild in diesem Fall, an einen anderen Ort kopieren. Aber: wie bekomme ich den Pfad und Dateinamen?
Ich habe folgendes:
Java:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    // check if photo was selected
    if(resultCode == RESULT_OK) {
       // if it was photo loading intent
        if(requestCode==0) {  // if intent is from imageview
            Uri imgUri = data.getData();
...
Das ist die URI die ich einlesen will:

Java:
public Uri saveCover(Context context, Uri uri) {
    String oPath = Environment.getExternalStorageDirectory()+"/test/data/";
    new File(oPath).mkdirs();
   File iF = contentUriToFile(context, uri);
    File oF = new File(oPath+iF.getName());


     try {
        oF.createNewFile();
        InputStream fis =new FileInputStream(iF);
        FileOutputStream fos =new FileOutputStream(oF);
        byte[] buffer =new byte[1024];
        int length;
        while ((length=fis.read(buffer)) >0) {
            fos.write(buffer);
        }
        fis.close();
        fos.close();
        return Uri.fromFile(oF);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}







public File contentUriToFile(Context context, Uri uri) {
    String filePath = null;
    Uri _uri = uri;
     if (_uri != null && "content".equals(_uri.getScheme())) {
        Cursor cursor = context.getContentResolver().query(_uri, new String[] { MediaStore.Images.ImageColumns.DATA }, null, null, null);
        cursor.moveToFirst();
        filePath = cursor.getString(0);
        cursor.close();
    } else {
        filePath = _uri.getPath();
    }
    return new File(filePath);
}

Fehler:
Code:
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65536, result=-1, data=Intent { dat=content://com.android.providers.media.documents/document/image:53173 flg=0x1 }} to activity {com.ludevstudio.mp3audiobookplayer/com.ludevstudio.mp3audiobookplayer.AddBookActivit}: java.lang.NullPointerException
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5041)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:5084)
        at android.app.ActivityThread.-wrap20(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2053)
        at android.os.Handler.dispatchMessage(Handler.java:108)
        at android.os.Looper.loop(Looper.java:166)
        at android.app.ActivityThread.main(ActivityThread.java:7529)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
     Caused by: java.lang.NullPointerException
        at java.io.File.<init>(File.java:282)
        at com.ludevstudio.mp3audiobookplayer.data.Library.contentUriToFile(Library.java:252)
        at com.ludevstudio.mp3audiobookplayer.data.Library.saveCover(Library.java:211)
        at com.ludevstudio.mp3audiobookplayer.AddBookStep3BookFragment.onActivityResult(AddBookStep3BookFragment.java:164)
        at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:160)
        at android.app.Activity.dispatchActivityResult(Activity.java:7701)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5037)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:5084) 
        at android.app.ActivityThread.-wrap20(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2053) 
        at android.os.Handler.dispatchMessage(Handler.java:108) 
        at android.os.Looper.loop(Looper.java:166) 
        at android.app.ActivityThread.main(ActivityThread.java:7529) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921) 
I/Process: Sending signal. PID: 2537 SIG: 9
Application terminated.
 
Was steht in der Zeile: at com.ludevstudio.mp3audiobookplayer.data.Library.contentUriToFile(Library.java:252) bzw wie sieht die contentUriToFile Methode aus? Dort tritt die NullPointerException auf.
 
Was steht in der Zeile: at com.ludevstudio.mp3audiobookplayer.data.Library.contentUriToFile(Library.java:252) bzw wie sieht die contentUriToFile Methode aus? Dort tritt die NullPointerException auf.
Java:
public [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+file']File[/URL] contentUriToFile([URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+context']Context[/URL] context, Uri uri) {
    [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string']String[/URL] filePath = null;
    Uri _uri = uri;
     if (_uri != null && "content".equals(_uri.getScheme())) {
        [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+cursor']Cursor[/URL] cursor = context.getContentResolver().query(_uri, new [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string']String[/URL][] { MediaStore.Images.ImageColumns.DATA }, null, null, null);
        cursor.moveToFirst();
        filePath = cursor.getString(0);
        cursor.close();
    } else {
        filePath = _uri.getPath();
    }
    return new [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+file']File[/URL](filePath);
}
Stand auch oben
 
Das müsste in der Fehlermeldung (siehe Oben) stehen.
Im Stacktrace wird nur die Zeile (252) gennant. Das sagt mir ja aber noch lange nicht, welche Zeile das in deinem Code ist 😉

D.h. irgendwas stimmt mit dem Cursor nicht
Kannst du dir denn zu 100% sicher sein, dass er den if-Block ausführt und nicht den else-Block? Am Besten schaust du mal mit einem Debugger (oder Log-Ausgaben im LogCat) drüber und prüfst die Inhalte der Variablen.
 
Kannst du dir denn zu 100% sicher sein, dass er den if-Block ausführt und nicht den else-Block?
Ja kann ich. denn: der else block wird ausgeführt, wenn es sich um eine nicht-content uri handelt also sowas wie: /storage/sdcard/music/dumdidumdidum.mp3. das funktioniert.
nur bei den content uris stürzt es ab
besagte Zeile 252 lautet:
Java:
return new File(filePath);
filepath ist bei Ausführung des if blocks null!
 
Für jeden, der zukünftig einmal auf dieses Problem stoßen sollte:
Folgendes funktioniert für mich:
Java:
public Uri saveCover(Context context, Uri uri, boolean isContent) {
    String oPath = Environment.getExternalStorageDirectory()+"/test/data/";
    new File(oPath).mkdirs();
   File iF = new File(uri.getPath());
    File oF = new File(oPath+getFileNameFromURI(context, uri));


    InputStream in;
    try {
        oF.createNewFile();
        if(isContent) {
            in = context.getContentResolver().openInputStream(uri);
        } else {
            in =new FileInputStream(iF);
        }
        FileOutputStream fos =new FileOutputStream(oF);
        byte[] buffer =new byte[1024];
        int length;
        while ((length=in.read(buffer)) >0) {
            fos.write(buffer);
        }
        in.close();
        fos.close();
        return Uri.fromFile(oF);

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}







public String getFileNameFromURI(Context context, Uri uri) {
    String filePath = null;
    Uri _uri = uri;
   String filename = null;
     if (_uri != null && "content".equals(_uri.getScheme())) {
        Cursor cursor = context.getContentResolver().query(_uri, null, null, null,
                null,null);
        try {
             if(cursor!=null && cursor.moveToFirst()) {
                 filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
             }
        } finally {
            cursor.close();
        }
    } else {
        filePath = _uri.getPath();
        filename =new File(_uri.getPath()).getName();
     }

    return filename;
}
 

Zurück
Oben