Código PHP para rastreamento de objetos dos Correios

Fala galera!
Recebemos recentemente uma notificação dos Correios referente a uma atualização do Sistema de Rastreamento de Objetos – SRO. A versão antiga não funciona mais, e somos redirecionados para uma página com o aviso sobre essa atualização.
Codificamos então uma maneira rápida e prática para realizar as consultas de acordo com as novas diretivas utilizando código PHP para rastreamento de objetos dos Correios.

Código php para rastreamento de objetos dos correiosCódigo PHP para rastreamento de objetos dos Correios

Antigamente, poderíamos consultar o andamento das entregas enviando os dados necessários através do método GET. Porém, a nova versão funciona com o método POST. O link de destino também foi atualizado: o novo endereço é https://www2.correios.com.br/sistemas/rastreamento/resultado_semcontent.cfm.

POST ATUALIZADO

Galera, o Correios atualizou o local do script de pesquisa, sendo agora OBRIGATÓRIO consultar pelo HTTPS, e não HTTP. Os códigos abaixo foram corrigidos!

Vamos ao código PHP completo:

$post = array('Objetos' => 'CODIGO_RASTREAMENTO');
// iniciar CURL
$ch = curl_init();
// informar URL e outras funções ao CURL
curl_setopt($ch, CURLOPT_URL, "https://www2.correios.com.br/sistemas/rastreamento/resultado_semcontent.cfm");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, http_build_query($post));
// Acessar a URL e retornar a saída
$output = curl_exec($ch);
// liberar
curl_close($ch);
// Imprimir a saída
echo $output;

Explicando o código:

$post = array('Objetos' => 'CODIGO_RASTREAMENTO');

Neste trecho, vamos criar um array com o índice “Objetos” que é obrigatório. A ele atribuímos o código de rastreamento ‘CODIGO_RASTREAMENTO’ (substitua pelo código que deseja consultar).

$ch = curl_init();

Aqui vamos iniciar a biblioteca CURL, que nos permite consultar acessar outras páginas sem sair do local atual.

curl_setopt($ch, CURLOPT_URL, "https://www2.correios.com.br/sistemas/rastreamento/resultado_semcontent.cfm");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, http_build_query($post));

Setamos então algumas opções na CURL:

  • CURLOPT_URL: o endereço para onde vamos enviar os dados. Neste caso passamos a URL do sistema de rastreamento de objetos dos correios.
  • CURLOPT_RETURNTRANSFER: definimos TRUE para recuperarmos o retorno da página.
  • CURLOPT_POSTFIELDS: é aqui onde informamos os dados que serão enviados. Note que é obrigatório o uso da função http_build_query do PHP para formatação correta dos dados.
$output = curl_exec($ch);

Vamos então executar a ação e gravar o retorno na variável $output.

curl_close($ch);

Não se esqueça de fechar a sessão CURL para liberar todos os recursos. A variável $ch também é deletada.

echo $output;

Por fim exibimos o retorno na tela através de um “echo”.

Considerações

Utilizando este código, você terá em sua tela o retorno exatamente como o site dos Correios exibe. Caso queira formatar a sua maneira, deverá utilizar técnicas para pegar apenas os dados que deseja e salvar em suas respectivas variáveis. Um bom exemplo é com DOMDocument.

Até mais!

Como criar uma Activity no Android

Fala galera! Hoje vamos ver como criar uma Activity no Android.

Basicamente, Activity é uma classe que gerencia uma UI (interface com o usuário). Todas as aplicações Android começam por uma Activity. Ou seja, quando um aplicativo é iniciado, sua Activity principal é lançada.

Se você ainda não viu o último tutorial da série, clique no link a seguir: exibir mensagens no Android. Se você ainda continua é preguiçoso e apenas baixou o projeto, importe-o para sua workspace. Para tal, vá em File → Import… → Existing Projects into Workspace, dentro de General.

Ciclo de vida de uma Activity

Antes de começar, é muito importante conhecer o funcionamento de uma Activity. Observe o diagrama abaixo:

Como criar uma Activity no Android

A partir deste diagrama, fica mais fácil de entender o funcionamento. Implicitamente, ele introduz os estados que uma Activity pode assumir. Veja a próxima imagem:

Como criar uma Activity no Android

Segue uma breve explicação de cada método nativo da classe Activity:

  • onCreate(): É a primeira função a ser executada quando uma Activity é lançada. Geralmente é a responsável por carregar os layouts XML e outras operações de inicialização. É executada somente uma vez durante a “vida útil” da Activity.
  • onStart(): É chamada imediatamente após a onCreate() – e também quando uma Activity que estava em background volta a ter foco.
  • onResume(): Assim como a onStart(), é chamada na inicialização da Activity (logo após a própria onStart()) e também quando uma Activity volta a ter foco. Qual a diferença entre as duas? A onStart() só é chamada quando a Activity não estava mais visível na tela e volta a ter o foco, enquanto a onResume() sempre é chamada nas “retomadas de foco”.
  • onPause(): É a primeira função a ser invocada quando a Activity perde o foco (ou seja, uma outra Activity vem à frente).
  • onStop(): Análoga à onPause(), só é chamada quando a Activity fica completamente encoberta por outra Activity (não é mais visível).
  • onDestroy(): A última função a ser executada. Depois dela, a Activity é considerada “morta” – ou seja, nao pode mais ser relançada. Se o usuário voltar a requisitar essa Activity, outro objeto será contruído.
  • onRestart(): Chamada imediatamente antes da onStart(), quando uma Activity volta a ter o foco depois de estar em background.

Como criar uma Activity

Para criar uma nova Activity, são três passos básicos: criar o layout (como já visto neste link), criar a classe que estende a classe Activity, declarar essa nova classe no AndroidManifest.xml.

Vamos então alterar nosso projeto, de forma que a primeira tela seja apenas para listar os carros cadastrados no banco de dados.

