android开发步步为营之2:开发自定义进度条对话框

来源:互联网 发布:java socket 客户端 编辑:程序博客网 时间:2024/04/28 00:26

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>

 

第五步、运行效果