sábado, 19 de outubro de 2013

Fala que eu te escuto!

Introdução
"Eu tenho tanto pra lhe falar, mas com palavras ~é difícil escrever~".

Com esta pequena "brincadeirinha" começo este post expondo uma dificuldade presente em diferentes devices e circunstâncias.

Escrever no device, muitas vezes é muito complicado e dependendo para o que você está escrevendo é pior ainda. Por exemplo, quando você precisa buscar um contato em sua lista telefonica enquanto dirige(não faça isso ok?! ;P), ou então escrever um texto no Hangout enquanto anda de onibus nessas maravilhosas ruas brasileiras... enfim... em diferentes casos, escrever algo enquanto o mundo em sua volta exige sua atenção é muito complicado.

O Google, sabendo dessa dificuldade, criou uma maneira simples e prática para resolvermos este problema. Só é preciso falar e o device irá entender e, então, transpor o mesmo em texto. Essa mágica acontece pela classe RecognizeIntent.

Agora sim, podemos somente falar e a "mágica" irá acontecer.
Vamos entender como funciona?

Explicando a RecognizeIntent
A RecognizeIntent é uma Intent onde é possível termos acesso a ferramenta de Speech do Android. Só precisamos disparar uma intent RecognizerIntent.ACTION_RECOGNIZE_SPEECH e uma tela irá se abrir para que o usuário fale.
Depois disso, será retornado uma lista de palavras/frases ordenado pelo nível de maior probabilidade para a menor de similaridade ao que foi falado.

Algumas propriedades que podem ser passadas pelo "intent.putExtra(...)":
  • RecognizerIntent.EXTRA_LANGUAGE_MODEL - Através dele você pode informar qual a lingua que deverá ser trabalhada. Por default é o "en-US" porém é possível informar "pt-BR" por exemplo. Caso você queira deixar que o próprio Android decida qual língua está sendo dita, você irá passar o valor "RecognizerIntent.LANGUAGE_MODEL_FREE_FORM";
  • RecognizerIntent.EXTRA_PROMPT - Aqui é possível passar um pequeno texto para ser apresentado junto a tela de Speech, algo que possa auxiliar o usuário na hora de falar o que precisa ser dito.
Exemplo
No código abaixo podemos ver como é chamado a Intent e depois como pegamos a lista de possíveis resultados.

Obs: A tela tem um botão na parte superior e abaixo uma lista onde serão apresentados a lista de possíveis resultados.

Segue o código comentado:

public class MainActivity extends Activity {

 private static final int RESULT_SPEECH = 1234;
 private ImageButton btnSpeak;
 private ListView listText;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  btnSpeak = (ImageButton) findViewById(R.id.btnSpeak);
  listText = (ListView) findViewById(R.id.listText);

  //Verifica se existe a RecognizerIntent.ACTION_RECOGNIZE_SPEECH na vesão do Device
  //Caso não exista, desabilitamos o botão e evitamos uma ActivityNotFoundException
  if (getPackageManager().queryIntentActivities(
    new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0).size() > 0) {

   btnSpeak.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
     //Criamos a intent
     Intent intent = new Intent(
       RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
     //Informamos que a linguagem será automática
     intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
       RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
     //Passamos o texto de auxílio ao usuário
     intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
       "Fale que eu te escuto Tutorial");
     //Chama a Activity passando o código identificador de result
     startActivityForResult(intent, RESULT_SPEECH);
    }
   });
  } else {
   btnSpeak.setEnabled(false);
  }
 }

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);

  //Verifica se o retorno é da nossa Intent
  if (requestCode == RESULT_SPEECH && resultCode == RESULT_OK && null != data) {
   //Passa a lista de possíveis resultados e passa para a lista de Textos por um Adapter genérico
   ArrayList listResults = data
     .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
   listText.setAdapter(new ArrayAdapter(this,
     android.R.layout.simple_list_item_1, listResults));
  }
 }
}


Alguns prints da App de exemplo funcionando:




