Android 平台下Cordova FtpClient插件开发

需要引用一个commons-net-3.3.jar,下载地址:http://commons.apache.org/proper/commons-net/download_net.cgi

建立一个包,名为:com.JajaCy.FtpClient

package com.JajaCy.FtpClient;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class FtpClientPlugin extends CordovaPlugin {
    public static final String ACTION_LIST ="list";
    public static final String ACTION_GET ="get";
    public static final String ACTION_PUT ="put";
    private String filePath="/sdcard/JajaCy/";//本地存储地址
    private String username="admin";//用户名
    private String password="admin";//密码
    private int port=21;//服务器端口号
    
    
    @Override
    public boolean execute(String action,JSONArray data,final CallbackContext callbackContext){
        PluginResult.Status status = PluginResult.Status.OK;
        JSONArray result = new JSONArray();
        Log.d("FtpClientPlugin", "Hello, this is a native function called from Cordova!");  
        if(action.equals(ACTION_LIST)){//列表
            try{
                final String ip=data.getString(0);///接收到的值
                final String fileDirectory=data.getString(1);///接收到的值
                System.out.println(ip);
                //this.DisplayToast("192.168.1.108", callbackContext);//返回下载列表
                //getFiles("192.168.1.108", callbackContext);
                Log.d("ACTION_LIST",fileDirectory);  
                cordova.getThreadPool().execute(new Runnable(){
                    public void run(){
                        getFiles(ip, fileDirectory,callbackContext);//获取文件列表
                    }
                });
                //callbackContext.sendPluginResult(new PluginResult(status, result));
                return true;
            }
            catch(Exception ex){
                Log.d("FtpClientPlugin", ex.toString());
            }
        }
        else if(action.equals(ACTION_GET)){//下载
            try {
                final String ip =data.getString(0);
                final String fileName =data.getString(1);
                final String fileDirectory=data.getString(2);
                cordova.getThreadPool().execute(new Runnable(){
                    public void run(){
                        get(ip, fileName,fileDirectory,callbackContext);//下载
                    }
                });
                return true;
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        else if(action.equals(ACTION_PUT)){//上传
            try{
                final String ip =data.getString(0);
                final String fileName =data.getString(1);
                final String fileDirectory=data.getString(2);
                cordova.getThreadPool().execute(new Runnable(){
                    public void run(){
                        put(ip, fileName,fileDirectory,callbackContext);//上传
                    }
                });
                return true;
            }
            catch(JSONException e){
                e.printStackTrace();
            }
        }
        return false;
    }
    
    /**
     * 获取文件列表
     * */
    public void getFiles(String ip,String fileDirectory,CallbackContext callbackContext){
        FTPClient ftpClient=createConnection(ip);
        JSONObject obj = new JSONObject();//创建JSON对象
        JSONArray jsonArray = new JSONArray(); //JSON数组
        boolean flag=false;
        try{
            FTPFile[] ftpFiles=ftpClient.listFiles();//得到目录的相应文件列表
            for(int i=0; i<ftpFiles.length; i++){
                String fileName=ftpFiles[i].getName();
                int index=fileName.lastIndexOf("\t");//去掉空字符串并返回长度
                jsonArray.put(i,fileName.substring(index+1,fileName.length()));//返回图片名称
            }
            flag=true;
        }
        catch(IOException e2){
            e2.printStackTrace();
        }
        catch(JSONException e1){
            e1.printStackTrace();
        }
        finally{
            logOutConnection(ftpClient);
        }
        
        if(flag){
            try {
                obj.put("Message", "success");
                obj.put("data", jsonArray);
                callbackContext.success(obj);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        else{
            try {
                obj.put("Message", "failure");
                callbackContext.error(obj);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
    
    /**
     * 将文件上传到FTPSERVER 服务器上
     * @param ip                 服务地址
     * @param fileName             上传文件名称
     * @param fileDirectory     指定上传的目录
     * @param callbackContext     返回成功的信息
     * */
    public void put(String ip,String fileName,String fileDirectory,CallbackContext callbackContext){
        FTPClient ftpClient=createConnection(ip);//登录成功
        boolean flag=false;
        try{
            String path="/"+fileDirectory+"/";//需要切换的目录
            String remotePath = new String(path.getBytes("GBK"), "ISO-8859-1");//服务器文件路径
            ftpClient.changeWorkingDirectory(remotePath);//转到服务器目录
            ftpClient.setBufferSize(102400);//设置缓冲区大小,直接或者间接影响下载速度
            File file=new File(filePath+fileDirectory);//本地目录
            File[] files=file.listFiles();
            for(File fs:files){
                InputStream fis=null;
                fis=new FileInputStream(filePath+fileDirectory+"/"+fs.getName());
                ftpClient.storeFile(new String(fs.getName().getBytes("GBK"),"ISO-8859-1"), fis);
                fis.close();
            }
            flag=true;
            ftpClient.logout();
        }
        catch(IOException e){
            e.printStackTrace();
        }
        finally{
            try {
                if(ftpClient.isConnected()){
                    ftpClient.disconnect();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(flag){
            callbackContext.success("success");
        }
        else{
            callbackContext.error("failure");
        }
    }
    
    /**
    *从服务下载文件
    *@param ip                 服务器IP地址
    *@param fileName         下载文件名称
    *@param fileDirectory     指定下载的目录
    *@param callbackContext 返回成功的信息
    */
    public void get(String ip,String fileName,String fileDirectory,CallbackContext callbackContext){
        FTPClient ftpClient=createConnection(ip);//登录成功
        boolean flag=false;
        try {
            ftpClient.setBufferSize(102400);//设置缓冲区大小,直接或者间接影响下载速度
            String path="/"+fileDirectory+"/";//需要切换的目录
            String remotePath = new String(path.getBytes("GBK"), "ISO-8859-1");//服务器文件路径
            ftpClient.changeWorkingDirectory(remotePath);//转到服务器目录
            
            String localPath=filePath+fileDirectory;//本地目录
            
            FTPFile[] ftpFiles=ftpClient.listFiles();//得到目录的相应文件列表
            for(FTPFile ftpFile:ftpFiles){
                int index=ftpFile.getName().lastIndexOf("\t");//去掉空字符串并返回长度
                String name=ftpFile.getName().substring(index+1,ftpFile.getName().length());//返回图片名称
                if(fileName.equals(name)){
                    File localFile=new File(this.createDirectory(localPath)+"/"+fileName);//根据绝对路径初始化文件
                    singleFile(ftpClient,localFile, fileName);//单文件下载
                    flag=true;
                }
                else if(fileName.isEmpty()){//文件名称为空的时候将下载整个目录中的文件
                    System.out.println();
                    File localFile=new File(this.createDirectory(localPath)+"/"+name);//根据绝对路径初始化文件
                    singleFile(ftpClient,localFile, name);//单文件下载
                    flag=true;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally{
            this.logOutConnection(ftpClient);
            System.out.println(flag);
            //System.exit(flag ? 1 : 0); //退出进程
        }
        
        if(flag){
            callbackContext.success("success");
        }
        else{
            callbackContext.error("failure");
        }
    }
    
    /**
     * 创建目录
     * @param fileDirectory 路径
     * */
    public File createDirectory(String fileDirectory){
        File sdcardFile=new File(fileDirectory);//本地目录
        if(!sdcardFile.exists()){//检测目录是否存在
            sdcardFile.mkdirs();//如果不存在就创建目录-----注意mkdirs()与mkdir()的区别
        }
        return sdcardFile;
    }
    
    /**
     * 单文件下载
     * @param ftpClient 客户端对象
     * @param localPath 本地存储目录
     * @param fileName     文件名称
     * */
    public void singleFile(FTPClient ftpClient,File localFile,String fileName){
        try{
            OutputStream outputstream=new FileOutputStream(localFile);//输出流
            ftpClient.retrieveFile(new String(fileName.getBytes("GBK"),"ISO-8859-1"), outputstream);//下载文件
            outputstream.flush();
            outputstream.close();//关闭流 
        }
        catch(IOException e){
            e.printStackTrace();
        }
    }
    
    /**
    * 创建一个FTP SERVER 
    * @param ip   is FTPSERVER URL
    */
    public FTPClient createConnection(String ip){
        FTPClient ftpClient=new FTPClient();//创建一个客户端对象
        try{
            int reply;
            ftpClient.connect(ip, port);//进行连接
            reply=ftpClient.getReplyCode();//获取响应值
            if(!FTPReply.isPositiveCompletion(reply)){
                ftpClient.disconnect();//断开连接
                System.out.println("连接服务器失败");  
            }
            // 下面三行代码必须要,而且不能改变编码格式
            ftpClient.setControlEncoding("GBK");
            
            // 如果采用默认端口,可以使用ftp.connect(url) 的方式直接连接FTP服务器  
            ftpClient.login(username, password);//登录
            //ftpClient.enterLocalPassiveMode();//使用被动模式
            reply=ftpClient.getReplyCode();//回执码
            if(!FTPReply.isPositiveCompletion(reply)){
                ftpClient.disconnect();
                 System.out.println("连接服务器失败");  
            }
            else{
                FTPClientConfig conf=new FTPClientConfig(FTPClientConfig.SYST_NT);
                conf.setServerLanguageCode("zh");
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);//设置文件类型
            }
              System.out.println("login");
        }
        catch(IOException e){
            e.printStackTrace();
        }
        return ftpClient;
    }
    
    /**
    *    退出登录并断开连接
    * @param ftpClient FTP客户端对象
    */
    public void logOutConnection(FTPClient ftpClient){
        try {
            ftpClient.logout();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        
        try {
            if(ftpClient.isConnected()){
                ftpClient.disconnect();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

AndroidManifest.xml中设置权限:

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.VIBRATE" />

在res/config.xml中添加:

<feature name="FtpClient">
        <param name="android-package" value="com.JajaCy.FtpClient.FtpClientPlugin"/>
    </feature>

assets\www\plugins\com.JajaCy.FtpClient这个目录中建一个名称为FtpClientPlugin.js的js文件

cordova.define('com.JajaCy.FtpClient.FtpClientPlugin', function(require, exports, module) {
    var exec=require('cordova/exec');
    module.exports={
        /**
        * 获取文件列表
        * param:data
        */
        getFiles:function(data1,data2,fn){
            /**
            一共五个参数
            第一个 :成功会掉 
            第二个 :失败回调 
            第三个 :将要调用的类的配置名字(在config.xml中配置 稍后在下面会讲解) 
            第四个 :调用的方法名(一个类里可能有多个方法 靠这个参数区分) 
            第五个 :传递的参数  以json的格式 
            */
            exec(function(result){
                console.log(result.Message);
                fn(result);//JSON.parse(result)
            },nativePluginErrorHandler,"FtpClient","list",[data1,data2])
        },
        /**
        * 上传文件
        * data1:服务器ip地址
        * data2:文件名称
        * data3:当前目录名称
        */
        put:function(data1,data2,data3,fn){
            exec(function(result){
            fn(result);
            },nativePluginErrorHandler,"FtpClient","put",[data1,data2,data3])
        },
        /**
        * 下载文件
        * data1:服务器ip地址
        * data2:文件名称
        * data3:当前目录名称
        */
        get:function(data1,data2,data3,fn){
            exec(function(result){
            fn(result);
            },nativePluginErrorHandler,"FtpClient","get",[data1,data2,data3])
        }
    }
});

 /**
成功时调用的方法
*/
function nativePluginResultHandler (result) {   
   //alert("SUCCESS: \r\n"+result );   
   console.log(result);
} 
/**
失败时调用的方法
*/  
function nativePluginErrorHandler (error) {   
   alert("ERROR: \r\n"+error );   
}

然后在cordova_plugins.js这个文件中进行插件配置:

{
    "file": "plugins/com.JajaCy.FtpClient/FtpClientPlugin.js",
        "id": "com.JajaCy.FtpClient.FtpClientPlugin",
        "clobbers": [
            "window.ftp"   //调用的方法名
        ]
}

在module.exports.metadata中添加:

module.exports.metadata = 
// TOP OF METADATA
{
    "com.JajaCy.FtpClient":"0.0.1"
}

开始进行调用:

window.ftp.get("192.168.1.108", '','image', function (data) {//下载指定目录的文件
            if (data == "success") {
                Ext.Msg.alert("菜品图片下载完成");
            }
            else{
                Ext.Msg.alert("未连接服务器!");
            }
        });
window.ftp.put("192.168.1.108", '','image', function (data) {//上传指定目录的文件
            if (data == "success") {
                Ext.Viewport.unmask();
                Ext.Msg.alert("菜品图片下载完成");
            }
            else{
                Ext.Viewport.unmask();
                Ext.Msg.alert("未连接服务器!");
            }
        });

 

posted @ 2014-12-08 14:05  Follow-your-heart  阅读(451)  评论(0编辑  收藏  举报