Primeiramente, vamos alterar o arquivo activity_main.xml para que ele exiba somente a lista, e também um botão para cadastrar novos veículos.
PS: Não se esqueça de criar a constante “cadastrar” no arquivo /res/values/strings.xml.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="vertical" >
 
   <Button
       android:id="@+id/cadastrar"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/cadastrar" />
 
   <ListView
       android:id="@+id/lista"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" >
   </ListView>
 
</LinearLayout>

Vamos atualizar nossa Activity principal ListaCarros, fazendo as adaptações para o novo layout.

public class ListaCarros extends ActionBarActivity {
                Button cadastrar;
                ListView lista;
                List listaCarros;
                ArrayAdapter<String[]> adaptador;
                Dados dados;
                Cursor carros;
                @Override
                protected void onCreate(Bundle savedInstanceState) {
                               super.onCreate(savedInstanceState);
                               setContentView(R.layout.activity_main);
                               cadastrar = (Button) findViewById(R.id.cadastrar);
                               lista = (ListView) findViewById(R.id.lista);
                               listaCarros = new ArrayList();
                               adaptador = new Adaptador();
                               dados = new Dados(this);
                               cadastrar.setOnClickListener(new OnClickListener() {
                                               @Override
                                               public void onClick(View v) {
                                                               Intent i = new Intent(ListaCarros.this, CadastrarCarros.class);
                                                               startActivity(i);
                                               }
                               });
                               lista.setAdapter(adaptador);
                               atualizaLista();
                }
                @Override
                public boolean onCreateOptionsMenu(Menu menu) {
                               // Inflate the menu; this adds items to the action bar if it is present.
                               getMenuInflater().inflate(R.menu.main, menu);
                               return true;
                }
                @Override
                public boolean onOptionsItemSelected(MenuItem item) {
                               // Handle action bar item clicks here. The action bar will
                               // automatically handle clicks on the Home/Up button, so long
                               // as you specify a parent activity in AndroidManifest.xml.
                               int id = item.getItemId();
                               if (id == R.id.action_settings) {
                                               return true;
                               }
                               return super.onOptionsItemSelected(item);
                }
                // Classe responsável por criar um adaptador para as linhas do ListView
                class Adaptador extends ArrayAdapter {
                               Adaptador() {
                                               // Chama o construtor da classe ArrayAdapter, passando a classe
                                               // atual,
                                               // um layout padrão e a lista dos itens que serão adicionados.
                                               super(ListaCarros.this, android.R.layout.simple_list_item_1,
                                                                              listaCarros);
                               }
                               // Vamos sobrepor o método getView, pois é aqui que vamos chamar nosso
                               // layout
                               // customizado
                               @Override
                               public View getView(int position, View convertView, ViewGroup parent) {
                                               // Instanciando os itens necessários: linha atual, classe
                                               // Armazenador
                                               // e o conteúdo que será inserido
                                               View linha = convertView;
                                               Armazenador armazenador = null;
                                               final String[] item_linha = (String[]) listaCarros.get(position);
                                               // Neste trecho é que chamaos nosso layout. Usamos o método
                                               // getLayoutInflater()
                                               // e depois indicamos o layout. Também já inserimos os dados na
                                               // posição atual
                                               // através da classe Armazenador.
                                               if (linha == null) {
                                                               LayoutInflater inflater = getLayoutInflater();
                                                               linha = inflater.inflate(R.layout.linha_carro, null);
                                                               armazenador = new Armazenador(linha, position);
                                                               linha.setTag(armazenador);
                                               } else {
                                                               armazenador = (Armazenador) linha.getTag();
                                               }
                                               // Agora sim, vamos jogar os dados nos seus respectivos campos do
                                               // layout da linha
                                               armazenador.popularFormulario((String[]) listaCarros.get(position));
                                               // Retorno obrigatório do método
                                               return linha;
                               }
                }
                // Classe responsável por "jogar" os dados nos campos corretos
                class Armazenador {
                               // Declaração dos campos
                               private TextView nomeCarro = null;
                               private TextView anoCarro = null;
                               private TextView corCarro = null;
                               // Construtor que instancia os campos
                               Armazenador(View linha, int position) {
                                               nomeCarro = (TextView) linha.findViewById(R.id.nomeCarro);
                                               anoCarro = (TextView) linha.findViewById(R.id.anoCarro);
                                               corCarro = (TextView) linha.findViewById(R.id.corCarro);
                               }
                               // Método para "jogar" os textos nos respectivos campos
                               void popularFormulario(String[] c) {
                                               nomeCarro.setText(c[0]);
                                               anoCarro.setText(c[1]);
                                               corCarro.setText(c[2]);
                               }
                }
                private void atualizaLista() {
                               adaptador.clear(); // Limpa o adaptador para evitar duplicados
                               carros = dados.obterTodos();
                               carros.moveToFirst(); // Move o ponteiro para o primeiro registro
                               while (!carros.isAfterLast()) {
                                               String veiculo = carros.getString(1).toString();
                                               String ano = carros.getString(2).toString();
                                               String cor = carros.getString(3).toString();
                                               String id = String.valueOf(carros.getInt(0));
                                               String[] c = { veiculo, ano, cor, id }; // Cria um array com os
                                                                                                                                                                                                            // dados do carro
                                               adaptador.add(c); // Adiciona no ArrayList
                                               carros.moveToNext(); // Move o ponteiro para o próximo registro
                               }
                               adaptador.notifyDataSetChanged(); // Atualiza a lista
                }
}

Vamos então criar nosso layout para cadastrar os novos veículos. Vamos chama-lo de cadastrar.xml.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="vertical" >
 
   <EditText
       android:id="@+id/veiculo"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:hint="@string/veiculo" >
 
       <requestFocus />
   </EditText>
 
   <EditText
       android:id="@+id/ano"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:ems="10"
       android:hint="@string/ano" />
 
   <EditText
       android:id="@+id/cor"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:ems="10"
       android:hint="@string/cor" />
 
   <Button
       android:id="@+id/salvar"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/salvar" />
 
   <Button
       android:id="@+id/listar"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/listar" />
 
