diff options
Diffstat (limited to 'docs/html-intl/intl/pt-br')
13 files changed, 2474 insertions, 0 deletions
diff --git a/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/index.jd b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/index.jd new file mode 100644 index 0000000..5912058 --- /dev/null +++ b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/index.jd @@ -0,0 +1,72 @@ +page.title=Como gerenciar o ciclo de vida da atividade +page.tags=ciclo de vida da atividade +helpoutsWidget=true + +trainingnavtop=true +startpage=true + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + + +<h2>Dependências e pré-requisitos</h2> +<ul> + <li>Como criar um projeto do Android (consulte <a href="{@docRoot}training/basics/firstapp/creating-project.html">Como criar um projeto +do Android</a>)</li> +</ul> + + +<h2>Leia também</h2> +<ul> + <li><a href="{@docRoot}guide/components/activities.html">Atividades</a></li> +</ul> + + +<h2>Tente</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Baixar a demonstração</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + +</div> +</div> + +<p>Conforme o usuário navega, sai e retorna para o seu aplicativo, as +instâncias {@link android.app.Activity} no aplicativo transitam entre diferentes estados no +ciclo de vida. Por exemplo, quando a +atividade começa pela primeira vez, ela fica em primeiro plano no sistema e tem o foco do +usuário. Durante o processo, o sistema Android chama uma série de métodos do ciclo de vida na +atividade, onde você define a interface do usuário e outros componentes. Se o usuário executa uma +ação que inicia outra atividade ou alterna para outro aplicativo, o sistema chama outro conjunto de +métodos do ciclo de vida em sua atividade conforme ela fica em segundo plano (onde a atividade já não +está visível, mas a instância e seu estado permanecem intactos).</p> + +<p>Dentro dos métodos de retorno de chamada do ciclo de vida, você pode declarar como a atividade deve se comportar quando o +usuário sai e retorna da atividade. Por exemplo, se estiver construindo um reprodutor de vídeos de transmissão em sequência, +você pode pausar o vídeo e encerrar a conexão da rede quando o usuário alternar para outro +aplicativo. Quando o usuário retornar, será possível reconectar a rede e permitir que ele reinicie o vídeo +de onde parou.</p> + +<p>Essa lição explica a importância dos métodos de retorno de chamada do ciclo de vida que cada instância {@link +android.app.Activity} recebe e como utilizá-los para que a atividade faça o que o +usuário espera e não consuma recursos do sistema quando não estiver em uso.</p> + +<h2>Lições</h2> + +<dl> + <dt><b><a href="starting.html">Iniciando uma atividade</a></b></dt> + <dd>Aprenda os fundamentos sobre ciclo de vida da atividade, como o usuário pode iniciar seu aplicativo e como +executar atividades básicas de criação.</dd> + <dt><b><a href="pausing.html">Pausando e reiniciando uma atividade</a></b></dt> + <dd>Aprenda sobre o que acontece quando sua atividade é pausada (parcialmente obscurecida) e retomada e o que +fazer durante essas mudanças de estados.</dd> + <dt><b><a href="stopping.html">Interrompendo e reiniciando uma atividade</a></b></dt> + <dd>Aprenda sobre o que acontece quando o usuário sai da atividade completamente e retorna.</dd> + <dt><b><a href="recreating.html">Recriando uma atividade</a></b></dt> + <dd>Aprenda sobre o que acontece quando sua atividade é destruída e como reconstruir o estado +da atividade quando necessário.</dd> +</dl> + diff --git a/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/pausing.jd b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/pausing.jd new file mode 100644 index 0000000..55f772e --- /dev/null +++ b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/pausing.jd @@ -0,0 +1,147 @@ +page.title=Pausando e reiniciando uma atividade +page.tags=ciclo de vida da atividade +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>Esta lição ensina a</h2> + <ol> + <li><a href="#Pause">Pausar sua atividade</a></li> + <li><a href="#Resume">Reiniciar sua atividade</a></li> + </ol> + + <h2>Leia também</h2> + <ul> + <li><a href="{@docRoot}guide/components/activities.html">Atividades</a> + </li> + </ul> + +<h2>Tente</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Baixar a demonstração</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + + </div> +</div> + +<p>Durante o uso normal do aplicativo, a atividade em primeiro plano as vezes é obstruída por outros +componentes visuais que causam a <em>pausa</em>. Por exemplo, quando uma atividade + semitransparente é aberta (como uma no estilo de um diálogo), a atividade anterior pausa. Enquanto a +atividade estiver parcialmente visível, mas não for o foco da atividade, ela permanecerá pausada.</p> + +<p>No entanto, se a atividade estiver completamente obstruída e não visível, ela <em>para</em> (o que será +discutido na próxima lição).</p> + +<p>Conforme a atividade entra no estado pausado, o sistema chama o método {@link +android.app.Activity#onPause onPause()} em seu {@link android.app.Activity}, que permite +interromper ações em andamento que não devem continuar enquanto pausadas (como um vídeo) nem persistir +quaisquer informações que devam ser permanentemente salvas caso o usuário continue a sair do aplicativo. Se +o usuário retornar à atividade do estado de pausa, o sistema a reiniciará e chamará o método +{@link android.app.Activity#onResume onResume()}.</p> + +<p class="note"><strong>Observação:</strong> quando a atividade receber o chamado para {@link +android.app.Activity#onPause()}, pode ser um indicativo de que a atividade será pausada por um +momento e o usuário poderá retornar o foco para a atividade. No entanto, geralmente é um indicativo +de que o usuário está saindo da atividade.</p> + +<img src="{@docRoot}images/training/basics/basic-lifecycle-paused.png" /> +<p class="img-caption"><strong>Figura 1.</strong> Quando uma atividade semitransparente obscurece +sua atividade, o sistema chama {@link android.app.Activity#onPause onPause()} e a atividade +aguarda no estado Pausa (1). Se o usuário retornar à atividade enquanto ainda estiver pausada, o + sistema chama {@link android.app.Activity#onResume onResume()} (2).</p> + + +<h2 id="Pause">Pausar sua atividade</h2> + +<p>Quando o sistema chama {@link android.app.Activity#onPause()} para sua atividade, teoricamente +significa que a atividade ainda está parcialmente visível, mas geralmente é um indício +de que o usuário está saindo da atividade e logo entrará em estado Interrompido. Use +o retorno de chamada {@link android.app.Activity#onPause()} para:</p> + +<ul> + <li>Interromper animações ou outras ações em andamento que consomem a CPU.</li> + <li>Consolidar alterações não salvas apenas se o usuário esperar que essas alterações sejam permanentemente salvas ao +saírem (como um rascunho de email).</li> + <li>Liberar recursos do sistema, como receptores, cabos para sensores (como +GPS), ou outros recursos que podem afetar a vida da bateria enquanto a atividade estiver pausada e o usuário +não precisar deles.</li> +</ul> + +<p>Por exemplo, se seu aplicativo utiliza o {@link android.hardware.Camera}, o método +{@link android.app.Activity#onPause()} é um bom local para liberá-los.</p> + +<pre> +@Override +public void onPause() { + super.onPause(); // Always call the superclass method first + + // Release the Camera because we don't need it when paused + // and other activities might need to use it. + if (mCamera != null) { + mCamera.release() + mCamera = null; + } +} +</pre> + +<p>Geralmente, recomenda-se <strong>não</strong> utilizar {@link android.app.Activity#onPause()} para armazenar +alterações do usuário (como informações pessoais digitadas em um formulário) para armazenamento permanente. O único momento +que se deve persistir na mudança do usuário para armazenamento permanente dentro do {@link android.app.Activity#onPause()} +é quando tem certeza de que o usuário espera que as alterações sejam salvas automaticamente (como ao esboçar um email). +No entanto, evite executar trabalhos de uso intensivo da CPU durante {@link +android.app.Activity#onPause()}, como gravar em um banco de dados, porque isso pode retardar a transição +visível para a próxima atividade (execute operações de encerramento pesadas durante +{@link android.app.Activity#onStop onStop()}).</p> + +<p>Simplifique a quantidade de operações feitas no método {@link android.app.Activity#onPause +onPause()} para permitir uma transição mais rápida para o próximo +destino do usuário se a atividade for realmente interrompida.</p> + +<p class="note"><strong>Observação:</strong> quando a atividade está pausada, a instância {@link +android.app.Activity} é mantida na memória e chamada novamente quando a atividade é retomada. +Não é necessário reiniciar componentes que foram criados durante qualquer método de retorno de chamada que +leve ao estado Reiniciado.</p> + + + +<h2 id="Resume">Reiniciar sua atividade</h2> + +<p>Quando o usuário reinicia a atividade do estado Pausado, o sistema chama o método {@link +android.app.Activity#onResume()}.</p> + +<p>Certifique-se de que o sistema chama esse método sempre que a atividade entrar no primeiro plano, +mesmo quando estiver sendo criada. Dessa forma, implemente o {@link +android.app.Activity#onResume()} para inicializar os componentes liberados durante {@link +android.app.Activity#onPause()} e execute quaisquer outras inicializações que devem ocorrer sempre que a +atividade entrar em estado Reiniciado (como ao iniciar animações e componentes de inicialização usados apenas +enquanto a atividade tiver o foco do usuário).</p> + +<p>O seguinte exemplo de {@link android.app.Activity#onResume()} é uma contrapartida ao +exemplo {@link android.app.Activity#onPause()} acima. Portanto, ele inicializa a câmera que é + liberada quando a atividade entra em pausa.</p> + +<pre> +@Override +public void onResume() { + super.onResume(); // Always call the superclass method first + + // Get the Camera instance as the activity achieves full user focus + if (mCamera == null) { + initializeCamera(); // Local method to handle camera init + } +} +</pre> + + + + + + + diff --git a/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/recreating.jd b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/recreating.jd new file mode 100644 index 0000000..7cb122f --- /dev/null +++ b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/recreating.jd @@ -0,0 +1,178 @@ +page.title=Recriando uma atividade +page.tags=ciclo de vida da atividade +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>Esta lição ensina a</h2> + <ol> + <li><a href="#SaveState">Salvar o estado da atividade</a></li> + <li><a href="#RestoreState">Restaurar o estado da atividade</a></li> + </ol> + + <h2>Leia também</h2> + <ul> + <li><a href="{@docRoot}training/basics/supporting-devices/screens.html">Compatibilidade + com diferentes telas</a></li> + <li><a href="{@docRoot}guide/topics/resources/runtime-changes.html">Tratar alterações no tempo de execução</a></li> + <li><a href="{@docRoot}guide/components/activities.html">Atividades</a> + </li> + </ul> + + </div> +</div> + +<p>Estas são algumas possibilidade onde a atividade é destruída devido ao comportamento normal do aplicativo, como +quando o usuário pressiona o botão <em>Voltar</em> ou sua atividade sinaliza sua própria destruição +chamando {@link android.app.Activity#finish()}. O sistema também pode destruir a atividade se +for interrompida e não tiver sido utilizada por um longo período de tempo ou a atividade do primeiro plano exigir mais +recursos, então, o sistema deverá fechar processos de segundo plano para recuperar memória.</p> + +<p>Quando a atividade é destruída porque o usuário pressiona <em>Voltar</em> ou a atividade se +encerra, o conceito do sistema de que a instância {@link android.app.Activity} se perde +porque o comportamento indica que a atividade já não é necessária. No entanto, se o sistema destruir +a atividade devido a limitações do sistema (em vez do comportamento normal do aplicativo), embora a instância real +{@link android.app.Activity} tenha se perdido, o sistema lembra que ela existiu de forma que se +o usuário navegar de volta, o sistema criará uma nova instância da atividade usando um conjunto +de dados salvos que descrevem o estado da atividade quando foi destruída. Os dados salvos +utilizados pelo sistema para restaurar o estado anterior é chamado de “estado da instância” e é uma coleção +de pares de valores-chave armazenados no objeto {@link android.os.Bundle}.</p> + +<p class="caution"><strong>Cuidado:</strong> a atividade é destruída e recriada cada vez +que o usuário girar a tela. Quando a tela altera a orientação, o sistema destrói e recria +a atividade de primeiro plano porque a configuração da tela mudou e a atividade talvez precise +carregar recursos alternativos (como o layout).</p> + +<p>Por padrão, o sistema usa o estado da instância {@link android.os.Bundle} para salvar informações +sobre cada objeto {@link android.view.View} em seu layout de atividade (como o valor do texto informado +em um objeto {@link android.widget.EditText}). Assim, se a instância da atividade for destruída e +recriada, o estado do layout é restaurado em seu estado anterior sem +que haja necessidade de códigos. No entanto, sua +atividade pode conter mais informações de estado do que se deseja restaurar, como varáveis de membro que +rastreiam o progresso do usuário na atividade.</p> + +<p class="note"><strong>Observação:</strong> para que o sistema Android restaure o estado das +visualizações em sua atividade, <strong>cada visualização precisa ter uma ID exclusiva</strong>, fornecido pelo atributo +<a href="{@docRoot}reference/android/view/View.html#attr_android:id">{@code +android:id}</a>.</p> + +<p>Para salvar dados adicionais sobre o estado da atividade, substitua +o método de retorno de chamada {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}. +O sistema chama este método quando o usuário sai da atividade +e transmite o objeto{@link android.os.Bundle}, que será salvo +caso a atividade seja destruída inesperadamente. Se +o sistema precisar recriar a instância da atividade posteriormente, transmitirá o mesmo objeto {@link +android.os.Bundle} para ambos os métodos {@link android.app.Activity#onRestoreInstanceState +onRestoreInstanceState()} e {@link android.app.Activity#onCreate onCreate()} +.</p> + +<img src="{@docRoot}images/training/basics/basic-lifecycle-savestate.png" /> +<p class="img-caption"><strong>Figura 2.</strong> Conforme o sistema começa a interromper a atividade, ele +chama {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}(1) para que você possa especificar +outros dados de estado que gostaria de salvar caso a instância {@link android.app.Activity} precise ser +recriada. +Se a atividade for destruída e a mesma instância precisar ser recriada, o sistema transmite os dados do +estado definidos em (1) para ambos os métodos {@link android.app.Activity#onCreate onCreate()} +(2) e {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} +(3).</p> + + + +<h2 id="SaveState">Salvar o estado da atividade</h2> + +<p>Conforme a atividade é interrompida, o sistema chama {@link android.app.Activity#onSaveInstanceState +onSaveInstanceState()} para que a atividade possa salvar informações de estado com uma coleção de pares de +valor-chave. A implementação padrão deste método salva informações sobre o estado da hierarquia de exibições +da atividade, como o texto em um widget {@link android.widget.EditText} ou a posição de rolagem +de um {@link android.widget.ListView}.</p> + +<p>Para salvar informações de estado adicionais para a atividade, +implemente {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} e adicione +pares de valor-chave ao objeto {@link android.os.Bundle}. Por exemplo:</p> + +<pre> +static final String STATE_SCORE = "playerScore"; +static final String STATE_LEVEL = "playerLevel"; +... + +@Override +public void onSaveInstanceState(Bundle savedInstanceState) { + // Save the user's current game state + savedInstanceState.putInt(STATE_SCORE, mCurrentScore); + savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel); + + // Always call the superclass so it can save the view hierarchy state + super.onSaveInstanceState(savedInstanceState); +} +</pre> + +<p class="caution"><strong>Cuidado:</strong> sempre chame a implementação de superclasse de {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} para que a implementação padrão +possa salvar o estado da hierarquia de exibições.</p> + + + +<h2 id="RestoreState">Restaurar o estado da atividade</h2> + +<p>Quando a atividade é recriada depois de ter sido destruída, é possível recuperar o estado +salvo do {@link android.os.Bundle} que o sistema +transmitiu a atividade. Ambos os métodos de retorno de chamada {@link android.app.Activity#onCreate onCreate()} e {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} recebem +o mesmo {@link android.os.Bundle} que contém informações do estado da instância.</p> + +<p>Como o método {@link android.app.Activity#onCreate onCreate()} é chamado se o +sistema estiver criando uma nova instância da atividade ou recriando uma anterior, verifique +se o {@link android.os.Bundle} do estado é null antes de tentar realizar a leitura. Se for null, +o sistema estará criando uma nova instância da atividade em vez de restaurar uma anterior +que tenha sido destruída.</p> + +<p>Por exemplo, esta é uma forma de restaurar alguns dados de estado no {@link android.app.Activity#onCreate +onCreate()}:</p> + +<pre> +@Override +protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); // Always call the superclass first + + // Check whether we're recreating a previously destroyed instance + if (savedInstanceState != null) { + // Restore value of members from saved state + mCurrentScore = savedInstanceState.getInt(STATE_SCORE); + mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); + } else { + // Probably initialize members with default values for a new instance + } + ... +} +</pre> + +<p>Em vez de restaurar o estado durante {@link android.app.Activity#onCreate onCreate()}, você +pode implementar {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}, que o sistema chama +depois do método {@link android.app.Activity#onStart()}. O sistema chama {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} se houver um estado +salvo para ser restaurado. Portanto, não é necessário verificar se {@link android.os.Bundle} é null:</p> + +<pre> +public void onRestoreInstanceState(Bundle savedInstanceState) { + // Always call the superclass so it can restore the view hierarchy + super.onRestoreInstanceState(savedInstanceState); + + // Restore state members from saved instance + mCurrentScore = savedInstanceState.getInt(STATE_SCORE); + mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); +} +</pre> + +<p class="caution"><strong>Cuidado:</strong> sempre chame a implementação de superclasse de {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} para que a implementação padrão +possa restaurar o estado da hierarquia de exibições.</p> + +<p>Para saber mais sobre recriação de atividades devido a +um evento de reinicialização no tempo de execução (como quando a tela gira), consulte <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Tratar alterações no tempo de execução</a>.</p> + diff --git a/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/starting.jd b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/starting.jd new file mode 100644 index 0000000..1f8f080 --- /dev/null +++ b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/starting.jd @@ -0,0 +1,285 @@ +page.title=Iniciando uma atividade +page.tags=ciclo de vida de atividade +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>Esta lição ensina a</h2> +<ol> + <li><a href="#lifecycle-states">Entender o ciclo de vida do retorno de chamada</a></li> + <li><a href="#launching-activity">Especificar a atividade da tela de início do aplicativo</a></li> + <li><a href="#Create">Criar uma nova instância</a></li> + <li><a href="#Destroy">Destruir a atividade</a></li> +</ol> + + <h2>Leia também</h2> + <ul> + <li><a href="{@docRoot}guide/components/activities.html">Atividades</a></li> + </ul> + +<h2>Tente</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Baixar a demonstração</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + + </div> +</div> + +<p>Diferente de outros paradigmas de programação em que os aplicativos são lançados com um método {@code main()}, o +sistema Android inicia o código em uma instância {@link android.app.Activity} chamando métodos específicos +de retorno de chamada que correspondem a determinados estágios do seu +ciclo de vida. Há uma sequência de métodos de retorno de chamada que iniciam uma atividade e uma sequência de métodos +de retorno de chamada que interrompem uma atividade.</p> + +<p>Essa lição proporciona uma visão geral dos métodos do ciclo de vida mais importantes e mostra como +lidar com o primeiro retorno de chamada do ciclo de vida que cria uma nova instância de sua atividade.</p> + + + +<h2 id="lifecycle-states">Entender o ciclo de vida do retorno de chamada</h2> + +<p>Durante a vida de uma atividade, o sistema chama um núcleo principal de métodos do ciclo de vida em +uma sequência parecida com uma pirâmide em degraus. Isto é, cada estágio do +ciclo de vida da atividade corresponde a um degrau da pirâmide. Conforme o sistema cria uma nova instância de atividade, +cada método de retorno de chamada leva o estado da atividade um degrau acima. O topo da pirâmide é o +ponto em que a atividade funciona em primeiro plano e o usuário pode interagir com ela.</p> + +<p>Conforme o usuário começa a sair da atividade, o sistema chama outros métodos que a movem +de volta em direção à base da pirâmide para desfazer a atividade. Em alguns casos, a atividade é movida +parcialmente em direção à base da pirâmide e aguarda (como quando o usuário muda para outro aplicativo), no +ponto em que a atividade é movida novamente em direção ao topo (se o usuário retornar à atividade) e +reinicia de onde o usuário parou.</p> + + +<img src="{@docRoot}images/training/basics/basic-lifecycle.png" /> +<p class="img-caption"><strong>Figura 1.</strong> Ilustração simplificada do ciclo de vida +da atividade, expressa como pirâmide em degraus. Isso mostra que, para cada retorno de chamada usado para levar +uma atividade ao estado de Reiniciado, em direção ao topo, há um método de retorno de chamada +que leva a atividade um degrau abaixo. A atividade também pode retornar ao estado de retomada do +estado de Pausado e Interrompido.</p> + + +<p>Dependendo da complexidade de sua atividade, não há necessidade de implementar todos os +métodos do ciclo de vida. No entanto, é importante compreender cada um e implementar apenas aqueles que +garantem que seu aplicativo tenha o desempenho esperado pelo usuário. A implementação adequada dos métodos do ciclo de vida da atividade +garante que seu aplicativo tenha um bom desempenho em vários sentidos, incluindo que:</p> +<ul> + <li>Não apresente falhas se o usuário receber uma chamada telefônica ou mudar para outro aplicativo +enquanto estiver usando o seu aplicativo.</li> + <li>Não consuma recursos importantes do sistema quando o usuário não estiver utilizando +ativamente o aplicativo.</li> + <li>Não perca o progresso do usuário se ele sair do aplicativo e retornar +mais tarde.</li> + <li>Não apresente falhas nem perca o progresso do usuário quando a orientação da tela mudar entre +paisagem e retrato.</li> +</ul> + +<!-- +<p class="table-caption"><strong>Table 1.</strong> Activity lifecycle state pairs and callback +methods.</p> +<table> + <tr> + <th scope="col">Lifecycle State</th> + <th scope="col">Startup Method</th> + <th scope="col">Teardown Method</th> + </tr> + <tr> + <td>Created / Destroyed</td> + <td>{@link android.app.Activity#onCreate onCreate()}</td> + <td>{@link android.app.Activity#onDestroy()}</td> + </tr> + <tr> + <td>Started / Stopped</td> + <td>{@link android.app.Activity#onStart()}</td> + <td>{@link android.app.Activity#onStop()}</td> + </tr> + <tr> + <td>Resumed / Resumed</td> + <td>{@link android.app.Activity#onResume()}</td> + <td>{@link android.app.Activity#onPause()}</td> + </tr> +</table> +--> + +<p>Como você aprenderá nas lições seguintes, há várias situações de transições de +atividades entre estados diferentes, como ilustrado na figura 1. No entanto, apenas três +desses estados podem ser estáticos. Isto é, a atividade pode existir em um de apenas três estados por +um período de tempo maior:</p> +<dl> + <dt>Reiniciado</dt> + <dd>Neste estado, a atividade está no primeiro plano e o usuário consegue interagir. +(Também chamado de estado de funcionamento.)</dd> + <dt>Pausado</dt> + <dd>Neste estado, a atividade está parcialmente obscurecida por outra atividade. A +outra atividade que está em primeiro plano é semitransparente ou não cobre totalmente a tela. A +atividade pausada não recebe entrada do usuário e não executa nenhum código. + <dt>Interrompido</dt> + <dd>Neste estado, a atividade está completamente oculta e não é visível para o usuário. Considera-se +que está em segundo plano. Enquanto interrompido, a instância da atividade e todas as +informações de estado, como variáveis de membro, são retidas, mas não é possível executar nenhum código.</dd> +</dl> + +<p>Os outros estados (Criado e Iniciado) são temporários e o sistema rapidamente se move rapidamente de um +estado a outro chamando o próximo método de retorno de chamada do ciclo de vida. Isto é, depois que o sistema chama +{@link android.app.Activity#onCreate onCreate()}, ele rapidamente chama {@link +android.app.Activity#onStart()}, que é seguido por {@link +android.app.Activity#onResume()}.</p> + +<p>Isso é tudo que precisamos dizer sobre o ciclo de vida básico de atividades. Agora você aprenderá sobre alguns dos +comportamentos específicos do ciclo de vida.</p> + + + +<h2 id="launching-activity">Especificar a atividade da tela de início do aplicativo</h2> + +<p>Quando o usuário seleciona seu aplicativo na tela inicial, o sistema chama o método {@link +android.app.Activity#onCreate onCreate()} para {@link android.app.Activity} no aplicativo +que foi declarado como atividade da “inicializador” (ou “principal”). Essa é a atividade que serve como +ponto de entrada principal da interface do usuário do aplicativo.</p> + +<p>É possível definir qual atividade será usada como principal no arquivo manifesto do Android, <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">{@code AndroidManifest.xml}</a>, que está +na raiz do diretório do seu projeto.</p> + +<p>A principal atividade do aplicativo deve ser declarada no manifesto com um <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a> que inclui a ação {@link +android.content.Intent#ACTION_MAIN MAIN} e categoria +{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER}. Por exemplo:</p> + +<pre> +<activity android:name=".MainActivity" android:label="@string/app_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> +</activity> +</pre> + +<p class="note"><strong>Observação:</strong> ao criar um novo projeto do Android com ferramentas +SDK Android, os arquivos padrões do projeto incluem uma classe {@link android.app.Activity} que é declarada no +manifesto com esse filtro.</p> + +<p>Se a ação {@link android.content.Intent#ACTION_MAIN MAIN} nem a categoria +{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} forem declaradas para uma de suas +atividades, o ícone do aplicativo não aparecerá na lista de aplicativos da tela inicial.</p> + + + +<h2 id="Create">Criar uma nova instância</h2> + +<p>A maioria dos aplicativos tem várias atividades que permitem ao usuário realizar diferentes ações. +Tanto para a atividade principal criada quando o usuário clica no ícone do aplicativo quanto uma +atividade diferente que o aplicativo inicia em resposta à ação do usuário, o sistema cria +cada nova instância do {@link android.app.Activity} chamando o método {@link +android.app.Activity#onCreate onCreate()}.</p> + +<p>Implemente o método {@link android.app.Activity#onCreate onCreate()} para realizar a lógica básica +de inicialização do aplicativo que deve acontecer apenas uma vez na vida completa da atividade. Por +exemplo, sua implementação do {@link android.app.Activity#onCreate onCreate()} deve definir a +interface do usuário e possivelmente instanciar algumas variáveis de escopo de classe.</p> + +<p>Por exemplo, o seguinte modelo do método {@link android.app.Activity#onCreate onCreate()} + mostra alguns códigos que realizam configurações fundamentais para a atividade, como +declarar a interface do usuário (definida em arquivo de layout XML), definir variáveis de membro +e configurar parte da interface do usuário.</p> + +<pre> +TextView mTextView; // Member variable for text view in the layout + +@Override +public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Set the user interface layout for this Activity + // The layout file is defined in the project res/layout/main_activity.xml file + setContentView(R.layout.main_activity); + + // Initialize member TextView so we can manipulate it later + mTextView = (TextView) findViewById(R.id.text_message); + + // Make sure we're running on Honeycomb or higher to use ActionBar APIs + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + // For the main activity, make sure the app icon in the action bar + // does not behave as a button + ActionBar actionBar = getActionBar(); + actionBar.setHomeButtonEnabled(false); + } +} +</pre> + +<p class="caution"><strong>Cuidado:</strong> utilizar {@link android.os.Build.VERSION#SDK_INT} para +evitar que sistemas antigos executem novas APIs funciona apenas no Android 2.0 (API Nível +5) e versões posteriores. Versões mais antigas encontram uma exceção no tempo de execução.</p> + +<p>Depois que o {@link android.app.Activity#onCreate onCreate()} termina de executar, o sistema +chama os métodos {@link android.app.Activity#onStart()} e {@link android.app.Activity#onResume()} + em rápida sucessão. A atividade nunca reside nos estados Criado ou Iniciado. Tecnicamente, a +atividade se torna visível para o usuário quando {@link android.app.Activity#onStart()} é chamado, mas +{@link android.app.Activity#onResume()} é executado e a atividade permanece no estado Reiniciado +até que algo diferente ocorra, como o recebimento de uma chamada telefônica, o usuário +navegar para outra atividade ou a tela do dispositivo desligar.</p> + +<p>Nas próximas lições, você verá como outros métodos de inicialização, {@link +android.app.Activity#onStart()} e {@link android.app.Activity#onResume()}, podem ajudar +no ciclo de vida da atividade quando utilizado para reiniciar a atividade dos estados Pausado e Interrompido.</p> + +<p class="note"><strong>Observação:</strong> o método {@link android.app.Activity#onCreate onCreate()} +inclui um parâmetro chamado <code>savedInstanceState</code>, que será discutido mais adiante +na lição <a href="recreating.html">Recriando uma atividade</a>.</p> + + +<img src="{@docRoot}images/training/basics/basic-lifecycle-create.png" /> +<p class="img-caption"><strong>Figura 2.</strong> Outra ilustração da estrutura do ciclo de vida da +atividade com ênfase nos três retornos de chamada principais que o sistema chama na sequência quando +cria uma nova instância da atividade: {@link android.app.Activity#onCreate onCreate()}, {@link +android.app.Activity#onStart()} e{@link android.app.Activity#onResume()}. Depois que esta sequência de +retornos de chamada for concluída, a atividade chega ao estado Reiniciado em que os usuários podem interagir com a +atividade até que mude para outra atividade.</p> + + + + + + + +<h2 id="Destroy">Destruir a atividade</h2> + +<p>Embora o retorno de chamada do primeiro ciclo de vida da atividade seja {@link android.app.Activity#onCreate +onCreate()}, o último retorno de chamada será {@link android.app.Activity#onDestroy}. O sistema chama +este método na atividade como o último +sinal de que a instância da atividade está sendo completamente removida da memória do sistema.</p> + +<p>A maioria dos aplicativos não exige a implementação desse método porque referências de classe locais são destruídas +com a atividade, que realiza a maior parte da limpeza durante {@link +android.app.Activity#onPause} e {@link android.app.Activity#onStop}. No entanto, se a +atividade incluir threads de segundo plano criados durante {@link +android.app.Activity#onCreate onCreate()} ou outro recurso de longa execução que pode +vazar memória se não forem fechados adequadamente, você deve finalizá-los durante {@link +android.app.Activity#onDestroy}.</p> + +<pre> +@Override +public void onDestroy() { + super.onDestroy(); // Always call the superclass + + // Stop method tracing that the activity started during onCreate() + android.os.Debug.stopMethodTracing(); +} +</pre> + +<p class="note"><strong>Observação:</strong> o sistema chama {@link android.app.Activity#onDestroy} +depois de ter chamado {@link android.app.Activity#onPause} e {@link +android.app.Activity#onStop} em qualquer situação, exceto uma: quando você chama {@link +android.app.Activity#finish()} pelo método {@link android.app.Activity#onCreate onCreate()} +. Em alguns casos, como quando a atividade assume a posição temporária de tomadora de decisões para +lançar outra atividade, chame {@link android.app.Activity#finish()} pelo {@link +android.app.Activity#onCreate onCreate()} para destruir a atividade. Nesse caso, o sistema +chama imediatamente {@link android.app.Activity#onDestroy} sem chamar qualquer outro + método do ciclo de vida.</p> diff --git a/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/stopping.jd b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/stopping.jd new file mode 100644 index 0000000..2eba377 --- /dev/null +++ b/docs/html-intl/intl/pt-br/training/basics/activity-lifecycle/stopping.jd @@ -0,0 +1,187 @@ +page.title=Interrompendo e reiniciando uma atividade +page.tags=ciclo de vida da atividade +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>Esta lição ensina a</h2> + <ol> + <li><a href="#Stop">Interromper sua atividade</a></li> + <li><a href="#Start">Iniciar/reiniciar sua atividade</a></li> + </ol> + + <h2>Leia também</h2> + <ul> + <li><a href="{@docRoot}guide/components/activities.html">Atividades</a> + </li> + </ul> + +<h2>Tente</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Baixar a demonstração</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + + </div> +</div> + +<p>Interromper e reiniciar adequadamente sua atividade é um processo importante no ciclo de vida da atividade +que garante que o usuário perceba que o aplicativo está sempre ativo e não perca o progresso. +Há alguns cenários fundamentais em que sua atividade é interrompida e reiniciada:</p> + +<ul> + <li>O usuário abre a janela Aplicativos Utilizados Recentemente e alterna de um aplicativo a outro. A +atividade em seu aplicativo atualmente em primeiro plano é interrompida. Se o usuário retornar ao +aplicativo pelo ícone de inicialização da tela inicial ou da janela Aplicativos Utilizados Recentemente, a atividade é reiniciada.</li> + <li>O usuário executar uma ação em seu aplicativo que inicia uma nova atividade. A atividade atual +é interrompida quando a segunda é criada. Se o usuário pressionar o botão <em>Voltar</em> +, a primeira atividade será reiniciada.</li> + <li>Se o usuário receber uma chamada telefônica enquanto estiver usando o seu aplicativo.</li> +</ul> + +<p>A classe {@link android.app.Activity} fornece dois métodos do ciclo de vida, {@link +android.app.Activity#onStop()} e {@link android.app.Activity#onRestart()}, que permite que você +decida exatamente como a atividade responderá à interrupção e reinicialização. Diferentemente do estado pausado, +que identifica obstruções parciais da interface de usuário, o estado interrompido garante que a interface não fique +visível e que o foco do usuário permaneça em outra atividade (ou mesmo outro aplicativo).</p> + +<p class="note"><strong>Observação:</strong> como o sistema retém a instância {@link android.app.Activity} +na memória quando interrompida, talvez não seja necessário implementar os métodos +{@link android.app.Activity#onStop()} e {@link android.app.Activity#onRestart()} (ou mesmo {@link +android.app.Activity#onStart()}. Para a maioria das atividades que são relativamente simples, a +atividade será interrompida e reiniciada normalmente e talvez seja necessário apenas usar {@link +android.app.Activity#onPause()} para pausar ações em andamento e desconectar dos recursos do sistema.</p> + +<img src="{@docRoot}images/training/basics/basic-lifecycle-stopped.png" /> +<p class="img-caption"><strong>Figura 1.</strong> Quando o usuário sai da atividade, o sistema +chama {@link android.app.Activity#onStop onStop()} para interrompê-la (1). Se o usuário retornar +enquanto a atividade estiver interrompida, o sistema chama {@link android.app.Activity#onRestart onRestart()} +(2), rapidamente seguido por {@link android.app.Activity#onStart onStart()} (3) e {@link +android.app.Activity#onResume()} (4). Observe que independentemente do que tenha causado a interrupção +da atividade, o sistema sempre chama {@link android.app.Activity#onPause onPause()} antes de chamar {@link +android.app.Activity#onStop onStop()}.</p> + + + +<h2 id="Stop">Interromper sua atividade</h2> + +<p>Quando sua atividade recebe uma chamada para o método {@link android.app.Activity#onStop()}, não +está mais visível e deve liberar quase todos os recursos que não foram necessários enquanto o usuário não +estiver utilizando. Quando a atividade for interrompida, o sistema pode destruir a instância se for necessário para +recuperar memória do sistema. Em casos extremos, o sistema pode simplesmente desligar o processo do aplicativo sem +chamar o retorno de chamada{@link android.app.Activity#onDestroy()} final da atividade, portanto, é importante +usar {@link android.app.Activity#onStop()} para liberar recursos que podem vazar memória.</p> + +<p>Embora o método {@link android.app.Activity#onPause onPause()} seja chamado antes de +{@link android.app.Activity#onStop()}, use {@link android.app.Activity#onStop onStop()} +para executar operações de desligamento maiores, que exigem mais da CPU, como escrever informação no +banco de dados.</p> + +<p>Por exemplo, esta é uma implementação de {@link android.app.Activity#onStop onStop()} que +salva os conteúdos de uma nota de rascunho no armazenamento persistente:</p> + +<!-- TODO: Find a better example for onStop, because this kind of thing should probably use a +separate thread but that's too complicated to show here. --> +<pre> +@Override +protected void onStop() { + super.onStop(); // Always call the superclass method first + + // Save the note's current draft, because the activity is stopping + // and we want to be sure the current note progress isn't lost. + ContentValues values = new ContentValues(); + values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText()); + values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle()); + + getContentResolver().update( + mUri, // The URI for the note to update. + values, // The map of column names and new values to apply to them. + null, // No SELECT criteria are used. + null // No WHERE columns are used. + ); +} +</pre> + +<p>Quando sua atividade é interrompida, o objeto {@link android.app.Activity} é mantido na memória +e é chamado novamente quando a atividade é reiniciada. Não é necessário reiniciar componentes que foram +criados durante qualquer método de retorno de chamada que leve ao estado Reiniciado. O sistema também +tem controle do estado atual de cada {@link android.view.View} no layout. Portanto, se o usuário +inserir um texto em um widget do {@link android.widget.EditText}, o conteúdo será retido e você não +precisará salvar e restaurar.</p> + +<p class="note"><strong>Observação:</strong> mesmo que o sistema destrua sua atividade enquanto estiver interrompida, +ele ainda mantém o estado do objeto {@link android.view.View} (como texto em {@link +android.widget.EditText}) em um {@link android.os.Bundle} (um blob de pares de valores-chave) e os restaura +se o usuário navegar de volta para a mesma instância da atividade (a <a href="recreating.html">próxima lição</a> falará mais sobre uso do {@link android.os.Bundle} para salvar +outros dados do estado caso sua atividade seja destruída e recriada).</p> + + + +<h2 id="Start">Iniciar/reiniciar sua atividade</h2> + +<p>Quando sua atividade voltar ao primeiro plano do estado interrompido, ela recebe uma chamada para +{@link android.app.Activity#onRestart()}. O sistema também chama o método {@link +android.app.Activity#onStart()}, que acontece sempre que a atividade se tornar visível +(ao ser reiniciada ou criada pela primeira vez). No entanto, o método {@link +android.app.Activity#onRestart()} é chamado apenas quando a atividade é reiniciada do +estado interrompido. Portanto, é possível usá-la para executar trabalhos de restauração especiais necessários apenas se +a atividade tiver sido interrompida, mas não destruída.</p> + +<p>Dificilmente um aplicativo precisará usar {@link android.app.Activity#onRestart()} para restaurar +o estado da atividade. Portanto, não há diretrizes para este método que se apliquem à +população geral de aplicativos. Contudo, como espera-se que o método {@link android.app.Activity#onStop()} +limpe todos os recursos da atividade, será necessário instanciá-los +quando a atividade for reiniciada. Ainda assim, será necessário instanciá-los quando a atividade for criada +pela primeira vez (quando não houver instâncias existentes da atividade). Por esse motivo, recomenda-se +utilizar o método de retorno de chamada {@link android.app.Activity#onStart()} como contrapartida +ao método {@link android.app.Activity#onStop()}, porque o sistema chama {@link +android.app.Activity#onStart()} quando cria sua atividade e quando reinicia a +atividade do estado interrompido.</p> + +<p>Por exemplo, como o usuário pode ter ficado longe do aplicativo por um longo período +, o método {@link android.app.Activity#onStart()} é uma boa forma de confirmar se +os recursos do sistema exigidos estão habilitados:</p> + +<pre> +@Override +protected void onStart() { + super.onStart(); // Always call the superclass method first + + // The activity is either being restarted or started for the first time + // so this is where we should make sure that GPS is enabled + LocationManager locationManager = + (LocationManager) getSystemService(Context.LOCATION_SERVICE); + boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); + + if (!gpsEnabled) { + // Create a dialog here that requests the user to enable GPS, and use an intent + // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action + // to take the user to the Settings screen to enable GPS when they click "OK" + } +} + +@Override +protected void onRestart() { + super.onRestart(); // Always call the superclass method first + + // Activity being restarted from stopped state +} +</pre> + + + + +<p>Quando o sistema destrói a atividade, ele chama o método {@link android.app.Activity#onDestroy()} +para seu {@link android.app.Activity}. Como talvez a maior parte de +seus recursos tenha sido liberada com {@link android.app.Activity#onStop()}, no momento em que você receber a chamada para {@link +android.app.Activity#onDestroy()}, não haverá muito a ser feito pelos aplicativos. Esse método é sua +última chance de limpar os recursos que levariam a vazamento de memória. Portanto, certifique-se de que +outros threads sejam destruídos e outras ações de longa execução como o rastreamento de métodos também estejam +interrompidas.</p> + diff --git a/docs/html-intl/intl/pt-br/training/basics/data-storage/databases.jd b/docs/html-intl/intl/pt-br/training/basics/data-storage/databases.jd new file mode 100644 index 0000000..37d0d43 --- /dev/null +++ b/docs/html-intl/intl/pt-br/training/basics/data-storage/databases.jd @@ -0,0 +1,317 @@ +page.title=Salvando dados em bancos de dados do SQL +page.tags=armazenamento de dados +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + + +<div id="tb-wrapper"> +<div id="tb"> + +<h2>Esta lição ensina a</h2> +<ol> + <li><a href="#DefineContract">Definir um esquema e contrato</a></li> + <li><a href="#DbHelper">Criar um banco de dados usando de um SQL Helper</a></li> + <li><a href="#WriteDbRow">Colocar informações no banco de dados</a></li> + <li><a href="#ReadDbRow">Ler informações de um banco de dados</a></li> + <li><a href="#DeleteDbRow">Excluir informações de um banco de dados</a></li> + <li><a href="#UpdateDbRow">Atualizar um banco de dados</a></li> +</ol> + +<h2>Leia também</h2> +<ul> + <li><a href="{@docRoot}guide/topics/data/data-storage.html#db">Usando bancos de dados</a></li> +</ul> + +<!-- +<h2>Try it out</h2> + +<div class="download-box"> + <a href="{@docRoot}shareables/training/Sample.zip" class="button">Download the sample</a> + <p class="filename">Sample.zip</p> +</div> +--> + +</div> +</div> + + +<p>Salvar dados em um banco de dados é ideal para dados que se repetem ou estruturados, +como informações de contato. Esta lição assume que você esteja +familiarizado com bancos de dados do SQL em gera, e o ajuda a começar a trabalhar com bancos de dados +do SQLite no Android. As APIs necessárias para usar um banco de dados +no Android estão disponíveis no pacote {@link android.database.sqlite}.</p> + + +<h2 id="DefineContract">Definir um esquema e contrato</h2> + +<p>Um dos princípios mais importantes de bancos de dados do SQL é o esquema: uma declaração +formal de como o banco de dados é organizado. O esquema é refletido nas declarações SQL +usadas na criação do banco de dados. É aconselhável +criar uma classe de acompanhamento, conhecida como classe de <em>contrato</em>, que especifica claramente +o layout do esquema de forma sistemática e autodocumentada.</p> + +<p>Uma classe de contrato é o contêiner das constantes que definem nomes para URIs, +tabelas e colunas. A classe de contrato permite usar as mesmas constantes +em outras classes no mesmo pacote. Permite que você altere o nome da +coluna em um local e que a mudança se propague pelos seus códigos.</p> + +<p>Uma boa forma de organizar uma classe de contrato é colocar definições que sejam +globais para todo o banco de dados no nível raiz da classe. Crie uma classe +interna para cada tabela que enumera suas colunas.</p> + +<p class="note"><strong>Observação:</strong> implementando a interface {@link +android.provider.BaseColumns}, sua classe interior pode herdar um campo-chave +primário chamado {@code _ID} que algumas classes do Android, como adaptadores de cursor, esperam + que você tenha. Não é uma obrigatório, mas pode ajudar para um trabalho mais harmonioso com o banco de dados +no framework do Android.</p> + +<p>Por exemplo, este trecho define o nome da tabela e das colunas para uma +única tabela:</p> + + +<pre> +public final class FeedReaderContract { + // To prevent someone from accidentally instantiating the contract class, + // give it an empty constructor. + public FeedReaderContract() {} + + /* Inner class that defines the table contents */ + public static abstract class FeedEntry implements BaseColumns { + public static final String TABLE_NAME = "entry"; + public static final String COLUMN_NAME_ENTRY_ID = "entryid"; + public static final String COLUMN_NAME_TITLE = "title"; + public static final String COLUMN_NAME_SUBTITLE = "subtitle"; + ... + } +} +</pre> + + + +<h2 id="DbHelper">Criar um banco de dados usando de um SQL Helper</h2> + +<p>Uma vez definidos o visual dos bancos de dados, implemente métodos +que criam e cuidam do banco de dados e das tabelas. Aqui estão algumas declarações +comuns para criar e exclui a tabela:</P> + +<pre> +private static final String TEXT_TYPE = " TEXT"; +private static final String COMMA_SEP = ","; +private static final String SQL_CREATE_ENTRIES = + "CREATE TABLE " + FeedEntry.TABLE_NAME + " (" + + FeedEntry._ID + " INTEGER PRIMARY KEY," + + FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP + + FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP + + ... // Any other options for the CREATE command + " )"; + +private static final String SQL_DELETE_ENTRIES = + "DROP TABLE IF EXISTS " + FeedEntry.TABLE_NAME; +</pre> + +<p>Da mesma forma você salva arquivos no <a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">armazenamento +interno</a> do dispositivo, o Android armazena seu banco de dados no espaço privado do disco associado +ao aplicativo. Seus dados estão protegidos porque, por padrão, essa área não +pode ser acessada por outros aplicativos.</p> + +<p>Um conjunto de APIs está disponível na classe {@link +android.database.sqlite.SQLiteOpenHelper}. +Ao usar esta classe para obter referências para seu banco de dados, o sistema +realiza operações +de possível longa execução para criar e atualizar o banco de dados apenas quando +necessário e <em>não durante a inicialização do aplicativo</em>. Basta chamar +{@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} ou +{@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase}.</p> + +<p class="note"><strong>Observação:</strong> devido à possibilidade de serem de longa execução, +certifique-se que chamar {@link +android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} ou {@link +android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} em um thread de segundo plano, +como {@link android.os.AsyncTask} ou {@link android.app.IntentService}.</p> + +<p>Para usar {@link android.database.sqlite.SQLiteOpenHelper}, crie uma subclasse que +substitua os métodos de retorno de chamada {@link +android.database.sqlite.SQLiteOpenHelper#onCreate onCreate()}, {@link +android.database.sqlite.SQLiteOpenHelper#onUpgrade onUpgrade()} e {@link +android.database.sqlite.SQLiteOpenHelper#onOpen onOpen()}. Também é possível +implementar {@link android.database.sqlite.SQLiteOpenHelper#onDowngrade onDowngrade()}, +mas não é obrigatório.</p> + +<p>Por exemplo, esta é uma implementação de {@link +android.database.sqlite.SQLiteOpenHelper} que utiliza alguns dos comandos exibidos abaixo:</p> + +<pre> +public class FeedReaderDbHelper extends SQLiteOpenHelper { + // If you change the database schema, you must increment the database version. + public static final int DATABASE_VERSION = 1; + public static final String DATABASE_NAME = "FeedReader.db"; + + public FeedReaderDbHelper(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + public void onCreate(SQLiteDatabase db) { + db.execSQL(SQL_CREATE_ENTRIES); + } + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + // This database is only a cache for online data, so its upgrade policy is + // to simply to discard the data and start over + db.execSQL(SQL_DELETE_ENTRIES); + onCreate(db); + } + public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { + onUpgrade(db, oldVersion, newVersion); + } +} +</pre> + +<p>Para acessar seu banco de dados, instancie sua subclasse de {@link +android.database.sqlite.SQLiteOpenHelper}:</p> + +<pre> +FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext()); +</pre> + + + + +<h2 id="WriteDbRow">Colocar informações no banco de dados</h2> + +<p>Coloque dados no banco de dados transmitindo um objeto {@link android.content.ContentValues} + para o método {@link android.database.sqlite.SQLiteDatabase#insert insert()}.</p> + +<pre> +// Gets the data repository in write mode +SQLiteDatabase db = mDbHelper.getWritableDatabase(); + +// Create a new map of values, where column names are the keys +ContentValues values = new ContentValues(); +values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id); +values.put(FeedEntry.COLUMN_NAME_TITLE, title); +values.put(FeedEntry.COLUMN_NAME_CONTENT, content); + +// Insert the new row, returning the primary key value of the new row +long newRowId; +newRowId = db.insert( + FeedEntry.TABLE_NAME, + FeedEntry.COLUMN_NAME_NULLABLE, + values); +</pre> + +<p>Este primeiro argumento para {@link android.database.sqlite.SQLiteDatabase#insert insert()} +é apenas o nome da tabela. O segundo argumento fornece +o nome de uma coluna em que o framework pode inserir NULL caso o +{@link android.content.ContentValues} esteja vazio (se você definir como {@code "null"}, +o framework não inserirá uma linha quando não houver valores).</p> + + + + +<h2 id="ReadDbRow">Ler informações de um banco de dados</h2> + +<p>Para ler de um banco de dados, utilize o método {@link android.database.sqlite.SQLiteDatabase#query query()} +, transmitindo seus critérios de seleção e colunas desejadas. +O método combina elementos de {@link android.database.sqlite.SQLiteDatabase#insert insert()} + e {@link android.database.sqlite.SQLiteDatabase#update update()}, exceto que a lista da coluna +define os dados que serão analisados e não os dados a serem inseridos. Os resultados da consulta +são retornados em um objeto {@link android.database.Cursor}.</p> + +<pre> +SQLiteDatabase db = mDbHelper.getReadableDatabase(); + +// Define a <em>projection</em> that specifies which columns from the database +// you will actually use after this query. +String[] projection = { + FeedEntry._ID, + FeedEntry.COLUMN_NAME_TITLE, + FeedEntry.COLUMN_NAME_UPDATED, + ... + }; + +// How you want the results sorted in the resulting Cursor +String sortOrder = + FeedEntry.COLUMN_NAME_UPDATED + " DESC"; + +Cursor c = db.query( + FeedEntry.TABLE_NAME, // The table to query + projection, // The columns to return + selection, // The columns for the WHERE clause + selectionArgs, // The values for the WHERE clause + null, // don't group the rows + null, // don't filter by row groups + sortOrder // The sort order + ); +</pre> + +<p>Para ver uma linha no cursor, utilize um dos métodos de movimento {@link android.database.Cursor}, +que sempre deverão ser chamados antes de começar a ler valores. Geralmente, deve-se iniciar +chamando {@link android.database.Cursor#moveToFirst}, que coloca a “posição leitura” na +primeira entrada nos resultados. Para cada linha, você pode ler um valor de coluna chamando um dos métodos GET +{@link android.database.Cursor}, como {@link android.database.Cursor#getString +getString()} ou {@link android.database.Cursor#getLong getLong()}. Para cada um dos métodos GET, +você deve transmitir a posição de índice da coluna desejada, que pode ser obtida chamando +{@link android.database.Cursor#getColumnIndex getColumnIndex()} ou +{@link android.database.Cursor#getColumnIndexOrThrow getColumnIndexOrThrow()}. +Por exemplo:</p> + +<pre> +cursor.moveToFirst(); +long itemId = cursor.getLong( + cursor.getColumnIndexOrThrow(FeedEntry._ID) +); +</pre> + + + + +<h2 id="DeleteDbRow">Excluir informações de um banco de dados</h2> + +<p>Para excluir linhas de uma tabela, forneça os critérios de seleção que as +identifique. A API do banco de dados oferece um mecanismo para criar +critérios de seleção que protegem contra injeção do SQL. O mecanismo divide a +especificação da seleção em uma cláusula e argumentos de seleção. A +cláusula define a coluna a se olhar e também permite combinar testes de +coluna. Os argumentos são valores para testes comparativos que são dependentes dentro de uma cláusula. +Como o resultado não é tratado da mesma forma que uma declaração SQL comum, ele fica +imune à injeção de SQL.</p> + +<pre> +// Define 'where' part of query. +String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?"; +// Specify arguments in placeholder order. +String[] selectionArgs = { String.valueOf(rowId) }; +// Issue SQL statement. +db.delete(table_name, selection, selectionArgs); +</pre> + + + +<h2 id="UpdateDbRow">Atualizar um banco de dados</h2> + +<p>Quando precisar alterar um subconjunto dos valores de seu banco de dados, utilize o método {@link +android.database.sqlite.SQLiteDatabase#update update()}.</p> + +<p>A atualização da tabela combina a sintaxe de valores do conteúdo de {@link +android.database.sqlite.SQLiteDatabase#insert insert()} com a sintaxe {@code where} de +{@link android.database.sqlite.SQLiteDatabase#delete delete()}.</p> + +<pre> +SQLiteDatabase db = mDbHelper.getReadableDatabase(); + +// New value for one column +ContentValues values = new ContentValues(); +values.put(FeedEntry.COLUMN_NAME_TITLE, title); + +// Which row to update, based on the ID +String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?"; +String[] selectionArgs = { String.valueOf(rowId) }; + +int count = db.update( + FeedReaderDbHelper.FeedEntry.TABLE_NAME, + values, + selection, + selectionArgs); +</pre> + diff --git a/docs/html-intl/intl/pt-br/training/basics/data-storage/files.jd b/docs/html-intl/intl/pt-br/training/basics/data-storage/files.jd new file mode 100644 index 0000000..d071d39 --- /dev/null +++ b/docs/html-intl/intl/pt-br/training/basics/data-storage/files.jd @@ -0,0 +1,379 @@ +page.title=Salvando arquivos +page.tags=armazenamento de dados +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + + +<div id="tb-wrapper"> +<div id="tb"> + +<h2>Esta lição ensina a</h2> +<ol> + <li><a href="#InternalVsExternalStorage">Escolher entre armazenamento interno e externo</a></li> + <li><a href="#GetWritePermission">Obter permissões para armazenamento externo</a></li> + <li><a href="#WriteInternalStorage">Salvar arquivos em armazenamento interno</a></li> + <li><a href="#WriteExternalStorage">Salvar arquivos em armazenamento externo</a></li> + <li><a href="#GetFreeSpace">Consultar espaço livre</a></li> + <li><a href="#DeleteFile">Excluir um arquivo</a></li> +</ol> + +<h2>Leia também</h2> +<ul> + <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">Utilizando armazenamento +interno</a></li> + <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesExternal">Utilizando armazenamento +externo</a></li> +</ul> + +</div> +</div> + +<p>O Android usa um sistema de arquivos +parecido com sistemas de arquivos em disco de outras plataformas. Esta lição explica +como trabalhar com o sistema de arquivos Android para ler e gravar arquivos com APIs {@link java.io.File} +.</p> + +<p>Um objeto {@link java.io.File} é adequado para ler ou gravar grandes quantidades de dados em +ordens crescente sem pular nenhum item. Por exemplo, é bom para arquivos de imagens ou +qualquer troca executada por uma rede.</p> + +<p>Esta lição demonstra como executar tarefas básicas relacionadas a arquivos em seu aplicativo. +Assume-se que você já esteja familiarizado com os fundamentos do sistema de arquivos Linux e com +APIs de entrada/saída de arquivos padrão no {@link java.io}.</p> + + +<h2 id="InternalVsExternalStorage">Escolher entre armazenamento interno e externo</h2> + +<p>Todos os dispositivos Android têm duas áreas de armazenamento de arquivos: armazenamento “interno” e “externo”. Estes nomes +têm origem no início do Android, quando a maior parte de seus dispositivos oferecia memória embutida não volátil +(armazenamento interno), além de uma mídia de armazenamento removível, como micro cartões SD (armazenamento externo). +Alguns dispositivos dividem o espaço de armazenamento permanente em partições “interna” e “externa”. Assim, mesmo +sem uma mídia de armazenamento removível, sempre há dois espaços de armazenamento e +o comportamento da API permanece inalterado independentemente da remoção do armazenamento externo. +A lista a seguir resume as principais informações sobre cada tipo de espaço de armazenamento.</p> + +<div class="col-5" style="margin-left:0"> +<p><b>Armazenamento interno:</b></p> +<ul> +<li>Está sempre disponível.</li> +<li>Por padrão, os arquivos salvos aqui podem apenas ser acessados pelo seu aplicativo.</li> +<li>Quando o usuário desinstala o aplicativo, o sistema exclui todos os arquivos do aplicativo salvos no +armazenamento interno.</li> +</ul> +<p>O armazenamento interno funciona melhor quando você deseja garantir que o usuário nem outros aplicativos +tenham acesso aos seus arquivos.</p> +</div> + +<div class="col-7" style="margin-right:0"> +<p><b>Armazenamento externo:</b></p> +<ul> +<li>Não está sempre disponível porque o usuário pode montar o armazenamento externo, como um armazenamento USB, + e em alguns casos, removê-lo do dispositivo.</li> +<li>É de leitura universal, ou seja, +arquivos salvos aqui podem ser lidos em outros dispositivos.</li> +<li>Quando o usuário desinstala o aplicativo, o sistema exclui todos os arquivos do aplicativo salvos aqui +apenas se estiverem salvos no diretório de {@link android.content.Context#getExternalFilesDir +getExternalFilesDir()}.</li> +</ul> +<p>O armazenamento externo é o melhor +local para arquivos que não exigem acesso restrito e para os arquivos que você deseja compartilhar +com outros aplicativos ou permitir que o usuário acesse através com um computador.</p> +</div> + + +<p class="note" style="clear:both"> +<strong>Dica:</strong> embora os aplicativos sejam instalados no armazenamento interno por +padrão, é possível especificar o atributo <a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code +android:installLocation}</a> em seu manifesto para que o aplicativo +seja instalado no armazenamento externo. Os usuários se beneficiam dessa opção quando o tamanho do APK é muito grande e +ele dispõe de maior espaço em armazenamento externo do que interno. Para obter mais +informações, consulte <a href="{@docRoot}guide/topics/data/install-location.html">Local de instalação do aplicativo</a>.</p> + + +<h2 id="GetWritePermission">Obter permissões para armazenamento externo</h2> + +<p>Para gravar no armazenamento externo, você deve solicitar a +permissão {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} em seu <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">arquivo de manifesto</a>:</p> + +<pre> +<manifest ...> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + ... +</manifest> +</pre> + +<div class="caution"><p><strong>Cuidado:</strong> +atualmente, os aplicativos podem ler o armazenamento externo +sem precisar de permissão especial. No entanto, isso será alterado em lançamentos futuros. Se seu aplicativo precisar +ler o armazenamento externo (mas não gravar nele), será necessário declarar a permissão {@link +android.Manifest.permission#READ_EXTERNAL_STORAGE}. Para garantir que o aplicativo continue +a funcionar adequadamente, declare essa permissão agora antes que as mudanças entrem em vigor.</p> +<pre> +<manifest ...> + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + ... +</manifest> +</pre> +<p>No entanto, se seu aplicativo usa a permissão {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} +, já existe uma permissão implícita para leitura do armazenamento externo.</p> +</div> + +<p>Não é necessária permissão para salvar arquivos no armazenamento +interno. Seu aplicativo sempre terá permissão para ler e +gravar arquivos em seu diretório de armazenamento interno.</p> + + + + + +<h2 id="WriteInternalStorage">Salvar arquivos em armazenamento interno</h2> + +<p>Ao salvar um arquivo no armazenamento interno, você pode obter o diretório adequado como um +{@link java.io.File} chamando um destes dois métodos:</p> + +<dl> + <dt>{@link android.content.Context#getFilesDir}</dt> + <dd>Retorna um {@link java.io.File} que representa um diretório interno para seu aplicativo.</dd> + <dt>{@link android.content.Context#getCacheDir}</dt> + <dd>Retorna um {@link java.io.File} que representa um diretório interno para os arquivos de cache temporários +de seu aplicativo. Certifique-se de excluir cada arquivo assim que não +for mais necessário e estabeleça um limite de tamanho razoável para a quantidade de memória usada em um determinado +período de tempo, como 1MB. Se o sistema começar a ficar com pouco espaço de armazenamento, ele poderá excluir arquivos de cache +sem avisar.</dd> +</dl> + +<p>Para criar um novo arquivo em um desses diretórios, use o construtor {@link +android.Manifest.permission#READ_EXTERNAL_STORAGE}, transmitindo o {@link java.io.File} fornecido por um +dos métodos acima que especifica o diretório de armazenamento interno. Por exemplo:</p> + +<pre> +File file = new File(context.getFilesDir(), filename); +</pre> + +<p>Uma outra alternativa é chamar {@link +android.content.Context#openFileOutput openFileOutput()} para obter um {@link java.io.FileOutputStream} +que grave em um arquivo salvo no seu diretório interno. O exemplo a seguir +mostra como gravar texto em um arquivo:</p> + +<pre> +String filename = "myfile"; +String string = "Hello world!"; +FileOutputStream outputStream; + +try { + outputStream = openFileOutput(filename, Context.MODE_PRIVATE); + outputStream.write(string.getBytes()); + outputStream.close(); +} catch (Exception e) { + e.printStackTrace(); +} +</pre> + +<p>Em alternativa, caso precise colocar arquivos em cache, use {@link +java.io.File#createTempFile createTempFile()}. Por exemplo, o método a seguir extrai o +nome do arquivo de {@link java.net.URL} e cria um arquivo com o mesmo nome +no diretório de cache interno de seu aplicativo.</p> + +<pre> +public File getTempFile(Context context, String url) { + File file; + try { + String fileName = Uri.parse(url).getLastPathSegment(); + file = File.createTempFile(fileName, null, context.getCacheDir()); + catch (IOException e) { + // Error while creating file + } + return file; +} +</pre> + +<p class="note"><strong>Observação:</strong> +o diretório de armazenamento interno do seu aplicativo é especificado +pelo nome do pacote do aplicativo em um local específico do sistema de arquivos Android. +Teoricamente, outros aplicativos poderão ler seus arquivos internos se você definir +o arquivo para modo leitura. No entanto, o outro aplicativo também precisaria saber o nome do pacote +do seu aplicativo e os nomes dos arquivos. Outros aplicativos não podem navegar nos diretórios internos e não têm +permissão para ler ou gravar a menos que os arquivos sejam explicitamente definidos para permitir tais ações. Portanto, +desde que você utilize {@link android.content.Context#MODE_PRIVATE} para seus arquivos no armazenamento interno, +eles não ficarão acessíveis a outros aplicativos.</p> + + + + + +<h2 id="WriteExternalStorage">Salvar arquivos em armazenamento externo</h2> + +<p>Como o armazenamento externo pode ficar indisponível, como se o usuário ativar o +armazenamento no PC ou remover o cartão SD que fornece armazenamento externo, +você deve sempre verificar se o volume está disponível antes de acessá-lo. Consulte o estado de armazenamento +externo chamando {@link android.os.Environment#getExternalStorageState}. Se o estado +retornado for igual a {@link android.os.Environment#MEDIA_MOUNTED}, os arquivos poderão ser lidos +e gravados. Os métodos a seguir ajudam a determinar a disponibilidade +de armazenamento:</p> + +<pre> +/* Checks if external storage is available for read and write */ +public boolean isExternalStorageWritable() { + String state = Environment.getExternalStorageState(); + if (Environment.MEDIA_MOUNTED.equals(state)) { + return true; + } + return false; +} + +/* Checks if external storage is available to at least read */ +public boolean isExternalStorageReadable() { + String state = Environment.getExternalStorageState(); + if (Environment.MEDIA_MOUNTED.equals(state) || + Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { + return true; + } + return false; +} +</pre> + +<p>Embora o usuário e outros aplicativos possam modificar o armazenamento externo, há duas +categorias de arquivos que deverão ser salvas aqui:</p> + +<dl> + <dt>Arquivos públicos</dt> + <dd>Arquivos que +precisam estar livremente disponíveis ao usuário e outros aplicativos. Ao desinstalar o aplicativo, +o usuário deve continuar a ter acesso a esses arquivos. + <p>Por exemplo, fotos capturadas pelo aplicativo ou outros arquivos baixados.</p> + </dd> + <dt>Arquivos privados</dt> + <dd>Arquivos que pertencem ao aplicativo e que devem ser excluídos na desinstalação +. Embora esses arquivos estejam teoricamente à disposição do usuário e de outros aplicativo por estarem +no armazenamento externo, na verdade são arquivos que não têm valor para o usuário +fora do aplicativo. Ao desinstalar o aplicativo, o sistema exclui +todos os arquivos no diretório privado externo do aplicativo. + <p>Por exemplo, recursos adicionais baixados através do aplicativo ou arquivos de mídia temporários.</p> + </dd> +</dl> + +<p>Para salvar arquivos públicos no armazenamento externo, use o método +{@link android.os.Environment#getExternalStoragePublicDirectory +getExternalStoragePublicDirectory()} para obter um {@link java.io.File} que representa +o diretório correto no armazenamento externo. O método exige um argumento que especifica +o tipo de arquivo que se deseja salvar para que possa ser logicamente organizado com outros arquivos públicos +, como {@link android.os.Environment#DIRECTORY_MUSIC} ou {@link +android.os.Environment#DIRECTORY_PICTURES}. Por exemplo:</p> + +<pre> +public File getAlbumStorageDir(String albumName) { + // Get the directory for the user's public pictures directory. + File file = new File(Environment.getExternalStoragePublicDirectory( + Environment.DIRECTORY_PICTURES), albumName); + if (!file.mkdirs()) { + Log.e(LOG_TAG, "Directory not created"); + } + return file; +} +</pre> + + +<p>Se você deseja salvar arquivos privados do aplicativo, obtenha o +diretório correto chamando {@link +android.content.Context#getExternalFilesDir getExternalFilesDir()} e informe um nome indicando +o tipo de diretório desejado. Cada diretório criado dessa forma é adicionado ao diretório principal +que contém todos os arquivos do armazenamento externo do aplicativo que o sistema exclui quando o +usuário faz a desinstalação.</p> + +<p>Por exemplo, este é um método que pode ser usado para criar um diretório para um álbum de fotos individual:</p> + +<pre> +public File getAlbumStorageDir(Context context, String albumName) { + // Get the directory for the app's private pictures directory. + File file = new File(context.getExternalFilesDir( + Environment.DIRECTORY_PICTURES), albumName); + if (!file.mkdirs()) { + Log.e(LOG_TAG, "Directory not created"); + } + return file; +} +</pre> + +<p>Se nenhum dos nomes de subdiretórios predefinidos se adequa aos arquivos, chame {@link +android.content.Context#getExternalFilesDir getExternalFilesDir()} e transmita {@code null}. Isso +retorna o diretório raiz para o diretório privado do aplicativo no armazenamento externo.</p> + +<p>Lembre-se de que {@link android.content.Context#getExternalFilesDir getExternalFilesDir()} +cria um diretório dentro de um diretório que é excluído quando o usuário desinstala o aplicativo. +Se os arquivos salvos precisarem estar disponíveis após a desinstalação do +aplicativo, como +quando seu aplicativo é uma câmera e o usuário deseja manter as fotos, use {@link android.os.Environment#getExternalStoragePublicDirectory +getExternalStoragePublicDirectory()}.</p> + + +<p>Independentemente do uso de {@link +android.os.Environment#getExternalStoragePublicDirectory +getExternalStoragePublicDirectory()} para arquivos compartilhados ou +{@link android.content.Context#getExternalFilesDir +getExternalFilesDir()} para arquivos privados do aplicativo, é importante usar +os nomes de diretório fornecidos pelas constantes de API, como +{@link android.os.Environment#DIRECTORY_PICTURES}. Esses nomes de diretório garantem +que os arquivos sejam tratados de forma adequada pelo sistema. Por exemplo, arquivos salvos em {@link +android.os.Environment#DIRECTORY_RINGTONES} são categorizados pelo scanner de mídia dos sistema como toques +e não como música.</p> + + + + +<h2 id="GetFreeSpace">Consultar espaço livre</h2> + +<p>Se você já souber antecipadamente a quantidade de dados a ser salvo, descubra se +há espaço disponível suficiente sem fazer com que um {@link +java.io.IOException} chame {@link java.io.File#getFreeSpace} ou {@link +java.io.File#getTotalSpace}. Esses métodos informam o espaço disponível atual e o +espaço total no volume de armazenamento. Essa informação ajuda a evitar o preenchimento +do volume de armazenamento além de um determinado limite.</p> + +<p>No entanto, o sistema não garante que será possível gravar a quantidade de bytes indicada +por {@link java.io.File#getFreeSpace}. Se o número retornado tiver +alguns MB além do tamanho dos dados que deseja salvar ou se o sistema de arquivos +estiver abaixo de 90% cheio, é possível continuar com segurança. +Caso contrário, não grave no armazenamento.</p> + +<p class="note"><strong>Observação:</strong> não é obrigatório verificar a quantidade de espaço disponível +antes de salvar o arquivo. É possível tentar gravar o arquivo diretamente e depois +obter um {@link java.io.IOException}, se houver. Essa ação é recomendada +caso você não saiba exatamente quanto espaço será necessário. Por exemplo, se +você alterar a codificação do arquivo antes de salvá-lo convertendo uma imagem PNG em +JPEG, não é possível saber o tamanho do arquivo antecipadamente.</p> + + + + +<h2 id="DeleteFile">Excluir um arquivo</h2> + +<p>Sempre exclua arquivos que não sejam mais necessários. A forma mais simples de apagar um +arquivo é fazer com que o arquivo de referência aberto chame {@link java.io.File#delete} por conta própria.</p> + +<pre> +myFile.delete(); +</pre> + +<p>Se o arquivo estiver salvo em armazenamento interno, é possível solicitar ao {@link android.content.Context} para localizar e +excluir o arquivo chamando {@link android.content.Context#deleteFile deleteFile()}:</p> + +<pre> +myContext.deleteFile(fileName); +</pre> + +<div class="note"> +<p><strong>Observação:</strong> quando o usuário desinstala o aplicativo, o sistema Android também +exclui:</p> +<ul> +<li>Todos os arquivos salvos no armazenamento interno</li> +<li>Todos os arquivos salvos no armazenamento externo usando {@link +android.content.Context#getExternalFilesDir getExternalFilesDir()}.</li> +</ul> +<p>No entanto, recomenda-se exclui manualmente todos os arquivos em cache criados com +{@link android.content.Context#getCacheDir()} regularmente e +outros arquivos que não sejam mais necessários.</p> +</div> + diff --git a/docs/html-intl/intl/pt-br/training/basics/data-storage/index.jd b/docs/html-intl/intl/pt-br/training/basics/data-storage/index.jd new file mode 100644 index 0000000..2b88ce1 --- /dev/null +++ b/docs/html-intl/intl/pt-br/training/basics/data-storage/index.jd @@ -0,0 +1,57 @@ +page.title=Salvando dados +page.tags=armazenamento de dados,arquivos,sql,basededados,preferências +helpoutsWidget=true + +trainingnavtop=true +startpage=true + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + +<h2>Dependências e pré-requisitos</h2> +<ul> + <li>Android 1.6 (API Nível 4) ou superior</li> + <li>Familiaridade com coleções de valores-chave do Map</li> + <li>Familiaridade com API de E/S de arquivos Java</li> + <li>Familiaridade com bancos de dados do SQL</li> +</ul> + +<h2>Leia também</h2> +<ul> + <li><a href="{@docRoot}guide/topics/data/data-storage.html">Opções de armazenamento</a></li> +</ul> + +</div> +</div> + +<p>A maioria dos aplicativos Android precisa salvar dados, mesmo que seja apenas para salvar informações sobre o estado do aplicativo +durante {@link android.app.Activity#onPause onPause()} para que o progresso do usuário não seja perdido. A maior parte +dos aplicativos não triviais também precisa salvar configurações do usuário e alguns aplicativos precisam gerenciar grandes +quantidades de informação em arquivos e bancos de dados. Esta aula apresenta as +principais opções de armazenamento de dados no Android, incluindo:</p> + +<ul> + <li>Como salvar pares de valores-chave de tipos de dados simples em um arquivo de preferências +compartilhadas</li> + <li>Como salvar arquivos arbitrários no sistema de arquivos do Android</li> + <li>Como usar bancos de dados gerenciadas pelo SQLite</li> +</ul> + + +<h2>Lições</h2> + +<dl> + <dt><b><a href="shared-preferences.html">Salvando conjuntos de valores-chave</a></b></dt> + <dd>Aprenda a como usar um arquivo de preferências compartilhadas para armazenar pequenas quantidades de informação em pares de +valores-chave.</dd> + + <dt><b><a href="files.html">Salvando arquivos</a></b></dt> + <dd>Aprenda a como salvar um arquivo básico, como para armazenar longas sequências de dados que + são geralmente lidas em ordem.</dd> + + <dt><b><a href="databases.html">Salvando dados em bancos de dados do SQL</a></b></dt> + <dd>Aprenda a usar o banco de dados do SQLite para ler e gravar dados estruturados.</dd> + +</dl> diff --git a/docs/html-intl/intl/pt-br/training/basics/data-storage/shared-preferences.jd b/docs/html-intl/intl/pt-br/training/basics/data-storage/shared-preferences.jd new file mode 100644 index 0000000..0c84487 --- /dev/null +++ b/docs/html-intl/intl/pt-br/training/basics/data-storage/shared-preferences.jd @@ -0,0 +1,120 @@ +page.title=Salvando conjuntos de valor-chave +page.tags=armazenamento de dados +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + + +<div id="tb-wrapper"> +<div id="tb"> + +<h2>Esta lição ensina a</h2> +<ol> + <li><a href="#GetSharedPreferences">Obter um identificador para preferências compartilhadas</a></li> + <li><a href="#WriteSharedPreference">Gravar em preferências compartilhadas</a></li> + <li><a href="#ReadSharedPreference">Ler de preferências compartilhadas</a></li> +</ol> + +<h2>Leia também</h2> +<ul> + <li><a href="{@docRoot}guide/topics/data/data-storage.html#pref">Usando preferências compartilhadas</a></li> +</ul> + +</div> +</div> + + +<p>Caso você tenha uma coleção relativamente pequena de valores-chave para salvar, +use as APIs {@link android.content.SharedPreferences}. +Um objeto {@link android.content.SharedPreferences} indica um arquivo que contém +pares de valores-chave e fornece métodos simples para ler e gravar. Cada arquivo +{@link android.content.SharedPreferences} é +gerenciado pelo framework e pode ser privado ou compartilhado.</p> + +<p>Essa lição mostra como usar as APIs {@link android.content.SharedPreferences} para armazenar e +recuperar valores simples.</p> + +<p class="note"><strong>Observação:</strong> as APIs {@link android.content.SharedPreferences} são +usadas apenas para leitura e gravação de pares de valores-chave e não devem ser confundidas com as APIs +{@link android.preference.Preference}, que ajudam a criar uma interface do usuário +para as configurações do seu aplicativo (embora usem {@link android.content.SharedPreferences} como +implementação para salvar as configurações de aplicativo). Para obter mais informação sobre uso de APIs {@link +android.preference.Preference}, consulte a guia <a href="{@docRoot}guide/topics/ui/settings.html">Configurações</a>.</p> + +<h2 id="GetSharedPreferences">Obter um identificador para preferências compartilhadas</h2> + +<p>É possível criar um novo arquivo de preferência compartilhada ou acessar um existente +chamando um destes dois métodos:</p> +<ul> + <li>{@link android.content.Context#getSharedPreferences(String,int) +getSharedPreferences()} — Use este método se precisar identificar vários arquivos de preferência compartilhada +por nome, que devem ser especificados com o primeiro parâmetro. É possível chamá-lo por qualquer +{@link android.content.Context} em seu aplicativo.</li> + <li>{@link android.app.Activity#getPreferences(int) getPreferences()} — Use este método por um +{@link android.app.Activity} se precisar +usar apenas um arquivo de preferência compartilhada para a atividade. Como ele retorna um arquivo de preferência compartilhada +padrão que pertence à atividade, não é necessário fornecer um nome.</li> +</ul> + +<p>Por exemplo, o código a seguir é executado dentro de um {@link android.app.Fragment}. +Ele acessa o arquivo de preferências compartilhadas que é +identificado pela cadeia de caracteres de recursos {@code R.string.preference_file_key} e o abre usando +o modo privado para que o arquivo possa ser acessado apenas pelo seu aplicativo.</p> + +<pre> +Context context = getActivity(); +SharedPreferences sharedPref = context.getSharedPreferences( + getString(R.string.preference_file_key), Context.MODE_PRIVATE); +</pre> + +<p>Ao nomear seus arquivos de preferência compartilhada, você deve usar um nome que seja identificável exclusivamente +para o aplicativo, como {@code "com.example.myapp.PREFERENCE_FILE_KEY"}</p> + +<p>Em alternativa, caso precise apenas de um arquivo de preferência compartilhada para sua atividade, use o método +{@link android.app.Activity#getPreferences(int) getPreferences()}:</p> + +<pre> +SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE); +</pre> + +<p class="caution"><strong>Cuidado:</strong> se você criar um arquivo de preferência compartilhada +com {@link android.content.Context#MODE_WORLD_READABLE} ou {@link +android.content.Context#MODE_WORLD_WRITEABLE}, qualquer outro aplicativo que conhecer o identificador de arquivo +poderá acessar seus dados.</p> + + +<h2 id="WriteSharedPreference">Gravar em preferências compartilhadas</h2> + +<p>Para gravar em um arquivo de preferência compartilhada, crie um {@link +android.content.SharedPreferences.Editor} chamando {@link +android.content.SharedPreferences#edit} em seu {@link android.content.SharedPreferences}.</p> + +<p>Transmita as chaves e os valores que deseja gravar com métodos como {@link +android.content.SharedPreferences.Editor#putInt putInt()} e {@link +android.content.SharedPreferences.Editor#putString putString()}. Chame {@link +android.content.SharedPreferences.Editor#commit} para salvar as alterações. Por exemplo:</p> + +<pre> +SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE); +SharedPreferences.Editor editor = sharedPref.edit(); +editor.putInt(getString(R.string.saved_high_score), newHighScore); +editor.commit(); +</pre> + + +<h2 id="ReadSharedPreference">Ler de preferências compartilhadas</h2> + +<p>Para recuperar valores de um arquivo de preferência compartilhada, chame métodos como {@link +android.content.SharedPreferences#getInt getInt()} e {@link +android.content.SharedPreferences#getString getString()}, fornecendo a chave para o valor +desejado e opcionalmente um valor padrão para retornar caso a chave não esteja +presente. Por exemplo:</p> + +<pre> +SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE); +int defaultValue = getResources().getInteger(R.string.saved_high_score_default); +long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue); +</pre> + diff --git a/docs/html-intl/intl/pt-br/training/basics/intents/filters.jd b/docs/html-intl/intl/pt-br/training/basics/intents/filters.jd new file mode 100644 index 0000000..73f0b84 --- /dev/null +++ b/docs/html-intl/intl/pt-br/training/basics/intents/filters.jd @@ -0,0 +1,236 @@ +page.title=Permitindo que outros aplicativos iniciem sua atividade +page.tags=intenções +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + +<h2>Esta lição ensina a</h2> +<ol> + <li><a href="#AddIntentFilter">Adicionar um filtro de intenções</a></li> + <li><a href="#HandleIntent">Responder à intenção em sua atividade</a></li> + <li><a href="#ReturnResult">Retornar um resultado</a></li> +</ol> + +<h2>Leia também</h2> +<ul> + <li><a href="{@docRoot}training/sharing/index.html">Compartilhando dados simples</a></li> + <li><a href="{@docRoot}training/secure-file-sharing/index.html">Compartilhando arquivos</a> +</ul> + </div> +</div> + +<p>As duas lições anteriores enfatizaram um aspecto: iniciar a atividade de outro aplicativo pelo +seu aplicativo. Mas se seu aplicativo puder executar uma ação que pode ser útil para outro aplicativo, +ele precisa estar preparado para responder às solicitações de ação de outros aplicativos. Por exemplo, se +construir um aplicativo social que compartilhe mensagens ou fotos com os amigos do usuário, é interessante +que ele possa responder à intenção {@link android.content.Intent#ACTION_SEND} para que os usuários consigam iniciar uma +ação de “compartilhar” por outro aplicativo e iniciar seu aplicativo para executar a ação.</p> + +<p>Para permitir que outros aplicativos iniciem sua atividade, adicione um elemento <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a> +em seu arquivo de manifesto para o elemento <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> correspondente.</p> + +<p>Quando seu aplicativo é instalado em um dispositivo, o sistema identifica seu filtro de +intenções e adiciona a informação a um catálogo interno de intenções suportado por todos os aplicativos instalados. +Quando um aplicativo chama {@link android.app.Activity#startActivity +startActivity()} ou {@link android.app.Activity#startActivityForResult startActivityForResult()}, +com uma intenção implícita, o sistema encontra qual atividade (ou atividades) pode responder à +intenção.</p> + + + +<h2 id="AddIntentFilter">Adicionar um filtro de intenções</h2> + +<p>Para definir adequadamente a quais intenções sua atividade responderá, cada filtro de intenções adicionado +deverá ser o mais específico possível em termos de tipo de ação e dados aceitos pela +atividade.</p> + +<p>O sistema pode enviar uma determinada {@link android.content.Intent} para uma atividade se ela tiver +um filtro de intenções que atenda aos seguintes critérios do objeto {@link android.content.Intent}:</p> + +<dl> + <dt>Ação</dt> + <dd>Uma cadeia de caracteres que dá nome a ação a ser executada. Geralmente, um dos valores definidos para a plataforma +como {@link android.content.Intent#ACTION_SEND} ou {@link android.content.Intent#ACTION_VIEW}. + <p>Especifique-o em seu filtro de intenções com o elemento <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code <action>}</a>. +O valor especificado neste elemento deve ser o nome completo da cadeia de caracteres para a ação e não a +API constante (veja exemplos abaixo).</p></dd> + + <dt>Dados</dt> + <dd>A descrição dos dados associados à intenção. + <p>Especifique-a em seu filtro de intenções com o elemento <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a>. Através de um +ou mais atributos neste elemento, você pode especificar apenas o tipo MIME, apenas um prefixo de URI, +apenas um esquema de URI ou uma combinação destes e outros elementos que indicam o tipo de dados +aceito.</p> + <p class="note"><strong>Observação:</strong> se não precisar especificar os dados +{@link android.net.Uri} (como quando sua atividade responde a outros tipos de dados “extra”, em vez +do URI), especifique apenas o atributo {@code android:mimeType} para declarar o tipo de +dado que sua atividade trata, como {@code text/plain} ou {@code image/jpeg}.</p> +</dd> + <dt>Categoria</dt> + <dd>Oferece uma outra forma de caracterizar a atividade que trata a intenção, geralmente relacionada +ao gesto do usuário ou localização onde foi iniciada. Há diferentes categorias +compatíveis com o sistema, mas a maioria raramente é utilizada. No entanto, todas as intenções implícitas são definidas com +{@link android.content.Intent#CATEGORY_DEFAULT} por padrão. + <p>Especifique-a em seu filtro de intenções com o elemento <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code <category>}</a> +.</p></dd> +</dl> + +<p>Em seu filtro de intenções, declare quais critérios serão aceitos por sua atividade +informando cada um deles com elementos XML correspondentes aninhados no elemento <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a> +.</p> + +<p>Este é um exemplo de atividade com filtro de intenções que responde à intenção {@link +android.content.Intent#ACTION_SEND} quando o tipo de dado é texto ou imagem:</p> + +<pre> +<activity android:name="ShareActivity"> + <intent-filter> + <action android:name="android.intent.action.SEND"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:mimeType="text/plain"/> + <data android:mimeType="image/*"/> + </intent-filter> +</activity> +</pre> + +<p>Cada intenção em entrada especifica apenas uma ação e um tipo de dado, mas pode-se declarar +múltiplas instâncias dos elementos <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code +<action>}</a>, <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code +<category>}</a> e <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code +<data>}</a> em cada +<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a>.</p> + +<p>Se dois pares de ação e dados fores mutuamente exclusivos em +seus comportamentos, crie filtros de intenções separados para especificar quais ações são aceitáveis +quando pareadas com qual tipo de dado.</p> + +<p>Imagine que sua atividade responda à ambos, texto e imagem, para intenções {@link +android.content.Intent#ACTION_SEND} e {@link +android.content.Intent#ACTION_SENDTO}. Nesse caso, defina dois +filtros de intenções separados para as duas ações porque uma intenção {@link +android.content.Intent#ACTION_SENDTO} deve usar os dados {@link android.net.Uri} para especificar +o endereço do destinatário utilizando o esquema do URI {@code send} ou {@code sendto}. Por exemplo:</p> + +<pre> +<activity android:name="ShareActivity"> + <!-- filter for sending text; accepts SENDTO action with sms URI schemes --> + <intent-filter> + <action android:name="android.intent.action.SENDTO"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:scheme="sms" /> + <data android:scheme="smsto" /> + </intent-filter> + <!-- filter for sending text or images; accepts SEND action and text or image data --> + <intent-filter> + <action android:name="android.intent.action.SEND"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:mimeType="image/*"/> + <data android:mimeType="text/plain"/> + </intent-filter> +</activity> +</pre> + +<p class="note"><strong>Observação:</strong> para receber intenções implícitas, inclua a categoria +{@link android.content.Intent#CATEGORY_DEFAULT} no filtro de intenções. Os métodos {@link +android.app.Activity#startActivity startActivity()} e {@link +android.app.Activity#startActivityForResult startActivityForResult()} tratam todas as intenções como se elas tivessem +declarado a categoria {@link android.content.Intent#CATEGORY_DEFAULT}. Se você não a declarar +em seu filtro de intenções, nenhuma intenção implícita resolverá sua atividade.</p> + +<p>Para obter mais informações sobre o envio e recebimento de intenções {@link android.content.Intent#ACTION_SEND} +que realizam comportamentos de compartilhamento social, veja a lição <a href="{@docRoot}training/sharing/receive.html">Recebendo dados simples de outros aplicativos</a>.</p> + + +<h2 id="HandleIntent">Responder à intenção em sua atividade</h2> + +<p>Para decidir qual ação tomar em sua atividade, leia a {@link +android.content.Intent} utilizada para iniciá-la.</p> + +<p>Quando sua atividade iniciar, chame {@link android.app.Activity#getIntent()} para retomar a +{@link android.content.Intent} que iniciou a atividade. Pode-se fazer isso a qualquer momento durante +o ciclo de vida da atividade, mas recomenda-se fazê-lo no início do retorno de chamada como +{@link android.app.Activity#onCreate onCreate()} ou {@link android.app.Activity#onStart()}.</p> + +<p>Por exemplo:</p> + +<pre> +@Override +protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.main); + + // Get the intent that started this activity + Intent intent = getIntent(); + Uri data = intent.getData(); + + // Figure out what to do based on the intent type + if (intent.getType().indexOf("image/") != -1) { + // Handle intents with image data ... + } else if (intent.getType().equals("text/plain")) { + // Handle intents with text ... + } +} +</pre> + + +<h2 id="ReturnResult">Retornar um resultado</h2> + +<p>Se você deseja retornar um resultado para a atividade que invocou a sua, simplesmente chame {@link +android.app.Activity#setResult(int,Intent) setResult()} para especificar o código do resultado e o resultado {@link +android.content.Intent}. Quando sua operação estiver concluída e o usuário retornar à atividade +original, chame {@link android.app.Activity#finish()} para fechar (e destruir) a atividade. Por +exemplo:</p> + +<pre> +// Create intent to deliver some kind of result data +Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"); +setResult(Activity.RESULT_OK, result); +finish(); +</pre> + +<p>Sempre especifique um código de resultado com o resultado. Geralmente é {@link +android.app.Activity#RESULT_OK} ou {@link android.app.Activity#RESULT_CANCELED}. Pode-se fornecer +dados adicionais com uma {@link android.content.Intent}, caso seja necessário.</p> + +<p class="note"><strong>Observação:</strong> o resultado é definido como {@link +android.app.Activity#RESULT_CANCELED} por padrão. Portanto, se o usuário pressionar o botão <em>Voltar</em> +antes de concluir a ação e definir o resultado, a atividade original recebe +o resultado “cancelado”.</p> + +<p>Se você apenas precisar retornar um número inteiro que indique uma das várias opções de resultado, defina +o código de resultados para qualquer valor maior que 0. Se você usar o código do resultado para fornecer um número inteiro e não +houver necessidade de incluir {@link android.content.Intent}, chame {@link +android.app.Activity#setResult(int) setResult()} e transmita apenas um código de resultado. Por exemplo:</p> + +<pre> +setResult(RESULT_COLOR_RED); +finish(); +</pre> + +<p>Nesse caso, talvez existam apenas alguns poucos resultados possíveis. Portanto, o código do resultado é um número inteiro definido +localmente (maior que 0). Isso funciona bem ao retornar um resultado de uma atividade +em seu próprio aplicativo porque a atividade que recebe o resultado pode fazer uma referência à constante pública +para determinar o valor do código de resultado.</p> + +<p class="note"><strong>Observação:</strong> não há necessidade de verificar se sua atividade foi iniciada +com {@link +android.app.Activity#startActivity startActivity()} ou {@link +android.app.Activity#startActivityForResult startActivityForResult()}. Simplesmente chame {@link +android.app.Activity#setResult(int,Intent) setResult()} se a intenção que iniciou sua atividade +estiver esperando um resultado. Se a atividade inicial tivesse chamado {@link +android.app.Activity#startActivityForResult startActivityForResult()}, o sistema o forneceria +o resultado para {@link android.app.Activity#setResult(int,Intent) setResult()}. Caso contrário, +o resultado é ignorado.</p> + + + + + + diff --git a/docs/html-intl/intl/pt-br/training/basics/intents/index.jd b/docs/html-intl/intl/pt-br/training/basics/intents/index.jd new file mode 100644 index 0000000..94108b8 --- /dev/null +++ b/docs/html-intl/intl/pt-br/training/basics/intents/index.jd @@ -0,0 +1,62 @@ +page.title=Interagindo com outros aplicativos +page.tags=intenções,atividade +helpoutsWidget=true + +trainingnavtop=true +startpage=true + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + +<h2>Dependências e pré-requisitos</h2> +<ul> + <li>Conhecimento básico sobre o ciclo de vida da atividade (consulte <a href="{@docRoot}training/basics/activity-lifecycle/index.html">Como gerenciar o ciclo de vida +da atividade</a>)</li> +</ul> + + +<h2>Leia também</h2> +<ul> + <li><a href="{@docRoot}training/sharing/index.html">Compartilhando dados simples</a></li> + <li><a href="{@docRoot}training/secure-file-sharing/index.html">Compartilhando arquivos</a> + <li><a href="http://android-developers.blogspot.com/2009/11/integrating-application-with-intents.html"> +Integrando aplicativos e intenções (publicações do blog)</a></li> + <li><a href="{@docRoot}guide/components/intents-filters.html">Intenções e filtros de +intenções</a>.</li> +</ul> + +</div> +</div> + +<p>Geralmente, um aplicativo Android tem várias <a href="{@docRoot}guide/components/activities.html">atividades</a>. Cada atividade exibe uma +interface do usuário que permite ao usuário executar tarefas específicas (como visualizar um mapa ou tirar uma foto). +Para levar o usuário de uma atividade para outra, o aplicativo deve usar um {@link +android.content.Intent} para definir a “intenção” do aplicativo de fazer algo. Ao transmitir um +{@link android.content.Intent} para o sistema com um método como {@link +android.app.Activity#startActivity startActivity()}, o sistema usa {@link +android.content.Intent} para identificar e iniciar o componente adequado do aplicativo. Usar intenções +permite até mesmo que o aplicativo inicie uma atividade que esteja contida em outro aplicativo.</p> + +<p>Um {@link android.content.Intent} pode ser <em>explícito</em> para iniciar um componente específico +(uma instância {@link android.app.Activity} específica) ou <em>implícito</em> para iniciar qualquer +componente que possa responder à ação pretendida (como “capturar uma foto”).</p> + +<p>Esta aula mostra como utilizar um {@link android.content.Intent} para executar algumas interações +básicas com outros aplicativos, como iniciar outro aplicativo, receber seus resultados, e +disponibilizar seu aplicativo para responder às intenções de outros aplicativos.</p> + +<h2>Lições</h2> + +<dl> + <dt><b><a href="sending.html">Enviando o usuário para outro aplicativo</a></b></dt> + <dd>Mostra como criar intenções implícitas para iniciar outros aplicativos que podem executar uma +ação.</dd> + <dt><b><a href="result.html">Obtendo resultados de uma atividade</a></b></dt> + <dd>Como iniciar outra atividade e receber seu resultado.</dd> + <dt><b><a href="filters.html">Permitindo que outros aplicativos iniciem sua atividade</a></b></dt> + <dd>Como fazer com que atividades em seu aplicativo se abram para serem usadas por outros aplicativos através de definição +de filtros de intenções que declaram as intenções implícitas aceitas pelo aplicativo.</dd> +</dl> + diff --git a/docs/html-intl/intl/pt-br/training/basics/intents/result.jd b/docs/html-intl/intl/pt-br/training/basics/intents/result.jd new file mode 100644 index 0000000..ecb5a47 --- /dev/null +++ b/docs/html-intl/intl/pt-br/training/basics/intents/result.jd @@ -0,0 +1,178 @@ +page.title=Obtendo resultados de uma atividade +page.tags=intenções +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + +<h2>Esta lição ensina a</h2> +<ol> + <li><a href="#StartActivity">Iniciar a atividade</a></li> + <li><a href="#ReceiveResult">Receber o resultado</a></li> +</ol> + +<h2>Leia também</h2> +<ul> + <li><a href="{@docRoot}training/sharing/index.html">Compartilhando dados simples</a></li> + <li><a href="{@docRoot}training/secure-file-sharing/index.html">Compartilhando arquivos</a> +</ul> + + </div> +</div> + +<p>Iniciar outra atividade não precisa ser a única forma. Pode-se também iniciar outra atividade e +receber um resultado de volta. Para receber um resultado, chame {@link android.app.Activity#startActivityForResult +startActivityForResult()} (em vez de {@link android.app.Activity#startActivity +startActivity()}).</p> + +<p>Por exemplo, o aplicativo pode iniciar um aplicativo de câmera e receber a foto capturada como resultado. Ou, +ao iniciar o aplicativo Pessoas para que o usuário selecione um +contato, você receberá os detalhes do contato como resultado.</p> + +<p>Evidentemente a atividade que responde deve ser projetada para retornar um resultado. Quando isso acontecer, ela +enviará o resultado para outro objeto {@link android.content.Intent}. A atividade recebe o resultado no +retorno de chamada {@link android.app.Activity#onActivityResult onActivityResult()}.</p> + +<p class="note"><strong>Observação:</strong> pode-se usar intenções explícitas ou implícitas ao chamar +{@link android.app.Activity#startActivityForResult startActivityForResult()}. Ao iniciar uma de +suas próprias atividades que recebem um resultado, use uma intenção explícita para garantir que o +resultado esperado será recebido.</p> + + +<h2 id="StartActivity">Iniciar a atividade</h2> + +<p>Não há nada especial no objeto {@link android.content.Intent} utilizado para iniciar +uma atividade para um resultado, mas é preciso transmitir um argumento de número inteiro adicional ao método {@link +android.app.Activity#startActivityForResult startActivityForResult()}.</p> + +<p>O argumento de número inteiro é um “código de pedido” que identifica o pedido. Quando você recebe o +resultado {@link android.content.Intent}, o retorno de chamada fornece o mesmo código de pedido para que o +aplicativo possa identificar adequadamente o resultado e determinar como responder a ele.</p> + +<p>Essa é uma forma de iniciar uma atividade que permite ao usuário escolher um contato:</p> + +<pre> +static final int PICK_CONTACT_REQUEST = 1; // The request code +... +private void pickContact() { + Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts")); + pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers + startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST); +} +</pre> + + +<h2 id="ReceiveResult">Receber o resultado</h2> + +<p>Quando o usuário termina a atividade subsequente e retorna, o sistema chama o método +{@link android.app.Activity#onActivityResult onActivityResult()} da atividade. Esse método inclui três +argumentos:</p> + +<ul> + <li>O código de pedido passado para {@link +android.app.Activity#startActivityForResult startActivityForResult()}.</li> + <li>Um código de resultado especificado pela segunda atividade. Se a operação for bem sucedida, será {@link +android.app.Activity#RESULT_OK} ou {@link +android.app.Activity#RESULT_CANCELED} se o usuário tiver desistido ou a operação tiver falhado por algum +motivo.</li> + <li>Um {@link android.content.Intent} que transporta os dados do resultado.</li> +</ul> + +<p>Esta é uma forma de responder ao resultado para a intenção “escolher um contato”:</p> + +<pre> +@Override +protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // Check which request we're responding to + if (requestCode == PICK_CONTACT_REQUEST) { + // Make sure the request was successful + if (resultCode == RESULT_OK) { + // The user picked a contact. + // The Intent's data Uri identifies which contact was selected. + + // Do something with the contact here (bigger example below) + } + } +} +</pre> + +<p>Nesse exemplo, o resultado {@link android.content.Intent} retornado pelos +aplicativos Contatos ou Pessoas do Android fornece um conteúdo {@link android.net.Uri} que identifica o +contato escolhido pelo usuário.</p> + +<p>Para que o resultado seja tratado de forma adequada, é preciso saber o formato do resultado +{@link android.content.Intent}. Isso é fácil quando umas das suas atividades +retorna o resultado. Os aplicativos incluídos na plataforma Android oferecem suas próprias APIs que +podem ser usadas para dados de resultado específicos. Por exemplo, o aplicativo Pessoas (Contatos em algumas versões mais +antigas) sempre retorna um resultado com URI de conteúdo que identifica o contato escolhido e o aplicativo +Câmera retorna um {@link android.graphics.Bitmap} no {@code "data"} extra (consulte a lição +<a href="{@docRoot}training/camera/index.html">Capturando fotografias</a>).</p> + + +<h4>Bônus: Ler os dados do contato</h4> + +<p>O código acima que mostra como obter um resultado pelo aplicativo Pessoas não +traz muitos detalhes sobre como exatamente ler os dados do resultado porque exige uma discussão mais avançada +sobre <a href="{@docRoot}guide/topics/providers/content-providers.html">provedores +de conteúdo</a>. No entanto, se você desejar saber mais, aqui estão alguns códigos que mostram como consultar os +dados de resultado para obter o número de telefone do contato selecionado:</p> + +<pre> +@Override +protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // Check which request it is that we're responding to + if (requestCode == PICK_CONTACT_REQUEST) { + // Make sure the request was successful + if (resultCode == RESULT_OK) { + // Get the URI that points to the selected contact + Uri contactUri = data.getData(); + // We only need the NUMBER column, because there will be only one row in the result + String[] projection = {Phone.NUMBER}; + + // Perform the query on the contact to get the NUMBER column + // We don't need a selection or sort order (there's only one result for the given URI) + // CAUTION: The query() method should be called from a separate thread to avoid blocking + // your app's UI thread. (For simplicity of the sample, this code doesn't do that.) + // Consider using {@link android.content.CursorLoader} to perform the query. + Cursor cursor = getContentResolver() + .query(contactUri, projection, null, null, null); + cursor.moveToFirst(); + + // Retrieve the phone number from the NUMBER column + int column = cursor.getColumnIndex(Phone.NUMBER); + String number = cursor.getString(column); + + // Do something with the phone number... + } + } +} +</pre> + +<p class="note"><strong>Observação:</strong> antes do Android 2.3 (API nível 9), executar uma consulta +no {@link android.provider.ContactsContract.Contacts Contacts Provider} (como mostrado +acima) exige que o aplicativo declare a permissão {@link +android.Manifest.permission#READ_CONTACTS} (consulte <a href="{@docRoot}guide/topics/security/security.html">Segurança e permissões</a>). Contudo, +iniciar com Android 2.3, o aplicativo Contatos/Pessoas dá ao aplicativo permissão +temporária para ler no Provedor de Contatos quando retornar um resultado. A permissão temporária +aplica-se apenas a pedidos de contato específicos, portanto, não é possível consultar um contato diferente daquele +especificado pelo {@link android.net.Uri} da intenção, a menos que você declare a permissão {@link +android.Manifest.permission#READ_CONTACTS}.</p> + + + + + + + + + + + + + + + diff --git a/docs/html-intl/intl/pt-br/training/basics/intents/sending.jd b/docs/html-intl/intl/pt-br/training/basics/intents/sending.jd new file mode 100644 index 0000000..526374d --- /dev/null +++ b/docs/html-intl/intl/pt-br/training/basics/intents/sending.jd @@ -0,0 +1,256 @@ +page.title=Enviando o usuário para outro aplicativo +page.tags=intenções +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + + +<div id="tb-wrapper"> + <div id="tb"> + +<h2>Esta lição ensina a</h2> +<ol> + <li><a href="#Build">Criar uma intenção implícita</a></li> + <li><a href="#Verify">Confirmar se há um aplicativo para receber a intenção</a></li> + <li><a href="#StartActivity">Iniciar uma atividade com uma intenção</a></li> + <li><a href="#AppChooser">Mostrar um selecionador de aplicativo</a></li> +</ol> + +<h2>Leia também</h2> +<ul> + <li><a href="{@docRoot}training/sharing/index.html">Compartilhando dados simples</a></li> +</ul> + + </div> +</div> + +<p>Uma das características mais importantes do Android é a habilidade do aplicativo enviar o usuário para outro aplicativo +com base em uma “ação” que gostaria de executar. Por exemplo, se +o aplicativo tiver o endereço de um negócio que você gostaria de mostrar em um mapa, não é necessário criar +uma atividade no aplicativo que mostre um mapa. Em vez disso, é possível criar uma solicitação para exibir o endereço +usando {@link android.content.Intent}. O sistema Android inicia um aplicativo que possa mostrar +o endereço em um mapa.</p> + +<p>Como explicado na primeira lição, <a href="{@docRoot}training/basics/firstapp/index.html">Criando +seu primeiro aplicativo</a>, use intenções para navegar entre atividades no aplicativo. Geralmente +isso é feito com <em>intenções explícitas</em>, que define o nome exato da classe do +componente que deseja iniciar. No entanto, quando desejar que outro aplicativo execute uma ação, como +“visualizar um mapa”, use uma <em>intenção implícita</em>.</p> + +<p>Esta lição mostra como criar uma intenção implícita para uma ação específica e como utilizá-la +para iniciar uma atividade que executa a ação em outro aplicativo.</p> + + + +<h2 id="Build">Criar uma intenção implícita</h2> + +<p>Intenções implícitas não declaram o nome da classe do componente a iniciar, mas declaram uma +ação a executar. A ação especifica o que deve ser feito, como <em>visualizar</em>, +<em>editar</em>, <em>enviar</em> ou <em>obter</em> algo. Geralmente, as intenções incluem dados associados +à ação, como o endereço que deseja visualizar ou a mensagem de email a ser enviada. +Dependendo da intenção que deseja criar, os dados podem ser {@link android.net.Uri}, +um dos outros tipos de dados ou a intenção pode não precisar de dado algum.</p> + +<p>Se seu dados forem um {@link android.net.Uri}, há um simples construtor {@link +android.content.Intent#Intent(String,Uri) Intent()} que pode ser usado para definir a ação e +os dados.</p> + +<p>Este é um exemplo de como criar uma intenção para iniciar uma chamada telefônica usando os dados {@link +android.net.Uri} para especificar o número de telefone:</p> + +<pre> +Uri number = Uri.parse("tel:5551234"); +Intent callIntent = new Intent(Intent.ACTION_DIAL, number); +</pre> + +<p>Quando o aplicativo invoca a intenção chamando {@link android.app.Activity#startActivity +startActivity()}, o aplicativo Telefone inicia uma chamada para o número especificado.</p> + +<p>Estas são algumas outras intenções e suas ações e pares de dados {@link android.net.Uri} +:</p> + +<ul> + <li>Visualizar um mapa: +<pre> +// Map point based on address +Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); +// Or map point based on latitude/longitude +// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level +Intent mapIntent = new Intent(Intent.ACTION_VIEW, location); +</pre> + </li> + <li>Visualizar uma página da Web: +<pre> +Uri webpage = Uri.parse("http://www.android.com"); +Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage); +</pre> + </li> +</ul> + +<p>Outros tipos de intenções implícitas exigem dados “extras” que fornecem diferentes tipos de dados, +como uma cadeia de caracteres. É possível adicionar um ou mais dados extras utilizando vários métodos {@link +android.content.Intent#putExtra(String,String) putExtra()}.</p> + +<p>Por padrão, o sistema determina o tipo MIME adequado que uma intenção exige com base nos dados +{@link android.net.Uri} incluídos. Se você não incluir um {@link android.net.Uri} na +intenção, sempre utilize {@link android.content.Intent#setType setType()} para especificar o tipo +de dado associado à intenção. Definir o tipo de MIME especifica melhor que tipos de +atividades receberão a intenção.</p> + +<p>Estas são mais algumas intenções que adicionam dados extra para especificar a intenção desejada:</p> + +<ul> + <li>Enviar um email com um anexo: +<pre> +Intent emailIntent = new Intent(Intent.ACTION_SEND); +// The intent does not have a URI, so declare the "text/plain" MIME type +emailIntent.setType(HTTP.PLAIN_TEXT_TYPE); +emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients +emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject"); +emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text"); +emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment")); +// You can also attach multiple items by passing an ArrayList of Uris +</pre> + </li> + <li>Criar um evento de calendário: +<pre> +Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI); +Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30); +Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30); +calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis()); +calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis()); +calendarIntent.putExtra(Events.TITLE, "Ninja class"); +calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo"); +</pre> +<p class="note"><strong>Observação:</strong> esta intenção para evento de calendário é suportada apenas com nível de API +14 e superior.</p> + </li> +</ul> + +<p class="note"><strong>Observação:</strong> é importante definir seu {@link +android.content.Intent} para ser o mais específico possível. Por exemplo, se você deseja exibir uma imagem +usando a intenção {@link android.content.Intent#ACTION_VIEW}, especifique o tipo de MIME do +{@code image/*}. Isto evita que aplicativos que podem “exibir” outros tipos de dados (como um aplicativo de mapas) seja +acionado pela intenção.</p> + + + +<h2 id="Verify">Confirmar se há um aplicativo para receber a intenção</h2> + +<p>Embora a plataforma do Android garanta que determinadas intenções sejam resolvidas com um dos + aplicativos embutidos (como aplicativo de Telefone, Email ou Agenda), sempre inclua uma +etapa de confirmação antes de chamar uma intenção.</p> + +<p class="caution"><strong>Cuidado:</strong> se você invocar uma intenção e não houver aplicativo +disponível no dispositivo para tratar a intenção, o aplicativo falhará.</p> + +<p>Para confirmar se há atividade disponível para responder à intenção, chame {@link +android.content.pm.PackageManager#queryIntentActivities queryIntentActivities()} para obter uma lista +de atividades que podem tratar a {@link android.content.Intent}. Se o {@link +java.util.List} retornado não estiver vazio, a intenção poderá ser usada com segurança. Por exemplo:</p> + +<pre> +PackageManager packageManager = {@link android.content.Context#getPackageManager()}; +List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, + PackageManager.MATCH_DEFAULT_ONLY); +boolean isIntentSafe = activities.size() > 0; +</pre> + +<p>Se <code>isIntentSafe</code> for <code>true</code>, pelo menos um aplicativo responderá à +intenção. Se for <code>false</code>, não há aplicativos disponíveis para responder à intenção.</p> + +<p class="note"><strong>Observação:</strong> faça essa verificação quando a atividade +iniciar, caso seja necessário desabilitar a funcionalidade que usa a intenção antes do usuário tentar utilizá- +la. Caso conheça um aplicativo específico que possa lidar com a intenção, forneça um link para que o +usuário baixe o aplicativo (veja como <a href="{@docRoot}distribute/tools/promote/linking.html">vincular para seus produtos no Google +Play</a>).</p> + + +<h2 id="StartActivity">Iniciar uma atividade com uma intenção</h2> + +<div class="figure" style="width:200px;margin-top:-10px"> + <img src="{@docRoot}images/training/basics/intents-choice.png" alt="" /> + <p class="img-caption"><strong>Figura 1.</strong> Exemplo de diálogo de seleção que aparece +quando mais de um aplicativo pode tratar uma intenção.</p> +</div> + +<p>Quando tiver criado sua {@link android.content.Intent} e definido as informações extras, chame {@link +android.app.Activity#startActivity startActivity()} para enviá-la ao sistema. Se o sistema +identificar mais de uma atividade que pode tratar a intenção, um diálogo exibirá para que o usuário +selecione qual aplicativo usar, como mostrado na figura 1. Se houver apenas uma atividade para tratar a +intenção, o sistema a iniciará imediatamente.</p> + +<pre> +startActivity(intent); +</pre> + +<p>Este é um exemplo completo que mostra como criar uma intenção para exibir um mapa, confirmar se há +um aplicativo para tratar a intenção e iniciar:</p> + +<pre> +// Build the intent +Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); +Intent mapIntent = new Intent(Intent.ACTION_VIEW, location); + +// Verify it resolves +PackageManager packageManager = {@link android.content.Context#getPackageManager()}; +List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0); +boolean isIntentSafe = activities.size() > 0; + +// Start an activity if it's safe +if (isIntentSafe) { + startActivity(mapIntent); +} +</pre> + + + +<h2 id="AppChooser">Mostrar um selecionador de aplicativo</h2> + +<div class="figure" style="width:200px;margin-top:-10px"> + <img src="{@docRoot}images/training/basics/intent-chooser.png" alt="" /> + <p class="img-caption"><strong>Figura 2.</strong> Um diálogo seletor.</p> +</div> + +<p>Observe que ao iniciar uma atividade passando seu {@link android.content.Intent} para {@link +android.app.Activity#startActivity startActivity()} e quando há mais de um aplicativo que responde à +intenção, o usuário pode selecionar qual aplicativo usar por padrão (marcando uma caixa de seleção na parte inferior +do diálogo, veja a figura 1). Isto é bom quando se executa uma ação para qual o usuário +deseja usar o mesmo aplicativo todas as vezes, como quando abre uma página da Web (o usuário +geralmente usa apenas um navegador) ou para tirar fotos (o usuário prefere uma câmera).</p> + +<p>Contudo, se a ação a ser executada puder ser tratada por vários aplicativos e o usuário +preferir um aplicativo diferente a cada vez, como a ação “compartilhar” onde os usuários podem ter vários +aplicativos para compartilhar um item, você deve exibir explicitamente um diálogo seletor +conforme mostrado na figura 2. O diálogo seletor +força o usuário a selecionar qual aplicativo usar para a ação todas as vezes (o usuário não pode selecionar +um aplicativo padrão para a ação).</p> + +<p>Para exibir o seletor, crie uma {@link android.content.Intent} usando {@link +android.content.Intent#createChooser createChooser()} e transmita para {@link +android.app.Activity#startActivity startActivity()}. Por exemplo:</p> + +<pre> +Intent intent = new Intent(Intent.ACTION_SEND); +... + +// Always use string resources for UI text. +// This says something like "Share this photo with" +String title = getResources().getString(R.string.chooser_title); +// Create intent to show chooser +Intent chooser = Intent.createChooser(intent, title); + +// Verify the intent will resolve to at least one activity +if (intent.resolveActivity(getPackageManager()) != null) { + startActivity(chooser); +} +</pre> + +<p>Isso exibe um diálogo com uma lista de aplicativos que respondem à intenção transmitida ao método {@link +android.content.Intent#createChooser createChooser()} e utiliza o texto fornecido como +título do diálogo.</p> + + + |