Trabalho e ensino outros a trabalharem com Android desde algum momento em 2011 e em todos esses anos notei que os estudantes fazem sempre as mesmas perguntas técnicas referentes à alguns aspectos no mínimo “inusitados” da plataforma. A ideia do post de hoje é agrupar as dúvidas mais comuns em apenas um artigo que sirva de referência em Português, visto que elas já foram largamente discutidas e respondidas em fóruns, na documentação oficial e no StackOverflow, todos em Inglês.
As perguntas respondidas neste artigo são:
- Qual a diferença entre px, dp, dip e sp no tamanho de componentes (width e height)?
- Como esconder o teclado virtual do Android?
- Somente posso programar Android com Java?
- Como solucionar o problema de NetworkOnMainThreadException?
- Como evitar que o EditText ganhe foco quando a Activity inicia?
- Como saber o tamanho da tela do dispositivo em que o app está rodando?
- Como centralizar o texto dentro de um TextView (horizontal e verticalmente)?
- O que é Context no Android?
- Qual a diferença entre match_parent e fill_parent?
- Como obter o código-fonte a partir de um APK?
- Como eu resolvo o problema “R cannot be resolved”?
- Como eu resolvo “Gradle DSL method not found: ‘runProGuard'”?
- Como desabilitar modo paisagem em meu app?
- Como passar informações de uma Activity para outra em Android?
- Como adicionar um JAR como biblioteca?
- Qual a diferença entre minSdkVersion e targetSdkVersion?
- Como carregar uma imagem de uma URL em uma ImageView?
- Como eu troco o ícone do meu app?
- Somente posso programar apps Android no Android Studio?
- Como acesso uma API localhost em uma máquina por dentro do AVD?
- Qual o melhor livro para aprender como programar apps?
Nunca programou um app sequer e quer começar rapidamente e com o pé direito? Dá uma olhada nesse meu vídeo aqui.
#1 – Qual a diferença entre px, dp, dip e sp no tamanho de componentes (width e height)?
Segundo este artigo do site oficial do Android, temos a seguinte explicação:
- px (Pixels): correspondem aos pixels na tela.
- in (inches, polegadas): correspondem ao tamanho físico da tela, lembrando que 1 polegada corresponde a 2,54 centímetros.
- mm (milímetros): também baseado no tamanho físico da tela.
- pt (pontos): 1/72 de uma polegada baseado no tamanho físico da tela.
- dp ou dip (density-independent pixels ou pixels independentes de densidade): uma unidade de medida abstrata baseada na densidade física da tela. Estas unidades são relativas a uma tela de 160dpi (pontos por polegada). A proporção de dp para pixels muda conforme a densidade de tela, mas não necessariamente em uma proporção direta. Note que o Android aceita tanto dip quanto dp, são sinônimos, embora dp é mais parecido com sp, visto abaixo.
- sp (scale-independent pixels ou pixels independentes de escala): parecido com a unidade dp, mas também escala de acordo com a preferência de tamanho de letra, ou seja, escala conforme preferência do usuário.
Outras fontes que ajudam a esclarecer esse ponto são esse artigo e esse outro. Para calcular as dimensões em dispositivos reais, você pode usar este app. Mais respostas para esta mesma questão podem ser encontradas aqui.
Obviamente essas unidades se aplicam somente ao SDK nativo, para Corona SDK, por exemplo, use este artigo.
#2 – Como esconder o teclado virtual do Android?
Você pode esconder o teclado virtual do Android usando a classe InputMethodManager, e chamando o método hideSoftInputFromWindow, passando o token da janela contendo a view (componente) que está com o foco.
1 2 3 4 5 6 7 8 |
// verifica se tem alguma view com foco View view = this.getCurrentFocus(); if (view != null) { InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(view.getWindowToken(), 0); } |
Isto força o teclado a ser escondido em todas situação. Em algumas ocasiões você pode querer usar InputMethodManager.HIDE_IMPLICIT_ONLY como segundo parâmetro para garantir que o teclado somente será ocultado quando o usuário não forçá-lo a aparecer (pressionando o botão do menu).
Outras opções de como fazê-lo podem ser encontradas aqui.
#3 – Somente posso programar para Android com Java?
Não, um exemplo é Corona SDK, que permite que você use a linguagem de scripting Lua para programar para Android e iOS. E esse post aqui fala mais a respeito de diversas opções para Android, iOS e muito mais.
#4 – Como solucionar o problema de NetworkOnMainThreadException?
Esta exceção é bem comum quando estamos escrevendo algum app que se conecte a alguma API/web service na Internet. Isso porque o Android não permite por padrão executar operações de rede no fluxo (thread) principal de execução, ou seja, tem de rodar em uma thread separada, de maneira assíncrona, para não travar o smartphone do usuário em casos de Internet lenta.
Existem duas soluções aqui. Ou uma gambiarra e uma solução, dependendo do gosto do desenvolvedor. Na gambiarra, que mostrarei abaixo, com apenas duas linhas de código no onCreate da sua activity você diz ao Android para ignorar essa regra de não permitir conexão com a Internet na thread principal.
1 2 3 4 |
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); |
Já o jeito correto, e por isso mais trabalhoso, envolve criar uma classe assíncrona para executar a tarefa de conexão que você deseja, como abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
class NetworkTask extends AsyncTask<String, Void, TYPE> { private Exception exception; protected TYPE doInBackground(String... urls) { try { //tarefa que conecta na Internet e retorna TYPE } catch (Exception e) { this.exception = e; return null; } } protected void onPostExecute(TYPE retorno) { // verifica se deu algum erro, checando exception // faz alguma coisa com o obejto de retorno } } |
Nesta classe eu usei a palavra TYPE para sinalizar onde você deve colocar o tipo de dado que será retornado pela sua tarefa assíncrona. Pode ser um objeto JSON, um XML, um objeto Java, você decide e troca TYPE pelo tipo correto. No método doInBackground você coloca a conexão com a Internet e o retorno do tipo de dado. No método onPostExecute você verifica se deu erro e usa o objeto que retornou da Internet. O nome da classe, NetworkTask, é apenas uma sugestão.
Para usar esta classe, adicione esta linha no momento que deseja realizar a tarefa assíncrona:
1 2 3 |
new NetworkTask().execute(url); |
Não esqueça da permissão de Internet no AndroidManifest.xml:
1 2 3 |
<uses-permission android:name="android.permission.INTERNET"/> |
#5 – Como evitar que o EditText ganhe foco quando a Activity inicia?
Quem nunca reclamou que o primeiro campo do formulário sempre já vem com o foco definido? Ou pior, já ativa automaticamente o teclado, escondendo o restante do formulário? O trecho de layout abaixo soluciona isso!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!-- Item inútil para evitar que EditText receba o foco --> <LinearLayout android:focusable="true" android:focusableInTouchMode="true" android:layout_width="0px" android:layout_height="0px"/> <!-- :nextFocusUp e :nextFocusLeft são definidos com mesmo id desse componente para evitar que o inútil receba o foco de novo --> <EditText android:id="@+id/edittext" android:layout_width="fill_parent" android:layout_height="wrap_content" android:nextFocusUp="@id/edittext" android:nextFocusLeft="@id/edittext"/> |
#6 – Como saber o tamanho da tela do dispositivo em que o app está rodando?
Se você quer saber as dimensões da tela em pixels, use getSize:
1 2 3 4 5 6 7 |
Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); int width = size.x; int height = size.y; |
Se você não está em uma Activity você pode pegar pegar o “default display” através do contexto WINDOW_SERVICE:
1 2 3 4 |
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); |
Antes de existir o getSize (que surgiu na API 13), você podia usar os métodos getWidth e getHeight que são agora deprecated:
1 2 3 4 5 |
Display display = getWindowManager().getDefaultDisplay(); int width = display.getWidth(); // deprecated int height = display.getHeight(); // deprecated |
Outro jeito de conseguir a mesma coisa é usando DisplayMetrics, que nada mais e do que uma estrutura descrevendo informações gerais sobe o display, como seu tamanho, densidade e escala da fonte. Para acessar os membros de DisplayMetrics, inicialize um objeto como abaixo:
1 2 3 4 |
DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); |
Uma vez que você tenha um objeto metrics como acima, use widthPixels para saber o tamanho absoluto da tela em pixels:
1 2 3 |
Log.d("ApplicationTagName", "Display width in px is " + metrics.widthPixels); |
#7 – Como centralizar o texto dentro de um TextView (horizontal e verticalmente)?
1 2 3 4 5 6 7 8 |
<TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="@string/**yourtextstring**" /> |
ou via Java:
1 2 3 |
.setGravity(Gravity.CENTER); |
#8 – O que é Context no Android?
De forma resumida, como o nome sugere, é o contexto do estado atual da aplicação ou objeto, servindo para que uma parte de seu app conheça detalhes de outra parte, de um ponto de vista mais estrutural. Tipicamente você usa context para pegar informações de uma parte do programa, como uma activity.
Você obtém o context chamando getApplicationContext(), getContext() e getBaseContext(), dependendo da situação.
Usos típicos de context incluem:
- Criar novos objetos, novas views, adapters, listeners, etc:
1 2 3 4 |
TextView tv = new TextView(getContext()); ListAdapter adapter = new SimpleCursorAdapter(getApplicationContext(), ...); |
2. Acessar recursos comuns, padrões do Android, serviços como LAYOUT_INFLATER_SERVICE, preferências compartilhadas, etc:
1 2 3 4 |
context.getSystemService(LAYOUT_INFLATER_SERVICE) getApplicationContext().getSharedPreferences(*name*, *mode*); |
3. Acessar componentes implicitamente como content providers, broadcasts, intents, etc:
1 2 3 |
getApplicationContext().getContentResolver().query(uri, ...); |
#9 – Qual a diferença entre match_parent e fill_parent?
Eles são a mesma coisa desde API 8, mas prefira usar match_parent que é o termo mais moderno. Para quem não sabe o efeito, ambos dizem que a view deseja ser tão grande quanto seu parent (a view de fora). Mais informações na documentação oficial.
#10 – Como obter o código fonte a partir de um APK?
Já falei sobre isso nesse post.
#11 – Como eu resolvo o problema “R cannot be resolved”?
A classe R é gerada automaticamente pelo Android Studio enquanto estamos programando e compilando. Basicamente ela contém referências de memória aos componentes que compõem o app, desde views, até resources e por aí vai. Quando vemos a mensagem ‘R cannot be resolved’ e as referências à classe R aparecem vermelhas indicando erro por toda parte, geralmente é porque seu app não está compilando corretamente e, nesta hora, um checkup completo cai bem.
Primeiro, verifique se o Android Studio não está processando alguma coisa em background (na barra inferior de status diz isso). Às vezes, enquanto ele está processando algo (como um build demorado), o R aparece como ‘cannot be resolved’. Verifique também se na pasta res não há arquivos com aviso de erro, principalmente arquivos de layout com erros de XML (tags que não fecham, caracteres inválidos, etc) ou imagens faltando.
#12 – Como eu resolvo “Gradle DSL method not found: ‘runProguard'”?
Se você está usando a versão 0.14.0 ou superior do plugin do Gradle você pode trocar “runProguard” por “minifyEnabled” nos seus arquivos build.gradle. Esse erro acontece porque runProguard foi renomeado para minifyEnabled na versão 0.14.0. Mais informações na documentação oficial e tudo sobre o Gradle neste post aqui.
#13 – Como desabilitar modo paisagem em meu app?
Adicione android:screenOrientation=”portrait” na sua activity presente no AndroidManifest.xml. Por exemplo:
1 2 3 4 5 |
<activity android:name=".MainActivity" android:label="@string/app_name" android:screenOrientation="portrait" /> |
#14 – Como passar informações de uma Activity para outra em Android?
O jeito mais fácil de fazer isso é colocando um ‘extra’ no intent que será usado para iniciar a outra activity:
1 2 3 4 5 |
Intent intent = new Intent(getBaseContext(), OutraActivity.class); intent.putExtra("INFO", informacao); startActivity(intent); |
Na activity de destino, pegue o ‘extra’ da seguinte maneira:
1 2 3 |
String s = getIntent().getStringExtra("INFO"); |
Você pode passar variáveis de qualquer tipo primitivo e Strings, tendo de chamar o método corresponde para dar o ‘get’ no extra depois. Para passar objetos, a classe do objeto deve implementar a interface Serializable. Mais informações na documentação oficial.
#15 – Como adicionar um JAR como biblioteca?
- Coloque o seu arquivo JAR na pasta libs do seu projeto
- No Android Studio, clique com o botão direito no arquivo e escolha ‘Add as library’
- Verifique se no seu arquivo build.gradle existe a diretiva para compilar arquivos JAR também: fileTree(dir: ‘libs’, include: ‘*.jar’)
- Faça um clean/build
#16 – Qual a diferença entre minSdkVersion e targetSdkVersion?
android:minSdkVersion: designa o nível mínimo de API exigido para executar essa aplicação, evitando que usuários de dispositivos mais antigos consigam instalá-la.
android:targetSdkVersion: designa o nível de API preferível para o app. Essa informação diz que o app foi testado e desenvolvido para funcionar nessa versão, mas que também deve rodar em versões mais antigas, embora uma discrepância grande entre esses dois números pode gerar incompatibilidade retroativa.
Para mais informações, consulte a documentação oficial.
#17 – Como carregar uma imagem de uma URL em uma ImageView?
Essa resposta, muito boa aliás, foi copiada deste site.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// mostra uma imagem da Internet na ImageView new DownloadImageTask((ImageView) findViewById(R.id.imageView1)) .execute("http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png"); //para funcionar o código acima, você deve ter a classe abaixo dentro da sua activity private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { ImageView bmImage; public DownloadImageTask(ImageView bmImage) { this.bmImage = bmImage; } protected Bitmap doInBackground(String... urls) { String urldisplay = urls[0]; Bitmap mIcon11 = null; try { InputStream in = new java.net.URL(urldisplay).openStream(); mIcon11 = BitmapFactory.decodeStream(in); } catch (Exception e) { Log.e("Error", e.getMessage()); e.printStackTrace(); } return mIcon11; } protected void onPostExecute(Bitmap result) { bmImage.setImageBitmap(result); } } |
Não esqueça que para isso funcionar você deve ter a permissão para acessar a Internet no seu arquivo AndroidManifest.xml.
1 2 3 |
<uses-permission android:name="android.permission.INTERNET" /> |
#18 – Como eu troco o ícone do meu app?
Se você pretende que seu app esteja disponível em diversos dispositivos, você deve ter o ícone da sua aplicação em diversas resoluções, todos colocados na pasta res/drawable, com os seguintes tamanhos:
- drawable-ldpi (120 dpi, Low density screen) – 36px x 36px
- drawable-mdpi (160 dpi, Medium density screen) – 48px x 48px
- drawable-hdpi (240 dpi, High density screen) – 72px x 72px
- drawable-xhdpi (320 dpi, Extra-high density screen) – 96px x 96px
- drawable-xxhdpi (480 dpi, Extra-extra-high density screen) – 144px x 144px
- drawable-xxxhdpi (640 dpi, Extra-extra-extra-high density screen) – 192px x 192px
#19 – Somente posso programar apps Android no Android Studio?
Não, você também pode usar o Eclipse e o NetBeans. No entanto, caso você queira ficar craque no Android Studio mesmo, este post tem tudo que você precisa saber!
#20 – Como acesso uma API localhost na minha máquina por dentro do AVD?
Não use a palavra localhost como URL, pois neste caso o seu app iria procurar o endereço local no próprio dispositivo. Ao invés disso, para fins de teste, quando a API/web service está rodando na sua própria máquina host do AVD, use o IP 10.0.2.2 que é reservado para o localhost da máquina física do AVD.
Para mais dicas incríveis de como fazer testes avançados de seus apps, consulte este post aqui.
#21 – Qual o melhor livro para aprender como programar apps?
Criando apps para empresas com Android, de Luiz Fernando Duarte Junior.
Olá, tudo bem?
O que você achou deste conteúdo? Conte nos comentários.