</LinearLayout>

Como criar uma Activity no Android

E agora, vamos criar a nova Activity CadastrarCarros, que será a nova responsável por inserir os registros no banco de dados.

public class CadastrarCarros extends ActionBarActivity {
                EditText veiculo, ano, cor;
                Button salvar, listar;
                Dados dados;
                @Override
                protected void onCreate(Bundle savedInstanceState) {
                               super.onCreate(savedInstanceState);
                               setContentView(R.layout.cadastrar);
                               veiculo = (EditText) findViewById(R.id.veiculo);
                               ano = (EditText) findViewById(R.id.ano);
                               cor = (EditText) findViewById(R.id.cor);
                               salvar = (Button) findViewById(R.id.salvar);
                               listar = (Button) findViewById(R.id.listar);
                               dados = new Dados(this);
                               salvar.setOnClickListener(new OnClickListener() {
                                               @Override
                                               public void onClick(View v) {
                                                               dados.inserir(veiculo.getText().toString(), ano.getText()
                                                                                                              .toString(), cor.getText().toString());
                                                                              Toast.makeText(CadastrarCarros.this,
                                                                                                              "Registro inserido com sucesso!",
                                                                                                              Toast.LENGTH_SHORT).show();
                                                               veiculo.setText(null);
                                                               ano.setText(null);
                                                              cor.setText(null);
                                               }
                               });
                               listar.setOnClickListener(new OnClickListener() {
                                               @Override
                                               public void onClick(View v) {
                                                               Intent i = new Intent(CadastrarCarros.this, ListaCarros.class);
                                                               startActivity(i);
                                               }
                               });
                }
                @Override
                public boolean onCreateOptionsMenu(Menu menu) {
                               // Inflate the menu; this adds items to the action bar if it is present.
                               getMenuInflater().inflate(R.menu.main, menu);
                               return true;
                }
                @Override
                public boolean onOptionsItemSelected(MenuItem item) {
                               // Handle action bar item clicks here. The action bar will
                               // automatically handle clicks on the Home/Up button, so long
                               // as you specify a parent activity in AndroidManifest.xml.
                               int id = item.getItemId();
                               if (id == R.id.action_settings) {
                                               return true;
                               }
                               return super.onOptionsItemSelected(item);
                }
}

Como criar uma Activity no Android

E não podemos nos esquecer de declarar a nova Activity no arquivo AndroidManifest.xml.

<activity android:name="br.com.yesbr.tutorial.CadastrarCarros" ></activity>

Rode a aplicação e veja como ficou.

E no final das contas, como criar uma Activity no Android?

Para criar uma nova Activity, devemos instanciar um objeto da classe Intent, passando como parâmetros o contexto atual da aplicação e a nova classe que será chamada. As ações foram inseridas nas ações dos botões Cadastrar na classe ListaCarros e Salvar na classe CadastrarCarros. Depois, chamamos o método startActivity(), passando como parâmetro o objeto Intent que foi criado.

Considerações Finais

Agora que já sabemos como criar várias Activities, podemos separar as ações da nossa aplicação em várias telas. Porém, ainda não foi criada a parte de edição dos dados, e iremos ver essa etapa no próximo tutorial, quando veremos como passar parâmetros para uma Activity.

Baixe o projeto atual aqui.

Falou, galera!

Exibir mensagens no Android

Fala galera! No tutorial de hoje vamos aprender a exibir mensagens no Android.

Se você ainda não viu o último tutorial da série, clique no link a seguir: manipulando dados do banco no Android. Se você ainda continua é preguiçoso e apenas baixou o projeto, importe-o para sua workspace. Para tal, vá em File → Import… → Existing Projects into Workspace, dentro de General.

Exibir mensagens no Android

Vamos exibir mensagens no Android sempre que uma ação for executada em nosso projeto: cadastro, alteração ou exclusão de registros do banco. Para tal, vamos estudar duas classes: AlertDialog e Toast.

Toast exibe uma mensagem rápida ao usuário em uma pequena janela. Ela fica visível por um tempo determinado, e depois desaparece. Não tem interação com o usuário, sendo utilizado apenas para informações rápidas.

Exibir mensagens no Android

AlertDialog nada mais é que uma caixa de diálogo. Ela não ocupa toda a tela e é normalmente utilizada para eventos modais, requerendo uma interação por parte dos usuários antes de prosseguir. Ele pode exibir um título, até três botões, uma lista de itens selecionáveis, ou algum layout personalizado.

Exibir mensagens no Android

Como você já deve ter percebido, um AlertDialog já foi implementado em nosso projeto. Ao clicar em algum item da lista de carros, uma caixa de diálogo aparece na tela questionando qual ação deverá ser tomada. Então, vamos implementar a classe Toast. Ela é muito simples, e pode ser implementada com apenas uma linha de código.

Primeiro, vamos adicionar logo após o método inserir() na ação do botão Salvar.

Toast.makeText(ListaCarros.this, "Registro inserido com sucesso!", Toast.LENGTH_SHORT).show();

E também depois do método alterar() no mesmo botão.

Toast.makeText(ListaCarros.this, "Registro alterado com sucesso!", Toast.LENGTH_SHORT).show();

E por último, após o método excluir() no nosso AlertDialog.

Toast.makeText(ListaCarros.this, "Registro inserido com sucesso!", Toast.LENGTH_SHORT).show();

E agora, execute o código e realize alguma das três operações para ver o resultado.

Exibir mensagens no Android

Considerações Finais

Nosso projeto está simples, porém bem funcional. A classe Toast é bem simples de se implementar, sem necessidade de conhecimento mais aprofundado.
No próximo tutorial, vamos aprender a criar novas telas no Android.

Baixe o projeto atual aqui.

Até mais!

Manipulando dados do banco no Android

Fala, galera!

