您的位置:首页 > 移动开发

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

2015-11-04 09:33 513 查看
原博客地址:http://blog.csdn.net/hfreeman2011/article/details/8808887

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

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

图解APP下载升级过程:

                    

       

         

 
      


核心代码:

1.MainActivity.java

[java]
view plaincopy

public class MainActivity extends Activity implements OnClickListener {  
      
    /*******down APP name******/  
    public static final String appName = "updateAppTest";  
    /*******down APP address*******/  
    public static final String downUrl = "http://gdown.baidu.com/data/wisegame/bd47bd249440eb5f/shenmiaotaowang2.apk";  
      
    private Button updateButton = null;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
          
        setContentView(R.layout.activity_main);  
          
        updateButton = (Button)findViewById(R.id.updateButton);  
        updateButton.setOnClickListener(this);  
    }  
  
    @Override  
    public void onClick(View view) {  
        // TODO Auto-generated method stub  
        if(view == updateButton){  
            /*****update service*******/  
            Intent intent = new Intent(this,UpdateService.class);  
            intent.putExtra("Key_App_Name",appName);  
            intent.putExtra("Key_Down_Url",downUrl);                          
            startService(intent);  
              
        }  
    }  
  
}  

2.FileUtil.java

[java]
view plaincopy

/** 
 * 类描述:FileUtil 
 *  @author hexiaoming 
 *  @version   
 */  
public class FileUtil {  
      
    public static File updateDir = null;  
    public static File updateFile = null;  
    /***********保存升级APK的目录***********/  
    public static final String KonkaApplication = "konkaUpdateApplication";  
      
    public static boolean isCreateFileSucess;  
  
    /**  
    * 方法描述:createFile方法 
    * @param   String app_name 
    * @return  
    * @see FileUtil 
    */  
    public static void createFile(String app_name) {  
          
        if (android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState())) {  
            isCreateFileSucess = true;  
              
            updateDir = new File(Environment.getExternalStorageDirectory()+ "/" + KonkaApplication +"/");  
            updateFile = new File(updateDir + "/" + app_name + ".apk");  
  
            if (!updateDir.exists()) {  
                updateDir.mkdirs();  
            }  
            if (!updateFile.exists()) {  
                try {  
                    updateFile.createNewFile();  
                } catch (IOException e) {  
                    isCreateFileSucess = false;  
                    e.printStackTrace();  
                }  
            }  
  
        }else{  
            isCreateFileSucess = false;  
        }  
    }  
}  

3.UpdateService.java

[java]
view plaincopy

/*** 
 * 升级服务 
 *  
 * @author hexiaoming 
 *  
 */  
public class UpdateService extends Service {  
      
    public static final String Install_Apk = "Install_Apk";  
    /********download progress step*********/  
    private static final int down_step_custom = 3;  
      
    private static final int TIMEOUT = 10 * 1000;// 超时  
    private static String down_url;  
    private static final int DOWN_OK = 1;  
    private static final int DOWN_ERROR = 0;  
      
    private String app_name;  
      
    private NotificationManager notificationManager;  
    private Notification notification;  
    private Intent updateIntent;  
    private PendingIntent pendingIntent;  
    private RemoteViews contentView;  
  
          
    @Override  
    public IBinder onBind(Intent arg0) {  
        return null;  
    }  
  
    /**  
    * 方法描述:onStartCommand方法 
    * @param   Intent intent, int flags, int startId 
    * @return    int 
    * @see     UpdateService 
    */  
    @Override  
    public int onStartCommand(Intent intent, int flags, int startId) {  
          
        app_name = intent.getStringExtra("Key_App_Name");  
        down_url = intent.getStringExtra("Key_Down_Url");  
          
        // create file,应该在这个地方加一个返回值的判断SD卡是否准备好,文件是否创建成功,等等!  
        FileUtil.createFile(app_name);  
          
        if(FileUtil.isCreateFileSucess == true){              
            createNotification();  
            createThread();  
        }else{  
            Toast.makeText(this, R.string.insert_card, Toast.LENGTH_SHORT).show();  
            /***************stop service************/  
            stopSelf();  
              
        }  
          
        return super.onStartCommand(intent, flags, startId);  
    }  
  
  
      
    /********* update UI******/        
    private final Handler handler = new Handler() {  
        @Override  
        public void handleMessage(Message msg) {  
            switch (msg.what) {  
            case DOWN_OK:  
                  
                /*********下载完成,点击安装***********/  
                Uri uri = Uri.fromFile(FileUtil.updateFile);  
                Intent intent = new Intent(Intent.ACTION_VIEW);  
                intent.setDataAndType(uri,"application/vnd.android.package-archive");  
                pendingIntent = PendingIntent.getActivity(UpdateService.this, 0, intent, 0);  
                  
                notification.flags = Notification.FLAG_AUTO_CANCEL;                    
                notification.setLatestEventInfo(UpdateService.this,app_name, getString(R.string.down_sucess), pendingIntent);  
                //notification.setLatestEventInfo(UpdateService.this,app_name, app_name + getString(R.string.down_sucess), null);             
                notificationManager.notify(R.layout.notification_item, notification);     
                  
                /*****安装APK******/  
                //installApk();   
                  
                //stopService(updateIntent);  
                /***stop service*****/  
                stopSelf();  
                break;  
                  
            case DOWN_ERROR:  
                notification.flags = Notification.FLAG_AUTO_CANCEL;   
                //notification.setLatestEventInfo(UpdateService.this,app_name, getString(R.string.down_fail), pendingIntent);  
                notification.setLatestEventInfo(UpdateService.this,app_name, getString(R.string.down_fail), null);  
                  
                /***stop service*****/  
                //onDestroy();  
                stopSelf();  
                break;  
                  
            default:  
                //stopService(updateIntent);  
                /******Stop service******/  
                //stopService(intentname)  
                //stopSelf();  
                break;  
            }  
        }  
    };  
      
