目录

  • 1 第一周 android简介
    • 1.1 第一课 Android基础入门1
    • 1.2 第二课 Android基础入门2
    • 1.3 第三课 Android UI开发介绍
  • 2 第二周 android布局
    • 2.1 第一课 Android 布局文件介绍1
    • 2.2 第二课 Android 布局文件介绍2
    • 2.3 第三课 Android 布局文件介绍3
  • 3 第三周 Android UI组件开发
    • 3.1 第一课 Button和ImageButton
    • 3.2 第二课 TextView和EditText
    • 3.3 第三课 RadioButton和CheckBox
  • 4 第四周 Android UI组件开发
    • 4.1 第一课 Spinner和ListView
    • 4.2 第二课 应用案例-手机信息页面
    • 4.3 第三课 Android生命周期
  • 5 第五周 Android组件通信
    • 5.1 第一课 Intent的介绍
    • 5.2 第二课 Intent实现各种系统功能
    • 5.3 第三课 应用案例-手机注册页面
  • 6 第六周 数据存储
    • 6.1 第一课 应用案例-新建联系人
    • 6.2 第二课 数据存储-简单文件存储
    • 6.3 第三课 SharedPreferences存储
  • 7 第七周 数据存储
    • 7.1 第一课 xml文件存储
    • 7.2 第二课 应用案例-植物百科
    • 7.3 第三课  ListView 组件高级使用
  • 8 第八周 SQLite数据库
    • 8.1 第一课 应用案例-应用列表
    • 8.2 第二课 使用SQLite数据库存储(创建数据库和表)
    • 8.3 第三课 使用SQLite数据库存储(对表数据操作)
  • 9 第九周 项目实战-商品购物车处理
    • 9.1 第一课 使用SQLite数据库存储(对表数据查询)
    • 9.2 第二课 商品购物车处理(布局)
    • 9.3 第三课 商品购物车处理(数据处理)
  • 10 第十周 内容提供者及广播
    • 10.1 第一课 内容提供者的使用
    • 10.2 第二课 广播概念以及如何使用
    • 10.3 第三课 自定义广播
  • 11 第十一周 广播和服务
    • 11.1 第一课 应用案例-电池电量
    • 11.2 第二课 应用案例-通话记录
    • 11.3 第三课 服务简介
  • 12 第十二周 服务应用
    • 12.1 第一课 应用案例—音乐播放器
    • 12.2 第二课 应用案例—地震监测
    • 12.3 第三课 获得手机SIM卡信息
  • 13 第十三周 网络编程
    • 13.1 第一课 网络编程入门
    • 13.2 第二课 使用HttpClient访问网络
    • 13.3 第三课 webview组件
  • 14 第十四周 网络编程应用案例
    • 14.1 第一课 消息机制简介
    • 14.2 第二课 应用案例-应用升级
    • 14.3 第三课 应用案例-应用升级
第二课 应用案例-应用升级

案例  应用升级

一、案例描述

1、考核知识点

    Handler消息机制原理

    AsyncTask

    HttpClient

    文件下载

2、练习目标

    掌握Hanlder的使用

    掌握如何向服务器请求数据

    掌握从服务器下载文件

3、需求分析

应用软件都有一个必需的功能:软件升级。当出现新版本时应用会提示升级并下载最新版本替换当前版本。在Android中这个过程可以通过HttpClient、AsyncTask和Handler结合实现。

4、设计思路(实现原理)

1)   通过在AsyncTask访问服务器,得到最新版本号;

2)   通过HttpClient连接服务器从服务器下载最新版本的apk;

3)   通过Handler将下载的进度显示在界面上;

4)   下载完成后安装应用,如果已经下载完成再次点击下载时则直接安装。

二、案例实现

       (1)创建第一个界面

创建一个名为“应用升级”的程序并创建第一个界面MainActivity,该Activity用于进行下载、展示下载框的逻辑,界面没有过多逻辑,只有一个TextView显示当前版本号。程序主界面如图所示。

 


MainActivity界面对应的布局文件(activity_main.xml)如下所示:

 1  <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"

 2      xmlns:tools="http://schemas.android.com/tools"

 3      android:layout_width="match_parent"

 4      android:layout_height="match_parent"

 5      tools:context=".MainActivity">

 6   

 7      <TextView

 8          android:id="@+id/tv_hint"

 9          android:layout_width="wrap_content"

 10         android:layout_height="wrap_content"

 11         android:layout_centerHorizontal="true"

 12         android:layout_centerVertical="true"

 13         android:text="当前版本号:1.0" />

 14 </RelativeLayout>


