terça-feira, 12 de junho de 2012

Efetuando download via FTP

Olá pessoal,

Hoje vou mostrar como acessar um servidor FTP, utilizando android vou criar uma classe client FTP completa com todas as funcionalidades que você irá precisar como por exemplo listar arquivos, excluir, mudar de diretório, mas no exemplo prático será apresentada a rotina para efetuar um download via FTP.

Como de costume vou apresentar todos os fontes utilizados já com comentários para facilitar no aprendizado.

Abaixo segue um print dos arquivos do projeto:


Abaixo segue o arquivo clsFTP.java
package br.com.EscolaDeAndroid.FTP;

import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import android.util.Log;

public class clsFTP {
    FTPClient mFtp;  
    private String TAG = "clsFTP";

   
    //Listar os arquivos e diretórios de um determinado caminho
    public FTPFile[] Dir(String pDiretorio)
    {
        try {
            FTPFile[] ftpFiles = mFtp.listFiles(pDiretorio);

            return ftpFiles;
        } catch(Exception e) {
            Log.e(TAG, "Erro: não foi possível listar os arquivos e pastas do diretório " + pDiretorio + ". " + e.getMessage());
        }
        return null;
    }    
    
    //Pegar o nome do diretório corrente
    public String DiretorioCorrente()
    {
        try {
            String workingDir = mFtp.printWorkingDirectory();
            return workingDir;
        } catch(Exception e) {
            Log.e(TAG, "Erro: não foi possível obter o diretório atual. " + e.getMessage());
        }
        return null;
    }    
    
    //Mudar de diretório
    public boolean MudarDiretorio(String pDiretorio)
    {
        try {
            mFtp.changeWorkingDirectory(pDiretorio);
        } catch(Exception e) {
            Log.e(TAG, "Erro: não foi possível mudar o diretório para " + pDiretorio);
        }
        return false;
    }    
    
    //Criar um diretório
    public boolean CriarDiretorio(String pDiretorio)
    {
        try {
            boolean status = mFtp.makeDirectory(pDiretorio);
            return status;
        } catch(Exception e) {
            Log.e(TAG, "Erro: não foi possível criar o diretório " + pDiretorio);
        }
        return false;
    }    
    
    //Excluir um diretório
    public boolean RemoveDiretorio(String pDiretorio)
    {
        try {
            boolean status = mFtp.removeDirectory(pDiretorio);
            return status;
        } catch(Exception e) {
            Log.e(TAG, "Erro: não foi possível remover o diretório " + pDiretorio);
        }
        return false;
    }    
    
