🚀 5.3 Crie um Content Provider para o seu aplicativo
Embora o Room simplifique a persistência interna, um ContentProvider é necessário se você deseja que outros aplicativos acessem seus dados de viagens. No Android moderno, integramos o ContentProvider diretamente com a nossa base de dados Room.
Definindo o Contrato (BoaViagemContract)
O contrato centraliza as URIs e nomes de colunas, facilitando o uso por terceiros:
public final class BoaViagemContract {
public static final String AUTHORITY = "br.com.casadocodigo.boaviagem.provider";
public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
public static final class Viagem {
public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "viagem");
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.boaviagem.viagem";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.boaviagem.viagem";
public static final String DESTINO = "destino";
public static final String ORCAMENTO = "orcamento";
}
}Implementando o Provedor com Room
No Android Studio 2023.1, nossa classe BoaViagemProvider utiliza o singleton do AppDatabase para obter os dados. Como o ContentProvider exige o retorno de um Cursor, acessamos o banco de dados subjacente do Room:
public class BoaViagemProvider extends ContentProvider {
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
uriMatcher.addURI(AUTHORITY, "viagem", 1);
uriMatcher.addURI(AUTHORITY, "viagem/#", 2);
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
var db = AppDatabase.getDatabase(getContext()).getOpenHelper().getReadableDatabase();
var queryBuilder = new SupportSQLiteQueryBuilder("viagem")
.columns(projection)
.selection(selection, selectionArgs)
.orderBy(sortOrder);
if (uriMatcher.match(uri) == 2) {
queryBuilder.selection("id = ?", new Object[]{uri.getLastPathSegment()});
}
return db.query(queryBuilder.create());
}
// Métodos insert, update and delete seguem lógica similar
@Override
public boolean onCreate() { return true; }
@Override
public String getType(Uri uri) {
return (uriMatcher.match(uri) == 1) ? Viagem.CONTENT_TYPE : Viagem.CONTENT_ITEM_TYPE;
}
}IMPORTANT
Compatibilidade Room e Cursor: O Room é projetado para retornar objetos, mas o
ContentProviderexigeCursors. Ao usargetOpenHelper().getReadableDatabase(), você acessa a engine SQLite do Room mantendo a consistência dos dados e aproveitando a estrutura já definida.
TIP
Não esqueça de registrar o provedor no
AndroidManifest.xml. No Android 11+ (API 30), outros apps só verão seu provedor se declararem<queries>com a autoridade correta no manifesto deles.