sexta-feira, 18 de janeiro de 2013

Android - Arquivo de Configuração


Os Arquivos de Configurações sempre foram usados pelos aplicativos ou sistemas operacionais. São arquivos onde podemos guardar informações que podem ser facilmente alteradas sem a necessidade de recompilação da aplicação, ou seja, basta alterarmos o mesmo para que tais configurações sejam aplicadas. No Windows utilizamos o Registro, no Delphi temos o “.ini” e em outras linguagens como o C# o “.XML”, que são arquivos que possuem estruturas onde definimos as configurações, nas quais são definidas dentro de elementos através de atributos pré-definidos (chave/valor). Em se tratando da linguagem Java, temos as “Properties” – as denominadas Propriedades, na qual iremos usá-la neste artigo.

Classe “Properties” (Propriedades)

No Android, um objeto da classe “Properties” é um “Hashtable”, onde as chaves e os valores devem ser Strings. Cada propriedade pode ter um padrão de lista de propriedades que especifica os valores para serem usados quando uma determinada chave não é encontrada.
A codificação de caracteres utilizada é a ISO-8859-1 em vez de UTF-8. A ISO-8859-1 é capaz de representar apenas um pequeno subconjunto de Unicode, podendo usar ambos os métodos “LoadFromXML/ StoreToXML” (que usam UTF-8 por padrão) ou as sobrecargas que levam um “OutputStreamWriter”. É importante ressaltar que podemos salvar arquivos do tipo “.XML” e ”.properties”, sendo que este último será o qual iremos basear nosso exemplo. 
Os principais métodos públicos desta classe são:

SetProperty: método utilizado para definir os atributos, como par chave/valor.
GetProperty: método responsável por recuperar os valores definidos, usando par chave/valor.
Store: este método armazena os dados, possuindo também o “StoretoXML” que guarda as configurações no formato padrão XML.
Load: responsável por carregar as propriedades do tipo “InputStream”. Já o método “LoadFromXML” lê as informações contidas em um arquivo no padrão XML.

Criando um exemplo

Depois de conhecermos um pouco desta classe, montaremos um pequeno exemplo para maior aprendizado. Este exemplo será responsável por armazenar dados referentes às configurações básicas de um servidor FTP, como: Usuário, Senha, Url e diretório. Pelo fato destas configurações serem parametrizadas, tomei como base este tipo de aplicação. O Primeiro passo será de criar um projeto em Android e alterar o arquivo de configuração “AndroidManisfest.xml”, permitindo a leitura e escrita em um arquivo externo da aplicação, Veja a seguir o código XML para esta tarefa:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
             package="pct.Android_ArquivosConfiguracao"
          android:versionCode="1"
          android:versionName="1.0">

<uses-sdk android:minSdkVersion="8" />
   
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<application android:icon="@drawable/icon" android:label="@string/app_name">
      <activity android:name=".Android_ArquivosConfiguracaoActivity"
                android:label="@string/app_name">
        <intent-filter>
          <action android:name="android.intent.action.MAIN" />
          <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
      </activity>
</application>
</manifest>
Esta tarefa também pode ser feita pela interface gráfica de configurações. Clique no botão “Add...” para adicionar os tipos de permissões desejadas.  Ver Imagem 01.

Figura 01: Adicionando Permissões.


Classe Configuração

Definimos uma classe para manuseio destas configurações, clique com o botão direito em “New/class...” com o nome de “configuracao.java”. Crie as seguintes propriedades privadas: Usuário, Senha , Url e Diretório e os métodos “Getters and Setters” encarregados de trabalhar com estas propriedades.

package pct.Android_ArquivosConfiguracao;

public class configuracao
{
    private String usuario;
    private String senha;
    private String url;
    private String diretorio;
   
     public String getUsuario()
     {
         return usuario;
     }

     public void setUsuario(String usuario)
     {
         this.usuario = usuario;
     }

     public String getSenha()
     {
         return senha;
     }

     public void setSenha(String senha)
     {
         this.senha = senha;
     }

     public String getUrl()
     {
         return url;
     }

     public void setUrl(String url)
     {
         this.url = url;
     }

     public String getDiretorio()
     {
         return diretorio;
     }

     public void setDiretorio(String diretorio)
     {
         this.diretorio = diretorio;
     }
}

Criando o Lay-Out

Adicione 4 TextViews, 4 EditTExts e 2 Buttons para a criação do Lay-Out.Ver Imagem 02.

Figura 02: Lay-Out. 

O botão salvar será responsável por guardar as informações dentro do arquivo, já o carregar por ler os dados contidos.