2)创建AsyncTask向服务器请求数据

创建VersionUpdateTask.java服务器数据为文本文件,想服务器请求得到数据之后,解析出最新的版本号与应用当前版本号对比,如果服务器版本号大于本地版本号则提示升级,否则不进行操作。

 1  public class VersionUpdateTaskextends AsyncTask<Void, Void, String> {

 2      private final UpgradeAction action;

 3      private Context context;

 4      private String versionUrlAddress;

 5      private String versionData;

 6      public static String newVersionName;

 7      public VersionUpdateTask(UpgradeAction action, String url,Context context) {

 8          super();

 9          this.versionUrlAddress = url;

 10         this.action = action;

 11         this.context = context;

 12     }

 13     @Override

 14     protected String doInBackground(Void... params) {

 15         try {

 16             HttpGet httpGet = new HttpGet(versionUrlAddress);

 17             HttpClient client = new DefaultHttpClient();

 18             HttpResponse response = client.execute(httpGet);

 19             client.getParams().setParameter(

 20                     CoreConnectionPNames.CONNECTION_TIMEOUT, 800);

 21             client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,

 22                     800);

 23             if (response.getStatusLine().getStatusCode() ==HttpStatus.SC_OK) {

 24                 versionData =EntityUtils.toString(response.getEntity(), "GBK");

 25                 return versionData;

 26             }

 27         } catch (Exception e) {

 28         }

 29         return null;

 30     }

 31  

 32     @Override

 33     protected void onPostExecute(String jo) {

 34         if (!Utils.isNetworkConnected(context)) {

 35             return;

 36         }

 37         String[] split = jo.split(",");

 38         newVersionName = split[0];

 39         String replace = split[1].replace(";","\n");

 40         String clientVersionName = Utils.getAppVersionCode(context);

 41        

 42         float netFloat = Float.parseFloat(newVersionName);

 43         float parseFloata = Float.parseFloat(clientVersionName);

 44        

 45        

 46         System.out.println("netInt = "+netFloat);

 47         System.out.println("parseInt = "+parseFloata);

 48        

 49         if (netFloat > parseFloata) {

 50             final VersionUpdateHintDialog ad = newVersionUpdateHintDialog(

 51                     context);

 52             ad.setTitle("是否下载新版本?");

 53             ad.setMessage(replace);

 54             ad.setPositiveButton("", new OnClickListener(){

 55                 @Override

 56                 public void onClick(View v) {

 57                     action.download();

 58                     ad.dismiss();

 59                 }

 60             });

 61             ad.setNegativeButton("", new OnClickListener(){

 62  

 63                 @Override

 64                 public void onClick(View v) {

 65                     action.cancel();

 66                     ad.dismiss();

 67                 }

 68             });

 69         } else {

 70             File downLoadApk = new File(

 71                     Environment.getExternalStorageDirectory(),Utils.APKNAME

 72                             + VersionUpdateTask.newVersionName +".apk");

 73             if (downLoadApk.exists()) {

 74                 downLoadApk.delete();

 75             }

 76         }

 77     }

 78 }


3)创建下载提示对话框VersionUpdateHintDialog.java