Conclusão
Bem, podemos ver como é simples utilizarmos algo que é tão poderoso.

Usando esta ferramenta, podemos aumentar muito o poder das nossas apps e facilitar muito a vida de nossos usuários.
Use e abuse por que é 0800! hehe

Qualquer dúvida ou comentários, por favor, só escrever na parte de comentários.
Bons estudos.

[]~

segunda-feira, 30 de setembro de 2013

Autenticação usando API Google+

Introdução
No desenvolvimento mobile sempre existe a necessidade de trabalhar com usuários. Dessa forma, aumentamos as possibilidades de nossa App pois teremos o controle de dados específicos de cada usuário, podendo então, mostrar dados específicos de um usuário A e quando o usuário B for utilizar a App terá suas informações apresentadas. Além do mais, se mantermos esses dados online, podemos possibilitar ao usuário o acesso a essas informações em vários lugares.

Para se ter esse controle de usuário existem duas formas:
  • Fazer a manutenção do usuário, cadastrando o mesmo e criando toda uma infra específica para se trabalhar com o mesmo;
  • Usar uma API de autenticação de alguma rede social, seja ela Facebook, Twitter, Google+, etc.
Com as possibilidades dessas APIs de autenticação(que não só proporcionam a autenticação em si) não vemos muito a necessidade de usar esta primeira forma pois o custo para mante-la sería grande perto das facilidades das APIs do mercado hoje.

API Google+ Mobile
A Google criou o Google+ API Mobile onde podemos trabalhar com várias funcionalidades do Google+ como compartilhamento de informação, botão +1, iteração com seus círculos, entre outras coisas.

Entre estas outras coisas, está a autenticação, onde podemos fazer autenticação usando o usuário e senha do seu cadastro no Google sem que os dados fiquem expostos. Dessa forma podemos deixar o trabalho pesado para o Google e nos preocupamos em implementar as nossa App.

E é isso que iremos aprender a utilizar hoje. Vamos configurar nossa App para utilizar a Google+ API para realizar uma autenticação.

Configuração de Ambiente
Nos passos iniciais é necessário organizar a casa, criando a sua própria API no Console de APIs do Google e ativando a API do Google+ para poder utiliza-la. Então vamos seguir os passos abaixo:
  • Acesse o Console de APIs Google e crie seu projeto;
  • Selecione "Services" e procure por "Google+ API". Ative-o!
  • Agora vamos criar a nossa API de Acesso criando um ID para Client Mobile e, então, poder usar o OAuth 2.0 para autenticação.
    • Clique em "API Access" e depois em "Create an OAuth 2.0 client ID...";
    • Irá abrir uma janela solicitando algumas informações básicas sobre a App que você está trabalhando, para fins de estudo, vamos só escrever o "Product Name" e clicar em Next;
    • Irá aparecer os campos de configuração de Acesso. Marque a opção "Installed Application", depois a opção "Android";
    • Agora é necessário você informar o package da sua aplicação(atenção: É necessário que o package seja identico ao package da sua aplicação), também é necessário você colocar o SHA-1 da sua máquina por questões de segurança para acesso a API enquanto você está desenvolvendo;
      • Para criar o SHA-1 "keytool -exportcert -alias androiddebugkey -keystore <path-to-debug-or-production-keystore> -list -v" sendo que o eclipse, por padrão, utiliza o caminho "~/.android/debug.keystore" no Mac. Caso você crie em outro lugar, terá que alterar no Eclipse também.
    • Por fim, habilitar a opção Deep Link e clicar em "Create client ID".
Essa é a configuração inicial para trabalhar com a API do Google+. Agora estamos prontos para utilizar a estrutura disponibilizado pelo Google para autenticação entre outras funcionalidades.

Agora vamos para a criação e configuração do nosso projeto.

Criando e configurando a App Mobile

