2016-05-30 27 views
0

Bisher haben wir Cursor == null gelöst, wenn sie über ContentResolver abgerufen werden, indem separate Logik für SDKs < 11, 11-18,> = 19 verwendet wird. So etwas wieWie erhalten Sie Cursor über ContentResolver auf jedem Gerät?

public static Cursor getRealPathFromURI_API19(Context context, Uri uri) { 
    String[] filePathColumn = {MediaStore.Images.Media.DATA}; 
    Cursor cursor = context.getContentResolver().query(uri, filePathColumn, null, null, null); 
    return cursor; 
} 

public static Cursor getRealPathFromURI_API11to18(Context context, Uri contentUri) { 
    String[] proj = {MediaStore.Images.Media.DATA}; 
    String result = null; 

    CursorLoader cursorLoader = new CursorLoader(context, contentUri, proj, null, null, null); 
    Cursor cursor = cursorLoader.loadInBackground(); 
    return cursor; 
} 

public static Cursor getRealPathFromURI_BelowAPI11(Context context, Uri contentUri) { 
    String[] proj = {MediaStore.Images.Media.DATA}; 
    Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null); 
    return cursor; 
} 

jedoch auf Galaxy S5, wenn wir ein Bild auf ein eigenes Verzeichnis im internen öffentlichen Speicher (nicht privat data/data) speichern, bekommen wir cursor==null. Auf anderen Geräten erhalten wir keinen Null-Cursor.

Der Fluss der App ist wie folgt:

  1. Nehmen Bild mit Kamera

  2. speichert es in der Datei in einem eigenen Verzeichnis (öffentliches Verzeichnis im internen Speicher)

  3. Zugang Datei über ContentResolver und zurück Cursor

Die Schritte 1 und 2 sind richtig ausgeführt. Überprüft! Ich kann das Bild, das ich über die Kamera im angegebenen Verzeichnis aufgenommen habe, sehen.

Ich habe auch überprüft, ob die Bitmap über

InputStream input; 
    Bitmap bmp; 
    try { 
     input = getContentResolver().openInputStream(uri); 
     bmp = BitmapFactory.decodeStream(input); 
    } catch (FileNotFoundException e1) { 
     Log.e("tafg", "error"); 
    } 

zugänglich ist und ich nie eine Exception.

Trotz alledem bleibt Cursor auf einigen Geräten null. Jeder kann erraten, warum und was ist der ultimative Weg, niemals den Null-Cursor zu bekommen?

PS. Gibt es eine Bibliothek von Drittanbietern, die dieses Teil richtig behandelt?

PPS. Wir verwenden Retrofit, um bis zu 10 Bilder zu erhalten, die über die Kamera gespeichert und auf den Remote-Server hochgeladen werden. Das Verwenden und Arbeiten mit Bitmap ist in diesem Fall nicht möglich, da OOM auf dem 5. oder 6. Bild angezeigt wird. Daher muss die Retrofit-Logik ContentResolver verwenden, um die Bilder zu erhalten, die hochgeladen werden müssen.

Antwort

1

Bisher haben wir gelöst Cursor == null, wenn sie über ContentResolver abgerufen durch Verwendung separater Logik für SDKs < 11, 11-18,> = 19.

Ich empfehle dringend, dass Sie den gesamten Code und use a Uri properly löschen.

Der Fluss der App ist wie folgt:

Ihr Schritt # 3 ist sinnlos. Sie wissen, wo sich die Datei befindet, da Sie sie in Schritt 2 eingeben. Und indem Sie Schritt 3 loswerden, können Sie auch den falschen "echten Pfad" -Code loswerden.

Jeder kann erraten, warum

Vielleicht MediaStore nicht über das Bild nicht kennt, weil es noch nicht indiziert wurde.Siehe MediaScannerConnection und ihre scanFile() Methode.

Beachten Sie auch, dass Sie cursor nicht auf einen Wert in getRealPathFromURI_API19() setzen. Ich würde erwarten, dass dieser Code nicht kompiliert wird, also gehe ich davon aus, dass es sich um ein Copy/Paste-Problem in Ihrer Frage handelt.

Was ist der ultimative Weg, niemals Null Cursor zu bekommen?

Stoppen Sie abzufragen für sie an erster Stelle.

+0

Ja, einfügen Problem. Fest! – sandalone

+0

Ich habe nicht gesagt, dass wir Retrofit verwenden, um die Datei abzufragen, damit wir sie auf den Remote-Server hochladen können. Es gibt bis zu 10 Dateien, die gleichzeitig auf den Server hochgeladen werden. Und wenn ich auf "Bilder per Retrofit hochladen" klicke, bricht die App "cursor == null" ab. Ändert diese zusätzliche Information zum Retrofit etwas in Ihrer Antwort? – sandalone

+1

@sandalone: ​​Nicht wirklich. In Schritt 2 haben Sie einen Dateisystempfad zu dem Bild, das Sie auf [Externer Speicher] geschrieben haben (https://commonsware.com/blog/2014/04/08/storage-situation-external-storage.html) ("Speichern Sie es in Datei in einem eigenen Verzeichnis"). Verwenden Sie diesen Dateisystempfad mit Retrofit. Im besten Fall ist Schritt 3 ein umständlicher, langsamer, unzuverlässiger Weg, genau den gleichen Dateisystempfad zu bekommen, und ich sehe nicht, wie das Ihnen oder dem Benutzer hilft. – CommonsWare