AsyncTask逻辑中如果需要下载则要弹出下载提示对话框:

 1  public classVersionUpdateHintDialog {

 2      Context context;

 3      android.app.AlertDialog alertDialog;

 4      TextView tv_title, tv_title_msg;

 5      TextView messageView;

 6      LinearLayout ll_button;

 7      private Button btn_confirm, btn_cancel;

 8      public VersionUpdateHintDialog(Context context) {

 9          this.context = context;

 10         alertDialog = newandroid.app.AlertDialog.Builder(context).create();

 11         alertDialog.setCancelable(false);

 12         alertDialog.show();

 13         Window window = alertDialog.getWindow();

 14         window.setContentView(R.layout.alertdialog);

 15         tv_title = (TextView) window.findViewById(R.id.tv_title);

 16         messageView = (TextView)window.findViewById(R.id.tv_message);

 17         ll_button = (LinearLayout) window.findViewById(R.id.ll_buttonLayout);

 18         btn_confirm = (Button) window.findViewById(R.id.btn_confirm);

 19         btn_cancel = (Button) window.findViewById(R.id.btn_cancel);

 20         tv_title_msg = (TextView)window.findViewById(R.id.tv_title_msg);

 21     }

 22     public void setTitle(int resId) {

 23         tv_title.setText(resId);

 24     }

 25     public void setTitle(String title) {

 26         tv_title.setText(title);

 27     }

 28     public void setMessage(int resId) {

 29         messageView.setText(resId);

 30     }

 31     public void setMessage(String message) {

 32         messageView.setText(message);

 33     }

 34     public void setPositiveButton(String text,

 35             final View.OnClickListener listener) {

 36         LinearLayout.LayoutParams params = new LayoutParams(

 37                 LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);

 38         btn_confirm.setLayoutParams(params);

 39         btn_confirm.setOnClickListener(listener);

 40     }

 41     public void setNegativeButton(String text,

 42             final View.OnClickListener listener) {

 43         LinearLayout.LayoutParams params = new LayoutParams(

 44                 LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);

 45         btn_cancel.setLayoutParams(params);

 46         btn_cancel.setOnClickListener(listener);

 47         if (ll_button.getChildCount() > 0) {

 48             params.setMargins(20, 0, 0, 0);

 49             btn_cancel.setLayoutParams(params);

 50         } else {

 51             btn_cancel.setLayoutParams(params);

 52         }

 53     }

 54     public void dismiss() {

 55         alertDialog.dismiss();

 56     }

 57 }


 4)下载提示对话框所对应的布局文件alertdialog.xml

 1  <?xmlversion="1.0" encoding="utf-8"?>

 2  <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

 3      android:layout_width="match_parent"

 4      android:layout_height="match_parent"

 5      android:orientation="vertical">

 6      <LinearLayout

 7          android:layout_width="280dp"

 8          android:layout_height="wrap_content"

 9          android:layout_gravity="center"

 10         android:background="@drawable/set_yuanjiao"

 11         android:orientation="vertical">

 12         <RelativeLayout

 13             android:layout_width="wrap_content"

 14             android:layout_height="wrap_content"

 15             android:layout_marginTop="10dp"

 16             android:layout_marginBottom="10dp">

 17             <ImageView

 18                 android:id="@+id/iv_hint"

 19                 android:layout_width="wrap_content"

 20                 android:layout_height="wrap_content"

 21                 android:layout_marginLeft="20dp"

 22                 android:layout_marginTop="5dp"

 23                 android:src="@drawable/xh_gantanhao"/>

 24             <TextView

 25                 android:id="@+id/tv_title"

 26                 android:layout_width="fill_parent"

 27                 android:layout_height="wrap_content"

 28                 android:layout_alignParentRight="true"

 29                 android:layout_centerVertical="true"

 30                 android:layout_toRightOf="@+id/iv_hint"

 31                 android:layout_marginLeft="10dp"

 32                 android:text="更新"

 33                 android:textColor="#249ef6"/>

 34         </RelativeLayout>

 35         <View

 36             android:id="@+id/view_hx"

 37             android:layout_width="fill_parent"

 38             android:layout_height="1dp"

 39             android:layout_marginLeft="10dp"

 40             android:layout_marginRight="10dp"

 41             android:layout_marginTop="5dp"

 42             android:background="#249ef6"/>

 43         <TextView

 44             android:id="@+id/tv_title_msg"

 45             android:layout_width="wrap_content"

 46             android:layout_height="wrap_content"

 47             android:layout_marginLeft="20dp"

 48             android:layout_marginTop="10dp"

 49             android:text="新版本特性:"

 50             android:textColor="#666666"/>

 51         <TextView

 52             android:id="@+id/tv_message"

 53             android:layout_width="fill_parent"

 54             android:layout_height="wrap_content"

 55             android:layout_marginBottom="10dp"

 56             android:layout_marginLeft="20dp"

 57             android:layout_marginRight="10dp"

 58             android:layout_marginTop="10dp"

 59             android:text="内容"

 60             android:textSize="20dp"

 61             android:textColor="#666666"/>

 62         <!-- LinearLayout中加按钮-->

 63         <LinearLayout

 64             android:id="@+id/ll_buttonLayout"

 65             android:layout_width="fill_parent"

 66             android:layout_height="fill_parent"

 67             android:layout_gravity="center"

 68             android:layout_marginBottom="15dp"

 69             android:gravity="center"

 70             android:orientation="horizontal">

 71             <Button

 72                 android:id="@+id/btn_confirm"

 73                 android:layout_width="wrap_content"

 74                 android:layout_height="wrap_content"

 75                 android:background="@drawable/button_queren"

 76                 android:text="立即更新"

 77                 android:textColor="#ffffff"/>

 78             <Button

 79                 android:id="@+id/btn_cancel"

 80                 android:layout_width="wrap_content"

 81                 android:layout_height="wrap_content"

 82                 android:background="@drawable/xh_button_quxiao"

 83                 android:text="稍后再说"

 84                 android:textColor="#000000"/>

 85         </LinearLayout>

 86     </LinearLayout>

 87 </LinearLayout>


