Content Providers

Os Content Providers são parte importantíssima da arquitetura de um sistema android. É responsabilidade deles prover às aplicações o conteúdo que elas precisam para funcionar, ou seja, os dados.

ContentProviderMas por que são realmente necessários?

As aplicações poderiam muito bem acessar diretamente um banco de dados, por exemplo. Porém, é uma boa prática tornar o modo como os dados são gravados transparente à aplicação. Dessa forma, a aplicação pode manter o foco nas interações com o usuário.

Além disso, essa técnica permite a criação de Shared Content Providers, que são providers “públicos” que podem ser acessados por várias aplicações. Por exemplo, existe o content provider de SMS/MMS que permite a qualquer aplicação ler as mensagens recebidas por um telefone celular.

E como é feita a comunicação entre Content Providers e Aplicações?

Uri. Guarde bem este nome, pois você irá precisar muito dele durante a sua carreira como desenvolvedor android.

Toda a comunicação entre aplicações e providers é feita através dos métodos da interface ContentProvider, que sempre recebem um objeto Uri como parâmetro. O formato da Uri é definido pelo content provider. Por exemplo, a Uri content://sms/inbox acessa as mensagens de inbox no Content Provider de SMS. Falaremos um pouco mais sobre as Uris a seguir, mas primeiro, vamos conhecer os métodos que usaremos para enviá-las para o provider:

  • query(Uri, String[], String, String[], String)- usado para recuperar dados.
  • insert(Uri, ContentValues) – usado para inserir dados.
  • update(Uri, ContentValues, String, String[]) – usado para atualizar dados.
  • delete(Uri, String, String[]) – usado para deletar dados.
  • getType(Uri) – usado para obter o MIME type de certo dado.

O QuickNotes Content Provider

Depois dessa rápida introdução, vamos colocar a mão na massa.

Iremos criar um content provider para o QuickNotes, que servirá para gravar e recuperar as anotações do usuário, da seguinte forma:


diagrama ContentProviderIntencionalmente coloquei a caixa que define como o provider irá gravar os dados para mostrar que isso é irrelevante para a aplicação.

A estrutura das URIs

Uma Uri usada para acessar Content Provider segue o formato:

content://<authority>/<parametro1>/<parametro2>/…/<parametroN>

Onde authority é o “nome” do provider, e os parâmetros são aqueles definidos pelo provider. Por exemplo, a seguinte Uri:

content://sms/conversations/10

Acessa o Content Provider de SMS, e seleciona a conversation de Id número 10.

Criando um Content Provider

Para criar seu próprio content provider, é preciso fazer 2 coisas:

  1. Criar uma sub-classe da ContentProvider, implementando os métodos públicos que eu citei no começo do artigo;
  2. Registrar o provider no AndroidManifest.xml

Vamos começar criando a classe QuickNotesProvider:

package br.com.felipesilveira.quicknotes;

import android.content.ContentProvider;
import android.net.Uri;
import android.content.ContentValues;
import android.database.Cursor;

public class QuickNotesProvider extends ContentProvider {
	// Aqui definimos os formatos possíveis de Uri que
	// o nosso provider irá aceitar.
	public static final Uri CONTENT_URI = Uri
.parse("content://br.com.felipesilveira.quicknotes.quicknotesprovider");

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		return 0;
	}

	@Override
	public String getType(Uri uri) {
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		return null;
	}

	@Override
	public boolean onCreate() {
		return false;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		return null;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		return 0;
	}
}

Agora, vamos registrar o nosso provider no AndroidManifest, adicionando a seguinte linha entre as tags <application …> e </application>

<provider
android:authorities="br.com.felipesilveira.quicknotes.quicknotesprovider"
android:name=".QuickNotesProvider"/>

E assim o nosso Content Provider está pronto para receber requisições da aplicação. Ainda não retorna nenhum resultado significativo – mas isso faremos no próximo artigo, onde ensinarei como acessar um banco de dados SQLite, para fazer esse provider realmente efetivo.

Desenvolvendo para Android

DICA: Usando o MOTODEV Studio, a tarefa de criar um content provider fica muito mais fácil. Basta acessar New > Android Content Provider, que um template será criado, com todos os métodos! daí é só implementar a lógica deles.


Posts Relacionados

  1. Acessando um Content Provider
  2. Como usar banco de dados em uma aplicação android