Primeiro temos que adicionar a biblioteca da API no nosso Workspace.
Essa biblioteca está disponível dentro do nosso SDK Android. Caso não encontra-lo em seu SDK, terá que baixá-lo através do "SDK Manager".
  • Com o Eclipse ADT aberto, vá em "File > Import > Existing Android Code Into Workspace > Browser";
  • Agora você irá selecionar o caminho "{caminho_sdk_android}/extras/google/google_play_services/libproject/google-play-services_lib" e depois clicar em Finish;
  • Com a biblioteca devidamente importada, agora você só precisa adiciona-la como uma biblioteca no projeto que você criou.

Obs: o único cuidado que você tem que tomar é que o seu projeto precisa, obrigatoriamente, trabalhar com o mesmo package que você informou lá na criação do ID Client para acesso a API.

Code is Live! o/
Vejamos um exemplo.
Neste exemplo, vamos fazer um Login e Logout usando a API. É algo simples porém de fácil entendimento para que o conceito seja aprendido.

Segue abaixo o código:

package br.com.guisj.signin;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.plus.PlusClient;

public class MainActivity extends Activity implements ConnectionCallbacks,
  OnConnectionFailedListener {

 private static final String TAG = "MainActivity";
 private static final int REQUEST_CODE_RESOLVE_ERR = 9000;

 private ProgressDialog mConnectionProgressDialog;
 private PlusClient mPlusClient;
 private ConnectionResult mConnectionResult;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  // Iniciacao de comunicacao com a Google+ API
  mPlusClient = new PlusClient.Builder(this, this, this)
    .setVisibleActivities("http://schemas.google.com/AddActivity",
      "http://schemas.google.com/BuyActivity").build();

  mConnectionProgressDialog = new ProgressDialog(this);
  mConnectionProgressDialog.setMessage("Signin...");

  findViewById(R.id.sign_in_button).setOnClickListener(
    onClickSignInButton());
  findViewById(R.id.sign_out_button).setOnClickListener(
    onClickSignOutButton());
 }

 /**
  * Metodo responsavel por disconectar o usuario da App
  * 
  * @return
  */
 private OnClickListener onClickSignOutButton() {
  return new OnClickListener() {

   @Override
   public void onClick(View v) {
    if (mPlusClient.isConnected()) {
     mPlusClient.clearDefaultAccount();
     mPlusClient.disconnect();
     mPlusClient.connect();
    }
   }
  };
 }

 /**
  * Metodo responsevel por solicitar a conexao de um usuario a sua App. Caso
  * sua app esteja sendo aberta pela primeira vez e nao tenha nenhum usuario
  * vinculado, sera aberta uma janela para que seja selecionado um usuario e
  * depois feito a liberacao de acesso aos dados do mesmo
  * 
  * @return
  */
 private OnClickListener onClickSignInButton() {
  return new OnClickListener() {

   @Override
   public void onClick(View v) {
    if (!mPlusClient.isConnected()) {
     if (mConnectionResult == null) {
      mConnectionProgressDialog.show();
     } else {
      try {
       mConnectionResult
         .startResolutionForResult(
           MainActivity.this,
           REQUEST_CODE_RESOLVE_ERR);
      } catch (SendIntentException e) {
       mConnectionResult = null;
       mPlusClient.connect();
      }
     }
    }
   }
  };
 }

 @Override
 protected void onStart() {
  super.onStart();
  // Quando iniciar a aplicacao, conectar o usuario cadastrado
  mPlusClient.connect();
 }

 @Override
 protected void onStop() {
  super.onStop();
  // Quando finalizar a aplicacao, desconectar o usuario cadastrado
  mPlusClient.disconnect();
 }

 /**
  * Metodo responsavel por chamar novamente a solicitacao de conexao caso
  * aconteca algum problema de comunicacao entre a API
  */
 @Override
 public void onConnectionFailed(ConnectionResult result) {
  if (mConnectionProgressDialog.isShowing()) {
   if (result.hasResolution()) {
    try {
     result.startResolutionForResult(this,
       REQUEST_CODE_RESOLVE_ERR);
    } catch (SendIntentException e) {
     mPlusClient.connect();
    }
   }
  }

  mConnectionResult = result;
 }

 /**
  * Depois que a conexao for bem sucedida mostrar um Toast com o email do
  * usuario logado Obs: necessario acrescentar ao AndroidManifest.xml
  * uses-permission android:name="android.permission.GET_ACCOUNTS"
  */
 @Override
 public void onConnected(Bundle connectionHint) {
  mConnectionProgressDialog.dismiss();
  String accountName = mPlusClient.getAccountName();
  Toast.makeText(this, accountName + " is connected.", Toast.LENGTH_LONG)
    .show();
 }

 @Override
 public void onDisconnected() {
  Log.d(TAG, "disconnected");
 }

 /**
  * Retorno da solicitacao de conexao a API
  */
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == REQUEST_CODE_RESOLVE_ERR && resultCode == RESULT_OK) {
   mConnectionResult = null;
   mPlusClient.connect();
  }
 }

}