5)创建监听按钮点击的接口UpgradeAction.java

在下载提示对话框中自定义了两个按钮,创建一个接口监听这两个按钮的点击事件,在主界面中处理逻辑:

 1  public interface UpgradeAction{

 2      public Context getContext();

 3      public void download();

 4      public void cancel();

 5  }


6)主界面逻辑

MainActivity中开启AsyncTask进行网络连接,并在UpgradeAction接口中处理应用的下载或者取消操作,如果下载,则显示下载应用对话框。

 6  public class MainActivityextends Activity implements UpgradeAction {

 7      /** 新版本保存在SD卡的名称 */

 8      private String appName;

 9      /** 新版本下载对话框 */

 10     private AppDownLoadDiaLog downBar;

 11     /** 新版本APK总大小 */

 12     private int fileLength;

 13     /** 新版本下载进度 */

 14     private int DownedFileLength = 0;

 15     protected static final int DOWNFNEWVERSION = 101;

 16     private Thread thread;

 17     private boolean stopThreadFlag;

 18     private TextView tv_hint;

 19     @Override

 20     protected void onCreate(Bundle savedInstanceState) {

 21         super.onCreate(savedInstanceState);

 22         setContentView(R.layout.activity_main);

 23         new VersionUpdateTask(this, Utils.SERVICEADDRESS,this).execute();

 24         tv_hint = (TextView) findViewById(R.id.tv_hint);

 25     }

 26     @Override

 27     protected void onResume() {

 28         super.onResume();

 29         tv_hint.setText("当前版本    :   " + Utils.getAppVersionCode(this));

 30     }

 31     protected void downAppFile(final String url) {

 32         thread = new Thread() {

 33             public void run() {

 34                 HttpClient client = new DefaultHttpClient();

 35                 HttpGet get = new HttpGet(url);

 36                 HttpResponse response;

 37                 try {

 38                     response = client.execute(get);

 39                     HttpEntity entity = response.getEntity();

 40                     InputStream is = entity.getContent();

 41                     fileLength = (int) entity.getContentLength();

 42                     FileOutputStream fileOutputStream = null;

 43                     if (is == null) {

 44                         throw new RuntimeException("isStream isnull");

 45                     }

 46                     File file = new File(

 47                             Environment.getExternalStorageDirectory(),appName);

 48                     fileOutputStream = new FileOutputStream(file);

 49                     byte[] buf = new byte[1024];

 50                     int ch = -1;

 51                     do {

 52                         ch = is.read(buf);

 53                         if (ch <= 0) {

 54                             break;

 55                         }

 56                         fileOutputStream.write(buf, 0, ch);

 57                         DownedFileLength += ch;

 58  

 59                         Message message1 = new Message();

 60                         message1.what = DOWNFNEWVERSION;

 61                         handler.sendMessage(message1);

 62                     } while (true);

 63                     is.close();

 64                     fileOutputStream.close();

 65                     if (!stopThreadFlag) {

 66                         Utils.installNewApk(MainActivity.this,appName, downBar);

 67                     }

 68                 } catch (Exception e) {

 69                     e.printStackTrace();

 70                 }

 71             }

 72         };

 73         thread.start();

 74     }

 75     private Handler handler = new Handler() {

 76         private int x;

 77         public void handleMessage(Message msg) {

 78             if (!Thread.currentThread().isInterrupted()) {

 79                 switch (msg.what) {

 80                 case 0:

 81                     // Log.i("文件长度----------->", progressBar.getMax() + "");

 82                     break;

 83                 case DOWNFNEWVERSION:

 84                     String fileLengthMB = Utils.bytes2kb(fileLength);

 85                     String DownedFileLengthMB = Utils

 86                             .bytes2kb(DownedFileLength);

 87                     x = (int) (DownedFileLength * 100 / fileLength);

 88                     downBar.setBar(x);

 89                     downBar.setMessage(x+ "%");

 90                     downBar.setSize(DownedFileLengthMB +"/" + fileLengthMB);

 91                     break;

 92                 case 2:

 93                     Utils.installNewApk(MainActivity.this, appName,downBar);

 94                     break;

 95                 default:

 96                     break;

 97                 }

 98             }

 99         }

 100         };

 101         @Override

 102         public Context getContext() {

 103             return null;

 104         }

 105         @Override

 106         public void download() {

 107             appName = "应用升级" + VersionUpdateTask.newVersionName + ".apk";

 108             // 点击更新,如果已经下载过最新版本直接安装

 109             File downLoadApk = newFile(Environment.getExternalStorageDirectory(),

 110                     appName);

 111             if(downLoadApk.exists()) {

 112                 Intent intent = new Intent(Intent.ACTION_VIEW);

 113                 intent.setDataAndType(Uri.fromFile(new File(Environment

 114                         .getExternalStorageDirectory(), appName)),

 115                         "application/vnd.android.package-archive");

 116                 startActivity(intent);

 117             } else {

 118                 DownedFileLength = 0;

 119                 showProgressBar();

 120             }

 121         }

 122         protected void showProgressBar() {

 123             downBar = new AppDownLoadDiaLog(MainActivity.this);

 124             downBar.setNegativeButton("", new OnClickListener(){

 125                 @Override

 126                 public void onClick(View v) {

 127                     downBar.dismiss();

 128                     thread.interrupt();

 129                     stopThreadFlag = true;

 130                     try {

 131                         File downLoadApk = new File(Environment

 132                                 .getExternalStorageDirectory(), "应用升级"

 133                                 + VersionUpdateTask.newVersionName +".apk");

 134                         if (downLoadApk.exists()) {

 135                             downLoadApk.delete();

 136                         }

 137                     } catch (Exception e) {

 138                         Log.v("VersionUpdate", "",e);

 139                     }

 140                 }

 141             });

 142             downAppFile(Utils.APKSERVICEADDRESS);

 143         }

 144         @Override

 145         public void cancel() {

 146      

 147         }

 148     }


