前言
最近公司一个项目需要把图片上传到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
https://download.csdn.net/download/wen_haha/10458986
GitHub
https://github.com/kongkongdaren/FTPPhotoDemo