Como armazenar blobs grandes em um provedor de conteúdo Android?

Tenho alguns arquivos grandes (imagens e vídeo) que preciso armazenar em um provedor de conteúdo. A documentação do Android indica ...

Se você estiver expondo dados de bytes grandes demais para serem inseridos na tabela - como um arquivo de bitmap grande -, o campo que expõe os dados aos clientes deve na verdade conter uma sequência de conteúdo: URI. Este é o campo que fornece aos clientes acesso ao arquivo de dados. O registro também deve ter outro campo, chamado "_data", que lista o caminho exato do arquivo no dispositivo para esse arquivo. Este campo não pretende ser lido pelo cliente, mas pelo ContentResolver. O cliente chamará ContentResolver.openInputStream () no campo voltado para o usuário que contém o URI do item. O ContentResolver solicitará o campo "_data" para esse registro e, como possui permissões mais altas que um cliente, poderá acessar esse arquivo diretamente e retornar ao cliente um wrapper de leitura para o arquivo. -http://developer.android.com/guide/topics/providers/content-providers.html#creating

Estou com dificuldades para encontrar um exemplo. Em particular, desejo usar o bitmap no contexto de um ImageView. Considere o seguinte código quase-código (não funciona) ...

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

Observações / Problemas ...

Como o uri armazenado / recuperado pode ser reconstruído corretamente? (é texto na tabela)

A implementação setImageURI utiliza o conteúdo de resolução openInputStream, portanto, isso deve funcionar.

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

Eu consegui funcionar. Peguei uma dica do MediaStore e MediaProvider. Os arquivos que contêm os dados são nomeados com base no provedor de conteúdo (diretório), no nome da coluna, no ID da linha e no tipo de mídia. O resolvedor de conteúdo adquire o descritor de arquivo da seguinte maneira ...

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

... e o provedor de conteúdo responde da mesma forma ...

@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;
}

questionAnswers(3)

yourAnswerToTheQuestion