7)应用下载对话框

自定义一个对话框,当中显示进度条显示当前下载进度:

 1  public class AppDownLoadDiaLog{

 2      Context context;

 3      android.app.AlertDialog alertDialog;

 4      TextView titleView;

 5      TextView tv_down, tv_down_size;

 6      ProgressBar progressBar;

 7      Button btn_down_canel;

 8      public AppDownLoadDiaLog(Context context) {

 9          this.context = context;

 10         alertDialog = newandroid.app.AlertDialog.Builder(context).create();

 11         alertDialog.show();

 12         // 关键在下面的两行,使用window.setContentView,替换整个对话框窗口的布局

 13         Window window = alertDialog.getWindow();

 14         window.setContentView(R.layout.alertdiadownlog);

 15         tv_down = (TextView) window.findViewById(R.id. tv_down);

 16         tv_down_size = (TextView) window.findViewById(R.id. tv_down_size);

 17         btn_down_canel = (Button) window.findViewById(R.id.btn_down_canel);

 18         progressBar = (ProgressBar) window.findViewById(R.id.bar_down);

 19         progressBar.setMax(100);

 20     }

 21     public void setNegativeButton(String text,

 22             final View.OnClickListener listener) {

 23         btn_down_canel.setTextSize(Utils.px2dip(context, 24));

 24         btn_down_canel.setOnClickListener(listener);

 25     }

 26     public void setTitle(int resId) {

 27         titleView.setText(resId);

 28     }

 29     public void setTitle(String title) {

 30         titleView.setText(title);

 31     }

 32     public void setMessage(int resId) {

 33         tv_down.setText(resId);

 34     }

 35     public void setMessage(String message) {

 36         tv_down.setText(message);

 37     }

 38     public void setSize(int resId) {

 39         tv_down_size.setText(resId);

 40     }

 41     public void setSize(String message) {

 42         tv_down_size.setText(message);

 43     }

 44     public void setBar(int resId) {

 45         progressBar.setProgress(resId);

 46     }

 47     /**

 48      * 关闭对话框

 49      */

 50     public void dismiss() {

 51         alertDialog.dismiss();

 52     }

 53 }


