Caso prefira, você encontrará todo esse material, em inglês, no site do Developer Android. A tradução e comentários dos materiais eu faço livremente para ajudar a comunidade que fala português.

quarta-feira, 13 de abril de 2011

Content Providers - Parte 03

Criando um Content Provider

Para criar um content provider, você deve:

  • Configurar o sistema para guardar os dados. A maioria dos content provider guardam seus dados usando os métodos de arquivo do Android ou os bancos de dados SQLite mas você pode guardar seus dados da maneira como achar melhor. O Android provê a classe SQLiteOpenHelper para ajudá-lo a criar um banco de dados e a classe SQLiteDatabase para gerenciá-lo.
  • Extender a classe ContentProvider para prover acesso aos dados.
  • Declarar o content provider no arquivo de manifesto da sua aplicação (AndroidManifest.xml)
Extendendo a classe ContentProvider

Você define uma subclasse ContentProvider expondo seus dados para outros usando as convenções esperadas pelo ContentResolver e pelo objeto Cursor. Isso significa implementar seis métodos abstratos declarados na classe ContentProvider:
query()
insert()
update()
delete()
getType()
onCreate()
O método query() deve retornar um objeto Cursor que pode iterar pelos dados requeridos. O Cursor em si é uma interface mas o Android provê alguns objetos Cursos que você pode usar. Por exemplo, o SQLiteCursor pode interar pelos dados guardados em um banco de dados SQLite. Você obtem um objeto Cursor chamando o método query() da classe SQLiteDatabase. Existem outras implementações de cursores, como MatrixCursor, para dados não guardados em bancos de dados.

Como esses métodos ContentProvider podem ser chamados de objetos ContentProvider em diferentes provessos e threads, eles devem ser implementados como sendo do tipo thread-safe.

Como uma cortesia, você também poderá chamar ContentResolver.notifyChange() para notificar os listeners quando houverem modificações nos dados.

Ao invés de definir a subclasse você mesmo, existem outros passos que você deveria tomar para simplificar o seu trabalho de trabalhar com clientes e fazer da classe algo mais acessível:

1) Definir uma Uri como public static final e nomeada CONTENT_URI. Essa é a string que representará a URI content: completa que o content provider requer. Você deve definir uma string única para esse valor. A melhor solução é usar um nome de classe completamente qualificado do content provider (em caixa baixa). Assim, por exemplo, a URI para a classe TransportationProvider deve ser definida como mostrado aqui:

public static final Uri CONTENT_URI =
               Uri.parse("content://com.example.codelab.transportationprovider");
Se o provider tem subtabelas, também defina um CONTENT_URI para cada uma delas. Esses URIs devem ter a mesma autoridade e devem ser distintas apenas pelos caminhos. Por exemplo:
content://com.example.codelab.transportationprovider/train
content://com.example.codelab.transportationprovider/air/domestic
content://com.example.codelab.transportationprovider/air/international
2) Definir os nomes das colunas que o content provider retornará aos clientes. Se você estiver usando um banco de dados, essas colunas terão nomes idênticos aos especificados no banco de dados. Também defina como public static as constantes que os clientes podem usar nas pesquisas e outras instruções.

Esteja certo de incluir uma coluna do tipo inteiro nomeada "_id" para os IDs dos registros. Você deve ter esse campo mesmo que a tabela não contenha nenhum outro campo. Se você estiver usando o SQLite como repositório, o campo _ID deverá ser como mostrado abaixo:

INTEGER PRIMARY KEY AUTOINCREMENT

3) Cuidadosamente documente cada tipo de dados de cada coluna. O cliente necessita dessas informações para que possa ler os dados.

4) Se você está gerenciando um novo tipo de dados, você deve definir um novo tipo MIME a ser retornado em sua implementação de ContentProvider.getType(). O tipo depende em se o content: submetido ao getType() limita a requisição para um registro específico. Existe uma forma de tipo MIME para cada registro único e outro para registros múltiplos. Use os métodos Uri para ajudá-lo a determinar o que está sendo requerido.

  • Para registros simples: vnd.android.cursor.item/vnd.yourcompanyname.contenttype
    Por exemplo, uma requisição para o trem de registro 122 com a chamada abaixo
          content://com.example.transportationprovider/trains/122 
    deve retornar um MIME do tipo:
          vnd.android.cursor.item/vnd.example.rail
  • Para registros múltiplos: vnd.android.cursor.dir/vnd.yourcompanyname.contenttype
    Por exemplo, uma requisição de todos os trens como a chamada abaixo
          content://com.example.transportationprovider/trains
    deve retornar um MIME do tipo:
          vnd.android.cursor.dir/vnd.example.rail
5) Se você está expondo dados em bytes que são muito longos para serem gravados em bancos de dados - como um enorme arquivo bitmap -o campo que expõe os dados para o cliente devem conter uma string content: URI. Esse é o campo que dá ao cliente acesso aos dados do arquivo. O registro deve também ter outro campo nomeado de "_data", que lista o caminho exato do arquivo no dispositivo. Esse campo não deve poder ser lido pelo cliente mas apenas pelo ContentResolver. O cliente chamará ContentResolver.openInputStream(). O ContentResolver vai requerer o campo "_data" para o registro e já que tem permissões mais elevadas no cliente, deverá ser capaz de acessar o arquivo diretamente e retornar um wrapper de leitura do arquivo para o cliente.

Declarando um content provider

Para deixar que o sistema Android saiba dos content providers que você desenvolveu, declare-os no elemento <provider> do arquivo de manifesto. Content Providers que não são declarados no manifesto não são visíveis no sistema Android.

O atributo name é o nome da subclasse do ContentProvider. O atributo authorities é a parte de autoridade da content: URI que identifica o provedor. Por exemplo, se a subclasse ContentProvider é do tupo AutoInfoProvider, o elemento <provider> deverá se parecer como abaixo:
<provider android:name="com.example.autos.AutoInfoProvider"
          android:authorities="com.example.autos.autoinfoprovider"
          . . . />
</provider>
Note que o atributo authorities omite o caminho de parte do content: URI. Por exemplo, se as subtabelas de AutoInfoProvider são controladas por diferentes tipos de carros ou fabricantes,
content://com.example.autos.autoinfoprovider/honda
content://com.example.autos.autoinfoprovider/gm/compact
content://com.example.autos.autoinfoprovider/gm/suv
esses caminhos não serão declarados no manifesto. A authority é o que identifica o provedor, não o caminho; seu provedor pode interpretar o caminho de parte da URI da maneira como você escolher.

0 comentários:

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.
Related Posts Plugin for WordPress, Blogger...