Android实现点击Notification通知栏,跳转指定activity页面

news2025/6/8 20:24:59

效果

1、点击通知栏通知,假如app正在运行,则直接跳转到指定activity显示具体内容,在指定activity中按返回键返回其上一级页面。

2、点击通知栏通知,假如app已经退出,先从SplashActivity进入,显示app启动界面,在Loginactivity判断是否登录状态完成后,进入MainActivity再跳转到指定activity显示具体内容,在指定activity中按Back键返回其上一级页面。

实现

1、定义【AndroidManifest.xml】清单

【android:parentActivityName】

通过定义上面这个属性来判断点击返回时的处理逻辑。

示例:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.lives">

    ......

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/logo"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/logo"
        android:supportsRtl="true"
        android:theme="@style/Theme.Lives"
        android:usesCleartextTraffic="true"
        tools:targetApi="31">
        <!-- 启动动画页面 -->
        <activity
            android:name=".activities.SplashActivity"
            android:exported="true"
            android:theme="@style/SplashTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!-- 登录页面 -->
        <activity
            android:name=".activities.LoginActivity"
            android:exported="false" />
        <!-- 主页面 -->
        <activity
            android:name=".activities.MainActivity"
            android:exported="false" />
        <!-- 一级子页面 -->
        <activity
            android:name=".activities.NoticeActivity"
            android:parentActivityName=".activities.MainActivity"
            android:exported="false" />
        <!-- 二级子页面 -->
        <activity
            android:name=".activities.NoticeItemActivity"
            android:parentActivityName=".activities.NoticeActivity"
            android:exported="false" />

        ......
    </application>

</manifest>

 注意:因为逻辑原因,我们不能在主界面点击返回时,返回到登录界面,所以LoginActivity、SplashActivity和MainActivity这3个是不能添加这个父组件参数的,我们会在后面进行处理的。

2、实现notification配置

我是在我自己的websocket服务中直接调用的,你们自己也可以封装成一个工具类,我的代码示例:

/**
     * 发送消息通知
     * @param title 通知标题
     * @param message 通知内容
     * @param type 通知类型
     * @param targetActivityClass 点击通知后要跳转的目标 Activity 类
     */
    private void sendMessageNotification(String title, String message, Class<?> targetActivityClass) {
        Intent resultIntent;
        // 判断当前app是否运行中
        if (!isAppRunning()) {
            // 如果 app 已退出,先启动 SplashActivity
            Log.d(TAG, "App 未运行,启动 SplashActivity");
            resultIntent = new Intent(this, SplashActivity.class);
            // 携带目标 Activity 信息,方便后续跳转
            resultIntent.putExtra("targetActivity", targetActivityClass.getName());
            resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        } else {
            // 如果 app 未退出,直接使用原有目标 Activity
            Log.d(TAG, "App 运行中,直接使用目标 Activity");
            resultIntent = new Intent(this, targetActivityClass);
        }

        // 创建一个 TaskStackBuilder 实例,用于构建一个任务栈,该任务栈可以帮助管理 Activity 的启动顺序和回退行为
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        // 将目标意图 resultIntent 添加到任务栈中,并根据 AndroidManifest.xml 中的父 Activity 配置构建完整的任务栈
        stackBuilder.addNextIntentWithParentStack(resultIntent);
        // 从任务栈中获取一个 PendingIntent,该 PendingIntent 包含了任务栈中的所有意图
        // 0 表示请求码,用于唯一标识这个 PendingIntent
        // PendingIntent.FLAG_UPDATE_CURRENT 表示如果该 PendingIntent 已经存在,则更新其内部的额外数据
        PendingIntent pendingIntent =
                stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

        // 执行消息发送
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_launcher_background)  // 设置通知小图标
                .setContentTitle(title) // 设置通知标题
                .setContentText(message) // 设置通知内容
                .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级为高
                .setDefaults(Notification.DEFAULT_ALL) // 设置默认的声音、震动和灯光
                .setFullScreenIntent(null, true) // 对于紧急通知,可触发横幅通知
                .setContentIntent(pendingIntent) // 设置点击通知后的跳转意图
                .setAutoCancel(true); // 点击通知后自动取消通知

        // 发送通知
        notificationManager.notify((int) System.currentTimeMillis(), builder.build());
    }

    // 判断是否app当前运行中
    private boolean isAppRunning() {
        // 获取当前运行的应用程序列表
        ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        // 获取当前应用程序的包名
        List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
        if (appProcesses == null) {
            return false;
        }
        // 遍历应用程序列表,检查当前应用程序是否在运行中
        final String packageName = getPackageName();
        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND &&
                    appProcess.processName.equals(packageName)) {
                return true;
            }
        }
        return false;
    }