Hoje vamos continuar o tutorial anterior: vamos aprender a alterar e excluir registros, manipulando dados do banco no Android.

Se você ainda não viu o último tutorial da série, clique no link a seguir: banco de dados em Android. Se você continua é preguiçoso e apenas baixou o projeto, importe-o para sua workspace. Para tal, vá em File → Import… → Existing Projects into Workspace, dentro de General.

Manipulando dados do banco no Android

No tutorial anterior modificamos nosso projeto para que os dados fossem salvos diretamente no SQLite. Os princípios para alterar e excluir os dados são os mesmos: o próprio SQLite possui métodos próprios para gerenciar os dados, e são bem simples de entender.

Vamos adicionar dois novos métodos na nossa classe Dados. Um será responsável por alterar os dados, e o outro fará a exclusão. O método para alterar receberá como parâmetros os dados do carro em questão, além do seu ID. Já o método de exclusão receberá apenas o ID.

public void alterar(String veiculo, String ano, String cor, int id) {
    ContentValues valores = new ContentValues();
    valores.put("veiculo", veiculo);
    valores.put("ano", ano);
    valores.put("cor", cor);
    getWritableDatabase().update("carros", valores, "id="+id, null);
}
 
public void excluir(int id) {
    getWritableDatabase().delete("carros", "id="+id, null);
}

Agora temos que alterar nossa lista, para que ao clicar em algum item seja exibido um box perguntando para o usuário se ele deseja alterar ou excluir o registro. Porém, antes de implementar o box, precisamos adicionar o ID dos registros no nosso adaptador. Ele não será exibido em nenhum lugar, mas é essencial para manipular os registros. Vamos então alterar o método atualizaLista().

private void atualizaLista() {
    adaptador.clear(); // Limpa o adaptador para evitar duplicados
    carros = dados.obterTodos();
    carros.moveToFirst(); // Move o ponteiro para o primeiro registro
    while (!carros.isAfterLast()) {
        String veiculo = carros.getString(1).toString();
        String ano = carros.getString(2).toString();
        String cor = carros.getString(3).toString();
        String id = String.valueOf(carros.getInt(0));
        String[] c = { veiculo, ano, cor, id }; // Cria um array com os
                                                // dados do carro
        adaptador.add(c); // Adiciona no ArrayList
        carros.moveToNext(); // Move o ponteiro para o próximo registro
    }
    adaptador.notifyDataSetChanged(); // Atualiza a lista
}

É necessário também adicionarmos um novo atributo do tipo int. Ele servirá para armazenamento do ID do carro que está sendo alterado. Ele está com valor -1 para que saibamos quando um registro está sendo alterado.

int id = -1;

Agora sim, vamos alterar a ação ao clicar em algum item da lista.

// Ao clicar na linha, será exibida um box perguntando ao
// usuário se ele deseja alterar ou excluir o registro. Coloque seu
// código dentro do método onClick().
linha.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        new AlertDialog.Builder(ListaCarros.this)
                       .setTitle("Tutorial YESbr")
                       .setCancelable(false)
                       .setMessage("Selecione uma ação:")
                       .setPositiveButton("Alterar",
                           new DialogInterface.OnClickListener() {
                               public void onClick(
                                   DialogInterface dialog,
                                   int which) {
                                       // Ao clicar em alterar, os dados do
                                       // registro em questão
                                       // serão passados para os campos de
                                       // texto
                                       veiculo.setText(item_linha[0]);
                                       ano.setText(item_linha[1]);
                                       cor.setText(item_linha[2]);
                                       id = Integer.parseInt(item_linha[3]);
                                   }
                               })
                       .setNegativeButton("Excluir",
                           new DialogInterface.OnClickListener() {
                               public void onClick(
                                   DialogInterface dialog,
                                   int which) {
                                       // Ao clicar em excluir, o registro
                                       // é excluído do banco de dados e
                                       // atualiza a lista
                                       dados.excluir(Integer
                                           .parseInt(item_linha[3]));
                                       atualizaLista();
                                   }
                               }).show();
    }
});

Por último, temos que alterar a ação do botão salvar para que seja chamado o método correto em caso de inserção ou alteração de registro.

salvar.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        if (id == -1) {
            dados.inserir(veiculo.getText().toString(), ano.getText()
                .toString(), cor.getText().toString());
        } else {
            dados.alterar(veiculo.getText().toString(), ano.getText()
                .toString(), cor.getText().toString(), id);
            id = -1; // reseta o ID
        }
        atualizaLista();
    }
});

Finish him! Rode o projeto e veja como ficou.

Manipulando dados do banco no Android

Notas Importantes

1- Anteriormente, nosso projeto não iniciava com a lista já preenchida caso existissem dados salvos no banco. Para fazê-lo, bastaria chamar o método atualizaLista() logo após definirmos o adaptador na nossa lista, dentro do método onCreate().

2- Ao salvar ou alterar algum registro, os campos do formulário ainda continuavam preenchidos. A partir de agora, eles serão “zerados”.

Considerações Finais

Agora já conhecemos as quatro operações básicas do SQLite: selecionar, inserir, alterar e excluir. No próximo tutorial vamos aprender a exibir mensagens na tela do smartphone, informando ao usuário o resultado de uma operação.

Baixe o projeto atual aqui.

Até lá!

Banco de Dados em Android

Banco de Dados em AndroidFala galera!

Hoje vamos aprender a salvar dados de um formulário no banco de dados em Android! Com isso, sua aplicação poderá salvar informações, e um novo leque de possibilidades de aplicações foi aberto!! (lista de contatos, informações pessoas, etc.)

Se você ainda não viu o último tutorial da série, aproveite e aprenda um pouco mais sobre como criar um ListView personalizado no Android. Se você continua é preguiçoso e apenas baixou o projeto, importe-o para sua workspace. Para tal, vá em File → Import… → Existing Projects into Workspace, dentro de General.

Banco de dados em Android

