android notification通知栏方式更新APP

这次是我第一次写博客哦,各位程序大哥大姐们多多捧场啊.,下面是我自己写的一个像支付宝一样在

通知栏弹出notification来动态实时更新app版本,成功则让用户点击安装,失败则可以点击重试,也可以点击取消.

里面用了广播接收者和service组件.

话不多说,直接上代码啦.

首先是activity判断是否需要更新,如果需要更新,则把URL放到bundle里,传递给service

public void update() {
        Intent intent = new Intent(this, UpdateService.class);
//这里是以支付宝的APP URL 来当作更新的APP, 大家自行修改就行啦
        intent.putExtra("downUrl", "http://tfs.alipayobjects.com/L1/71/100/and/alipay_wap_main.apk");
        startService(intent);
    }



接下来就是更新的service了,我用到了xutils框架,其实没什么东西,如果你没用过的话,你就用个别的能下载,下载完了 成功和失败都有回调就行啦.

package com.ycb.www.news.services;

import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;

import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.HttpHandler;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;

import java.io.File;
import java.text.NumberFormat;

/**
 * 下载的services,配合xutils的httputils使用,完成notification的下载功能
 */
public class UpdateService  extends Service{

    //是否已经开始下载
    private boolean isBegin=false;
    Intent intent ;
    public static HttpHandler downLoadHandler;
    private NumberFormat numberFormat;


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {

        return null;
    }


    @Override
    public void onCreate() {
        super.onCreate();
        intent =new Intent();
        numberFormat = NumberFormat.getInstance();
        numberFormat.setMaximumFractionDigits(2);
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        String downUrl = intent.getStringExtra("downUrl");
        //如果下载地址为空,则什么都不干
        if(TextUtils.isEmpty(downUrl)){
                stopSelf();
//            throw  new IllegalArgumentException("the download url is empty!!!!");
            return 0;
        }
        if(isBegin){
            //此时已经开始了
            return 0;
        }else{
            isBegin=true;
        }
            downLoad(downUrl);
        return super.onStartCommand(intent, flags, startId);
    }



    private void downLoad(final String downUrl) {
        Log.i("tag","开始下载!!!");
        HttpUtils hu=new HttpUtils(10000);
        downLoadHandler = hu.download(downUrl,
                Environment.getExternalStorageDirectory().getAbsolutePath()+"/ycb.apk", new RequestCallBack() {

                    @Override
                    public void onCancelled() {
                        stopSelf();
                        super.onCancelled();
                    }

                    @Override
            public void onSuccess(ResponseInfo responseInfo) {
                intent.setAction("com.ycb.www.complete");
                intent.putExtra("filepath", responseInfo.result.getAbsolutePath());
                Log.i("tag", responseInfo.result.getAbsolutePath());
                sendBroadcast(intent);
                stopSelf();
            }

            @Override
            public void onFailure(HttpException error, String msg) {
                intent.setAction("com.ycb.www.failed");
                intent.putExtra("downUrl", downUrl);
//                Log.i("tag", "onFailure!!!");
                sendBroadcast(intent);
            }

            @Override
            public void onLoading(long total, long current, boolean isUploading) {
                Double rate= (double)current / (double)total;

                String format = numberFormat.format(rate);
                int   r= (int) (Double.valueOf(format)*100);
//                Log.i("tag", ""+r);
                intent.putExtra("rate", r);
                intent.setAction("com.ycb.www.updating");
                sendBroadcast(intent);
                super.onLoading(total, current, isUploading);
            }
        });

    }


}




下面是用到的 广播接收者,代码有注释,看不懂的可以下面跟我交流哦.

import android.annotation.TargetApi;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.widget.RemoteViews;





import java.io.File;


/**
 * notification更新的广播接收者,根据action不同,做出的结果不同,
 * 其中intent因为是同一个intent的,所以并没有new 新的
 *
 */
public class UpdateReceiver extends BroadcastReceiver {




    private NotificationManager manager;
    private RemoteViews views;
    private Notification notification;



        
    @Override
        public void onReceive(Context context, Intent intent) {

               if(notification==null) {


             //版本兼容,高低版本初始化notification的方式不同
            if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.JELLY_BEAN)
                initNotification(context);
            else{
                initNotificationForLowVersion(context);
            }
        }




