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