Nativamente, o Android disponibiliza uma forma de persistir dados utilizando o SQLite. Ele é leve e muito fácil de utilizar.

Se você não tem experiência com SQL, não se preocupe: o aprendizado é fácil e rápido, e logo você estará entendido dos conceitos.

Inicialmente, vamos criar uma classe chamada Dados, que irá estender SQLiteOpenHelper.

public class Dados extends SQLiteOpenHelper {

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
    }
 
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
    }
 
}

Ao fazer o procedimento, será acusado um erro: o construtor da classe não foi criado. O construtor serve para acessar os métodos desta classe. Para cria-lo, antes vamos definir dois atributos privados, estáticos e finais NOME_BANCO e VERSAO_SCHEMA. Como o próprio nome diz, estes atributos são referentes ao nome e versão do schema do banco de dados que vamos criar.

private static final String NOME_BANCO = "listacarros.db";
private static final int VERSAO_SCHEMA = 1;

Feito isso, vamos instanciar nosso construtor da classe (que necessita de um parâmetro do tipo Context), chamando o método super() e passando os atributos necessários.

public Dados(Context context) {
    super(context, NOME_BANCO, null, VERSAO_SCHEMA);
}

Depois de criar o construtor, vamos modificar o método onCreate(). Nesse método deverão ser passados os SQLs de criação das tabelas. No nosso caso, vamos criar apenas uma tabela chamada carros.

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE carros("
                                   + "id INTEGER PRIMARY KEY AUTOINCREMENT, veiculo TEXT, ano TEXT, cor TEXT);");
}

O método onUpgrade() não será modificado, pois ele somente é chamado quando há uma atualização. Porém, ele não pode ser apagado, pois é obrigatório na classe.

O próximo passo será criar um método que irá salvar os dados no banco. Este método irá receber como parâmetros os dados do carro em questão.

public void inserir(String veiculo, String ano, String cor) {
   ContentValues valores = new ContentValues();
   valores.put("veiculo", veiculo);
   valores.put("ano", ano);
   valores.put("cor", cor);
   getWritableDatabase().insert("carros", null, valores);
}

Precisamos também criar um método para recuperar todos os carros cadastrados no banco.

public Cursor obterTodos() {
    return getReadableDatabase().rawQuery(
                                   "select * FROM carros ORDER BY veiculo", null);
}

OBS: Corrija todos os erros de importação com Ctrl + Shift + O.

Vamos agora modificar nossa classe principal ListaCarros, alterando como a listagem é recuperada e modificando a ação do botão Salvar.

Primeiro, vamos criar um atributo do tipo Dados, nossa classe previamente criada.

Dados dados;

No método onCreate(), vamos chamar o construtor da classe Dados passando o contexto da classe ListaCarros (atributo this).

dados = new Dados(this);

Feito isto, estamos prontos para salvar os dados no banco!

Modifique a ação do botão salvar de maneira que os dados sejam armazenados no banco de dados através do método inserir() que criamos. Vamos também chamar o método atualizaLista(), o qual falaremos a seguir.

salvar.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        dados.inserir(veiculo.getText().toString(), ano.getText().toString(), cor.getText().toString());
    }
});

Vamos agora modificar nossa lista. De início, criar um novo atributo chamado carros do tipo Cursor, que servirá para armazenar todos os registros do banco de dados.

Cursor carros;

Finalmente, vamos criar o método atualizaLista(), que será responsável por popular nossa lista. Nele, vamos salvar o retorno do método obterTodos() da classe Dados. Logo após, vamos percorrer todos os registros e inserir cada um em nosso adaptador. Só não se esquece de limpar o adaptador para não adicionar registros duplicados.

private void atualizaLista() {
    adaptador.clear(); // Limpa o adaptador para evitar duplicados
    carros = dados.obterTodos();
    carros.moveToFirst(); // Move o ponteiro para o primeiro registro
    while (!carros.isAfterLast()) {
        String veiculo = carros.getString(1).toString();
        String ano = carros.getString(2).toString();
        String cor = carros.getString(3).toString();
        String[] c = { veiculo, ano, cor }; // Cria um array com os dados do carro
        adaptador.add(c); // Adiciona no ArrayList
        carros.moveToNext(); // Move o ponteiro para o próximo registro
    }
    adaptador.notifyDataSetChanged(); // Atualiza a lista
}

Já era! Execute seu projeto e tenha sonhos maravilhosos!

Banco de Dados em Android

Considerações Finais

Muito simples, não? Com pouco trabalho, nossa aplicação ficou um pouco mais interessante. Agora temos banco de dados! No próximo tutorial, vamos aprender a editar e excluir os registros do banco de dados.

Baixe o projeto atual aqui.

Falou, galera!

Criando um ListView personalizado no Android

Faaala galera!

Aqui vamos nós para mais um tutorial. Hoje vamos aprender como podemos customizar um ListView!

Se você ainda não viu o último tutorial da série, aproveite e aprenda um pouco mais sobre como manipular dados de um formulário em Android. Se você continua é preguiçoso e apenas baixou o projeto, importe-o para sua workspace. Para tal, vá em File → Import… → Existing Projects into Workspace, dentro de General.

Bora lá começar?!

Criando um ListView personalizado no Android

Vamos começar alterando nosso layout atual adicionando mais dois campos EditText, com os IDs ano e cor. Não se esqueça de criar as strings constantes ano e cor, no arquivo res/values/strings.xml.

<EditText
       android:id="@+id/ano"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:ems="10"
       android:hint="@string/ano" />
 
   <EditText
       android:id="@+id/cor"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:ems="10"
       android:hint="@string/cor" />

PS: não vou adicionar o código inteiro para não ficar muito extenso. Se você está com preguiça dificuldades, siga todo o tutorial para aprender, é claro, e depois baixe o projeto no final.

Abra a nossa Activity principal ListaCarros. Nela vamos instanciar os campos que acabamos de criar.

