android自定義Dialog實現文件下載和下載進度

       最近要實現一個檢驗更新的功能,當進入程序的時候,開始請求服務器,然後得到服務器的響應更新結果!如果需要更新的話,就打開一個Dialog,在Dialog上面下載文件,於是自己研究了一個自定義dialog的實現,也完成了在dialog上面有進度的下載文件(自己的作圖技術查,隨便畫了一個背景吐舌頭),效果圖如下:

 

 

效果如上,下面我把代碼貼出來:

主界面Activity: 主界面就定義了一個Button,當點擊Button後,彈出Dialog

package com.spring.sky.dialog.download;


import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

/**
 * 主界面
 * @author spring sky
 */
public class MainActivity extends Activity implements
		android.view.View.OnClickListener {
	private Button bt;
	private ImageView imageView;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		init();
	}

	private void init() {
		bt = (Button) this.findViewById(R.id.bt);
		bt.setOnClickListener(this);
		imageView = (ImageView) findViewById(R.id.imageview);
	}

	@Override
	public void onClick(View v) {
		DownloadDialog dialog = new DownloadDialog(this,
				"http://img308.ph.126.net/AM2zg9CNx0kG8K3jY122RQ==/3902932027070067384.jpg");
		dialog.setImageView(imageView);  //當前下載的是一個圖片,所以下載完成後,把這個圖片顯示在界面上
		dialog.show();
	}
}

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

        <Button
            android:id="@+id/bt"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="彈出框下載文件" />

        <ImageView
            android:id="@+id/imageview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
             />
    </LinearLayout>

</ScrollView>


自定義的Dialog  :  這個基本就是實現Dialog的佈局,還有Dialog的背景透明效果,然後用戶點擊了下載,啓動一個新線程下載,同時用handler來發送消息,讓下載操作的進度在Dialog的view上面呈現出來,當下載完成的時候,點擊按鈕就可以看見下載的圖片了!  (我測試爲了簡單就用了一個ImageView把圖片顯示出來)

package com.spring.sky.dialog.download;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;


import android.app.Dialog;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

/***
 * dialog文件下載
 * @author spring sky <br>
 * QQ :840950105
 */
public class DownloadDialog extends Dialog implements
		android.view.View.OnClickListener {
	private static final int DOWNLOAD_PREPARE = 0;
	private static final int DOWNLOAD_WORK = 1;
	private static final int DOWNLOAD_OK = 2;
	private static final int DOWNLOAD_ERROR = 3;
	private static final String TAG = "IndexActivity";
	private Context mContext;

	private Button bt;
	private ProgressBar pb;
	/** 下載過程中不能點擊 */
	private boolean isClick = false;
	private boolean downloadOk = false;
	private TextView tv;
	/**
	 * 下載的url
	 */
	private String url = null;
	private String filePath;

	/**
	 * 文件大小
	 */
	int fileSize = 0;

	/**
	 * 下載的大小
	 */
	int downloadSize = 0;

	/**
	 * handler
	 */
	private Handler handler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case DOWNLOAD_PREPARE:
				Toast.makeText(mContext, "準備下載", Toast.LENGTH_SHORT).show();
				pb.setVisibility(ProgressBar.VISIBLE);
				Log.e(TAG, "文件大小:" + fileSize);
				pb.setMax(fileSize);
				break;
			case DOWNLOAD_WORK:
				Log.e(TAG, "已經下載:" + downloadSize);
				pb.setProgress(downloadSize);
				int res = downloadSize * 100 / fileSize;
				tv.setText("已下載:" + res + "%");
				bt.setText(FileUtil.FormetFileSize(downloadSize) + "/"
						+ FileUtil.FormetFileSize(fileSize));
				break;
			case DOWNLOAD_OK:
				downloadOk = true;
				bt.setText("下載完成顯示圖片");
				downloadSize = 0;
				fileSize = 0;
				Toast.makeText(mContext, "下載成功", Toast.LENGTH_SHORT).show();
				break;
			case DOWNLOAD_ERROR:
				downloadSize = 0;
				fileSize = 0;
				Toast.makeText(mContext, "下載失敗", Toast.LENGTH_SHORT).show();
				break;
			}
			super.handleMessage(msg);
		}
	};

	private ImageView imageView;

	public DownloadDialog(Context context, String url) {

		super(context, R.style.Theme_CustomDialog);
		mContext = context;
		this.url = url;
		filePath = FileUtil.getPath(mContext, url);
	}

	@Override
	public void cancel() {
		super.cancel();
	}

	/**
	 * 下載文件
	 */
	private void downloadFile() {
		try {
			URL u = new URL(url);
			URLConnection conn = u.openConnection();
			InputStream is = conn.getInputStream();
			fileSize = conn.getContentLength();
			if (fileSize < 1 || is == null) {
				sendMessage(DOWNLOAD_ERROR);
			} else {
				sendMessage(DOWNLOAD_PREPARE);
				FileOutputStream fos = new FileOutputStream(filePath);
				byte[] bytes = new byte[1024];
				int len = -1;
				while ((len = is.read(bytes)) != -1) {
					fos.write(bytes, 0, len);
					fos.flush();
					downloadSize += len;
					sendMessage(DOWNLOAD_WORK);
				}
				sendMessage(DOWNLOAD_OK);
				is.close();
				fos.close();
			}
		} catch (Exception e) {
			sendMessage(DOWNLOAD_ERROR);
			e.printStackTrace();
		}
	}
	/***
	 * 得到文件的路徑
	 * 
	 * @return
	 */
	public String getFilePath() {
		return filePath;
	}
	private void init() {
		bt = (Button) this.findViewById(R.id.down_bt);
		bt.setOnClickListener(this);
		tv = (TextView) this.findViewById(R.id.down_tv);
		pb = (ProgressBar) this.findViewById(R.id.down_pb);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.down_bt:
			if (isClick) {
				// 啓動一個線程下載文件
				Thread thread = new Thread(new Runnable() {
					@Override
					public void run() {
						downloadFile();
					}
				});
				thread.start();
				isClick = false;
			}

			if (downloadOk) // 下載完成後 ,把圖片顯示在ImageView上面
			{
				imageView.setImageBitmap(BitmapFactory.decodeFile(filePath));
				cancel();
			}
			break;
		default:
			break;
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.download_layuot);
		init();
	}

	/**
	 * @param what
	 */
	private void sendMessage(int what) {
		Message m = new Message();
		m.what = what;
		handler.sendMessage(m);
	}

	public void setImageView(ImageView imageView) {
		this.imageView = imageView;
	}

	@Override
	public void show() {
		isClick = true;
		downloadOk = false;
		super.show();
	}

}

