Android实现下载图片并保存到SD卡中

来源:互联网 发布:能隐藏号码打电话软件 编辑:程序博客网 时间:2024/05/22 14:21

1.java代码,下载图片的主程序

先实现显示图片,然后点击下载图片按钮,执行下载功能。

从网络上取得的图片,生成Bitmap时有两种方法,一种是先转换为byte[],再生成bitmap;一种是直接用InputStream生成bitmap。

(1)ICS4.0及更高版本中的实现

4.0中不允许在主线程,即UI线程中操作网络,所以必须新开一个线程,在子线程中执行网络连接;然后在主线程中显示图片。

public class IcsTestActivity extends Activity {    private final static String TAG = "IcsTestActivity";    private final static String ALBUM_PATH            = Environment.getExternalStorageDirectory() + "/download_test/";    private ImageView mImageView;    private Button mBtnSave;    private ProgressDialog mSaveDialog = null;    private Bitmap mBitmap;    private String mFileName;    private String mSaveMessage;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        mImageView = (ImageView)findViewById(R.id.imgSource);        mBtnSave = (Button)findViewById(R.id.btnSave);        new Thread(connectNet).start();        // 下载图片        mBtnSave.setOnClickListener(new Button.OnClickListener(){            public void onClick(View v) {                mSaveDialog = ProgressDialog.show(IcsTestActivity.this, "保存图片", "图片正在保存中,请稍等...", true);                new Thread(saveFileRunnable).start();        }        });    }    /**     * Get image from newwork     * @param path The path of image     * @return byte[]     * @throws Exception     */    public byte[] getImage(String path) throws Exception{        URL url = new URL(path);        HttpURLConnection conn = (HttpURLConnection) url.openConnection();        conn.setConnectTimeout(5 * 1000);        conn.setRequestMethod("GET");        InputStream inStream = conn.getInputStream();        if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){            return readStream(inStream);        }        return null;    }    /**     * Get image from newwork     * @param path The path of image     * @return InputStream     * @throws Exception     */    public InputStream getImageStream(String path) throws Exception{        URL url = new URL(path);        HttpURLConnection conn = (HttpURLConnection) url.openConnection();        conn.setConnectTimeout(5 * 1000);        conn.setRequestMethod("GET");        if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){            return conn.getInputStream();        }        return null;    }    /**     * Get data from stream     * @param inStream     * @return byte[]     * @throws Exception     */    public static byte[] readStream(InputStream inStream) throws Exception{        ByteArrayOutputStream outStream = new ByteArrayOutputStream();        byte[] buffer = new byte[1024];        int len = 0;        while( (len=inStream.read(buffer)) != -1){            outStream.write(buffer, 0, len);        }        outStream.close();        inStream.close();        return outStream.toByteArray();    }    /**     * 保存文件     * @param bm     * @param fileName     * @throws IOException     */    public void saveFile(Bitmap bm, String fileName) throws IOException {        File dirFile = new File(ALBUM_PATH);        if(!dirFile.exists()){            dirFile.mkdir();        }        File myCaptureFile = new File(ALBUM_PATH + fileName);        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));        bm.compress(Bitmap.CompressFormat.JPEG, 80, bos);        bos.flush();        bos.close();    }    private Runnable saveFileRunnable = new Runnable(){        @Override        public void run() {            try {                saveFile(mBitmap, mFileName);                mSaveMessage = "图片保存成功!";            } catch (IOException e) {                mSaveMessage = "图片保存失败!";                e.printStackTrace();            }            messageHandler.sendMessage(messageHandler.obtainMessage());        }    };    private Handler messageHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            mSaveDialog.dismiss();            Log.d(TAG, mSaveMessage);            Toast.makeText(IcsTestActivity.this, mSaveMessage, Toast.LENGTH_SHORT).show();        }    };    /*     * 连接网络     * 由于在4.0中不允许在主线程中访问网络,所以需要在子线程中访问     */    private Runnable connectNet = new Runnable(){        @Override        public void run() {            try {                String filePath = "http://img.my.csdn.net/uploads/201402/24/1393242467_3999.jpg";                mFileName = "test.jpg";                //以下是取得图片的两种方法                //////////////// 方法1:取得的是byte数组, 从byte数组生成bitmap                byte[] data = getImage(filePath);                if(data!=null){                    mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);// bitmap                }else{                    Toast.makeText(IcsTestActivity.this, "Image error!", 1).show();                }                ////////////////////////////////////////////////////////                //******** 方法2:取得的是InputStream,直接从InputStream生成bitmap ***********/                mBitmap = BitmapFactory.decodeStream(getImageStream(filePath));                //********************************************************************/                // 发送消息,通知handler在主线程中更新UI                connectHanlder.sendEmptyMessage(0);                Log.d(TAG, "set image ...");            } catch (Exception e) {                Toast.makeText(IcsTestActivity.this,"无法链接网络!", 1).show();                e.printStackTrace();            }        }    };    private Handler connectHanlder = new Handler() {        @Override        public void handleMessage(Message msg) {            Log.d(TAG, "display image");            // 更新UI,显示图片            if (mBitmap != null) {                mImageView.setImageBitmap(mBitmap);// display image            }        }    };}
(2)2.3以及以下版本可以在主线程中操作网络连接,但最好不要这样做,因为连接网络是阻塞的,如果5秒钟还没有连接上,就会引起ANR。

 

下载进度条的可以参考我的另外一个帖子:Android更新下载进度条

 

2.main.xml文件,只有一个button和一个ImageView

3.在mainfest文件中增加互联网权限和写sd卡的权限

4.预览图:

注:本实例图片是本人拍摄的位于东京西郊美军横田基地的一个大门。

横田基地的图片已经删除,所以无法加载。更新了我空间相册的另外一张图,此图较小,所以保存时很快,“图片正在保存中,请稍等...”的画面会一闪而过。

在4.2.1魅族mx3真机上验证如下:


原创粉丝点击