一个APP下载升级的Demo(通知栏实时更新下载进度)------(一)

原博客地址:http://blog.csdn.net/hfreeman2011/article/details/8808887


APP下载升级,通知栏实时更新下载进度功能的说明:

    提供一个升级的按钮,当用户按下升级的按钮时,进入APP升级下载过程,这时通知栏显示下载进度,并且实时更新下载进度,当下载完成后,提示点击通知栏进行APP安装!下载的APP存放在SD卡的下载目录下(KonkaApplication).


图解APP下载升级过程:

                                            








核心代码:

1.MainActivity.java

  1. public class MainActivity extends Activity implements OnClickListener {  
  2.       
  3.     /*******down APP name******/  
  4.     public static final String appName = "updateAppTest";  
  5.     /*******down APP address*******/  
  6.     public static final String downUrl = "http://gdown.baidu.com/data/wisegame/bd47bd249440eb5f/shenmiaotaowang2.apk";  
  7.       
  8.     private Button updateButton = null;  
  9.   
  10.     @Override  
  11.     protected void onCreate(Bundle savedInstanceState) {  
  12.         super.onCreate(savedInstanceState);  
  13.           
  14.         setContentView(R.layout.activity_main);  
  15.           
  16.         updateButton = (Button)findViewById(R.id.updateButton);  
  17.         updateButton.setOnClickListener(this);  
  18.     }  
  19.   
  20.     @Override  
  21.     public void onClick(View view) {  
  22.         // TODO Auto-generated method stub  
  23.         if(view == updateButton){  
  24.             /*****update service*******/  
  25.             Intent intent = new Intent(this,UpdateService.class);  
  26.             intent.putExtra("Key_App_Name",appName);  
  27.             intent.putExtra("Key_Down_Url",downUrl);                          
  28.             startService(intent);  
  29.               
  30.         }  
  31.     }  
  32.   
  33. }  

2.FileUtil.java
  1. /** 
  2.  * 类描述:FileUtil 
  3.  *  @author hexiaoming 
  4.  *  @version   
  5.  */  
  6. public class FileUtil {  
  7.       
  8.     public static File updateDir = null;  
  9.     public static File updateFile = null;  
  10.     /***********保存升级APK的目录***********/  
  11.     public static final String KonkaApplication = "konkaUpdateApplication";  
  12.       
  13.     public static boolean isCreateFileSucess;  
  14.   
  15.     /**  
  16.     * 方法描述:createFile方法 
  17.     * @param   String app_name 
  18.     * @return  
  19.     * @see FileUtil 
  20.     */  
  21.     public static void createFile(String app_name) {  
  22.           
  23.         if (android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState())) {  
  24.             isCreateFileSucess = true;  
  25.               
  26.             updateDir = new File(Environment.getExternalStorageDirectory()+ "/" + KonkaApplication +"/");  
  27.             updateFile = new File(updateDir + "/" + app_name + ".apk");  
  28.   
  29.             if (!updateDir.exists()) {  
  30.                 updateDir.mkdirs();  
  31.             }  
  32.             if (!updateFile.exists()) {  
  33.                 try {  
  34.                     updateFile.createNewFile();  
  35.                 } catch (IOException e) {  
  36.                     isCreateFileSucess = false;  
  37.                     e.printStackTrace();  
  38.                 }  
  39.             }  
  40.   
  41.         }else{  
  42.             isCreateFileSucess = false;  
  43.         }  
  44.     }  
  45. }  

