public class ProgressDialog extends AlertDialog
java.lang.Object
↳ android.app.Dialog
↳ android.app.AlertDialog
↳ android.app.ProgressDialog
从类的继承关系我们可以看到ProgressDialog继承至AlertDialog,所以我们今天自己写一个继承至AlertDialog的自定义进度条对话框。完成的功能是:下载盛付通的sdk,下载的过程中显示进度条,下载完毕之后将apk安装用户手机。开始我们的实验。
第一步、设计界面
主界面custompdview.xml 放置了一个按钮,用来触发下载apk事件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button android:layout_width="wrap_content" android:id="@+id/btncustom" android:text="演示自定义进度对话框"android:layout_height="wrap_content" android:layout_alignParentTop="true"android:layout_centerHorizontal="true" android:layout_marginTop="50dp"></Button>
</RelativeLayout>
自定义ProgressDialog界面downloadprogressdialog.xml
放置了一个SeekBar其实和ProgressBar功能一样,就是长得不一样,两个TextView
SeekBar用来显示下载进度,其中一个TextView用来显示当前下载的总量,另外一个用来显示下载的百分比。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_gravity="center_vertical" android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"android:id="@+id/tvprogressnum" android:text="" android:layout_below="@+id/seekbar"android:layout_alignParentLeft="true" android:layout_marginLeft="84dp"></TextView>
<SeekBar android:layout_width="match_parent" android:id="@+id/seekbar"android:layout_height="wrap_content" android:layout_alignParentTop="true"android:layout_alignParentLeft="true"></SeekBar>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"android:id="@+id/tvprogresspercent" android:text="" android:layout_alignTop="@+id/tvprogressnum"android:layout_toRightOf="@+id/tvprogressnum" android:layout_marginLeft="29dp"></TextView>
</RelativeLayout>
第二步、设计下载进度对话框DownloadProgressDialog.java
/**
*
*/
package com.figo.helloworld;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;
/**
* 自定义下载文件进度条对话框
* @author zhuzhifei
*
*/
public class DownloadProgressDialog extends AlertDialog {
private SeekBar mProgress;//显示进度
private TextView mProgressNum;//显示下载总量
private TextView mProgressPercent;//显示下载百分比
public static final int M = 1024 * 1024;//M
public static final int K = 1024;//K
private double dMax;//文件大小
private double dProgress;//进度
private int middle = K;//默认为K
private int prev = 0;//开始值
private Handler mViewUpdateHandler;//Handler用来通知更新进度
private static final NumberFormat nf = NumberFormat.getPercentInstance();//进度格式
private static final DecimalFormat df = new DecimalFormat("###.##");//文件大小格式
public DownloadProgressDialog(Context context) {
super(context);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(getContext());
mViewUpdateHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
//通过handler更新进度
super.handleMessage(msg);
double percent = dProgress / dMax;
if (prev != (int) (percent * 100)) {
mProgress.setProgress((int) (percent * 100));
mProgressNum.setText(df.format(dProgress) + "/"
+ df.format(dMax) + (middle == K ? "K" : "M"));
mProgressPercent.setText(nf.format(percent));
prev = (int) (percent * 100);
}
if (mProgress.getProgress() == 100) {
mProgressPercent.setText(nf.format(1));
}
}
};
//从自定义的对话框downloadprogressdialog.xml加载页面
View view = inflater.inflate(R.layout.downloadprogressdialog, null);
mProgress = (SeekBar) view.findViewById(R.id.seekbar);
mProgressNum = (TextView) view.findViewById(R.id.tvprogressnum);
mProgressPercent = (TextView) view.findViewById(R.id.tvprogresspercent);
setView(view);
onProgressChanged();
super.onCreate(savedInstanceState);
}
private void onProgressChanged() {
mViewUpdateHandler.sendEmptyMessage(0);//发送一条消息触发handleMessage事件
}
//获取下载文件的最大值
public double getDMax() {
return dMax;
}
//设置下载文件的最大值
public void setDMax(double max) {
if (max > M) {
middle = M;
} else {
middle = K;
}
dMax = max / middle;
}
//获取当前进度
public double getDProgress() {
return dProgress;
}
//设置当前进度
public void setDProgress(double progress) {
dProgress = progress / middle;
onProgressChanged();
}
}
第三步、设计Activity CustomPdActivity.java
/**
*
*/
package com.figo.helloworld;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
/**
* @author zhuzhifei
*
*/
public class CustomPdActivity extends Activity implements OnClickListener {
protected Context context;//上下文
private DownloadProgressDialog progressDialog;//自定义进度对话框
private Button btncustom;//按钮
//加载主界面
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custompdview);
btncustom = (Button) findViewById(R.id.btncustom);
btncustom.setOnClickListener(this);
context = getApplicationContext();
btncustom.setOnClickListener(this);
}
// 写一个下载异步任务
class DownLoadTask extends AsyncTask<Void, Integer, Uri> {
// 执行任务
@Override
protected Uri doInBackground(Void... params) {
return downLoad();
}
// 更新进度
@Override
protected void onProgressUpdate(Integer... progress) {
progressDialog.setDProgress(progress[0]);
}
// 任务执行完成之后
@Override
protected void onPostExecute(Uri result) {
if (progressDialog != null) {
progressDialog.dismiss();
}
if (result == null) {
Toast.makeText(context, "下载失败,请点击更新按钮重新下载", Toast.LENGTH_SHORT)
.show();
return;
}
Toast.makeText(context, "下载完毕,开始安装...", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(result,
"application/vnd.android.package-archive");
startActivity(intent);
finish();
}
// 下载程序
private Uri downLoad() {
URL url = null;
File file = null;
try {
// 下载盛付通手机版
url = new URL(
"http://spm.shengpay.com/apk/ShengPay-release.apk");
HttpURLConnection con = (HttpURLConnection) url
.openConnection();
int fileLength = con.getContentLength();
progressDialog.setDMax(fileLength);// 设置文件大小
InputStream in = con.getInputStream();
file = new File(context.getCacheDir(), "ShengPay-release.apk");
if (!file.exists()) {
file.createNewFile();
}
// 以下是设置权限,不然没有权限去解压会报没权限:
// Unable to open zip
// '/data/data/com.figo.helloworld/cache/ShengPay-release.apk':
// Permission denied
Runtime.getRuntime()
.exec("chmod 777 " + file.getAbsolutePath());
FileOutputStream out = new FileOutputStream(file);
byte[] bytes = new byte[1024];
int c;
int count = 0;
while ((c = in.read(bytes)) != -1) {
out.write(bytes, 0, c);
if (c < 1024) {
publishProgress(count * 1024 + c);
} else {
count++;
publishProgress(count * 1024);
}
}
in.close();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
return Uri.fromFile(file);
// return flag;
}
}
// 按钮点击事件
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btncustom:
progressDialog = new DownloadProgressDialog(this);
progressDialog.setTitle("文件下载");
progressDialog.show();
// 执行任务
new DownLoadTask().execute();
break;
}
}
}
第四步、AndroidManifest.xml注册Activity
<activity android:name=".CustomPdActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
第五步、运行效果