        String action = intent.getAction();
            switch (action) {
                case "com.ycb.www.cancel":
                    manager.cancel(0);//如果传递过来的是用户取消,则用notificationManger取消通知栏,并取消下载
                    UpdateService.downLoadHandler.cancel();
                    break;
                case "com.ycb.www.failed":
                    intent.setAction("com.ycb.www.restart"); //如果是失败了,则通知用户下载失败,点击重试
                    PendingIntent failedpendingIntent=PendingIntent.getBroadcast(context, 200, intent, PendingIntent.FLAG_CANCEL_CURRENT);
                    views.setOnClickPendingIntent(R.id.ll_content, failedpendingIntent);//给布局文件添加点击事件
                    views.setTextViewText(R.id.tv, "下载失败,点击重试");
                    manager.notify(0, notification);
                    break;
                case "com.ycb.www.restart":
                    manager.cancel(0);
                    intent.setClass(context, UpdateService.class);//service重新下载的action,配合下载失败
                    context.startService(intent);
                    break;
                case "com.ycb.www.install":  //下载成功以后安装APP的action
                    manager.cancel(0);
                    Intent startInstall =new Intent();
                    startInstall.setAction(Intent.ACTION_VIEW);
                    String filepath = intent.getStringExtra("filepath");
                    startInstall.setDataAndType(Uri.fromFile(new File(filepath)), "application/vnd.android.package-archive");
                    startInstall.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(startInstall);
                    break;
                case "com.ycb.www.complete":   //下载完成后action
                    intent.setAction("com.ycb.www.install");
                    PendingIntent pendingIntent=PendingIntent.getBroadcast(context, 200, intent, PendingIntent.FLAG_CANCEL_CURRENT);
                    views.setOnClickPendingIntent(R.id.ll_content, pendingIntent);
                    views.setTextViewText(R.id.tv, "下载完成,点击安装");
                    views.setProgressBar(R.id.progressBar, 100, 100, false);
                    manager.notify(0, notification);
                    break;
                case "com.ycb.www.updating":   //一直在更新的action
                    int rate = intent.getIntExtra("rate", 0);
                    views.setTextViewText(R.id.tv,"正在下载...."+rate+"%");
                    views.setProgressBar(R.id.progressBar,100,rate,false);
                    manager.notify(0, notification);  //通过不停的notify 动态更新状态栏
            }


        }

             //初始化低版本的notification,
    private void initNotificationForLowVersion(Context context) {
        //设置notifiction布局
        views = new RemoteViews(context.getPackageName(), R.layout.notification_update);


        notification=new Notification();


        notification.when=System.currentTimeMillis();


        notification.tickerText="银承宝新版正在下载";
        //设置view
        notification.contentView=views;
        //设置小图标
        notification.icon=R.drawable.img_menu;
        //设置布局文件中的textView的内容
        views.setTextViewText(R.id.tv, "下载中....0%");


        //设置布局文件中的ProgressBar进度
        views.setProgressBar(R.id.progressBar, 100, 0, false);
        //退出的intent
        Intent intent=new Intent("com.ycb.www.cancel");
        //退出的延迟意图
        PendingIntent mPendingIntent =PendingIntent.getBroadcast(context.getApplicationContext(),200,intent,PendingIntent.FLAG_UPDATE_CURRENT);
        //点击之后退出
        views.setOnClickPendingIntent(R.id.ib, mPendingIntent);
    }




    /**
     * 初始化高版本的notification
     * @param context
     */
            @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
            private void initNotification(Context context){
                manager = (NotificationManager)context. getSystemService(Context.NOTIFICATION_SERVICE);
                views = new RemoteViews(context.getPackageName(), R.layout.notification_update);
                Notification.Builder builder=new Notification.Builder(context.getApplicationContext());
                notification = builder.setAutoCancel(false).setSmallIcon(R.drawable.img_menu).setContentText("下载中").setContentTitle("下载").
                        setWhen(System.currentTimeMillis()).setTicker("XXXX APP 正在下载")
                        .setContent(views).build();


                views.setTextViewText(R.id.tv, "下载中....0%");
                views.setProgressBar(R.id.progressBar, 100, 0, false);
                Intent intent=new Intent("com.ycb.www.cancel");
                PendingIntent mPendingIntent =PendingIntent.getBroadcast(context.getApplicationContext(),200,intent,PendingIntent.FLAG_UPDATE_CURRENT);
                views.setOnClickPendingIntent(R.id.ib, mPendingIntent);


            }


}




最后就是用到的权限和 manifest里面的配置了.

 
    
    
    
   
        
            
                
                
                
                
                
                

            
        



附送源码,点击下载,不用谢我了



你可能感兴趣的:(android)