// 执行生成Notification通知
sendMessageNotification("标题", "内容", NoticeItemActivity.class);

3、在SplashActivity等未配置父组件参数的3个Activity中进行判断处理跳转

在onCreate方法中调用如下代码

// 检查是否有指定跳转的目标Activity信息(例如通知栏跳转等)
Intent intent = getIntent();
Intent loginIntent = new Intent(SplashActivity.this, LoginActivity.class);
if (intent.hasExtra("targetActivity")) {
     String targetActivityName = intent.getStringExtra("targetActivity");
     Log.d("SplashActivity", "SplashActivity检查到存在目标Activity: " + targetActivityName);
     loginIntent.putExtra("targetActivity", targetActivityName);
} else {
     Log.d("SplashActivity", "SplashActivity未检查到存在目标Activity,直接跳转登录页面");
}
startActivity(loginIntent);
finish();

其他2个Activity同理,但是MainActivity有点区别,因为他需要到指定Activity,代码如下:

// 检查是否有指定跳转的目标Activity信息(例如通知栏跳转等)
Intent intent = getIntent();
if (intent.hasExtra("targetActivity")) {
   String targetActivityName = intent.getStringExtra("targetActivity");
   Log.d(TAG, "MainActivity检查到存在目标Activity: " + targetActivityName);
   if(targetActivityName.equals("com.example.lives.activities.MainActivity")) {
        Log.d(TAG, "当前已经处于主页面,无需跳转");
   } else {
        try {
            Class<?> targetActivityClass = Class.forName(targetActivityName);
            // 使用 Handler 进行延时操作
            new android.os.Handler(android.os.Looper.getMainLooper()).postDelayed(() -> {
                 Intent targetIntent = new Intent(MainActivity.this, targetActivityClass);
                 startActivity(targetIntent);
            }, 200);
        } catch (ClassNotFoundException e) {
            Log.e(TAG, "MainActivity跳转目标Activity未实现: " + e);
        }
   }
} else {
   Log.d(TAG, "MainActivity未检查到存在目标Activity,无需操作");
}

这样就基本实现了我们想要的效果,具体一些细节体验可以继续优化,欢迎大家交流!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2404528.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Codeforces Round 1025 (Div. 2) B. Slice to Survive

Codeforces Round 1025 (Div. 2) B. Slice to Survive 题目 Duelists Mouf and Fouad enter the arena, which is an n m n \times m nm grid! Fouad’s monster starts at cell ( a , b ) (a, b) (a,b), where rows are numbered 1 1 1 to n n n and columns 1 1 1 t…

ubuntu中使用docker

上一篇我已经下载了一个ubuntu:20.04的镜像&#xff1b; 1. 查看所有镜像 sudo docker images 2. 基于本地存在的ubuntu:20.04镜像创建一个容器&#xff0c;容器的名为cppubuntu-1。创建的时候就会启动容器。 sudo docker run -itd --name cppubuntu-1 ubuntu:20.04 结果出…

[ElasticSearch] DSL查询

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

iview中的table组件点击一行中的任意一点选中本行

<Table border ref"selection" size"small" on-row-click"onClickRow"></Table>// table组件点击一行任意位置选中onClickRow(row, index) {this.$refs.selection.toggleSelect(index)}写上toggleSelect(index)方法即可&#xff0c;…

《探秘跨网段局域网IP广播:解锁网络通信的新姿势》

一、从基础出发:广播与跨网段 在计算机网络的世界中,广播域是一个至关重要的概念。简单来说,广播域是指网络中能接收任一台主机发出的广播帧的所有主机集合。当一台主机在广播域内发出一个广播帧时,同一广播域内的所有其他主机都可以收到该广播帧。在没有路由器或 VLAN 分割…

maven微服务${revision}依赖打包无法识别

1、场景描述 我现在又一个微服务项目&#xff0c;父pom的版本&#xff0c;使用<properties>定义好&#xff0c;如下所示&#xff1a; <name>ypsx-finance-center</name> <artifactId>ypsx-finance</artifactId> <packaging>pom</pack…

2025年06月07日Github流行趋势

项目名称&#xff1a;netbird 项目地址url&#xff1a;https://github.com/netbirdio/netbird项目语言&#xff1a;Go历史star数&#xff1a;14824今日star数&#xff1a;320项目维护者&#xff1a;mlsmaycon, braginini, pascal-fischer, lixmal, pappz项目简介&#xff1a;使…

WPS中将在线链接转为图片

