安卓图片下载及存储

网上找到一个下载图片的工具类,下载到的图片是Drawable类型的。

  1 package com.cn.gordon.exhibition.walk.utils;
  2 
  3 import java.io.InputStream;
  4 import java.lang.ref.SoftReference;
  5 import java.net.URL;
  6 import java.net.URLConnection;
  7 import java.util.HashMap;
  8 import java.util.concurrent.BlockingQueue;
  9 import java.util.concurrent.LinkedBlockingQueue;
 10 import java.util.concurrent.RejectedExecutionHandler;
 11 import java.util.concurrent.ThreadPoolExecutor;
 12 import java.util.concurrent.TimeUnit;
 13 
 14 import android.graphics.drawable.Drawable;
 15 import android.os.Handler;
 16 import android.os.Looper;
 17 /**
 18  * 加载图片类
 19  * @author jialg
 20  *
 21  */
 22 public class AsyncImageLoader {
 23     private static final String TAG = "AsyncImageLoader";
 24     private ThreadPoolExecutor mPoolExecutor;
 25     private HashMap<String, SoftReference<Drawable>> imageCache;
 26     private Handler mMainThreadHandler;
 27  
 28     /**
 29      * 创建一个异步图片加载器,默认最大5个工作线程,最大等待队列20
 30      */
 31     public AsyncImageLoader() {
 32         this(5, 20);
 33     }
 34  
 35     /**
 36      * 创建一个异步图片加载器,当等待下载的图片超过设置的最大等待数量之后,会从等待队列中放弃一个最早加入队列的任务
 37      * 
 38      * @param maxPoolSize 最大工作线程数
 39      * @param queueSize 最大等待数
 40      */
 41     public AsyncImageLoader(int maxPoolSize, int queueSize) {
 42         this(2, maxPoolSize, 3, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(queueSize),
 43                 new ThreadPoolExecutor.DiscardOldestPolicy());
 44     }
 45  
 46     /**
 47      * 自定义线程池的加载器,请参考:{@link ThreadPoolExecutor}
 48      * 
 49      * @param corePoolSize
 50      * @param maximumPoolSize
 51      * @param keepAliveTime
 52      * @param unit
 53      * @param workQueue
 54      * @param handler
 55      */
 56     public AsyncImageLoader(int corePoolSize, int maximumPoolSize, long keepAliveTime,
 57             TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
 58         imageCache = new HashMap<String, SoftReference<Drawable>>();
 59         mPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit,
 60                 workQueue, handler);
 61         mMainThreadHandler = new Handler(Looper.getMainLooper());
 62     }
 63  
 64     /**
 65      * 异步加载一张图片
 66      * 
 67      * @param imageUrl
 68      * @param imageCallback
 69      */
 70     public void loadDrawable(final String imageUrl, final ImageCallback imageCallback) {
 71         if (imageCache.containsKey(imageUrl)) {
 72             SoftReference<Drawable> softReference = imageCache.get(imageUrl);
 73             Drawable drawable = softReference.get();
 74             if (drawable != null) {
 75                 imageCallback.onLoaded(drawable);
 76                 return;
 77             }
 78         }
 79         LoadImageTask task = new LoadImageTask(imageUrl, this, mMainThreadHandler, imageCallback);
 80         mPoolExecutor.execute(task);
 81     }
 82  
 83     /**
 84      * 停止线程池运行,停止之后,将不能在继续调用 {@link #loadDrawable(String, ImageCallback)}
 85      */
 86     public void shutdown() {
 87         mPoolExecutor.shutdown();
 88         imageCache.clear();
 89     }
 90  
 91     private void cache(String url, Drawable drawable) {
 92         imageCache.put(url, new SoftReference<Drawable>(drawable));
 93     }
 94  
 95     /**
 96      * 下载任务
 97      * 
 98      */
 99     private static final class LoadImageTask implements Runnable {
100  
101         private Handler mHandler;
102         private ImageCallback mCallback;
103         private AsyncImageLoader mLoader;
104         private String mPath;
105  
106         /**
107          * @param imgPath 要下载的图片地址
108          * @param loader 图片加载器
109          * @param handler 主线程Handler
110          * @param imageCallback 图片加载回调
111          */
112         public LoadImageTask(String imgPath, AsyncImageLoader loader, Handler handler,
113                 ImageCallback imageCallback) {
114             this.mHandler = handler;
115             this.mPath = imgPath;
116             this.mLoader = loader;
117             this.mCallback = imageCallback;
118         }
119  
120         @Override
121         public void run() {
122             URL url;
123             InputStream is = null;
124             try {
125                 url = new URL(mPath);
126                 URLConnection conn = url.openConnection();
127                 conn.connect();
128                 is = conn.getInputStream();
129                 final Drawable drawable = Drawable.createFromStream(is, "src");
130                 mLoader.cache(mPath, drawable);
131                 mHandler.post(new Runnable() {
132  
133                     @Override
134                     public void run() {
135                         mCallback.onLoaded(drawable);
136                     }
137                 });
138             } catch (final Exception e) {
139                 mHandler.post(new Runnable() {
140  
141                     @Override
142                     public void run() {
143                         mCallback.onError(e);
144                     }
145                 });
146             }
147         }
148     }
149  
150     /**
151      * 回调接口,在主线程中运行
152      * 
153      */
154     public static interface ImageCallback {
155         /**
156          * 加载成功
157          * 
158          * @param imageDrawable 下载下来的图片
159          */
160         public void onLoaded(Drawable drawable);
161  
162         /**
163          * 加载失败
164          * 
165          * @param e 异常
166          */
167         public void onError(Exception e);
168     }
169 }