EditText ano, cor;
ano = (EditText) findViewById(R.id.ano);
cor = (EditText) findViewById(R.id.cor);

Agora vem a parte principal do nosso tutorial. Para customizar nossa lista, são 3 passos: criar um layout para as linhas da lista, criar as classes para adaptar a lista, e implementar a adaptação.

Primeiramente, vamos criar o layout das linhas em res/layout/linha_carro.xml. Seguindo as alterações já realizadas, vamos criar um layout básico, que irá exibir as informações de nome, ano e cor dos veículos.

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent">
 
   <TextView
       android:id="@+id/nomeCarro"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_alignParentLeft="true"
       android:layout_alignParentTop="true"
       android:text="TextView"
       android:textStyle="bold" />
 
   <TextView
       android:id="@+id/anoCarro"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentLeft="true"
       android:layout_below="@+id/nomeCarro"
       android:text="TextView" />
 
   <TextView
       android:id="@+id/corCarro"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignBaseline="@+id/anoCarro"
       android:layout_alignBottom="@+id/anoCarro"
       android:layout_alignParentRight="true"
      android:text="TextView" />
 
</RelativeLayout>

O segundo passo é um pouco mais complicado. Precisamos criar 2 classes que irão adaptar as listas. Vamos chama-las de Adaptador, que estende ArrayAdapter, e Armazenador. Como o nome já diz, uma classe faz a adaptação e a outra armazena as informações nos lugares corretos. Deixei o código todo comentado para facilitar pra mim pra você entender.

// Classe responsável por criar um adaptador para as linhas do ListView
class Adaptador extends ArrayAdapter {
                Adaptador() {
                               // Chama o construtor da classe ArrayAdapter, passando a classe atual,
                               // um layout padrão e a lista dos itens que serão adicionados.
                               super(ListaCarros.this, android.R.layout.simple_list_item_1, listaCarros);
                }
 
                // Vamos sobrepor o método getView, pois é aqui que vamos chamar nosso layout
                // customizado
                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
 
                               // Instanciando os itens necessários: linha atual, classe Armazenador
                               // e o conteúdo que será inserido
                               View linha = convertView;
                               Armazenador armazenador = null;
                               final String[] item_linha = (String[]) listaCarros.get(position);
 
                               // Neste trecho é que chamaos nosso layout. Usamos o método getLayoutInflater()
                               // e depois indicamos o layout. Também já inserimos os dados na posição atual
                               // através da classe Armazenador.
                               if (linha == null) {
                                               LayoutInflater inflater = getLayoutInflater();
                                               linha = inflater.inflate(R.layout.linha_carro, null);
                                               armazenador = new Armazenador(linha, position);
                                               linha.setTag(armazenador);
                               } else {
                                               armazenador = (Armazenador) linha.getTag();
                               }
 
                               // Apenas uma "firula". Ao clicar na linha, será exibida uma mensagem
                               // com o nome do carro. Coloque seu código dentro do método onClick().
                               linha.setOnClickListener(new OnClickListener() {
                                               @Override
                                               public void onClick(View v) {
                                                               Toast.makeText(getApplicationContext(), item_linha[0], Toast.LENGTH_SHORT).show();
                                               }
                               });
 
                               // Agora sim, vamos jogar os dados nos seus respectivos campos do layout da linha
                               armazenador.popularFormulario((String[]) listaCarros.get(position));
 
                               // Retorno obrigatório do método
                               return linha;
                }
}
 
// Classe responsável por "jogar" os dados nos campos corretos
class Armazenador {
                // Declaração dos campos
                private TextView nomeCarro = null;
                private TextView anoCarro = null;
                private TextView corCarro = null;
 
                // Construtor que instancia os campos
                Armazenador(View linha, int position) {
                               nomeCarro = (TextView) linha.findViewById(R.id.nomeCarro);
                               anoCarro = (TextView) linha.findViewById(R.id.anoCarro);
                               corCarro = (TextView) linha.findViewById(R.id.corCarro);
                }
 
                // Método para "jogar" os textos nos respectivos campos
                void popularFormulario(String[] c) {
                               nomeCarro.setText(c[0]);
                               anoCarro.setText(c[1]);
                               corCarro.setText(c[2]);
                }
}

NOTA: alguns warnings serão exibidos, porém não influenciam em nada.

Terceiro e último passo: vamos programar nossas classes de adaptação. É preciso modificar o tipo de algumas variáveis, pois antes existia apenas 1 informação (nome do carro), e agora irão existir 3.

List<String[]> listaCarros;
ArrayAdapter<String[]> adaptador;

Precisamos também trocar a instância do adaptador, e a ação do botão Salvar.

adaptador = new Adaptador();
salvar.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                               String[] c = {veiculo.getText().toString(), ano.getText().toString(), cor.getText().toString()};
                               listaCarros.add(c);
                               adaptador.notifyDataSetChanged();
                }
});

Beleza, execute o código e seja feliz!

Criando um ListView personalizado no Android

Considerações Finais

Nosso projeto começa a ficar interessante. Aprendemos a customizar nossa lista de acordo com o necessário. No próximo tutorial vamos aprender a salvar os dados em banco de dados!

Baixe o projeto atual aqui.

Até mais, pessoal!

Como manipular dados de um formulário em Android

Fala galera!

Continuando nossa série de tutoriais Android, vamos ver hoje como manipular dados de um formulário em Android. Vamos obter os dados dos campos e salvar na memória do aparelho.

Se você ainda não viu o último tutorial da série, aproveite e aprenda um pouco mais sobre layouts XML em Android. Se você é preguiçoso e apenas baixou o projeto, importe-o para sua workspace. Para tal, vá em File → Import… → Existing Projects into Workspace, dentro de General.

Feito isso, mãos à obra!

Como manipular dados de um formulário em Android

Vamos modificar nossa Activity principal ListaCarros. Vamos fazer com que, ao apertar o botão Salvar, a aplicação salve os dados digitados na memória do aparelho. Lembre-se que ao fechar o aplicativo, é feita a limpeza da memória e os dados são apagados.

