欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

关于Android Q上点击通知无法跳转的问题

程序员文章站 2022-06-24 12:36:43
在Android Q 即api 29上,可能会出现使用PendingIntent点击通知无法跳转的问题,但是你找了半天找不到问题,举个例子,app自动更新兼容android Q的时候就会遇到这个问题,下载完安装,当app处于前台的时候没有任何问题,在后台的时候就会出现问题,因为google在Android Q 上禁止后台启动activity了,所以当你在gradle中设置:targetSdkVersion 29后就会出现app在后台的时候无法启动系统的安装程序了,于是查阅资料人家会告诉你这样写:ap...

在Android Q 即api 29上,可能会出现使用PendingIntent点击通知无法跳转的问题,但是你找了半天找不到问题,举个例子,app自动更新兼容android Q的时候就会遇到这个问题,下载完安装,当app处于前台的时候没有任何问题,在后台的时候就会出现问题,因为google在Android Q 上禁止后台启动activity了,所以当你在gradle中设置:

targetSdkVersion 29

后就会出现app在后台的时候无法启动系统的安装程序了,于是查阅资料人家会告诉你这样写:
app兼容Android Q启动安装程序兼容代码:

    public static void installApk(Context mContext, File apkFile) {
        if (!apkFile.exists()) {
            return;
        }
        Intent i = new Intent(Intent.ACTION_VIEW);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK |
                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件
            Uri apkFileUri = FileProvider.getUriForFile(mContext,
                    mContext.getPackageName() + ".fileprovider", apkFile);
            i.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
            mContext.startActivity(i);
        } else {
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            i.setDataAndType(Uri.parse("file://" + apkFile.toString()),
                    "application/vnd.android.package-archive");
            mContext.startActivity(i);
        }
    }

首先你会发现这样写前台安装没问题,但是后台安装就会有问题了,然后利用点击通知启动安装程序的方式兼容android Q后台启动activity:

/**
 * Created by 方舟 on 2017/10/13.
 * 更新通知
 */
public class UpdateNotificationUtil extends ContextWrapper {

    private Context mContext;
    private static NotificationManager mManager;
    private NotificationCompat.Builder mBuilder;
    private static UpdateNotificationUtil updateNotificationUtil;

    public static UpdateNotificationUtil getInstance() {
        if (updateNotificationUtil != null && mManager != null) {
            return updateNotificationUtil;
        }
        synchronized (ApplicationHelper.getInstance()) {
            if (updateNotificationUtil == null || mManager == null) {
                updateNotificationUtil = new UpdateNotificationUtil(ApplicationHelper.getInstance());
            }
        }
        return updateNotificationUtil;
    }

    private UpdateNotificationUtil(Context context) {
        super(context);
        this.mContext = context;
        mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    }
    
    @RequiresApi(api = Build.VERSION_CODES.O)
    public void createNotificationChannel() {
        NotificationChannel channel = new NotificationChannel(ConstantsHelper.NOTIFY_CHANNEL_ID,
                ConstantsHelper.NOTIFY_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
        mManager.createNotificationChannel(channel);
    }

    public void sendNotificationFullScreen(String title, String content, File apkFile) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createNotificationChannel();
            Intent i = new Intent(Intent.ACTION_VIEW);
            i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK |
                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件
            Uri apkFileUri = FileProvider.getUriForFile(ApplicationHelper.getInstance(),
                    ApplicationHelper.getInstance().getPackageName() + ".fileprovider", apkFile);
            i.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
            PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(ApplicationHelper.getInstance(),
                    1, i, PendingIntent.FLAG_UPDATE_CURRENT);

            NotificationCompat.Builder notificationBuilder =
                    new NotificationCompat.Builder(this, ConstantsHelper.NOTIFY_CHANNEL_ID)
                            .setSmallIcon(R.mipmap.ic_launcher)
                            .setContentTitle(title)
                            .setTicker(content)
                            .setContentText(content)
                            .setAutoCancel(true)
                            .setDefaults(Notification.DEFAULT_ALL)
                            .setPriority(NotificationCompat.PRIORITY_MAX)
                            .setCategory(Notification.CATEGORY_CALL)
                            .setFullScreenIntent(fullScreenPendingIntent, true);
            Notification notification = notificationBuilder.build();
            mManager.notify(1, notification);
        }
    }

    public void clearAllNotification() {
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if (notificationManager != null) {
            notificationManager.cancelAll();
        }
    }
}

当app前台已经有通知了就不会再发送通知了,因此在创建通知前需要先清空

            UpdateNotificationUtil notificationUtils = UpdateNotificationUtil.getInstance();
            notificationUtils.clearAllNotification();
            notificationUtils.sendNotificationFullScreen("新版本已下载完成", "点击安装", apkFile);
            mContext.startActivity(i);

优化后的installApk方法:

  public static void installApk(Context mContext, File apkFile) {
        if (!apkFile.exists()) {
            return;
        }
        Intent i = new Intent(Intent.ACTION_VIEW);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK |
                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件
            Uri apkFileUri = FileProvider.getUriForFile(mContext,
                    mContext.getPackageName() + ".fileprovider", apkFile);
            i.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
            UpdateNotificationUtil notificationUtils = UpdateNotificationUtil.getInstance();
            notificationUtils.clearAllNotification();
            notificationUtils.sendNotificationFullScreen("新版本已下载完成", "点击安装", apkFile);
            mContext.startActivity(i);
        } else {
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            i.setDataAndType(Uri.parse("file://" + apkFile.toString()),
                    "application/vnd.android.package-archive");
            mContext.startActivity(i);
        }
    }

网上会告诉你这样写已经大功告成了!!!
NO!NO!NO!这样还是会有问题,这样的话,在华为、oppo、vivo部分机型上点击通知栏是不会启动安装程序的,就是点击没有反应。
需要添加全屏通知权限

//AndroidManifest 声明新权限,不用动态申请
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/>

这样才是大功告成!

本文地址:https://blog.csdn.net/fzkf9225/article/details/107151777