Android 應用內更新 並且通知更新下載進度(通知欄兼容 Android 8.0)

安卓8.0之後 原來的Notification 有所變動 已不滿足需求

1. 首先增加了 NotificationChannel 屬性 需要對其進行相關配置

    private static void createNotification(NotificationManager notificationManager) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel notificationChannel = new NotificationChannel(CALENDAR_ID, "ander drowload apk default channel.",
                    NotificationManager.IMPORTANCE_MIN);
            // 設置渠道描述
            notificationChannel.setDescription("通知更新");
            // 是否繞過請勿打擾模式
            notificationChannel.canBypassDnd();
            // 設置繞過請勿打擾模式
            notificationChannel.setBypassDnd(true);
            // 桌面Launcher的消息角標
            notificationChannel.canShowBadge();
            // 設置顯示桌面Launcher的消息角標
            notificationChannel.setShowBadge(true);
            // 設置通知出現時聲音,默認通知是有聲音的
            notificationChannel.setSound(null, null);
            // 設置通知出現時的閃燈(如果 android 設備支持的話)
            notificationChannel.enableLights(false);

            notificationChannel.setLightColor(Color.RED);
            // 設置通知出現時的震動(如果 android 設備支持的話)
            notificationChannel.enableVibration(false);
            notificationManager.createNotificationChannel(notificationChannel);
        }
    }

2. 原來的Notification 方法已經不適用於8.0 系統

    public NotificationCompat.Builder getNotificationBuilder() {
        return new NotificationCompat.Builder(getApplicationContext(), CALENDAR_ID)
                .setWhen(System.currentTimeMillis())
                .setContentTitle("title")
                .setContentText("context...")
                .setSmallIcon(R.mipmap.ic_launcher_round)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),
                        R.mipmap.ic_launcher_round))
                .setAutoCancel(true);
    }

3. 下載APK的方法 並實時更新通知欄進度

 DownloadUtil.get().download(DownloadConstant.apkDown, DownloadConstant.PATH_APK_DOWNLOAD_MANAGER, "zhaoyu.apk",
                new DownloadUtil.OnDownloadListener() {
                    @Override
                    public void onDownloadSuccess(File file) {
                        notificationBuilder .setContentText("下載成功,點擊安裝應用");
                        notificationBuilder.setContentIntent(pendingIntent);
                        notificationBuilder.setAutoCancel(true);
                        notification = notificationBuilder.build();
                        notificationManager.cancel(NotificationID);
                        notificationManager.notify(0, notification);
                        stopSelf();
                    }
                    @Override
                    public void onDownloading(int progress) {
                        notificationBuilder .setContentText("當前下載進度 " + progress + "%");
                        notification = notificationBuilder.build();
                        notificationManager.notify(NotificationID, notification);
                    }
                    @Override
                    public void onDownloadFailed(Exception e) {
                        notificationBuilder .setContentText("下載失敗");
                        notificationBuilder.setAutoCancel(true);
                        notification = notificationBuilder.build();
                        notificationManager.cancel(NotificationID);
                        notificationManager.notify(0, notification);
                        stopSelf();
                    }
                });
                我這裏用的是Okhttp3  請求的下載請求  方法有很多種  只能可以正常下載即可
public class DownloadUtil {

    private static DownloadUtil downloadUtil;
    private static OkHttpClient okHttpClient;
    public static DownloadUtil get() {
        if (downloadUtil == null) {
            downloadUtil = new DownloadUtil();
        }
        return downloadUtil;
    }
    public DownloadUtil() {
        okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(500, TimeUnit.MILLISECONDS)
                .readTimeout(500, TimeUnit.MILLISECONDS)
                .build();
    }

    public static void download( String url,  String destFileDir,  String destFileName,  OnDownloadListener listener) {
        Request request = new Request.Builder()
                .url(url)
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                listener.onDownloadFailed(e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                File dir = new File(destFileDir);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                File file = new File(dir, destFileName);
                try {
                    is = response.body().byteStream();
                    long total = response.body().contentLength();
                    fos = new FileOutputStream(file);
                    long sum = 0;
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        int progress = (int) (sum * 1.0f / total * 100);
                        listener.onDownloading(progress);
                    }
                    if (null != fos){
                        fos.flush();
                        listener.onDownloadSuccess(file);
                    }
                } catch (Exception e) {
                    listener.onDownloadFailed(e);
                }finally {

                    try {
                        if (is != null) {
                            is.close();
                        }
                        if (fos != null) {
                            fos.close();
                        }
                    } catch (IOException e) {

                    }

                }


            }
        });
    }


    public interface OnDownloadListener{

        /**
         * 下載成功之後的文件
         */
        void onDownloadSuccess(File file);

        /**
         * 下載進度
         */
        void onDownloading(int progress);

        /**
         * 下載異常信息
         */

        void onDownloadFailed(Exception e);
    }
}
這裏是下載方法發

