segunda-feira, 23 de agosto de 2010

Android: Usando Reflection para acessar recursos

Olá povo,

Alguns alunos já me perguntaram sobre como obter recursos de uma aplicação Android através do nome do arquivo. Isso pode ser feito através da API de Reflection de Java (pacote java.lang.reflect.*). No exemplo abaixo vou mostrar como obter uma imagem a partir do seu nome.


try {
// Obtém a referência da classe R
Class c = Class.forName("nome.do.pacote.da.app.R");

// Obtém as inner classes: id, layout, drawable, ...
Class[] innerClasses = c.getClasses();

// Procurando inner class drawable
Class drawableClass = null;

for (int i = 0; i < innerClasses.length; i++) {
if (innerClasses[i].getSimpleName()
.equals("drawable")){

drawableClass = innerClasses[i];
break;
}
}
// Procurando o atributo com o nome da imagem
Field f = drawableClass.getField("nome_da_img");

// Obtendo o valor do campo
int resourceId = f.getInt(null);

// Criando uma image view apenas pra exemplificar
ImageView img = new ImageView(context);

// Setando a imagem (recurso) do ImageView
img.setImageResource(resourceId);

} catch (Exception e) {
e.printStackTrace();
}


Como já sabemos, a classe R armazena valores do tipo int que representam os recurso da aplicação. O que fizemos aqui foi obter uma referência para a classe R, depois obter uma referência para a classe interna drawable, e por último, pegar o valor de um dos seus atributos baseados no seu nome.
Podemos fazer isso para as demais classes como id, layout, etc.

4br4ç05,
nglauber

sexta-feira, 30 de julho de 2010

Motorola Shop4Apps

Olá povo,

A Motorola acaba de lançar a Shop4Apps, sua própria loja virtual de aplicativos para dispositivos com o sistema operacional Android.

O aplicativo já vem instalado no modelo FlipOut, mas também pode ser acessado de qualquer telefone através do endereço: http://motorola.com/shop4apps.

No Brasil não é possível comprar aplicações no Android Market. O Shop4Apps vem para preencher essa lacuna. A loja também poderá ser utilizada pelos usuários da Argentina e México.

Achei bastante interessante.

4br4ç05,
nglauber

terça-feira, 27 de julho de 2010

Utilização de Estilos no Android - Parte 2

Olá povo,

Dando continuidade ao exemplo de utilização de estilos no Android, vou mostrar como modificar o visual de alguns componentes. Todos os elementos visuais que são selecionáveis ou clicáveis podem utilizar o recurso <selector> que permite modificar a aparência do componente, indicando quais imagens serão utilizadas para cada estado do componente. Essas imagens são definidas em um arquivo XML que deve ficar dentro da pasta res/drawable. Isso mesmo, a pasta drawable não armazena só imagens.
Vamos criar um selector que modificará as imagens de um RadioButton. Para isso, crie o arquivo res/layout/meuradiobutton.xml que deve ficar como abaixo:

<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_window_focused="false"
android:state_checked="false"
android:drawable="@drawable/img_radio_desmarcado" />
<item
android:state_window_focused="true"
android:state_checked="true"
android:drawable="@drawable/img_radio_marcado" />
</selector>

No exemplo acima, dentro da tag <selector> definimos as imagens utilizadas quando o componente estiver marcado (checked) e desmarcado. Lembrando que as imagens "img_radio_marcado" e "img_radio_desmarcado" também devem estar dentro da pasta res/drawable.

Agora devemos aplicar o selector ao RadioButton. Para utilizar o selector, basta utilizar a propriedade android:button.


<RadioButton
android:checked="false"
android:button="@drawable/meuradiobutton"
android:layout_width="wrap_content"
android:layout_heighth="wrap_content"
android:id="@+id/radioButton1"
android:text="Fácil" />


Podemos observar o resultado na figura abaixo:

Um outra característica legal de modificar é a cor de seleção de Grid e Lista. A idéia é a mesma, criamos um selector e o associamos ao GridView ou ao ListView.