Obs: foi acrescentado dois botões no layout, um para login e outro para logout, sendo que o para Login, foi usado o componente "com.google.android.gms.common.SignInButton" disponível pela própria Google+ API seguindo os padrões de UI da mesma. Também é necessário acrescentar a tag "<uses-permission android:name="android.permission.GET_ACCOUNTS" />" para ter acesso ao email do usuário.

Testando
Para você testar a sua aplicação. É necessário ter um device pois os emuladores padrões não tem a parte de configuração de Contas para que você possa configurar a sua conta Google. 

Porém, recentemente eu fiz um post sobre emuladores otimizados para testar suas Apps e, particularmente, o Genymotion emula um device, tendo a parte de configuração de contas. Dessa forma, é possível que você realize os seus testes utilizando este emulador, sem problemas.

Conclusão
Eu iria fazer uma explicação mais detalhada sobre a classe PlusClient porém o post já está bem grande. Posteriormente irei fazer mais posts sobre a biblioteca e as explicações irão aparecendo.

Bem, podemos ver que a API está ai, que não é difícil configura-la e muito menos utiliza-la.
Ela disponibiliza muitas outras funcionalidades, que se utilizadas da forma correta, irão acrescentar e muito qualidade a sua App auxiliando, até mesmo, a uma melhor colocação no Google Play.

Qualquer dúvida e sugestão, por favor, comente na parte de comentários.

Bons estudos.

[]~



segunda-feira, 23 de setembro de 2013

Você conhece o Application do Android?

Introdução
Quando vamos desenvolver aplicativos, seja qual for a linguagem, sempre existe o momento em que precisamos trabalhar com variáveis globais, manter o usuário logado, salvar arquivos em cache, entre outros exemplos em que o conteúdo sería acessível a aplicação toda.

Para isso, existe um padrão chamado Singleton que possibilita o acesso de uma variável estática onde é possível trabalhar com essas situações.

Porém, no Android, é possível trabalhar com uma classe chamada Application onde se mantem ativa e acessível pela aplicação enquanto esta estiver acessível, com a vantagem de você ter controle de quando a aplicação foi finalizada ou alguma configuração alterada, entre outras coisas.

Dessa forma podemos ter controle total do conteúdo que estamos mantendo globalmente, por exemplo, caso eu tenha algumas imagens mantidas em cache, quando a aplicação for finalizada, eu podería forçar a limpeza da memória eliminando as imagens da mesma, caso não fizesse isso, o device poderá ficar a espera do Garbage de memória do Android podendo ter alguma demora dependendo da situação.

Bem, vamos a algumas explicações e depois a prática! o/

O que é o tal do Singleton?
O Singleton nada mais é do que um padrão onde garante uma única instância de uma classe para a aplicação toda, ou seja, a mesma classe não poderá ser iniciada duas(02) vezes na mesma aplicação.

Usando o padrão Singleton é possível trabalhar com variáveis globais ou então centralizar o trabalho de conexão ao banco ou até mesmo manter os dados do usuário logado, entre outras coisas.