3.UpdateService.java
  1. /*** 
  2.  * 升级服务 
  3.  *  
  4.  * @author hexiaoming 
  5.  *  
  6.  */  
  7. public class UpdateService extends Service {  
  8.       
  9.     public static final String Install_Apk = "Install_Apk";  
  10.     /********download progress step*********/  
  11.     private static final int down_step_custom = 3;  
  12.       
  13.     private static final int TIMEOUT = 10 * 1000;// 超时  
  14.     private static String down_url;  
  15.     private static final int DOWN_OK = 1;  
  16.     private static final int DOWN_ERROR = 0;  
  17.       
  18.     private String app_name;  
  19.       
  20.     private NotificationManager notificationManager;  
  21.     private Notification notification;  
  22.     private Intent updateIntent;  
  23.     private PendingIntent pendingIntent;  
  24.     private RemoteViews contentView;  
  25.   
  26.           
  27.     @Override  
  28.     public IBinder onBind(Intent arg0) {  
  29.         return null;  
  30.     }  
  31.   
  32.     /**  
  33.     * 方法描述:onStartCommand方法 
  34.     * @param   Intent intent, int flags, int startId 
  35.     * @return    int 
  36.     * @see     UpdateService 
  37.     */  
  38.     @Override  
  39.     public int onStartCommand(Intent intent, int flags, int startId) {  
  40.           
  41.         app_name = intent.getStringExtra("Key_App_Name");  
  42.         down_url = intent.getStringExtra("Key_Down_Url");  
  43.           
  44.         // create file,应该在这个地方加一个返回值的判断SD卡是否准备好,文件是否创建成功,等等!  
  45.         FileUtil.createFile(app_name);  
  46.           
  47.         if(FileUtil.isCreateFileSucess == true){              
  48.             createNotification();  
  49.             createThread();  
  50.         }else{  
  51.             Toast.makeText(this, R.string.insert_card, Toast.LENGTH_SHORT).show();  
  52.             /***************stop service************/  
  53.             stopSelf();  
  54.               
  55.         }  
  56.           
  57.         return super.onStartCommand(intent, flags, startId);  
  58.     }  
  59.   
  60.   
  61.       
  62.     /********* update UI******/        
  63.     private final Handler handler = new Handler() {  
  64.         @Override  
  65.         public void handleMessage(Message msg) {  
  66.             switch (msg.what) {  
  67.             case DOWN_OK:  
  68.                   
  69.                 /*********下载完成,点击安装***********/  
  70.                 Uri uri = Uri.fromFile(FileUtil.updateFile);  
  71.                 Intent intent = new Intent(Intent.ACTION_VIEW);  
  72.                 intent.setDataAndType(uri,"application/vnd.android.package-archive");  
  73.                 pendingIntent = PendingIntent.getActivity(UpdateService.this0, intent, 0);  
  74.                   
  75.                 notification.flags = Notification.FLAG_AUTO_CANCEL;                    
  76.                 notification.setLatestEventInfo(UpdateService.this,app_name, getString(R.string.down_sucess), pendingIntent);  
  77.                 //notification.setLatestEventInfo(UpdateService.this,app_name, app_name + getString(R.string.down_sucess), null);             
  78.                 notificationManager.notify(R.layout.notification_item, notification);     
  79.                   
  80.                 /*****安装APK******/  
  81.                 //installApk();   
  82.                   
  83.                 //stopService(updateIntent);  
  84.                 /***stop service*****/  
  85.                 stopSelf();  
  86.                 break;  
  87.                   
  88.             case DOWN_ERROR:  
  89.                 notification.flags = Notification.FLAG_AUTO_CANCEL;   
  90.                 //notification.setLatestEventInfo(UpdateService.this,app_name, getString(R.string.down_fail), pendingIntent);  
  91.                 notification.setLatestEventInfo(UpdateService.this,app_name, getString(R.string.down_fail), null);  
  92.                   
  93.                 /***stop service*****/  
  94.                 //onDestroy();  
  95.                 stopSelf();  
  96.                 break;  
  97.                   
  98.             default:  
  99.                 //stopService(updateIntent);  
  100.                 /******Stop service******/  
  101.                 //stopService(intentname)  
  102.                 //stopSelf();  
  103.                 break;  
  104.             }  
  105.         }  
  106.     };  
  107.       
  108.     private void installApk() {  
  109.         // TODO Auto-generated method stub  
  110.         /*********下载完成,点击安装***********/  
  111.         Uri uri = Uri.fromFile(FileUtil.updateFile);  
  112.         Intent intent = new Intent(Intent.ACTION_VIEW);  
  113.           
  114.         /**********加这个属性是因为使用Context的startActivity方法的话,就需要开启一个新的task**********/  
  115.         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);   
  116.           
  117.         intent.setDataAndType(uri,"application/vnd.android.package-archive");                     
  118.         UpdateService.this.startActivity(intent);            
  119.     }  
  120.       
  121.     /**  
  122.     * 方法描述:createThread方法, 开线程下载 
  123.     * @param    
  124.     * @return    
  125.     * @see     UpdateService 
  126.     */  
  127.     public void createThread() {  
  128.         new DownLoadThread().start();  
  129.     }  
  130.   
  131.       
  132.     private class DownLoadThread extends Thread{  
  133.         @Override  
  134.         public void run() {  
  135.             // TODO Auto-generated method stub  
  136.             Message message = new Message();  
  137.             try {                                 
  138.                 long downloadSize = downloadUpdateFile(down_url,FileUtil.updateFile.toString());  
  139.                 if (downloadSize > 0) {                    
  140.                     // down success                                       
  141.                     message.what = DOWN_OK;  
  142.                     handler.sendMessage(message);                                                                         
  143.                 }  
  144.             } catch (Exception e) {  
  145.                 e.printStackTrace();  
  146.                 message.what = DOWN_ERROR;  
  147.                 handler.sendMessage(message);  
  148.             }                         
  149.         }         
  150.     }  
  151.       
  152.   
  153.   
  154.     /**  
  155.     * 方法描述:createNotification方法 
  156.     * @param    
  157.     * @return     
  158.     * @see     UpdateService 
  159.     */  
  160.     public void createNotification() {  
  161.           
  162.         //notification = new Notification(R.drawable.dot_enable,app_name + getString(R.string.is_downing) ,System.currentTimeMillis());  
  163.         notification = new Notification(  
  164.                 //R.drawable.video_player,//应用的图标  
  165.                 R.drawable.ic_launcher,//应用的图标  
  166.                 app_name + getString(R.string.is_downing),  
  167.                 System.currentTimeMillis());  
  168.         notification.flags = Notification.FLAG_ONGOING_EVENT;   
  169.         //notification.flags = Notification.FLAG_AUTO_CANCEL;  
  170.           
  171.          /*** 自定义  Notification 的显示****/           
  172.         contentView = new RemoteViews(getPackageName(),R.layout.notification_item);  
  173.         contentView.setTextViewText(R.id.notificationTitle, app_name + getString(R.string.is_downing));  
  174.         contentView.setTextViewText(R.id.notificationPercent, "0%");  
  175.         contentView.setProgressBar(R.id.notificationProgress, 1000false);  
  176.         notification.contentView = contentView;  
  177.   
  178. //      updateIntent = new Intent(this, AboutActivity.class);  
  179. //      updateIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);  
  180. //      //updateIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  
  181. //      pendingIntent = PendingIntent.getActivity(this, 0, updateIntent, 0);  
  182. //      notification.contentIntent = pendingIntent;  
  183.           
  184.         notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  185.         notificationManager.notify(R.layout.notification_item, notification);  
  186.     }  
  187.   
  188.     /*** 
  189.      * down file 
  190.      *  
  191.      * @return 
  192.      * @throws MalformedURLException 
  193.      */  
  194.     public long downloadUpdateFile(String down_url, String file)throws Exception {  
  195.           
  196.         int down_step = down_step_custom;// 提示step  
  197.         int totalSize;// 文件总大小  
  198.         int downloadCount = 0;// 已经下载好的大小  
  199.         int updateCount = 0;// 已经上传的文件大小  
  200.           
  201.         InputStream inputStream;  
  202.         OutputStream outputStream;  
  203.   
  204.         URL url = new URL(down_url);  
  205.         HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();  
  206.         httpURLConnection.setConnectTimeout(TIMEOUT);  
  207.         httpURLConnection.setReadTimeout(TIMEOUT);  
  208.         // 获取下载文件的size  
  209.         totalSize = httpURLConnection.getContentLength();  
  210.           
  211.         if (httpURLConnection.getResponseCode() == 404) {  
  212.             throw new Exception("fail!");  
  213.             //这个地方应该加一个下载失败的处理,但是,因为我们在外面加了一个try---catch,已经处理了Exception,  
  214.             //所以不用处理                          
  215.         }  
  216.           
  217.         inputStream = httpURLConnection.getInputStream();  
  218.         outputStream = new FileOutputStream(file, false);// 文件存在则覆盖掉  
  219.           
  220.         byte buffer[] = new byte[1024];  
  221.         int readsize = 0;  
  222.           
  223.         while ((readsize = inputStream.read(buffer)) != -1) {  
  224.               
  225. //          /*********如果下载过程中出现错误,就弹出错误提示,并且把notificationManager取消*********/  
  226. //          if (httpURLConnection.getResponseCode() == 404) {  
  227. //              notificationManager.cancel(R.layout.notification_item);  
  228. //              throw new Exception("fail!");  
  229. //              //这个地方应该加一个下载失败的处理,但是,因为我们在外面加了一个try---catch,已经处理了Exception,  
  230. //              //所以不用处理                          
  231. //          }  
  232.                           
  233.             outputStream.write(buffer, 0, readsize);  
  234.             downloadCount += readsize;// 时时获取下载到的大小  
  235.             /*** 每次增张3%**/  
  236.             if (updateCount == 0 || (downloadCount * 100 / totalSize - down_step) >= updateCount) {  
  237.                 updateCount += down_step;  
  238.                 // 改变通知栏  
  239.                 contentView.setTextViewText(R.id.notificationPercent,updateCount + "%");  
  240.                 contentView.setProgressBar(R.id.notificationProgress, 100,updateCount, false);            
  241.                 notification.contentView = contentView;  
  242.                 notificationManager.notify(R.layout.notification_item, notification);             
  243.             }  
  244.         }  
  245.         if (httpURLConnection != null) {  
  246.             httpURLConnection.disconnect();  
  247.         }  
  248.         inputStream.close();  
  249.         outputStream.close();  
  250.           
  251.         return downloadCount;  
  252.     }  
  253.   

   

notification_item

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="3dp" >

    <ImageView
        android:id="@+id/notificationImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/stat_sys_download"
        android:paddingLeft="16dp"/>

    <TextView
        android:id="@+id/notificationTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_toRightOf="@id/notificationImage"
        android:paddingLeft="26dp"
        android:textColor="#FFFFFFFF" />
    <!-- android:textColor="#FF000000"  -->

    <TextView
        android:id="@+id/notificationPercent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/notificationImage"
        android:paddingTop="2dp"
        android:textColor="#FFFFFFFF"
        android:paddingLeft="16dp"/>

    <ProgressBar
        android:id="@+id/notificationProgress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/notificationTitle"
        android:layout_alignParentRight="true"
        android:layout_alignTop="@id/notificationPercent"
        android:layout_below="@id/notificationTitle"
        android:paddingLeft="26dp"
        android:paddingRight="3dp"
        android:paddingTop="2dp" />

</RelativeLayout>





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值