您的位置:首页 > 移动开发 > Android开发

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

2014-08-13 14:17 232 查看
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。

public class AndroidTest2_3_3 extends Activity {

private final static String TAG = "AndroidTest2_3_3";

private final static String ALBUM_PATH

= Environment.getExternalStorageDirectory() + "/download_test/";

private ImageView imageView;

private Button btnSave;

private ProgressDialog myDialog = null;

private Bitmap bitmap;

private String fileName;

private String message;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

imageView = (ImageView)findViewById(R.id.imgSource);

btnSave = (Button)findViewById(R.id.btnSave);

String filePath = "http://hi.csdn.net/attachment/201105/21/134671_13059532779c5u.jpg";

fileName = "test.jpg";

try {

//////////////// 取得的是byte数组, 从byte数组生成bitmap

byte[] data = getImage(filePath);

if(data!=null){

bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);// bitmap

imageView.setImageBitmap(bitmap);// display image

}else{

Toast.makeText(AndroidTest2_3_3.this, "Image error!", 1).show();

}

////////////////////////////////////////////////////////

//******** 取得的是InputStream,直接从InputStream生成bitmap ***********/

bitmap = BitmapFactory.decodeStream(getImageStream(filePath));

if (bitmap != null) {

imageView.setImageBitmap(bitmap);// display image

}

//********************************************************************/

Log.d(TAG, "set image ...");

} catch (Exception e) {

Toast.makeText(AndroidTest2_3_3.this,"Newwork error!", 1).show();

e.printStackTrace();

}

// 下载图片

btnSave.setOnClickListener(new Button.OnClickListener(){

public void onClick(View v) {

myDialog = ProgressDialog.show(AndroidTest2_3_3.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(bitmap, fileName);

message = "图片保存成功!";

} catch (IOException e) {

message = "图片保存失败!";

e.printStackTrace();

}

messageHandler.sendMessage(messageHandler.obtainMessage());

}

};

private Handler messageHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

myDialog.dismiss();

Log.d(TAG, message);

Toast.makeText(AndroidTest2_3_3.this, message, Toast.LENGTH_SHORT).show();

}

};

}

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

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

[xhtml] view plaincopy

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/btnSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保存图片"
/>
<ImageView
android:id="@+id/imgSource"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
/>
</LinearLayout>

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

[xhtml] view plaincopy

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

4.预览图:

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: