关于缓存图片到sd卡里的 用AsyncTask实现了异步下载图片了,现在想实现个缓存,想把图片下载到sd卡上,然后每次要下载图片时都检查看sd卡,如果有直接从sd卡上读取出来,没有再去下载并下载后存到sd卡上,有没有大神有代码可以学习下的? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 能存进去,那大牛你告诉我下,知道文件的具体路径和文件名称,怎么把它从sd卡里取出然后转化成bitmap流呢?求指导~ 这代码网上也应该有的吧,一段给你参考下File file = new File(Environment.getExternalStorageDirectory()+"/device.png"); InputStream inputStream = new FileInputStream(file); long length = file.length(); byte[] bytes = new byte[(int)length]; int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead= inputStream.read(bytes, offset, bytes.length-offset)) >= 0) { offset += numRead; } Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 思路就是这样的你需要有个配合记录的文件,比如数据库,我们的项目里是这么干的下载图片获取Bitmap,将bitmap写到sd卡,同时将图片sd卡保存的路径和图片对应的网络url做为一条记录存起。读取图片的时候,优先通过数据库获取url对应的本地路径的图片,没在本地取到bitmap,再去网络获取至于具体实现,楼主还是自己来吧,没什么难度 如果是本地图片的话应该很简单的吧,能拿到uri就很容易转bitmap的。BitmapFactory.decodeStream(is).is就是一个输入流。怎么做IO你到你具体的图片应该还是挺简单的吧。PS:我也是个新手,以上是些浅薄的建议望笑纳。 我刚做这个功能,哈哈,其实你第一次下载下来缓存的时候可以定义个全局图片存储的sdcard路径,这样,判断图片存不存在就用之前定义的路径,这样就ok了呀 我对图片出来的类:package com.mandao.animal1.util;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.util.Arrays;import java.util.Comparator;import java.util.List;import android.graphics.Bitmap;import android.os.Environment;import android.os.StatFs;import android.util.Log;import com.mandao.animal1.common.Config;/** * 将图片存到sdcard中。 * @author xiaomiao * */public class SaveImageToSdcard { private final String TAG = this.getClass().toString(); private int imageLength; public final int CACHE_SIZE = 20; //设置保存图片文件夹为20M public final static int MB = 1024 * 1024; public final int OVER_TIME = 14 * 24 * 60 * 60 * 1000; //过期时间总数是两个星期 public final String WHOLESALE_CONV = ".png"; /** * 构造函数传递图片大小 * @param imgLength */ public SaveImageToSdcard(int imgLength){ this.imageLength = imgLength; } /** * 图片保存 * @param 图片 * @param 保存路径地址 */ public void saveBmpToSd(Bitmap bm, String url,int chapter, String bookName) { if (bm == null) { Log.w(TAG, " trying to save null bitmap"); return; } // 判断sdcard上的空间 if (imageLength > freeSpaceOnSd()) { Log.w(TAG, "Low free space onsd, do not cache"); return; } //截取图片名称的后面名字 String filename = convertUrlToFileName(url); try { File file = new File(Config.FILEDIR); if(!file.exists()){ file.mkdir(); } //创建一个目录 file = new File(Config.FILEDIR + File.separator + bookName); if(!file.exists()){ file.mkdir(); } //当chapter为0时表示图片为封面,保存在漫画目录下 if(chapter == 0){ file = new File(Config.FILEDIR + File.separator + bookName, filename); }else{ //创建章节目录 file = new File(Config.FILEDIR + File.separator + bookName + File.separator + chapter); if(!file.exists()){ file.mkdir(); } //在目录下创建图片文件 file = new File(Config.FILEDIR + File.separator + bookName + File.separator + chapter, filename); } // //先删除两个星期没用过的图片// removeExpiredCache(FILEDIR + File.separator + bookName);// //要是还是不够大,删除近期没用过的图片// removeCache(FILEDIR + File.separator + bookName); if (!file.exists()) { file.createNewFile(); } OutputStream outStream = new FileOutputStream(file); bm.compress(Bitmap.CompressFormat.PNG, 100, outStream); outStream.flush(); outStream.close(); Log.i(TAG, "Image saved"); } catch (FileNotFoundException e) { Log.w(TAG, "FileNotFoundException"); } catch (IOException e) { Log.w(TAG, "IOException"); } } /** * 计算sdcard上的剩余空间 * @return */ private int freeSpaceOnSd() { boolean sdCardExit = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); //判断sdcard是否存在 if(sdCardExit) { StatFs stat = new StatFs(Environment.getExternalStorageDirectory() .getPath()); double sdFreeMB = ((double) stat.getAvailableBlocks() * (double) stat .getBlockSize()) / MB; return (int) sdFreeMB; }else { Log.i(TAG, "sdCard is not exist"); return 0; } } /** * 修改文件的最后修改时间 * @param 文件目录 * @param 文件名称 */ private void updateFileTime(String dir,String fileName) { File file = new File(dir,fileName); long newModifiedTime = System.currentTimeMillis(); file.setLastModified(newModifiedTime); } /** * 从图片路径中获取图片名 * @param url */ private String convertUrlToFileName(String url){ String name = ""; if(url != null && !"".equals(url)){ name = url.substring(url.lastIndexOf("/")+1, url.length()); } return name; } /** *计算存储目录下的文件大小,当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定 * 那么删除40%最近没有被使用的文件 * @param dirPath * @param filename */ private void removeCache(String dirPath) { File dir = new File(dirPath); File[] files = dir.listFiles(); if (files == null) { return; } int dirSize = 0; for (int i = 0; i < files.length;i++) { if(files[i].getName().toLowerCase().contains(WHOLESALE_CONV)) { dirSize += files[i].length(); } } if (dirSize > CACHE_SIZE * MB || imageLength > freeSpaceOnSd()) { int removeFactor = (int) ((0.4 * files.length) + 1); Arrays.sort(files, new FileLastModifSort()); Log.i(TAG, "Clear some expiredcache files "); for (int i = 0; i < removeFactor; i++) { if(files[i].getName().toLowerCase().contains(WHOLESALE_CONV)) { files[i].delete(); } } } } /** * 删除过期文件 * @param dirPath * @param filename */ public void removeExpiredCache(String dirPath) { List<String> listImage = GetSdcardImageList.getIamgeName(dirPath); //循环将过期的图片删除 if(listImage != null){ for(int i=0;i<listImage.size();i++){ File file = new File(dirPath,listImage.get(i)); if (System.currentTimeMillis() - file.lastModified() > OVER_TIME) { Log.i(TAG, "Clear some expiredcache files"); file.delete(); } } } } /** * TODO 根据文件的最后修改时间进行排序 * */ class FileLastModifSort implements Comparator<File>{ public int compare(File arg0, File arg1) { if (arg0.lastModified() > arg1.lastModified()) { return 1; } else if (arg0.lastModified() == arg1.lastModified()) { return 0; } else { return -1; } } } /** * 删除图片目录 * @param url */ public static void deleteDir(String url){ File f = new File(url); if(f.isDirectory()){ f.delete(); } }} 基站定位问题 ServerSocket做的端口监听时间长老是被回收的问题 dialog或者popupwindow中的edittext怎么插入图片 各位大侠 多多指教 [BK_求助]Android:配置文件AndroidManifest 如何隐藏键盘 android handler问题,更新ui 安卓app想向php段提交表单,POST方式可以吗? Button 是否点击 几个与Android开发环境搭建有关的问题,希望有好心人愿意帮忙解答? Win7下NDKR7b&&Cygwin,编译libiconv-1.14 java开发工程师转android移动开发需要了解哪些?
InputStream inputStream = new FileInputStream(file);
long length = file.length();
byte[] bytes = new byte[(int)length];
int offset = 0;
int numRead = 0;
while (offset < bytes.length && (numRead= inputStream.read(bytes, offset, bytes.length-offset)) >= 0)
{
offset += numRead;
}
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
你需要有个配合记录的文件,比如数据库,我们的项目里是这么干的
下载图片获取Bitmap,将bitmap写到sd卡,同时将图片sd卡保存的路径和图片对应的网络url做为一条记录存起。
读取图片的时候,优先通过数据库获取url对应的本地路径的图片,没在本地取到bitmap,再去网络获取至于具体实现,楼主还是自己来吧,没什么难度
package com.mandao.animal1.util;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;import android.graphics.Bitmap;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;import com.mandao.animal1.common.Config;/**
* 将图片存到sdcard中。
* @author xiaomiao
*
*/
public class SaveImageToSdcard {
private final String TAG = this.getClass().toString();
private int imageLength;
public final int CACHE_SIZE = 20; //设置保存图片文件夹为20M
public final static int MB = 1024 * 1024;
public final int OVER_TIME = 14 * 24 * 60 * 60 * 1000; //过期时间总数是两个星期
public final String WHOLESALE_CONV = ".png";
/**
* 构造函数传递图片大小
* @param imgLength
*/
public SaveImageToSdcard(int imgLength){
this.imageLength = imgLength;
}
/**
* 图片保存
* @param 图片
* @param 保存路径地址
*/
public void saveBmpToSd(Bitmap bm, String url,int chapter, String bookName) {
if (bm == null) {
Log.w(TAG, " trying to save null bitmap");
return;
}
// 判断sdcard上的空间
if (imageLength > freeSpaceOnSd()) {
Log.w(TAG, "Low free space onsd, do not cache");
return;
}
//截取图片名称的后面名字
String filename = convertUrlToFileName(url);
try {
File file = new File(Config.FILEDIR);
if(!file.exists()){
file.mkdir();
}
//创建一个目录
file = new File(Config.FILEDIR + File.separator + bookName);
if(!file.exists()){
file.mkdir();
}
//当chapter为0时表示图片为封面,保存在漫画目录下
if(chapter == 0){
file = new File(Config.FILEDIR + File.separator + bookName, filename);
}else{
//创建章节目录
file = new File(Config.FILEDIR + File.separator + bookName + File.separator + chapter);
if(!file.exists()){
file.mkdir();
}
//在目录下创建图片文件
file = new File(Config.FILEDIR + File.separator + bookName + File.separator + chapter, filename);
}
// //先删除两个星期没用过的图片
// removeExpiredCache(FILEDIR + File.separator + bookName);
// //要是还是不够大,删除近期没用过的图片
// removeCache(FILEDIR + File.separator + bookName);
if (!file.exists()) {
file.createNewFile();
}
OutputStream outStream = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
Log.i(TAG, "Image saved");
} catch (FileNotFoundException e) {
Log.w(TAG, "FileNotFoundException");
} catch (IOException e) {
Log.w(TAG, "IOException");
}
} /**
* 计算sdcard上的剩余空间
* @return
*/
private int freeSpaceOnSd() {
boolean sdCardExit = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
//判断sdcard是否存在
if(sdCardExit) {
StatFs stat = new StatFs(Environment.getExternalStorageDirectory()
.getPath());
double sdFreeMB = ((double) stat.getAvailableBlocks() * (double) stat
.getBlockSize()) / MB;
return (int) sdFreeMB;
}else {
Log.i(TAG, "sdCard is not exist");
return 0;
}
}
/**
* 修改文件的最后修改时间
* @param 文件目录
* @param 文件名称
*/
private void updateFileTime(String dir,String fileName) {
File file = new File(dir,fileName);
long newModifiedTime = System.currentTimeMillis();
file.setLastModified(newModifiedTime);
}
/**
* 从图片路径中获取图片名
* @param url
*/
private String convertUrlToFileName(String url){
String name = "";
if(url != null && !"".equals(url)){
name = url.substring(url.lastIndexOf("/")+1, url.length());
}
return name;
}
/**
*计算存储目录下的文件大小,当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定
* 那么删除40%最近没有被使用的文件
* @param dirPath
* @param filename
*/
private void removeCache(String dirPath) {
File dir = new File(dirPath);
File[] files = dir.listFiles();
if (files == null) {
return;
}
int dirSize = 0;
for (int i = 0; i < files.length;i++) {
if(files[i].getName().toLowerCase().contains(WHOLESALE_CONV)) {
dirSize += files[i].length();
}
}
if (dirSize > CACHE_SIZE * MB || imageLength > freeSpaceOnSd()) {
int removeFactor = (int) ((0.4 * files.length) + 1);
Arrays.sort(files, new FileLastModifSort());
Log.i(TAG, "Clear some expiredcache files ");
for (int i = 0; i < removeFactor; i++) {
if(files[i].getName().toLowerCase().contains(WHOLESALE_CONV)) {
files[i].delete();
}
}
}
}
/**
* 删除过期文件
* @param dirPath
* @param filename
*/
public void removeExpiredCache(String dirPath) {
List<String> listImage = GetSdcardImageList.getIamgeName(dirPath);
//循环将过期的图片删除
if(listImage != null){
for(int i=0;i<listImage.size();i++){
File file = new File(dirPath,listImage.get(i));
if (System.currentTimeMillis() - file.lastModified() > OVER_TIME) {
Log.i(TAG, "Clear some expiredcache files");
file.delete();
}
}
}
}
/**
* TODO 根据文件的最后修改时间进行排序 *
*/
class FileLastModifSort implements Comparator<File>{
public int compare(File arg0, File arg1) {
if (arg0.lastModified() > arg1.lastModified()) {
return 1;
} else if (arg0.lastModified() == arg1.lastModified()) {
return 0;
} else {
return -1;
}
}
}
/**
* 删除图片目录
* @param url
*/
public static void deleteDir(String url){
File f = new File(url);
if(f.isDirectory()){
f.delete();
}
}
}