<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<!--Imagem do item da lista clicado -->
<item
android:state_pressed="true"
android:drawable="@drawable/img_clicado" />
<!--Imagem do item da lista selecionado sem foco -->
<item
android:state_focused="false"
android:drawable="@drawable/img_selecionado" />
<!--Imagem do item da lista selecionado com foco -->
<item
android:state_window_focused="true"
android:drawable="@drawable/img_selecionado" />
<!--Imagem do item da lista não selecionado -->
<item
android:state_window_focused="false"
android:drawable="@android:color/transparent" />
</selector>


Para esse exemplo temos uma imagem para quando item da lista está selecionado (navegando com o direcional, se o telefone possuir) e outra pra quando o item for clicado. Para aplicar o selector à lista, altere a propriedade listSelector.

<ListView
android:id="@+id/listView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:listSelector="@drawable/meuselector"/>


O resultado é apresentado na figira abaixo.



Qualquer dúvida, deixem seus comentários.

4br4ç05,
nglauber

Utilização de Estilos no Android - Parte 1

Olá povo,

Aqui vai mais um post sobre UI com Android. Vou falar um pouco sobre como modificar a aparência dos componentes do Android utilizando estilos, similares aos CSS que encontramos no HTML.

Dentro da pasta res de um projeto Android, ficam os arquivos de recursos. As subpastas drawable (imagens), layout (arquivos de definição de tela) e values (textos ou strings) são figurinhas fáceis em qualquer projeto. No entanto, nos arquivos que ficam dentro da pasta values (que não necessariamente precisa se chamar strings.xml) podemos definir também cores, estilos e temas para serem aplicados nas telas do nosso programa. Isso ajuda em futuras manutenções que você queira fazer no visual do seu aplicativo, uma vez que todas as telas estarão referenciando um local centralizado.

Vamos dar uma olhada no nosso arquivo res/values/meurecurso.xml


<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Strings -->
<string name="msg_verde_e_branco">
Texto verde e branco
</string>

<string name="msg_vermelho_e_branco">
Texto vermelho e branco
</string>

<!-- Cores -->
<color name="vermelho">#FF0000</color>
<color name="verde">#00FF00</color>
<color name="branco">#FFFFFF</color>

<!-- Estilo -->
<style name="estiloExemplo">
<item name="android:textSize">16dp</item>
<item name="android:textColor">
@color/branco
</item>
<item name="android:background">
@color/vermelho
</item>
<item name="android:textStyle">italic</item>
</style>
</resources>


Notem que com a tag <color> atribuimos um nome ao valor da cor em hexadecimal no formato AARRGGBB. Já o estilo, é uma combinação de propriedades e valores para a mesma que serão aplicados de uma vez a um componente. No nosso caso, foram as propriedades: textSize, textColor, textStyle e background.

Agora é só utilizarmos esses carinhas no nosso arquivo de layout como abaixo.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<TextView
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="@string/msg_verde_e_branco"
android:background="@color/verde"
android:textColor="@color/branco"
android:textStyle="bold" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/msg_vermelho_e_branco"
style="@style/estiloExemplo" />
</LinearLayout>


O resultado, ficará como na imagem abaixo;



Notem que o primeiro TextField utiliza individualmente as cores que definimos no nosso arquivo de valores. Enquanto que o segundo, aplica várias propriedades de uma vez através da propriedade style.

4br4ços,
nglauber

sábado, 24 de julho de 2010

Capturando Eventos do Sistema com Android

Olá pessoal,

A facilidade da plataforma Android me encanta muito, nunca programei com nada tão bacana. Por isso, vou falar um pouquinho sobre como capturar eventos do sistema utilizando BroadcastReceivers. A classe android.content.BroadcastReceiver é utilizada para receber eventos de sistema (ou nossos próprios) e tratá-los em background. Ela não possui interface gráfica associada e possui um tempo de vida muito curto (cerca de 10 segundo), então se quisermos mostrar algum feedback pro usuário devemos delegar isso pra uma Activity.

