前言
最近公司一个项目需要把图片上传到ftp服务器,以前没有写过这一方面的,只写过上传http的,当时也是很蒙,查了很多资料,幸好最后搞出来了,现在分享一下,希望对大家有一点帮助。
本篇博客的主要内容如下:
- 系统现有相机相册的调用
- 对照片进行裁剪
- 上传图片到Ftp
需要的准备:
1.commons-net-3.0.1.jar,大家可以去网上下载这个jar包,也可以直接下载我的demo
2.需要知道你要上传FTP服务器的hostname,服务器的端口号,登录账号,登录密码,保存的目录。
界面:
界面很简单,就两个按钮加一个图片展示
代码:
下面我就把代码贴上,布局xml我就不放了
1.FileTool(文件上传工具类)
public class FileTool {
/**
* Description: 向FTP服务器上传文件
*
* @param url
* FTP服务器hostname
* @param port
* FTP服务器端口
* @param username
* FTP登录账号
* @param password
* FTP登录密码
* @param path
* FTP服务器保存目录,是linux下的目录形式,如/photo/
* @param filename
* 上传到FTP服务器上的文件名,是自己定义的名字,
* @param input
* 输入流
* @return 成功返回true,否则返回false
*/
public static boolean uploadFile(String url, int port, String username,
String password, String path, String filename, InputStream input) {
boolean success = false;
FTPClient ftp = new FTPClient();
// LogUitl.Infor(url+port+username+password+path);
try {
int reply;
ftp.connect(url, port);// 连接FTP服务器
// 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
ftp.login(username, password);//登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return success;
}
ftp.setFileType(FTP.BINARY_FILE_TYPE);//上传上去的图片数据格式()一定要写这玩意,不然在服务器就打不开了
if (!ftp.changeWorkingDirectory(path)) {
if (ftp.makeDirectory(path)) {
ftp.changeWorkingDirectory(path);
}
}
// ftp.changeWorkingDirectory(path);
//设置成其他端口的时候要添加这句话
// ftp.enterLocalPassiveMode();
ftp.storeFile(filename, input);
input.close();
ftp.logout();
success = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return success;
}
}
2.打开相册,通过隐式意图打开
// 使用意图直接调用手机相册
Intent intentPhoto = new Intent(
Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// 打开手机相册,设置请求码
startActivityForResult(intentPhoto, 1);
3.Android 6.0加入了动态权限,权限有普通权限和危险权限两种,其中危险权限在6.0以上的手机是需要动态添加权限的,例如:读写SD的卡权限就需要动态添加
(1)首先判断当前系统是否是Android6.0(对应API 23)以及以上,如果是则判断是否含有了写文件的权限,如果没有则调用动态申请权限的代码,ActivityCompat.requestPermission方法的第一个参数是目标Activity,第二个参数是String[]字符数组类型的权限集,第三个即请求码:
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 4);
} else {
openAlbum();//此为打开相册的方法
}
}
(2)回调函数,申请权限后回调onRequestPermissionResult函数,第一个参数为请求码,第二个参数是刚刚请求的权限集,第三个参数是请求结果,0表示授权成功,-1表示授权失败:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case 4:
if(grantResults.length>0 &&grantResults[0] == PackageManager.PERMISSION_GRANTED){
openAlbum();
}else {
Toast.makeText(this, "请允许读取相册!", Toast.LENGTH_SHORT).show();
}
break;
default:
}
}
4.裁剪图片,选择完图片以后需要裁剪图片
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 150);
intent.putExtra("outputY", 150);
intent.putExtra("return-data", true);
startActivityForResult(intent, 2);
5.裁剪完图片以后需要重新命名,并重新保存到新的文件夹中,为以后上传图片做准备
Bundle extras = data.getExtras();
if (extras != null) {
String name = creatTime + ".jpg";//图片是以系统时间命名
Bundle bundle = data.getExtras();
// 获取相机返回的数据,并转换为Bitmap图片格式
Bitmap bitmap = (Bitmap) bundle.get("data");
FileOutputStream b = null;
File file = new File(getAlbumStorageDir("upload"), name);//upload 是裁剪完图片之后重新保存的文件夹名字
try {
b = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (b != null) {
b.flush();
b.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 将图片显示在ImageView里
ivPhoto.setImageBitmap(bitmap);
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
MainActivity.this.sendBroadcast(mediaScanIntent);
}
6.调用fileTool工具类进行上传
try {
FileInputStream in = new FileInputStream(photoFile);
//将下面的信息换成自己需要的即可
boolean flag = FileTool.uploadFile("FTP服务器hostname", 21,"登录名", "登录密码", "要传入的文件夹名字(若服务器没有这个文件夹,可以自动建文件夹,无需手动建)", photoFile.getName(), in);
if (flag == true) {
handler.sendEmptyMessage(1);
} else {
handler.sendEmptyMessage(2);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
总结
到这里基本就已经完成了,剩下的就是大家自己整合了。
Demo
GitHub
https://github.com/kongkongdaren/FTPPhotoDemo