一.客户端通信工具类:
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.SocketException; 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; /** * 用于Android和FTP服务器进行交互的工具类 */ public class FTPUtils { private FTPClient ftpClient = null; private static FTPUtils ftpUtilsInstance = null; private String ftpUrl; private int ftpPort; private String userName; private String userPassword; private final int connectTimeout = 5000; private FTPUtils() { ftpClient = new FTPClient(); } /* * 得到类对象实例(因为只能有一个这样的类对象,所以用单例模式) */ public static FTPUtils getInstance() { if (ftpUtilsInstance == null) { ftpUtilsInstance = new FTPUtils(); } return ftpUtilsInstance; } /** * 设置FTP服务器 * * @param FTPUrl * FTP服务器ip地址 * @param FTPPort * FTP服务器端口号 * @param UserName * 登陆FTP服务器的账号 * @param UserPassword * 登陆FTP服务器的密码 * @return */ public boolean initFTPSetting(String FTPUrl, int FTPPort, String UserName, String UserPassword) { ftpUrl = FTPUrl; ftpPort = FTPPort; userName = UserName; userPassword = UserPassword; int reply; try { //设定连接超时时间 ftpClient.setConnectTimeout(connectTimeout); // 要连接的FTP服务器Url,Port ftpClient.connect(FTPUrl, FTPPort); // 登陆FTP服务器 ftpClient.login(UserName, UserPassword); // 看返回的值是不是230,如果是,表示登陆成功 reply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { // 断开 ftpClient.disconnect(); return false; } return true; } catch (SocketException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } } /** * 断开FTP服务器 */ public boolean disconnectFTP(){ try { ftpClient.disconnect(); return true; } catch (IOException e) { e.printStackTrace(); return false; } } /** * 上传文件 * * @param FilePath * 要上传文件所在SDCard的路径 * @param FileName * 要上传的文件的文件名(如:Sim唯一标识码) * @return true为成功,false为失败 */ public boolean uploadFile(String FilePath, String FileName) { if (!ftpClient.isConnected()) { if (!initFTPSetting(ftpUrl, ftpPort, userName, userPassword)) { return false; } } try { // 设置存储路径 // ftpClient.makeDirectory("/FtpFileTest"); // ftpClient.changeWorkingDirectory("/FtpFileTest"); // 设置上传文件需要的一些基本信息 ftpClient.setBufferSize(1024); ftpClient.setControlEncoding("UTF-8"); ftpClient.enterLocalPassiveMode(); ftpClient.setFileType(FTP.BINARY_FILE_TYPE); // 文件上传吧~ FileInputStream fileInputStream = new FileInputStream(FilePath); ftpClient.storeFile(FileName, fileInputStream); // 关闭文件流 fileInputStream.close(); // 退出登陆FTP,关闭ftpCLient的连接 ftpClient.logout(); ftpClient.disconnect(); } catch (IOException e) { e.printStackTrace(); return false; } return true; } /** * 下载文件 * * @param FilePath * 要存放的文件的路径 * @param FileName * 远程FTP服务器上的那个文件的名字 * @return true为成功,false为失败 */ public boolean downLoadFile(String FilePath, String FileName) { if (!ftpClient.isConnected()) { if (!initFTPSetting(ftpUrl, ftpPort, userName, userPassword)) { return false; } } try { // 转到指定下载目录 ftpClient.changeWorkingDirectory("/data"); // 列出该目录下所有文件 FTPFile[] files = ftpClient.listFiles(); // 遍历所有文件,找到指定的文件 for (FTPFile file : files) { if (file.getName().equals(FileName)) { // 根据绝对路径初始化文件 File localFile = new File(FilePath); // 输出流 OutputStream outputStream = new FileOutputStream(localFile); // 下载文件 ftpClient.retrieveFile(file.getName(), outputStream); // 清除缓存 outputStream.flush(); // 关闭流 outputStream.close(); } } // 退出登陆FTP,关闭ftpCLient的连接 ftpClient.logout(); ftpClient.disconnect(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return true; } }
二.利用Android设备作为FTP服务器,以下是FTPServer类
import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.ftpserver.FtpServer; import org.apache.ftpserver.FtpServerFactory; import org.apache.ftpserver.ftplet.Authority; import org.apache.ftpserver.ftplet.DefaultFtplet; import org.apache.ftpserver.ftplet.FtpException; import org.apache.ftpserver.ftplet.FtpRequest; import org.apache.ftpserver.ftplet.FtpSession; import org.apache.ftpserver.ftplet.Ftplet; import org.apache.ftpserver.ftplet.FtpletResult; import org.apache.ftpserver.ftplet.UserManager; import org.apache.ftpserver.listener.ListenerFactory; import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory; import org.apache.ftpserver.usermanager.SaltedPasswordEncryptor; import org.apache.ftpserver.usermanager.impl.BaseUser; import org.apache.ftpserver.usermanager.impl.WritePermission; import android.os.Environment; public class FtpServerlet extends DefaultFtplet{ private FtpServer mFtpServer; private final int mPort = 2121; private final String mDirectory = Environment.getExternalStorageDirectory().getPath() + "/FtpFileTest"; private final String mUser = "way"; private final String mPassword = "way"; private static FtpServerlet mInstance; public static FtpServerlet getInstance(){ if(mInstance == null){ mInstance = new FtpServerlet(); } return mInstance; } /** * FTP启动 * @throws FtpException */ public void start() throws FtpException { if (null != mFtpServer && false == mFtpServer.isStopped()) { return; } File file = new File(mDirectory); if (!file.exists()) { file.mkdirs(); } FtpServerFactory serverFactory = new FtpServerFactory(); ListenerFactory listenerFactory = new ListenerFactory(); // 设定端末番号 listenerFactory.setPort(mPort); // 通过PropertiesUserManagerFactory创建UserManager然后向配置文件添加用户 PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory(); userManagerFactory.setPasswordEncryptor(new SaltedPasswordEncryptor()); UserManager userManager = userManagerFactory.createUserManager(); List<Authority> auths = new ArrayList<Authority>(); Authority auth = new WritePermission(); auths.add(auth); //添加用户 BaseUser user = new BaseUser(); user.setName(mUser); user.setPassword(mPassword); user.setHomeDirectory(mDirectory); user.setAuthorities(auths); userManager.save(user); // 设定Ftplet Map<String, Ftplet> ftpletMap = new HashMap<String, Ftplet>(); ftpletMap.put("Ftplet", this); serverFactory.setUserManager(userManager); serverFactory.addListener("default", listenerFactory.createListener()); serverFactory.setFtplets(ftpletMap); // 创建并启动FTPServer mFtpServer = serverFactory.createServer(); mFtpServer.start(); } /** * FTP停止 */ public void stop() { // FtpServer不存在和FtpServer正在运行中 if (null != mFtpServer && false == mFtpServer.isStopped()) { mFtpServer.stop(); } } @Override public FtpletResult onAppendStart(FtpSession session, FtpRequest request) throws FtpException, IOException { System.out.println("onAppendStart"); return super.onAppendStart(session, request); } @Override public FtpletResult onAppendEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { System.out.println("onAppendEnd"); return super.onAppendEnd(session, request); } @Override public FtpletResult onLogin(FtpSession session, FtpRequest request) throws FtpException, IOException { System.out.println("onLogin"); return super.onLogin(session, request); } @Override public FtpletResult onConnect(FtpSession session) throws FtpException, IOException { System.out.println("onConnect"); return super.onConnect(session); } @Override public FtpletResult onDisconnect(FtpSession session) throws FtpException, IOException { System.out.println("onDisconnect"); return super.onDisconnect(session); } @Override public FtpletResult onUploadStart(FtpSession session, FtpRequest request) throws FtpException, IOException { System.out.println("onUploadStart"); return super.onUploadStart(session, request); } @Override public FtpletResult onUploadEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { String FtpUploadPath = mDirectory + "/" + request.getArgument(); //接收到文件后立即删除 File uploadFile = new File(FtpUploadPath); uploadFile.delete(); return super.onUploadEnd(session, request); } }
三.客户端和服务器的AndroidManifest中添加相关权限
<!--允许应用打开网络套接口 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!--允许应用访问关于Wi-Fi网络的信息 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!-- 允许应用写用户的外部存储器 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 允许应用进入Wi-Fi的组播方式 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<!-- 允许应用改变Wi-Fi的连接状态 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!-- 允许应用改变网络的连接状态 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!-- 允许应用访问网络上的信息 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>