1page.title=Criação de um Provedor de Conteúdo 2@jd:body 3<div id="qv-wrapper"> 4<div id="qv"> 5 6 7<h2>Neste documento</h2> 8<ol> 9 <li> 10 <a href="#DataStorage">Projeto de armazenamento de dados</a> 11 </li> 12 <li> 13 <a href="#ContentURI">Projeto de URIs de conteúdo</a> 14 </li> 15 <li> 16 <a href="#ContentProvider">Implementação da classe ContentProvider</a> 17 <ol> 18 <li> 19 <a href="#RequiredAccess">Métodos obrigatórios</a> 20 </li> 21 <li> 22 <a href="#Query">Implementação do método query()</a> 23 </li> 24 <li> 25 <a href="#Insert">Implementação do método insert()</a> 26 </li> 27 <li> 28 <a href="#Delete">Implementação do método delete()</a> 29 </li> 30 <li> 31 <a href="#Update">Implementação do método update()</a> 32 </li> 33 <li> 34 <a href="#OnCreate">Implementação do método onCreate()</a> 35 </li> 36 </ol> 37 </li> 38 <li> 39 <a href="#MIMETypes">Implementação de tipos MIME do Provedor de Conteúdo</a> 40 <ol> 41 <li> 42 <a href="#TableMIMETypes">Tipos MIME para tabelas</a> 43 </li> 44 <li> 45 <a href="#FileMIMETypes">Tipos MIME para arquivos</a> 46 </li> 47 </ol> 48 </li> 49 <li> 50 <a href="#ContractClass">Implementação de uma classe de contrato</a> 51 </li> 52 <li> 53 <a href="#Permissions">Implementação de permissões do Provedor de Conteúdo</a> 54 </li> 55 <li> 56 <a href="#ProviderElement">O elemento <provider></a> 57 </li> 58 <li> 59 <a href="#Intents">Intenções e acesso a dados</a> 60 </li> 61</ol> 62<h2>Classes principais</h2> 63 <ol> 64 <li> 65 {@link android.content.ContentProvider} 66 </li> 67 <li> 68 {@link android.database.Cursor} 69 </li> 70 <li> 71 {@link android.net.Uri} 72 </li> 73 </ol> 74<h2>Exemplos relacionados</h2> 75 <ol> 76 <li> 77 <a href="{@docRoot}resources/samples/NotePad/index.html"> 78 Aplicativo de exemplo do Bloco de Notas 79 </a> 80 </li> 81 </ol> 82<h2>Veja também</h2> 83 <ol> 84 <li> 85 <a href="{@docRoot}guide/topics/providers/content-provider-basics.html"> 86 Preceitos do provedor de conteúdo</a> 87 </li> 88 <li> 89 <a href="{@docRoot}guide/topics/providers/calendar-provider.html"> 90 Provedor de agenda</a> 91 </li> 92 </ol> 93</div> 94</div> 95 96 97<p> 98 O provedor de conteúdo gerencia o acesso a um repositório central de dados. Implementa-se 99 um provedor como uma ou mais classes em um aplicativo do Android, em conjunto com elementos 100 no arquivo de manifesto. Uma das classes implementa uma subclasse 101 {@link android.content.ContentProvider}, que é a interface entre o provedor 102 e outros aplicativos. Embora provedores de conteúdo se destinem a disponibilizar dados a outros 103 aplicativos, naturalmente é possível ter atividades no aplicativo que permitam ao usuário 104 consultar e modificar os dados gerenciados pelo provedor. 105</p> 106<p> 107 O restante deste tópico é uma lista básica de etapas para a criação de um provedor de conteúdo e uma lista 108 de APIs para usar. 109</p> 110 111 112<!-- Before You Start Building --> 113<h2 id="BeforeYouStart">Antes de começar a criar</h2> 114<p> 115 Antes de começar a criar um provedor, faça o seguinte: 116</p> 117<ol> 118 <li> 119 <strong>Avalie se você precisa de um provedor de conteúdo</strong>. É necessário criar um provedor 120 de conteúdo para fornecer um ou mais dos recursos a seguir: 121 <ul> 122 <li>Oferecer dados ou arquivos complexos a outros aplicativos.</li> 123 <li>Permitir que usuários copiem dados complexos do seu aplicativo para outros aplicativos.</li> 124 <li>Fornecer sugestões de pesquisa personalizada usando a estrutura de pesquisa.</li> 125 </ul> 126 <p> 127 <em>Não</em> é necessário um provedor para usar um banco de dados SQLite se o uso for inteiramente dentro 128 do próprio aplicativo. 129 </p> 130 </li> 131 <li> 132 Se você ainda não tiver feito isso, leia o tópico 133 <a href="{@docRoot}guide/topics/providers/content-provider-basics.html"> 134 Preceitos do provedor de conteúdo</a> para saber mais sobre provedores. 135 </li> 136</ol> 137<p> 138 A seguir, siga estas etapas para criar seu provedor: 139</p> 140<ol> 141 <li> 142 Projete o armazenamento bruto dos dados. Os provedores de conteúdo oferecem dados de duas maneiras: 143 <dl> 144 <dt> 145 Dados de arquivo 146 </dt> 147 <dd> 148 Dados que normalmente transitam em arquivos, como 149 fotos, áudio ou vídeos. Armazene os arquivos no espaço privado 150 do seu aplicativo. Em resposta a uma solicitação de um arquivo por outro aplicativo, 151 o provedor pode oferecer um identificador para o arquivo. 152 </dd> 153 <dt> 154 Dados "estruturados" 155 </dt> 156 <dd> 157 Dados que normalmente transitam em um banco de dados, uma matriz ou estrutura similar. 158 Armazene os dados de forma compatível com tabelas de linhas e colunas. Cada linha 159 representa uma entidade, como uma pessoa ou um item em um inventário. Cada coluna representa 160 alguns dados da entidade, como o nome da pessoa ou o preço do item. Um modo comum de 161 armazenar esse tipo de dados é em um banco de dados SQLite, mas é possível usar qualquer tipo 162 de armazenamento persistente. Para saber mais sobre os tipos de armazenamento disponíveis 163 no sistema Android, consulte a seção <a href="#DataStorage"> 164Projeto de armazenamento de dados</a>. 165 </dd> 166 </dl> 167 </li> 168 <li> 169 Defina uma implementação sólida da classe {@link android.content.ContentProvider} 170 e seus métodos obrigatórios. Essa classe é a interface entre seus dados e o restante 171 do sistema Android. Para obter mais informações sobre essa classe, consulte a seção 172 <a href="#ContentProvider">Implementação da classe ContentProvider</a>. 173 </li> 174 <li> 175 Defina a string de autoridade do provedor, suas URIs de conteúdo e seus nomes de coluna. Se você deseja que 176 o aplicativo do provedor trate de intenções, defina também ações de intenção, dados extras 177 e sinalizadores. Também defina as permissões necessárias para aplicativos que queiram 178 acessar seus dados. Deve-se considerar definir todos esses valores como constantes 179 em uma classe de contrato separada; posteriormente, será possível expor essa classe a outros desenvolvedores. Para 180 obter mais informações sobre URIs de conteúdo, consulte 181 a seção <a href="#ContentURI">Projeto de URIs de conteúdo</a>. 182 Para obter mais informações sobre intenções, consulte 183 a seção <a href="#Intents">Intenções e acesso a dados</a>. 184 </li> 185 <li> 186 Adicione outras partes opcionais, como dados de exemplo ou uma implementação 187 de {@link android.content.AbstractThreadedSyncAdapter} que possa sincronizar dados entre 188 o provedor e os dados com base em nuvem. 189 </li> 190</ol> 191 192 193<!-- Designing Data Storage --> 194<h2 id="DataStorage">Projeto de armazenamento de dados</h2> 195<p> 196 Os provedores de conteúdo são a interface para dados salvos em um formato estruturado. Antes de criar 197 a interface, é preciso decidir como armazenar os dados. É possível armazená-los da forma que 198 quiser e, em seguida, projetar a interface para ler e gravar os dados conforme o necessário. 199</p> 200<p> 201 Essas são algumas das tecnologias de armazenamento de dados disponíveis no Android: 202</p> 203<ul> 204 <li> 205 O sistema Android contém uma API de banco de dados SQLite que os provedores do Android usam 206 para armazenar dados orientados a tabela. 207 A classe {@link android.database.sqlite.SQLiteOpenHelper} ajuda a criar bancos de dados 208 e a classe {@link android.database.sqlite.SQLiteDatabase} é a classe de base para acessar 209 banco de dados. 210 <p> 211 Lembre-se de que não é necessário usar nenhum banco de dados para implementar o repositório. Um provedor 212 aparece externamente como um conjunto de tabelas, semelhante a um banco de dados relacional, mas isso não 213 é um requisito para a implementação interna do provedor. 214 </p> 215 </li> 216 <li> 217 Para armazenar dados de arquivos, o Android tem diversas APIs orientadas a arquivo. 218 Para saber mais sobre armazenamento de arquivos, leia o tópico 219 <a href="{@docRoot}guide/topics/data/data-storage.html">Armazenamento de dados</a>. Se você estiver 220 projetando um provedor que oferece dados relacionados a mídia como música ou vídeos, é possível 221 ter um provedor que combine dados de tabela e de arquivos. 222 </li> 223 <li> 224 Para trabalhar com dados com base em rede, use classes em {@link java.net} 225 e em {@link android.net}. É possível, também, sincronizar dados com base em rede com uma armazenagem 226 local de dados, como um banco de dados e, em seguida, fornecer os dados na forma de tabelas ou arquivos. 227 O exemplo de aplicativo <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html"> 228 Exemplo de adaptador de sincronização</a> demonstra o tipo de sincronização. 229 </li> 230</ul> 231<h3 id="DataDesign"> 232 Considerações para projetar dados 233</h3> 234<p> 235 A seguir há algumas dicas para projetar a estrutura de dados do seu provedor: 236</p> 237<ul> 238 <li> 239 Os dados de tabela sempre devem ter uma coluna de "chave principal" que o provedor mantém 240 como um valor numérico exclusivo para cada linha. É possível usar esse valor para vincular a linha a linhas 241 relacionadas em outras tabelas (usando-o como uma "chave externa"). Embora seja possível usar qualquer nome 242 para essa coluna, é melhor usar {@link android.provider.BaseColumns#_ID BaseColumns._ID} 243 porque a vinculação dos resultados de uma consulta de provedor com uma 244 {@link android.widget.ListView} requer que uma das colunas tenha o nome 245 <code>_ID</code>. 246 </li> 247 <li> 248 Se você deseja fornecer imagens bitmap ou outras partes muito grandes de dados orientados a arquivo, armazene 249 os dados em um arquivo e, em seguida, forneça-o indiretamente em vez de armazená-lo diretamente em uma 250 tabela. Ao fazer isso, será necessário informar aos usuários do provedor que eles precisam usar 251 um método de arquivo {@link android.content.ContentResolver} para acessar os dados. 252 </li> 253 <li> 254 Use objeto grande binário (BLOB) como tipo de dados para armazenar dados que variam em tamanho ou que tenham 255 estrutura variável. Por exemplo: é possível usar uma coluna de BLOB para armazenar 256 um <a href="http://code.google.com/p/protobuf">buffer de protocolo</a> ou 257 uma <a href="http://www.json.org">estrutura JSON</a>. 258 <p> 259 Pode-se usar um BLOB para implementar uma tabela <em>independente de esquema</em>. Nesse 260 tipo de tabela, define-se uma coluna de chave principal, uma coluna de tipo MIME e uma 261 ou mais colunas genéricas como BLOB. O significado dos dados nas colunas BLOB é indicado 262 pelo valor na coluna de tipo MIME. Isso permite o armazenamento de diferentes tipos de linha 263 na mesma tabela. A tabela de "dados" {@link android.provider.ContactsContract.Data} 264 do Provedor de contatos é um exemplo de uma tabela 265 independente de esquema. 266 </p> 267 </li> 268</ul> 269<!-- Designing Content URIs --> 270<h2 id="ContentURI">Projeto de URIs de conteúdo</h2> 271<p> 272 <strong>URI de conteúdo</strong> é uma URI que identifica dados em um provedor. URIs de conteúdo 273 contêm o nome simbólico de todo o provedor (sua <strong>autoridade</strong>) e um 274 nome que aponta para uma tabela ou arquivo (um <strong>caminho</strong>). Parte do ID opcional aponta para 275 uma linha individual em uma tabela. Cada método de acesso aos dados 276 {@link android.content.ContentProvider} de tem uma URI de conteúdo como um argumento. Isso permite 277 determinar a tabela, a linha ou o arquivo a acessar. 278</p> 279<p> 280 Os conceitos básicos de URIs de conteúdo são escritos no tópico 281 <a href="{@docRoot}guide/topics/providers/content-provider-basics.html"> 282 Preceitos do provedor de conteúdo</a>. 283</p> 284<h3>Projeto de uma autoridade</h3> 285<p> 286 Os provedores normalmente têm uma única autoridade, que serve como seu nome interno do Android. Para 287 evitar conflitos com outros provedores, deve-se usar a propriedade de domínio da internet (ao contrário) 288 como a base da autoridade do provedor. Em virtude de esta recomendação ser verdadeira para nomes 289 de pacote do Android, é possível definir a autoridade do provedor como uma extensão do nome 290 do pacote que contém o provedor. Por exemplo: se o nome do pacote do Android for 291 <code>com.example.<appname></code>, deve-se atribuir ao provedor 292 a autoridade <code>com.example.<appname>.provider</code>. 293</p> 294<h3>Projeto de uma estrutura de caminho</h3> 295<p> 296 Desenvolvedores normalmente criam URIs de conteúdo a partir da autoridade anexando caminhos que apontam para 297 tabelas individuais. Por exemplo: se você tiver duas tabelas (<em>tabela1</em> e 298 <em>tabela2</em>), combine a autoridade do exemplo anterior para produzir 299 as URIs de conteúdo 300 <code>com.example.<appname>.provider/table1</code> e 301 <code>com.example.<appname>.provider/table2</code>. Caminhos não 302 se limitam a um único segmento e não precisa ter uma tabela para cada nível do caminho. 303</p> 304<h3>Identificação de IDs de URIs de conteúdo</h3> 305<p> 306 Por convenção, provedores fornecem acesso a uma linha exclusiva em uma tabela aceitando uma URI de conteúdo 307 com um valor de ID para a linha no fim da URI. Também por convenção, provedores combinam 308 o valor do ID com a coluna <code>_ID</code> da tabela e realizam o acesso solicitado 309 na linha correspondente. 310</p> 311<p> 312 Essa convenção facilita a padronização comum do projeto para aplicativos que acessam um provedor. O aplicativo 313 realiza uma consulta no provedor e exibe o {@link android.database.Cursor} 314 resultante em uma {@link android.widget.ListView} usando um {@link android.widget.CursorAdapter}. 315 A definição de {@link android.widget.CursorAdapter} requer que uma das colunas 316 no {@link android.database.Cursor} seja <code>_ID</code> 317</p> 318<p> 319 Em seguida, o usuário seleciona uma das linhas exibidas na IU para visualizar ou modificar 320 os dados. O aplicativo tem a linha correspondente do {@link android.database.Cursor} apoiando 321 a {@link android.widget.ListView}, obtém o valor <code>_ID</code> para essa linha, anexa-o 322 à URI de conteúdo e envia a solicitação de acesso ao provedor. O provedor, então, pode realizar 323 a consulta ou modificação na exata linha que o usuário selecionou. 324</p> 325<h3>Padrões de URI de conteúdo</h3> 326<p> 327 Para ajudar a escolher que ação tomar para uma URI de conteúdo recebida, a API do provedor contém 328 a classe de conveniência {@link android.content.UriMatcher}, que mapeia "padrões" de URI de conteúdo 329 como valores de número inteiro. É possível usar os valores de número inteiro em uma declaração <code>switch</code> que 330 escolha a ação desejada para a URI de conteúdo ou URIs que atendam ao padrão determinado. 331</p> 332<p> 333 Um padrão de URI de conteúdo corresponde a URIs de conteúdo que usam caracteres especiais: 334</p> 335 <ul> 336 <li> 337 <strong><code>*</code>:</strong> Corresponde a uma string de qualquer caractere válido de qualquer comprimento. 338 </li> 339 <li> 340 <strong><code>#</code>:</strong> Corresponde a uma string de caracteres numéricos de qualquer comprimento. 341 </li> 342 </ul> 343<p> 344 Como um exemplo de projeto e codificação da identificação de URIs de conteúdo, considere um provedor 345 com a autoridade <code>com.example.app.provider</code> que reconheça as URIs de conteúdo 346 que apontam para tabelas: 347</p> 348<ul> 349 <li> 350 <code>content://com.example.app.provider/table1</code>: Uma tabela chamada <code>table1</code>. 351 </li> 352 <li> 353 <code>content://com.example.app.provider/table2/dataset1</code>: Uma tabela chamada 354 <code>dataset1</code>. 355 </li> 356 <li> 357 <code>content://com.example.app.provider/table2/dataset2</code>: Uma tabela chamada 358 <code>dataset1</code>. 359 </li> 360 <li> 361 <code>content://com.example.app.provider/table3</code>: Uma tabela chamada <code>table3</code>. 362 </li> 363</ul> 364<p> 365 O provedor também reconhece essas URIs de conteúdo se elas tiverem um ID de linha anexado, como 366 <code>content://com.example.app.provider/table3/1</code> para a linha identificada por 367 <code>1</code> em <code>table3</code>. 368</p> 369<p> 370 Os seguintes padrões de URI de conteúdo seriam possíveis: 371</p> 372<dl> 373 <dt> 374 <code>content://com.example.app.provider/*</code> 375 </dt> 376 <dd> 377 Corresponde a qualquer URI de conteúdo no provedor. 378 </dd> 379 <dt> 380 <code>content://com.example.app.provider/table2/*</code>: 381 </dt> 382 <dd> 383 Corresponde a uma URI de conteúdo das tabelas <code>dataset1</code> 384 e <code>dataset2</code>, mas não a URIs de conteúdo de <code>table1</code> 385 nem <code>table3</code>. 386 </dd> 387 <dt> 388 <code>content://com.example.app.provider/table3/#</code>: Corresponde a uma URI de conteúdo 389 para linhas exclusivas em <code>table3</code>, como 390 <code>content://com.example.app.provider/table3/6</code> da linha identificada por 391 <code>6</code>. 392 </dt> 393</dl> 394<p> 395 O fragmento de código a seguir mostra como funcionam os métodos em {@link android.content.UriMatcher}. 396 Esse código identifica URIs para toda uma tabela, diferentemente das URIs 397 para uma linha exclusiva, usando o padrão de URI de conteúdo 398 <code>content://<authority>/<path></code> para tabelas e 399 <code>content://<authority>/<path>/<id></code> para linhas exclusivas. 400</p> 401<p> 402 O método {@link android.content.UriMatcher#addURI(String, String, int) addURI()} mapeia 403 uma autoridade e um caminho como um valor de número inteiro. O método {@link android.content.UriMatcher#match(Uri) 404 match()} retorna o valor de número inteiro para a URI. Uma declaração <code>switch</code> 405 escolhe entre consultar a tabela inteira e consultar um único registro: 406</p> 407<pre class="prettyprint"> 408public class ExampleProvider extends ContentProvider { 409... 410 // Creates a UriMatcher object. 411 private static final UriMatcher sUriMatcher; 412... 413 /* 414 * The calls to addURI() go here, for all of the content URI patterns that the provider 415 * should recognize. For this snippet, only the calls for table 3 are shown. 416 */ 417... 418 /* 419 * Sets the integer value for multiple rows in table 3 to 1. Notice that no wildcard is used 420 * in the path 421 */ 422 sUriMatcher.addURI("com.example.app.provider", "table3", 1); 423 424 /* 425 * Sets the code for a single row to 2. In this case, the "#" wildcard is 426 * used. "content://com.example.app.provider/table3/3" matches, but 427 * "content://com.example.app.provider/table3 doesn't. 428 */ 429 sUriMatcher.addURI("com.example.app.provider", "table3/#", 2); 430... 431 // Implements ContentProvider.query() 432 public Cursor query( 433 Uri uri, 434 String[] projection, 435 String selection, 436 String[] selectionArgs, 437 String sortOrder) { 438... 439 /* 440 * Choose the table to query and a sort order based on the code returned for the incoming 441 * URI. Here, too, only the statements for table 3 are shown. 442 */ 443 switch (sUriMatcher.match(uri)) { 444 445 446 // If the incoming URI was for all of table3 447 case 1: 448 449 if (TextUtils.isEmpty(sortOrder)) sortOrder = "_ID ASC"; 450 break; 451 452 // If the incoming URI was for a single row 453 case 2: 454 455 /* 456 * Because this URI was for a single row, the _ID value part is 457 * present. Get the last path segment from the URI; this is the _ID value. 458 * Then, append the value to the WHERE clause for the query 459 */ 460 selection = selection + "_ID = " uri.getLastPathSegment(); 461 break; 462 463 default: 464 ... 465 // If the URI is not recognized, you should do some error handling here. 466 } 467 // call the code to actually do the query 468 } 469</pre> 470<p> 471 Outra classe, {@link android.content.ContentUris}, fornece métodos convenientes para trabalhar 472 com a parte <code>id</code> das URIs de conteúdo. As classes {@link android.net.Uri} 473 e {@link android.net.Uri.Builder} contêm métodos convenientes para analisar objetos 474 {@link android.net.Uri} existentes e criar novos. 475</p> 476 477<!-- Implementing the ContentProvider class --> 478<h2 id="ContentProvider">Implementação da classe ContentProvider</h2> 479<p> 480 A instância {@link android.content.ContentProvider} gerencia o acesso 481 a um conjunto de dados estruturado lidando com solicitações de outros aplicativos. Todas as formas 482 de acesso ocasionalmente chamam {@link android.content.ContentResolver} que, em seguida, chama um método 483 concreto de {@link android.content.ContentProvider} para obter acesso. 484</p> 485<h3 id="RequiredAccess">Métodos obrigatórios</h3> 486<p> 487 A classe abstrata {@link android.content.ContentProvider} define seis métodos abstratos 488 que devem ser implementados como parte das subclasses concretas. Todos esses métodos, exceto 489 {@link android.content.ContentProvider#onCreate() onCreate()}, são chamados por um aplicativo cliente 490 que está tentando acessar seu provedor de conteúdo: 491</p> 492<dl> 493 <dt> 494 {@link android.content.ContentProvider#query(Uri, String[], String, String[], String) 495 query()} 496 </dt> 497 <dd> 498 Recupere dados do provedor. Use os argumentos para selecionar a tabela 499 para consultar as linhas e colunas a retornar e a ordem de classificação do resultado. 500 Retorne os dados como um objeto {@link android.database.Cursor}. 501 </dd> 502 <dt> 503 {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} 504 </dt> 505 <dd> 506 Insira uma nova linha no provedor. Use os argumentos para selecionar 507 a tabela de destino e obter os valores de coluna a usar. Retorne uma URI de conteúdo para 508 a linha recentemente inserida. 509 </dd> 510 <dt> 511 {@link android.content.ContentProvider#update(Uri, ContentValues, String, String[]) 512 update()} 513 </dt> 514 <dd> 515 Atualize as linhas existentes no provedor. Use os argumentos para selecionar a tabela e linhas 516 para atualizar e obter os valores de coluna atualizados. Retorne o número de linhas atualizadas. 517 </dd> 518 <dt> 519 {@link android.content.ContentProvider#delete(Uri, String, String[]) delete()} 520 </dt> 521 <dd> 522 Exclua linhas do provedor. Use os argumentos para selecionar a tabela e as linhas 523 a excluir. Retorne o número de linhas excluídas. 524 </dd> 525 <dt> 526 {@link android.content.ContentProvider#getType(Uri) getType()} 527 </dt> 528 <dd> 529 Retorne o tipo MIME correspondente a uma URI de conteúdo. Esse método é descrito com mais 530 detalhes na seção <a href="#MIMETypes">Implementação de tipos MIME do Provedor de Conteúdo</a>. 531 </dd> 532 <dt> 533 {@link android.content.ContentProvider#onCreate() onCreate()} 534 </dt> 535 <dd> 536 Inicializar o provedor. O sistema Android chama esse método imediatamente 537 após criar o provedor. Observe que o provedor não é criado até que 538 um objeto {@link android.content.ContentResolver} tente acessá-lo. 539 </dd> 540</dl> 541<p> 542 Observe que esses métodos têm a mesma assinatura dos métodos 543 {@link android.content.ContentResolver} de mesmo nome. 544</p> 545<p> 546 A implementação desses métodos deve levar em conta o seguinte: 547</p> 548<ul> 549 <li> 550 Todos esses métodos, exceto {@link android.content.ContentProvider#onCreate() onCreate()}, 551 podem ser chamados por diversos encadeamentos simultaneamente, então devem ter encadeamento seguro. Para saber 552 mais sobre encadeamentos múltiplos, consulte o tópico 553 <a href="{@docRoot}guide/components/processes-and-threads.html"> 554 Processos e encadeamentos</a>. 555 </li> 556 <li> 557 Evite realizar longas operações em {@link android.content.ContentProvider#onCreate() 558 onCreate()}. Adie tarefas de inicialização até que sejam realmente necessárias. 559 A seção <a href="#OnCreate">Implementação do método onCreate()</a> 560 aborda o assunto mais detalhadamente. 561 </li> 562 <li> 563 Embora seja preciso implementar esses métodos, o código não precisa fazer nada além 564 de retornar o tipo de dados esperado. Por exemplo: você pode querer evitar que outros aplicativos 565 insiram dados em algumas tabelas. Para tanto, pode-se ignorar a chamada de 566 {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} e retornar 567 0. 568 </li> 569</ul> 570<h3 id="Query">Implementação do método query()</h3> 571<p> 572 573 O método {@link android.content.ContentProvider#query(Uri, String[], String, String[], String) 574 ContentProvider.query()} precisa retornar um objeto {@link android.database.Cursor} ou, se 575 falhar, gerar uma {@link java.lang.Exception}. Se você estiver usando um banco de dados SQLite 576 como armazenamento de dados, pode simplesmente retornar o {@link android.database.Cursor} retornado 577 por um dos métodos <code>query()</code> da classe {@link android.database.sqlite.SQLiteDatabase}. 578 Se a consulta não corresponder a nenhuma linha, deve-se retornar uma instância {@link android.database.Cursor} 579cujo método {@link android.database.Cursor#getCount()} retorne 0. 580 Deve-se retornar <code>null</code> somente se ocorrer um erro interno durante o processo de consulta. 581</p> 582<p> 583 Se você não estiver usando um banco de dados SQLite como modo de armazenamento de dados, use uma das subclasses concretas 584 de {@link android.database.Cursor}. Por exemplo, a classe {@link android.database.MatrixCursor} 585 implementa um cursor em que cada linha é uma matriz de {@link java.lang.Object}. Com essa classe, 586 use {@link android.database.MatrixCursor#addRow(Object[]) addRow()} para adicionar uma nova linha. 587</p> 588<p> 589 Lembre-se de que o sistema Android deve ser capaz de se comunicar com {@link java.lang.Exception} 590 entre limites de processo. O Android pode fazer isso para as exceções a seguir, que podem ser úteis 591 para tratar de erros de consulta: 592</p> 593<ul> 594 <li> 595 {@link java.lang.IllegalArgumentException} (é possível escolher lançar isso se o provedor 596 receber uma URI de conteúdo inválida) 597 </li> 598 <li> 599 {@link java.lang.NullPointerException} 600 </li> 601</ul> 602<h3 id="Insert">Implementação do método insert()</h3> 603<p> 604 O método {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} adiciona 605 uma nova linha à tabela apropriada usando os valores no argumento 606 {@link android.content.ContentValues}. Se um nome de coluna não estiver no argumento {@link android.content.ContentValues}, 607 talvez seja necessário fornecer um valor padrão para ele tanto no código do provedor quanto no esquema 608 do banco de dados. 609</p> 610<p> 611 Esse método deve retornar a URI de conteúdo da nova linha. Para construir isso, anexe o valor <code>_ID</code> 612 da nova linha (ou outra chave principal) à URI de conteúdo da tabela usando 613 {@link android.content.ContentUris#withAppendedId(Uri, long) withAppendedId()}. 614</p> 615<h3 id="Delete">Implementação do método delete()</h3> 616<p> 617 O método {@link android.content.ContentProvider#delete(Uri, String, String[]) delete()} 618 não precisa excluir linhas fisicamente do armazenamento de dados. Se você estiver usando um adaptador de sincronização 619 com o provedor, considere marcar uma linha excluída 620 com um sinalizador "excluir" em vez de removê-la totalmente. O adaptador de sincronização pode 621 verificar se há linhas excluídas e removê-las do servidor antes de excluí-las do provedor. 622</p> 623<h3 id="Update">Implementação do método update()</h3> 624<p> 625 O método {@link android.content.ContentProvider#update(Uri, ContentValues, String, String[]) 626 update()} usa o mesmo argumento {@link android.content.ContentValues} usado por 627 {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()}, e os 628 mesmos argumentos <code>selection</code> e <code>selectionArgs</code> usados por 629 {@link android.content.ContentProvider#delete(Uri, String, String[]) delete()} e 630 {@link android.content.ContentProvider#query(Uri, String[], String, String[], String) 631 ContentProvider.query()}. Isso deve permitir a reutilização do código entre esses métodos. 632</p> 633<h3 id="OnCreate">Implementação do método onCreate()</h3> 634<p> 635 O sistema Android chama {@link android.content.ContentProvider#onCreate() 636 onCreate()} quando inicia o provedor. Nesse método, devem-se realizar apenas tarefas de inicialização 637 de execução rápida e adiar a criação do banco de dados e o carregamento dos dados até que o provedor 638 receba efetivamente uma solicitação de acesso aos dados. Se houver tarefas longas 639 em {@link android.content.ContentProvider#onCreate() onCreate()}, a inicialização do provedor 640 ficará lenta. Consequentemente, isso diminuirá a rapidez da resposta do provedor 641 a outros aplicativos. 642</p> 643<p> 644 Por exemplo: se você estiver usando um banco de dados SQLite, é possível criar 645 um novo objeto {@link android.database.sqlite.SQLiteOpenHelper} 646 em {@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()} 647 e, em seguida, criar as tabelas SQL na primeira vez em que o banco de dados for aberto. Para facilitar isso, 648 a primeira vez que chamar {@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase 649 getWritableDatabase()}, ele automaticamente chamará 650 o método {@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase) 651 SQLiteOpenHelper.onCreate()} 652</p> 653<p> 654 Os dois fragmentos a seguir demonstram a interação 655 entre {@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()} 656 e {@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase) 657 SQLiteOpenHelper.onCreate()}. O primeiro fragmento é a implementação de 658 {@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()}. 659</p> 660<pre class="prettyprint"> 661public class ExampleProvider extends ContentProvider 662 663 /* 664 * Defines a handle to the database helper object. The MainDatabaseHelper class is defined 665 * in a following snippet. 666 */ 667 private MainDatabaseHelper mOpenHelper; 668 669 // Defines the database name 670 private static final String DBNAME = "mydb"; 671 672 // Holds the database object 673 private SQLiteDatabase db; 674 675 public boolean onCreate() { 676 677 /* 678 * Creates a new helper object. This method always returns quickly. 679 * Notice that the database itself isn't created or opened 680 * until SQLiteOpenHelper.getWritableDatabase is called 681 */ 682 mOpenHelper = new MainDatabaseHelper( 683 getContext(), // the application context 684 DBNAME, // the name of the database) 685 null, // uses the default SQLite cursor 686 1 // the version number 687 ); 688 689 return true; 690 } 691 692 ... 693 694 // Implements the provider's insert method 695 public Cursor insert(Uri uri, ContentValues values) { 696 // Insert code here to determine which table to open, handle error-checking, and so forth 697 698 ... 699 700 /* 701 * Gets a writeable database. This will trigger its creation if it doesn't already exist. 702 * 703 */ 704 db = mOpenHelper.getWritableDatabase(); 705 } 706} 707</pre> 708<p> 709 O próximo fragmento é a implementação de 710 {@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase) 711 SQLiteOpenHelper.onCreate()}, inclusive uma classe auxiliar: 712</p> 713<pre class="prettyprint"> 714... 715// A string that defines the SQL statement for creating a table 716private static final String SQL_CREATE_MAIN = "CREATE TABLE " + 717 "main " + // Table's name 718 "(" + // The columns in the table 719 " _ID INTEGER PRIMARY KEY, " + 720 " WORD TEXT" 721 " FREQUENCY INTEGER " + 722 " LOCALE TEXT )"; 723... 724/** 725 * Helper class that actually creates and manages the provider's underlying data repository. 726 */ 727protected static final class MainDatabaseHelper extends SQLiteOpenHelper { 728 729 /* 730 * Instantiates an open helper for the provider's SQLite data repository 731 * Do not do database creation and upgrade here. 732 */ 733 MainDatabaseHelper(Context context) { 734 super(context, DBNAME, null, 1); 735 } 736 737 /* 738 * Creates the data repository. This is called when the provider attempts to open the 739 * repository and SQLite reports that it doesn't exist. 740 */ 741 public void onCreate(SQLiteDatabase db) { 742 743 // Creates the main table 744 db.execSQL(SQL_CREATE_MAIN); 745 } 746} 747</pre> 748 749 750<!-- Implementing ContentProvider MIME Types --> 751<h2 id="MIMETypes">Implementação de tipos MIME de ContentProvider</h2> 752<p> 753 A classe {@link android.content.ContentProvider} tem dois métodos para retornar tipos MIME: 754</p> 755<dl> 756 <dt> 757 {@link android.content.ContentProvider#getType(Uri) getType()} 758 </dt> 759 <dd> 760 Um dos métodos obrigatórios que devem ser implementados em qualquer provedor. 761 </dd> 762 <dt> 763 {@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()} 764 </dt> 765 <dd> 766 Um método que deve ser implementado se o provedor fornecer arquivos. 767 </dd> 768</dl> 769<h3 id="TableMIMETypes">Tipos MIME para tabelas</h3> 770<p> 771 O método {@link android.content.ContentProvider#getType(Uri) getType()} retorna 772 uma {@link java.lang.String} em formato MIME que descreve o tipo de dados retornado pelo argumento 773 da URI de conteúdo. O argumento {@link android.net.Uri} pode ser um padrão em vez de uma URI específica; 774 nesse caso, deve-se retornar o tipo de dados associado a URIs de conteúdo que correspondam 775 ao padrão. 776</p> 777<p> 778 Para tipos de dados comuns como texto, HTML ou JPEG, 779 {@link android.content.ContentProvider#getType(Uri) getType()} deve retornar o tipo MIME 780 padrão daqueles dados. Há uma lista completa desse tipos de padrão 781 no site de 782 <a href="http://www.iana.org/assignments/media-types/index.htm">Tipos de mídia MIME IANA</a>. 783</p> 784<p> 785 Para obter URIs de conteúdo que apontam para uma linha ou linhas de dados de tabela, 786 {@link android.content.ContentProvider#getType(Uri) getType()} deve retornar 787 um tipo MIME no formato MIME específico do fornecedor do Android: 788</p> 789<ul> 790 <li> 791 Parte do tipo: <code>vnd</code> 792 </li> 793 <li> 794 Parte do subtipo: 795 <ul> 796 <li> 797 Se um padrão de URI se destinar a uma única linha: <code>android.cursor.<strong>item</strong>/</code> 798 </li> 799 <li> 800 Se um padrão de URI se destinar a mais de uma linha: <code>android.cursor.<strong>dir</strong>/</code> 801 </li> 802 </ul> 803 </li> 804 <li> 805 Parte específica do provedor: <code>vnd.<name></code>.<code><type></code> 806 <p> 807 Fornecem-se <code><name></code> e o <code><type></code>. 808 O valor <code><name></code> deve ser globalmente exclusivo 809 e o <code><type></code> deve ser exclusivo para o padrão de URI 810 correspondente. Uma boa escolha para <code><name></code> é o nome da empresa 811 ou alguma parte do nome do pacote do Android do seu aplicativo. Uma boa escolha para 812 <code><type></code> é uma string que identifique a tabela associada 813 à URI. 814 </p> 815 816 </li> 817</ul> 818<p> 819 Por exemplo: se a autoridade de um provedor 820 for <code>com.example.app.provider</code> e ele expuser uma tabela chamada 821 <code>table1</code>, o tipo MIME de diversas linhas em <code>table1</code> será: 822</p> 823<pre> 824vnd.android.cursor.<strong>dir</strong>/vnd.com.example.provider.table1 825</pre> 826<p> 827 Para uma única linha de <code>table1</code>, o tipo MIME será: 828</p> 829<pre> 830vnd.android.cursor.<strong>item</strong>/vnd.com.example.provider.table1 831</pre> 832<h3 id="FileMIMETypes">Tipos MIME para arquivos</h3> 833<p> 834 Se o provedor oferecer arquivos, implemente 835 {@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()}. 836 O método retorna uma matriz {@link java.lang.String} de tipos MIME para os arquivos que o provedor 837 pode retornar de uma dada URI de conteúdo. É preciso filtrar os tipos MIME oferecidos pelo argumento do filtro 838 de tipo MIME para retornar somente os tipos MIME que o cliente quer tratar. 839</p> 840<p> 841 Por exemplo: considere um provedor que ofereça imagens de foto como arquivos em formatos <code>.jpg</code>, 842 <code>.gif</code> e <code>.png</code>. 843 Se um aplicativo chama {@link android.content.ContentResolver#getStreamTypes(Uri, String) 844 ContentResolver.getStreamTypes()} com a string de filtro <code>image/*</code> (algo que 845 seja uma "imagem"), 846 o método {@link android.content.ContentProvider#getStreamTypes(Uri, String) 847 ContentProvider.getStreamTypes()} deve retornar a matriz: 848</p> 849<pre> 850{ "image/jpeg", "image/png", "image/gif"} 851</pre> 852<p> 853 Se o aplicativo estiver interessado apenas em arquivos <code>.jpg</code>, ele pode chamar 854 {@link android.content.ContentResolver#getStreamTypes(Uri, String) 855 ContentResolver.getStreamTypes()} com a string de filtro <code>*\/jpeg</code> 856 e {@link android.content.ContentProvider#getStreamTypes(Uri, String) 857 ContentProvider.getStreamTypes()} deve retornar: 858<pre> 859{"image/jpeg"} 860</pre> 861<p> 862 Se o provedor não oferecer nenhum tipo MIME solicitado na string de filtro, 863 {@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()} 864 deve retornar <code>null</code>. 865</p> 866 867 868<!-- Implementing a Contract Class --> 869<h2 id="ContractClass">Implementação de uma classe de contrato</h2> 870<p> 871 Uma classe de contrato é uma classe <code>public final</code> que contém definições de constantes para 872 os nomes de coluna das URIs, dos tipos MIME e de outros metadados que pertencem ao provedor. A classe 873 estabelece um contrato entre o provedor e outros aplicativos, garantindo que o provedor 874 possa ser corretamente acessado mesmo se houver mudanças nos valores atuais de URIs, nomes de coluna 875 etc. 876</p> 877<p> 878 As classes de contrato também ajudam os desenvolvedores porque normalmente suas constantes têm nomes mnemônicos e, 879 por isso, os desenvolvedores têm menos chance de usar valores incorretos para nomes de coluna ou URIs. Já que é 880 uma classe, ela pode conter documentação Javadoc. Ambientes de desenvolvimento integrados, como 881 o Eclipse, podem preencher automaticamente os nomes de constantes da classe de contrato e exibir Javadoc para 882 as constantes. 883</p> 884<p> 885 Os desenvolvedores não podem acessar o arquivo de classe da classe de contrato do aplicativo, mas podem 886 compilá-lo estaticamente no aplicativo a partir de um arquivo <code>.jar</code> que você fornece. 887</p> 888<p> 889 A classe {@link android.provider.ContactsContract} e classes aninhadas são exemplos 890 de classes de contrato. 891</p> 892<h2 id="Permissions">Implementação de permissões do Provedor de Conteúdo</h2> 893<p> 894 Permissões e acesso, para todos os aspectos do sistema Android, são descritos detalhadamente no 895 tópico <a href="{@docRoot}guide/topics/security/security.html">Permissões e segurança</a>. 896 O tópico <a href="{@docRoot}guide/topics/data/data-storage.html">Armazenamento de dados</a> também 897 descreve segurança e permissões em vigor para diversos tipos de armazenamento. 898 Em resumo, os pontos importantes são: 899</p> 900<ul> 901 <li> 902 Por padrão, arquivos de dados armazenados no armazenamento interno do dispositivo são privados em relação 903 ao aplicativo e ao provedor. 904 </li> 905 <li> 906 Os bancos de dados {@link android.database.sqlite.SQLiteDatabase} criados são privados em relação 907 ao aplicativo e ao provedor. 908 </li> 909 <li> 910 Por padrão, arquivos de dados salvos em armazenamentos externos são <em>públicos</em> 911 e <em>legíveis para todos</em>. Não é possível usar um provedor de conteúdo para restringir o acesso a arquivos 912 em um armazenamento externo porque outros aplicativos podem usar chamadas de outra API para lê-los e gravar neles. 913 </li> 914 <li> 915 O método que chama a abertura ou criação de arquivos ou bancos de dados SQLite no armazenamento 916 interno do seu dispositivo podem fornecer acesso de leitura e gravação a todos os outros aplicativos. Se você 917 usar um arquivo ou banco de dados interno como o repositório do provedor e conceder-lhe 918 acesso "legível para todos" ou "gravável por todos", as permissões definidas para o provedor 919 no manifesto não protegerão os dados. O acesso padrão de arquivos e bancos de dados 920 no armazenamento interno é "privado" e, para o repositório do provedor, não é recomendável alterar isso. 921 </li> 922</ul> 923<p> 924 Se você deseja usar permissões do provedor de conteúdo para controlar o acesso aos dados, deve 925 armazená-los em arquivos internos, bancos de dados SQLite ou em "nuvem" (por exemplo, 926 em um servidor remoto) e mantê-los privados em relação ao aplicativo. 927</p> 928<h3>Implementação de permissões</h3> 929<p> 930 Todos os aplicativos podem ler ou gravar no provedor, mesmo que os dados em questão 931 sejam privados porque, por padrão, o provedor não tem permissões definidas. Para mudar isso, 932 defina permissões do provedor no arquivo de manifesto por meio de atributos ou elementos 933 filho do elemento <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 934 <provider></a></code>. É possível definir permissões que se apliquem a todo o provedor, 935 a determinadas tabelas, a registros específicos ou a todos os três. 936</p> 937<p> 938 As permissões são definidas para o provedor com um ou mais 939 elementos <code><a href="{@docRoot}guide/topics/manifest/permission-element.html"> 940 <permission></a></code> no arquivo de manifesto. Para tornar 941 a permissão exclusiva para o provedor, use escopo de estilo Java para 942 o atributo <code><a href="{@docRoot}guide/topics/manifest/permission-element.html#nm"> 943 android:name</a></code>. Por exemplo: nomeie a permissão de leitura 944 <code>com.example.app.provider.permission.READ_PROVIDER</code>. 945 946</p> 947<p> 948 A lista a seguir descreve o escopo de permissões do provedor, começando 949 com as permissões que se aplicam a todo o provedor e seguindo para as mais específicas. 950 Permissões mais específicas têm precedência sobre as de escopo maior: 951</p> 952<dl> 953 <dt> 954 Única permissão de leitura e gravação no nível do provedor 955 </dt> 956 <dd> 957 Uma permissão que controla os acessos de leitura e gravação a todo o provedor, especificada 958 com o atributo <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn"> 959 android:permission</a></code> 960 do elemento <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 961 <provider></a></code>. 962 </dd> 963 <dt> 964 Permissões de leitura e gravação separadas no nível do provedor 965 </dt> 966 <dd> 967 Uma permissão de leitura e uma permissão de gravação para todo o provedor. São especificadas 968 com os atributos <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#rprmsn"> 969 android:readPermission</a></code> 970 e <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#wprmsn"> 971 android:writePermission</a></code> 972 do elemento <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 973 <provider></a></code>. Elas têm precedência sobre a permissão exigida 974 por <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn"> 975 android:permission</a></code>. 976 </dd> 977 <dt> 978 Permissão no nível do caminho 979 </dt> 980 <dd> 981 Permissão de leitura, gravação ou leitura/gravação para uma URI de conteúdo no provedor. Especifica-se 982 cada URI que se deseja controlar 983 com um elemento filho <code><a href="{@docRoot}guide/topics/manifest/path-permission-element.html"> 984 <path-permission></a></code> 985 do elemento <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 986 <provider></a></code>. Para cada URI de conteúdo, pode-se especificar 987 uma permissão de leitura/gravação, uma permissão de leitura, uma permissão de gravação ou as três. As permissões 988 de leitura e gravação têm precedência sobre a permissão de leitura/gravação. Além disso, 989 permissões no nível do caminho têm precedência sobre permissões no nível do provedor. 990 </dd> 991 <dt> 992 Permissão temporária 993 </dt> 994 <dd> 995 Nível de permissão que concede acesso temporário a um aplicativo mesmo que ele 996 não tenha as permissões normalmente exigidas. O recurso de acesso 997 temporário reduz o número de permissões que um aplicativo deve solicitar 998 no manifesto. Ao ativar permissões temporárias, os únicos aplicativos que precisam de 999 permissões "permanentes" para seu provedor são os que têm acesso contínuo 1000 a todos os dados. 1001 <p> 1002 Considere as permissões necessárias para implementar um provedor e um aplicativo de e-mail 1003 ao permitir um aplicativo visualizador de imagens externas para exibir anexos de fotos 1004 do provedor. Para conceder o acesso necessário ao visualizador de imagens sem as permissões exigidas, 1005 configure permissões temporárias das URIs de conteúdo de fotos. Projete o aplicativo de e-mail 1006 para que, quando o usuário quiser exibir uma foto, o aplicativo envie uma intenção 1007 com a URI de conteúdo da foto e sinalizadores de permissão para o visualizador de imagens. O visualizador de imagens poderá, 1008 então, consultar o provedor de e-mail para recuperar a foto mesmo que ele 1009 não tenha a permissão normal de leitura para o provedor. 1010 </p> 1011 <p> 1012 Para ativar permissões temporárias, defina 1013 o atributo <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn"> 1014 android:grantUriPermissions</a></code> 1015 do elemento <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 1016 <provider></a></code> ou adicione um ou mais 1017 elementos filhos <code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html"> 1018 <grant-uri-permission></a></code> 1019 ao elemento <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 1020 <provider></a></code>. Se forem usadas permissões temporárias, será necessário chamar 1021 {@link android.content.Context#revokeUriPermission(Uri, int) 1022 Context.revokeUriPermission()} sempre que remover suporte a URI de conteúdo do 1023 provedor, e a URI de conteúdo será associada a uma permissão temporária. 1024 </p> 1025 <p> 1026 O valor do atributo determina o nível de acessibilidade do provedor. 1027 Se o atributo estiver definido como <code>true</code>, o sistema concederá permissão 1028 temporária a todo o provedor, sobrepondo todas as outras permissões exigidas 1029 pelas permissões no nível do provedor ou no nível do caminho. 1030 </p> 1031 <p> 1032 Se esse sinalizador estiver definido como <code>false</code>, será necessário adicionar 1033 elementos filhos <code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html"> 1034 <grant-uri-permission></a></code> 1035 ao elemento <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 1036 <provider></a></code>. Cada elemento filho especifica a URI ou URIs 1037 de conteúdo para as quais o acesso temporário é concedido. 1038 </p> 1039 <p> 1040 Para delegar o acesso temporário a um aplicativo, a intenção deve conter 1041 os sinalizadores {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}, 1042 {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION} ou ambos. Eles 1043 são definidos com o método {@link android.content.Intent#setFlags(int) setFlags()}. 1044 </p> 1045 <p> 1046 Se o atributo <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn"> 1047 android:grantUriPermissions</a></code> não estiver presente, presume-se que ele seja 1048 <code>false</code>. 1049 </p> 1050 </dd> 1051</dl> 1052 1053 1054 1055<!-- The Provider Element --> 1056<h2 id="ProviderElement">O elemento <provider></h2> 1057<p> 1058 Como os componentes {@link android.app.Activity} e {@link android.app.Service}, 1059 a subclasse de {@link android.content.ContentProvider} 1060 deve ser definida no arquivo de manifesto do aplicativo 1061 pelo elemento <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 1062 <provider></a></code>. O sistema Android obtém as seguintes informações 1063 do elemento: 1064<dl> 1065 <dt> 1066 Autoridade 1067 (<a href="{@docRoot}guide/topics/manifest/provider-element.html#auth">{@code 1068 android:authorities}</a>) 1069 </dt> 1070 <dd> 1071 Nomes simbólicos que identificam todo o provedor dentro do sistema. Esse 1072 atributo é descrito com mais detalhes na seção 1073 <a href="#ContentURI">Projeto de URIs de conteúdo</a>. 1074 </dd> 1075 <dt> 1076 Nome da classe do provedor 1077 (<code> 1078<a href="{@docRoot}guide/topics/manifest/provider-element.html#nm">android:name</a> 1079 </code>) 1080 </dt> 1081 <dd> 1082 A classe que implementa {@link android.content.ContentProvider}. Esta classe é 1083 abordada com mais detalhes na seção 1084 <a href="#ContentProvider">Implementação da classe ContentProvider</a>. 1085 </dd> 1086 <dt> 1087 Permissões 1088 </dt> 1089 <dd> 1090 Atributos que especificam as permissões que outros aplicativos precisam ter para acessar 1091 os dados do provedor: 1092 <ul> 1093 <li> 1094 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn"> 1095 android:grantUriPermssions</a></code>: Sinalizador de permissão temporária. 1096 </li> 1097 <li> 1098 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn"> 1099 android:permission</a></code>: Permissão única de leitura/gravação por todo o provedor. 1100 </li> 1101 <li> 1102 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#rprmsn"> 1103 android:readPermission</a></code>: Permissão de leitura por todo o provedor. 1104 </li> 1105 <li> 1106 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#wprmsn"> 1107 android:writePermission</a></code>: Permissão de gravação por todo o provedor. 1108 </li> 1109 </ul> 1110 <p> 1111 As permissões e os atributos correspondentes são abordados com mais 1112 detalhes na seção 1113 <a href="#Permissions">Implementação de permissões do Provedor de conteúdo</a>. 1114 </p> 1115 </dd> 1116 <dt> 1117 Atributos de início e controle 1118 </dt> 1119 <dd> 1120 Esses atributos determinam como e quando o sistema Android inicia o provedor, 1121 as características do processo do provedor e outras configurações de tempo de execução: 1122 <ul> 1123 <li> 1124 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#enabled"> 1125 android:enabled</a></code>: sinalizador que permite ao sistema iniciar o provedor. 1126 </li> 1127 <li> 1128 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#exported"> 1129 android:exported</a></code>: sinalizador que permite a outros aplicativos usarem esse provedor. 1130 </li> 1131 <li> 1132 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#init"> 1133 android:initOrder</a></code>: a ordem em que esse provedor deve ser iniciado, 1134 relativa a outros provedores no mesmo processo. 1135 </li> 1136 <li> 1137 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#multi"> 1138 android:multiProcess</a></code>: sinalizador que permite ao sistema iniciar o provedor 1139 no mesmo processo que o cliente chama. 1140 </li> 1141 <li> 1142 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#proc"> 1143 android:process</a></code>: o nome do processo em que o provedor deve 1144 ser executado. 1145 </li> 1146 <li> 1147 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#sync"> 1148 android:syncable</a></code>: sinalizador que indica que os dados do provedor devem ser 1149 sincronizados com os dados em um servidor. 1150 </li> 1151 </ul> 1152 <p> 1153 os atributos estão totalmente documentados no tópico do guia de desenvolvimento 1154 do elemento 1155 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 1156 <provider></a></code>. 1157 </p> 1158 </dd> 1159 <dt> 1160 Atributos informacionais 1161 </dt> 1162 <dd> 1163 Um ícone e um rótulo opcionais para o provedor: 1164 <ul> 1165 <li> 1166 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#icon"> 1167 android:icon</a></code>: um recurso desenhável contendo um ícone para o provedor. 1168 O ícone aparece próximo ao rótulo do provedor na lista de aplicativos 1169 em <em>Configurações</em> > <em>Aplicativos</em> > <em>Todos</em>. 1170 </li> 1171 <li> 1172 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#label"> 1173 android:label</a></code>: um rótulo informacional que descreve o provedor, 1174 seus dados ou ambos. O rótulo aparece na lista de aplicativos 1175 em <em>Configurações</em> > <em>Aplicativos</em> > <em>Todos</em>. 1176 </li> 1177 </ul> 1178 <p> 1179 Os atributos estão totalmente documentados no tópico do guia de desenvolvimento 1180 do elemento <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> 1181 <provider></a></code>. 1182 </p> 1183 </dd> 1184</dl> 1185 1186<!-- Intent Access --> 1187<h2 id="Intents">Intenções e acesso a dados</h2> 1188<p> 1189 Os aplicativos podem acessar um provedor de conteúdo indiretamente com uma {@link android.content.Intent}. 1190 O aplicativo não chama nenhum método de {@link android.content.ContentResolver} 1191 nem de {@link android.content.ContentProvider}. Em vez disso, ele envia uma intenção que inicia uma atividade, 1192 que, em geral, é parte do aplicativo do próprio provedor. A atividade de destino é responsável 1193 pela recuperação e exibição dos dados na IU. Conforme a ação na intenção, 1194 a atividade de destino também pode levar o usuário a realizar modificações nos dados do provedor. 1195 Uma intenção também pode conter dados "extras" que a atividade de destino exibe 1196 na IU; o usuário terá, então, a opção de alterar esses dados antes de usá-los para modificar 1197 os dados no provedor. 1198</p> 1199<p> 1200 1201</p> 1202<p> 1203 Pode ser necessário usar acesso de intenções para ajudar a garantir a integridade deles. O provedor pode depender 1204 de ter dados inseridos, atualizados e excluídos de acordo com a lógica de negócio rigorosamente definida. Se 1205 for o caso, a permissão para que outros aplicativos modifiquem os dados diretamente pode levar 1206 à invalidação dos dados. Se você deseja que os desenvolvedores usem o acesso via intenções, certifique-se de documentá-lo minuciosamente. 1207 Explique por que o acesso via intenções pela IU do aplicativo é melhor do que tentar 1208 modificar os dados com códigos. 1209</p> 1210<p> 1211 O tratamento das intenções recebidas com a intenção de modificar os dados do provedor não é diferente 1212 de tratar de outras intenções. Para saber mais sobre o uso de intenções, leia o tópico 1213 <a href="{@docRoot}guide/components/intents-filters.html">Intenções e filtros de intenções</a>. 1214</p> 1215