Segue link(Wikipédia) com um resumo e exemplos de várias linguagens usando o padrão Singleton.

Desvendando o Application
Para se trabalhar com o Application não é nada complicado, segue os passos:
  • Criar uma classe que extenda da classe android.app.Application;
  • Adicionar essa classe a propriedade name da tag <application> do AndroidManifest.xml;
  • Acessar em qualquer Activity da sua aplicação atraves do comando getApplicationContext();
Viu como é simples? É perfeitamente possível trabalhar com o padrão Singleton substituindo essa configuração toda, porém perdemos o controle do status atual da aplicação. Essa sería a grande vantagem de usar o Application.
Segue abaixo alguns métodos úteis do Application:
  • onCreate()
    • Chamado quando a aplicação é iniciada, antes da Activity, Service ou Objetos receptores sejam criados;
  • onTerminate()
    • Esse método somente usado para processos de ambientes emulados;
  • onConfigurationChanged(Configuration newConfig)
    • Chamado pelo sistema quando a configuração do device mudou enquanto a aplicação está rodando;
  • onTrimMemory(int level)
    • Chamado quando o sistema determina que é uma boa hora para limpar processos desnecessários em memória;
  • onLowMemory()
    • Ele é chamado quando o sistema roda com pouca memória e processos tenham que cortar seu consumo de memória;

Podemos ver, com esses métodos, que temos praticamente total controle do que acontece durante a aplicação. Dessa forma podemos expandir muito as possibilidades da nossa Aplicação.

Vamos a prática? o/
Vamos fazer um exemplo simples, onde iremos salvar uma mensagem no Application e depois buscar a mesma e apresentar na tela usando o Toast. Algo simples mas que mostra a funcionalidade em si.

1- Depois do seu projeto criado, vamos criar uma classe chamada AppApplication que extenda de "android.app.Application". Também criar uma variável chamada "message" e encapsula-la.
import android.app.Application;

public class AppApplication extends Application {
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

2- Depois vamos atualizar o nosso AndroidManifest.xml, incluindo a informação "nome-pacote-application+nome-classe-application" na propriedade "name" da tag <application>;

3- Agora vem a alteração da sua Activity. Segue abaixo o código da Activity:
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ((Button)findViewById(R.id.btnMessage)).setOnClickListener(onClickMessage());
        ((Button)findViewById(R.id.btnAlertMessage)).setOnClickListener(onClickAlertMessage());
    }

    /**
     * Quando clicar no botão Salvar Mensagem, irá salvar a mensagem no Application
     * @return View.OnClickListener
     */
    private View.OnClickListener onClickMessage() {
        return new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Pega a mensagem do EditText
                String message = ((EditText)findViewById(R.id.etMessage)).getText().toString();
                // Seta a mensagem no AppApplication
                ((AppApplication)getApplicationContext()).setMessage(message);
                ((EditText)findViewById(R.id.etMessage)).setText("");
                Toast.makeText(MainActivity.this, "Mensagem Salva no Application", Toast.LENGTH_LONG).show();
            }
        };
    }

    /**
     * Quando clicar no botão Alerta Mensagem, irá buscar a mensagem do Application e mostrar em um Toast
     * @return View.OnClickListener
     */
    private View.OnClickListener onClickAlertMessage() {
        return new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Pega a mensagem salva no AppApplication
                String message = ((AppApplication)getApplicationContext()).getMessage();
                // Mostra a mensagem no Toast
                Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
            }
        };
    }
}

Obs: Eu criei no layout hum(01) EditText para escrever a mensagem e dois(02) botões para salvar e mostrar a mensagem.
Conclusão e documentação
Viu como é simples? É possível fazer muito mais como manter o usuário logado entre outras coisas. A minha intensão com o exemplo é mostrar como é simples a utilização do Application.

Para saber mais sobre a classe Application, segue a documentação da mesma: link