Logo no primeiro instante, devemos instanciar todos os itens que vamos utilizar, neste caso serão os dois campos EditText, o botão Button e a lista ListView. Mas primeiro vamos declarar os componentes. Esse código é adicionado antes do método onCreate(). Vamos também instanciar um objeto do tipo List<String>que irá armazenar os dados salvos para exibir na nossa lista, e um objeto do tipo ArrayAdapter<String> que irá manter os dados salvos na lista.

EditText veiculo;
Button salvar;
ListView lista;
List<String> listaCarros;
ArrayAdapter<String> adaptador;

Note que, ao dar Ctrl C + Ctrl V digitar esse código, o Eclipse acusará erro. Isso acontece pois ao declarar componentes, devemos importar suas classes respectivas. E para fazer isso automaticamente, no Eclipse, basta apertar Ctrl + Shift + O.

Agora sim, vamos instanciar os objetos. Vamos utilizar a função nativa findViewById, retorna uma View (componente) de acordo com o parâmetro passado. Esse parâmetro será o ID do campo, vindo da classe R. Antes da função findViewById, devemos “forçar” a conversão do seu retorno para o tipo de componente ao qual faz referência. No caso da List e do ArrayAdapter, vamos apenas instanciar a classe, passando os parâmetros padrões.

veiculo = (EditText) findViewById(R.id.veiculo);
salvar = (Button) findViewById(R.id.salvar);
lista = (ListView) findViewById(R.id.lista);
listaCarros = new ArrayList<String>();
adaptador = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listaCarros);

Para adicionar a ação ao botão, devemos chamar o método setOnClickListener presente na classe Button. Dentro dele, no método onClick(), todas as ações serão definidas. Vamos fazer com que os dados digitados sejam salvos na lista de carros, e exibida no objeto lista.

salvar.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        listaCarros.add(veiculo.getText().toString());
        adaptador.notifyDataSetChanged();
    }
});

Depois de adicionar na lista o texto digitado no campo, devemos chamar o método notifyDataSetChanged() para informar que a lista de carros foi atualizada.

Por fim, não podemos nos esquecer de atrelar o adaptador à lista.

lista.setAdapter(adaptador);

Tudo pronto! Execute o código e veja como ficou.

Como manipular dados de um formulário em Android

Considerações Finais

Esse projeto, até o momento, é bem simples e faz muito pouco perto do que podemos fazer. No próximo tutorial vamos incrementar nossa lista, adicionando mais campos ao formulário.

Baixe o projeto atual aqui.

Até mais, pessoal!

Layouts XML em Android

Fala galera!

Hoje vamos aprender um pouco sobre layouts XML em Android. Para isso, vamos criar um novo projeto e utilizá-lo em todos os nossos tutoriais seguintes, a fim de criarmos um aplicativo completo.

Seguindo os passos no tutorial anterior (Hello World em Android), vamos criar um projeto chamado Tutorial YESbr, onde a classe principal será chamada ListaCarros.

Layouts XML em Android

Depois de criado, vamos observar a estrutura de diretórios do projeto. Inicialmente, vamos trabalhar apenas com 3 diretórios: src, res/layouts e res/values. No diretório src ficam os arquivos .java dentro dos respectivos pacotes, onde colocamos toda a programação. No diretório res/layouts ficam os arquivos XML dos layouts, e no diretório res/values ficam as constantes do sistema.

Layouts XML em Android

Layouts XML em Android

Vamos começar a edição do layout principal. Abrindo o arquivo activity_main.xml, vamos observar a seguinte estrutura:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context="br.com.yesbr.tutorial.ListaCarros" >
 
   <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/hello_world" />
 
</RelativeLayout>

Se você já trabalhou com Swing no Java, fica mais fácil entender a estrutura.

Os layouts são organizados em elementos, representados no código fonte por tags, e são distribuídos de forma hierárquica.

No layout criado automaticamente, podemos observar dois componentes:

  • RelativeLayout: é um container, onde serão adicionados outros componentes. Nesse layout os componentes são “flutuantes”, ou seja, sem alinhamento padrão.
  • TextView: é um elemento de texto. Neste caso, está imprimindo a constante @string/hello_world (mais abaixo vamos falar sobre as constantes).

Inicialmente, vamos apenas modificar nosso layout para o código abaixo. O objetivo do aplicativo é obter a lista de carros que estão/serão cadastrados. Para isso, vamos utilizar quatro elementos:

  • LinearLayout: outro tipo de container, porém neste os elementos são inseridos um após o outro. dependendo da orientação do layout.
  • EditText: uma caixa de texto para inserção de informação.
  • Button: botão que irá executar uma ação.
  • ListView: obtém uma lista previamente submetida.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="vertical" >
 
   <EditText
       android:id="@+id/veiculo"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:hint="@string/veiculo" >
 
       <requestFocus />
   </EditText>
 
   <Button
       android:id="@+id/salvar"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/salvar" />
 
   <ListView
       android:id="@+id/lista"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" >
   </ListView>
 
</LinearLayout>

Todos os atributos dos componentes são precedidos por android:, indicando ser um atributo android.

O LinearLayout adota uma orientação vertical, ou seja, os elementos são inseridos um abaixo do outro. layout_width e layout_height indicam largura e altura respectivamente, e foram configurados como fill_parent para preencher toda a área disponível.