WPS中将在线链接转为图片 文章目录 WPS中将在线链接转为图片一&#xff1a;解决方案1、下载图片&#xff0c;精确匹配&#xff08;会员功能&#xff09;2、将在线链接直接转为图片 一&#xff1a;解决方案 1、下载图片&#xff0c;精确匹配&#xff08;会员功能&#xff09; …

实战二:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…

vue生成二维码图片+文字说明

需求&#xff1a;点击下载图片&#xff0c;上方是二维码&#xff0c;下方显示该二维码的相关内容&#xff0c;并且居中显示&#xff0c;支持换行 解决方案步骤&#xff1a; 1. 使用qrcode生成二维码的DataURL。 2. 创建canvas&#xff0c;将二维码图片绘制到canvas的上半部分…

机器学习监督学习实战五:六种算法对声呐回波信号进行分类

本项目基于UCI的声呐目标识别数据集&#xff08;Sonar, Mines vs. Rocks&#xff09;&#xff0c;通过10种机器学习算法比较&#xff0c;发现集成学习方法表现最优。研究首先对60个声呐能量特征进行可视化分析&#xff08;分布直方图、相关性矩阵&#xff09;&#xff0c;对比了…

​React Hooks 的闭包陷阱问题

这是主包在面试中遇到的一道题目&#xff0c;面试官的问题是&#xff1a;"这个页面初次展示出来时Count和step的值是什么&#xff0c;我点击按钮count和step的值有什么变化&#xff1f;“ 这个题目主包回答的不好&#xff0c;所以想做一个总结。 题目 import React, { …

力扣面试150题--克隆图

Day 61 题目描述 思路 /* // Definition for a Node. class Node {public int val;public List<Node> neighbors;public Node() {val 0;neighbors new ArrayList<Node>();}public Node(int _val) {val _val;neighbors new ArrayList<Node>();}public N…

鸿蒙PC,有什么缺点?

点击上方关注 “终端研发部” 设为“星标”&#xff0c;和你一起掌握更多数据库知识 价格太高&#xff0c;二是部分管理员权限首先&#xff0c;三对于开发者不太友好举个例子&#xff1a;VSCode的兼容性对程序员至关重要。若能支持VSCode&#xff0c;这台电脑将成为大多数开发者…

PDF图片和表格等信息提取开源项目

文章目录 综合性工具专门的表格提取工具经典工具 综合性工具 PDF-Extract-Kit - opendatalab开发的综合工具包&#xff0c;包含布局检测、公式检测、公式识别和OCR功能 仓库&#xff1a;opendatalab/PDF-Extract-Kit特点&#xff1a;功能全面&#xff0c;包含表格内容提取的S…

《Progressive Transformers for End-to-End Sign Language Production》复现报告

摘要 本文复现了《Progressive Transformers for End-to-End Sign Language Production》一文中的核心模型结构。该论文提出了一种端到端的手语生成方法&#xff0c;能够将自然语言文本映射为连续的 3D 骨架序列&#xff0c;并引入 Counter Decoding 实现动态序列长度控制。我…

计算机视觉——相机标定

计算机视觉——相机标定 一、像素坐标系、图像坐标系、相机坐标系、世界坐标系二、坐标系变换图像坐标系 → 像素坐标系相机坐标系 → 图像坐标系世界坐标系 → 相机坐标系 ⋆ \star ⋆ 世界坐标系 → 像素坐标系 三、相机标定 一、像素坐标系、图像坐标系、相机坐标系、世界坐…

C语言中的数据类型(二)--结构体

在之前我们已经探讨了C语言中的自定义数据类型和数组&#xff0c;链接如下&#xff1a;C语言中的数据类型&#xff08;上&#xff09;_c语言数据类型-CSDN博客 目录 一、结构体的声明 二、结构体变量的定义和初始化 三、结构体成员的访问 3.1 结构体成员的直接访问 3.2 结…

C++11:原子操作与内存顺序:从理论到实践的无锁并发实现

文章目录 0.简介1.并发编程需要保证的特性2.原子操作2.1 原子操作的特性 3.内存顺序3.1 顺序一致性3.2 释放-获取&#xff08;Release-Acquire)3.3 宽松顺序&#xff08;Relaxed)3.4 内存顺序 4.无锁并发5. 使用建议 0.简介 在并发编程中&#xff0c;原子性、可见性和有序性是…

动力电池点焊机:驱动电池焊接高效与可靠的核心力量|比斯特自动化

在新能源汽车与储能设备需求激增的背景下&#xff0c;动力电池的制造工艺直接影响产品性能与安全性。作为电芯与极耳连接的核心设备&#xff0c;点焊机如何平衡效率、精度与可靠性&#xff0c;成为电池企业关注的重点。 动力电池点焊机的核心功能是确保电芯与极耳的稳固连接。…