1 page.title=Preceitos do provedor de contedo 2 @jd:body 3 <div id="qv-wrapper"> 4 <div id="qv"> 5 <!-- In this document --> 6 <h2>Neste documento</h2> 7 <ol> 8 <li> 9 <a href="#Basics">Viso geral</a> 10 <ol> 11 <li> 12 <a href="#ClientProvider">Acesso a um provedor</a> 13 </li> 14 <li> 15 <a href="#ContentURIs">URIs de contedo</a> 16 </li> 17 </ol> 18 </li> 19 <li> 20 <a href="#SimpleQuery">Recuperao de dados do provedor</a> 21 <ol> 22 <li> 23 <a href="#RequestPermissions">Solicitao de permisso de acesso para leitura</a> 24 </li> 25 <li> 26 <a href="#Query">Construo da consulta</a> 27 </li> 28 <li> 29 <a href="#DisplayResults">Exibio dos resultados da consulta</a> 30 </li> 31 <li> 32 <a href="#GettingResults">Obteno de dados de resultados da consulta</a> 33 </li> 34 </ol> 35 </li> 36 <li> 37 <a href="#Permissions">Permisses do provedor de contedo</a> 38 </li> 39 <li> 40 <a href="#Modifications">Insero, atualizao e excluso de dados</a> 41 <ol> 42 <li> 43 <a href="#Inserting">Insero de dados</a> 44 </li> 45 <li> 46 <a href="#Updating">Atualizao de dados</a> 47 </li> 48 <li> 49 <a href="#Deleting">Excluso de dados</a> 50 </li> 51 </ol> 52 </li> 53 <li> 54 <a href="#DataTypes">Tipos de dados do provedor</a> 55 </li> 56 <li> 57 <a href="#AltForms">Formas alternativas de acesso ao provedor</a> 58 <ol> 59 <li> 60 <a href="#Batch">Acesso em lote</a> 61 </li> 62 <li> 63 <a href="#Intents">Acesso a dados via intenes</a> 64 </li> 65 </ol> 66 </li> 67 <li> 68 <a href="#ContractClasses">Classes de contrato</a> 69 </li> 70 <li> 71 <a href="#MIMETypeReference">Referncia de tipo MIME</a> 72 </li> 73 </ol> 74 75 <!-- Key Classes --> 76 <h2>Classes principais</h2> 77 <ol> 78 <li> 79 {@link android.content.ContentProvider} 80 </li> 81 <li> 82 {@link android.content.ContentResolver} 83 </li> 84 <li> 85 {@link android.database.Cursor} 86 </li> 87 <li> 88 {@link android.net.Uri} 89 </li> 90 </ol> 91 92 <!-- Related Samples --> 93 <h2>Exemplos relacionados</h2> 94 <ol> 95 <li> 96 <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List2.html"> 97 Cursor (Pessoas)</a> 98 </li> 99 <li> 100 <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List7.html"> 101 Cursor (Telefones)</a> 102 </li> 103 </ol> 104 105 <!-- See also --> 106 <h2>Veja tambm</h2> 107 <ol> 108 <li> 109 <a href="{@docRoot}guide/topics/providers/content-provider-creating.html"> 110 Criao de um Provedor de contedo</a> 111 </li> 112 <li> 113 <a href="{@docRoot}guide/topics/providers/calendar-provider.html"> 114 Provedor de agenda</a> 115 </li> 116 </ol> 117 </div> 118 </div> 119 120 <!-- Intro paragraphs --> 121 <p> 122 O provedor de contedo gerencia o acesso a um repositrio central de dados. Um provedor 123 parte de um aplicativo do Android, que, em geral, fornece a prpria IU para trabalhar com 124 os dados. Contudo, provedores de contedo destinam-se principalmente ao uso por outros 125 aplicativos, que acessam o provedor usando um objeto cliente do provedor. Juntos, provedores 126 e clientes do provedor oferecem interface padronizada e consistente para dados que tambm lidam com 127 comunicao em processos internos e garantem acesso a dados. 128 </p> 129 <p> 130 Esse tpico descreve os conceitos bsicos do seguinte: 131 </p> 132 <ul> 133 <li>Como os provedores de contedo funcionam.</li> 134 <li>A API usada para recuperar dados de um provedor de contedo.</li> 135 <li>A API usada para inserir, atualizar ou excluir dados em um provedor de contedo.</li> 136 <li>Outros recursos de API que facilitam o trabalho com provedores.</li> 137 </ul> 138 139 <!-- Basics --> 140 <h2 id="Basics">Viso geral</h2> 141 <p> 142 O provedor de contedo apresenta dados a aplicativos externos na forma de uma ou mais tabelas 143 similares s tabelas encontradas em um banco de dados relacional. Uma linha representa uma instncia de algum tipo 144 de dados que o provedor coleta e cada coluna na linha representa uma parte individual de 145 dados coletados por uma instncia. 146 </p> 147 <p> 148 Por exemplo: um dos provedores embutidos na plataforma do Android o dicionrio do usurio, que 149 armazena as grafias de palavras incomuns que o usurio deseja manter. A tabela 1 ilustra 150 como podem ser os dados nesta tabela do provedor: 151 </p> 152 <p class="table-caption"> 153 <strong>Tabela 1:</strong> Tabela de dicionrio do usurio de exemplo. 154 </p> 155 <table id="table1" style="width: 50%;"> 156 <tr> 157 <th style="width:20%" align="center" scope="col">palavra</th> 158 <th style="width:20%" align="center" scope="col">id do aplicativo</th> 159 <th style="width:20%" align="center" scope="col">frequncia</th> 160 <th style="width:20%" align="center" scope="col">localidade</th> 161 <th style="width:20%" align="center" scope="col">_ID</th> 162 </tr> 163 <tr> 164 <td align="center" scope="row">reduodomapa</td> 165 <td align="center">usurio1</td> 166 <td align="center">100</td> 167 <td align="center">en_US</td> 168 <td align="center">1</td> 169 </tr> 170 <tr> 171 <td align="center" scope="row">pr-compilador</td> 172 <td align="center">usurio14</td> 173 <td align="center">200</td> 174 <td align="center">fr_FR</td> 175 <td align="center">2</td> 176 </tr> 177 <tr> 178 <td align="center" scope="row">applet</td> 179 <td align="center">usurio2</td> 180 <td align="center">225</td> 181 <td align="center">fr_CA</td> 182 <td align="center">3</td> 183 </tr> 184 <tr> 185 <td align="center" scope="row">const</td> 186 <td align="center">usurio1</td> 187 <td align="center">255</td> 188 <td align="center">pt_BR</td> 189 <td align="center">4</td> 190 </tr> 191 <tr> 192 <td align="center" scope="row">int</td> 193 <td align="center">usurio5</td> 194 <td align="center">100</td> 195 <td align="center">en_UK</td> 196 <td align="center">5</td> 197 </tr> 198 </table> 199 <p> 200 Na tabela 1, cada linha representa uma instncia de uma palavra que pode no ser 201 encontrada em um dicionrio comum. Cada coluna representa alguns dados dessa palavra, como 202 a localidade em que foi encontrada pela primeira vez. Os cabealhos da coluna so nomes de coluna armazenados 203 no provedor. Para consultar a localidade de uma linha, consulte a sua coluna <code>locale</code>. Para 204 esse provedor, a coluna <code>_ID</code> serve como uma coluna de "chave principal" que 205 o provedor mantm automaticamente. 206 </p> 207 <p class="note"> 208 <strong>Observao:</strong> os provedores no precisam ter uma chave principal e no precisam 209 usar <code>_ID</code> como o nome de coluna de uma chave principal se uma for apresentada. Contudo, 210 se voc deseja agrupar dados de um provedor em um {@link android.widget.ListView}, um dos 211 nomes de coluna deve ser <code>_ID</code>. Esse requisito explicado com mais detalhes 212 na seo <a href="#DisplayResults">Exibio dos resultados da consulta</a>. 213 </p> 214 <h3 id="ClientProvider">Acesso a um provedor</h3> 215 <p> 216 Os aplicativos acessam dados a partir de um provedor de contedo 217 com um objeto cliente {@link android.content.ContentResolver}. Esse objeto tem mtodos que chamam 218 mtodos de nome idntico no objeto do provedor, uma instncia de uma das subclasses 219 concretas de {@link android.content.ContentProvider}. 220 Os mtodos {@link android.content.ContentResolver} fornecem as funes bsicas 221 do "CRUD" (criar, recuperar, atualizar e excluir) de armazenamento persistente. 222 </p> 223 <p> 224 O objeto {@link android.content.ContentResolver} no processo do aplicativo 225 cliente e o objeto {@link android.content.ContentProvider} no aplicativo que possui 226 o provedor lidam automaticamente com a comunicao de processos internos. 227 {@link android.content.ContentProvider} tambm age como uma camada de abstrao entre 228 ser repositrio de dados e a aparncia externa de dados na forma de tabelas. 229 </p> 230 <p class="note"> 231 <strong>Observao:</strong> para acessar um provedor, o aplicativo normalmente precisa solicitar permisses 232 especficas no arquivo de manifesto. Isso descrito com mais detalhes na seo 233 <a href="#Permissions">Permisses do provedor de contedo</a>. 234 </p> 235 <p> 236 Por exemplo: para obter uma lista das palavras e respectivas localidades do Provedor de dicionrio do usurio, 237 chama-se {@link android.content.ContentResolver#query ContentResolver.query()}. 238 O mtodo {@link android.content.ContentResolver#query query()} chama 239 o mtodo {@link android.content.ContentProvider#query ContentProvider.query()} definido pelo 240 Provedor de dicionrio do usurio. As linhas de cdigo a seguir exibem 241 uma chamada {@link android.content.ContentResolver#query ContentResolver.query()}: 242 <p> 243 <pre> 244 // Queries the user dictionary and returns results 245 mCursor = getContentResolver().query( 246 UserDictionary.Words.CONTENT_URI, // The content URI of the words table 247 mProjection, // The columns to return for each row 248 mSelectionClause // Selection criteria 249 mSelectionArgs, // Selection criteria 250 mSortOrder); // The sort order for the returned rows 251 </pre> 252 <p> 253 A tabela 2 mostra como os argumentos para 254 {@link android.content.ContentResolver#query 255 query(Uri,projection,selection,selectionArgs,sortOrder)} correspondem a uma declarao SQL SELECT: 256 </p> 257 <p class="table-caption"> 258 <strong>Tabela 2:</strong> Query() comparada consulta SQL. 259 </p> 260 <table id="table2" style="width: 75%;"> 261 <tr> 262 <th style="width:25%" align="center" scope="col">Argumento query()</th> 263 <th style="width:25%" align="center" scope="col">Palavra-chave/parmetro de SELEO</th> 264 <th style="width:50%" align="center" scope="col">Observaes</th> 265 </tr> 266 <tr> 267 <td align="center"><code>Uri</code></td> 268 <td align="center"><code>FROM <em>table_name</em></code></td> 269 <td><code>Uri</code> mapeia para a tabela no provedor chamado <em>table_name</em>.</td> 270 </tr> 271 <tr> 272 <td align="center"><code>projection</code></td> 273 <td align="center"><code><em>col,col,col,...</em></code></td> 274 <td> 275 <code>projection</code> uma matriz de colunas que devem ser includas para cada linha 276 recuperada. 277 </td> 278 </tr> 279 <tr> 280 <td align="center"><code>selection</code></td> 281 <td align="center"><code>WHERE <em>col</em> = <em>value</em></code></td> 282 <td><code>selection</code> especifica o critrio para a seleo de linhas.</td> 283 </tr> 284 <tr> 285 <td align="center"><code>selectionArgs</code></td> 286 <td align="center"> 287 (No exatamente equivalente. Argumentos de seleo substituem marcadores de posio <code>?</code> 288 na clusula de seleo.) 289 </td> 290 </tr> 291 <tr> 292 <td align="center"><code>sortOrder</code></td> 293 <td align="center"><code>ORDER BY <em>col,col,...</em></code></td> 294 <td> 295 <code>sortOrder</code> especifica a ordem em que as linhas aparecem 296 no {@link android.database.Cursor} retornado. 297 </td> 298 </tr> 299 </table> 300 <h3 id="ContentURIs">URIs de contedo</h3> 301 <p> 302 <strong>URI de contedo</strong> uma URI que identifica dados em um provedor. URIs de contedo 303 contm o nome simblico de todo o provedor (sua <strong>autoridade</strong>) 304 e um nome que aponta para uma tabela (um <strong>caminho</strong>). Ao chamar 305 um mtodo cliente para acessar uma tabela em um provedor, a URI de contedo da tabela 306 um dos argumentos. 307 </p> 308 <p> 309 Nas linhas de cdigo anteriores, a constante 310 {@link android.provider.UserDictionary.Words#CONTENT_URI} contm a URI de contedo 311 da tabela de "palavras" do dicionrio do usurio. O objeto {@link android.content.ContentResolver} 312 analisa a autoridade da URI e usa-na para "determinar" o provedor 313 comparando a autoridade a uma tabela de provedores conhecidos do sistema. 314 O {@link android.content.ContentResolver} pode, ento, enviar os argumentos da consulta ao provedor 315 correto. 316 </p> 317 <p> 318 O {@link android.content.ContentProvider} usa o caminho que parte da URI de contedo para escolher 319 a tabela para acessar. Os provedores normalmente tm um <strong>caminho</strong> para cada tabela exposta. 320 </p> 321 <p> 322 Nas linhas de cdigo anteriores, a URI completa da tabela de "palavras" : 323 </p> 324 <pre> 325 content://user_dictionary/words 326 </pre> 327 <p> 328 onde a string <code>user_dictionary</code> a autoridade do provedor e 329 a string <code>words</code> o caminho da tabela. A string 330 <code>content://</code> (o <strong>esquema</strong>) est sempre presente 331 e identifica isso como uma URI de contedo. 332 </p> 333 <p> 334 Muitos provedores permitem acesso a uma nica linha em uma tabela, por meio da anexao do valor de um ID 335 no fim da URI. Por exemplo, para recuperar uma linha em que <code>_ID</code> seja 336 <code>4</code> do dicionrio do usurio, possvel usar essa URI de contedo: 337 </p> 338 <pre> 339 Uri singleUri = ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI,4); 340 </pre> 341 <p> 342 Normalmente usam-se valores de ID ao recuperar um conjunto de linhas e, em seguida, necessrio atualizar ou excluir 343 uma delas. 344 </p> 345 <p class="note"> 346 <strong>Observao:</strong> as classes {@link android.net.Uri} e {@link android.net.Uri.Builder} 347 contm mtodos convenientes para a construo de objetos de URI bem formados a partir de strings. 348 As {@link android.content.ContentUris} contm mtodos conveniente para anexar valores de ID 349 a uma URI. O fragmento anterior usa {@link android.content.ContentUris#withAppendedId 350 withAppendedId()} para anexar um ID URI de contedo UserDictionary. 351 </p> 352 353 354 <!-- Retrieving Data from the Provider --> 355 <h2 id="SimpleQuery">Recuperao de dados pelo Provedor</h2> 356 <p> 357 Esta seo descreve como recuperar dados de um provedor usando o Provedor de dicionrio do usurio 358 como um exemplo. 359 </p> 360 <p class="note"> 361 Por uma questo de clareza, os fragmentos de cdigo nesta seo chamam 362 {@link android.content.ContentResolver#query ContentResolver.query()} no "encadeamento da IU". 363 No cdigo atual, contudo, deve-se realizar consultas assincronamente em um encadeamento separado. Um modo de faz-lo 364 usar a classe {@link android.content.CursorLoader}, descrita 365 com mais detalhes no guia <a href="{@docRoot}guide/components/loaders.html"> 366 Carregadores</a>. Alm disso, as linhas de cdigo so somente fragmentos no mostram um aplicativo 367 completo. 368 </p> 369 <p> 370 Para recuperar dados de um provedor, siga essas etapas bsicas: 371 </p> 372 <ol> 373 <li> 374 Solicite a permisso de acesso para leitura para um provedor. 375 </li> 376 <li> 377 Defina o cdigo que envia uma consulta ao provedor. 378 </li> 379 </ol> 380 <h3 id="RequestPermissions">Solicitao de permisso de acesso para leitura</h3> 381 <p> 382 Para recuperar dados de um provedor, o aplicativo precisa de "permisso de acesso a leitura" 383 para o provedor. No possvel solicitar essa permisso em tempo de execuo. Em vez disso, deve-se especificar 384 que precisa dessa permisso no manifesto com o elemento 385 <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> 386 e o nome da permisso exata definida 387 pelo provedor. Ao especificar esse elemento no manifesto, voc est efetivamente "solicitando" essa 388 permisso para o aplicativo. Quando usurios instalam seu aplicativo, eles concedem essa solicitao 389 implicitamente. 390 </p> 391 <p> 392 Para encontrar o nome exato da permisso de acesso para leitura do provedor que est usando, bem 393 como os nomes de outras permisses de acesso usadas pelo provedor, consulte a documentao 394 do provedor. 395 </p> 396 <p> 397 O papel das permisses no acesso a provedores descrito com mais detalhes na seo 398 <a href="#Permissions">Permisses do provedor de contedo</a>. 399 </p> 400 <p> 401 O Provedor de Dicionrio do Usurio define a permisso 402 <code>android.permission.READ_USER_DICTIONARY</code> no arquivo de manifesto, portanto, se um 403 aplicativo quiser ler pelo provedor, deve solicitar essa permisso. 404 </p> 405 <!-- Constructing the query --> 406 <h3 id="Query">Construo da consulta</h3> 407 <p> 408 A prxima etapa na recuperao de dados de um provedor construir uma consulta. Este primeiro fragmento 409 define algumas variveis para acessar o Provedor de Dicionrio do Usurio: 410 </p> 411 <pre class="prettyprint"> 412 413 // A "projection" defines the columns that will be returned for each row 414 String[] mProjection = 415 { 416 UserDictionary.Words._ID, // Contract class constant for the _ID column name 417 UserDictionary.Words.WORD, // Contract class constant for the word column name 418 UserDictionary.Words.LOCALE // Contract class constant for the locale column name 419 }; 420 421 // Defines a string to contain the selection clause 422 String mSelectionClause = null; 423 424 // Initializes an array to contain selection arguments 425 String[] mSelectionArgs = {""}; 426 427 </pre> 428 <p> 429 O prximo fragmento mostra como usar 430 {@link android.content.ContentResolver#query ContentResolver.query()} usando o Provedor de 431 Dicionrio do Usurio como exemplo. Uma consulta cliente do provedor similar a uma consulta SQL e contm um 432 conjunto de colunas para retornar, um conjunto de critrios de seleo e uma classificao ordenada. 433 </p> 434 <p> 435 O conjunto de colunas que a consulta deve retornar chamado de <strong>projeo</strong> 436 (a varivel <code>mProjection</code>). 437 </p> 438 <p> 439 A expresso que especifica as linhas a recuperar dividida em uma clusula de seleo 440 e em argumentos de seleo. A clusula de seleo uma combinao de expresses lgicas e booleanas 441 e nomes e valores de colunas (a varivel <code>mSelectionClause</code>). Ao especificar 442 o parmetro <code>?</code> substituvel em vez de um valor, o mtodo da consulta recupera o valor 443 da matriz de argumentos de seleo (a varivel <code>mSelectionArgs</code>). 444 </p> 445 <p> 446 No prximo fragmento, se o usurio no inserir nenhuma palavra, a clusula de seleo ser definida como 447 <code>null</code> e a consulta retornar todas as palavras no provedor. Se o usurio inserir 448 uma palavra, a clusula de seleo ser definida como <code>UserDictionary.Words.WORD + " = ?"</code> 449 e o primeiro elemento da matriz de argumentos de seleo definida como a palavra que o usurio inserir. 450 </p> 451 <pre class="prettyprint"> 452 /* 453 * This defines a one-element String array to contain the selection argument. 454 */ 455 String[] mSelectionArgs = {""}; 456 457 // Gets a word from the UI 458 mSearchString = mSearchWord.getText().toString(); 459 460 // Remember to insert code here to check for invalid or malicious input. 461 462 // If the word is the empty string, gets everything 463 if (TextUtils.isEmpty(mSearchString)) { 464 // Setting the selection clause to null will return all words 465 mSelectionClause = null; 466 mSelectionArgs[0] = ""; 467 468 } else { 469 // Constructs a selection clause that matches the word that the user entered. 470 mSelectionClause = UserDictionary.Words.WORD + " = ?"; 471 472 // Moves the user's input string to the selection arguments. 473 mSelectionArgs[0] = mSearchString; 474 475 } 476 477 // Does a query against the table and returns a Cursor object 478 mCursor = getContentResolver().query( 479 UserDictionary.Words.CONTENT_URI, // The content URI of the words table 480 mProjection, // The columns to return for each row 481 mSelectionClause // Either null, or the word the user entered 482 mSelectionArgs, // Either empty, or the string the user entered 483 mSortOrder); // The sort order for the returned rows 484 485 // Some providers return null if an error occurs, others throw an exception 486 if (null == mCursor) { 487 /* 488 * Insert code here to handle the error. Be sure not to use the cursor! You may want to 489 * call android.util.Log.e() to log this error. 490 * 491 */ 492 // If the Cursor is empty, the provider found no matches 493 } else if (mCursor.getCount() < 1) { 494 495 /* 496 * Insert code here to notify the user that the search was unsuccessful. This isn't necessarily 497 * an error. You may want to offer the user the option to insert a new row, or re-type the 498 * search term. 499 */ 500 501 } else { 502 // Insert code here to do something with the results 503 504 } 505 </pre> 506 <p> 507 Essa consulta anloga declarao SQL: 508 </p> 509 <pre> 510 SELECT _ID, word, locale FROM words WHERE word = <userinput> ORDER BY word ASC; 511 </pre> 512 <p> 513 Nesta declarao SQL, os nomes de coluna reais so usados no lugar de constantes de classes de contrato. 514 </p> 515 <h4 id="Injection">Proteo contra inseres mal-intencionadas</h4> 516 <p> 517 Se os dados gerenciados pelo provedor de contedo estiverem em um banco de dados SQL, inclusive dados no confiveis 518 externos nas declaraes SQL brutas, existe a possibilidade de haver uma injeo de SQL. 519 </p> 520 <p> 521 Considere esta clusula de seleo: 522 </p> 523 <pre> 524 // Constructs a selection clause by concatenating the user's input to the column name 525 String mSelectionClause = "var = " + mUserInput; 526 </pre> 527 <p> 528 Se voc fizer isso, estar permitindo que o usurio concatene SQL mal-intencionados na sua declarao SQL. 529 Por exemplo: o usurio poderia inserir "nada; REMOVER TABELA *;" para <code>mUserInput</code>, o que 530 resultaria na clusula de seleo <code>var = nothing; DROP TABLE *;</code>. Como 531 a clusula de seleo tratada como uma declarao SQL, isso pode fazer com que o provedor apague todas 532 as tabelas no banco de dados SQLite em questo (a menos que o provedor esteja configurado para capturar 533 tentativas de <a href="http://en.wikipedia.org/wiki/SQL_injection">injeo de SQL</a>). 534 </p> 535 <p> 536 Para evitar este problema, use uma clusula de seleo que use <code>?</code> como um parmetro 537 substituvel e uma matriz de argumentos de seleo separada. Ao fazer isso, a insero de dados do usurio 538 limita-se diretamente consulta em vez de ser interpretada como parte de uma declarao SQL. 539 Pelo fato de no ser tratada como SQL, a insero de dados do usurio no injeta SQL mal-intencionados. Em vez de usar 540 a concatenao para incluir a insero de dados do usurio, use esta clusula de seleo: 541 </p> 542 <pre> 543 // Constructs a selection clause with a replaceable parameter 544 String mSelectionClause = "var = ?"; 545 </pre> 546 <p> 547 Configure a matriz de argumentos de seleo desta maneira: 548 </p> 549 <pre> 550 // Defines an array to contain the selection arguments 551 String[] selectionArgs = {""}; 552 </pre> 553 <p> 554 Insira um valor na matriz de argumentos de seleo desta maneira: 555 </p> 556 <pre> 557 // Sets the selection argument to the user's input 558 selectionArgs[0] = mUserInput; 559 </pre> 560 <p> 561 Usar uma clusula de seleo que use <code>?</code> como um parmetro substituvel e uma matriz 562 de argumentos de seleo o melhor modo de especificar uma seleo, mesmo que o provedor se baseie 563 base em um banco de dados SQL. 564 </p> 565 <!-- Displaying the results --> 566 <h3 id="DisplayResults">Exibio dos resultados da consulta</h3> 567 <p> 568 O mtodo cliente {@link android.content.ContentResolver#query ContentResolver.query()} sempre 569 retorna um {@link android.database.Cursor} contendo as colunas especificadas pela projeo 570 da consulta para as linhas que atendem aos critrios de seleo da consulta. 571 Um objeto {@link android.database.Cursor} fornece acesso para leitura aleatrio para as linhas e colunas que 572 contm. Usando mtodos {@link android.database.Cursor}, possvel repetir as linhas 573 nos resultados, determinar o tipo dos dados de cada coluna, extrair os dados de uma coluna e examinar 574 outras propriedades dos resultados. Algumas implementaes do {@link android.database.Cursor} atualizam o objeto 575 automaticamente quando os dados do provedor mudam ou acionam mtodos em um objeto observador 576 quando o {@link android.database.Cursor} muda, ou ambos. 577 </p> 578 <p class="note"> 579 <strong>Observao:</strong> os provedores podem restringir acesso a colunas com base na natureza 580 do objeto que realiza a consulta. Por exemplo: o Provedor de Contatos restringe o acesso de algumas colunas 581 a adaptadores de sincronizao, por isso ela no os retornar a uma atividade ou servio. 582 </p> 583 <p> 584 Se nenhuma linha atender aos critrios de seleo, o provedor 585 retorna um objeto {@link android.database.Cursor} para o qual 586 {@link android.database.Cursor#getCount Cursor.getCount()} 0 (um cursor vazio). 587 </p> 588 <p> 589 Se ocorrer um erro interno, os resultados da consulta dependem do provedor determinado. Ele pode 590 escolher retornar <code>null</code> ou pode gerar uma {@link java.lang.Exception}. 591 </p> 592 <p> 593 J que {@link android.database.Cursor} uma "lista" de linhas, um bom modo de exibir 594 o contedo de um {@link android.database.Cursor} vincul-lo a uma {@link android.widget.ListView} 595 por meio de um {@link android.widget.SimpleCursorAdapter}. 596 </p> 597 <p> 598 O fragmento a seguir continua o cdigo do fragmento anterior. Ele cria 599 um objeto {@link android.widget.SimpleCursorAdapter} contendo o {@link android.database.Cursor} 600 recuperado pela consulta e configura esse objeto para ser o adaptador de uma 601 {@link android.widget.ListView}: 602 </p> 603 <pre class="prettyprint"> 604 // Defines a list of columns to retrieve from the Cursor and load into an output row 605 String[] mWordListColumns = 606 { 607 UserDictionary.Words.WORD, // Contract class constant containing the word column name 608 UserDictionary.Words.LOCALE // Contract class constant containing the locale column name 609 }; 610 611 // Defines a list of View IDs that will receive the Cursor columns for each row 612 int[] mWordListItems = { R.id.dictWord, R.id.locale}; 613 614 // Creates a new SimpleCursorAdapter 615 mCursorAdapter = new SimpleCursorAdapter( 616 getApplicationContext(), // The application's Context object 617 R.layout.wordlistrow, // A layout in XML for one row in the ListView 618 mCursor, // The result from the query 619 mWordListColumns, // A string array of column names in the cursor 620 mWordListItems, // An integer array of view IDs in the row layout 621 0); // Flags (usually none are needed) 622 623 // Sets the adapter for the ListView 624 mWordList.setAdapter(mCursorAdapter); 625 </pre> 626 <p class="note"> 627 <strong>Observao:</strong> para retornar uma {@link android.widget.ListView} com um 628 {@link android.database.Cursor}, o cursor deve conter uma coluna chamada <code>_ID</code>. 629 Por isso, a consulta exibida anteriormente recupera a coluna <code>_ID</code> da 630 tabelas de "palavras", mesmo que a {@link android.widget.ListView} no a exiba. 631 Essa restrio tambm explica por que a maioria dos provedores tem uma coluna <code>_ID</code> para cada 632 tabela. 633 </p> 634 635 <!-- Getting data from query results --> 636 <h3 id="GettingResults">Obteno de dados de resultados da consulta</h3> 637 <p> 638 Em vez de simplesmente exibir resultados da consulta, possvel us-los para outras tarefas. Por 639 exemplo: possvel recuperar grafias de um dicionrio do usurio e, em seguida, procur-los 640 em outros provedores. Para isso, repetem-se as linhas no {@link android.database.Cursor}: 641 </p> 642 <pre class="prettyprint"> 643 644 // Determine the column index of the column named "word" 645 int index = mCursor.getColumnIndex(UserDictionary.Words.WORD); 646 647 /* 648 * Only executes if the cursor is valid. The User Dictionary Provider returns null if 649 * an internal error occurs. Other providers may throw an Exception instead of returning null. 650 */ 651 652 if (mCursor != null) { 653 /* 654 * Moves to the next row in the cursor. Before the first movement in the cursor, the 655 * "row pointer" is -1, and if you try to retrieve data at that position you will get an 656 * exception. 657 */ 658 while (mCursor.moveToNext()) { 659 660 // Gets the value from the column. 661 newWord = mCursor.getString(index); 662 663 // Insert code here to process the retrieved word. 664 665 ... 666 667 // end of while loop 668 } 669 } else { 670 671 // Insert code here to report an error if the cursor is null or the provider threw an exception. 672 } 673 </pre> 674 <p> 675 As implementaes {@link android.database.Cursor} contm diversos mtodos "get" (obter) 676 para recuperar diferentes tipos de dados do objeto. Por exemplo, o fragmento anterior 677 usa {@link android.database.Cursor#getString getString()}. Elas tambm tm 678 um mtodo {@link android.database.Cursor#getType getType()} que retorna um valor indicando 679 o tipo dos dados da coluna. 680 </p> 681 682 683 <!-- Requesting permissions --> 684 <h2 id="Permissions">Permisses do provedor de contedo</h2> 685 <p> 686 Um aplicativo do provedor pode especificar permisses que outros aplicativos devem ter para 687 acessar os dados do provedor. Essas permisses garantem que o usurio saiba quais dados 688 um aplicativo tentar acessar. Com base nos requisitos do provedor, outros aplicativos 689 solicitam as permisses de que precisam para acessar o provedor. Usurios finais veem as permisses 690 solicitadas quando instalam o aplicativo. 691 </p> 692 <p> 693 Se um aplicativo do provedor no especificar nenhuma permisso, outros aplicativos no tero 694 acesso aos dados do provedor. No entanto, os componentes no aplicativo do provedor sempre tm 695 acesso total para leitura e gravao, independentemente das permisses especificadas. 696 </p> 697 <p> 698 Como observado anteriormente, o Provedor de Dicionrio do Usurio requer 699 a permisso <code>android.permission.READ_USER_DICTIONARY</code> para recuperar dados dele. 700 O provedor tem a permisso <code>android.permission.WRITE_USER_DICTIONARY</code> 701 separadamente para insero, atualizao ou excluso de dados. 702 </p> 703 <p> 704 Para obter as permisses necessrias para acessar um provedor, um aplicativo as solicita 705 como um elemento <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> 706 no arquivo de manifesto. Quando o Android Package Manager (gerente de pacotes do Android) instala o aplicativo, o usurio 707 precisa aprovar todas as permisses que o aplicativo solicita. Se o usurio aprovar todas elas, 708 o gerente de pacotes continua a instalao; se o usurio no as aprovar, o gerente de pacotes 709 aborta a instalao. 710 </p> 711 <p> 712 O elemento 713 <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> a seguir 714 solicita acesso para leitura ao Provedor de Dicionrio do Usurio: 715 </p> 716 <pre> 717 <uses-permission android:name="android.permission.READ_USER_DICTIONARY"> 718 </pre> 719 <p> 720 O impacto das permisses no acesso ao provedor explicado com mais detalhes 721 no guia <a href="{@docRoot}guide/topics/security/security.html">Permisses e segurana</a>. 722 </p> 723 724 725 <!-- Inserting, Updating, and Deleting Data --> 726 <h2 id="Modifications">Insero, atualizao e excluso de dados</h2> 727 <p> 728 Do mesmo modo que se recupera dados de um provedor, tambm usa-se a interao entre 729 um cliente do provedor e o {@link android.content.ContentProvider} do provedor para modificar dados. 730 Chama-se um mtodo de {@link android.content.ContentResolver} com argumentos que so passados para 731 o mtodo correspondente de {@link android.content.ContentProvider}. O provedor e o cliente 732 do provedor tratam automaticamente da segurana e da comunicao de processos internos. 733 </p> 734 <h3 id="Inserting">Insero de dados</h3> 735 <p> 736 Para inserir dados em um provedor, chame 737 o mtodo 738 {@link android.content.ContentResolver#insert ContentResolver.insert()}. Esse mtodo insere uma nova linha no provedor e retorna uma URI de contedo dessa linha. 739 Este fragmento mostra como inserir uma nova palavra no Provedor de Dicionrio do Usurio: 740 </p> 741 <pre class="prettyprint"> 742 // Defines a new Uri object that receives the result of the insertion 743 Uri mNewUri; 744 745 ... 746 747 // Defines an object to contain the new values to insert 748 ContentValues mNewValues = new ContentValues(); 749 750 /* 751 * Sets the values of each column and inserts the word. The arguments to the "put" 752 * method are "column name" and "value" 753 */ 754 mNewValues.put(UserDictionary.Words.APP_ID, "example.user"); 755 mNewValues.put(UserDictionary.Words.LOCALE, "en_US"); 756 mNewValues.put(UserDictionary.Words.WORD, "insert"); 757 mNewValues.put(UserDictionary.Words.FREQUENCY, "100"); 758 759 mNewUri = getContentResolver().insert( 760 UserDictionary.Word.CONTENT_URI, // the user dictionary content URI 761 mNewValues // the values to insert 762 ); 763 </pre> 764 <p> 765 Os dados da nova linha vo para um objeto {@link android.content.ContentValues} nico, que 766 tem forma semelhante a um cursor de uma linha. As colunas nesse objeto no precisam ter 767 o mesmo tipo de dados e, se voc no quiser especificar um valor, pode definir uma coluna 768 como <code>null</code> usando {@link android.content.ContentValues#putNull ContentValues.putNull()}. 769 </p> 770 <p> 771 O fragmento no adiciona a coluna <code>_ID</code> porque essa coluna mantida 772 automaticamente. O provedor atribui um valor exclusivo de <code>_ID</code> para cada linha 773 adicionada. Os provedores normalmente usam esse valor como a chave principal da tabela. 774 </p> 775 <p> 776 A URI de contedo retornada em <code>newUri</code> identifica a linha recentemente adicionada com 777 o seguinte formato: 778 </p> 779 <pre> 780 content://user_dictionary/words/<id_value> 781 </pre> 782 <p> 783 O <code><id_value></code> o contedo de <code>_ID</code> da nova linha. 784 A maioria dos provedores pode detectar essa forma de URI de contedo automaticamente e, em seguida, realizar a operao 785 solicitada naquela linha. 786 </p> 787 <p> 788 Para obter o valor de <code>_ID</code> do {@link android.net.Uri} retornado, chame 789 {@link android.content.ContentUris#parseId ContentUris.parseId()}. 790 </p> 791 <h3 id="Updating">Atualizao de dados</h3> 792 <p> 793 Para atualizar uma linha, use um objeto {@link android.content.ContentValues} com os valores 794 e os critrios de seleo atualizados, como se faz com uma insero e em uma consulta, respectivamente. 795 O mtodo cliente usado 796 {@link android.content.ContentResolver#update ContentResolver.update()}. S necessrio adicionar 797 valores ao objeto {@link android.content.ContentValues} das colunas que forem atualizadas. Se voc 798 deseja apagar o contedo de uma coluna, defina o valor como <code>null</code>. 799 </p> 800 <p> 801 O fragmento a seguir altera todas as linhas cuja localidade tem o idioma "en" para 802 terem uma localidade de <code>null</code>. O valor de retorno o nmero de linhas que foram atualizadas: 803 </p> 804 <pre> 805 // Defines an object to contain the updated values 806 ContentValues mUpdateValues = new ContentValues(); 807 808 // Defines selection criteria for the rows you want to update 809 String mSelectionClause = UserDictionary.Words.LOCALE + "LIKE ?"; 810 String[] mSelectionArgs = {"en_%"}; 811 812 // Defines a variable to contain the number of updated rows 813 int mRowsUpdated = 0; 814 815 ... 816 817 /* 818 * Sets the updated value and updates the selected words. 819 */ 820 mUpdateValues.putNull(UserDictionary.Words.LOCALE); 821 822 mRowsUpdated = getContentResolver().update( 823 UserDictionary.Words.CONTENT_URI, // the user dictionary content URI 824 mUpdateValues // the columns to update 825 mSelectionClause // the column to select on 826 mSelectionArgs // the value to compare to 827 ); 828 </pre> 829 <p> 830 Voc tambm deve filtrar a insero de dados do usurio ao chamar 831 {@link android.content.ContentResolver#update ContentResolver.update()}. Para saber mais sobre 832 isso, leia a seo <a href="#Injection">Proteo contra inseres mal-intencionadas</a>. 833 </p> 834 <h3 id="Deleting">Excluso de dados</h3> 835 <p> 836 Excluir linhas semelhante a recuperar dados de linhas: especificam-se critrios de seleo para as linhas 837 que se deseja excluir e o mtodo cliente retorna o nmero de linhas excludas. 838 O fragmento a seguir exclui linhas cujo appid (id do aplicativo) corresponda a "usurio". O mtodo retorna 839 o nmero de linhas excludas. 840 </p> 841 <pre> 842 843 // Defines selection criteria for the rows you want to delete 844 String mSelectionClause = UserDictionary.Words.APP_ID + " LIKE ?"; 845 String[] mSelectionArgs = {"user"}; 846 847 // Defines a variable to contain the number of rows deleted 848 int mRowsDeleted = 0; 849 850 ... 851 852 // Deletes the words that match the selection criteria 853 mRowsDeleted = getContentResolver().delete( 854 UserDictionary.Words.CONTENT_URI, // the user dictionary content URI 855 mSelectionClause // the column to select on 856 mSelectionArgs // the value to compare to 857 ); 858 </pre> 859 <p> 860 Tambm se deve filtrar a insero de dados do usurio ao chamar 861 {@link android.content.ContentResolver#delete ContentResolver.delete()}. Para saber mais sobre 862 isso, leia a seo <a href="#Injection">Proteo contra inseres mal-intencionadas</a>. 863 </p> 864 <!-- Provider Data Types --> 865 <h2 id="DataTypes">Tipos de dados do provedor</h2> 866 <p> 867 Provedores de contedo podem oferecer muitos tipos de dados diferentes. O Provedor de Dicionrio do Usurio oferece somente 868 texto, mas provedores tambm podem oferecer os seguintes formatos: 869 </p> 870 <ul> 871 <li> 872 nmero inteiro 873 </li> 874 <li> 875 nmero inteiro longo (longo) 876 </li> 877 <li> 878 ponto flutuante 879 </li> 880 <li> 881 ponto flutuante longo (duplo) 882 </li> 883 </ul> 884 <p> 885 Outros tipos de dados que provedores usam com frequncia so objetos binrios largos (BLOB) implementados como uma 886 matriz de byte de 64 kB. possvel ver os tipos de dados disponveis consultando 887 os mtodos "get" da classe {@link android.database.Cursor}. 888 </p> 889 <p> 890 O tipo dos dados para cada coluna em um provedor normalmente listado na documentao do provedor. 891 Os tipos de dados do Provedor de Dicionrio do Usurio so listados na documentao de referncia 892 para sua classe de contrato {@link android.provider.UserDictionary.Words} (classes de contrato so 893 descritas na seo <a href="#ContractClasses">Classes de contrato</a>). 894 Tambm possvel determinar o tipo dos dados chamando {@link android.database.Cursor#getType 895 Cursor.getType()}. 896 </p> 897 <p> 898 Os provedores tambm mantm informaes do tipo MIME de dados para cada URI de contedo que definem. possvel 899 usar as informaes do tipo MIME para descobrir se o aplicativo pode tratar de dados que 900 o provedor fornece ou para escolher um tipo de tratamento com base no tipo MIME. Normalmente necessrio ter 901 o tipo MIME ao trabalhar com um provedor que contenha estruturas 902 complexas de dados ou arquivos. Por exemplo: a tabela {@link android.provider.ContactsContract.Data} 903 no Provedor de contatos usa tipos MIME para etiquetar o tipo dos dados de contato armazenados em cada 904 linha. Para obter o tipo MIME correspondente a uma URI de contedo, chame 905 {@link android.content.ContentResolver#getType ContentResolver.getType()}. 906 </p> 907 <p> 908 A seo <a href="#MIMETypeReference">Referncia de tipo MIME</a> descreve 909 a sintaxe de tipos MIME padro e personalizados. 910 </p> 911 912 913 <!-- Alternative Forms of Provider Access --> 914 <h2 id="AltForms">Formas alternativas de acessar o provedor</h2> 915 <p> 916 Trs formas alternativas de acesso ao provedor so importantes no desenvolvimento do aplicativo: 917 </p> 918 <ul> 919 <li> 920 <a href="#Batch">Acesso em lote</a>: possvel criar um lote de chamadas de acesso com mtodos na 921 classe {@link android.content.ContentProviderOperation} e, em seguida, aplic-los com 922 {@link android.content.ContentResolver#applyBatch ContentResolver.applyBatch()}. 923 </li> 924 <li> 925 Consultas assncronas: Devem-se realizar consultas em um encadeamento separado. Um modo de fazer isso 926 usar um objeto {@link android.content.CursorLoader}. Os exemplos 927 no guia <a href="{@docRoot}guide/components/loaders.html">Carregadores</a> demonstram 928 como fazer isso. 929 </li> 930 <li> 931 <a href="#Intents">Acesso a dados via intenes</a> Embora no seja possvel enviar uma inteno 932 diretamente a um provedor, possvel enviar uma inteno ao aplicativo do provedor, que 933 normalmente o recomendvel para modificar os dados do provedor. 934 </li> 935 </ul> 936 <p> 937 O acesso em lote e a modificao via intenes so descritos nas sees a seguir. 938 </p> 939 <h3 id="Batch">Acesso em lote</h3> 940 <p> 941 O acesso em lote a um provedor til para inserir uma grande quantidade de linhas ou para inserir 942 linhas em diversas tabelas na mesma chamada de mtodo ou, em geral, para realizar um conjunto de 943 operaes dentre limites de processo como uma transao (uma operao atmica). 944 </p> 945 <p> 946 Para acessar um provedor em "modo de lote", 947 cria-se uma matriz de objetos {@link android.content.ContentProviderOperation} e, em seguida, 948 envia-os a um provedor de contedo com 949 {@link android.content.ContentResolver#applyBatch ContentResolver.applyBatch()}. Confere-se a 950 <em>autoridade</em> do provedor de contedo para esse mtodo em vez de para uma URI de contedo especfica. 951 Isso permite que cada objeto {@link android.content.ContentProviderOperation} na matriz trabalhe 952 com uma tabela diferente. Chamar {@link android.content.ContentResolver#applyBatch 953 ContentResolver.applyBatch()} retorna uma matriz de resultados. 954 </p> 955 <p> 956 A descrio da classe de contrato {@link android.provider.ContactsContract.RawContacts} 957 contm um fragmento de cdigo que demonstra a insero em lote. 958 O aplicativo de exemplo do <a href="{@docRoot}resources/samples/ContactManager/index.html">Gerente de contato</a> 959 contm um exemplo de acesso em lote em seu 960 arquivo de origem <code>ContactAdder.java</code>. 961 </p> 962 <div class="sidebox-wrapper"> 963 <div class="sidebox"> 964 <h2>Exibio de dados usando um aplicativo auxiliar</h2> 965 <p> 966 Se o seu aplicativo <em>tem</em> permisses de acesso, ainda possvel usar 967 uma inteno para exibir dados em outro aplicativo. Por exemplo: o aplicativo Agenda aceita 968 uma inteno {@link android.content.Intent#ACTION_VIEW} que exibe uma data ou evento especfico. 969 Isso permite a exibio de informaes da agenda sem precisar criar a prpria IU. 970 Para saber mais sobre esse recurso, consulte 971 o guia <a href="{@docRoot}guide/topics/providers/calendar-provider.html">Provedor de agenda</a>. 972 </p> 973 <p> 974 O aplicativo para o qual voc enviou uma inteno no precisa ser o aplicativo 975 associado ao provedor. Por exemplo: voc pode recuperar um contato 976 do Provedor de Contatos e, em seguida, enviar uma inteno {@link android.content.Intent#ACTION_VIEW} 977 que contm a URI de contedo da imagem do contato para um visualizador de imagens. 978 </p> 979 </div> 980 </div> 981 <h3 id="Intents">Acesso a dados via intenes</h3> 982 <p> 983 Intenes podem fornecer acesso indireto a um provedor de contedo. Basta permitir que o usurio acesse 984 dados em um provedor mesmo se o aplicativo no tiver permisses de acesso, tanto 985 retornando uma inteno de resultado de um aplicativo que tem permisses quanto ativando 986 um aplicativo que tem permisses e permitindo que o usurio trabalhe nele. 987 </p> 988 <h4>Obteno de acesso com permisses temporrias</h4> 989 <p> 990 possvel acessar dados em um provedor de contedo, mesmo sem s permisses 991 de acesso adequadas. Basta enviar uma inteno a um aplicativo que tenha as permisses e 992 receber de volta uma inteno de resultado contendo permisses da "URI". 993 Essas so permisses para uma URI de contedo especfica que duram enquanto durar a atividade 994 que as recebeu. O aplicativo que tem permisses permanentes concedem permisses 995 temporrias ativando um sinalizador na inteno de resultado: 996 </p> 997 <ul> 998 <li> 999 <strong>Permisso de leitura:</strong> 1000 {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION} 1001 </li> 1002 <li> 1003 <strong>Permisso de gravao:</strong> 1004 {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION} 1005 </li> 1006 </ul> 1007 <p class="note"> 1008 <strong>Observao:</strong> esses sinalizadores no fornecem acesso geral de leitura ou gravao ao provedor 1009 cuja autoridade esteja contida na URI de contedo. O acesso destina-se somente URI. 1010 </p> 1011 <p> 1012 Um provedor define permisses de URI para URIs de contedo no manifesto usando o atributo 1013 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">android:grantUriPermission</a></code> 1014 do elemento 1015 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code>, 1016 bem como o elemento filho 1017 <code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html"><grant-uri-permission></a></code> 1018 do elemento 1019 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code> 1020 . O mecanismo das permisses de URI explicado com mais detalhes 1021 no guia <a href="{@docRoot}guide/topics/security/security.html">Permisses e segurana</a>, 1022 na seo "Permisses da URI". 1023 </p> 1024 <p> 1025 Por exemplo: possvel recuperar dados de um contato no Provedor de Contatos, mesmo sem 1026 a permisso {@link android.Manifest.permission#READ_CONTACTS}. Voc pode desejar fazer 1027 isso em um aplicativo que envie e-mails de parabenizao a um contato no aniversrio dele. Em vez de 1028 solicitar {@link android.Manifest.permission#READ_CONTACTS}, que fornece acesso a todos 1029 os contatos do usurio e suas informaes, prefervel deixar que o usurio controle quais 1030 contatos sero usados pelo seu aplicativo. Para isso, use o processo a seguir: 1031 </p> 1032 <ol> 1033 <li> 1034 O aplicativo envia uma inteno contendo a ao 1035 {@link android.content.Intent#ACTION_PICK} e o tipo MIME 1036 {@link android.provider.ContactsContract.RawContacts#CONTENT_ITEM_TYPE} dos "contatos" usando 1037 o mtodo {@link android.app.Activity#startActivityForResult 1038 startActivityForResult()}. 1039 </li> 1040 <li> 1041 Como essa inteno corresponde ao filtro de intenes da 1042 atividade de "seleo" do aplicativo Pessoas, a atividade ficar em primeiro plano. 1043 </li> 1044 <li> 1045 Na atividade de seleo, o usurio seleciona 1046 um contato para atualizar. Quando isso acontece, a atividade de seleo chama 1047 {@link android.app.Activity#setResult setResult(resultcode, intent)} 1048 para configurar uma inteno para retornar ao aplicativo. A inteno contm a URI de contedo 1049 do contato que o usurio selecionou e os sinalizadores "extras" 1050 {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}. Esses sinalizadores concedem 1051 permisso de URI para que o aplicativo leia dados do contato apontados pela 1052 URI de contedo. A atividade de seleo, em seguida, chama {@link android.app.Activity#finish()} para 1053 retornar o controle para o aplicativo. 1054 </li> 1055 <li> 1056 A atividade volta ao primeiro plano e o sistema chama o 1057 mtodo {@link android.app.Activity#onActivityResult onActivityResult()} 1058 da sua atividade. Esse mtodo recebe a inteno de resultado criada pela atividade de seleo 1059 no aplicativo Pessoas. 1060 </li> 1061 <li> 1062 Com a URI de contedo da inteno de resultado, possvel ler os dados do contato 1063 a partir do Provedor de Contatos, mesmo que no tenha solicitado permisso permanente de acesso a leitura 1064 para o provedor no manifesto. Pode-se, ento, pode obter as informaes de data de nascimento do contato 1065 ou seu endereo de e-mail e, assim, enviar um e-mail de parabenizao. 1066 </li> 1067 </ol> 1068 <h4>Uso de outro aplicativo</h4> 1069 <p> 1070 Um modo simples que permite ao usurio modificar dados para os quais voc no tem permisses de acesso 1071 ativar um aplicativo que tenha permisses e deixar o usurio fazer o resto. 1072 </p> 1073 <p> 1074 Por exemplo: o aplicativo Agenda aceita uma 1075 inteno {@link android.content.Intent#ACTION_INSERT} que permite a ativao da 1076 IU de insero do aplicativo. Voc pode passar dados "extras" nessa inteno que o aplicativo 1077 usa para "pr-preencher" a IU. como os eventos recorrentes tm sintaxe complexa, o modo 1078 recomendado de inserir eventos no Provedor de Agenda ativar o aplicativo Agenda com um 1079 {@link android.content.Intent#ACTION_INSERT} e, em seguida, deixar o usurio inserir o evento. 1080 </p> 1081 <!-- Contract Classes --> 1082 <h2 id="ContractClasses">Classes de contrato</h2> 1083 <p> 1084 As classes de contrato definem constantes que ajudam os aplicativos a trabalhar com URIs de contedo, nomes 1085 de colunas, aes de intenes e outros recursos de um provedor de contedo. Elas no esto 1086 automaticamente inclusas em um provedor; o desenvolvedor do provedor deve defini-las e 1087 disponibiliz-las a outros desenvolvedores. Muitos dos provedores includos na plataforma 1088 do Android tm classes de contrato correspondentes no pacote {@link android.provider}. 1089 </p> 1090 <p> 1091 Por exemplo: o Provedor de Dicionrio do Usurio tem uma classe de contrato 1092 {@link android.provider.UserDictionary} que contm constantes de URI de contedo e de nome de coluna. 1093 A URI de contedo da tabela de "palavras" definida na constante 1094 {@link android.provider.UserDictionary.Words#CONTENT_URI UserDictionary.Words.CONTENT_URI}. 1095 A classe {@link android.provider.UserDictionary.Words} tambm contm constantes de nome de coluna 1096 que so usadas nos fragmentos de exemplo neste guia. Por exemplo, uma projeo de consulta pode ser 1097 definida como: 1098 </p> 1099 <pre> 1100 String[] mProjection = 1101 { 1102 UserDictionary.Words._ID, 1103 UserDictionary.Words.WORD, 1104 UserDictionary.Words.LOCALE 1105 }; 1106 </pre> 1107 <p> 1108 Outra classe de contrato {@link android.provider.ContactsContract} para o Provedor de Contatos. 1109 A documentao de referncia desta classe contm fragmentos de cdigo de exemplo. Uma das suas 1110 subclasses, {@link android.provider.ContactsContract.Intents.Insert}, uma classe 1111 de contrato que contm constantes para intenes e dados da inteno. 1112 </p> 1113 1114 1115 <!-- MIME Type Reference --> 1116 <h2 id="MIMETypeReference">Referncia do tipo MIME</h2> 1117 <p> 1118 Provedores de contedo podem retornar tipos MIME de mdia, strings de tipos MIME personalizados ou ambos. 1119 </p> 1120 <p> 1121 Tipos MIME tm o formato 1122 </p> 1123 <pre> 1124 <em>type</em>/<em>subtype</em> 1125 </pre> 1126 <p> 1127 Por exemplo: o tipo MIME <code>text/html</code> conhecido tem o tipo <code>text</code> 1128 e o subtipo <code>html</code>. Se o provedor retornar esse tipo para uma URI, 1129 uma consulta usando essa URI retornar um texto que contm tags HTML. 1130 </p> 1131 <p> 1132 Strings de tipo MIME personalizado, tambm chamadas de tipos MIME "especficos do fornecedor" (vendor-specific), tm mais 1133 valores de <em>tipo</em> e <em>subtipo</em> complexos. O valor de <em>tipo</em> sempre 1134 </p> 1135 <pre> 1136 vnd.android.cursor.<strong>dir</strong> 1137 </pre> 1138 <p> 1139 para diversas linhas ou 1140 </p> 1141 <pre> 1142 vnd.android.cursor.<strong>item</strong> 1143 </pre> 1144 <p> 1145 para uma nica linha. 1146 </p> 1147 <p> 1148 O <em>subtipo</em> especfico do provedor. Os provedores embutidos do Android normalmente tm um subtipo 1149 simples. Por exemplo, quando o aplicativo de contatos cria uma linha para um nmero de telefone, 1150 ele configura o seguinte tipo MIME na linha: 1151 </p> 1152 <pre> 1153 vnd.android.cursor.item/phone_v2 1154 </pre> 1155 <p> 1156 Observe que o valor do subtipo simplesmente <code>phone_v2</code>. 1157 </p> 1158 <p> 1159 Outros desenvolvedores de provedor podem criar os prprios padres de subtipos com base 1160 na autoridade do provedor e nos nomes da tabela. Por exemplo: considere um provedor que contenha horrios de trens. 1161 A autoridade do provedor <code>com.example.trains</code> e ele contm as tabelas 1162 Linha1, Linha2 e Linha3. Em resposta URI de contedo 1163 </p> 1164 <p> 1165 <pre> 1166 content://com.example.trains/Line1 1167 </pre> 1168 <p> 1169 para a tabela Linha1, o provedor retorna o tipo MIME 1170 </p> 1171 <pre> 1172 vnd.android.cursor.<strong>dir</strong>/vnd.example.line1 1173 </pre> 1174 <p> 1175 Em resposta URI de contedo 1176 </p> 1177 <pre> 1178 content://com.example.trains/Line2/5 1179 </pre> 1180 <p> 1181 da linha 5 na tabela Linha2, o provedor retorna o tipo MIME 1182 </p> 1183 <pre> 1184 vnd.android.cursor.<strong>item</strong>/vnd.example.line2 1185 </pre> 1186 <p> 1187 A maioria dos provedores define constantes de classe de contrato para os tipos MIME que usam. 1188 A classe de contrato {@link android.provider.ContactsContract.RawContacts} do Provedor de Contatos, 1189 por exemplo, define a constante 1190 {@link android.provider.ContactsContract.RawContacts#CONTENT_ITEM_TYPE} para o tipo MIME 1191 de uma linha exclusiva do contato bruto. 1192 </p> 1193 <p> 1194 URIs de contedo de linhas exclusivas so descritas na seo 1195 <a href="#ContentURIs">URIs de contedo</a>. 1196 </p> 1197