zoukankan      html  css  js  c++  java
  • 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:   vipa1888@163.com


    QQ   : 840950105  

    吐舌头随便把源码也给大家共享一下,免得大家复制麻烦,地址: http://download.csdn.net/detail/vipa1888/4224438

  • 相关阅读:
    Ubuntu 15.04 下apt-get安装JDK
    Ubuntu下apt-get安装Java,Tomcat
    虚拟化技术比较 PV HVM
    Java8 Lambda表达式教程
    SpringMVC实现上传和下载
    web.xml中的url-pattern映射规则
    java文件读写操作大全
    Java创建文件
    JAVA文件中获取路径及WEB应用程序获取路径方法
    session.flush()与session.clear()的区别及使用环境
  • 原文地址:https://www.cnblogs.com/springskyhome/p/3689932.html
Copyright © 2011-2022 走看看