    //Deletar arquivo
    public boolean Delete(String pArquivo)
    {
        try {
            boolean status = mFtp.deleteFile(pArquivo);
            return status;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }    
    
    //Renomear arquivo
    public boolean Rename(String from, String to)
    {
        try {
            boolean status = mFtp.rename(from, to);
            return status;
        } catch (Exception e) {
            Log.e(TAG, "Erro: Não pode renomear o arquivo: " + from + " para: " + to);
        }
        return false;
    }    
    
    //Baixar um arquivo do servidor FTP
    public boolean Download(String pDiretorioOrigem, String pArqOrigem, String pArqDestino)  
    {  
        boolean status = false;  
        try {  
            MudarDiretorio(pDiretorioOrigem); 
            
            //Cria o outputStream para ser passado como parametro  
            FileOutputStream desFileStream = new FileOutputStream(pArqDestino);;  
              
            //Tipo de arquivo  
            mFtp.setFileType(FTP.BINARY_FILE_TYPE);  
              
            //http://commons.apache.org/net/apidocs/org/apache/commons/net/ftp/FTPClient.html#enterLocalActiveMode()  
            mFtp.enterLocalPassiveMode();  
              
            //Faz o download do arquivo  
            status = mFtp.retrieveFile(pArqOrigem, desFileStream);  
              
            //Fecho o output  
            desFileStream.close();  
    
            return status;  
        } catch (Exception e) {  
            Log.e(TAG, "Erro: Falha ao efetuar download. " + e.getMessage());  
        }  
        return status;  
    }
    
    //Enviar arquivo para o servidor FTP
    public boolean Upload(String pArqOrigem, String pArqDestino, String pDiretorioDestino)
    {
        boolean status = false;
        try {
            FileInputStream srcFileStream = new FileInputStream(pArqOrigem);

            //muda o diretório para o destino específico
            if (MudarDiretorio(pDiretorioDestino)) {
                status = mFtp.storeFile(pArqDestino, srcFileStream);
            }

            srcFileStream.close();
            return status;
        } catch (Exception e) {
            Log.e(TAG, "Erro: Falha ao efetuar Upload. " + e.getMessage());
        }
        return status;
    }
    
    //Encerrar a conexão com o servidor FTP
    public boolean Desconectar()
    {
        try {
            //mFtp.logout();
            mFtp.disconnect();
            mFtp = null;
            return true;
        } catch (Exception e) {
            Log.e(TAG, "Erro: ao desconectar. " + e.getMessage());
        }
        return false;
    }    
    
    //Efetuar conexão com o servidor FTP
    public boolean Conectar(String pHost, String pUsuario, String pSenha, int pPorta)
    {
        try {
            mFtp = new FTPClient();
            
            // conectando no host
            mFtp.connect(pHost, pPorta);
            
            //verifica se a conexão está ok
            if (FTPReply.isPositiveCompletion(mFtp.getReplyCode())) {
                
                //efetua login
                boolean status = mFtp.login(pUsuario, pSenha);

                mFtp.setFileType(FTP.BINARY_FILE_TYPE);
                mFtp.enterLocalPassiveMode();
                
                return status;
            }
        } catch(Exception e) {
            Log.e(TAG, "Erro: não foi possível conectar ao host " + pHost);
        }
        return false;
    }    
}

Abaixo segue o arquivo TesteFTPActivity.java:
package br.com.EscolaDeAndroid.FTP;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.widget.EditText;
import android.widget.Toast;

public class TesteFTPActivity extends Activity {
    clsFTP mClienteFTP;
    EditText editText;
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        editText = (EditText)findViewById(R.id.editText1);
        String lstrArq = "";
        
        try {
            mClienteFTP = new clsFTP();
            
            //Definindo o nome do arquivo que será gravado no SD
            lstrArq = "/teste2.txt";
            File lArquivo = new File(Environment.getExternalStorageDirectory(), lstrArq); 
            
            mClienteFTP.Conectar("ftp.seuendereco.com", "usuario", "senha", 21);
            
            //Faz o download do arquivo passando o nome dele(dentro o servidor) e local onde ele vai ser guardado  
            mClienteFTP.Download("/nomedapasta", "teste.txt", lArquivo.toString());
              
            //Desconecta do ftp  
            mClienteFTP.Desconectar();          
            
            //Efetua a leitura do arquivo   
            FileReader fileReader= new FileReader(lArquivo);  
            BufferedReader leitor= new BufferedReader(fileReader);  
            String linha = null;    
              
            //Loop para ler e carregar o editText  
            while((linha = leitor.readLine()) != null) {    
                editText.append(linha);  
            }   
            
            leitor.close();
            fileReader.close();
                
        } catch (Exception e) {
            trace("Erro : " + e.getMessage());
        }
            
    }
    
    public void toast (String msg)
    {
        Toast.makeText (getApplicationContext(), msg, Toast.LENGTH_SHORT).show ();
    } 
     
    private void trace (String msg) 
    {
        toast (msg);
    }    
}

Abaixo segue o arquivo AndroidManifest.xml, onde deveremos adicionar as permissões para acessar a internet e gravar no SD:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="br.com.EscolaDeAndroid.FTP"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="7" />
 <uses-permission android:name="android.permission.INTERNET"/>
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".TesteFTPActivity"
            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>

Abaixo segue o arquivo main.xml:
<?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" >

    <EditText
        android:id="@+id/editText1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:inputType="text"
        android:ems="10" >
        <requestFocus />
    </EditText>

</LinearLayout>

Por enquanto é isso pessoal, espero que seja útil esse projeto para vocês, e caso necessitem, por exemplo, enviar um arquivo via FTP, dentro da classe clsFTP.java já possui esse e outros métodos.



Desenvolvi o jogo Circus Puzzle Free ele é um quebra-cabeça e está publicado no Android Market, agradeço a todos que baixarem, jogarem e comentarem.



Desenv com qualidade!