图片下载之后,要进行存储,存储的类型是Bitmap,所以要将图片先转成BitmapDrawable,然后再转成Bitmap,运用上面的工具类进行图片的下载,并进行保存。

public class EntryActivity extends Activity {
    private AsyncImageLoader asyncImageLoader;
    private static String ALBUM_PATH = getSDPath() +         java.io.File.separator +  "exhibition_walk"; 
    
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.walkmain);
        asyncImageLoader= new AsyncImageLoader();
        init();
        
    }  
    private void init(){
        asyncImageLoader.loadDrawable(urlStr, new ImageCallback(){
                     @Override
                     public void onLoaded(Drawable imageDrawable) {
                         if(imageDrawable != null){
                             v1.setImageDrawable(imageDrawable);
                             BitmapDrawable draw = (BitmapDrawable) imageDrawable;
                             final Bitmap bitmap = draw.getBitmap();
                             try {  
                                 if (bitmap!=null) {
                                     Toast.makeText(EntryActivity.this, "下载的图片可用", Toast.LENGTH_SHORT).show();
                                     savePicture(bitmap, System.currentTimeMillis()+".jpg");  
                                    }else{
                                        
                                        Toast.makeText(EntryActivity.this, "下载的图片不可用", Toast.LENGTH_SHORT).show();
                                    }
                             } catch (IOException e) {  
                                 e.printStackTrace();  
                             }  
                         }
                     }

                    @Override
                    public void onError(Exception e) {
                        
                    }
                });
    }
    private void savePicture(Bitmap bitmap,String fileName) throws IOException{
        File dirFile = new File(ALBUM_PATH);  
        if(!dirFile.exists()){  
            dirFile.mkdirs();  
            Toast.makeText(EntryActivity.this, "创建文件夹", Toast.LENGTH_SHORT).show();
        }  
        File myCaptureFile = new File(ALBUM_PATH +  java.io.File.separator +fileName);  
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));  
        bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);  
        bos.flush();  
        bos.close();  
    }
/**
     * 获取sd卡的路径
     * 
     * @return 路径的字符串
     */
    public static String getSDPath() {
        File sdDir = null;
        boolean sdCardExist = Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在
        if (sdCardExist) {
            sdDir = Environment.getExternalStorageDirectory();// 获取外存目录
        }
        return sdDir.toString();
    }

}  

最后,图片存储到sd卡上,要进行权限的声明:

1 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
原文地址:https://www.cnblogs.com/SeawinLong/p/4101031.html