8)下载框所对应的布局文件alertdiadownlog.xml

 1  <?xmlversion="1.0" encoding="utf-8"?>

 2  <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

 3      android:layout_width="match_parent"

 4      android:layout_height="match_parent"

 5      android:orientation="vertical">

 6      <LinearLayout

 7          android:layout_width="300dp"

 8          android:layout_height="wrap_content"

 9          android:layout_gravity="center"

 10         android:background="@drawable/set_yuanjiao"

 11         android:orientation="vertical">

 12         <TextView

 13             android:id="@+id/tv_down_title"

 14             android:layout_width="fill_parent"

 15             android:layout_height="wrap_content"

 16             android:layout_alignParentRight="true"

 17             android:layout_centerVertical="true"

 18             android:layout_marginLeft="20dp"

 19             android:layout_marginTop="10dp"

 20             android:text="下载中,请稍后..."

 21             android:textSize="16dp"/>

 22         <cn.itcast.appdownload.view.MyProgressBar

 23             android:id="@+id/bar_down"

 24             style="?android:attr/progressBarStyleHorizontal"

 25             android:layout_width="fill_parent"

 26             android:layout_height="fill_parent"

 27             android:layout_marginLeft="20dp"

 28             android:layout_marginRight="20dp"

 29             android:layout_marginTop="10dp"

 30             android:background="@drawable/xh_set_yuan"

 31             android:progressDrawable="@drawable/myprogress"/>

 32         <LinearLayout

 33             android:layout_width="wrap_content"

 34             android:layout_height="wrap_content"

 35             android:orientation="horizontal">

 36             <TextView

 37                 android:id="@+id/tv_down"

 38                 android:layout_width="wrap_content"

 39                 android:layout_height="wrap_content"

 40                 android:layout_marginLeft="20dp"

 41                 android:layout_marginTop="5dp"/>

 42             <TextView

 43                 android:id="@+id/tv_down_size"

 44                 android:layout_width="wrap_content"

 45                 android:layout_height="wrap_content"

 46                 android:layout_marginLeft="20dp"

 47                 android:layout_marginTop="5dp"/>

 48         </LinearLayout>

 49             <Button

 50                 android:id="@+id/btn_down_canel"

 51                 android:layout_width="match_parent"

 52                 android:layout_height="wrap_content"

 53                 android:layout_marginBottom="10dp"

 54                 android:layout_marginLeft="20dp"

 55                 android:layout_marginRight="20dp"

 56                 android:layout_marginTop="10dp"

 57                 android:text="取消"

 58                 android:textColor="#000000"/>

 59  

 60         <LinearLayout

 61             android:id="@+id/ll_buttonLayout"

 62             android:layout_width="fill_parent"

 63             android:layout_height="fill_parent"

 64             android:layout_gravity="center"

 65             android:gravity="center"

 66             android:orientation="horizontal">

 67         </LinearLayout>

 68     </LinearLayout>

 69     <!-- 底部椭园边缘 -->

 70 </LinearLayout>


9 自定义进度条MyProgressBar.java

 1  public class MyProgressBarextends ProgressBar {

 2      private String text_progress;

 3      private Paint mPaint;

 4      public MyProgressBar(Context context) {

 5          super(context);

 6          initPaint();

 7      }

 8      public MyProgressBar(Context context, AttributeSet attrs) {

 9          super(context, attrs);

 10         initPaint();

 11     }

 12     public MyProgressBar(Context context, AttributeSet attrs, intdefStyle) {

 13         super(context, attrs, defStyle);

 14         initPaint();

 15     }

 16     @Override

 17     public synchronized void setProgress(int progress) {

 18         super.setProgress(progress);

 19         setTextProgress(progress);

 20     }

 21     @Override

 22     protected synchronized void onDraw(Canvas canvas) {

 23         // TODO Auto-generated method stub

 24         super.onDraw(canvas);

 25         Rect rect=new Rect();

 26         this.mPaint.getTextBounds(this.text_progress, 0,

 27           this.text_progress.length(), rect);

 28         int x = (getWidth() / 2) -rect.centerX();

 29         int y = (getHeight() / 2) -rect.centerY();

 30         canvas.drawText(this.text_progress, x,y, this.mPaint);

 31     }

 32     private void initPaint(){

 33         this.mPaint=new Paint();

 34         this.mPaint.setAntiAlias(true);

 35         this.mPaint.setColor(Color.WHITE);

 36     }

 37     private void setTextProgress(int progress){

 38         int i = (int) ((progress * 1.0f / this.getMax()) * 100);

 39         this.text_progress = String.valueOf(i)+ "%";

 40     }

 41 }