Para implementarmos um BroadcastReceiver basta criar uma classe que a estenda, implementar o método onReceive(Context, Intent) e registrá-la com a tag <receiver> AndroidManifest.xml ou no código através do método context.registerReceiver(receiver, filtro). Para desativar podemos utilizar uma chamada para context.unregisterReceiver(receiver). Se quisermos enviar nossa própria mensagem de broadcast, podemos chamar o método sendBroadcast(Intent).

No nosso exemplo, capturaremos as mudanças de estado do telefone. Ou seja, quando for feita, recebida ou terminada uma ligação, nosso BroadcastReceiver entrará em ação.

Primeiro, crie a classe conforme abaixo:

public class InterceptCall extends BroadcastReceiver {

 public void onReceive(Context ctx, Intent it) {
   String estado = it.getStringExtra("state");
   String num = it.getStringExtra("incoming_number");
   String msg = null;
     
   if (estado.equals("RINGING")){
     msg = "O número "+ num +" está chamando.";
         
   } else if (estado.equals("OFFHOOK")){
     msg = "Em ligação.";
       
   } else if (estado.equals("IDLE")){
     if (num != null){
       msg = "Chamada não atendida de "+ num;
     } else {
       msg = "Chamada atendida, foi terminada.";
     }
   }
     
   Toast.makeText(ctx, msg, Toast.LENGTH_LONG).show();
 }
}
Com esse receiver, capturamos a mudança de estado do telefone em ligações. A Intent que o dispara tem dois extras: state e incoming_number. O primeiro indica o estado do telefone e o segundo o número do telefone de quem está ligando. O telefone vai para o estado RINGING (tocando) quando o telefone está recebendo a ligação. Ao atender ou fazer uma chamada o telefone vai para o estado OFFHOOK (fora do gancho). E por último, ao terminar uma ligação o telefone volta para o seu estado padrão, IDLE (parado).

Notem que nem OFFHOOK e nem IDLE quando não se atende a ligação, contam com o número do telefone que o chamou.

Para finalizar, basta registrarmos o nosso BroadcastReceiver no AndroidManifest.xml, dentro da tag <application>, conforme abaixo:

<receiver android:name="InterceptCall">
<intent-filter>
  <action
  android:name="android.intent.action.PHONE_STATE"/>
  <category
  android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
Também adicione a permissão para ler o estado da ligação no AndroidManifest.xml FORA DA TAG .
<uses-permission 
  android:name="android.permission.READ_PHONE_STATE"/>
Pronto! Agora é só brincar com os demais eventos do sistema.

4br4ç05,
nglauber

segunda-feira, 19 de julho de 2010

Ah! Se meu código falasse...

Olá povo,

Meu nobre colega Emerson Espinola está lançando o seu primeiro livro "Ah! if my Code could talk...". O livro em inglês é uma fábula que conta a trajetória fantástica, difícil e engraçada de um software a ser lançado para o Cliente. Se o seu código pudesse falar, acredito que iria escrever este livro :)

O primeiro capítulo está disponível gratuitamente. O preço para ler o restante é US$ 2,99 que dá praticamente R$ 5,00. Um valor bem simbólico não é? :)

Clique aqui para ler o primeiro capítulo e divirtam-se.

4br4ç05,
nglauber

terça-feira, 13 de julho de 2010

App Inventor for Android

Olá povo,

A Google não para de investir no Android (acho que já falei isso milhões de vezes). Dessa vez a novidade da compania é o App Inventor. Uma ferramenta simples e fácil para desenvolvimento de aplicações Android. Utilizando um esquema de "arrastar e soltar" - não só de componentes, mas também com eventos e ações - é possivel desenvolver aplicações utilizando simplesmente um browser com acesso a internet e um telefone Android. Essa estratégia visa atrair mais desenvolvedores e facilitar (ainda mais?) o desenvolvimento de aplicações para a plataforma.

Infelizmente até o momento eu não pude utilizar, mas achei a idéia muito legal, apesar de ser meio descrente nessas ferramentas "mágicas".

Mas como é da Google, sempre vale dar uma atenção maior ;)
Quem quiser dar um conferida, acessem: http://appinventor.googlelabs.com.



4br4ç05,
nglauber