dialog的download_layuot.xml佈局文件:  這個使用了相對佈局,讓ProgressBar和TextView呈現在一個居中位置,看起來就像連在一起的效果!同時Button來實現文件大小的顯示

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/dialog"
    android:orientation="vertical" >
	<TextView
	    	android:layout_margin="5dip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="有新的版本更新"
            android:textSize="20dip"
            android:textColor="@android:color/white" />
	
	<RelativeLayout
	     android:layout_margin="10dip"
	     android:layout_width="fill_parent"
	     android:layout_height="wrap_content"
          android:layout_gravity="center_horizontal"
	     >
	     <ProgressBar
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:id="@+id/down_pb"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="260dip"
            android:layout_height="wrap_content"
            />
	     <TextView
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:id="@+id/down_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="開始下載..."
            android:textColor="@android:color/white"
            android:textSize="20sp" />
	</RelativeLayout>
        <Button
            android:layout_gravity="center_horizontal"
            android:id="@+id/down_bt"
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:text="點擊下載"
            android:textColor="@android:color/black"
            android:textSize="16sp"
            android:layout_marginTop="10dip"
            android:layout_marginBottom="10dip" />
</LinearLayout>


在dialog中需要一個樣式,這個樣式可以實現Dialog後面的背景透明:

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke android:width="3dp"/>
    <corners android:radius="3dp" />
    <padding android:left="10dp" android:top="10dp"
        android:right="10dp" android:bottom="10dp" />
    <solid android:color="@android:color/transparent"/>
</shape>


 

還有一個FileUtil.java的文件工具類:

package com.spring.sky.dialog.download;

import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.DecimalFormat;

import android.content.Context;
import android.os.Environment;
import android.util.Log;

/**
 * 文件工具類
 * @author spring sky
 *
 */
public class FileUtil {
	/**
	 * 獲取目錄名稱
	 * @param url
	 * @return FileName
	 */
	public static String getFileName(String url)
	{
		int lastIndexStart = url.lastIndexOf("/");
		if(lastIndexStart!=-1)
		{
			return url.substring(lastIndexStart+1, url.length());
		}else{
			return new Timestamp(System.currentTimeMillis()).toString();
		}
	}
	/**
	 * 判斷SD卡是否存在
	 * @return boolean
	 */
	public static boolean checkSDCard() {
		if (android.os.Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED)) {
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * 保存目錄目錄到目錄
	 * @param context
	 * @return  目錄保存的目錄
	 */
	public static String setMkdir(Context context)
	{
		String filePath = null;
		if(checkSDCard())
		{
			filePath = Environment.getExternalStorageDirectory()+File.separator+"yishuabao"+File.separator+"downloads";
		}else{
			filePath = context.getCacheDir().getAbsolutePath()+File.separator+"yishuabao"+File.separator+"downloads";
		}
		File file = new File(filePath);
		if(!file.exists())
		{
			file.mkdirs();
			Log.e("file", "目錄不存在   創建目錄    ");
		}else{
			Log.e("file", "目錄存在");
		}
		return filePath;
	}
	
	/**
	 * 獲取路徑
	 * @return
	 * @throws IOException
	 */
	public static  String getPath(Context context,String url)
	{
		String path = null;
		try {
			path = FileUtil.setMkdir(context)+File.separator+url.substring(url.lastIndexOf("/")+1);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return path;
	}
	
	/**
	 * 獲取文件的大小
	 * 
	 * @param fileSize
	 *            文件的大小
	 * @return
	 */
	public static String FormetFileSize(int fileSize) {// 轉換文件大小
		DecimalFormat df = new DecimalFormat("#.00");
		String fileSizeString = "";
		if (fileSize < 1024) {
			fileSizeString = df.format((double) fileSize) + "B";
		} else if (fileSize < 1048576) {
			fileSizeString = df.format((double) fileSize / 1024) + "K";
		} else if (fileSize < 1073741824) {
			fileSizeString = df.format((double) fileSize / 1048576) + "M";
		} else {
			fileSizeString = df.format((double) fileSize / 1073741824) + "G";
		}
		return fileSizeString;
	}
	
}


以上代碼邏輯可能簡單,主要的是要懂得dialog的佈局效果的! 同時使用Handler動態的顯示出下載進度!  共享給大家,和大家共同學習!  微笑

如有疑問,請聯繫:

Author:   spring sky  

Email:   [email protected]


QQ   : 840950105  

 

吐舌頭隨便把源碼也給大家共享一下,免得大家複製麻煩,地址: http://download.csdn.net/detail/vipa1888/4224438

 

 

 

 

發佈了67 篇原創文章 · 獲贊 238 · 訪問量 51萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章