Android Basico

March 26, 2018 | Author: orangota | Category: Android (Operating System), Virtual Machine, Mobile App, Computing, Technology


Comments



Description

Página 1 de 84Lição 1: Desenvolvimento para Android A plataforma Android é baseada em sistema operacional Linux, adaptada para funcionamento em dispositivos móveis, como: smart phones, PDAs e Tablets. Para o desenvolvimento de aplicativos, foi disponibilizada uma máquina virtual, especialmente otimizada para uso em dispositivos móveis, além de um ambiente de programação completo, com componentes visuais, de acesso a dados e redes. Interessante notar é que a máquina virtual Dalvik é um projeto Open Source (http://code.google.com/p/dalvik/), e NÃO É UMA MÁQUINA VIRTUAL JAVA ® ! Isso mesmo: DALVIK NÃO É JAVA! Existe uma aplicação, chamada “dx”, que pode converter o bytecode compilado a partir da máquina virtual Java (especificação da Oracle), no bytecode da Dalvik. A Google disponibilizou um ambiente de programação baseado em Java ®, que permite o desenvolvimento de aplicações para a plataforma Android. Ele possui emuladores de dispositivos Android e conversores de bytecode. Segundo pesquisa da empresa Canalys , no quatro trimestre de 2010, quase 33 milhões de smartphones equipados com o sistema Android foram entregues, comparado com 31 milhões equipados com o sistema Symbian, da Nokia. Arquitetura do ambiente Android A arquitetura do ambiente de desenvolvimento Android é dividida em camadas. Sua aplicação roda na camada superior, por exemplo: contatos, telefone, jogos, calendário, seu programa etc. Abaixo desta camada, vem um framework de componentes, que formam uma API de gerenciamento e serviços para uso das aplicações. Abaixo da camada de framework, temos as bibliotecas de serviços, como OpenGL e SQLite, e as bibliotecas principais do ambiente, além da própria máquina virtual Dalvik. Finalmente, abaixo de tudo, temos o Kernel Linux. Embora seja possível, devido a grande diversidade de dispositivos, não é recomendado programar aplicações em C/C++. O ambiente de programação Android fornece tudo o que você necessita para criar aplicações sinistras! Você não precisa programar em C/C++ ou usar chamadas ao Kernel. Tudo o que necessita para criar aplicações Android, é do SDK e de um ambiente de programação Java. Cada aplicação Android é executada por uma instâncla da máquina virtual Dalvik, rodando em um processo separado dentro do sistema operacional. Página 2 de 84 Componentes Uma aplicação Android é um conjunto de componentes, que podem ser:     Activities – atividades ou telas; Services – serviços em background; Content Providers – disponibilizam dados; Broadcast Receivers – respondem a avisos gerais do sistema; Uma aplicação Android é orientada a eventos. Um evento é um sinal, que pode ter sido originado pelo usuário (um toque) ou não (o timer, o bloqueio de tela etc). Logo, é uma aplicação dividida em diversos tipos de componentes (activities, services etc), que compartilham um nome de pacote (sim, é muito importante) e de aplicação comum, por exemplo: br.com.thecodebakers.hpp.Hppfree Os tipos de componentes são declarados e implementados na camada “framework”, e você os estende para criar seus componentes específicos. View e ViewGroups Uma View é um elemento de interface. Comparando com uma página HTML, seriam os elementos de formulário, como: botões, caixa de texto, radio buttons etc. As Views podem gerar e receber Eventos, que podem ser interceptados no código-fonte. As Views podem ser agrupadas em ViewGroups, que fornecem o layout de arrumação na tela. Existem Views fornecidas pelo framework, que já agregam a parte visual e algum tipo de comportamento. São chamadas de “Widgets”. Se a sua aplicação possuir algum tipo de interface visual, o que é o caso para a maioria delas, então conterá algumas Telas (activities), com Layouts (ViewGroups) e Views arrumadas nelas. É através das Views que você e o usuário se comunicam. Página 3 de 84 Activity Uma Activity é uma tela onde o usuário pode fazer algo. Note que o relacionamento entre Activity e caso de uso não é 1 para 1. Um caso de uso pode envolver várias activities. Para criar uma Activity é necessário criar um arquivo de layout, que contém um ViewGroup e um ou mais ViewGroups ou Views internos, todos arrumados de acordo com a usabilidade da sua aplicação. Depois, é necessário criar a subclasse de Activity, que será invocada quando o usuário solicitar. A parte de código é quem comanda o espetáculo, usando a parte de layout. Todos os eventos gerados pelas Views do Layout, e pelos controles do aparelho (botão de “menu”, “menu de contexto” e botão “back”) poderão ser tratados no código de sua activity. Uma activity pode iniciar outros componentes de sua aplicação, como: outras Activities, Services etc; Service http://developer.android.com/guide/topics/fundamentals/services.html Um componente que executa operações de longo prazo e em background; Podemos iniciar um service em outro componente. Ele continuará a executar mesmo que o usuário mude de aplicação. Outros componentes podem se conectar com o nosso service. Exemplos: I/O, serviços de rede, de GPS, de alerta etc. Imagine uma aplicação de vendas. Os vendedores recebem atualizações de Clientes e as acessam através da sua aplicação, O Download automático de atualizações poderia ser feito por um Service de sua aplicação. Um service, uma instância de: android.app.Service, fica rodando em Background e pode executar tarefas longas, repetitivas ou a intervalos determinados. E também pode ser acessado por outras aplicações. Um Media Player, por exemplo, utiliza um Service, que fica tocando a música mesmo que a interface do media player seja fechada. Sua aplicação pode criar seus próprios Services ou usar Services fornecidos por outros. A criação de Services está fora do escopo deste curso, mas é abordada em cursos mais avançados. Página 4 de 84 Content Provider http://developer.android.com/guide/topics/providers/content-providers.html Amazenam e recuperam dados, disponibilizando-os para outras aplicações. Exemplos: Contacts, Agenda etc. Você também pode criar Content Providers para outras aplicações; O Android vem com vários Content Providers, como por exemplo as informações de contato. Você pode obter a lista de contatos do usuário (desde que autorizado por ele), acrescentar, remover etc. Você não precisa criar um Content Provider para lidar com os dados de sua aplicação, mas, se quiser compartilhá-los, então terá que pensar nisto. Como as aplicações Android são muito relacionadas com “MashUps”, é bom pensar em compartilhar os dados de suas aplicações, tornando-as mais populares. O desenvolvimento de content providers está fora do escopo deste curso. Broadcast Receiver http://developer.android.com/reference/android/content/BroadcastReceiver.html Classe que recebe alertas gerais do sistema. Podem ser gerados pelas activities ou não. Exemplo: SCREEN_OFF – gerado pelo sistema quando a tela é bloqueada. Você pode tomar atitudes de acordo com o tipo de alerta recebido. Um Broadcast Receiver (derivado de: android.content.BroadcastReceiver) segue o padrão GoF “Observer”. Ele se registra e fica observando se determinado evento geral acontece. É diferente da classe de uma Activity, que somente observa eventos gerados pelas suas Views. Este tipo de componente pode receber eventos gerados pelo código de sua aplicação, de outras aplicações ou mesmo do sistema Android. Quando a tela é desligada, por exemplo, é possível tomar alguamas atitudes. Nosso projeto: Hercules Password Protector (http://code.google.com/p/hercules-password-protector) usa um Broadcast Receiver para “fechar o cofre” caso a tela tenha sido desligada. A criação de Broadcast Receivers está fora do escopo deste curso. Lição 2: Ambiente de desenvolvimento Android APK Para ser executada e distribuída, sua aplicação Android tem que ser empacotada dentro de um arquivo com formato e extensão “apk” (Android Package). Algumas coisas são muito importantes neste arquivo:     O hashcode de todas as pastas é calculado e colocado dentro do “MANIFEST.MF”, que fica dentro do META-INF; A pasta “res” contém todos os recursos não compiláveis da aplicação, como: arquivos XML, Layouts, menus, imagens etc; Arquivo “dex”. Este contém todo o bytecode da sua aplicação, traduzido para bytecode Dalvik; Arquivo “arsc”. Este contém os strings e uma tabela com todas as entradas do diretório “res”, em formato binário; Antes de instalar um APK, você deve assiná-lo digitalmente. Isto pode ser feito com um certificado de assinatura de código ou com uma chave auto-assinada. O processo de montagem manual de um APK é bastante complexo e está fora do escopo deste curso. Veremos como criar APKs utilizando a IDE "eclipse". As únicas exigências são: 1. Você pode publicar suas aplicações no Android Market. o mercado de aplicativos para dispositivos móveis. E você pode facilmente publicar suas aplicações nele. The Code Bakers.dex” acessados. pagando US$ 25. Dentro da pasta “/data/dalvik-cache”. . Pode ser gratuita ou paga. que pode ser facilmente acessado pelos dispositivos móveis.xml”. A figura mostra um shell de comandos conectado a um emulador Android. O crescimento da plataforma Android. Sua aplicação tem que estar assinada com uma chave criptográfica privada. 4. é apontado (juntamente com o iPad) como o fator impulsionador do mercado apps. http://market.com. cuja validade termine depois de 22 de Outubro de 2033.xml”. e dentro da pasta “/data/app”.Página 5 de 84 A APP dentro do Device Tudo acontece dentro do diretório “/data”. Você tem que fornecer o “apk” da sua aplicação. de 320 x 480 pixels. 5. Neste site é possível encontrar inúmeros aplicativos. 2. tornando-se a mais utilizada no mundo. de seu arquivo “AndroidManifest. cujo número de novos aparelhos superou a Symbian no terceiro trimestre de 2010. temos algumas aplicações publicadas no Android Market. 6. Sua aplicação tem que definir os atributos: android:icon e android:label no elemento <application> do arquivo “AndroidManifest. tornando-se um mercado mais lucrativo que o de CD's. temos os arquivos “apk” de cada aplicação que instalamos. Você tem que fornecer pelo menos dois “screen shots”. Nós. tanto gratuitos como pagos.00 pelo registro (uma única vez). em seu dispositivo Android.android. 3. deve crescer de 7 bilhões de downloads para cerca de 50 bilhões até 2012. Você tem que fornecer um ícone de alta resolução (512 x 512 pixels) independentemente do ícone de lançamento da aplicação. 7. ou “apps”. De acordo com pesquisas da loja de aplicativos “GetJar”. temos os arquivos “. Na plataforma Android. Android Market Toda infra-estrutura para você distribuir sua aplicação para o grande público. Sua aplicação tem que definir os atributos: android:versionCode e android:versionName no elemento <manifest>. Você tem que ter uma conta no Android Market. temos o site Android Market. Veremos como administrar dispositivos mais adiante. acrescentando um "plug-in" chamado ADT.Página 6 de 84 Todo o processo de publicação é feito pela Internet e não há nenhum tempo de aprovação. então há necessidades posteriores (fora do escopo deste curso).google. dentro dele. Na segunda etapa. podemos utilizar a IDE "eclipse". valeu! Sua aplicação pode ser gratuita ou paga. Não é necessário possuir um dispositivo Android! Você pode desenvolver e executar em um "emulador". Para desenvolver.zip o Linux: http://dl. é transformado em bytecode Dalvik. quando compilado. .  O SDK que você está baixando é apenas para configurar a instalação. ou seja. Isto é feito em “Help / Install New Software / Add Site”. O mínimo necessário é:    O SDK (você já baixou e instalou). Baixar o Android SDK: o Windows: http://dl. publicou. de modo a poder criar um AVD (Android Virtual Device). Platform-tools. e o framework do Android (Android SDK).com/android/android-sdk_r10-windows. Indique o diretório clicando no botão “Browse”. exemplos. APIs e documentação.zip o Mac: http://dl. Configuração do ambiente  Baixar o eclipse (última versão).google. Ambiente de desenvolvimento Para desenvolver aplicações Android.tgz Baixar o plug-in ADT: configurar eclipse update site: "https://dl-ssl.com/android/android-sdk_r10-mac_x86. Se for paga.menu: Window / SDK and AVD Manager” do eclipse). Baixando as plataformas específicas O ambiente é composto por vários outros componentes: Plataformas.com/android/android-sdk_r10-linux_x86. Selecione todos os arquivos e baixe.com/android/eclipse/". ou seja.google. um emulador. para indicar ao eclipse onde está instalado o SDK. só com Java. Platform (você pode baixar pelo “Android SDK and AVD Manager” . você precisa uma plataforma. Descompacte-o em qualquer diretório e anote este como a raiz do SDK. baixaremos através do eclipse as APIs necessárias. que permite emular vários tamanhos de tela e características de dispositivos móveis. Baixe o eclipse e. Selecione o menu: “Window / Preferences” e selecione “Android”. configure o site de download indicado. O desenvolvimento é feito em Java e.google. Nós sempre instalamos a API level 7. pois corresponde à versão do Android dos nossos celulares. Você não precisa instalar todos os SDKs. dependendo da versão do Android e da API que desejamos.Página 7 de 84 Podemos instalar várias plataformas e APIs. Veja quais são as versões de Android e os API levels: . NDK 3 . NDK 5 API level 10 API level 11 API level 12 2. mas vai ser muito mais difícil. o plugin ADT foi desenvolvido para "eclipse". Você pode fazer tudo "na mão". Isto é muito importante! Você deve baixar a plataforma (via SDK and AVD Manager) correspondente ao público-alvo que você quer atingir.1 API level API level 1 API level 2 API level 3. NDK 4 API level 9.3.2.0. Se sua aplicação exige um determinado nível de API. existe farto material na Internet. android:maxSdkVersion: Qual é o nível máximo de SDK que sua aplicação suporta. 2.3 .0 3.3. assim como de sua API de programação. Você pode estabelecer os requisitos para sua aplicação através de três atributos de seu arquivo “AndroidManifest. E você deve desenvolver em uma plataforma (AVD) compatível com o nível de API que você espera. permite que sejam usados elementos do nível desejado. temos que assumir que você já possua alguns conhecimentos básicos: Java e eclipse.5 1.1-update 1) API level 7. NDK 1 API level 4.x 2. Por que eclipse? Por que não o NetBeans? Por que não fazer "na mão"? Bem. Atualmente.3 .4 3.3 em segundo lugar). Em segundo lugar. nós achamos que "eclipse" é a IDE mais utilizada pelos desenvolvedores.buzzero. Lição 3: Obtendo e analisando um projeto pronto Eclipse Neste curso.6 2.2 (e 2. NDK 2 API level 5 API level 6 API level 8.0 1.1 1.Página 8 de 84 Laboratório 1 Baixe e instale todo o seu ambiente de desenvolvimento.3.1 2. Veja as versões do Android e o nível de API de cada uma. até agora: Code name (no code name) (no code name) Cupcake Donut Eclair Eclair Eclair Froyo Gingerbread Gingerbread Honeycomb Honeycomb Version 1. ao invés do nível mínimo. a maioria dos aparelhos que temos visto usa Android 2. android:targetSdkVersion: Qual é o nível de API que sua aplicação prefere executar. É um chute.xml”:    android:minSdkVersion: Qual é o menor nível de API que sua aplicação suporta. O default é “1”.2 2.html ANDROID VERSION x API LEVEL Existem muitas versões do Android.2. E. inclusive este curso gratuito: https://www.0 2. você deve informar isto.2.com/Feedib/curso-online-JAVA-ECLIPSE. Se você não conhece "eclipse".1 (incl. sem IDE alguma.m alguns casos. mas é baseado na nossa experiência como professores e como membros de várias comunidades Open Source. evitará diversos problemas (e xingamentos). a URL é: "http://biomago. No site do Google Code do projeto. Para instalar o plugin: 1. Clique no botão "Add. Assim.".x" e adicione. Agora.org/update_1.tigris.wikipedia. O laboratório desta lição é você conseguir baixar um projeto. quais são os principais arquivos etc. chamado: "Subeclipse".org/update_1. técnicos. o BioMago. Sabemos que você está com pressa. é necessário que você instale um novo plugin no "eclipse". Para isto. marque todos. por exemplo. respire fundo e murmure: "Ohmmmmmm". leia o Manual!" Antes de você fazer um projeto seu no Android.googlecode. Existe até um ditado famoso: "Quanto tudo mais falhar. Pode demorar um pouco.6. você pode fazer "checkout" de projetos armazenados no Servidor SVN (subversion). deixe "Checkout" selecioando. são as mais utilizadas pelas pessoas que baixaram nossas aplicações do Android Market. até agora (Junho 2011). Desta forma.6.. 4. Você verá uma caixa com o título: "Use this command to anonymously check out the latest project source code:". quais são as pastas. colocar no Celular e mostrar para a Mãe. você terá a URL que deve ser informada ao configurar o "repositório SVN" dentro do "eclipse". relaxe e entre em meditação profunda. Clique no menu "Help / Install New Software. No conjunto de abas logo abaixo. Agora. de modo a prestar atenção no que vamos dizer neste momento. Subversion e Mercurial). Se quiser saber mais sobre Controle de Versões e Subversion.googlecode. para obter os projetos. Informe a URL: "http://subclipse.. quando chegar o momento de fazer seu próprio programa. Nós. Google Code e Subversion Nós mantemos todo o nosso código-fonte dentro do "Google Code". A URL do update site é: http://subclipse. que é um repositório de projetos Open Source. Tenha paciência e vá com calma. o Avô.x. pode sar da posição de lótus! Vamos usar o Subversion para importar um projeto para a nossa workspace. é melhor conhecer um projeto já existente. anote a URL que está logo após as palavras "svn checkout". logo. 2. Nós optamos por utilizar sempre o Subversion. recomendamos o site da Wikipedia: http://pt.. analisar o código-fonte e executar no emulador. sente-se em posição de lótus. a Namorada ou o Namorado.tigris. ou seja.. que permitem aos usuários baixar e subir atualizações. 2.2).org/wiki/Subversion. Crie um repositório: http://biomago. veja qual é a URL do servidor do projeto: 1. Após carregar. as versões "Eclair" (2. o Pai. No caso do BioMago.Página 9 de 84 Segundo nossas estatísticas. Você tem que ver como é estruturado. sempre temos pressa em fazer tudo e não temos paciência para ler manuais.com/svn/trunk: . selecione a aba "Source". logo. Certifique-se de aceitar a licença de uso. Feche a Janela e selecione o site recém-adicionado. 3.com/svn/trunk/". 5.1) e "Froyo" (2. Um projeto no eclipse Agora. Ele fornece acesso a servidores de controle de versão (CVS." para adicionar o update site. Na pasta “gen”. É claro que pode executar diretamente no seu Celular. Ele é auto-gerado a cada novo recurso que adicionamos ao projeto. informe a URL acima. Depois. menus e strings da aplicação. Para mudar isto: selecione o projeto e. 4.xml” é a declaração da aplicação. distribuir e executar a aplicação. layouts (de activities). Executando a aplicação Sua aplicação será executada DENTRO de um programa emulador de ambiente Android. A pasta “res” contém os recursos em si: imagens (drawables). layouts. Clique em “new”. Atenção: Para executar esta aplicação. e importe o projeto. Na pasta “src” temos todo o código-fonte Java desenvolvido. selecione o repositório que você acabou de criar. se você baixou apenas o Android SDK 7. Recomendamos usar HVGA. Abra a parte “Android” e selecione a plataforma desejada. temos uma classe muito importante: R. Criando um Android Virtual Device . 2. estilos e strings. aceite os defaults.:Google APIs:7. menus. A estrutura é bem simples. o Skin: a tela.Página 10 de 84  Selecione “Window / Show View / SVN Repositories” e clique com o botão direito. Porém. com o botão direito. Ele contém todas as configurações necessárias para empacotar. selecionando: “New / Repository location”. você deve ter baixado a plataforma: Google Inc. Clique em “Create AVD” e vá tomar um café. Demora MUUUUUUIIIIITO! .java! Nunca altere este arquivo! Ele contém identificadores para imagens. 3.properties” contém as propriedades do projeto. Informe os dados desejados: o name: o nome do seu dispositivo virtual. o SD-card (size): o tamanho em megabytes do SD Card. então deve mudar a plataforma. A mais importante é qual Plataforma está sendo usada para executar o projeto. Você precisa criar um "AVD" (Android Virtual Device) para isto. O arquivo “AndroidManifest. o target: a versão de Android e o nível de API que ele vai suportar.. Agora. selecione: “Properties”.AVD (Emulador) Para criar um AVD: 1. Clique no menu "Window" e selecione SDK and AVD Manager. O arquivo “default.. Selecione "builtin". vamos baixar o projeto para nossa Workspace:  Selecione “File / Import / SVN / Checkout projects from SVN”. o que é contra-producente. conforme ensinado anteriormente. selecione “apply” e “run”. Você pode criar AVDs que simulem o seu Celular ou Tablet. é só clicar no projeto e selecionar "Run as / Android Application" Emulador O emulador é como se fosse um dispositivo móvel mesmo! Ele possui todas as teclas de um aparelho típico. saia do aplicativo e veja o que o Android oferece a você. Porém. Executando a aplicação Selecione seu projeto. ou então o que você espera encontrar no mercado. pode até alternar entre em pé (portrait) e deitado (landscape) usando CONTROL ESQUERDO + F11. “menu”. Abra a aba “target”. Guarde o nome do AVD que você criou. Se quiser. . Selecione: Run / Run Configurations. Windows: DOCUMENTS_AND_SETTINGS/android/avd/[nome do avd].Página 11 de 84 Você só precisará criar AVDs uma única vez. Depois. e indique qual AVD é o preferencial. Ele tem as teclas “home”. inclusive um teclado de hardware. 2. será fácil adaptar seu programa para utilizar outras formas e tamanhos de tela. e faça o seguinte: 1. 3. sempre que desejar testar em um dispositivo diferente. Nós temos alguns smartphones Sony Xperia (um X10 e um X10 mini). Ele pode ser econtrado na pasta:   Linux: (é uma pasta oculta): ~/. ou então. Talvez você esteja se perguntando: eu preciso ter um dispositivo Android para desenvolver? A resposta é NÃO! Porém. além de um Samsung “S”.android/avd/[nome do avd]. o Google sempre se refere a uma configuração chamada de "Baseline": Tela: HVGA (320x480) Se você usar esta configuração. A tecla “menu” desbloqueia o aparelho. Você conhece o Android? Não? Então aproveite! Acione a tecla “back”. só que você tem que acionar “Debug” e colocar breakpoints no códigofonte. “back” e “magnify”. ajuda bastante. Nas próximas vezes. Ah! E para depurar é a mesma coisa. na Janela "Project Explorer". tivemos que dividir algumas lições. analisar o código-fonte e conseguir executar o aplicativo. Laboratório O laboratório desta lição é você conseguir instalar o plugin subeclipse. serviço do Google que utilizamos para manter nossa comunidade. Se quiser uma versão posterior. baixar o projeto BioMago (http://code. é hora de criar um projeto: Selecione o menu: "File / New / Android Project". no menu de contexto. para não confundir (selecione o projeto e.google. selecione "Android" e aponte para a localização do SDK. Deixe selecionados os campos: "Create new project in workspace" e "Use default location". Lição 4: Criando sua primeira aplicação Android Está na hora de criar um "Hello world" O aprendizado de toda linguagem de programação começa com um famoso programa. 1) Para começar. 2) Com a Workspace criada.. Informe o campo "Min SDK version" com a versão de SDK mínima necessária para que sua aplicação seja executada. então pode utilizá-la. Logo.1. incluindo esta. acrescido do nome do projeto. Em Android este nome é muito importante. em duas partes. selecione: "Project.1. que o assistente criará para nós (este é um class name!). tem que baixar a plataforma. Nós só temos dispositivos Android 2.". . neste caso.. de modo a criar uma aplicação simples no "eclipse". vamos criar uma nova Workspace: Depois de criá-la. Preencha o campo: "Package Name" com o nome do pacote Java. escolhendo "Android" na tela seguinte. Pode ser que a opção "Android Project" não apareça. usamos o nome de domínio ao contrário.Página 12 de 84 Problemas de publicação do Blogger O Blogger. Preencha os campos conforme a lista abaixo:        Informe o campo: "Project Name" com o nome do futuro projeto (não use espaços nem caracteres especiais). configure o Android SDK. Marque o campo "Build target". Marque o campo "Create Activity" e informe o nome da classe da Activity principal. do tipo: "Hello World". então use "7". Preencha o campo: "Application Name" com o nome que você quer que as pessoas conheçam o seu projeto. clique em "Close Project"). está apresentando problemas intermitentes de publicação. Role a tela para cima. Vamos fazer a mesma coisa! Siga as instruções a seguir. Se estiver usando Android 2. Se você já tem uma workspace criada (a do projeto anterior). Lembre-se de fechar o projeto "BioMago".com/p/biomago/). Abra o menu: "window" / "preferences". conectar ao servidor SVN. Normalmente. de modo a diminuir o tamanho e o número de imagens. Marque "Android Application". não terá que fazer isto.Página 13 de 84 Ao clicar "Next". .. Examinando o código-fonte gerado Peraí. Selecione seu projeto. Nós não escrevemos nada! Como pode haver código-fonte? O plug-in "ADT" gera uma aplicação "Hello World" automaticamente. pressione o botão "menu" para desbloqueá-lo (se aparecer um diálogo de espera. escolha "Run Configurations". e clique no botão "new" da caixa de diálogo. 3) Configure o AVD e execute o projeto no emulador: Para executar o projeto. abra suas propriedades e selecione "Android". seu projeto estará criado. deixe desmarcada e clique "finish". há instruções sobre como fazer isto. Da próxima vez.. No curso. logo. note que é oferecida a opção de criar um projeto de teste. aponte o nome do projeto. Neste momento. Selecione seu projeto. Após algum tempo. Selecione o AVD "target". Ao aparecer o Emulator com a "cara de um celular" na tela. você deve ter criado um AVD (Android Virtual Device). depois pressione: "Apply" e "Run". Você verá que a API desejada estará marcada. selecione o botão "Wait"). todo o código-fonte e configurações necessários já estão prontos. 6. @Override 9. Um arquivo "AndroidManifest. Uma classe "R. criada automaticamente dentro da pasta: 'src/gen". Layout "main. dentro da pasta: "res/values". 11. como strings e ícones: Classe da Activity "Principal. } O método "onCreate" é invocado quando a Activity é criada (não existe na pilha). Ciclo de vida de activities Quando uma activity está em estado "running". 4.java". que "embaralha" o byte code da aplicação. dentro de "res". 2. . } 13. dentro de "src" e dentro do pacote Java que você informou. 3. dentro de "res/layout". public void onCreate(Bundle savedInstanceState) { 10.Bundle. */ 8.Página 14 de 84 Vamos examinar a aplicação.main). import android. dentro de cada uma das três pastas "drawable".com.ProGuard é um ofuscador de código.xml". Um arquivo "default. setContentView(R. criado na raiz do projeto . seja do sistema ou de suas Views. criado na raiz do projeto. Ícone "icon. import android. A chamada do método "setContentView()" indica qual é o layout que deve ser exibido na tela que a Activity vai exibir.png". além de recursos.layout.onCreate(savedInstanceState). super. ela já possui uma activity com um layout criado.primeiro.app. contendo as propriedades do projeto. 5. package br.Activity.xml". Dois strings "hello" e "app_name".os. Um arquivo "proguard. dificultando a engenharia reversa. com todo seu estado preservado e pode receber eventos.xml" (os layouts e todos os arquivos XML do Android devem ter nomes em minúsculas). está visível. /** Called when the activity is first created.thecodebakers.java". Vamos examinar o código-fonte da nossa Activity: 1. public class Principal extends Activity { 7. Para começar. Este é um arquivo que configura esta ferramenta.properties".cfg". criados dentro de um arquivo "strings. 12. Para começar. Para cada transição de estado. . onStart a activity está para se tornar visível.getApplicationContext(). dentro do TAG <manifest>. Arquivo "AndroidManifest. um exemplo disto é quando uma caixa de diálogo é aberta (ou uma janela de notificação). public void clicouLinear(View view) { 2. Você pode ou não sobrescrevê-los. neste comando: 1. 4. A Activity fica nesse estado somente por uns poucos momentos.class). recebendo input e eventos. Outra atividade recebeu o foco e o controle. sobrescrevemos apenas o método "onCreate()". caso haja extrema necessidade de memória e recursos. um método "callback" da classe Activity é invocado. Normalmente. invocado quando a tecla "back" do dispositivo é acionada.xml". Note que ele possui diversas informações sobre seu projeto. como: "onBackPressed()". na verdade não existe. onRestart a activity estava "Stopped" e foi ativada novamente. deixando esta tarefa a cargo do sistema. this.Página 15 de 84 Se outra atividade ou diálogo receber o foco. enquanto seu método "onDestroy()" está sendo executado. Ela poderá ser desativada pelo sistema. Existem outros "callbacks" importantes. onStop a activity está totalmente oculta por outra activity e esta função é chamada. LinearDemo. é ideal que as animações sejam pausadas e o estado seja salvo. ele possui alguns atributos interessantes:  package: muito importante! Sua aplicação é conhecida pelo nome do pacote. pois acaba de iniciar outra Activity. que passa a estar em estado "Stopped". Ela continuará a reter seu estado. O Estado "Killed". } Ao executar a linha com a chamada: "startActivity()". Há uma nuance de diferença entre o estado "Paused" e o "Stopped". a atividade a qual este código-fonte pertence passará a ficar em estado "Stopped". onPause a activity está parcialmente oculta. 3. dependendo da sua necessidade. nós não encerramos manualmente as activities. dentro da raiz do projeto. Ela pode ser destruída pelo sistema. a activity passa para o estado "Paused".xml" Abra o arquivo "AndroidManifest. Já uma activity em estado "Stopped" foi completamente ocultada por outra Activity. Neste método. onResume a activity vai começar a interagir com o usuário. caso haja necessidade de memória. A não ser em casos extremamente específicos. Ela continua "visível" e retém seu estado. pois ambos partem do pressuposto que a activity foi "oculta". de modo a poupar recursos do sistema. onDestroy a activity está para ser eliminada da memória. Intent i = new Intent (this.startActivity(i). você pode fazer "commit" de alterações ou parar animações. A nuance é a visibilidade. Neste estado. mas existem os métodos: onCreate quando a actitivy está para se tornar "Running". Uma activity em estado "Paused" não está totalmente oculta. por exemplo. ocultando totalmente a primeira. com/guide/topics/manifest/manifest-intro. Pontos importantes: Toda activity deve possuir pelo menos uma View para interagir com o usuário. Lição 5: Layout e interface com usuário Criação de layout Um Layout é um arquivo XML que define quais ViewGroups existem e quais Views elas contém. temos que inserir tags <activity> manualmente:   android:name: o nome da classe (será concatenado ao string especificado no atributo "package".html).googlecode. Veja a activity principal ("main") para ver como se faz. <LinearLayout xmlns:android="http://schemas. /> 13. android:layout_width="fill_parent" 16.Página 16 de 84  android:versionCode e android:versionName: número da versão da aplicação. <TextView 14. /> 20.java”. Dentro do tag <application> temos atributos importantes:   android:icon: identificação do ícone da aplicação.verde" 15. de acordo com os nomes de imagens dentro da classe "R".com/apk/res/android" 2. style="@style/titulo_link.android. <TextView 7. abra a view: “SVN repositories”. android:layout_height="fill_parent" 5. nós inserimos os tags de nossas activities. Selecione a pasta “Layouts” e faça “Checkout”. android:onClick="clicouLinear" 12. android:orientation="vertical" 3. do tag <manifest>). porém.android.xml”: 1. android:label: título da aplicação. Primeiro em forma numérica e depois em forma String. No eclipse.vermelho" 8. Adicione o repositório acima. O Assistente do ADT faz isto para nós. 2. Normalmente. Todos os elementos de layout são referenciados na classe “R.xml". android:text="@string/table" 18. android:layout_height="wrap_content" 17. então temos que colocar um tag <intent-filter> com dois subtags. android:layout_height="wrap_content" 10. Expanda o repositório. <TextView . Examine o arquivo “res/layout/main. 3. Sugerimos que você leia os manifestos dos nossos projetos ou então entre no site do Android (http://developer. android:layout_width="fill_parent" 4. se inserirmos mais classes de activities. contendo um ViewGroup e algumas Views. Ainda dentro do tag <application>. Se a activity for utilizada para lançar a aplicação. android:text="@string/linear" 11.com/svn/trunk/”: 1. 4. android:onClick="clicouTable" 19. Baixe o projeto “http://layout-exercise. Todas as activities que não especificarem este atributo. style="@style/titulo_link. > 6. usamos um arquivo de layout. android:layout_width="fill_parent" 9. Existe muito mais para se saber sobre o arquivo "AndroidManifest. herdarão o valor deste. android:layout_width="fill_parent" 30. android:text="@string/listacombarra" 53. Ele deve possuir um e somente um ViewGroup principal. Execute a aplicação e selecione “LinearLayout”: . style="@style/titulo_link. style="@style/titulo_link. style="@style/titulo_link. android:layout_height="wrap_content" 38.piscina" 43. android:layout_height="wrap_content" 45. android:text="@string/relative" 25. style="@style/titulo_link. android:layout_width="fill_parent" 23. neste caso. <TextView 35. android:layout_height="wrap_content" 31. que. android:text="@string/with_images" 32. /> 48.Página 17 de 84 21. android:layout_height="wrap_content" 24. O LinearLayout coloca tudo em sequência. </LinearLayout> Todo layout é um arquivo ANDROID XML.laranja1" 36. é o LinearLayout. cujo nome deve começar com letras minúsculas. android:text="@string/dontDoIt01" 39.azul" 22. /> 41. android:layout_width="fill_parent" 51. /> 27. <TextView 49. /> 55. android:layout_width="fill_parent" 37.amarelo" 50. android:onClick="clicouDont02" 47. android:layout_width="fill_parent" 44. android:text="@string/dontDoIt02" 46. android:onClick="clicouWithImages" 33. <TextView 42. android:onClick="clicouDont01" 40. style="@style/titulo_link. android:onClick="clicouLista" 54.lilas" 29. android:layout_height="wrap_content" 52. <TextView 28. android:onClick="clicouRelative" 26. e deve residir na pasta: “res/layout”. /> 34. java”.Página 18 de 84 Todas as views “filhas” são organizadas em sequência. Ela encherá o ViewGroup. Agora. note que temos 7 Views dentro do nosso ViewGroup principal e todas são do tipo “TextView”. com três propriedades informadas: android:layout_width Qual é a largura que a View prefere ter. WRAP_CONTENT A view quer ser grande o suficiente para conter o texto (ou imagem) atribuído. dentro de seu “parent”. que é o seu índice na tabela. que.scale independent.xml”: 1. As propriedades “android:layout_width” e “android:layout_height” são muito importantes e são obrigatórias.primeiro. public final class R { 4. Ele cria uma constante dentro da “inner class” apropriada. android:layout_height="fill_parent" 6. android:layout_height="wrap_content" 10. Sempre que criamos alguma coisa na pasta “res”. usamos um número inteiro. 2. 8. o ADT altera a classe “R. Nós podemos especificar três valores: FILL_PARENT A view quer ser tão grande naquela dimensão (altura ou largura) como o seu “parent”. android:layout_width="fill_parent" 5. estilos. dentro da pasta “gen”. Para identificar o recurso. android:layout_height Qual é a altura que a View prefere ter dentro de seu “parent”. package br. enquando couberem na mesma linha. Voltando ao arquivo “main.android. </LinearLayout> Temos uma única “TextView”. public static final class drawable { 7. strings. } 6.density independent values.com/apk/res/android" 3. android:text Qual é o texto que será exibido dentro da View. > 7. No nosso caso. public static final int icon=0x7f020000.0" encoding="utf-8"?> 2. <LinearLayout xmlns:android="http://schemas.1/72 de polegada ou “px” -pixels. Unidades Podem ser “dp” . public static final class attr { 5.thecodebakers. abra o seu primeiro projeto. e veja o arquivo “res/main. os nomes dos recursos ficam “compilados” em uma tabela binária. chamada de “<projeto>. } 9.xml”. public static final class layout { . 3. estamos estabelecento que a TextView será da largura de seu “parent” e terá a altura suficiente para conter o texto que atribuímos (este é o padrão para “TextView”). /> 12. android:text="@string/hello" 11. “sp” . imagens etc. Uma “TextView” serve para exibir textos.arsc”. android:layout_width="fill_parent" 9. Nossa aplicação pode ter vários tipos de recursos (resources): layouts. <?xml version="1. <TextView 8. Na propriedade “android:text” especificamos um string resource.java” do nosso primeiro projeto: 1. android:orientation="vertical" 4.com. “pt” . cujo layout é mais simples. neste caso é o ViewGroup LinearLayout. Eis o “R. com/apk/res/android" 3. ou o arquivo: “edicao. 6. o texto que será exibido é o que está contido dentro do recurso de strings chamado “hello”. android:text="@string/lblNascimento" 27. Abra o projeto “BioMago”. Note que. e “string”. android:layout_height="wrap_content" 12. “drawable”. android:layout_alignParentTop="true" 8. Principal!</string> 4. 12. dissemos o seguinte: android:text="@string/hello" Logo. </resources> Por que isto? para facilitar a localização (L10N) de nossa aplicação. 11.0" encoding="utf-8"?> 2. que fica na pasta “res”: 1. } Temos três “inner classes” que são constantes dentro desta classe: “attr”. xmlns:android="http://schemas. android:layout_height="wrap_content" 28. E onde fica ele? Dentro de um arquivo XML. Outro muito importante é o “id”. android:layout_centerHorizontal="true" 25. Vamos primeiramente ver o arquivo de layout: 1. que representa imagens.java do projeto “Layouts”). <string name="app_name">Primeiro Projeto</string> 5. 22. que representa os identificadores que criamos dentro de nossos layouts (veja a classe R. android:layout_width="fill_parent"/> 21. android:layout_below="@+id/lblnome" 16. A atividade que faz o cadastramento é a “Edicao. public static final int hello=0x7f040000. android:layout_centerHorizontal="true" 17. android:layout_centerHorizontal="true" 9. android:layout_below="@+id/txtNome" 24. Finalmente. android:layout_height="wrap_content" 20. temos também os “ids”.Página 19 de 84 10. 16.android. style="@style/titulo" 11. ao cadastrar. android:layout_width="fill_parent" 4.java” e seu layout é “R. que representa recursos de strings. 14. android:layout_width="fill_parent" 13. } public static final class string { public static final int app_name=0x7f040001.layout. android:layout_height="fill_parent"> 5. que representa layouts de views. que representa atributos (não estamos usando). No layout de nossa activity (primeiro projeto). “layout”. o BioMago tem que pegar o nome e a data de nascimento. <TextView 23. 15. android:id="@+id/lblnome"/> 14.xml”. android:text="@string/lblNome" 10. style="@style/titulo" 26. <string name="hello">Hello World. } public static final int main=0x7f030000. Execute o programa e cadastre um registro. android:id="@+id/lbldata"/> . <resources> 3. android:id="@+id/txtNome" 18. que importamos na primeira aula. <TextView 7. <RelativeLayout 2. 13. <?xml version="1. android:maxLines="1" 19. <EditText 15. android:layout_width="fill_parent" 29.edicao”. . android:layout_below="@+id/lbldata" 34. que está em negrito: 1.. que significa: se não existir o “id” “txtNome”. android:layout_height="wrap_content" 37. 7. </RelativeLayout> Neste projeto. <ImageView 41. android:layout_below="@+id/lblnome" 3. ></ImageView> 60.. android:layout_width="wrap_content" 58. .. } 5. Uma entrada foi criada dentro de R. android:maxLines="1" 6. android:onClick="salvar" 49.. android:layout_gravity="left" 45. public static final class attr { 3. android:layout_alignParentBottom="true" 42. } 13. 12. android:layout_gravity="left" 55. crie-o. Note a View “EditText”.. android:layout_alignParentLeft="true" 43. <ImageView 51. 15. android:layout_width="fill_parent" 38. . android:layout_width="fill_parent"/> O que é isso? A propriedade “id” permite que nos referenciamos a uma View dentro do código-fonte Java. android:id="@+id/btnSalvar" 46. android:layout_height="wrap_content" 47. ></ImageView> 50. podendo obter o valor que o usuário digitou. <EditText 2. public static final int txtNome=0x7f07000a. android:layout_height="wrap_content" 7. android:layout_centerHorizontal="true" 4. android:layout_alignParentBottom="true" 52..java: view plaincopy to clipboardprint? 1.. por exemplo. public static final class drawable { 6. public static final class layout { 14... } 8. 40. 31. . android:id="@+id/dtData" 36. usamos outro tipo de ViewGroup. . public static final class id { 9. android:layout_width="wrap_content" 48. 10. android:onClick="cancelar" 59. 11. . android:id="@+id/txtNome" 5. android:layout_height="wrap_content" 57. O que informamos dentro da propriedade foi “@+id/txtNome”.Página 20 de 84 30. 4. android:layout_alignParentRight="true" 53. ></DatePicker> 39. que é o “RelativeLayout”. android:id="@+id/btnCancelar" 56. <DatePicker 32. 33. android:layout_centerHorizontal="true" 35. } . android:src="@drawable/ok" 44. public final class R { 2. android:src="@drawable/cancelar" 54. 25. public void clicouLinear(View view) { 2. 24. com ou sem sinal. temos um método com a assinatura: “public void clicouLinear (View view)”. criamos um novo identificador de View dentro de nosso projeto. android:text="@string/linear" 6.getText(). Para concluir esta parte.EditText: 1.Página 21 de 84 16. 3. abra o layout “main. … 5. Por exemplo.. … Assim.startActivity(i). } Repare que no layout. a TextView está apontando o “android:onClick” para “clicouLinear”.setNome(txtNome.id. style="@style/titulo_link. 21. android:layout_width="fill_parent" 4. } Ou seja.. 23. } public static final class style { .xml” e a Activity “Principal.getApplicationContext(). 4. precisamos ter uma maneira de reagir aos eventos provocados pelo usuário.toString()”. 3. ..toString()).. 18. LinearDemo. } public static final class string { . Elemento elemento = new Elemento(). o código da Activity tem que declarar uma variável do tipo: android. /> 1. txtNome = (EditText) this.java”. nossa EditText somente aceitará a digitacão de algarismos.. elemento. 22.toString()). A EditText possui alguns atributos e propriedades muito interessantes. Intent i = new Intent (this. <TextView 2. private EditText txtNome. por exemplo. como o clique de um botão. podemos acessar a View e pegar o nome que o usuário informou.valueOf(txt. 8. this. do projeto “Layouts”: 1.. public void salvar (View view) { 6. que nos permite nomear um método de “callback” dentro da classe da Activity. android:layout_height="wrap_content" 5. mas note que ele somente devolve um “Editable”. temos que usar o método: “getText(). como se fosse um campo de senha. e podemos usá-lo para nos referenciar à EditText que criamos.getText(). 20.findViewById(R. e uma instância de . Se quisermos pegar o string. 7. android:onClick="clicouLinear" 7. 19. E.vermelho" 3. 9. Todo elemento “Clicável” possui o atributo XML: “android:onClick”. O nome do método tem que ser o mesmo informado no atributo. 4.. se quisermos converter em um número: Long. por exemplo. } public static final class menu { . Podemos pegar o conteúdo de uma EditText com o método “getText()”. public class Edicao extends Activity { 2. Se informarmos “numberSigned” no atributo XML “android:inputType”.. e o atributo: “android:password” substitui o valor digitado por um círculo. e que na classe da Activity. e a assinatura tem que ter “void” como retorno. 17.widget.txtNome). Para obter o nome do usuário. o atributo XML “android:inputType” nos permite determinar qual tipo de dado o usuário pode digitar.class). você tem todos os elementos para fazer o laboratório 2. 4.content. AlertDialog. Dois pontos importantes: 1 Todos os diálogos são MODELESS.res. como uma página Web..Builder(this).string. 8. Para começar.OnClickListener() { 4.erro_data_posterior)) 3. 2.show().content. exibindo um diálogo que mostrará o resultado.Builder(this) . 2 . int which) { } }) .string. 3. apontamos para os recursos da aplicação usando a classe android.OnClickList ener() { public void onClick(DialogInterface dialog. Ela receberá um número e fará sua fatoração (decomposição em números primos).setNeutralButton(res. }).lblOK). Também poderíamos mostrar uma caixa de diálogo.erro_data_posterior)) . Ela serve para obtermos recursos. por exemplo “strings”. // comandos.Página 22 de 84 “View” como argumento.AlertDialog.getString(R. Poderíamos reescrever este código-fonte assim: 1. Resources res = this. Este método será invocado quando aquela TextView for “clicada” pelo usuário. só que usamos outra classe para isto: 1. AlertDialog alert = construtor. estamos criando um “Intent” que chama a classe da atividade LinearDemo. criamos uma instância de android. construtor. public void onClick(DialogInterface dialog.app.Builder e outra de AlertDialog. O método “startActivity()” inicia a outra atividade. new DialogInterface. 6. 5. 1 Crie um novo projeto Android. Agora.show().getString(R. 8. mas no código Java precisamos usar: <instância de Resources>. } 7. Pode ser uma Actrivity do projeto ou um aplicativo externo. 6. 2 Use sempre string resources e evite literais.setMessage(res. new AlertDialog.setPositiveButton("Ok". Nos arquivos XML usamos apenas “@string/<nome>”. alert. int id) { 5. Depois. 9.java”.getString(R. Laboratório 2 Vamos criar uma aplicação que interage com o usuário.Resources. . Neste caso. E o que o método faz? Ele invoca outra Activity! Ele cria uma instância de android.string. uma mensagem.getString(identificador). Lembrando que todo resource string está possui seu identificador dentro da classe “R.create(). 2. conforme fizemos no Laboratório 1.getResources(). new DialogInterface.. tipo JOptionPane. que serve para determinar o que será executado. 7.Builder construtor = new AlertDialog.setMessage(res. dentro do código-fonte Java.Intent. import android. estávamos de bom humor e providenciamos uma implementação do “Crivo”. if (numero > 0 && numero < 3) { 18.view. para você. resultado = Long. else { 17. O crivo de Eratóstenes Para decompor em fatores primos. foi criado pelo matemático grego Eratóstenes (c. e usar um diálogo para mostrar o resultado.util. 5.nom. 4.xml” e acrescente: a Uma TextView contendo o rótulo: “Número” (deverá estar dentro de um string resource).Página 23 de 84 Edite o layout “main. private static long sinalUltimo = 1. Felizmente. b Uma EditView que receba o número digitado (deve apenas receber números e deve ter “id”).List. import java. obter uma lista de números primos! Segundo a Wikipedia: O Crivo de Eratóstenes é um algoritmo e um método simples e prático para encontrar números primos até um certo valor limite. String resultado = null.Iterator. primeiramente. import java.View. import java. public static String fatorar (long numero) { 11. } 20.util. resultado = "0". 12.ArrayList. private static List<Long> primos. 3 O “callback” deverá decompor o número informado em fatores primos. 19. Segundo a tradição. 6.). c Um botão Button. } 16.factorwiz. 9.sampaio. o terceiro bibliotecário-chefe da Biblioteca de Alexandria.cleuton. que pode ser encontrada ao final da lição. 13. é necessário. O resultado de sua aplicação deve ser como a figura: Implementação do Crivo 1. public class FatoracaoBO { 8.util. 3. que invoque o “callback” para fazer e mostrar a fatoração. else { . package br. 285-194 a.toString(numero). 7. 15.C. if (numero == 0) { 14. 10. 2. 52. } private static List<Long> crivo (long n) { List<Long> lprimos = new ArrayList<Long>(). resultado = calcular(valor). } else { if (resultado. 30. 80. break. } } return resultado. } } return resultado. 23.next().pow((double)p.hasNext()) { Long valor = it. 84.hasNext()) { Long valor = it. 83.iterator(). 67.iterator(). 86. if (valor == 1) { primo = primo * sinalUltimo. 47. 50. 63. Iterator<Long> it = lprimos. 29. 60. 25.toString(primo). 68. 40. 61. 85.iterator(). 33. 77. 35. 78. 79. Iterator<Long> it = primos.length() > 0) { resultado += "x". 44. } resultado += Long. 28. 71. x++) { lprimos. 56. 24. } } m++. 81. Long valor = numero. 31. x <= n. 42. 55. 66. if (resto > 0) { primo = it. 58. Long primo = it. 41. 48.next(). 82. 39. 73.2) <= n) { int m = 2. 70. 26. 43.iterator(). 38. 53.next().remove(). while (Math. } it = lprimos. if (valor==(m*p)) { it. } long p = 2.next(). } primos = crivo(valor). 49. valor = numero * (-1). 59. while (valor > 1) { long resto = valor % primo. while (m*p <= n) { it = lprimos. 22. 57. 76. 32. } valor = valor / primo. Long valor = numero. while (it. 46. 65. } private static String calcular(Long numero) { String resultado = "". 36. 37. if (numero < 0) { sinalUltimo = -1. 69. 75. 64. 27. . 54. 72. 62.add(x). while (it. 34. 51. 45.Página 24 de 84 21. 74. for (long x = 2. é que há muito mais além da simples tradução dos termos (o que pode ser feito no Google Translator!). 92. enfim. l10n significa “Localization”. antes de utilizá-lo dentro do seu produto? As figuras humanas. Evite jargões. 94. 90. porém. Na verdade. Muito cuidado com eles! Procure saber se está utilizando cores próprias (em alguns lugares. cães. sem mãos e sem dedos. regionalismos. break. foram evitados a todo custo? A única figura aceitável é aquele bonequinho utilizado em banheiros. diversos itens podem ser mal interpretados em suas aplicações. que é preparar uma aplicação para vários idiomas e/ou culturas. que são animais de estimação por aqui. as imagens que você está utilizando. e até mesmo "bips" podem ser considerados ofensivos. o que talvez não saiba. a ordem da escrita (de trás para frente ou vertical). 95. outros itens importantes são: cores. Além disto. com a economia globalizada. como a RS Globalization. pronomes e substantivos) pode variar de um idioma para outro. ou localização. que é adaptar uma aplicação internacionalizada para um determinado idioma / cultura. textos "bonitinhos" e humor. As próprias palavras utilizadas. } } } return lprimos. partes do corpo e especialmente mãos. veja "checklist" da comunidade do OpenOffice:         Se a característica será traduzida para um idioma com ordem da direita para a esquerda. São aspectos muito importantes em um projeto de software. sem roupas. 97. A ordem das palavras (adjetivos. principalmente hoje em dia. existem várias empresas. o problema é social e humano. ou internacionalização. Foram evitadas figuras que contenham palavras? Especialmente trocadilhos ou representações de palavras? Você ser certificou que um único ícone não seja utilizado com significados diferentes? O texto escolhido para a interface de usuário deve refletir um produto internacional. } if (valor > p) { p = valor. Eu me assegurei que não existem elementos GUI dentro de textos? A equipe examinou com cuidado a internacionalização de um componente de terceiros. 88. sussurros. } Lição 6: Internacionalização e localização Internacionalização i18n significa “Internationalization”. É muito difícil internacionalizar uma aplicação. embora a API do Android ofereça algumas facilidades. 91. gritos.Página 25 de 84 87. 89. que oferecem serviço de internacionalização de produtos. 96. 93. . por exemplo. como o sinal de "ok". a cor da bandeira do vizinho é ofensiva!) Figuras de animais são extremamente complicadas. E não assuma que exista uma posição com significado universal. seu layout deve ser examinado literalmente utilizando um espelho. sem cabelo. Para ter uma ideia. Mãos: nem tente! Não existe uma só posição de mãos que não seja ofensiva em algum lugar da Terra. podem significar alimento em outro lugar! E sons? Gemidos. Talvez você já tenha ouvido falar nesses termos. por exemplo. figuras de animais e sons. <TextView 2.googlecode. Crie STRING . abra o projeto “Layouts” e mude o idioma do simulador para “en” (Inglês): 1. android:layout_width="fill_parent" 4. public void onClick(DialogInterface dialog. }).Builder(this). Agora. int id) { 5. Vamos ver um exemplo: 1.. Vejamos outro exemplo ruim: 1. } 7. Internacionalizada (i18n). alert. usando a classe “android.vermelho" 3. Isto é feito através de algumas atitudes importantes. ela aparecerá em Inglês. Na prática.setPositiveButton("Ok". temos dois literais string dentro de uma caixa de diálogo.util. Agora. Isto também dificultará a criação de versões da aplicação para outros idiomas. /> Repare que informamos um literal string na propriedade “android:text”. JAMAIS USE LITERAIS STRING! A não ser para criar mensagens de log. procure o ícone da aplocação “Layout exercise” e rode novamente. 8. Você verá que a aplicação automaticamente passou a exibir os elementos em Inglês (inclusive seu título). android:onClick="clicouLinear" 7. 2. fazendo as localizações necessárias. android:layout_height="wrap_content" 5. Se decidirmos criar uma versão para o Inglês (ou Francês).Página 26 de 84 Localização Uma vez que sua aplicação esteja internacionalizada. por exemplo).setMessage(“O registro foi alterado”) 3.com/svn/trunk/).OnClickListener() { 4. 5. android:text="Informe seu nome" 6. Abra o exemplo “Layouts” (http://layout-exercise. a começar pelos textos exibidos. Mande rodar. Práticas para promover a Internacionalização Para criar uma aplicação Internacionalizada.d(“Teste”.Log” (Log. o que tornará difícil manter várias versões simultaneamente. teremos que alterar o código-fonte da aplicação.Builder construtor = new AlertDialog. mesmo que você não a tenha preparado para determinado idioma (Espanhol. 2. 9. “Mensagem”)). AlertDialog alert = construtor.. é necessário que ela esteja preparada para isto. 3. construtor. recomendamos que você sempre crie a aplicação com o idioma default em Inglês. 6. // comandos. Saia da aplicação e selecione “Custom locale”. Selecione “Apply”. 4. Isto é porque ela foi Localizada para Inglês. ou seja. no mínimo:   Não existam literais "string" dentro do código-fonte Não existam literais "string" dentro de elementos de layout Para que seja possível fazer a localização (L10N) de uma aplicação. new DialogInterface. Selecione “en – english” e mantenha pressionado o mouse (menu de contexto). Desta forma. Neste exemplo.create().show(). AlertDialog. style="@style/titulo_link. . ou seja. android:layout_height="wrap_content" 16. public static final class attr { 5. public static final int app_name=0x7f040001. criando entradas dentro da classe “R. public static final int resultado=0x7f040003.com/apk/res/android" 3. <Button 18. inicie com um TAG: <resources></resources> e acrescente os tags <string></string>. public static final int fatorar=0x7f040004. Para isto. <resources> 3. public static final int numero=0x7f040002.thecodebakers. 20. android:layout_height="fill_parent" 6. basta selecionar a pasta e escolher “new / Android XML File”. android:layout_height="wrap_content" 10.java”: 1. /> 12. public static final int main=0x7f030000. android:onClick="fatorar" . } 15. public final class R { 4. public static final int icon=0x7f020000. android:text="@string/numero" 11. <string name="app_name">Laboratorio2</string> 5. Principal!</string> 4. public static final class drawable { 7.0" encoding="utf-8"?> 2. > 7. <string name="resultado">Resultado</string> 7. public static final int hello=0x7f040000. public static final class id { 10. public static final class layout { 13. } 6. 11. } 22. <LinearLayout xmlns:android="http://schemas. 18. selecionando “values”. <?xml version="1.0" encoding="utf-8"?> 2. public static final class string { 16.lab02. 8. Vamos ver como usar em um arquivo de layout: 1. android:layout_width="fill_parent" 15. <?xml version="1.android. Dentro do arquivo de String resources. } 9. </resources> Temos vários string resources criados e o ADT automaticamente os “compilará” dentro do arquivo “. 3. android:layout_width="fill_parent" 9. /> 17. 21. 14. 17.Página 27 de 84 RESOURCES (ou recursos String). 2. android:text="@string/fatorar" 19. android:orientation="vertical" 4.com. 19. public static final int txtNumero=0x7f050000.arsc”. } Podemos utilizar string resources dentro de código-fonte Java e dentro de arquivos de layout. android:layout_width="fill_parent" 5. android:id="@+id/txtNumero" 14. <EditText 13. <TextView 8. } 12. como no exemplo: 1. <string name="hello">Hello World. <string name="fatorar">Fatorar</string> 8. package br. <string name="numero">Número</string> 6. dentro da pasta “res/values”. res. Ambos estão definidos dentro de “res/values/strings. android:layout_width="wrap_content" 21. /> 23. A pasta sem sufixo passa a ser a localização “default”.OnClickListener() { 9. Toda a pasta “res/values” pode ser localizada desta forma: “res/values-pt” para português! Basta usarmos a tabela internacional de idiomas (ISO 639-1) e dialetos (ISO 3166-1) como sufixo do nome da pasta “values”. Uma vez criada a pasta do idioma. basta copiar os arquivos de recursos (estilos. Se usarmos “@string/” e teclarmos CTRL+ESPAÇO. . long numero = Long. Se o país / idioma não estiver lá.Builder(this) 7.string. que nos permite obter o texto de um resource string. </LinearLayout> Note que usamos dois resource strings neste layout: um para o rótulo do campo a ser digitado e outro para o do botão de cálculo. Vejamos um exemplo prático: 1. será aberta uma lista de escolha contendo todos os resource strings declarados.toString()). String resultado = FatoracaoBO. new DialogInterface. Resources res = getResources(). res/values-pt-rBR Português do Brasil (o “r” é para informar que as duas letras a seguir são o código da região). 5. int which) { 10. não usamos “r”.resultado) + ": " + resultado) 8. Para usar resource strings dentro do código-fonte Java. Onde obtemos este número? Ah! Dentro da classe “R. new AlertDialog. 3. Exemplo: “pt_BR”. Exemplos: res/values-pt Português em geral.show(). dado o seu índice (dentro da tabela “. strings. android:layout_height="wrap_content" 22. Neste caso.findViewById(R. As pastas “drawable” também podem possuir o sufixo de país e idioma. O emulador possui uma aplicação “Custom Locale”. é possível adicionar um.java”! Como criar Localização de uma aplicação Uma aplicação internacionalizada pode ser facilmente localizada. Não só os values (estilos. .getString(R. } A classe Resources contém o método “getString()” (entre outros).fatorar(numero). Laboratório 3 . cores etc) para dentro dela e traduzir seu conteúdo. strings etc) podem ser localizados.Resources” desta forma: Resources <variável> = this. 6.xml” (o nome do arquivo não importa).id. EditText txtNumero = (EditText) this. public void fatorar(View view) { 2.setMessage(res. que permite alterar o idioma dele. dependendo do país. 4. mas as imagens também.getText(). Devemos lembrar que certas imagens podem ter entendimento diferente. 11. res/values-en-rUS Inglês dos Estados Unidos. } }).content.arsc”). public void onClick(DialogInterface dialog.txtNumero).Página 28 de 84 20.setNeutralButton("OK". temos que obter uma instância da classe : “android.valueOf(txtNumero. Sugerimos que seja sempre em inglês.getResources(). <?xml version="1. que utilizamos nas lições anteriores (http://code. 2. independentemente se há botões para eles na tela. O Menu de Opções deve conter TODOS os comandos da Activity. que se aplicam à Activity como um todo.Página 29 de 84 Internacionalize o exercício anterior. Ele se aplica a um só item. O menu de opções é utilizado para opções gerais.google. prefira sempre a segunda opção.0" encoding="utf-8"?> <menu xmlns:android="http://schemas. que é um arquivo Android XML. quando vários itens são exibidos simultaneamente. temos o zip da solução dentro do projeto: http://code. Ele é a opção preferencial de comandos do usuário. Se for "jogar a toalha". Menu de contexto (context menu) – acionado pelo "touch and hold". não localizamos o menu em si. 5. Devemos evitar colocar opções de item dentro do menu de opções e opções gerais dentro do menu de contexto. O menu de contexto é utilizado em listas (veremos mais adiante). mas os Strings que ele exibe. 4. Teste em ambos os idiomas. dentro da pasta: "res/menu". criando a versão para Português e deixando o Inglês como a localização “default”.android. Ele é acionado quando o usuário aciona a tecla "menu" do dispositivo. Entre colocar um botão na tela e colocar um comando no menu.com/p/biomago/). Apesar de ser possível. devemos criar um menu resource.google.com/p/curso-basicothecodebakers/downloads Lição 7: menus e estilos Menu de opções Toda activity pode ter menus:   Menu de opções (options menu) – acionado pela tecla "menu" do dispositivo. Para criar um menu de opções. Recupere o projeto "BioMago". Eis um arquivo de menu: 1.com/apk/res/android"> <item android:id="@+id/mnuIncluirRegistro" android:title="@string/mnu_novo_registro" /> . 3. </menu> Cada elemento "item" é uma entrada de menu. Podemos ter ícones no meu.Página 30 de 84 6. 4. 8. Note também que foram atribuídos "ids" a cada elemento. de modo que possam ser referenciados no código-fonte. <?xml version="1. Este "callback" é invocado apenas uma única vez. Se você quiser alterar o menu antes de exibi-lo. <item android:id="@+id/mnuIncluirRegistro" 5. cujo rótulo está na propriedade: "android: title". android:title="@string/mnu_ajuda" /> 9. <menu xmlns:android="http://schemas.android. <item android:id="@+id/mnuAjuda" 9. </menu> Só devemos ficar atentos porque os ícones do Android podem variar. android:title="@string/mnu_novo_registro" /> 7. android:icon="@android:drawable/ic_menu_help" 10. precisamos "inflá-lo" dentro da Activity. quando mudamos a plataforma ou a versão. android:title="@string/mnu_ajuda" /> 11. Por exemplo: 1. android:icon="@android:drawable/ic_menu_add" 6. Uma vez que criamos nosso menu resource. <item android:id="@+id/mnuAjuda" 8. use o "callback": "opPrepareOptionsMenu()". mas teremos que fornecer as imagens. 13. 7. 12. ou utilizar as que estão no Android. 10. quando o menu precisa ser criado. E isto é feito no "callback" "onCreateOptionsMenu()". . 11.com/apk/res/android"> 3.0" encoding="utf-8"?> 2. 3.Menu de opções Vamos criar uma nova Activity para a Ajuda: 1.menu_lista.view. public boolean onOptionsItemSelected(MenuItem item) { 3.mnuIncluirRegistro: 5.startActivity(i). 4. Intent i = new Intent (this.xml" para acrescentar a sua activity.xml". Se analisarmos a propriedade "id".menu. return true. Agora é hora de mais exercícios! Laboratório 4 . classe que representa um item de menu.incluirRegistro(null). 6. return true.inflate(R. bastando passá-lo no método "inflate". @Override 2.mnuAjuda: 8. Veja como o do BioMago foi feito. 2. 3. Agora só falta uma coisa: interceptar quando o usuário clicar em um item do menu! Como você deve ter advinhado. Eis o código usado no projeto "BioMago: 1.java". com um texto explicativo sobre sua aplicação. } Este "callback" recebe uma instância de "android. Crie uma classe que estenda "android. 5. Ajuda. vamos criar um menu resource: 1. 12. 7.java". case R. Crie um novo arquivo de layout chamado: "ajuda.getItemId()) { 4. Crie um string resource: "ajuda". 10. 6. A parte sobre menu de contexto veremos mais adiante. Agora. há um "callback" para quando um item do menu de opções é clicado: "onOptionsItemSelected() ".view. poderíamos criar o menu "na mão". 13. menu). Altere o arquivo "AndroidManifest. Isto está fora do escopo deste curso e não recomendamos que seja feito. 4. this. return true. 9.Activity" e escreva seu "callback" "onCreate()".id. } Usamos a classe "android. juntamente com o menu recebido. inflater. dentro de "res/layout" (new / Android XML file – layout).app. switch (item. Ao invés de fazer isto. 11. @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater().Página 31 de 84 1.getApplicationContext().id. através do seu "getter" ("item. inicializando o seu layout. Veja como fizemos no projeto BioMago.MenuInflater" para transformar nosso XML de menu em uma estrutura de objetos de menu. this.onOptionsItemSelected(item). } 14. Veja o "callback" da activity principal. podemos comparar com os "ids" criados em nossa classe "R. É claro que o identificador do nosso menu foi criado dentro da classe "R.getItemId()"). preenchendo os itens necessários dentro do "callback".MenuItem". Crie um bonito layout. case R.java" (lembre-se: todo "id" é criado também dentro da classe "R. e você criou "ids" para os itens de menu dentro do XML!). com os textos apropriados em Português e Inglês! .class). default: return super. 2. conforme fizemos na apostila e no BioMago. conforme a apostila e o BioMago. No mesmo código. 3.vermelho" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/linear" android:onClick="clicouLinear" /> Podemos definir várias propriedades. "bottom". 5. dentro da pasta "res". . <item name="android:textColor">#ffffff</item> 3. relaxe! Nós já colocamos a solução dentro do projeto do curso (http://code.Large"> 2. vamos inflar o menu dentro do nosso código-fonte: 1. 4. in (polegadas). "center". dp (density-independent pixels).. "android:height" altura da View. <item name="android:textColor">#ff0000</item> 10. "center_vertical". <style name="titulo_link. <item name="android:textStyle">bold</item> 5. "right". 7. </style> 8. adicione o "callback": "onCreateOptionsMenu()".java). o invocar a activity de ajuda. "fill_vertical".vermelho"> 9. mm (milímetros). acrescente o "callback": "onOptionsItemSelected() ". Crie uma pasta "menu". <item name="android:clickable">true</item> 7. A unidade pode ser: px (pixels). <TextView style="@style/titulo_link. <style name="titulo_link" parent="@android:style/TextAppearance. do tipo "menu". Finalmente. Estilo Um estilo é um conjunto de propriedades que afetam a visualização de um item. Se você não conseguir fazer. 2. onde um estilo "herda" de outros. Podem ser definidas diretamente ou em um arquivo XML (similar ao conceito de CSS). Coloque os itens: "novoRegistro" e "ajuda". 3. <item name="android:typeface">monospace</item> 4. Os valores possíveis são: "top". </style> Podemos utilizar o estilo derivado em qualquer View: 1. sp (scaled pixels basedos no tamanho de letra preferido). <item name="android:layout_height">wrap_content</item> 6.google.Página 32 de 84 2. por exemplo: TextView / EditText "android:gravity" como alinhar o texto se ele for menor que a "View". 6. dependendo do tipo de elemento. Use os strings que já existem.com/p/curso-basico-thecodebakers/downloads/list). "center_horizontal". Também existe o conceito de herança. 4. 2. "fill_horizontal" etc. No código da Activity principal (Principal. alterando as opções do "switch" para: o calcular o fatorial. Selecione a pasta "menu" e crie um novo Android XML File. Tenha cuidado com os "ids" e com os "titles". "left". Exemplo: 1. Black". Veja o projeto "Layouts". <action android:name="android. "android: typeFace" "normal". Também deverá existir uma entrada em "R. que deverá estar dentro de um arquivo Android XML. que permite informar um recurso de imagem (drawable) para ser aplcado ao fundo da tela. localizados na pasta "res/values". <uses-sdk android:minSdkVersion="7" /> 7. O Android já possui vários temas que podemos usar.intent. <activity android:name=". </activity> Note que aplicamos um tema chamado "imagem". Eis o estilo: 1. como "asset" e configurar em sua aplicação.intent. É definido como os estilos e pode ser aplicado a uma Activity (tag <activity>.xml". . android:versionCode="01010001" 4. </style> Ele usa o item "android:windowBackground". Lição 8: Temas e imagens Temas (Themes) Um Tema (ou "Theme") é um conjunto de estilos aplicatos a uma Activity inteira (ou a uma aplicação inteira). como: "@android:style/Theme. "sans".thecodebakers. <intent-filter> 13. <manifest xmlns:android="http://schemas.com. android:label="@string/NOME_VERSAO"> 12. 6. ou podemos herdar duas propriedades com o atributo "Parent".WRITE_EXTERNAL_STORAGE" /> 8. package="br.png". Abra o projeto "BioMago" novamente e veja o arquivo "AndroidManifest. "android: textSize" tamanho da letra.main" 10.category. (**) Se você quiser utilizar fontes externas.android. android:versionName="@string/NOME_VERSAO"> 5. do layout) ou à aplicação inteira (tag <application>) no arquivo "AndroidManifest..activities. android:theme="@style/imagem" 11. é possível carregar arquivos "TTF" .MAIN" /> 14. criada automaticamente.java".Black"> 2. </intent-filter> 16. <application android:icon="@drawable/icon" android:label="@string/NOME_VERSAO"> 9. Se procurarmos nas pastas "res/drawable.xml": 1.Página 33 de 84 "android:textColor" uma cor em formato RGB Html (ou uma referência a outro estilo). <category android:name="android. entre tags <style></style>.. <item name="android:windowBackground">@drawable/fundo</item> 3.com/apk/res/android" 2.Trye Type Font. Mas isto está fora do escopo deste curso.LAUNCHER" /> 15. "android:textStyle" "normal". adaptado para formato "em pé" (portrait -port) ou "deitado" (landscape -land)." veremos um arquivo "fundo. <style name="imagem" parent="@android:style/Theme. Os estilos podem ficar dentro de arquivos XML.biomago" 3. "serif" e "monospace" (**). que é o fundo de tela.action. Pode usar qualquer unidade das já mencionadas.permission. <uses-permission android:name="android. "bold" ou "italic". na pasta "res/values". 2 . indicando ao Android qual é o tipo de recurso que está lá. incluindo qual Porta TCP ele está escutando. As pastas "drawable" ficam dentro da pasta "res". Quando usamos uma imagem. É recomendável que você inicie seu desenvolvimento sempre usando esta configuração.Digite o comando: . Cada pasta "drawable" pode ter um ou mais sufixos. Depois. orientação da tela etc.Abra a pasta onde instalou o Android-SDK e vá para a subpasta "tools". As telas dos dispositivos que executam aplicações Android podem ter características totalmente diversas. Você verá o seu emulador listado. separando os arquivos em pastas. incluindo qual Porta TCP ele está escutando.2" polegadas. uma nova entrada é criada na classe "R. É muito importante aprender a utilizar corretamente o ADB. Para ver um exemplo.Abra a pasta onde instalou o Android-SDK e vá para a subpasta "platform-tools".Abra a pasta onde instalou o Android-SDK e vá para a subpasta "tools". Taxa de aspecto Se é muito mais alta ou muito mais larga que a configuração básica. . abra outra janela de comandos (deixando a original aberta) e veja se o seu emulador está sendo executado corretamente: Para Linux 1 . por exemplo. Para iniciar um emulator fora do eclipse. o Android automaticamente seleciona de qual pasta ele vai pegar. Para Windows 1 .Abra a pasta onde instalou o Android-SDK e vá para a subpasta "platform-tools". abra uma janela console e digite: Para Linux 1 .Digite o comando: adb devices. A cada imagem criada lá.java". sobre a qual nós já falamos anteriormente. as características das imagens podem ser: Tamanho Em polegadas medidas na diagonal maior. idioma. digite: adb logcat para ver o log de execução.Digite o comando: . dependendo da configuração do dispositivo móvel (ou do emulador) em uso. em seu projeto. digite: . Depois. Voltando ao nosso assunto. No projeto "BioMago" podemos ver estas pastas com seus recursos. Para Windows 1 ./adb devices. 2 . de acordo com os atributos das imagens. Você verá o seu emulador listado. como uma imagem.Página 34 de 84 Recursos de imagem Um "drawable" é "algo que se pode desenhar". por fora do "eclipse". você deve ter criado um AVD utilizando a configuração default ("HVGA"). 2 . Eles podem ser divididos por: resolução.Digite o comando: emulator -avd <nome do avd>./adb logcat para ver o log de execução. Agora. 2 ./emulator -avd <nome do avd>. A plataforma define como configuração básica (Baseline Configuration): HVGA (320x480) em uma tela de 3. tomaremos um erro porque a ordem está incorreta.android. como: layouts. -xhdpi e -nodpi acordo com a densidade da tela. o android liga seu mecanismo e faz a escala automaica Padrões de sufixos Para simplificar a vida do desenvolvedor.com/guide/topics/resources/providing-resources. Para densidade: ldpi (baixa). de acordo com o tipo de tela ou idioma (http://developer. De -mdpi. -large. Se não for importante. O Android fornece uma tabela com os vários tipos de diretórios. mdpi (média).Página 35 de 84 Resolução Quantidade de pixels na tela. normal. por exemplo. ou "deitada": landscape Densidade -ldpi.xml". normalmente medida por pixels horizontais x pixels verticais – 1 pixel = 1/72 de polegada Densidade Distribuição dos pixels pela tela – medida em DPI.html#AlternativeResources). -pt-rBR. Podemos até mesmo delimitar o tipo de dispositivo no qual nosso aplicativo roda. -normal. "res/drawable-land-hdpi" : recursos de imagem para telas em orientação "deitada" e de alta densidade. podem ter sufixos. por exemplo: "res/drawable-normal-port" : recursos de imagem para telas de tamanho normal () em orientação "em pé". colocando-os nas pastas apropriadas. Todos os diretórios de recursos. o android desabilita seu mecanismo de escala automática de pixels. É muito importante adaptar os recursos de imagem de acordo com o tipo de tela que estamos esperando. a plataforma Android criou os seguintes padrões: Para tamanho de tela: small. hdpi (alta) e xhdpi (muito alta). large e xlarge. -en-rUS -small. podemos especificar o elemento <supports-screens></supports-screens>. dentro do arquivo "AndroidManifest. Podemos classificar os recursos de imagem. -land Orientação da tela. Vamos reproduzir aqui os mais importantes: sufixo Idioma e região Tamanho de tela Exemplo -pt. . desde que a ordem seja seguida. confiando na aplicação para isto. se está "em pé": portrait. -hdpi. use "nodpi" Podemos classificar nossos recursos de imagem combinando estes sufixos. Se tentarmos criar uma pasta assim: "res/drawable-ldpi-port". desde que seja EXATAMENTE NA ORDEM DA TABELA. -xlarge Descrição Idioma e região dos recursos contidos nesta pasta Recursos classificados por tamanho de tela Orientação -port. Se "false". values e drawables. que permite estabelecer os tamanhos de tela suportados e se nossa aplicação sabe lidar com diferentes densidades:     "android:smallScreens" (true / false) "android:normalScreens (true / false) "android:largeScreens (true / false) "android:anyDensity" (true / false) – se "true". Se não houver (por exemplo. até que tenhamos completado as três. os métodos "onDestroy()" e "onRestart()" serão invocados. Use sempre a última como ponto inicial. vamos diminuindo a imagem e colocando na pasta correspondente. . Neste caso. Tente fazer! Se estiver ameaçado(a) de divórcio. substituindo o botão por uma imagem (uma imagem "clicável". hífens e caracteres especiais (incluindo espaços) nos nomes das imagens! Laboratório 5 Este é um "Big lab"! Dentro do projeto do curso (http://code. Portrait / Landscape O Android automaticamente re-inicia nossa activity caso ocorra alguma mudança na configuração. Podemos criar imagens de densidades e tamanhos diferentes utilizando programas gráficos como o GIMP (http://www. não insista! Baixe logo a solução (http://code. podemos criar imagens de background adequadas e colocá-las nas pastas corretas ("-port" ou "-land"). tanto de ícones como de backgrounds. como a orientação da tela. Melhorar a aplicação. Não faz parte do escopo deste curso interceptar este comportamento.org/) .google. como o programa "BioMago" usa para inserir novo registro – ajuste a imagem de acordo com a densidade da tela. Centralize a imagem e a caixa de texto. Providenciando as imagens de acordo com a densidade.zip". Neste laboratório. Depois. nós evitamos este trabalho e nos certificamos de que as imagens apareçam corretamente. 3. Neste caso. mdpi: 48 x 48 pixels. O Android tenta carregar a imagem de acordo com a densidade da tela. dependendo da orientação da tela. de acordo com a configuração básica do Android. por exemplo.Página 36 de 84 Calculando a densidade Nada impede que você use um só tamanho. independentemente de densidade ou tamanho da tela.com/p/curso-basico-thecodebakers/downloads/list). 2. Eis o tamanho (em pixels) dos ícones de lançamento. Os ícones de lançamento (Launch Icons) são um bom exercício de densidade. colocamos na pasta "-drawable-hdpi". Há certos dipos de imagens (e até layouts) que podem variar. Observações Os nomes das imagens em cada subdiretório de "drawable" devem ser iguais! Não use: letras maiúsculas. respeitando a ordem mostrada na tabela anterior. há um arquivo "exemplos_temas. Criamos uma cópia da imagem do ícone em tamanho maior (72 x 72 pixels). você vai: 1.gimp.com/p/curso-basico-thecodebakers/downloads/list). de acordo com a densidade da tela:    ldpi: 36 x 36 pixels. Crie estilos para ambos. que contém algumas sugestões de imagens. Crie fundos de tela para orientações diferentes. para que você melhore sua aplicação de fatoração. hdpi: 72 x 72 pixels. você não está usando o sufixo de densidade ou então está usando "-nodpi") o Android tentará escalar a imagem para a densidade correta.google. android:layout_weight="1" 11. android:layout_width="fill_parent" 9. android:layout_height="fill_parent" 10. Os elementos de uma lista podem ser selecionados com soft-touch e podemos criar "Intents" contendo a posição do elemento. <RelativeLayout 15. android:layout_height="wrap_content" . e é implementada usando um Layout e um Adapter.com/p/layout-exercise/) para ver a implementação básica de uma view. dentro da classe Java da Activity. Uma lista é uma view do tipo "ListView". dentre os quais podemos escolher qualquer um com softtouch (toque curto) sobre ele. android:layout_height="wrap_content" 17.Página 37 de 84 Lição 9: Listas Trabalhando com listas Listas são estruturas lineares contendo elementos. xmlns:android="http://schemas. android:background="#999999" 12. > 7. <ImageView 19. > 18.android. temos o arquivo de Layout: 1. android:layout_height="fill_parent" 6. 14. Para começar. Também é possível selecionar o menu de contexto de um elemento com touchand-hold (toque longo) sobre ele. android:orientation="vertical" 4.google. <LinearLayout 2. /> 13.com/apk/res/android" 3. <ListView android:id="@android:id/list" 8. Montagem de uma lista Abra o projeto "Layouts" (http://code. passando-a como "extra" para outra activity. android:layout_width="fill_parent" 16. android:layout_width="fill_parent" 5. android:layout_width="wrap_content" 20. 20. super. adapter = new ArrayAdapter<String>(this. Criamos um vetor de Strings e o passamos para uma instância de "android. lv_arr[1] = res.setTextFilterEnabled(true). lv_arr[0] = res. 11. private static final String TAG = "main". Uma das maneiras de fazer isto é implementar a interface: "android. private String [] lv_arr = new String[3]. @Override 8. 24. Resources res = this. formando uma barra inferior. int arg2. conforme a figura apresentada anteriormente. private ArrayAdapter<String> adapter = null. </LinearLayout> Aqui. O usuário seleciona um elemento com "soft-touch". public void onItemClick(AdapterView<?> arg0. listView = (ListView)findViewById(android.string. 3. que são assunto para outro curso. 21.Página 38 de 84 21. O preenchimento da lista é feito dentro do código-fonte da "Activity": 1. private ListView listView. Isto é feito atribuindo-se "1" ao "peso" (android:layout_weight) da "ListView". listView. que oferece o método "onItemClick()" que nos permite saber qual item foi selecionado: 1. 10. 15.onStart(). Assim. View arg1.string.listascombarra).R. passamos uma referência para a própria Activity.R.lista1). public class ListaComBarra extends Activity { 2. um formato de layout e o próprio vetor.onCreate(savedInstanceState). @Override 16. No construtor. usamos o "id" da lista padrão do Android: "android. ou seja. android:layout_centerHorizontal="true" 24.lista3). combinamos uma "ListVIew" e uma "ImageView".ArrayAdapter". é possível a convivência de ambos. Para começar.lista2). 4. super.getString(R. public void onCreate(Bundle savedInstanceState) { 9. clicando sobre o elemento desejado. ></ImageView> 25. listView.list". listView.layout. android:src="@drawable/terra_icone" 22.getResources(). @Override 2. 19.getString(R. que é uma classe adaptadora para passar elementos para a ListView. protected void onStart() { 17. 5.setOnItemClickListener(this).simple_list_item_1 .AdapterView. 23. 12. 7.setAdapter(adapter). lv_arr).widget. É um padrão usar sempre este "id" porque podemos usar Activities especiais (ListActivity).getString(R. Processando seleção de elementos Abra o projeto "BioMago".list). 18. long arg3) { . 6.string. 25. 13.widget. } O evento "onStart()" é invocado quando a Activity vai começar a receber inputs do usuário. android:id="@+id/btnIncuir" 23. 22. porque usamos isto no Layout: "@android:ïd/list".R.OnItemClickListener". Pronto! A lista está construída.id.layout. } 14.android.id. </RelativeLayout> 26. setContentView(R. lv_arr[2] = res. Um intent serve para invocar outra Activity da mesma aplicação ou de outra aplicação. veja o código (da activity de destino) que recebe e trata a informação contida nos "extras": 1. estamos utilizando apenas para invocar Activities internas. Crie um vetor de instância e dentro de "onStart()" o preencha.getString("nome")). No momento. Laboratório 6 Listas Vamos alterar o projeto "Layouts" para usar uma lista na primeira Activity: 1. Através dele. 2. nos permite obter um string através do seu nome. i. this. podemos obter o elemento em uma variável de instância e passar para a outra Activity. String)". preste atenção apenas a esta linha. Eis a imagem da nova "cara" da activity: . // Houve um soft-touch na lista // Pegamos o elemento e mostramos o biorritmo dele.getExtras(). dados[0]). } O terceiro argumento do método (arg2) é o índice do elemento selecionado (começando em zero). O método "getIntent()".Página 39 de 84 3.startActivity(i). Bundle extras = getIntent(). Podemos até testar se veio algo ou não. i. eis um código que invoca outra activity passando "extras": 1. 2. Na Activity de origem.getApplicationContext(). dados[1]).get(arg2).putExtra("data". O método "getString()" da classe "Bundle". 3. if (extras != null) { 3. imagem.java". da classe "Activity" nos permite obter uma referência para o Intent passado para ela. passando o nome e o valor do String que queremos "pendurar" no Intent. passando-as para a Activity seguinte. 7. 2. String elementoBruto = listaElementos.. Por exemplo. 4. 5.setNome(extras.os. 6. Intents com "extras" Podemos "pendurar" informação dentro dos "Intents". simplesmente usamos o método "putExtra (String. Assim. Altere o layout "main" para usar uma lista. ao invés de TextViews. pegamos o "Bundle" (android. Por enquanto. Na Activity de destino.Bundle) que veio anexado ao "Intent". podemos passar informações entre Activities. Agora. 5. Intent i = new Intent(this.class). GrafBio. 4. 3.. Ele também pode carregar "Strings" como argumentos para a Activity que está sendo invocada. Implemente "OnItemClickListener" e o método "onItemClick()". . Na Activity "Principal.putExtra("nome". .com/p/curso-basico-thecodebakers/downloads/list). siga nosso conselho anterior: sente-se em posição de lótus e medite por 1 hora. Tente fazer! Se estiver difícil. Serve para ações executadas sobre um único e determinado elemento. então baixe logo a solução (http://code. exibido pela ação “touch-and-hold” (pressionar e segurar) sobre um item. fazendo o som: "OOOOMMMMMM"! Caso ainda não consiga.Página 40 de 84 Extra: se houver tempo. mostrando o String que veio no Extra. Lição 10: Context menu e instalação de aplicações Context Menu É um menu "popup". Passe o nome selecionado. insira uma TextView em pelo menos duas das Activities. que pode ser um elemento de lista.google. A primeira coisa é sobrescrever o método "onCreateContextMenu()". dentro da pasta "res/menu".getMenuInfo().msg_confirmar_exclusao) 19. switch (item. 6. passamos a instância da ListView que criamos em nosso Layout. Abra o projeto BioMago e veja o arquivo de menu "menu_contexto.getNome()). @Override 2. 9.setMessage(R. menu. 4.menu_contexto.mnuCntExibir: 9. 18.com/apk/res/android"> <item android:id="@+id/mnuCntExibir" android:title="@string/mnu_exibir_grafico" /> <item android:id="@+id/mnuCntExcluir" android:title="@string/mnu_excluir" /> </menu> Criamos dois itens neste menu. GrafBio." Passando a instância da View que pode gerar menu de contexto. Resources res = getResources(). menuInfo). . precisamos usar o método: "registerForContextMenu(listView). na Activity. 3. menu). Depois. Intent i = new Intent(this. 3. i.android.getDateInstance(). MenuInflater inflater = getMenuInflater(). 6. Resources res = getResources(). da mesma maneira que o Options menu.setHeaderTitle(res. @Override public void onCreateContextMenu(ContextMenu menu.getListaPessoas(). 5.Página 41 de 84 Um context menu é criado como um recurso de menu. case R.getString(R.setNegativeButton(txtNao. 7. public boolean onContextItemSelected(MenuItem item) { 3. 11. 13. View v. public void onClick(DialogInterface dialog.id.string. da classe "Activity". 8. v.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.menu. String txtSim = res. <?xml version="1.OnClickListener() { 20. com os string resources e ids bem identificados.getApplicationContext().xml": 1. 2.onCreateContextMenu(menu. new AlertDialog. new DialogInterface. this. 4. int which) { 21. String txtNao = res. 17. ContextMenuInfo menuInfo) { super. A diferença é que temos que informar um título (que deve ser um resource string). comandarExclusao(elemento). new DialogInterface.getString(R.getItemId()) { 8. temos que: 1) criar o menu a partir do recurso e 2) interceptar o clique no menu de contexto.getString(R. sdf. 4. return true.inflate(R.OnClickListener() { .string. } }) 23.txtSim).startActivity(i). 5. AdapterContextMenuInfo info = (AdapterContextMenuInfo) item. Para interceptar o clique em um menu de contexto. elemento.position).applyPattern("dd/MM/yyyy"). pois menus de contexto sempre possuem um título. Neste caso. 7.id.format(elemento. . } Usamos um "MenuInflater" da mesma maneira que fizemos com o Options Menu. Eis o exemplo do BioMago: 1.get(info.string.putExtra("nome". final Elemento elemento = (Elemento)bo. 10.string.getNascimento())). 16. i. 2. 22. 7.putExtra("data". inflater. da classe "Activity": 1. 12. SimpleDateFormat sdf = (SimpleDateFormat) SimpleDateFormat.Builder(this).setPositiveButton(txtSim. 6.mnuCntExcluir: 15.txtNao). case R. No "onCreate()" da Activity. sdf. 9. 5.mnu_titulo_menu)). sobrescrevemos o método: "onContextItemSelected()".class). 14. 8. passando o identificador do nosso Menu Resource para ele. O objetivo. Nós já vimos como listar os dispositivos/emuladores ativos (adb devices). Se você ainda não tem um dispositivo com Android. Remoto: que roda como um "daemon" no dispositivo/emulador. Encaminhar portas TCPForwarding Ports. Instalação de aplicações no seu dispositivo móvel Podemos instalar aplicações de 3 maneiras:    A partir do Android Market Copiando para o aplicativo (via Astro ou semelhante) Utilizando o progama "ADB" Enquanto você estiver desenvolvendo e testando sua aplicação. pensamos que seria o momento de conversar sobre mais funcionalidades do utilitário "ADB". Pode ser a propriedade "id". o que nos interessa é como instalar aplicativos no seu dispositivo. Abrir um Shell de comandos para o dispositivo ou emulador. que roda em três partes:    Cliente: que permite enviar comandos ou pegar informações de um dispositivo. e também como ativar a janela de log (adb logcat). } }) 27. não queremos ficar perdendo tempo explicando detalhes que não interessam. chegou a hora de instalarmos as aplicações no seu dispositivo móvel (Celular ou Tablet). entre elas:     Instalar uma aplicação.show(). 26.onContextItemSelected(item). O Cliente é executado no seu desktop. . Copiar arquivos de/para um dispositivo ou instância de emulador. é necessário abrir um "prompt de comandos" (ou janela "Terminal".Página 42 de 84 24. Servidor: que roda como um "daemon" (um serviço) no seu desktop. ativado pelo comando "adb". 31. dentro da pasta onde o Android SDK está instalado. Porém. Como este é um curso básico. Com o ADB podemos fazer diversas tarefas. public void onClick(DialogInterface dialog. é melhor usar o utilitário "ADB" Antes de passarmos o laboratório. return. } 32. neste momento. pode pular esta parte. } Usamos um "AdapterContextMenuInfo" para obter a posição do elemento na lista. Agora. O ADB é uma aplicação distribuída. O ADB fica na subpasta "platform-tools". que retorna a posição do elemento dentro da lista (começando de zero). int which) { 25. se comunicando com o Servidor do seu desktop. return true. se estiver utilizando Linux). 28. ou a propriedade "position". que retorna o id do elemento na lista. seja em um dispositivo real ou em uma instância de emulador. . 29. de modo a permitir a comunicação entre o Cliente e o Dispositivo. embora possa utilizar o "ADB" para instalar em um emulador. 30. Para utilizá-lo. Tudo depende de como você quer localizar o elemento selecionado. é que você crie aplicações o mais rapidamente possível. default: return super. Página 43 de 84 Criação de certificado e assinatura de código A assinatura digital de uma aplicação protege seus usuários ao garantir que ela é autêntica e que não foi adulterada. e você pode contatálas para obter informações sobre certificados de Code Signing para aplicações Java. Tome cuidado com o campo "Validity (years)".255. então é só informar o caminho e digitar a senha. Para assinar.ufpe. O ADT ajuda você a gerar um certificado auto assinado. clique com o botão direito. Porém.00 (*) (*) A validade e os preços podem variar. Você tem duas opções: adquirir um certificado emitido por uma Autoridade Certificadora reconhecida. a CertSolutions e a Certisign. Se você não fizer isto. Se o seu produto for remunerado. Existem várias empresas no Brasil. então pode comprar um Certificado e diluir o custo na formação do seu preço. E para desenvolvimento e teste esta é a melhor opção. logo. mas apenas para você mesmo. Pronto! Seu APK está gerado e assinado. você pode procurar boas empresas. A tendência do projeto Android é acabar com o uso de aplicações sem assinatura digital. Para adquirir um certificado de assinatura de código.di. como a Comodo. deve criar uma. pois o Android Market exige que o certificado expire depois de 22 de Outubro de 2033. Certificado auto-assinado Você pode emitir um certificado e assinar seu código com ele. A compra e instalação de um certificado de Assinatura de Código é um processo complexo. Antes de instalar é necessário assinar digitalmente o seu APK. Preencha os dados da tela e guarde muito bem a senha escolhida. Agora. Porém. A janela "Export Android Application" vai aparecer e você deverá selecionar seu projeto e clicar "next".00 (*) Thawte: Validade 12 meses: US$ 299. vamos publicar um artigo explicando este processo. . quem garante aos outros que você é quem diz ser? Quem garante que o Certificado realmente pertence a você? É por isso que recomendamos a aquisição e uso de um certificado de Assinatura de Código emitido por uma empresa reconhecida. Se você já possui uma "keystore" (um arquivo que armazena certificados) e sabe a senha. é preciso um certificado digital de Code Signing ou Assinatura de Código (para saber mais: http://www. selecione "Android tools" e "Export signed application package" (exportar pacote de aplicação assinado). ou criar um certificado auto-assinado. se ainda não tem uma "keystore". quando tivermos "grana" para ter um destes.20 (*) Verisign: Validade 12 meses: US$ 499. Estas cotações estavam disponíveis on-line (nas páginas das empresas) e foram obtidas em Junho de 2011. No menu de contexto. recomendamos que você sempre assine. Gerando um pacote APK assinado Selecione o seu projeto na janela "Package Explorer" (ou "Project Explorer").htm). da sua workspace "eclipse".br/~flash/ais98/cripto/criptografia. não poderá instalar via ADB. Nós mesmos não tivemos condições de comprar um certificado desses até agora! Estamos usando certificado auto-assinado em nossas aplicações. embora seja possível executar copiando o APK diretamente para seu dispositivo. Isto garante que o seu código não foi violado. como estas abaixo:    Serasa: Validade 12 meses: R$ 1. os custos são altos. Futuramente. MODE_PRIVATE).txt".openFileOutput("dados. propriedades e SD Card para outro curso. Context. se esse argumento ainda não te convenceu. se for Linux). 4. usamos os métodos: "openFileOutput" e "openFileInput". 3. this. OutputStreamWriter owr = new OutputStreamWriter(fos). digite ". então baixe a solução (http://code. Arquivos internos Para lidar com arquivos internos. E a gravação de arquivos e a mesma sendo em armazenamento interno ou removível. Lição 11: Persistencia e retorno de activities Persistência Podemos ler e gravar dados de várias formas:    Propriedades Bancos de Dados SQLite Arquivos de dados Neste curso.com/p/curso-basico-thecodebakers/downloads/list). propriedades compartilhadas. Há várias maneiras de ler e gravar dados em um dispositivo Android. Abra a pasta onde o Android SDK está instalado e a subpasta "platform-tools". Podemos gravar propriedades particulares da aplicação./" antes do "adb". Agora é só executar diretamente a aplicação do seu dispositivo. simples e atende a 90% das necessidades. Bancos de Dados SQLite.google. da classe Activity. Digite o comando: adb install -r <path-do-APK-assinado> Se você estiver utilizando Linux. arquivos dentro do dispositivo e arquivos dentro do SD Card. Por que? Porque ele é fácil. não é? Tem que tentar! Como vai criar o próximo "Angry birds" se não se esforçar para fazer os laboratórios? Bem. Neste curso. Laboratório 7 Context menu Crie um context menu no projeto do lab 6. veremos como gravar arquivos dentro da memória interna do dispositivo. Deixaremos bancos de dados SQLite. É claro que você vai ter que criar uma Activity de Ajuda também! Você já sabe o que vamos dizer. conecte o dispositivo na USB (veja o artigo: Desenvolvendo diretamente no dispositivo Android para saber detalhes da configuração USB). na memória do aparelho. Vamos ver como criar ou gravar arquivos: 1. vamos apenas gravar arquivos internos.Página 44 de 84 Instalando no dispositivo via ADB Recomendamos fechar o "eclipse" e todas as instâncias de emulador que estiverem ativas (a não ser que você queira realmente instalar no emulador!) Depois. Abra uma janela "Prompt de comandos" (ou "Terminal". As opções serão: Mostrar Item e Ajuda. . FileOutputStream fos = 2. 3. } SQLite SQLite é um "engine" de banco de dados "embutido". para ser utilizado DENTRO de outras aplicações. mas como receber o resultado de outra Activity? Por exemplo. 7. bw. bw.sqlite. Ele não possui servidor e é apenas uma biblioteca de funções de banco de dados. ao construirmos aplicações desta forma. porém.readLine().Página 45 de 84 5. O método "openFileOutput" pode criar arquivos dentro do diretório interno da aplicação. Nós não vamos abordar SQLite neste curso (embora tenhamos a intenção de criar um curso separado). O Android já inclui a biblioteca do SQLite e possui alguns pacotes para facilitar seu uso.println("BOM DIA"). Context. 2. owr. break. Baixe o projeto Hércules Password Protector. 11.close(). 4. ou seja. adicionando o repositório: http://code.MODE__WORLD_READABLE Vpermite que outras aplocações leiam o arquivo. prendemos recursos desnecessariamente./files: /data/data/br. Um arquivo será criado dentro de /data/data/.lab08/files. Além disto. 7. O parâmetro "mode" é uma constante que significa: Context. o que aumenta o consumo de bateria em dispositivos móveis. . android. Para leitura. Sabemos que podemos passar "extras" dentro de um "Intent".openFileInput("dados. Criamos um exemplo para demonstrar isto. texto.flush(). 6. Pois. InputStreamReader ir = new InputStreamReader(fin).txt"). } 10. E vai torná-lo privado da sua aplicação. BufferedReader br = new BufferedReader(ir). while (true) { 6.com/p/hercules-password-protector. 9. 8. abrimos uma Activity para que o usuário selecione o contato desejado etc. Context. 9. Context. if (lido == null) { 8.*. que retorna uma instância de "FileInputStream" com o arquivo que desejamos ler: 1. com SQL e mecanismo de controle de transações.database. fos. String lido = br.google.append(lido). 5. é totalmente domínio público. StringBuffer texto = new StringBuffer().close(). FileInputStream fin = this. Invocando activities e recebendo retorno No Android nada é síncrono ou modal. 10. usamos o método "openFileInput()".MODE_PRIVATE Vai criar um arquivo ou sobrescrever.close().com.thecodebakers.MODE_WORLD_WRITEABLE Vpermite que outras aplicações gravem no arquivo.MODE_APPEND Vvai adicionar dados a um arquivo existente. PrintWriter bw = new PrintWriter(owr). se quiser ver um exemplo em ação. bw. Se não existir.show(). 4. CODIGO_SUBATIVIDADE). }) 14.titulo) 10.getExtras(). . } O método "startActivityForResult()" invoca um callback especial quando a sub-atividade é finalizada: "onActivityResult()". int resultCode. } A sub-activity pode exibir uma lista de seleção ou mesmo fazer qualquer outra coisa.OnClickListener() { 11.id. protected void onActivityResult(int requestCode. 4. if (requestCode == CODIGO_SUBATIVIDADE) { 5.setNeutralButton("OK". 6. Intent i = new Intent(this. public void onClick(DialogInterface dialog. . .zip&can=2&q=).class).setTitle(R. data).findViewById(R. 3. Laboratório 8 Arquivos Crie uma aplicação que leia e grave um arquivo texto. @Override 2. Intent data) { 3. Através do "Intent". public void chamar(View view) { 2.txt1). retorno). 4. Eis uma proposta de Activity: . } 16. public void fechar (View view) { 2.Builder(this) 8. podemos identificar qual é a Activity que está sendo invocada e podemos até mesmo passar parâmetros.string. startActivityForResult(i. mostre uma mensagem na EditText. a Activity principal vai ser acionada e vai receber um "Intent" com dados. Eis o nosso exemplo: 1. . super.getText(). Baixe o exemplo "sub. new AlertDialog. 6. procure por um arquivo interno.getApplicationContext(). Veja o código da Activity principal que invoca a sub-activity: 1. 5. 15. txt. A principal invoca a sub e aguarda um resultado.com/p/curso-basicothecodebakers/downloads/detail?name=sub.onActivityResult(requestCode.toString()).Outra. finish().google. Se ele existir. Intent retorno = new Intent(). No momento em que a activity for iniciada. 7. Note que passamos um "Intent" e um literal inteiro. retorno. new DialogInterface. Ao concluir.Página 46 de 84 Este processo envolve duas Activities: uma será a principal e a outra será a sub-activity. txt = (EditText) this. 3. ela terá que ser finalizada (invocando o método "finish()").getString("valor").putExtra("valor". Bundle extras = data. resultCode. int which) { 12. 7. } 13. carregue uma EditText com seu conteúdo. O usuário poderá digitar alguma coisa e clicar em um botão para salvar no arquivo. String texto = extras. } Desta forma.setMessage(texto) 9. O literal "int" é um código para nos informar qual foi a Activity que invocou "onActivityResult()": 1.zip" (http://code. setResult(RESULT_OK. Página 47 de 84 Esse é o último laboratório. O projeto final não terá solução publicada, logo, é sua última chance! Caso ainda não esteja convencido, então baixe a solução (http://code.google.com/p/curso-basicothecodebakers/downloads/list). Projeto final Vamos criar uma lista de compras! Normalmente, quando vamos ao mercado, precisamos criar uma lista de compras, que você possa utilizar no Supermercado. Deve haver uma lista de produtos mais comuns, os quais o usuário pode selecionar para comprar. Ao comprar, o produto deve ser marcado na lista, para evitar confusão. Você pode criar um arquivo com a lista de itens a serem comprados e marcar se já comprou. Crie um arquivo interno para a lista e você poderá editar este arquivo. Lembre-se de criar imagens, ícones, fundo etc. A beleza e usabilidade é que serão os principais atrativos do seu software. Para este projeto não haverá "cola"! Você deverá implementar sozinho(a), de modo a testar seus conhecimentos. Depois, se ficar "irado", faça upload para o Android Market! Tá na hora de transformar o tempo investido no curso em grana! Curso de SQLite no Android O foco desse curso é o uso do SQLite no Android, mas para um melhor entendimento do produto, pretendemos mostrar o seu funcionamento independente do ambiente Android. Nas próximas lições nos concentraremos no nosso objetivo, que é o seu uso no desenvolvimento de apps Android. Iniciamos o curso de SQLite fazendo a seguinte pergunta, por que devo aprender o SQLite? Bem, essa pergunta é fácil de responder, o Android já vem com o suporte nativo ao banco de dados SQLite. Claro que não é só por causa disso, mas que é um grande motivo é rsrsrs... Página 48 de 84 Mas vamos ao que interessa, afinal, como funciona o SQLite? SQLite é uma biblioteca desenvolvida em linguagem C que implementa um bando de dados SQL embutido. Programas que usam a biblioteca SQLite podem ter acesso a banco de dados SQL sem executar um processo RDBMS separado. Quais as suas principais características?   Transações atômicas, consistentes, isoladas e duráveis, ou seja, segue o conceito de ACID; Configuração zero, não é necessário nenhuma configuração para usar o banco, tampouco administrá-lo; Implementa o padrão SQL92; Um banco de dados completo é armazenado em um único arquivo (.db) que é multiplataforma; Suporte a base de dados com terabytes de dados armazenados; Código pequeno e compacto, menor que 325KB se for configurado com todos os recursos ou 190Kb, se usar apenas algumas configurações opcionais; API simples de usar; Sem dependências externas para outras bibliotecas;       Tipos de dados Quando falamos de banco de dados pensamos logo nos tipos de dados. O SQLite trabalha com tipagem dinâmica de dados, sim dinâmica. O conteúdo pode ser armazenado como:      INTEGER – valores inteiros até 8 bytes REAL – valores de ponto flutuante TEXT – armazena strings (UTF-8, UTF-16BE e UTF-16LE) BLOB – armazena dados binários NULL – É um valor nulo Analisando os tipos de dados acima, você não sentiu falta de nada, cadê o tipo booleano, e o tipo Date/Time? Bem, o SQLite armazena o tipo booleano como: 0 para falso, e 1 para verdadeiro. Já o tipo Date/Time pode ser armazenado como: TEXT, REAL ou INTEGER. Onde podemos usar o SQLite, em que tipo de aplicação?     Dispositivos e sistemas embarcados; Aplicações client/server; Sites de pequeno e médio porte; Aprendizado de banco de dados; Quem usa o SQLite?   Adobe; Apple, adivinha em quais produtos : iPhone, iPod Touch e iPad; Página 49 de 84      Dropbox; Firefox; Google, podemos destacar os principais produtos: o Chrome e o Android; Microsoft; Skype; No site do SQLite tem uma vasta lista de grandes empresas que utilizam o SQLite em seus produtos. Exercicio 1 – Instalando o SQLite Como o foco desse curso é o SQLite no Android, a seguir vamos apenas mostrar como instalar o SQLite no Linux/Windows para fins de testes e estudo. No Linux, você pode baixar via APT-GET da seguinte maneira: # apt-get update # apt-get install sqlite ou pode baixar o arquivo a última versão do arquivo “Precompiled Binaries for Linux” do site oficial do SQLite. Escolhemos esse tipo de instalação por ser mais simples. No Windows, favor baixar o arquivo sqlite-shell-win32-x86-3070701.zip (versão atual) e executar sqlite.exe após descompactar o arquivo zip. Se você não gosta de executar comandos via shell, não se desespere, existem vários aplicativos cliente para o SQLite. Eu sugiro a ferramenta SQLiteStudio por ser Open Source (GPL v2) e multiplataforma. Instando o SQLiteStudio no Linux Para executar a ferramenta no Linux, após o download do arquivo sqlitestudio-<VERSION>.bin só é necessário dar permissão de execução, conforme a seguir: chmod +x sqlitestudio-<VERSION>.bin Para permitir a execução sem a necessidade de colocar o caminho completo do arquivo, renomeie o arquivo para “sqlitestudio” e inclua no PATH do seu Linux. No Windows, baixe o aplicativo sqlitestudio-<VERSION>.exe. Não esqueça de colocar no PATH para possibilitar a chamada de qualquer lugar (diretório). Parabéns!!! Você acabou de instalar o SQLite na sua máquina. Se você reparou o processo de instalação e configuração do SQLite é muito simples e rápido. Para criar o seu banco de teste com o shell, execute o seguinte comando: ./sqlite3 curso Obs.: um arquivo .db será gerado no mesmo path do shell. Para criar uma tabela entre com o comando create table no shell, conforme exemplo abaixo: sqlite>CREATE TABLE aluno (nome VARCHAR(100), email VARCHAR(100)); Para verificar se a tabela foi criada, execute o seguinte comando: sqlite> .tables Nas próximas lições, abordaremos o SQLite no Android com exemplos e exercícios. Página 50 de 84 Lição 2: Conhecendo a API SQLite para Android Como já dito na lição 1, o Android já tem suporte nativo ao banco de dados SQLite. Nesta lição pretendemos detalhar a API com exemplos práticos e didáticos. Na primeira lição, criamos o banco de dados via shell ou usando a ferramenta SqliteStudio, o caminho poderia ser especificado no momento da criação do database. No ambiente Android, o banco fica armazenado num path especifico, conforme o nome do pacote da sua aplicação, conforme a seguinte estrutura de diretórios: /data/data/pacote.sua.app.android/databases. Isso significa que o banco de dados é visível apenas para a sua aplicação. Existe uma forma de acessar os bancos criados por outras aplicações, através da API Content Providers, ela permite o compartilhamento dos dados de outras aplicações. Não abordaremos o acesso via ContentProviders nesse curso. Mas como eu crio o banco de dados no meu device, Tio? Muita calma nessa hora jovem mancebo! Na primeira lição, aprendemos como criar o banco de dados SQLite de formal manual (shell ou outra ferramenta), já imaginou toda vez que você criar um banco de dados para a sua app Android ter que copiar o arquivo .db manualmente para a estrutura de diretórios citada acima. Imagina atualizar o banco em milhares de dispositivos, tarefa árdua né. Vimos então que podemos criar o banco de dados no Android de duas maneiras: manualmente, copiando o .db gerado para o diretório data/data/pacote.sua.app.android/databases, ou via programação. Nessa lição pretendemos abordar a criação de banco via programação, através das classes disponibilizadas na API do Android. Criando o banco de dados via programação Para criar o banco via programação é necessário o entendimento da API do Android, que disponiliza um conjunto de classes para acessar o SQLite. Inicialmente devemos criar uma classe que estenda a classe SQLiteOpenHelper, essa classe é responsável por gerenciar a criação e atualização do banco de dados no Android. Abaixo vamos demonstrar um exemplo prático baseado na aplicação HPP (Hercules Password Protector), onde criamos uma classe chamada DBHelper, que estende a classe SQLiteOpenHelper, consequentemente herda os seus métodos: onCreate (cria o banco no momento de sua instalação) e onUpgrade (atualiza o banco). Segue a implementação completa da classe citada acima: 1. public 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. ; 14. 15. 16. 17. 18. 19. 20. 21. 22. class DBHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "hppfree.db"; public static final int DATABASE_VERSION = 1; private static final String TABLE_NAME = "elemento"; public DBHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + TABLE_NAME + "(uid TEXT, textoSecreto BLOB)") } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if ((newVersion - oldVersion) > 2) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); } } 9. 6. agora você precisa entender como usar esse banco nas suas classes DAO .getReadableDatabase() : cria ou abre um banco para leitura.close().db = dbHelper. ContentValues cv = new ContentValues(). como também a classe DBHelper. 14. 17. repare que no construtor do DAO criamos uma instancia do DBHelper e passamos como parâmetro para a classe Helper (SQLiteOpenHelper) o contexto da aplicação: 1.Página 51 de 84 23.put("textoSecreto". cv). uuid). db. é necessário entender que existem dois métodos da classe SQLiteOpenHelper. e uma instancia da classe SQLiteDatabase. são eles: . 15. 7. public DBAdapter(Context context) { 7.getWritableDatabase(). public long insert(String uuid. 10. dbHelper = new DBHelper(context). public DBAdapter(Context context) { 2. public long insert(String uuid. leitura ou gravação.close(). uuid). lob). 6. byte[] lob) throws SQLException{ 11. cv. alterar. 13. cv. 12. e executar outros comandos SQL. } 9.db = dbHelper. 8. 5. … Ainda falando do trecho de código acima. Primeiramente. 1. você deve criar uma instancia da classe DBHelper (criada anteriormente). 4. db.put("uid". . 16.getWritableDatabase(). } 19. } Bem. dbHelper = new DBHelper(context). na sua classe que fará papel de DAO. } Acredito que vendo uma implementação pronta muitas dúvidas iniciais serão sanadas rapidamente. 5. public class DBAdapter implements IDBAdapter { 2. lob).put("uid". private DBHelper dbHelper= null. 3. long retorno = db. long retorno = db. Mas como ficou o acesso e o insert dos dados? Para manipulação dos dados. já mostramos a classe que vai gerenciar o banco. 3.put("textoSecreto". ContentValues cv = new ContentValues(). ou algo parecido. return retorno. 1. 3. byte[] lob) throws SQLException{ 2. } . return retorno. cv. 4. private SQLiteDatabase db = null. cv.getWritableDatabase(): cria ou abre um banco para leitura e gravação Como vamos gravar uma informação na base dados. utilizamos o método getWritableDatabase. cv). 24. Ela possui métodos para incluir. 8. Repare no exemplo retirado do aplicativo HPP. this. null. 18. Essa classe disponibiliza métodos para gerenciar um banco de dados SQLite. criamos a classe DAO e nessa classe instanciamos a classe SQLiteDatabase. this.insert("elemento". null.insert("elemento". Nesta lição vamos fazer um exercício para fixar o conteúdo dado até o momento. conforme abaixo: . cursor. elemento. A diferença do método update para o insert é que ele recebe como parâmetro uma string contendo o campo que representa a cláusula Where. array com os nomes das colunas. 3.moveToNext(). null. 11. e insere na base de dados. cv. } 13. null. que representa um conjunto de valores dos comandos SQL. Todas as consultas retornam um tipo de objeto chamado Cursor. new String[]{ uid }). e mostrará o resultado de uma busca na tela. null. Lição 3 .Página 52 de 84 Repare que nesse caso é necessário usar a classe ContentValues. 9.Criando um CRUD no SQLite Nas duas primeiras lições explicamos como funciona o SQLite é como funciona a API do Android. No exercício criaremos uma “app” que fará o cadastro de um curso.. Para agilizar um pouco o processo de criação de aplicação. null. 8.null.getString(0)). 10. Cursor cursor = db. while(!cursor. e os argumentos representados pelo sinal “?”.query("elemento".. 2.getBlob(1)).add(elemento). Onde os parâmetros da query são: nome da tabela.query("elemento". argumentos do where e as cláusulas groupby.setUUID(cursor.. null.null. conforme a seguir: 1.isAfterLast()){ 6. . 5.insert. having e order by.. vamos utilizar como fonte de consulta o código do projeto HPP (Hercules Password Protector) disponível no Google Code. Para facilitar o entendimento do exercício criamos uma tela com dois campos: nome e descrição do curso. e depois botões: salvar e pesquisar. O método para listar os dados ficou assim: 1.moveToFirst(). "uid = ?". null). Cursor cursor = db. null. lista. 7. conforme o seguinte exemplo: 1. 12. columns. . db. columns. Outro ponto importante do método insert é chamada db. cursor.update("elemento".setLob(cursor. 4. null). que recebe o nome da tabela e o ContentValues como parâmetro. elemento. Elemento elemento = new Elemento(). cláusula Where. Nas próximas lições iniciaremos um exercício prático com o SQLite. 17. descricao = (EditText) findViewById(R. 7.txtNome).txtDescricao). }else{ 31.id. descricao = (EditText) findViewById(R.getText(). 36. 20.txtNome).Página 53 de 84 Em seguida.id.getText().id.id. 22. 30.txtDescricao).setNome(nome. 15. nome = (EditText) findViewById(R. } 33. 8. @Override 11. public void onCreate(Bundle savedInstanceState) { 12. 34. 26.onCreate(savedInstanceState). //verfica se ja existe o valor 27. elemento. 10.main). 25. 23. private Elemento elemento. cursoAdappter = new CursoAdapter(this). } 16. criaremos a Activity para suportar os métodos da tela acima: 1. Elemento el = buscarPorNome(). 6. setContentView(R.alterar(elemento). 39. private String id. if (elemento == null) 28. cursoAdappter. public class CursoSQLite extends Activity { 2. } 35. 32. 19. nome = (EditText) findViewById(R.layout. private EditText nome. 24. 5. 4. public void pesquisar (View view) { 37. elemento = buscarPorNome(). 38.setDescricao(descricao.toString()). 14. cursoAdappter.toString()). private ICursoAdapter cursoAdappter . 3. elemento. 13.incluir(elemento). 9. . public void salvar(View view) { 18. super. { 29. private EditText descricao. 21. super(context. 7. a versão na DATABASE_VERSION e o nome da tabela em TABLE_NAME. Agora vamos criar a classe de acesso aos dados (famoso DAO) e as variáveis para acesso às classes CursoHelper e SQLiteDatabase. 50. 21. 44. 16. chamada DBHelper. 41. } nome. descricao.buscarPorNome(nome. 19. @Override 12. 23.getText(). 42. descricao TEXT)"). 51.oldVersion) > 2) { db. 18. 6. 24. this.toString()). public class CursoAdapter { 2. onCreate(db). } } @Override public void onUpgrade(SQLiteDatabase db. 46. int oldVersion. db. public void onCreate(SQLiteDatabase db) { 13. 14.id = el. public static final int DATABASE_VERSION = 1. null. } 10. 5. Lembre-se que essa classe é responsável pela criação(método onCreate) e atualização(método onUpgrade) do banco. 9. DATABASE_VERSION). 48. private CursoDBHelper cursoDBHelper= null. conforme a seguir: 1. public CursoDBHelper(Context context) { 8. ela estende a classe SQLiteOpenHelper. Segue a classe criada para o projeto curso SQLite: 1.setText(el.db". private SQLiteDatabase db = null. public class CursoDBHelper extends SQLiteOpenHelper { 2. return elemento.getId(). 17. Agora vamos para a parte que importa. 15. que é desenvolver um Adapter para acessar o banco de dados e executar as operações de CRUD. } } Repare que o nome do banco foi definido na variável DATABASE_NAME (curso.getNome()). Você pode copiar a classe desenvolvida para o projeto HPP. } Os passos citados acima foram abordados com mais detalhes no nosso curso de programação ANDROID . } public Elemento buscarPorNome() { elemento = cursoAdappter.toString(). 43.setText(el. 45. 3. 3. 22.getDescricao()). private static final String TABLE_NAME = "elemento". 11. DATABASE_NAME. 4. 49.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME).execSQL("CREATE TABLE " + TABLE_NAME + "(nome TEXT. private static final String DATABASE_NAME = "curso. . Conforme dito nas lições anteriores! Precisamos criar uma classe Helper que herda de SQLiteOpenHelper. 20. 47.Página 54 de 84 40.db) . int newVersion) { if ((newVersion . 18. elemento. 3."). 19. "id = ?". public int excluir(String id)throws SQLException{ 28. 6. esse objeto é responsável pelo acesso ao resultado da consulta. que deve ser repassado para a classe CursoDBHelper. } 12. elemento. são eles:        String nome tabela String[] colunas tabela String clausula where String[] parametros Where String clausula groupBy String clasusula having String orderBy (na consulta acima estamos ordenando o resultado pelo nome do curso). 13. cv. Log. 7. Em seguida.db = cursoDBHelper. 23. this. elemento. elemento.insert("elemento". 5.getId()). } 25.getNome()). columns. } Na lição 2 já explicamos o que significa o ContentValues e o método getWritableDatabase.put("descricao". cv. 10. cv.getDescricao()). 1. null.close(). } Note que no construtor da classe CursoAdapter recebe como parâmetro o Context. a consulta retorna um objeto chamado Cursor. cv.. exclusão: 1. db. public long incluir(Elemento elemento) throws SQLException{ 2.getWritableDatabase().db = cursoDBHelper."). vamos criar os métodos para inclusão. return retorno. "Registro atualizado com sucesso. 21. 8. alteração.Página 55 de 84 4. int retorno = db. 16.update("elemento". 22.toString() }). args. cv). ContentValues cv = new ContentValues(). 11. 29. elemento. 6. Segue a listagem completa da consulta pelo nome do curso: ."nome = ?". 9. "Esse voce deve implementar..getWritableDatabase().i(TAG. ContentValues cv = new ContentValues(). Cursor c = db. this.getNome()). "nome").i(TAG. 5.put("descricao". "Registro criado com sucesso.ge tId(). 17. 4. Log.query("elemento". null. db. public int alterar (Elemento elemento) throws SQLException{ 14. 27. } public CursoAdapter(Context context) { dbHelper = new CursoDBHelper(context). 7. return retorno.i(TAG.getDescricao()).put("nome". 20. cv. Repare que o método query recebe algumas informações como parâmetros. 24. 26. null. 15.put("id". Log. Ao executar o método query de SQLiteDatabase.put("nome".close(). long retorno = db. cv. new String[]{ elemento."). 6.Página 56 de 84 1. Vá para o diretório onde está instalado o seu SDK do Android. Se você quiser pode baixar pelo QR Code: O exercício dessa lição é criar o botão excluir com o código necessário para excluir o registro da base de dados. 7. curso = new Elemento(). curso. "nome". 4. null.setNome(c."nome = ?". c. curso. String[] columns = new String[]{"id". via linha de comando no emulador. siga os seguintes passos: Antes de qualquer coisa. e até gerenciar os bancos de dados das aplicações). curso. Para trabalhar com o SQLite no ADB. ative a "Depuração via USB". Gerenciando o SQLite através do ADB (Android Debug Bridge) Mas o que diabos é o ADB? É uma ferramenta muita importante para quem quer trabalhar com desenvolvimento Android. Abra uma janela de terminal(Linux) ou cmd (no caso do Windows).getString(1)). 13. 11. Elemento curso. montar o cartão de memória.getLong(0)). Agora é só executar o ADB. "nome" ). Cursor c = db. null.setDescricao(c. 9. args. "descricao"}./adb shell Iniciei mas recebi um erro no terminal: . que vem junto com o SDK Android. Com a ferramenta ADB você consegue executar diversas operações (instalar apps. String[] args = new String[]{id}. 10. 3.moveToFirst().setId((int)c.getString(2)). public Elemento buscarPorNome(String id){ 2.query("elemento". conforme abaixo: . 5. no seu dispositivo. 12. columns. 8. } O código fonte desse projeto foi disponibilizado para download no google code. return curso. exemplo: cd /caminho_diretorio_do_sdk/platform-tools/ Altere o path caminho_diretorio_do_sdk para o caminho do SDK do Android da sua máquina. /android create avd -n curso_sqlite2.1-update1. vai por mim. conforme a seguir: Android 2.1-update1 is a basic Android platform. no meu caso. eu escolhi a versão 2. with the following hardware config: hw. então leia o seguinte artigo e aprenda como fazer ./adb shell * daemon not running./adb shell Lembre-se que o ADB fica no diretório PATH_SEU_ANDROID_SDK/platform-tools. e execute o seguinte comando: . Entra numa janela de terminal. ele vai abrir um pouco mais a sua mente. starting it now on port 5037 * * daemon started successfully * error: device not found Isso é normal!!! Você tem um dispositivo acoplado na USB da sua máquina ou emulador está executando nesse momento? Senão.density=240 vm. Para listar as targets execute o seguinte comando: android list targets Agora vamos acessar o seu banco de dados através do ADB: . Mas tio eu não sei criar um emulador. Do you wish to create a custom hardware profile [no] Created AVD 'curso_sqlite2. vá para o diretório caminho_diretorio_do_sdk/tools e execute seguinte comando shell: .lcd. então faz na mão vai.heapSize=24 Para saber qual target usar.1 -t 2 Após executar o comando acima o seu AVD foi criado.1 do Android. você pode listar todas as targets instaladas na sua máquina e escolher uma opção. execute o emulador e rode o comando novamente.Página 57 de 84 > ~/android-sdk-linux_x86/platform-tools$ .1' based on Android 2. Ainda não conseguiu criar uma instancia do emulador (AVD) no Eclipse. Sugerimos também a leitura do artigo “Desenvolvendo diretamente no seu aparelho”. Gostou do curso de SQLite. acesse o SQLite especificando o pacote do banco do curso: # sqlite3 /data/data/br.thecodebakers. cursos e projetos.Página 58 de 84 . é possível especificar o caminho do banco de dados que se deseja explorar.cursosqlite/databases/curso SQLite version 3. Para inserir um registro na tabela criada: sqlite> INSERT INTO curso (nome. .com.tables Lista todas as tabelas do seu banco sqlite>.5. você já fez todo o laboratório baseado no ADB. nome TEXT NOT NULL. A ideia desse minicurso foi mostrar rapidamente como foi funciona o SQLite no Android. Segue alguns comandos que podem te ajuda no dia a dia: sqlite> .help" for instructions sqlite> Você acabou de acessar o banco SQLite via ADB! Agora é possível criar suas tabelas e executar suas operações de CRUD no seu banco de dados.schema Lista o esquema do seu banco. digite o comando sqlite3./adb -s emulator-5554 shell Para maiores informações acessar a documentação do ADB x SQLite Uma vez conectado ao emulador. Após se conectar no emulador. Se você seguiu toda a lição. Ao invocar esse comando. usando o comando a seguir: sqlite>. mas ao ambiente de desenvolvimento Android Espero que esse curso agregue valor para o seu conhecimento e sua evolução profissional. então clique no botão abaixo e ajude a The Code Bakers a continuar a publicar artigos.schema curso Seguem abaixo alguns exemplos comandos SQL: Para criar uma tabela: sqlite> CREATE TABLE curso (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT.data DATE). não se prendendo aos detalhes do banco. '2011-08-22'). ou você pode listar apenas o esquema de uma tabela. data) VALUES ('curso sqlite no android'.9 Enter ". e pode ser utilizado para criar apps pagas ou gratuitas. WebOS (HP – Palm).com/about/license). e recebe um pacote prontinho para rodar! Você pode continuar a fazer o curso. mas procure manter o módulo “www” bem separado. infelizmente. 2. Agora.phonegap. com pelo menos uma página chamada “index. já dá para desenvolver uma app. iPad. Crie um projeto. Você teria problemas para distribuí-la nas lojas especializadas (iTunes. Mas então. iPod). Android Market etc). Symbian. e CSS. e fornece um “meio-de-campo” para integrar sua app com as plataformas suportadas:      Android.html”. é necessário fazer alguns ajustes. infelizmente. Eu não sou programador! Preciso conhecer Java e Objective-C? Boa pergunta! Se você conhece HTML 5 e “arranha” em JavaScript. outras páginas. Como funciona o processo de criação? Simples: 1. Depois. CSS. pode usar o “Git” para criar e gerenciar seu projeto. pois você procurar separar seu projeto dos códigos específicos de cada plataforma. alguma coisa você vai ter que fazer. iOS (iPhone. JavaScript (com uma API de extensão). se concentrando mais na parte de API e técnicas de programação. como você faria sua aplicação usar a câmera? E o GPS? Você acabaria tendo que desenvolver uma camada nativa para cada tipo de aparelho. deixando todo o trabalho de integração à cargo do serviço. outras exigem menos. por que eu simplesmente não faço a página HTML sem usar o PhoneGap? Não seria mais simples? A resposta é sim. Use o mecanismo nativo (SDK) de cada plataforma. Compile e distribua! O passo 1 é muito importante. vamos iniciar pela plataforma Android. imagens etc. dependendo da plataforma. BlackBerry. não seria uma aplicação móvel. Para os que quiserem outras plataformas. Seu projeto pode conter JavaScript (interno ou externo à página). . Copie a pasta “www” para o local correto (depende da plataforma). Ele utiliza HTML 5. Algumas plataformas exigem maior trabalho de integração. Infelizmente. mostraremos tutoriais separados. Ele deve ficar dentro de uma pasta “www”. cada uma tem suas características. você não teria acesso à API PhoneGap. Por exemplo. você só se preocupa com o HTML 5 e JavaScript. Você pode até escolher uma delas para usar seu ambiente. vamos mostrar a parte específica sobre iOS. Ele é distribuído nos termos da licença MIT (http://www. e crie um projeto. que permite fazer interface com os dispositivos. e adivinha só: é exatamente o que o PhoneGap faz! Neste curso. Se quiser. porém. mas. Outra coisa que pode fazer é usar o PhoneGap Build! Assim. 3.Página 59 de 84 PhoneGap Lição 1: Praparando o terreno PhoneGap é um framework open source para facilitar a criação de aplicações móveis. Além disto. Logo. Para baixar e instalar o “eclipse”. vamos mostrar como instalar a plataforma (Android) e começar a criar uma aplicação.googlecode. logo.9. não sei se você poderá colocar sua aplicação no iTunes! Estude HTML 5. Finalmente. que tem muitos recursos que o Flash tinha. Nós vamos nos referenciar a ela como $PHONEGAP_HOME mais tarde. vai poder fazer tudo o que faria com Flash. Eu já tenho um jogo legal em flash! Será que posso usar o PhoneGap para colocá-lo no iTunes e ganhar uma grana? Bem.zip. que pode ser obtido diretamente na página do PhoneGap. Normalmente. ou então clicando nesse link diretamente: http://phonegap. É só baixar e descompactar este arquivo ZIP. que apenas executa aplicações Java.9. Existe o Java Runtime Environment. Aplicações Android são desenvolvidas usando a linguagem Java. Como dissemos anteriormente. para rodar em plataforma Android. logo. Ele é multiplataforma. que contém uma página “index. Então você deve ter o ambiente pronto para desenvolvimento. você teve ter o Java Software Development Kit (Java SDK) instalado em sua máquina. .6”.com/files/ProjectExcuse. Bem. vamos criar logo nosso primeiro projeto PhoneGap. é melhor ter algo pronto. e prepare-a para receber um projeto. lembro que temos um curso específico sobre Android. recomendamos que leia o tutorial: “Como criar uma app em 5 minutos com o PhoneGap Build”.com/files/phonegap-0. da Oracle. você desenvolveria o seu próprio aplicativo. Se você quiser conhecer mais profundamente esta plataforma. Crie um novo projeto “Android”. vamos começar pela plataforma Android. Descompacte em um local do seu HD (pode extrair apenas a última pasta) e guarde esta localização. pode deixar o nome padrão da pasta. Lembrando que nós já temos um tutorial sobre o assunto: http://www.html.thecodebakers. Primeiro passo: crie um projeto Android no eclipse. Se você usar bem a combinação HTML 5 + JavaScript + CSS. heim? Ué? Por que o espanto? Estamos falando de programa de computador! Pensou que fosse o quê? Nós já “amaciamos” e partimos o bifinho para você. só falta baixar o Kit do PhoneGap. temos boas e más notícias. e tem duas pastas: “__MACOSX” e “phonegap-0. leia a lição 2 do curso básico de Android: “Lição 2: Ambiente de desenvolvimento”.zip. para um primeiro contato. Se você só pretende usar o PhoneGap Build.org/2011/04/javasscript-noambiente-android. mas achamos que. o qual vamos utilizar para ensinar a baixar e instalar tudo. Agora. crie uma nova workspace (se é que já não fez isso quando instalou). mas você precisa do compilador.html”.Página 60 de 84 Arrumando a casa Nesta primeira lição. Temos uma aplicação ótima para servir de “Hello World”: http://gerador-de-desculpas-furadas. A má notícia é que a Apple não suporta Flash. porém.6. o plug-in para Android (“ADT”) e o Android SDK. Depois. Nós vamos usar esta última. Abra o “eclipse”. você vai precisar de uma “IDE” (Integrated Development Environment). e nós vamos usar o “eclipse”. A boa é que a comunidade PhoneGap está criando plugins para permitir o uso de Flash e tem algumas aplicações tentando fazer isso em Android. O primeiro programa a gente nunca esquece! Quem diria que você viraria um garoto (ou garota) de programa. você vai precisar do Kit de Desenvolvimento do PhoneGap. deve baixar e instalar o Java JDK.googlecode. Página 61 de 84 A lição 4.6) e copie os arquivos:   “phonegap. agora.x.x.js” (“x.cin. Pô. crie duas pastas dentro do projeto: “libs” e “assets/www” (uma pasta “www” dentro de uma pasta “assets”).x. temos que adicionar as bibliotecas do PhoneGap ao projeto. escolher “new” e “folder”. temos que fazer algumas alterações para poder “embutir” nossa aplicação PhoneGap dentro do projeto. Para começar.x. Para criar pastas em um projeto “eclipse” é só selecioná-lo com o botão direito. Você conseguiu criar um projeto? Ótimo! Então. respire fundo e murmure: “OOOHMMMMMM”! Faça isso por 10 minutos! É necessário porque você vai mexer no .x. explica como fazer isto: “Lição 4: Criando sua primeira aplicação Android”. dentro da pasta “assets” do seu projeto.x.x. sente-se em posição de lótus. “phonegap. Existem outras formas de se fazer isto.jar” (que está dentro de “libs”) e escolha: “Build path. No nosso caso é 0. Selecione o arquivo “phonegap. Veja este: http://www.x” é o número da versão.x.x/Android (o “x. abra a pasta $PHONEGAP_HOME/phonegap-x. Seu projeto deve ficar como a figura: Ficou assim? Ótimo! Agora.9. Segundo passo: adaptando seu projeto Android para receber o PhoneGap.x.htm.ufpe.x” é o número da versão) para a pasta “libs” do seu projeto.. do curso básico.jar” (“x. eu não conheço “eclipse”! Calma. repouse as mãos sobre as pernas. mas esta é a mais simples. Bem. Agora.x.x.x.x” é o número da versão) para a subpasta “www”.x.” e “Add to Build path”.br/~phmb/ip/MaterialDeEnsino/IntroducaoAoEclipse/IntroducaoAoEclipse. nós damos um jeito! Tem vários tutoriais na Internet.. endireite a coluna. 6. } 14.”.loadUrl("file:///android_asset/www/index.app. 13. 7. 12.loadUrl("file:///android_asset/www/index. ao criar o projeto. public void onCreate(Bundle savedInstanceState) { 11.” e a substitua por: “super. import android. Em nosso caso.html” e copie-o para dentro da subpasta “assets/www”. Veja a figura: Ao dar um duplo-clique sobre o arquivo Java. Não sabe o que é “activity”? Pô.html"). @Override 10. abre-se uma janela de edição do lado direito. logo abaixo dela.phonegap1. você deu um nome para a “activity” principal... */ 9.*.Activity. Seu aplicativo PhoneGap pode ser totalmente desenvolvido fora do projeto Android. 4. dentro da pasta “assets”.thecodebakers. public class Principal extends DroidGap { 8.phonegap1”.zip. 2. Ao criar o projeto.html").os. usamos o nome de domínio da empresa invertido. Dentro deste pacote está o arquivo-fonte em Java. digite uma nova linha contendo: “import com. import android. você criou um nome de pacote. import com.googlecode. que é a “activity” principal dele.phonegap. Depois. /** Called when the activity is first created. Localize a linha que diz: “import” e.Página 62 de 84 código-fonte Java do seu projeto! Ao criar o projeto. extraia o arquivo “index.). baixe a aplicação http://gerador-de-desculpasfuradas.thecodebakers.onCreate(savedInstanceState).. localize a linha que diz: “public class xxxxx extends Activity” (o “xxxx” não importa!) e mude a palavra em negrito para: “DroidGap”. Lembre-se que. com o texto do arquivo.. nós pedimos para você ler as lições 2 e 4 do curso básico. localize a linha que diz: “setContentView(. Você não leu tudo? Então volte e leia:   Lição 2: Ambiente de desenvolvimento Lição 4: Criando sua primeira aplicação Android Ela fica dentro da pasta “src” do projeto. copie todos os arquivos para dentro da subpasta “www”.Bundle. 3.*. package org. Finalmente. você criou também uma classe Java.” Seu código deve ficar como este: 1. Neste caso. super. 5. } Terceiro passo: copie seu aplicativo PhoneGap para dentro do projeto. . normalmente. mais o nome do projeto. que você criou na raiz do projeto.com/files/ProjectExcuse. super. Em nosso exemplo.phonegap. eu criei: “org. Contatos (Contacts) . Bússola (Compass) . vai demorar muito. Basta mantê-lo aberto! Você deve ver algo como isto: É o emulador com a sua aplicação PhoneGap executando! Agora é só mostrar para todo mundo! O que falta? Certamente. utilizando uma API padronizada. Distribuir no Android Market. Converter para iPhone.Capturar arquivos de mídia utilizando aplicações de captura. o estripador: por partes! Lição 2: Entendendo o funcionamento do PhoneGap Nesta lição. Conexão (Connection) . Eventos (Events) . entre elas:    Colocar para rodar no seu celular ou tablet. Captura (Capture) .Observar e capturar eventos nativos através do JavaScript. Dispositivo (Device) ...Capturar uma foto utilizando a câmera. faltam algumas coisas. ainda estamos utilizando o PhoneGap para Android. Câmera (Camera) . então já sabe o que é um AVD. Mas vamos fazer como Jack.Verificar o estado da Rede e do celular. O PhoneGap é um framework que permite a você desenvolver aplicações em HTML 5 + JavaScript. .Trabalhar com o arquivo de contatos do dispositivo. Eis o que o PhoneGap expõe para a camada JavaScript:         Acelerômetro (Accelerometer) . não? Então selecione seu projeto com o botão direito e escolha “Run as. um emulador. iPhone etc). por exemplo: gravador de áudio. a boa notícia é que você não precisa fechar o emulador para rodar novamente. Vamos aprender como utilizar a API PhoneGap.” e “Android Application” e aguarde alguns “porrilênios”. teremos uma parte sobre as características específicas do iOS (iPad. embora a maioria dos conceitos seja para ambiente multi-plataforma. Dependendo da sua máquina.Usar o sensor de movimento do dispositivo.Obter informações específicas do dispositivo. com acesso aos recursos dos dispositivos móveis.Página 63 de 84 Quarto passo: rode e mostre para a Mamãe! Se você leu tudo direitinho. Em breve.Obter a direção para onde o dispositivo está apontando. <title>Integrando com a API PhoneGap</title> 4. pode baixar plug-ins prontos para suas necessidades. audíveis e tácteis (vibração) do dispositivo. <script type="text/javascript" charset="utf-8" src="phonegap.Lidar com as opções de armazenamento nativas. <div id="saida"> 9. o repositório de plug-ins do PhoneGap tem muita coisa. <h3>Informações</h3> 8. como fazer? É nesse momento que entra a arquitetura de plug-ins do PhoneGap. </body> 12. e um componente JavaScript que expõe sua funcionalidade para as aplicações HTML 5. ou então queira usar uma característica para a qual não existe o componente JavaScript do PhoneGap. Notificação (Notification) . crie um arquivo “index.Página 64 de 84      Arquivo (File) .. todos separados por plataforma. Para desenvolver um plug-in.6. como ensinamos na lição anterior.Gravar e reproduzir arquivos de áudio.. Um pequeno exemplo usando a API PhoneGap Vamos começar criando uma aplicação típica PhoneGap. Logo. Dentro da pasta “assets/www”. Media (Media) .html”. Armazenamento (Storage) . </html> . <body> 7.9. Plug-ins prontos Se você quiser.Lidar com o sistema de arquivos nativos através do JavaScript.0. Porém.Notificações visuais. será que dá para desenvolver tudo assim? Caso você queira fazer um processamento em segundo plano (ou “background”). </head> 6. </div> 11. <head> 3. Geolocalização (Geolocation) . você precisa criar duas camadas: um componente em código nativo de cada dispositivo. existem alguns pré-requisitos para utilizar a API em toda sua plenitude.</p> 10. Este diagrama vem do site de documentação do PhoneGap. <p>Inicializando o PhoneGap.js" /> 5. Embora você possa utililizar qualquer HTML com JavaScript. Eis o “esqueleto geral” de uma aplicação básica: 1. <html> 2.Tornar sua aplicação consciente de sua localização. você não precisa se preocupar em aprender a lidar com as características de cada equipamento individualmente. Crie um projeto Android no “eclipse”. <html> 2. android:versionName="1. </div> 27.version + ' 18. Agora. Eis o código-fonte (adaptado do existente na API do PhoneGap): 1. 9. android:versionCode="1" 5.permission.teste" 4.INTERNET" /> 2. </script> 21. <body> 23. o evento “deviceready” será levantado. '. <head> 3. </html> Se você conhece JavaScript e HTML. 'Device UUID: ' + device.Principal" 11. 7.0"> 6. ' + 13. <category android:name="android. 'Device Platform: ' + device. </application> 18. <title>Integrando com a API PhoneGap</title> 4. <manifest xmlns:android="http://schemas. 'Device Version: ' + device.permission.innerHTML = 'Device Name: ' + device. <uses-permission android:name="android. Estas permissões devem ficar dentro do tag <manifest>: 1.action. </intent-filter> 16. precisamos esperar o ambiente PhoneGap inicializar e depois carregamos as informações dentro da “div” que criamos. 'Device PhoneGap: ' + device.permission. <uses-permission android:name="android. e colocamos nossa função. <application android:icon="@drawable/icon" android:label="@string/app_name"> 10.phonegap.. <script type="text/javascript" charset="utf-8" src="phonegap. } 20. <action android:name="android.9. que fica no raiz do projeto: 1. .getElementById("saida"). exibirInfo.platform + ' 14.uuid + ' 16. <uses-sdk android:minSdkVersion="7" /> 7.permission. </head> 22. function exibirInfo() { 8.6.android.0" encoding="utf-8"?> 2. como vamos realmente utilizar a API PhoneGap neste programa.addEventListener("deviceready". Quando o PhoneGap termina de inicializar (ele é carregado pelo primeiro tag “<script>” da página. false). ' + 11. <activity android:name=". criado pelo PhoneGap.0. ' + 17.Página 65 de 84 Note que estamos carregando o JavaScript do PhoneGap logo no início. <div id="saida"> 25. <uses-permission android:name="android. <p>Inicializando o PhoneGap. document.thecodebakers..js" /> 5. interceptamos o evento “deviceready”. <script type="text/javascript" charset="utf-8"> 6. <h3>Informações</h3> 24. saida.intent. var saida = document. você deve acrescentar as seguintes permissões no seu arquivo “AndroidManifest. </body> 28. </activity> 17. </manifest> Depois.</p> 26. android:label="@string/app_name"> 12. Antes de mais nada.MAIN" /> 14. 19. package="org. <intent-filter> 13.ACCESS_NETWORK_STATE" /> Elas indicarão ao usuário que o seu programa tenta acessar a INTERNET do dispositivo. ' + 15.phonegap + ' 12.com/apk/res/android" 3.intent.LAUNCHER" /> 15.INTERNET" /> 8. e também o estado da rede de comunicações. <?xml version="1. <uses-permission android:name="android.name + ' 10.xml”.ACCESS_NETWORK_STATE" /> 9.category. será fácil entender o que esta página faz. thecodebakers. import android. que foi criada automaticamente para o nosso projeto. Eis o código-fonte da minha activity: 1.6.app. “device. 6. <title>Integrando com a API PhoneGap</title> 4. finalmente. Só isso? Pô. function exibirInfo() { 8. /** Called when the activity is first created. ok? Eu sei que é pouco.0. Então vamos colocar um botão para dar uma “vibrada” no Celular.innerHTML = 'Device Name: ' + device.loadUrl("file:///android_asset/www/index. 5. Logo. public void onCreate(Bundle savedInstanceState) { 12. } 15. exibirInfo.Página 66 de 84 E então. 9. 3.Bundle. faltam duas “coisinhas”: primeiro. 4. 7. de modo que ela invoque a nossa página HTML.getElementById("saida").addEventListener("deviceready". temos que executar o programa em um AVD.js" /> 5. } E. temos que alterar a classe Java da Activity. 8.name + ' 10. Eis o novo código-fonte em HTML: 1. package org. 13. ela carregará o conteúdo da div “saida”. tá bom. saida. Ah. import com. E.teste.phonegap. ' + . document.DroidGap. 2. import android. eis o resultado da execução do programa: O nosso código-fonte solicita à API de Dispositivo as seguintes propriedades:      “device.uuid” : o identificador universal do aparelho. você não tem a menor ideia do que eu estou falando? Então volte à lição anterior e leia atentamente.Activity.phonegap” : versão do PhoneGap que está rodando. eu queria fazer mais! Ah. Para que este programa funcione. “device. var saida = document. @Override 11.version” : versão do sistema operacional do dispositivo.html"). nossa função será chamada. em segundo lugar.name” : o nome do produto (ou dispositivo). <script type="text/javascript" charset="utf-8"> 6. super. */ 10. 14. false).os.onCreate(savedInstanceState).phonegap.platform” : qual é o sistema operacional do dispositivo. mas temos que ir devagar. public class Principal extends DroidGap { 9. “device. <head> 3. super. <script type="text/javascript" charset="utf-8" src="phonegap. <html> 2.9. 7. “device. Página 67 de 84 11. <body> 30. </html> Estamos utilizando a API “notificações”. </script> 28. Você só vai sentir isso se colocar a aplicação rodando em seu Celular. Leia a partir do item “Instalação de aplicações no seu dispositivo móvel”.phonegap + ' 12. do curso de Android básico. da liçao 10. function vibrar() { 21. } 20.platform + ' 14.notification." value="Vibrar" /> 35. ' + 13.. ' + 15. navigator.alert("Vibrando". que pode ser acessada no endereço: https://github. 24. Felizmente. } 27. é necessário utilizar um plugin. logo. mas falta sempre alguma coisa. Por exemplo. 26. Colocando para rodar em um Celular Android Ainda não vamos usar o Android Market! Para começar. ' + 17. </head> 29. 'Device Version: ' + device.notification. '. return false. 25.google. 'Device Platform: ' + device. 19.. Eis os plugins que existiam no repositório até a data de hoje (7 de Agosto de 2011):  Analytics: Enviar estatísticas de visualização de páginas no seu aplicativo para o Google Analytics .com/p/gerador-de-desculpas-furadas/downloads/list. "Funcionou?". o PhoneGap já possui uma boa biblioteca de plugins.version + ' 18. Este é o laboratório desta lição. <div id="saida"> 32.com/phonegap/phonegap-plugins.uuid + ' 16. 23.. <p>Inicializando o PhoneGap.. Como compartilhar coisas no Facebook? Como enviar um e-mail? Essas funções são específicas de cada plataforma. </body> 36. 'Device PhoneGap: ' + device. "OK"). O projeto pode ser encontrado no Google Code: http://code. para nós. </div> 34. navigator. <input type="button" onclick="vibrar(). 22. <h3>Informações</h3> 31.</p> 33. gere um APK com certificado auto-assinado. Usando plugins O PhoneGap possui uma API padrão bem completa. para mostar um alerta e fazer o dispositivo vibrar.vibrate(2000). 'Device UUID: ' + device. usamos um método “addConstructor” que nos permite adicionar nosso plugin.Instanciar o PhoneGap e o plugin: <script type="text/javascript" charset="utf-8" src="phonegap. MeuPlugIn. você TEM que conhecer Java e TEM que saber programar em Android. [params]). }. então dá para começar.addPlugin('meuplugin'. } 9.js" /> . você implementa o método “execute”. 'acao'. 6. Nesta classe. 6. 5.0. para compartilhar informações SoftKeyboard: Mostra ou oculta o teclado StatusBarNotification: Permite escrever mensagens na barra de notificações do Android TTS: Permite usar as características de "Text-to-speach". Para invocar um plugin.. acao. Podemos passar um texto para ser "falado" WebIntent: Permite invocar qualquer "Intent" do Android Mas. Depois. precisamos fazer a “ponte” entre o JavaScript e a nossa classe. } Entre os argumentos que ele recebe. é um cliente para FTP PayPalPlugin: Este muito importante! Serve para você enviar pagamentos.. PluginManager.js" /> <script type="text/javascript" charset="utf-8" src="webintent. String callbackId) { 4.phonegap. Primeiramente. // . permite digitalizar códigos de barra Bluetooth: Permite comunicação via bluetooth ChildBrowser: Cria um navegador "popup" com páginas externas. é necessário registrar nosso plugin com ele. mas. Primeiramente. Para isto. 'org..Plugin”. if (action. 4. para que o PhoneGap saiba que seu plugin existe.exec(success. está o nome da ação que deve ser executada.thecodebakers.acao = function (params.prototype.. }). success. dentro da sua aplicação ClipboardManager: Integração com a "Clipboard" nativa ContactView: Permite integrar com o Intent visualizador de contatos nativo do Android. } 8. public class MeuPlugIn extends Plugin { 2. Isto é feito em um arquivo JavaScript: 1. desta forma: 1. como se desenvolve um plugin? Tenho certeza que está muito cedo para isto... JSONArray args. se insiste. 9. PhoneGap. fail) { 3. ao invés de lidar com a Contacts API FileUploader: Para enviar arquivos do dispositivo a um servidor FtpClient: Como o próprio nome diz.meuplugin').6.api.Página 68 de 84               BarcodeScanner: Como o próprio nome já diz. new MeuPlugIn()). // . // Associa à classe que executa o serviço 10.equals("acao")) { 5.9.addService('MeuPlugIn'. Temos que criar um objeto e um método. return PhoneGap. public PluginResult execute(String 3. ou seja. você tem que criar uma classe Java. PhoneGap. que estenda “com.addConstructor(function () { 7. implementar "inapp buy" PowerManagement: Permite acesso às funções de "power management" nativas Share: Cria um "Intent" ACTION_SEND. var MeuPlugIn = function () {}. Depois. // Cria uma instância do nosso plugin 8. 11. fail. Se já fez nosso Curso Básico de Programação Android. 7. 2. bastam duas coisas: 1 . 'MeuPlugIn'. meuplugin. 5.9. Incluímos mais uma função no nosso bloco de scripts: 1. Leia as instruções para saber como chamar a função desejada. O WebIntent foi criado por Boris Smus (http://smus. e baixar os dois arquivos (https://github. Porém.6.java” e “webintent. extras[WebIntent. 4. Alterações no arquivo “index./title> <script type="text/javascript" charset="utf-8" src="phonegap.js” deve ser copiado para a pasta “assets/www”. logo abaixo da carga inicial do PhoneGap: 1. então olhamos o repositório de plugins (https://github.EXTRA_TEXT] = document. O arquivo “WebIntent. 4. Não vamos entrar em mais detalhes aqui porque não é o momento. Se não leu. devemos criar os diretórios corretos dentro da pasta “src” (pode criar como Java Package) e copiá-lo para lá. Como se usa um plugin? Normalmente. Melhorando o “Gerador de Desculpas Furadas” Lembra do programa que fizemos na primeira lição? Bem.startActivity({ 6. Para começar.com/phonegap/phonegap-plugins/tree/master/Android). logo.js" /> <script type="text/javascript" charset="utf-8" src="webintent. Como vamos compartilhar a “desculpa” gerada? Bem. vamos adicionar um botão para compartilhar a “Desculpa Furada” que ele criou. Copie o arquivo “js” para a pasta “assets/www”. // etc }). tomando cuidado de criar a subpasta de pacote que ele pede (neste caso: "src/com/borismus/webintent"). window. que pegue o texto da “div” onde o gerador colocou a desculpa.com/files/ProjectExcuse. var extras = {}. o próprio autor dá instruções.zip). videos e outros”. com o código do “Gerador” (http://gerador-de-desculpasfuradas. o plugin “WebIntent” é mais completo e permite chamar qualquer “Intent”. invocar o plugin: window.googlecode.plugins.js”.js" /> E precisamos colocar um botão.webintent. 3. para começar. Você não sabe o que é o “EXTRA_TEXT”? Então leia nosso tutorial “Compartilhando imagens. vamos olhar a documentação da API do PhoneGap (http://docs. arg2: 'val2'.innerHTML.com/phonegap/phonegap-plugins/tree/master/Android/WebIntent ): “WebIntent.com/about).html” Temos que adicionar o “boot” do plugin. crie um projeto Android (falamos sobre isso na primeira lição deste curso). porém. extras: extras . Se não acharmos nada que sirva. Isto é bem interessante. incluindo aplicações que tenhamos desenvolvido. e envie como “EXTRA_TEXT” no “Intent”.0. extras[WebIntent. Vamos usar o “WebIntent”. 8. 3.Página 69 de 84 2 – No momento certo. Se você fez a primeira lição deste curso.java” possui uma declaração de pacote. então leia a primeira lição. type: 'text/plain'. Achamos dois! Os plugins “Share” e “WebIntent” atendem ao nosso propósito. action: WebIntent. deve ter uma Workspace com o projeto já criado nela. 2. 7.phonegap. pois abre uma janela infinita de probabilidades. <html> <head> <title>Gerador de desculpas furadas&lt. 5.plugins.com/android-phonegap-plugins.com/).EXTRA_SUBJECT] = "Querido(a) chefe!". Vamos acessar o GitHub do projeto WebIntent.ACTION_SEND.getElementById("output"). e ele possui um Blog no qual expõe seus projetos: http://smus. resumindo:    Copie o arquivo “java” para a pasta “src” do seu projeto. O arquivo “webintent. function compartilhar() { 2.acao({ arg1: 'val1'. é só criar um botão: 1. 11. então passamos uma função vazia. 15. Note que estamos criando uma coleção de argumentos. lendo e gravando arquivos no "sdcard".Página 70 de 84 9. JSON .com/p/gerador-de-desculpas-furadas/source/checkout.google. Agora. Não queremos ser avisados quando ele terminar. conforme já falamos no tutorial “Compartilhando imagens. passamos duas outras funções: uma para o evento de término da ação e outra para o caso de erro. 10. Então. Depois. o “Intent” ACTION_SEND será invocado e mostrará as telas para você escolher o canal e enviar. Jogou a toalha? Que isso?! Assim você me entristece. } ). vamos ver como lidar com esta interface.. Uma das interfaces desta API é a "File". você mata o coelho com duas “cassetadas”: http://code.Será o de "Sexta-feira 13"? . nós já temos um projeto no Google Code com a resposta pronta. } }.. 14. contento o EXTRA_SUBJECT (assunto da mensagem) e o EXTRA_TEXT (texto). 13. onclick="compartilhar()" /> Pronto! Eis a saída: Se você clicar no botão “Compartilhar”. 12. Só que acrescentamos o AdMob também. que te permite lidar com elementos do dispositivo sem se preocupar com detalhes de cada sistema operacional. Tudo bem. que permite lidar com arquivos. Lidando com arquivos O PhoneGap possui uma API bem interessante. function() {}. &<input type="button" value="Compartilhar" 2. Nesta lição. videos eoutros”. function() { alert('Erro ao compartilhar'). logo. meio "estressante". só que passamos outro ponteiro de função.resolveLocalFileSystemURI("file:///sdcard". Da maneira explícita: 1. cujo zip pode ser baixado desta URL: http://code. Esta função é implícita (nem tem nome) e dá um alerta. 5. Segundo o meu site preferido." Para entender bem a programação PhoneGap é necessário saber criar expressões JSON. window. o método "resolveLocalFileSystemURI" pode invocá-la. É o mesmo exemplo anterior.Página 71 de 84 Para entender legal a programação PhoneGap. }). 4. digamos. Veja um exemplo: { "Aluno" : { "nome": "João".com/p/gerador-de-desculpas-furadas/downloads/detail?name=FileProject.resolveLocalFileSystemURI("file:///sdcard". <B>function () { 3. <B>ok</B>. é necessário entender um pouco de JavaScript. 7. um acrônimo para "JavaScript Object Notation". que ensina tudo o que você precisa saber sobre esta técnica. alert('Erro ao tentar acessar o sdcard'). Um projeto de exemplo Criamos um projeto de exemplo para esta lição. } <B>function ok(diretorio)</B> { .org/. Ponteiros de função Em JavaScript é muito comum passarmos ponteiros de função como argumentos. a Wikipedia: "JSON (com a pronúncia ['dʒejzən]). o que é. 7 ] } } Nós podemos criar e passar objetos utilizando a sintaxe JSON.. Podemos fazer isto de duas maneiras: explícita e implícita. mas seu uso não requer Javascript exclusivamente. function () { alert('Erro ao tentar acessar o sdcard'). "notas": [ 8. é um formato leve para intercâmbio de dados computacionais. 3. característica do PhoneGap.. O JSON é uma das causas deste "stress". 8. 9. Isto é chamado de "callback".json. 2. A maneira implícita é declarar a função dentro da chamada de outra: 1. ok. e é um dos princípios da programação assíncrona. 6. }</B> 5. window... ). 4. Outro site muito interessante é o http://www. } Note que a função "ok" foi passada como argumento.google. 2. ou então clicando no QR code abaixo: . JSON é um subconjunto da notação de objeto de JavaScript.zip. 4.onCreate(savedInstanceState). <uses-permission android:name="android.Página 72 de 84 Notas sobre desenvolvimento JavaScript Desenvolver em JavaScript é.xml": 1. } . <uses-permission android:name="android. recomendamos ver a primeira lição do curso.html").html". Criar uma pasta "www" dentro da pasta "assets".js" e a sua página "index. Adicionar o jar que você acabou de copiar ao Build path do projeto. import android. Mas vamos mostrar como melhorar isso depois.ACCESS_NETWORK_STATE" /> Porém. As permissões básicas devem ser acrescentadas ao tag "<manifest>" do arquivo "AndroidManifest.permission. package org. caso deseje gravar arquivos no "sdcard": 1.permission.thecodebakers.xxx. @Override 9.phonegap. <uses-permission android:name="android. você pode utilizá-lo sem problemas.filesample. modifique sua classe de "activity": 1. 6. Mas. mas vamos repetir aqui as principais tarefas para preparar um projeto: 1. E o pior de tudo: não dá para depurar código JavaScript de maneira fácil no Android. 3. */ 8.. nem code completion no "eclipse". public void onCreate(Bundle savedInstanceState) { 10. 2. public class Principal extends DroidGap { 7.jar". 3. Sem um plugin para JavaScript. 5.xml".loadUrl("file:///android_asset/www/index.html". 11. você não tem sintax hi-light. } 13. 2.phonegap. e copiar para ela o arquivo "phonegap..Bundle. /** Called when the activity is first created. 5.os. Montando um projeto Se baixou o nosso projeto. Adicionar as permissões necessárias ao arquivo "AndroidManifest. super.WRITE_EXTERNAL_STORAGE" /> Finalmente.INTERNET" /> 2.xxx. Modificar sua "activity" para exibir sua página "index. 4. Copiar para ela o "phonegap. se quiser criar outro projeto do zero. além de qualquer javascript de plugin que você use. import com.DroidGap. no mínimo "nojento" =( . super.permission. existe uma permissão adicional. Criar uma pasta "libs" na raiz do projeto. 12. porque. Primeiramente. window. txtListagem = txtListagem + entries[i]. function() { 6. ok.fullPath. nós usamos o método "resolveLocalFileSystemURI" para obter o diretório "/sdcard/". window. 20. se tudo der certo. function () { 12. var leitor = diretorio. txtListagem = txtListagem + "</br>". que recebe como argumento um objeto de erro. 7. e outro para falha.log(entries[i]. } 32.PERSISTENT. mesmo usando o sintax hilight. 17. } 34. Vamos mostrar como obter a entrada de diretório do "sdcard": 1. console.readEntries( 21. ). bastando verificar nesta lista do . txtListagem = txtListagem + "Diretório: ".getElementById('output').name). que pode receber como argumento o objeto solicitado. as listagens de código-fonte costumam ficar meio bagunçadas. 5. } 39. txtListagem = txtListagem + "Arquivo: ". Toda a API "File" do PhoneGap é baseada na proposta de "File API". i<entries. if (entries[i].innerHTML = txtListagem. } 8. deverá mostrar um alerta de erro. recomendamos que você acompanhe o código-fonte pelo "eclipse". var i. Mas é simples. 35. cuja propriedade "code" nos permite saber qual foi o problema. 9. 41. alert('Erro ao tentar acessar o sdcard'). function() {}. 3. 36. 25. function gerar() { 2. } 14. } 29. 31. alert('Erro ao tentar acessar o file system'). ). Isto significa que. var txtListagem = diretorio.Página 73 de 84 Listando diretório A API "File" possui alguns objetos interessantes.name. 28. leitor. uma proposta livre de protocolo e API de acesso a arquivos e diretórios em páginas Web.resolveLocalFileSystemURI("file:///sdcard". Note que passamos a função "ok" como "callback" de sucesso para este método. else { 30.createReader(). do W3C. for (i=0. 33. 10. function ok(diretorio) { 18. }. i++) { 24. 11.code). caso ele consiga obter o diretório "/sdcard" ele deverá chamar a nossa função "ok". que representa uma entrada no diretório do File System. } Calma! Lembre-se de fazer uma meditação! Aliás. alert("Problema ao ler diretorio: " + erro. } 16.isDirectory) { 27. 40. ). 26.requestFileSystem(LocalFileSystem. entre eles o DirectoryEntry. usamos o método "requestFileSystem" para obter acesso ao FS do Android. caso contrário. 0. 38. 4. function(erro) { 37. document. 23. function(entries) { 22. A maioria das funções da API "File" recebe dois "callbacks" como argumentos: um para sucesso. 13. 15. 19.length. Mas. 2.readEntries( function(entries) { O que estamos fazendo aqui? A sintaxe do método "readEntries".Página 74 de 84 W3C: http://www. Para isto./platform-tools".file( 4. entradaArquivo. Se você rodar o programa de exemplo. no Windows). function (arquivo) { 5. com o método "createReader": var leitor = diretorio. É o que fazemos no resto do método "ok". do objeto "FileEntry" obtido. para podemos ler o conteúdo: 1. temos que obter o "FileEntry" do arquivo desejado. você tem que aprender a criar um arquivo dentro do "sdcard" do emulador.txt" aparece na listagem do diretório. function (entradaArquivo) { 3. 5. nós pegamos o nome do diretório e criamos um Reader para ler as entradas. Digite ". Os elementos que o DirectoryReader recebe podem ser "FileEntry" ou "DirectoryEntry". usamos o método "file". callBackFalha). tecle <CTRL><Z>. 3. Inicie o emulador no eclipse. Veja a figura: Para ler o arquivo. 6. Em nossa função "ok".readEntries(callBackSucsso. digite algumas linhas e. Lendo um arquivo Vamos mostrar o código para ler o conteúdo de um arquivo e mostrar na página. o que fazemos com o método "resolveLocalFileSystemURI" para localizar o arquvo ("/sdcard/teste. crie o arquivo com o comando: "cat > teste. Vá para a pasta: "android-sdk-.org/TR/file-system-api/#error-code-descriptions.. window.txt"). verá que o arquivo "teste./adb shell" no Linux (ou "adb shell" no Windows).w3. 2. 4. usamos o programa "adb": 1. antes disso. . escrevemos os dois "callbacks" de maneira implícita. Depois. Você está na console do emulador.. Abra uma janela terminal (ou um prompt de comandos. Agora é só Linux! Vá para a pasta do "sdcard": "cd /sdcard".txt". Agora. ao final. var leitor = new FileReader(). do Objeto "DirectoryReader" é: directoryReader. e nós testamos isso com os métodos "isFile()" e "isDirectory()". Talvez o que fique meio estranho é a linha seguinte: leitor.createReader().resolveLocalFileSystemURI("file:///sdcard/"+arquivo. target. 3.createWriter( 2. se for um arquivo de texto. [callback de sucesso]. precisamos acrescentar um método "onloadend" ao objeto FileReader. temos que obter um FileWriter sobre o arquivo. 2. Laboratório Sugiro que você pegue o aplicativo de exemplo e faça as seguintes modificações:    Modifique a listagem do diretório para colocar links nos arquivos e diretórios. 3. que recebe um "evento" como argumento. leitor. . As opções são informadas através de um objeto JSON. seu conteúdo será mostrado dentro de uma <DIV> que criamos. Porém. Para gravar. [callback de falha]).innerHTML = 8. 19. }. Usamos um objeto "FileReader" para ler o arquivo. [callback de falha]). entre nele e liste as entradas. }. Gravando um arquivo Podemos gravar e/ou criar um arquivo com o método "getFile". se for um diretório. que nos permite gravar dados. Esse comportamento inconsistente realmente atrapalha o desenvolvimento. não? O método "onloadend" é um tipo de "callback". }. 16. 12. entrada. function (erro) { 13. alert('Erro ao tentar acessar o arquivo'). entrada.onloadend = function(evt) { 7. 9. e possuem algumas propriedades. do objeto DirectoryEntry. 4. Seu funcionamento é meio diferente do modelo de "callbacks" das outras funções da API. } 15.readAsText(arquivo). document.Página 75 de 84 6.result. O método "readAsText" lê todo o conteúdo do arquivo. 10. Ao clicar no link. function () { 18. [callback de sucesso].result contém o texto lido. 14. A propriedade "evento". A sintaxe deste método é: 1. e sua sintaxe é: 1.target. 17. Permita criar e gravar dados em qualquer arquivo. ). Ao clicar o botão "ler Arquivo". O método "createWriter" faz isto. 11. }). leitor. alert("Erro ao acessar o arquivo"). mostre o conteúdo. como: "create" (se é para criar o arquivo) e "exclusive" (se você deseja acesso exclusivo). "<hr/>" + evt. que será chamado quando a leitura terminar.getElementById('arquivo'). [opções].getFile([path do arquivo]. 0.. Para consertar isso.PGAndroidString" />.com/files/pgandroidstring. criado para as versões anteriores. Vamos ver como fica o exemplo no nosso projeto de plugin: PGAndroidString. que traz algumas novidades importantes.addService". Retire o phonegap-0. incluindo os nativos da API. que serve para registrar os plugins que você vai usar.xml". crie a pasta). Adicione uma entrada no arquivo "res/xml/plugins. agora o PhoneGap tem uma novidade: o arquivo "plugins. Atualização do PhoneGap Antes de começarmos. Coloque o phonegap-1. com os mesmos dados da linha que você comentou: <plugin name="PGAndroidString" value="org.com/download.plugins. atualize o PhoneGap conforme já ensinamos e tente rodar. só que não deve invocar o "PluginManager. Remova os arquivos das versões anteriores. se você já tem um projeto criado.0. O pacote contém a mesma estrutura dos anteriores. que pode ser encontrada em: http://www. Simon Mac Donald publicou em seu Blog um post sobre a atualização para PhoneGap 1.zip e baixe o projeto. 3. Ao invés de usar o "addService()" dentro do "addConstructor()" no arquivo JavaScript do Plugin.0. do PhoneGap. Baixe a nova versão do PhoneGap.googlecode.. Comente a linha que começa com "PluginManager.thecodebakers. Depois.". vamos ver como utilizar mais um elemento da API PhoneGap. faça o seguinte:    Extraia o arquivo "PGAndroidStringSample. Examine o código HTML e substitua a versão do arquivo JS que você está carregando. e você deve copiá-lo para a pasta "res/xml" do seu projeto (se ela não existir. selecione: Import / General e "Existing projects into workspace". Na workspace do eclipse. deve atualizar alguns arquivos. Nesta lição.jar do seu Build path. pode ser que tome um erro ao tentar utilizá-lo.Página 76 de 84 Usando contatos e atualização para PhoneGap 1. O projeto não vai funcionar e você vai tomar um erro de JavaScript. dentro da pasta "Android/xml". e também a atualização para PhoneGap 1.jar em seu Build path.0. Porém. inclusive dos plugins. Se quiser saber mais detalhes. a parte de contatos.0.phonegap. Edite o arquivo JavaScript do Plugin: "pgandroidstring.html".addService.0 Durante este curso.js para a pasta "assets/www" do seu projeto. crie).0.0 do PhoneGap. .9. Depois. Baixe o arquivo zip da distribuição e vamos tentar atualizar o projeto de demonstração para PhoneGap 1. Isto se deve à nova maneira de registrar plugins. Aponte para o arquivo jar. 2. phonegap-1. Clique neste link: http://pgandroidstring.jar".x.androidstring. você ainda precisa carregar o JavaScript do plugin dentro de sua página "index. porém. faça o seguinte: 1. Este arquivo vem na distribuição. saiu a versão 1.js". temos que adicionar uma entrada no arquivo "plugins.jar para a pasta "libs" do seu projeto (se não existir.0.0. o plugin será registrado automaticamente pelo PhoneGap. Localize a pasta "Android" e copie:       phonegap-1.xml".phonegap. Agora.0. Plugins antigos Se você usa um plugin antigo.xml". cujas principais propriedades são:     id: Identificador.innerHTML += " 13.length. O elemento principal é a classe "Contact". opcoes. displayName: Nome que é exibido na lista. 5. (string) value: Valor do campo. . phoneNumbers: Um vetor de telefones do usuários. uma classe que estabelece os critérios de busca. opcoes. function procurar() { 2. var colunas = ["displayName". var opcoes = new ContactFindOptions().[[falha]].md. local. "emails"]. Ela receberá um vetor contendo os contatos encontrados.zip.). 4. (string) pref: Se é o valor preferido pelo usuário (telefone preferido. 6. "emails". ix < lista. "comercial" etc). pelo menos a parte básica. function(lista) { 8.Página 77 de 84 API de contatos Nós criamos um projeto para explicar como funciona a API de contatos. O elemento "ContactField" é uma classe que contém as propriedades:     type: Informa que tipo de dado é ("casa".getElementById("output"). Você pode baixar este projeto clicando neste link: http://geradorde-desculpas-furadas. Encontrados: " + lista. chamada caso tenha havido algum erro. do projeto que criamos: view plaincopy to clipboardprint? 1. navigator. 9. ix++) { 12. Sua sintaxe é: navigator. Ela recebe o código do erro como argumento. criada pelo PhoneGap. chamada caso a busca tenha sido ok. A descrição completa da API de contatos pode ser encontrada na documentação do PhoneGap: http://docs. Sucesso é um objeto "function". Falha é um objeto "function".filter = document.html".find([[colunas]]. emails: Um vetor de endereços de email do usuário. Vamos ver como funciona isso dentro do arquivo "index.com/files/ProjectAula5.[[sucesso]]. ou o endereço de uma função. (string). (string).innerHTML = " 10. Opções é uma instância de "ContactFindOptions". ou o endereço de uma função. (ContactField[]).displayName + "</b>".phonegap. 3.contacts.com/phonegap_contacts_contacts.[[opções]]). Os argumentos desta função:     Colunas é um vetor contendo os campos do contato desejados ("displayName". local.googlecode. var local = document.innerText. . (boolean) Podemos obter contatos utilizando a função assíncrona "contacts.getElementById("nome").. 11. ou clicando no QR Code abaixo.contacts. (ContactField[]).html.. email preferido etc).find()". <b>" + lista[ix]. for (var ix = 0.multiple = true.find(colunas. 7.length. que é recuperar contatos do dispositivo Android. Nesta lição. local. 18.innerHTML += "<li>" + lista[ix]. 15. . no vetor de emails de cada contato. 24. nós simplesmente navegamos no vetor de contatos recebidos e.length > 0) { local. e chegou a hora de vermos como são criados os plugins. } local. de modo que ele envie uma mensagem para o contato selecionado. 19. altere o programa desta lição. Criando um plugin para PhoneGap Esta é a última lição do curso de PhoneGap.Página 78 de 84 14. 20. 17.innerHTML += "</li>". } } }. iy < lista[ix]. Não vamos ficar "enrolando" vendo cada item da API. 23. passando o valor digitado no elemento "nome" e a opção true. O projeto funciona e o resultado está na imagem a seguir: Laboratório Agora é a sua vez! Lembra do plugin "WebIntent".emails. 22. 16. 26.innerHTML += "<ul>". um plugin para PhoneGap que criamos recentemente. Mostramos aqui o uso das principais funções e alguns exemplos de aplicações prontas. na função Callback de sucesso. que já é muito bem documentada no site do PhoneGap. opcoes). se houver email. } if (lista[ix]. Depois. iy++) { local.length. 21.emails[iy].value. criamos uma instância de "ContactFindOptions". 25. }. for (var iy = 0.emails. vamos trabalhar com o projeto "pgandroidstring". function(erro) { alert("Erro ao acessar os dados: " + erro). para retornar múltiplos resultados. 27.innerHTML += "</ul>". 28. que mostramos na lição 3? Bem. adicionando tudo ao HTML da div de saída. Antes de mais nada. É só usar o WebIntent e o ACTION_SEND! Se você preencher o campo EXTRA_EMAIL e use o mime type "text/plain". json. Isto é um acoplamento de lógica.Página 79 de 84 Extensões Apesar do PhoneGap possuir uma grande API. JSONObject resString = new JSONObject().res.json. como já ensinamos neste curso. 9.Plugin". e isto é feito com o auxílio de plugins. 15. import org. e você deve implementar o método: public PluginResult execute(String action. import com. 13.util.api.api. Sua classe deve estender "com.content.phonegap. 17. o que é ruim. 5. import org. "Entrou no execute"). String callBackId) Os argumentos são:    "action": nome da ação que o plugin deve executar. String arg2) { 21.phonegap.androidstring. import android. 4. 23. JSONArray dados. 24.thecodebakers. Log.phonegap.phonegap.d(TAG. 3. "dados": um vetor JSON contendo os argumentos passados para o plugin. 6. 8. import com.JSONException. 11. as vezes é necessário acessar recursos do aparelho.Plugin. Um plugin é composto por uma camada JavaScript que expõe um Objeto nativo. Por exemplo: acessar os recursos (resources) string de uma aplicação Android! Sim. public PluginResult execute(String action. temos que saber exatamente qual funcionalidade vamos expor. PluginResult result = null. private static final String TAG = "PGAndroidString". .. 10.plugins. e isto ajuda na "L10n" (Localization) da aplicação PhoneGap. 12. public class PGAndroidString extends Plugin { 16.api.Log. 18.PluginResult. Primeiramente. 7.api.PluginResult.Resources. import org. O tipo JSONArray vem dentro da plataforma Android ("android. você deve montar um projeto Android-Phonegap. lembra? Vamos ver o código-fonte da nossa classe de Plugin: 1. package org.. @Override 19. Nós já falamos sobre ele aqui. import com. "callBackId": quando seu plugin invoca código JavaScript da aplicação. 14. da qual já vimos algumas funções. import android. 22.Context.JSONObject. 2.jar") e serve para encapsular um vetor JSON.content.phonegap. import android.json. 20. mas é assim que funciona. criado e instanciado pelo framework do PhoneGap.Status. A classe do Plugin Para começar. JSONArray dados.JSONArray. "string".e(TAG.getString(resourceID). packageName).getResources(). Calma que temos algumas coisas para comentar aqui! Para começar.</B> <B>JSONObject pesquisa = dados.context.OK. } if (action.loadUrl("file:///android_asset/www/index.context. temos um Singleton: Context ctx = PGAndroidStringSingleton. resString.d(TAG.getResources(). E como carregamos o recurso. 58. nós normalmente usamos o método Activity. super. } catch (JSONException jsonEx) { Log.equalsIgnoreCase("getResourceString")) { try { <B>Context ctx = PGAndroidStringSingleton. 41.getMessage()).JSON_EXCEPTION. 55. 49.html"). 47. 53. Log. 56.getString("nome"). } result = new PluginResult(Status. ou então Context.getJSONObject(0). 44.</B> <B>int resourceID = res. try { resString.Página 80 de 84 25.</B> 5. resString). } return result.JSON_EXCEPTION). } 61. Log.</B> String texto = res. A segunda coisa "sinistra" é a maneira como pegamos os argumentos. public class Principal extends DroidGap { 2. } 8. 27. <B>String packageName = ctx.</B> Resources res = ctx. Note que o JSONArray contém um conjunto de JSONObjects. 42. que o usuário do plugin deve fazer em sua DroidGap: 1. Só que nossa classe não é um componente nativo do Android. 51.getIdentifier( pesquisa. 50. 35. 43. "JSON Exception "+ jsonEx.printStackTrace(). resString). criamos um Singleton só para armazenar o contexto da aplicação. Para obter um Resource. } } else { result = new PluginResult(Status.d(TAG. @Override 3. 6. 31.put("value". da classe Resources: . public void onCreate(Bundle savedInstanceState) { 4. "Não achou o recurso").INVALID_ACTION). 34.getResources(). } catch (Resources. Pegamos o primeiro deles (índice zero) e depois usamos a propriedade "nome" para encontrar o recurso.NotFoundException rex) { Log. 57. 46. super.put("value". logo. não temos acesso ao contexto. 26. 30. 45. 29.onCreate(savedInstanceState).context = this. 52. 33. "Retornando: " + texto). 36.getPackageName(). 32. nosso código consegue acessar o contexto e pegar os recursos necessários. } catch (JSONException e) { e. texto). Então. 38. 37.getApplicationContext(). 7. "acao invalida : "+action). <B>PGAndroidStringSingleton. se não temos acesso à classe "R"? É aí que entra o método "getIdentifier()". 39. } Desta forma. "Não achou o recurso"). 28. result = new PluginResult(Status. 59. result = new PluginResult(Status. 48. 54. 40.d(TAG. 60. [classe de recurso]. PluginManager. temos que criar um arquivo JavaScript que "encapsule" o acesso à sua classe de plugin.androidstring. nós criamos um JSONObject contendo a propriedade "value" e retornamos um PluginResult desta forma: 1. você deve acrecentar em sua página HTML a carga do arquivo JavaScript que criamos. falta adicionar a nossa função JavaScript à coleção de plugins da interface JavaScript da aplicação. 'PGAndroidString'.phonegap. 6. PhoneGap.put("value". A primeira linha cria a instância da classe "PGAndroidString" e a associa ao plugin "pgandroidstring". pegamos o nome do pacote do contexto. PGAndroidString. Isto é feito adicionado ao construtor da interface PhoneGap o seguinte código: 1. Porém.prototype. 8.) e terá que criar um arquivo "res/xml/plugins. }).a ndroidstring. successCallback.plugins. Note que o nome da ação "getResourceString" e o JSONArray ("[name]") são definidos nesta chamada. Um objeto Function para o caso de sucesso.xml" contendo: <plugin name="PGAndroidString" value="org. 5. failureCallbac k) { 3.PGAndroidString" /> Conforme ensinamos na lição passada. que recebe também o nome da instância de Objeto nativo a ser invocada. var PGAndroidString = function() {}. 4. Acessando o plugin Para usar o plugin. Em nosso caso. [name])..getstring = function(name. só falta informarmos a classe do recurso.OK.plugins. A primeira coisa que temos que fazer é criar uma instância de um Objeto JavaScript: 1. [nome do pacote]). que recebe:    Um objeto JSON ("name"). Note que se você estiver utilizando PhoneGap 1.thecodebakers. 2.addConstructor(function () { 2.successCallback.addService('PGAndroidString'. 2. return PhoneGap. e o nome do recurso de dentro do JSONArray. 'getResourceString'. Se tudo correr bem. new PGAndroidString()).getIdentifier([nome do recurso].thecodebakers. Ela repassa a chamada para a interface PhoneGap. }. O objeto JavaScript PGAndroidString recebeu uma função chamada "getstring". que é "string". A segunda linha informa onde encontrar a classe "PGAndroidString". 3. 9.exec( 4. texto). Um objeto Function para o caso de falha. . cujo construtor permite passar o Status (constantes) e um JSONObject.Página 81 de 84 Resources.phonegap. O arquivo JavaScript Para facilitar a vida do desenvolvedor.. 'org. failureCallback. resString).addService. 7. result = new PluginResult(Status.addPlugin('pgandroidstring'.PGAndroidString'). Nós devemos retornar uma instância de PluginResult.0 (ou superior) terá que comentar a segunda linha (PluginManager. resString. PhoneGap. alert(e. function pegar() { 2.Página 82 de 84 Isto é feito logo após à carga do próprio PhoneGap: <script type="text/javascript" charset="utf-8" src="phonegap. 7.value). mas o artigo ficou meio "escondido" dentro do Google Code.js" /> <script type="text/javascript" charset="utf-8" src="pgandroidstring.6.innerHTML = e. Desenvolvendo diretamente no dispositivo Android Este artigo se refere ao original em inglês: Using Hardware Devices. Esperamos que seja útil para você. mostraremos como utilizar o PhoneGap no MAC.getElementById('output'). 11. Assim que pudermos. 4.getstring( 3.innerHTML = r.value. 10. }). } Concluindo Neste curso. você deve invocar a função JavaScript que criou: 1. function(r){ 5.getElementById('output').pgandroidstring. document. function(e) { 8. 9. nós cobrimos o básico da programação PhoneGap e um pouco de recursos avançados também.value. como a criação de plugins. 6.9. {nome: 'teste'}. }. window. document. Preparação do computador .0 também! Para usar seu plugin.plugins. Você sabe como executar uma aplicação no seu dispositivo? Nós já falamos sobre isso.0.js" /> Isto vale para PhoneGap 1. com/wportal/devworld/search-downloads/android Se for outro aparelho.html Linux Ubuntu (o nosso caso) O Linux já tem o driver necessário. Por exemplo.d” (terá que se logar como “root” ou usar sudo gedit.. Se seu dispositivo é de outro fabricante.html. se seu aparelho for um Sony Ericsson (o meu é). SYSFS{idVendor}=="0bb4". insira a seguinte linha: SUBSYSTEM=="usb". crie um arquivo chamado: “51android.). Se for Android Developer Phone (ADP). Para começar. MODE="0666" O valor para SYSFS{idVendor} deve ser obtido de acordo com o seu fabricante: Company USB Vendor ID 0502 413c 0489 091E 18d1 0bb4 12d1 0482 1004 22b8 0955 10A9 04e8 04dd 0fce 19D2 Acer Dell Foxconn Garmin-Asus Google HTC Huawei Kyocera LG Motorola Nvidia Pantech Samsung Sharp Sony Ericsson ZTE O meu é: SYSFS{idVendor}=="0fce".com/sdk/oem-usb. dentro da pasta: “/etc/udev/rules. pois é um Sony Ericsson. Nesse arquivo. assumindo que seu Ubuntu é versão 8 ou superior. re-executando-o como “sudo”: . or Nexus S. você tem que procurar o driver correspondente. porém.. então o site é: http://developer. Digite o seguinte comando: chmod a+r /etc/udev/rules. Nexus One. algumas configurações são necessárias. então acesse o link: http://developer. acesse o link abaixo e procure o link para seu driver: http://developer.android.rules”.rules E mate o processo "daemon" do ADB. Dependendo do tipo de dispositivo.android. você tem um driver específico.sonyericsson.d/51-android.com/sdk/win-usb.Página 83 de 84 Windows ® Se você usa Windows ® então tem que instalar um driver USB para o seu dispositivo. Você pode executar. digite: “. Se estiver com interrogações. Isto fará com que o eclipse selecione o seu celular./adb devices”. Vá para o diretório “platform-tools” do seu Android SDK. . Vocë deve ver o seu dispositivo listado.Página 84 de 84 1. na janela Terminal. No eclipse. Agora. Marque a opção “Depuração USB”. depurar etc./adb start-server” Mantenha essa janela terminal aberta! Executando no eclipse Primeiramente./adb kill-server” 3. é porque você não deu as permissões ou não está executando o daemon do ADB como root. Abra o menu: “Configurações”. Execute: “. depois “Aplicativos” e depois “Desenvolvimento”. conecte o seu dispositivo e. conecte o seu dispositivo. 2. abra as configurações de execução (“Run configurations”) e desmarque os “targets” que estejam marcados. Execute: “sudo .
Copyright © 2024 DOKUMEN.SITE Inc.