O XML correspondente:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <TextView android:textAppearance="?android:attr/textAppearanceMedium"
    android:id="@+parametros/txtUrl"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Url:"
    android:typeface="sans">
    </TextView>
    <EditText android:id="@+parametros/edtUrl"
    android:layout_height="wrap_content"
    android:layout_width="320dp"
    android:typeface="sans">
    </EditText>
    <LinearLayout android:layout_width="match_parent"
    android:id="@+parametros/linearLayout1"
    android:layout_height="wrap_content">
        <LinearLayout android:layout_width="wrap_content"
        android:id="@+parametros/LinearLayout02"
        android:orientation="vertical"
        android:layout_height="wrap_content">
            <TextView android:textAppearance="?android:attr/textAppearanceMedium"
            android:id="@+parametros/txtUsuario"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Usuário:"
            android:typeface="sans">
            </TextView>
            <EditText android:id="@+parametros/edtUsuario"
            android:layout_height="wrap_content"
            android:layout_width="190dp"
            android:typeface="sans">
            </EditText>
        </LinearLayout>
        <LinearLayout android:layout_width="wrap_content"
        android:id="@+parametros/linearLayout2"
        android:layout_height="match_parent"
        android:orientation="vertical">
            <TextView android:textAppearance="?android:attr/textAppearanceMedium"
            android:id="@+parametros/txtSenha"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Senha:"
            android:typeface="sans">
            </TextView>
            <EditText android:id="@+parametros/edtSenha"
            android:layout_height="wrap_content"
            android:layout_width="130dp"
            android:typeface="sans">
            </EditText>
        </LinearLayout>
    </LinearLayout>
    <LinearLayout android:layout_width="match_parent"
    android:id="@+parametros/linearLayout7"
    android:layout_height="wrap_content">
        <LinearLayout android:id="@+parametros/linearLayout6"
        android:layout_height="match_parent"
        android:orientation="vertical" android:layout_width="match_parent">
            <TextView android:textAppearance="?android:attr/textAppearanceMedium"
            android:id="@+parametros/txtDiretorio"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Diretório Ftp:"
            android:typeface="sans">
            </TextView>
            <EditText android:id="@+parametros/edtDiretorio"
            android:layout_height="wrap_content"
            android:typeface="sans"
              android:layout_width="match_parent">
            </EditText>
        </LinearLayout>
    </LinearLayout>
    <LinearLayout android:id="@+id/linearLayout1"
    android:layout_height="wrap_content"
    android:layout_width="match_parent">
        <LinearLayout android:id="@+parametros/linearLayout9"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_gravity="center"
        android:gravity="center|center_horizontal"
        android:layout_width="match_parent">
            <Button android:id="@+parametros/btnCarregar"
            android:layout_height="wrap_content"
            android:layout_width="150dp"
            android:onClick="salvar"
            android:typeface="sans"
            android:text="Salvar"
            android:layout_gravity="center_horizontal">
            </Button>
            <Button android:id="@+parametros/btnSalvar"
            android:layout_height="wrap_content"
            android:layout_width="150dp"
            android:onClick="carregar"
            android:typeface="sans"
            android:text="Carregar"
            android:layout_gravity="center_horizontal">
            </Button>
        </LinearLayout>
    </LinearLayout>
   </LinearLayout>

Codificando o exemplo

Na atividade principal programarei três métodos, sendo:

Inicializalisteners: Método que irá iniciar os componentes.

Salvar: Salvar os dados no arquivo de propriedade.

Carregar: Ler os dados no arquivo de propriedade.

Segue a seguir o código completo comentado.

package pct.Android_ArquivosConfiguracao;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

Importe as seguintes bibliotecas. A principal neste caso é a “Java.util.Properties”.

public class Android_ArquivosConfiguracaoActivity extends Activity
{
    EditText edtUrl, edtUsuario, edtSenha, edtDiretorio;
   
Estas variáveis irão armazenar as propriedades contidas no arquivo de propriedades.

  @Override
  public void onCreate(Bundle savedInstanceState)
  {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      InicializaListeners();
  }

No início do programa chamaremos o método “Inicializalisteners”, nos permitindo trabalhar com os componentes na tela.
   
  public void InicializaListeners()
  {
     edtUrl = (EditText) findViewById(R.parametros.edtUrl); 
edtUsuario = (EditText) findViewById(R.parametros.edtUsuario);
edtSenha= (EditText) findViewById(R.parametros.edtSenha);
edtDiretorio = (EditText) findViewById(R.parametros.edtDiretorio);
  }

Faremos o uso do “findViewById()” para atribuir o “ID” dos componentes às variáveis criadas anteriormente.
   
