Wie speichere ich große Blobs in einem Android Content Provider?

Ich habe einige große Dateien (Bilder und Videos), die ich bei einem Inhaltsanbieter speichern muss. Die Android-Dokumentation zeigt ...

Wenn Sie Byte-Daten verfügbar machen, die zu groß sind, um sie in die Tabelle selbst einzufügen, z. B. eine große Bitmap-Datei, sollte das Feld, in dem die Daten für Clients verfügbar gemacht werden, tatsächlich einen Inhalt enthalten: URI-String. In diesem Feld können Clients auf die Datendatei zugreifen. Der Datensatz sollte auch ein anderes Feld mit dem Namen "_data" enthalten, in dem der genaue Dateipfad auf dem Gerät für diese Datei aufgeführt ist. Dieses Feld soll nicht vom Client gelesen werden, sondern vom ContentResolver. Der Client ruft ContentResolver.openInputStream () in dem benutzerbezogenen Feld auf, das den URI für das Element enthält. Der ContentResolver fordert das Feld "_data" für diesen Datensatz an, und da er über höhere Berechtigungen als ein Client verfügt, sollte er in der Lage sein, direkt auf diese Datei zuzugreifen und einen Lese-Wrapper für die Datei an den Client zurückzugeben. -http: //developer.android.com/guide/topics/providers/content-providers.html#creatin

Ich habe einige Schwierigkeiten, ein Beispiel zu finden. Insbesondere möchte ich die Bitmap im Kontext einer ImageView verwenden. Betrachten Sie den folgenden Code als Quasi-Code (es funktioniert nicht) ...

ImageView iv = ....
String iconUri = cursor.getString(cursor.getColumnIndex(Table.ICON));
iv.setImageURI(Uri.parse(iconUri));

Beobachtungen / Probleme ...

Wie kann der gespeicherte / wiederhergestellte Uri korrekt rekonstruiert werden? (es ist Text in der Tabelle)

Die Implementierung von setImageURI verwendet die Inhaltsauflösung openInputStream, damit dies funktioniert.

String scheme = mUri.getScheme();
...
} else if (ContentResolver.SCHEME_CONTENT.equals(scheme)
        || ContentResolver.SCHEME_FILE.equals(scheme)) {
  try {
    d = Drawable.createFromStream(
            mContext.getContentResolver().openInputStream(mUri),
            null);

- frameworks / base / core / java / android / widget / ImageView.java

Ich habe es geschafft. Ich habe einen Hinweis aus dem MediaStore und MediaProvider genommen. Die Dateien, die die Daten enthalten, werden anhand des Inhaltsanbieters (Verzeichnisses), des Spaltennamens, der Zeilen-ID und des Medientyps benannt. Der Content Resolver erhält dann wie folgt den Dateideskriptor ...

Uri iconUri = Uri.withAppendedPath(Table.getUri(cursor), Table.ICON);
ib.setImageURI(iconUri);

... und der Inhaltsanbieter antwortet in Form von Sachleistungen ...

@Override
public ParcelFileDescriptor openFile (Uri uri, String mode) {
int imode = 0;
if (mode.contains("w")) imode |= ParcelFileDescriptor.MODE_WRITE_ONLY;
if (mode.contains("r")) imode |= ParcelFileDescriptor.MODE_READ_ONLY;
if (mode.contains("+")) imode |= ParcelFileDescriptor.MODE_APPEND;
List<String> pseg = uri.getPathSegments();
if (pseg.size() < 3) return null;

try {
    File filePath = filePathFromRecord(pseg.get(2), pseg.get(1));
    return ParcelFileDescriptor.open(filePath, imode);
} catch (FileNotFoundException e) {
    e.printStackTrace();
}
return null;
}

Antworten auf die Frage(6)

Ihre Antwort auf die Frage