本文主要是讲解Android服务器之FTP服务器的上传下载功能,也是对之前所做项目的整理。
主要的代码块如下所示,对代码中相应地方稍作调整,复制粘贴到项目即可以使用,代码中会提供相应注释。
1.MainActivity
package com.example.ftpcommunication;
import org.apache.commons.net.ftp.FTPClient;
import android.os.Bundle;
import android.os.StrictMode;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
*
* 1.文件上传到FTP服务器
* 2.从FTP服务器上下载文件
* 所需jar包:commons-net-3.0.1.jar
* 将commons-net-3.0.1.jar放于libs中
*
*/
public class MainActivity extends Activity implements OnClickListener {
private String TAG="MainActivity";
//定义Buttons
private Button buttonUpLoad = null;
private Button buttonDownLoad = null;
private FTPClient ftpClient = null;
//FTP工具类
private FTPUtils ftpUtils = null;
@SuppressLint("NewApi") @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ftpmain);
//获取控件对象
buttonUpLoad = (Button) findViewById(R.id.button_upload);
buttonDownLoad = (Button) findViewById(R.id.button_download);
//设置控件对应相应函数
buttonUpLoad.setOnClickListener(this);
buttonDownLoad.setOnClickListener(this);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
//初始化和FTP服务器交互的类
InitFTPServerSetting();
}
public void InitFTPServerSetting() {
// TODO Auto-generated method stub
ftpUtils = FTPUtils.getInstance();
@SuppressWarnings("unused")
//记得修改成自己的
boolean flag = ftpUtils.initFTPSetting("192.168.1.106", 21, "admin", "123456");
}
@SuppressLint("SdCardPath") @Override
public void onClick(final View v) {
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.button_upload: {
//上传文件
Log.d(TAG,"上传文件");
// FTPUtils.getInstance().uploadFile("/sdcard/upload/", "user.xml","Test28","user.xml");
FTPUtils.getInstance().uploadMultiFile("/sdcard/upload/feedback_info/", "aa/",true);
}
//此处不能使用Toast,否则会报错
/* Toast.makeText(getApplicationContext(), "文件上传成功",
Toast.LENGTH_SHORT).show();*/
break;
case R.id.button_download: {
//下载文件
Log.d(TAG,"下载文件");
FTPUtils.getInstance().downLoadFile("sdcard/","/Test/", "user.xml");
//此处不能使用Toast,否则会报错
/*Toast.makeText(getApplicationContext(), "文件下载成功",
Toast.LENGTH_SHORT).show();*/
}
break;
default:
break;
}
}
}).start();
}
}
2.FTPUtils
/**
*
* 用于Android和FTP服务器进行交互的工具类
*
*/
public class FTPUtils {
private String TAG="FTPUtils";
private FTPClient ftpClient = null;
private static FTPUtils ftpUtilsInstance = null;
private String FTPUrl;
private int FTPPort;
private String UserName;
private String UserPassword;
// private String RemoteDir;
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)
{
this.FTPUrl = FTPUrl;
this.FTPPort = FTPPort;
this.UserName = UserName;
this.UserPassword = UserPassword;
int reply;
try {
//1.要连接的FTP服务器Url,Port
ftpClient.connect(FTPUrl, FTPPort);
//2.登陆FTP服务器
ftpClient.login(UserName, UserPassword);
//3.看返回的值是不是230,如果是,表示登陆成功
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply))
{
//断开
ftpClient.disconnect();
Log.d(TAG,"已断开连接");
return false;
}
Log.d(TAG,"连接成功");
return true;
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
}
/**
* 上传单个文件
* @param FilePath 要上传文件所在SDCard的路径
* @param FileName 要上传的文件的文件名(如:Sim唯一标识码)
* @return true为成功,false为失败
*/
@SuppressLint("SdCardPath")
public boolean uploadFile(String LocFilePath, String LocFileName,String RemotePath,String RemFileName) {
if (!ftpClient.isConnected())
{
if (!initFTPSetting(FTPUrl, FTPPort, UserName, UserPassword))
{
return false;
}
}
try {
//设置存储路径
ftpClient.makeDirectory(RemotePath);
ftpClient.changeWorkingDirectory(RemotePath);
//设置上传文件需要的一些基本信息
ftpClient.setBufferSize(1024);
ftpClient.setControlEncoding("UTF-8");
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
//文件上传吧~
FileInputStream fileInputStream = new FileInputStream(LocFilePath+LocFileName);
ftpClient.storeFile(LocFileName, fileInputStream);
//关闭文件流
fileInputStream.close();
//退出登陆FTP,关闭ftpCLient的连接
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
return true;
}
/**
* 上传多个文件
* 批量上传
*/
public boolean uploadMultiFile(String LocFilePath,String RemotePath,boolean del){
try {
File file = new File(LocFilePath);
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isFile()
&& files[i].getName().indexOf("bak") == -1) {
synchronized(RemotePath){
if (this.uploadFile(LocFilePath, files[i].getName(),
RemotePath, files[i].getName())
&& del) {
deleteFile(LocFilePath + files[i].getName());
}
}
}
}
return true;
} catch (Exception e) {
e.printStackTrace();
} finally {
/* //退出登陆FTP,关闭ftpCLient的连接
ftpClient.logout();
ftpClient.disconnect(); */
}
return false;
}
/**
* 下载单个文件
* @param FilePath 要存放的文件的路径
* @param FileName 远程FTP服务器上的那个文件的名字
* @return true为成功,false为失败
*/
@SuppressLint("SdCardPath")
public boolean downLoadFile(String LocFilePath,String RemotePath,String RemFileName) {
if (!ftpClient.isConnected())
{
if (!initFTPSetting(FTPUrl, FTPPort, UserName, UserPassword))
{
return false;
}
}
try {
// 转到指定下载目录
ftpClient.changeWorkingDirectory(RemotePath);
// 列出该目录下所有文件
FTPFile[] files = ftpClient.listFiles();
// 遍历所有文件,找到指定的文件
for (FTPFile file : files) {
if (file.getName().equals(RemFileName)) {
//根据绝对路径初始化文件
@SuppressWarnings("unused")
File localFile = new File(RemotePath);
// 输出流
OutputStream outputStream = new FileOutputStream(LocFilePath+RemFileName);
// 下载文件
ftpClient.retrieveFile(file.getName(), outputStream);
//关闭流
outputStream.close();
}
}
//退出登陆FTP,关闭ftpCLient的连接
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
/**
* 删除文件
* @param filePath
* @return
*/
public boolean deleteFile(String filePath) {
File file = new File(filePath);
if (!file.exists()) {
return false;
}
if (!file.isFile()) {
return false;
}
return file.delete();
}
}
3.导入commons-net-3.0.1.jar,这个包网上有下载。
注意一定要把它放到工程的libs目录下
。
4.布局文件:activity_ftpmain.xml
<LinearLayout 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:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="24dip"
android:layout_gravity="center"
android:text="FTP上传下载测试 "/>
<Button
android:id="@+id/button_upload"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="上传"
/>
<Button
android:id="@+id/button_download"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="下载"
/>
</LinearLayout>
5.Manifest文件配置
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>