    private void installApk() {  
        // TODO Auto-generated method stub  
        /*********下载完成,点击安装***********/  
        Uri uri = Uri.fromFile(FileUtil.updateFile);  
        Intent intent = new Intent(Intent.ACTION_VIEW);  
          
        /**********加这个属性是因为使用Context的startActivity方法的话,就需要开启一个新的task**********/  
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);   
          
        intent.setDataAndType(uri,"application/vnd.android.package-archive");                     
        UpdateService.this.startActivity(intent);            
    }  
      
    /**  
    * 方法描述:createThread方法, 开线程下载 
    * @param    
    * @return    
    * @see     UpdateService 
    */  
    public void createThread() {  
        new DownLoadThread().start();  
    }  
  
      
    private class DownLoadThread extends Thread{  
        @Override  
        public void run() {  
            // TODO Auto-generated method stub  
            Message message = new Message();  
            try {                                 
                long downloadSize = downloadUpdateFile(down_url,FileUtil.updateFile.toString());  
                if (downloadSize > 0) {                    
                    // down success                                       
                    message.what = DOWN_OK;  
                    handler.sendMessage(message);                                                                         
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
                message.what = DOWN_ERROR;  
                handler.sendMessage(message);  
            }                         
        }         
    }  
      
  
  
    /**  
    * 方法描述:createNotification方法 
    * @param    
    * @return     
    * @see     UpdateService 
    */  
    public void createNotification() {  
          
        //notification = new Notification(R.drawable.dot_enable,app_name + getString(R.string.is_downing) ,System.currentTimeMillis());  
        notification = new Notification(  
                //R.drawable.video_player,//应用的图标  
                R.drawable.ic_launcher,//应用的图标  
                app_name + getString(R.string.is_downing),  
                System.currentTimeMillis());  
        notification.flags = Notification.FLAG_ONGOING_EVENT;   
        //notification.flags = Notification.FLAG_AUTO_CANCEL;  
          
         /*** 自定义  Notification 的显示****/           
        contentView = new RemoteViews(getPackageName(),R.layout.notification_item);  
        contentView.setTextViewText(R.id.notificationTitle, app_name + getString(R.string.is_downing));  
        contentView.setTextViewText(R.id.notificationPercent, "0%");  
        contentView.setProgressBar(R.id.notificationProgress, 100, 0, false);  
        notification.contentView = contentView;  
  
//      updateIntent = new Intent(this, AboutActivity.class);  
//      updateIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);  
//      //updateIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  
//      pendingIntent = PendingIntent.getActivity(this, 0, updateIntent, 0);  
//      notification.contentIntent = pendingIntent;  
          
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
        notificationManager.notify(R.layout.notification_item, notification);  
    }  
  
    /*** 
     * down file 
     *  
     * @return 
     * @throws MalformedURLException 
     */  
    public long downloadUpdateFile(String down_url, String file)throws Exception {  
          
        int down_step = down_step_custom;// 提示step  
        int totalSize;// 文件总大小  
        int downloadCount = 0;// 已经下载好的大小  
        int updateCount = 0;// 已经上传的文件大小  
          
        InputStream inputStream;  
        OutputStream outputStream;  
  
        URL url = new URL(down_url);  
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();  
        httpURLConnection.setConnectTimeout(TIMEOUT);  
        httpURLConnection.setReadTimeout(TIMEOUT);  
        // 获取下载文件的size  
        totalSize = httpURLConnection.getContentLength();  
          
        if (httpURLConnection.getResponseCode() == 404) {  
            throw new Exception("fail!");  
            //这个地方应该加一个下载失败的处理,但是,因为我们在外面加了一个try---catch,已经处理了Exception,  
            //所以不用处理                          
        }  
          
        inputStream = httpURLConnection.getInputStream();  
        outputStream = new FileOutputStream(file, false);// 文件存在则覆盖掉  
          
        byte buffer[] = new byte[1024];  
        int readsize = 0;  
          
        while ((readsize = inputStream.read(buffer)) != -1) {  
              
//          /*********如果下载过程中出现错误,就弹出错误提示,并且把notificationManager取消*********/  
//          if (httpURLConnection.getResponseCode() == 404) {  
//              notificationManager.cancel(R.layout.notification_item);  
//              throw new Exception("fail!");  
//              //这个地方应该加一个下载失败的处理,但是,因为我们在外面加了一个try---catch,已经处理了Exception,  
//              //所以不用处理                          
//          }  
                          
            outputStream.write(buffer, 0, readsize);  
            downloadCount += readsize;// 时时获取下载到的大小  
            /*** 每次增张3%**/  
            if (updateCount == 0 || (downloadCount * 100 / totalSize - down_step) >= updateCount) {  
                updateCount += down_step;  
                // 改变通知栏  
                contentView.setTextViewText(R.id.notificationPercent,updateCount + "%");  
                contentView.setProgressBar(R.id.notificationProgress, 100,updateCount, false);            
                notification.contentView = contentView;  
                notificationManager.notify(R.layout.notification_item, notification);             
            }  
        }  
        if (httpURLConnection != null) {  
            httpURLConnection.disconnect();  
        }  
        inputStream.close();  
        outputStream.close();  
          
        return downloadCount;  
    }  
  


   

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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  博客