4. 下載完成後可根據實際的實際需求 進行安裝 另外10.0之後 安裝方法也需要有所調整

  // 通過Intent安裝APK文件
    public static void installApk(Context context){
        File file = new File(DownloadConstant.PATH_APK_DOWNLOAD_MANAGER+"/zhaoyu.apk");
        Intent intent = new Intent("android.intent.action.VIEW");
        //適配N
        if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.N){
            Uri contentUrl = FileProvider.getUriForFile(context,"com.zhaoyugf.zhaoyu.FileProvider",file);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(contentUrl,"application/vnd.android.package-archive");
        }else{
            intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        context.startActivity(intent);
    }

最後別忘了註冊service

在AndroidManifest.xml 中的 application節點下進行註冊

附上完整代碼

package com.zhaoyugf.zhaoyu.service;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Build;
import android.os.IBinder;

import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;

import com.zhaoyugf.zhaoyu.R;
import com.zhaoyugf.zhaoyu.base.MainActivity;
import com.zhaoyugf.zhaoyu.update.DownloadConstant;
import com.zhaoyugf.zhaoyu.update.DownloadUtil;

import java.io.File;

/**
 * Created by wangjungang
 * E-Mail:[email protected]
 * on 2020/4/24
 */
public class UpdateService extends Service {
    public static String CALENDAR_ID = "channel_01";
    public static int NotificationID = 1;
    private NotificationManager notificationManager;
    private Notification notification;
    private NotificationCompat.Builder notificationBuilder;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    //通知欄跳轉Intent
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        createNotification(notificationManager);
        Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
        resultIntent.putExtra("Installapk", true);
        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        notificationBuilder = getNotificationBuilder();
        notification = notificationBuilder.build();
        notificationManager.notify(NotificationID, notification);
        DownloadUtil.get().download(DownloadConstant.apkDown, DownloadConstant.PATH_APK_DOWNLOAD_MANAGER, "zhaoyu.apk",
                new DownloadUtil.OnDownloadListener() {
                    @Override
                    public void onDownloadSuccess(File file) {
                        notificationBuilder .setContentText("下載成功,點擊安裝應用");
                        notificationBuilder.setContentIntent(pendingIntent);
                        notificationBuilder.setAutoCancel(true);
                        notification = notificationBuilder.build();
                        notificationManager.cancel(NotificationID);
                        notificationManager.notify(0, notification);
                        stopSelf();
                    }
                    @Override
                    public void onDownloading(int progress) {
                        notificationBuilder .setContentText("當前下載進度 " + progress + "%");
                        notification = notificationBuilder.build();
                        notificationManager.notify(NotificationID, notification);
                    }
                    @Override
                    public void onDownloadFailed(Exception e) {
                        notificationBuilder .setContentText("下載失敗");
                        notificationBuilder.setAutoCancel(true);
                        notification = notificationBuilder.build();
                        notificationManager.cancel(NotificationID);
                        notificationManager.notify(0, notification);
                        stopSelf();
                    }
                });

        return super.onStartCommand(intent, 0, 0);
    }

    public NotificationCompat.Builder getNotificationBuilder() {
        return new NotificationCompat.Builder(getApplicationContext(), CALENDAR_ID)
                .setWhen(System.currentTimeMillis())
                .setContentTitle("title")
                .setContentText("context...")
                .setSmallIcon(R.mipmap.ic_launcher_round)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),
                        R.mipmap.ic_launcher_round))
                .setAutoCancel(true);
    }

    private static void createNotification(NotificationManager notificationManager) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel notificationChannel = new NotificationChannel(CALENDAR_ID, "ander drowload apk default channel.",
                    NotificationManager.IMPORTANCE_MIN);
            // 設置渠道描述
            notificationChannel.setDescription("通知更新");
            // 是否繞過請勿打擾模式
            notificationChannel.canBypassDnd();
            // 設置繞過請勿打擾模式
            notificationChannel.setBypassDnd(true);
            // 桌面Launcher的消息角標
            notificationChannel.canShowBadge();
            // 設置顯示桌面Launcher的消息角標
            notificationChannel.setShowBadge(true);
            // 設置通知出現時聲音,默認通知是有聲音的
            notificationChannel.setSound(null, null);
            // 設置通知出現時的閃燈(如果 android 設備支持的話)
            notificationChannel.enableLights(false);

            notificationChannel.setLightColor(Color.RED);
            // 設置通知出現時的震動(如果 android 設備支持的話)
            notificationChannel.enableVibration(false);
            notificationManager.createNotificationChannel(notificationChannel);
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章