Android实现使用sftp下载linux服务器上的图片文件

来源:互联网 发布:淘宝上僵尸手办来源 编辑:程序博客网 时间:2024/05/22 23:10
在工作的时候,APP改造时,精选页面和生活页面上面都有广告轮廓图片进行滚动,已达到宣传作用。而这些广告图片需要在內管中进行维护,然后我在內管中写了一个维护的方法,将图片保存在了linux服务上的一个分区下,保存图片的路径是: /home/weblogic/pdsebank/ibs/uploadTemp/pmobile/

该路径下是在內管中上传的图片(格式为.png),并将这些图片的名字、描述、路径等信息保存在了数据库中的一张表中。然后我在手机银行的后台写了一个接口,去从数据库中获取到了这些广告图片的信息,返回的是一个json格式的数据,其中就有广告图片的路径,路为:/home/weblogic/pdsebank/ibs/uploadTemp/pmobile/chosen_bander1.png(这只是其中一个广告图片的路径)。

然后我在android客户端去访问这个接口,获取到图片的url后,使用sftp访问linux服务器,去该路径下拿到该图片,并保存到本地的sdcard中,然后将sdcard中的图片读取出来,显示到ImageVIew控件中。


大体思路是这样的。

这是我们在我电脑上写的一个小的demo,模拟了工作中的linux服务器(在我电脑上搭建的linux服务器)。如果有什么问题,或者更好的方法请各位大神指教:


这是打印出的参考日志:


这是我在linux服务器上的存放的图片:


这是运行app后,下载到手机sdcard中的图片


代码实现:

需要的工具类,FileUtils.java、SDCardUtils.java是自己做项目写的,直接拿来用。

FileUtils.java