8 respostas to “Content Providers”

  1. ErickPetru disse:

    Parabéns pela iniciativa da série. Comecei com Android recentemente e estou gostando muito e prevendo investir muito desenvolvimento nela.
    Estava aguardando pela parte de Providers e esta introdução foi bem objetiva. Agora aguardo a parte de SQLite.

  2. Valeu Erick!
    Estou quase terminando o artigo sobre SQLite, em breve estará aqui.

  3. Tom disse:

    Fala Felipe, Parabéns pelos artigos, muito bom mesmo, pow cara nao para de fazer esses artigos nao, sei que é dificil arrumar tempo para atualizar o site… mas seria legal que todos que foram e serão beneficiados com seus artigos nada mas justo que façamos um doação para insentivar….. abraços

  4. Marivaldo disse:

    Felipe, Content Provider é uma espécie de Hibernate para Android??

  5. Oi Marivaldo,
    Hum, o conceito é um pouco diferente. O Content Provider é também uma abstração de um banco de dados, porém a forma de acessa-lo é bem diferente do hibernate.

    Valeu!

  6. Tiago Rocha disse:

    Boas Felipe, pode-me explicar uma coisa por favor.
    Estou também desenvolvendo uma aplicação para android.
    Tenho a base de dados alojada num servidor da empresa onde estou a estagiar.. como poderei acessar essa BD?
    É através do contentprovider? E depois a aplicação comunica com a base de dados, e recolhe a informação consoante a query?

    Obrigado pela atenção desde já.
    Gostaria de falar com você de uma maneira mais directa, se pudesse facultar o seu endereço electronico ou assim agradecia.

    Cumprimentos ,
    Tiago Rocha.

    tiago.aziz@gmail.com

    Me mande um mail. :)

  7. Jorge disse:

    Obrigado pelo conteúdo e pelas dicas Felipe!

  8. Arthur disse:

    Olá Felipe, estava seguindo seu curso normalmente, mas nessa fase quando fui debugar o quick_notes deu esse erro no logcat:

    12-23 16:04:28.813: E/AndroidRuntime(1120): FATAL EXCEPTION: main
    12-23 16:04:28.813: E/AndroidRuntime(1120): java.lang.RuntimeException: Unable to get provider br.com.promptinf.DBProvider: java.lang.ClassNotFoundException: br.com.promptinf.DBProvider
    12-23 16:04:28.813: E/AndroidRuntime(1120): at android.app.ActivityThread.installProvider(ActivityThread.java:4201)
    12-23 16:04:28.813: E/AndroidRuntime(1120): at android.app.ActivityThread.installContentProviders(ActivityThread.java:3963)
    12-23 16:04:28.813: E/AndroidRuntime(1120): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3917)
    12-23 16:04:28.813: E/AndroidRuntime(1120): at android.app.ActivityThread.access$1300(ActivityThread.java:122)
    12-23 16:04:28.813: E/AndroidRuntime(1120): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1184)
    12-23 16:04:28.813: E/AndroidRuntime(1120): at android.os.Handler.dispatchMessage(Handler.java:99)
    12-23 16:04:28.813: E/AndroidRuntime(1120): at android.os.Looper.loop(Looper.java:137)
    12-23 16:04:28.813: E/AndroidRuntime(1120): at android.app.ActivityThread.main(ActivityThread.java:4340)
    12-23 16:04:28.813: E/AndroidRuntime(1120): at java.lang.reflect.Method.invokeNative(Native Method)
    12-23 16:04:28.813: E/AndroidRuntime(1120): at java.lang.reflect.Method.invoke(Method.java:511)
    12-23 16:04:28.813: E/AndroidRuntime(1120): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    12-23 16:04:28.813: E/AndroidRuntime(1120): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    12-23 16:04:28.813: E/AndroidRuntime(1120): at dalvik.system.NativeStart.main(Native Method)
    12-23 16:04:28.813: E/AndroidRuntime(1120): Caused by: java.lang.ClassNotFoundException: br.com.promptinf.DBProvider
    12-23 16:04:28.813: E/AndroidRuntime(1120): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
    12-23 16:04:28.813: E/AndroidRuntime(1120): at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
    12-23 16:04:28.813: E/AndroidRuntime(1120): at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
    12-23 16:04:28.813: E/AndroidRuntime(1120): at android.app.ActivityThread.installProvider(ActivityThread.java:4186)
    12-23 16:04:28.813: E/AndroidRuntime(1120): … 12 more

    O que devo fazer?
    Obrigado
    Arthur

Deixe um comentário