EditText nada mais é que um campo de texto (tipo input type=text em HTML). Para ele, definimos o id “veiculo”, pois iremos na programação do projeto. Note que, antes do id, existe um prefixo “@+id/”, que indica o tipo de informação (neste caso, id). Definimos layout_width como match_parent (parecido com full_parent) e layout_height como wrap_content (ajuste de acordo com o conteúdo. O atributo hint é um texto prévio que vem no campo, semelhante ao “placeholder” em HTML. Também foi adicionado uma tag requestFocus dentro da tag EditText, que faz o campo já esteja pronto para digitação.

Button é o botão que irá chamar uma ação, simples assim. Para ele, foi definido o id “salvar”. layout_width e layout_height foram definidos como wrap_content. O texto do botão é definido pelo atributo text, neste caso com a constante @string/salvar.

ListView será identificado pela id lista, e layout_width e layout_height foram definidos como match_parent e wrap_content respectivamente.

Executando o projeto, vamos obter o seguinte resultado:

Layouts XML em Android

Constantes

As constantes são variáveis que não mudam (óoooh). Elas são definidas dentro do diretório res/values quando serão utilizadas em mais de um local, não tendo a necessidade de sempre criar uma por uma. Por padrão, o Eclipse cria três arquivos de constantes: dimens.xml, strings.xml e styles.xml. Pelo nome deles, você com certeza já compreendeu o que cada um deles armazena.

MAS E OS IDs?

Os IDs dos componentes ficam salvos em outro arquivo, a classe R. Essa classe possui todas as referências para os recursos da aplicação. Está localizada no diretório gen/nome_do_pacote, e o próprio Eclipse se encarrega de atualizá-lo quando necessário, e quando o projeto não apresenta nenhum erro. A classe R NUNCA deve ser alterada ou deletada.

Considerações Finais

Por enquanto, nosso projeto não faz o tratamento dos dados. Por enquanto…

Nos próximo post, vamos aprender a tratar os dados e salvar na memória. Não perca!

Baixe o projeto do Eclipse aqui.

DICA: Existe uma ferramenta online, gratuita, para edição de arquivos de layout XML em Android. É o DroidDraw.

Até mais!

Hello World em Android

Fala galera!

Continuando nossa série de tutoriais, vamos hoje criar nosso primeiro projeto: Hello World em Android! Com esse projeto, vamos começar a nos familiarizar com a programação para Android e com a interface do nosso IDE escolhido para a série, o Eclipse.

Começando nosso Hello World em Android

Primeiramente, vamos criar um novo projeto. Abra o Eclipse, vá ao menu File New → Project…, procure a seção Android, selecione Android Application Project e clique em Next.

Hello World em Android

Na tela seguinte, vamos definir o nome do nosso aplicativo, o nome do projeto e o pacote que será utilizado. Vamos definir também as opções de SDK. Na ordem, são elas: versão mínima necessária, versão máxima compatível, versão para compilar o projeto (de acordo com as versões que baixamos), e o tema. IMPORTANTE: O nome do aplicativo é o mesmo que irá aparecer no smartphone dos usuários.

Hello World em Android

Na próxima tela, vamos deixar marcadas as opções para criar o ícone da aplicação, a activity principal, e criar o projeto na Workspace.

Hello World em Android

Definindo nosso ícone da aplicação (vou manter o padrão mesmo).

Hello World em Android

Escolhendo o tipo da activity principal…

Hello World em Android

E por último, o nome da activity principal.

Hello World em Android

E pronto, está criado o nosso projeto!

Considerações

Os arquivos mais importantes (por enquanto) são o MainActivity.java, que está localizado dentro da pasta src, e o arquivo activity_main.xml, dentro da pasta res/layout.

O arquivo activity_main.xml é o que define o layout e a disposição dos componentes (textos, botões, imagens, etc.). Já o arquivo MainActivity.java é responsável por armazenar todo o código da aplicação.

Rodando a aplicação

Vamos executar nossa aplicação e ver como está. Para tal, clique no menu Run Run As → Android Application.

Hello World em Android

Feito isso, o emulador com a versão do Android compatível com o projeto será iniciado (pode demorar um pouco), e o nosso Hello World em Android será iniciado.

Hello World em Android

Hello World em Android

Isso é tudo, pessoal!

No próximos tutorial, vamos criar um projeto e ir incrementando ele aos poucos, até termos um aplicativo digno de ser publicado.

Se você ainda não viu os primeiro tutoriais da série, acesse agora

Até a próxima!

Emulador Android: como configurar

Fala galera!

Vamos ao segundo tutorial da série “Desenvolvendo Aplicativos para Android”.
Hoje vamos aprender a criar e configurar um emulador Android através do AVD Manager.

O que é AVD Manager?

O AVD Manager é o gerenciador de emuladores Android. A sigla AVD vem de Android Virtual Devices (traduzindo para o português: dispositivos virtuais Android).
No AVD você pode criar, editar e excluir seu emulador Android. Podem ser criados vários emuladores, com diferentes configurações e versões do Android.

Para mais informações sobre o AVD, acesse o site Android Developer.

Para acessar o AVD:

  • No Eclipse: selecione Window → Android Virtual Device Manager;
  • No Android Studio: selecione Tools → Android → AVD Manager;
  • Em outros IDEs: navegue até o diretório do SDK e execute o arquivo AVD Manager.exe;

Em alguns casos, na própria toolbar existe o ícone do AVD Manager.

Emulador Android

Então, a tela com a lista dos dispositivos será aberta.

Emulador Android

Criando meu primeiro emulador Android

Para criar um emulador, vamos clicar no botão Create. Vamos então preencher os dados referentes ao dispositivo desejado. O campo Device indica o tipo de dispositivo e o tamanho da tela. O campo Target indica a versão do Android que será utilizada. Dependendo da versão do Android, você pode escolher o processador em CPU/ABI. Você também pode configurar periféricos, como câmera frontal e traseira, teclado, cartão de memória, etc.

Emulador Android

Após preencher/selecionar todos os campos, basta clicar em OK para finalizar o processo.

Emulador Android

DICA

Crie vários dispositivos, de diferentes versões do Android e tamanho de tela para testar suas aplicações em todas as possibilidades.

Emulador Android: como configurar

Nas próximas semanas, vamos criar nosso primeiro projeto, o famoso Hello World!

Se você ainda não viu o primeiro tutorial da série, acesse agora: Como desenvolver aplicativos para Android

Até a próxima, galera!