Bem, essa é mais uma dica bacana para quem está conhecendo o universo Android.
Espero que tenha gostado e caso tenha dúvidas ou sugestões, por favor, comente no campo de comentários.

Bons estudos,

[]~

sexta-feira, 20 de setembro de 2013

Desvendando o AsyncTask

Introdução

Quando vamos desenvolver uma aplicação mobile, em algum momento nós sempre precisamos implementar algum tipo de requisição de alguma informação, seja ela online ou na própria base de dados local do Android.

Sabemos que, muitas vezes, esse tipo de requisição pode levar algum tempo pois não depende somente da aplicação, do seu código. Sempre irá existir algum delay realizando uma requisição.

O grande problema desse tipo de requisição é que a nossa aplicação, no momento que é iniciada, recebe a Thread principal do Android (Thread reponsável pelo UI) para trabalhar e quando usamos, indevidamente, essa Thread para realizar uma requisição, pode, muitas vezes, travar a aplicação, ou até mesmo a requisição ser cancelada pelo próprio Android para evitar problemas maiores com o funcionamento do S.O.

Para resolver esse problema, existe uma Classe abstrata chamada AsyncTask onde tem a finalidade de realizar a requisição em uma Thread separada no background do Android deixando a Thread principal livre para continuar trabalhando. Dessa forma, é possível realizar requisições sem comprometer o desempenho do S.O.

O que é o AsyncTask?
Como dito acima, o AsyncTask é uma Classe Abstrata utilizada para execução de metodos em uma thread background, deixando livre a Thread UI (Thread Principal).

A utilização da AsyncTask é para  processos de poucos segundos, caso seja necessário realizar processamentos mais demorados, é aconcelhável utilizar as opções de APIs presentes no package "java.util.concurrent", como indicado na documentação.

Quais são os métodos principais?

Essas métodos descritos abaixo, em nenhum momento, podem ser chamados diretamente. Eles são executados em uma ordem específica e cada um tem sua finalidade, vamos conhece-los?
  • onPreExecute()
    • Este é o primeiro método chamado quando executado o execute(Params...);
    • Este método é utilizado, entre outras coisas, para realizar as configurações do processo e/ou ativar algum Status Loader indicando que está acontecendo algum processo.
  • doInBackground(Params...)
    • Este método já é chamado após o método onPreExecute() ser finalizado. É nele que o processo será realizado em uma thread separada da Thread Principal;
    • Aqui você também poderá chamar o método publishProgress(Progress...) informando o valor de andamento do seu processo, o mesmo, quando chamado, irá executar o onProgressUpdate(Progress...) passando esse valor que você informou no publishProgress(Progress...);
    • Também é aconcelhável que, no método, seja validado sempre o método isCancelled() (este método retornará TRUE caso sejá chamado o método cancel()) para, caso retornar TRUE, você realize a parada do seu processamento.
  • onProgressUpdate(Progress...)
    • Este método é chamado quando o método publishProgress(Progress...) for acionado;
    • Ele é usado para dar um feedback do andamento do processo. Podemos, aqui, atualizar o status de uma barra de progresso, por exemplo;
    • Ele não tem um timeout, pois o método doInBackground(Params...) continua com seu processamento em outra thread, não sendo interferido pelo processamento do onProgressUpdate(Progress...).
  • onPostExecute(Result)
    • Por fim, este método é chamado logo após o término do método onInBackground(Params...);
    • Ele recebe o retorno do onInBackground(Params...). A partir do tipo configurado como retorno na configuração da Classe. É aqui que você terá a oportunidade de trabalhar com o Parâmetro recebido, por exemplo, caso você tenha feito o download de uma image, aqui você irá receber os bytes desta imagem e irá coloca-la no seu ImageView.

Como utilizar o AsyncTask?

Para utilizar o AsyncTask, é muito simples. Você só precisa criar uma classe e extender do AsyncTask como abaixo:
    