package com.example.test;import java.io.File;import android.content.Context;import android.os.Environment;public class FileUtils {public static final String CACHE = "cache";//缓存目录(主要用于缓存一些文件)public static final String ROOT = "GooglePlay";//定义该APP的根目录public static final String ICON = "icon";//缓存APP中的图标public static Context context;public FileUtils(Context context){this.context = context;}/** * 获取缓存图片路径 * @return/mnt/sdcard/GooglePlay/icon */public static File getIconDir() {return getDir(ICON);}/** * 获取缓存路径(里面缓存了json文件) * @return/mnt/sdcard/GooglePlay/cache */public static File getCacheDir() {return getDir(CACHE);}public static File getDir(String str) {StringBuilder path = new StringBuilder();if (isSDAvailable()) {path.append(Environment.getExternalStorageDirectory().getAbsolutePath());// /mnt/sdcardpath.append(File.separator);// '/'path.append(ROOT);// /mnt/sdcard/GooglePlaypath.append(File.separator);path.append(str);// /mnt/sdcard/GooglePlay/cache  或者  /mnt/sdcard/GooglePlay/icon} else {// sd卡不可用File filesDir = context.getCacheDir();// cachepath.append(filesDir.getAbsolutePath());// /data/data/com.xbmu.google/cachepath.append(File.separator);path.append(str);}File file = new File(path.toString());if (!file.exists() || !file.isDirectory()) {file.mkdirs();// 创建文件夹}return file;}/** * 判断sd卡是否可用 *  * @return */private static boolean isSDAvailable() {if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {return true;}return false;}}
SDCardUtils.java

package com.example.test;import java.io.File;import android.os.Environment;import android.os.StatFs;/** * SD卡相关的辅助类 *  * @author zhy *  */public class SDCardUtils{private SDCardUtils(){/* cannot be instantiated */throw new UnsupportedOperationException("cannot be instantiated");}/** * 判断SDCard是否可用 *  * @return */public static boolean isSDCardEnable(){return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);}/** * 获取SD卡路径 *  * @return /storage/emulated/0/ */public static String getSDCardPath(){return Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator;}/** * 获取SD卡的剩余容量 单位byte *  * @return */public static long getSDCardAllSize(){if (isSDCardEnable()){StatFs stat = new StatFs(getSDCardPath());// 获取空闲的数据块的数量long availableBlocks = (long) stat.getAvailableBlocks() - 4;// 获取单个数据块的大小(byte)long freeBlocks = stat.getAvailableBlocks();return freeBlocks * availableBlocks;}return 0;}/** * 获取指定路径所在空间的剩余可用容量字节数,单位byte *  * @param filePath * @return 容量字节 SDCard可用空间,内部存储可用空间 */public static long getFreeBytes(String filePath){// 如果是sd卡的下的路径,则获取sd卡可用容量if (filePath.startsWith(getSDCardPath())){filePath = getSDCardPath();} else{// 如果是内部存储的路径,则获取内存存储的可用容量filePath = Environment.getDataDirectory().getAbsolutePath();}StatFs stat = new StatFs(filePath);long availableBlocks = (long) stat.getAvailableBlocks() - 4;return stat.getBlockSize() * availableBlocks;}/** * 获取系统存储路径 *  * @return */public static String getRootDirectoryPath(){return Environment.getRootDirectory().getAbsolutePath();}}
SFtpUtil.java是自己参考网上的一些大神的例子,自己整合了一下,写出来的。有什么不足之处,请各位大神指教。
package com.example.test;import java.io.File;import java.util.Properties;import com.jcraft.jsch.Channel;import com.jcraft.jsch.ChannelSftp;import com.jcraft.jsch.JSch;import com.jcraft.jsch.JSchException;import com.jcraft.jsch.Session;import com.jcraft.jsch.SftpException;public class SFtpUtil {private static Session session  = null;private static Channel channel = null;private static ChannelSftp chSftp = null;/** * 链接sftp服务器 * @param ftpHost SFTP IP地址 * @param ftpUserName SFTP 用户名 * @param ftpPassword SFTP用户名密码 * @param ftpPort SFTP端口 */public static void connectFtpService(String ftpHost, String ftpUserName,String ftpPassword, int ftpPort){JSch jsch = new JSch();try {session = jsch.getSession(ftpUserName, ftpHost, ftpPort);session.setPassword(ftpPassword);session.setTimeout(100000);Properties config = new Properties();config.put("StrictHostKeyChecking", "no");session.setConfig(config);session.connect();} catch (JSchException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/** *  * @param ftpPath SFTP服务器中文件所在路径 格式: ftptest/aa * @param localPath 下载到本地的位置 格式:H:/download * @param fileName 文件名称 * @throws JSchException */public static void downloadSftpFile(String ftpPath, String localPath,String fileName) throws JSchException {channel = session.openChannel("sftp");channel.connect();chSftp  = (ChannelSftp) channel;String ftpFilePath = ftpPath + "/" + fileName;System.out.println("ftpFilePath:"+ftpFilePath);String localFilePath = localPath + File.separatorChar + fileName;System.out.println("localFilePath:"+localFilePath);try {chSftp .get(ftpFilePath, localPath);} catch (SftpException e) {e.printStackTrace();}}/** * 断开链接 */public static void disconnetFtpService(){try {} catch (Exception e) {e.printStackTrace();} finally {chSftp.quit();channel.disconnect();session.disconnect();}}}

以上都是我的准备工作,主要实现的逻辑在MainActivity.java类中

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <ImageView        android:id="@+id/id_icon"        android:layout_width="match_parent"        android:layout_height="160dp" /></RelativeLayout>
MainActivity.java

package com.example.test;import java.io.File;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.widget.ImageView;import com.jcraft.jsch.JSchException;public class MainActivity extends Activity {protected static final int LOADING_FAILED = -1;protected static final int LOADING_SUCCESS = 0;private SFtpUtil ftpUtil;private ImageView mImageView;private Bitmap bitmap;private Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {switch (msg.what) {case LOADING_SUCCESS:mImageView.setImageBitmap(bitmap);break;case LOADING_FAILED://图片不存在,设置默认图片mImageView.setImageResource(R.drawable.ic_launcher);break;default:break;}};};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mImageView = (ImageView) findViewById(R.id.id_icon);FileUtils fileUtils = new FileUtils(getApplicationContext());File cacheDir = fileUtils.getCacheDir();String cacheDirPath = cacheDir.getAbsolutePath()+File.separator;///mnt/sdcard/GooglePlay/cache/Log.e("缓存文件目录", cacheDirPath);File iconDir = fileUtils.getIconDir();///mnt/sdcard/GooglePlay/iconfinal String iconDirPath = iconDir.getAbsolutePath()+File.separator;Log.e("缓存图标目录", iconDirPath);final String path = SDCardUtils.getSDCardPath();Log.e("SD卡路径", path);///storage/emulated/0/String rootDirectoryPath = SDCardUtils.getRootDirectoryPath();///systemLog.e("系统存储路径", rootDirectoryPath);ftpUtil = new SFtpUtil();//开启一个线程去linux服务器上下载东西new Thread(new Runnable() {@Overridepublic void run() {try {ftpUtil.connectFtpService("192.168.1.110", "root", "q1w2e3r4", 22);ftpUtil.downloadSftpFile("/home/btt",iconDirPath, "chosen_bander1.png");ftpUtil.disconnetFtpService();File file = new File(iconDirPath);Message message = Message.obtain();if(file.isDirectory()){//判断文件目录是否存在/* * 这种方式存在缺陷,如果该目录(iconDirPath)下不存在我们所需要的图片, * 但是里面又有图片,就不会达到预期的效果if(file.list().length>0){//为true,表示该目录(iconDirPath)下存在文件String filePath = iconDirPath+"chosen_bander1.png";bitmap = BitmapFactory.decodeFile(filePath);message.what = LOADING_SUCCESS;}else{message.what = LOADING_FAILED;}*/String[] names = file.list();//获取if(names.length>0){//该目录下存在图片for (String name : names) {//循环遍历是否是我们在服务器端下载的文件(根据名字去判断)if("chosen_bander1.png".equals(name)){Log.e(iconDirPath+"目录下的需要展示文件名",name);String filePath = iconDirPath+"chosen_bander1.png";bitmap = BitmapFactory.decodeFile(filePath);message.what = LOADING_SUCCESS;}else{Log.e(iconDirPath+"目录下的不需要展示文件名",name);message.what = LOADING_FAILED;}}}else{message.what = LOADING_FAILED;}}else{message.what = LOADING_FAILED;}handler.sendMessage(message);} catch (JSchException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}).start();/*BitmapFactory.Options options = new BitmapFactory.Options();options.inSampleSize = 2;Log.e("图片路径:",iconDirPath+"chosen_bander1.png");Bitmap bitmap = BitmapFactory.decodeFile(iconDirPath+"chosen_bander1.png", options);mImageView.setImageBitmap(bitmap);*//*Bitmap bmpDefaultPic = null;if(bmpDefaultPic==null){bmpDefaultPic = BitmapFactory.decodeFile(iconDirPath+"chosen_bander1.png");}Log.e("bmpDefaultPic", (bmpDefaultPic==null)+"");Log.e("图片路径:",iconDirPath+"chosen_bander1.png");mImageView.setImageBitmap(bmpDefaultPic);*//*String filePath = iconDirPath+"chosen_bander1.png";File file = new File(filePath);if(file.exists()){ Bitmap bitmap = BitmapFactory.decodeFile(filePath); mImageView.setImageBitmap(bitmap);}else{//图片不存在,设置默认图片mImageView.setImageResource(R.drawable.ic_launcher);}*/}}
最后千万不要忘了在AndroidManifest.xml文件中配置访问网络的权限与读取sdcard卡的权限:

<uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
运行app后,成功将linux服务器上的图片下载到本地的sdcard卡中,并将sdcard中的图片显示在了ImageView控件上。打出的日志如下:

10-23 17:18:04.336: E/缓存文件目录(5558): /storage/emulated/0/GooglePlay/cache/
10-23 17:18:04.346: E/缓存图标目录(5558): /storage/emulated/0/GooglePlay/icon/
10-23 17:18:04.346: E/SD卡路径(5558): /storage/emulated/0/
10-23 17:18:04.346: E/系统存储路径(5558): /system
10-23 17:18:05.826: E//storage/emulated/0/GooglePlay/icon/目录下的需要展示文件名(5558): chosen_bander1.png


源码下载:

http://download.csdn.net/detail/btt2013/9661651



0 0
原创粉丝点击