  public void salvar(View v)
  {
     configuracao conf = new configuracao();
    conf.setUrl(edtUrl.getText().toString());
     conf.setUsuario(edtUsuario.getText().toString());
     conf.setSenha(edtSenha.getText().toString());
conf.setDiretorio(edtDiretorio.getText().toString());
     Properties properties = new Properties();
properties.setProperty("conf.Usuario", conf.getUsuario());
     properties.setProperty("conf.Senha", conf.getSenha());
     properties.setProperty("conf.Url", conf.getUrl());
properties.setProperty("conf.Diretorio", conf.getDiretorio());
        
     try
     {
    
FileOutputStream fos = new FileOutputStream("/mnt/sdcard/configuracao.properties");
          properties.store(fos, "CONFIGURACAO FTP:");
fos.close();
      Toast.makeText(Android_ArquivosConfiguracaoActivity.this, "Dados Salvos com sucesso!!", Toast.LENGTH_SHORT).show();
}
     catch (IOException ex)
     {
          ex.printStackTrace();
     }
}
   
O método Salvar irá guardar os dados no arquivo de propriedades. No primeiro momento instancie a classe “configuração” e atribua os dados necessários, neste caso estamos usando o EditText como entrada de Dados. Atribuímos para a URL, Usuário, Senha e Diretório. Logo após crie um objeto da classe “Java.util.Properties”, setando as propriedade e os seus valores. Através de um bloco “Try...Catch” criamos um objeto do tipo “FileOutputStream”, indicando o caminho onde será salvo e o nome do arquivo. O método “Store” grava os dados no arquivo e por final o comando “close” o libera da memória.
Damos uma mensagem informativa ao usuário que o comando foi executado com sucesso.

O arquivo “configuração.properties” deverá possuir a seguinte estrutura:

  
#CONFIGURACAO FTP:#
Mon Nov 19 17:00:05 GMT+00:00 2012
conf.Diretorio=theclub
conf.Url=ftp.teste.com.br
conf.Senha=teste123
conf.Usuario=thiago


public void carregar(View v)
{
    Properties properties = new Properties();
    try
    {
FileInputStream fis = new  FileInputStream("/mnt/sdcard/configuracao.properties");
     properties.load(fis);
   
     String Url = properties.getProperty("conf.Url");
String Usuario = properties.getProperty("conf.Usuario");
    String Senha = properties.getProperty("conf.Senha");
String Diretorio = properties.getProperty("conf.Diretorio");
       
     edtUrl.setText(Url);
     edtUsuario.setText(Usuario);
     edtSenha.setText(Senha);
     edtDiretorio.setText(Diretorio);
          Toast.makeText(Android_ArquivosConfiguracaoActivity.this, "Dados Carregados com sucesso!!", Toast.LENGTH_SHORT).show();

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

       
    }
}
O método carregar faz o trabalho inverso do Salvar. Instancie a classe “Proprierties” e utilize uma variável do tipo “FileInputStream” setando o arquivo que será lido. O método “Load” faz a leitura através do objeto criado anteriormente. Em seguida capturamos o valor da propriedade informando através da classe “Toast” uma mensagem informativa ao usuário.

Ver Imagem 03 e 04 o exemplo em “Run-Time”. 

Figura 03: Método salvar.

Figura 04: Método Carregar.

Salvando em XML

Outra opção que temos também é de salvar em XML utilizando o método “StoreToXML” e “LoadFromXML” tendo como resultado um arquivo neste mesmo formato. Veja a seguir um exemplo.

Para salvar em XML:

properties.storeToXML(fos, "CONFIGURACAO FTP:","ISO-8859-1");

Passamos como parâmetro o “OutPutStream”, o título e o tipo de XML.

Para carregar em XML:

properties.LoadfromXML(fis);

Para ler utilizamos apenas o “InputStream”.

O Arquivo gerado deverá fica idêntico ao XML a seguir:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>CONFIGURACAO FTP:</comment>
<entry key="conf.Diretorio">ftp.teste.com</entry>
<entry key="conf.Url">ftp.teste.com.br</entry>
<entry key="conf.Senha">teste123</entry>
<entry key="conf.Usuario">thiago</entry>
</properties>

Conclusão

A classe “Java.util.Properties” se torna muito importante quando trabalhamos com parametrização nos sistemas. Neste artigo achei necessário criar uma classe “configuração” para um melhor entendimento ao decorrer do desenvolvimento. Vimos que com pouco trabalho podemos guardar informações importantes em arquivos externos de configurações, como por exemplo: as configurações de um servidor FTP. Estes tipos de arquivos também são utilizados em configurações de Banco de Dados, definindo o Usuário, a senha ou o Caminho da Base de Dados. Fica a dica, Um Abraço e até o mês que vem!

Referências

http://developer.android.com/reference/java/util/Properties.html


Nenhum comentário:

Postar um comentário