private class ConsultaCEPCorreios extends AsyncTask<Params, Progress, Result>
  • Params: Tipo do Objeto que será passado por parâmetro, caso não precise mandar algum parâmetro, colocar colo "Void";
  • Progress: Tipo do Objeto usado para informar o progresso do processo, utilizados no método publishProgress(Progress...) e onProgressUpdate(Progress...);
  • Result: Tipo do Objeto de Retorno. Usado no método onInBackground(Params...) como sendo o seu retorno e o onPostExecute(Result).
Depois de configurado os métodos específicos para poder trabalhar com o AsyncTask, você só precisa chamar o método execute(Params...) para que o método seja executado.

Quando foi criado o AsyncTask, o mesmo era executado sempre em uma fila no background, sempre esperando um AsyncTask ser finalizado para depois outro ser executado. A partir da versão 1.6 do android, ele se tornou assíncrono, não existindo mais essa fila no background. Porém, a partir da versão 3.0 a fila voltou a ser o padrão para evitar erros de concorrência.
Caso seja necessário executar uma lista de AsyncTask assíncronas, será necessário trabalhar com o método executeOnExecutor(Executor, Params...) presente na classe AsyncTask.

É possível, a qualquer momento, chamar o método getStatus() onde irá retornar o status atual da execução do processo(AsyncTask.Status).

A qualquer momento é possível chamar o método cancel(boolean mayInterruptIfRunning) para executar o cancelamento do processo. Passando TRUE por parâmetro, o cancelamento será imediato sendo cancelado a Thread que está executando o mesmo, caso for FALSE, é permitido o término do processo em questão para depois finaliza-la. O concelho é que no seu processo seja sempre verificado o método isCancelled() para que o seu processo seja finalizado da melhor forma.

Depois de chamar o método execute(Params...) você também pode chamar o método get()/get(long timeout, TimeUnit unit) para pegar o Result do processo realizado. Este método é útil caso você não vá utilizar o onPostExecute(Result) para dar um destino para o Result. Quando chamado, o método fica aguardando o final do processamento da AsyncTask para depois retornar o valor. É possível configurar um valor de tempo para o timeout passando o mesmo por parâmetro, para, caso o processamento demore muito, seja cancelado o get.


Vamos ao que interessa?

Segue o link do github de um simples exemplo que fiz no Android Studio utilizando o AsyncTask e abaixo estou colocando somente o código da classe que foi implementado para realizar a busca de um endereço a partir de um cep.
    
private class ConsultaCEPCorreios extends AsyncTask<String, Integer, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            baseProgressBar.setVisibility(View.VISIBLE);
        }

        @Override
        protected String doInBackground(String... params) {
            String result = "";
            String url = "http://cep.republicavirtual.com.br/web_cep.php?formato=json&cep="+params[0];
            HttpClient httpClient = new DefaultHttpClient();
            try {
                HttpResponse response = httpClient.execute(new HttpGet(url));
                result += getStringFromInputStream(response.getEntity().getContent());
            } catch (IOException e) {
                Log.e("TAG_ASYNC_TASK", e.getMessage());
                baseProgressBar.setVisibility(View.INVISIBLE);
            }
            return result;
        }

        @Override
        protected void onPostExecute(String s) {
            baseProgressBar.setVisibility(View.INVISIBLE);
            tvEndereco.setText(s);
        }

        private String getStringFromInputStream(InputStream is) {
            BufferedReader br = null;
            StringBuilder sb = new StringBuilder();
            String line;
            try {
                br = new BufferedReader(new InputStreamReader(is));
                while ((line = br.readLine()) != null) {
                    sb.append(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (br != null) {
                    try {
                        br.close();
                    } catch (IOException e) {
                        Log.e("ASYNC_TASK", e.getMessage());
                    }
                }
            }
            return sb.toString();
        }
    }
Adianto que o código não está seguindo as boas práticas do desenvolvimento Android, e tem como única finalidade mostrar a utilidade do AsyncTask.

Só de olhar o código, já podemos ver vários trechos que vimos no texto acima. Acredito que se você der uma boa olhada no código do exemplo em complemento a documentação, irá tirar de uma vez por todas suas dúvidas de como utilizar o AsyncTask.

Qual material relevante para estudo sobre o AsyncTask?
Bem pessoal, o post ficou grande mas acredito que conseguimos espalhar bem os pontos do AsyncTask.
Acredito que agora, no mínimo, suas dúvidas sobre ele tenham dimínuido.

Caso surja alguma dúvida ou mesmo algum ponto que deixei de lado ou mesmo eu tenha me equivocado, por favor, o campo de comentários está logo aqui em baixo! ;)

