在工作的时候,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/sdcard
path.append(File.separator);// '/'
path.append(ROOT);// /mnt/sdcard/GooglePlay
path.append(File.separator);
path.append(str);// /mnt/sdcard/GooglePlay/cache 或者 /mnt/sdcard/GooglePlay/icon
} else {
// sd卡不可用
File filesDir = context.getCacheDir();// cache
path.append(filesDir.getAbsolutePath());// /data/data/com.xbmu.google/cache
path.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 block
e.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;
}
};
};
@Override
protected 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/icon
final 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();// /system
Log.e("系统存储路径", rootDirectoryPath);
ftpUtil = new SFtpUtil();
//开启一个线程去linux服务器上下载东西
new Thread(new Runnable() {
@Override
public 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 block
e.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