10)创建工具类

该工具类中包括检查当前是否有网络连接,获取本地版本号,安装新应用等功能。

 1  public class Utils {

 2      public static final String APKNAME = "app版本升级测试";

 3      public static final String APKSERVICEADDRESS =

 4      "http://172.16.25.39:8080/应用升级.apk";

 5      public static final String SERVICEADDRESS =

 6       "http://172.16.25.39:8080/versionUpdate.txt";

 7      public static boolean isNetworkConnected(Context context) {

 8          ConnectivityManager cm = (ConnectivityManager) context

 9                  .getSystemService(Context.CONNECTIVITY_SERVICE);

 10         NetworkInfo ni = cm.getActiveNetworkInfo();

 11         return ni != null && ni.isConnectedOrConnecting();

 12     }

 13     // 应用本地版本号

 14     public static String getAppVersionCode(Context context) {

 15         try {

 16             PackageManager pm = context.getPackageManager();

 17             PackageInfo pi = pm.getPackageInfo(context.getPackageName(),0);

 18             return pi.versionName;

 19         } catch (NameNotFoundException e) {

 20             return "";

 21         }

 22     }

 23     public static void installNewApk(Activity activity, StringappName,

 24             AppDownLoadDiaLog downBar) {

 25         downBar.dismiss();

 26         Intent intent = new Intent(Intent.ACTION_VIEW);

 27         intent.setDataAndType(Uri.fromFile(new File(Environment

 28                 .getExternalStorageDirectory(), appName)),

 29                 "application/vnd.android.package-archive");

 30         activity.startActivity(intent);

 31     }

 32     public static String bytes2kb(long bytes) {

 33         BigDecimal filesize = new BigDecimal(bytes);

 34         BigDecimal megabyte = new BigDecimal(1024 * 1024);

 35         float returnValue = filesize.divide(megabyte, 2,BigDecimal.ROUND_UP)

 36                 .floatValue();

 37         if (returnValue > 1)

 38             return (returnValue + "MB");

 39         BigDecimal kilobyte = new BigDecimal(1024);

 40         returnValue = filesize.divide(kilobyte, 2,BigDecimal.ROUND_UP)

 41                 .floatValue();

 42         return (returnValue + "KB");

 43     }

 44     // 根据手机的分辨率从 px(像素) 的单位转成为 dp

 45     public static int px2dip(Context context, float pxValue) {

 46         final float scale =context.getResources().getDisplayMetrics().density;

 47         return (int) (pxValue / scale + 0.5f);

 48     }

 49 }


注意:工具类中定义了两个常量,在初学者使用时需要把这两个常量APKSERVICEADDRESSSERVICEADDRESS改为自己服务器的地址以及apk存放地址。

11)添加权限

注意添加网络权限与向SD卡写入权限:

 1      <uses-permissionandroid:name="android.permission.INTERNET" />

 2      <uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE" />

 3      <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE" />


12)运行程序

首先在清单文件中把版本号改为2.0或者2.0以上,然后把应用打包或者将项目运行起来,将打包后的apk或者运行后在bin目录下产生的apk文件放在服务器下,再把项目版本改为1.0,并且把服务器中的最新版本号改为2.0以上,最后运行项目,会看到图所示画面。

       


由于服务器中最新版本号比当前版本号大,因此打开应用时提示升级,此时点击稍后再说按钮会取消对话框进入主界面,点击立即更新按钮则会下载新apk,如图所示。

三、案例总结

1、进行网络连接不能在主线程中完成,必须开一个子线程。

2、进行网络连接必须要添加相应权限。