Tenham bons estudos, grande abraço

[]~

segunda-feira, 9 de setembro de 2013

Lançamento ActionBarCompat

Olá,

Recentemente o Google lançou uma atualização da biblioteca de compatibilidade do android incluindo o novo ActionBarCompat onde proporcionará a utilização do ActionBar a partir da versão 2.1 do Android.

Até então, só era possível trabalhar com ActionBar nas versões a partir da 3.0(level 11), ou então, caso necessita-se utilizar para uma versão mais antiga, existe à opção ActionBarSherlock que é uma biblioteca que parte da biblioteca de compatibilidade do Google e implementa o ActionBar para as versões inferiores ao 3.0.

Sem mais delongas, segue abaixo um passo-a-passo simples de como desenvolver uma app android usando o ActionBarCompat.

1. Criar projeto para exemplo no Android Studio:


2. Depois do projeto criado, você irá abrir a sua activity principal, no meu caso MainActivity, e irá alterar a classe para extender a classe "android.support.v7.app.ActionBarActivity":
3. Alterado a classe principal, iremos ajustar o arquivo styles.xml da pasta "res/values/styles.xml alterando a configuração de "parent" do style AppBaseTheme de "android:Theme.Light" para "@style/Theme.AppCompat.Light":

4. Depois disso é só testar em um emulador configurado com a versão 2.1 do android e ver se está funcionando corretamente:

Esse passo-a-passo é simples e só fiz para mostrar como é fácil implementar o ActionBarCompat porém não dei explicação alguma como ele funciona entre outros detalhes.
Então, a princípio segue o link(inglês) da documentação do mesmo para maiores esclarecimentos.
Também segue abaixo um vídeo(inglês) com uma introdução sobre o ActionBarCompat.

Futuramente irei fazer um post mais detalhado sobre esse novo componente de compatibilidade e de outros também.

Tenha um ótimo estudo e bons works Android. o/

[]~

Dica: Emuladores otimizados para Android

Todo desenvolvedor Android sabe que, para configurar o emulador otimizado e o mesmo ter uma boa performace, é algo realmente complexo e da uma dor de cabeça.

Por isso hoje trago duas dicas que, para alegria da nação, irão resolver este problema de configuração. Segue abaixo:
Como no site oficial mostra, ele tem como finalidade disponibilizar emuladores Android para Testes e Demonstrações.
  • Requisitos: Além de umas configurações básicas de hardware, ele exige a instalação do VirtualBox, ou seja, caso não tenho o mesmo instalado não irá funcionar.
  • Instalação: Para instalar, é muito simples, você só terá que fazer um cadastro gratuito no site e seguir os passos de instalação dependendo do SO que você usa.

O programa tem como premissa tornar possível jogar jogos e rodar aplicativos Android em Desktops.
  • Requisitos: Usar SO Windows ou Mac, além de algumas configurações básicas.
  • Instalação: Para instalar é muito simples sem pré-requisitos para instalação de outros programas.
Tanto usando Genymotion quanto BlueStacks será possível utilizar para o desenvolvimento.

Para utiliza-los, você só precisa inicia o mesmo e depois, quando for rodar sua aplicação no Eclipse, selecionar o mesmo na opção de devices disponíveis.

Em um futuro próximo eu irei criar um tutorial mostrando como trabalhar com cada um.
Boa sorte a todos e bons códigos.

[]~