Android 集成firebase 推送(FCM)

1,集成firebase 基础

1>googleService文件

2>项目级gradle

3>app级gradle

4>setting 

2,推送相关

重点:

源文档:设置 Firebase Cloud Messaging 客户端应用 (Android) (google.com)

/*** 监听推送的消息* 三种情况:* 1,通知时:* 当应用处于前台的时候,推送的消息会走onMessageReceived方法,处于后台时走系统托盘。* 2,数据时:* 当应用处于前、后台的时候,会走onMessageReceived方法。* 3,通知且携带数据:* 当应用处于前台的时候,推送的消息会走onMessageReceived方法,处于后台时,通知走系统托盘,数据走Intent 的 extra 中(点击通知栏后)。*/

1>清单文件

2>MyFirebaseMessagingService类

/*** 推送数据对通知的影响* 1,如果我们推送的数据 notification 对应的数据 不为空,那么我们接收消息就需要分为两种情况,* 前台和后台,如果App当前状态为前台,那么 onMessageReceived 方法就会被调用,* 后续我们自己拿到对用的数据进行通知栏的显示,如果App当前状态为后台的话 那么我们无需自己写 sdk会自己弹出。**,2,如果我们推送的数据 notification 对应的数据为空,把所有的数据放置到data 字段里面,* 那么sdk不会为我们弹出通知,这时候无论App在前台还是后台都会调用 onMessageReceived ,* 这时候我们自己需要处理通知栏的ui 显示。这种情况一般用于自定义通知栏ui 的时候。*/public class MyFirebaseMessagingService extends FirebaseMessagingService {/*** 监听推送的消息* 三种情况:* 1,通知时:* 当应用处于前台的时候,推送的消息会走onMessageReceived方法,处于后台时走系统托盘。* 2,数据时:* 当应用处于前、后台的时候,会走onMessageReceived方法。* 3,通知且携带数据:* 当应用处于前台的时候,推送的消息会走onMessageReceived方法,处于后台时,通知走系统托盘,数据走Intent 的 extra 中(点击通知栏后)。*/@Overridepublic void onMessageReceived(@NonNull RemoteMessage message) {String testDemo = "0";//测试数据,后端自定义消息/或控制台测试时输入键值,时传递来 “键”-“值” 中的 值
//        Map<String, String> remoteMessageMap = message.getData();if (message.getData() != null && !message.getData().isEmpty()) {//不自定义消息,getData为空if (message.getData().size() > 0) {testDemo = message.getData().get("testDemo");//“键”-“值” 中的 键}}if (message.getNotification() != null && !message.getNotification().getTitle().isEmpty() && !message.getNotification().getBody().isEmpty()) {
//            sendNotification(message.getNotification().getTitle(), message.getNotification().getBody(), testDemo);String click_action = message.getNotification().getClickAction();sendNotification(message.getNotification().getTitle(), message.getNotification().getBody(), testDemo, click_action);}}/*** 当有新的Firebase token 时的回调* 第一次安装app 获取到的 pushtoken*/@Overridepublic void onNewToken(@NonNull String token) {//token 传递给后端!!Log.e("测试", "onNewToken =" + token);}/*** 自定义通知** @param messageBody*/private void sendNotification(String messageTitle, String messageBody, String testDemo, String click_action) {Intent intent = prepareIntent(click_action);
//    private void sendNotification(String messageTitle, String messageBody, String testDemo) {
//        Intent intent = new Intent(this, MainActivity.class);String channelID = getResources().getString(R.string.default_notification_channel_id);//渠道IDString channelName = getResources().getString(R.string.default_notification_channel_name);//渠道名称intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);if (testDemo != null && !testDemo.isEmpty()) {intent.putExtra("testDemo", testDemo);}int uniqueInt = (int) (System.currentTimeMillis() & 0xff);PendingIntent pendingIntent = PendingIntent.getActivity(this, uniqueInt /* Request code */, intent, PendingIntent.FLAG_UPDATE_CURRENT);NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);NotificationCompat.Builder notificationBuilder;//android 8 开始要 创建通知渠道,否则通知栏不弹出if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {notificationBuilder = new NotificationCompat.Builder(this, channelID);NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);notificationManager.createNotificationChannel(channel);} else {notificationBuilder = new NotificationCompat.Builder(this);}//设置titleif (messageTitle != null && !messageTitle.isEmpty()) {notificationBuilder.setContentTitle(messageTitle);} else {notificationBuilder.setContentTitle(getResources().getString(R.string.app_name));}//设置bodyif (messageBody != null && !messageBody.isEmpty()) {notificationBuilder.setContentText(messageBody);}
//        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);notificationBuilder.setSmallIcon(R.drawable.icon_return)//设置通知栏的小图标,必需设置,否则crash.setAutoCancel(true)//点击通知后,通知自动消失.setWhen(System.currentTimeMillis())// 设置通知时间,此事件用于通知栏排序.setPriority(NotificationCompat.PRIORITY_HIGH)// 设置优先级,低优先级可能被隐藏
//                .setSound(defaultSoundUri).setContentIntent(pendingIntent);//设置通知栏被点击时的事件notificationManager.notify(uniqueInt /* ID of notification */, notificationBuilder.build());}public Intent prepareIntent(String clickAction) {Intent intent;boolean isAppInBackground;isAppInBackground = ProcessJudgmentHelper.isRunBackground(this);if (isAppInBackground) {intent = new Intent(this, MainActivity.class);} else {intent = new Intent(clickAction);}return intent;}/*** 1,如果未开启通知,则跳转到通知设置界面,点击之后就需要跳转到 APP的通知设置界面,* 对应的Action是:Settings.ACTION_APP_NOTIFICATION_SETTINGS, 这个Action是 API 26 后增加的。* 2,如果在部分手机中无法精确的跳转到APP对应的通知设置界面,我们就考虑直接跳转到APP信息界面,* 对应的Action是:Settings.ACTION_APPLICATION_DETAILS_SETTINGS。**/}

4>主启动Activity(清单文件里设置 <action android:name="android.intent.action.MAIN" /> 的Activity)


/*** 1,清单文件里设置 <action android:name="android.intent.action.MAIN" /> 的Activity,一般是Splish 闪屏页。* 在onCreate() 方法里 获取用户PushToken,调用接口传给自己的后端,以防有变化。* 2,如果是自定义消息(当后端或者控制台设置响应的data 键值)在onResume() 方法里 使用intent 获取到对应的值,进行相关操作,* 例如:根据约定值 进行响应页面的跳转。***/
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);requestPer();try {boolean goolgePlayServiceAvailable = FirebaseManager.getInstance().isGoolgePlayServiceAvailable(this);if (goolgePlayServiceAvailable) {uploadPushToken();} else {Log.e("测试", "谷歌服务不可用");}} catch (Exception e) {e.printStackTrace();Log.e("测试", "谷歌服务异常");}}@Overrideprotected void onResume() {super.onResume();Intent intent = getIntent();//当后端或者控制台设置自定义消息后,点击通知时能获取到对应的值String testDemo = intent.getStringExtra("testDemo");if (testDemo != null && !testDemo.isEmpty()) {//如有特殊情形,要判断是否登录,没登录跳转登录页
//            if(){
//            }if (testDemo.equals("66")) {Intent intentSeconActivity = new Intent(this, SeconActivity.class);startActivity(intentSeconActivity);finish();}}}/*** 上传push token* 正常情况下每次启动 都会获取到!*/private void uploadPushToken() {FirebaseMessaging.getInstance().getToken().addOnCompleteListener(new OnCompleteListener<String>() {@Overridepublic void onComplete(@NonNull Task<String> task) {if (!task.isSuccessful()) {Log.e("测试", "Fetching FCM registration token failed", task.getException());return;}// Get new FCM registration tokenString token = task.getResult();Log.e("测试", "MainActivity token =" + token);}});}/*** android 高版本请求推送权限*/private void requestPer() {XXPermissions.with(this)// 申请单个权限.permission(Permission.POST_NOTIFICATIONS).request(new OnPermissionCallback() {@Overridepublic void onGranted(List<String> permissions, boolean all) {}@Overridepublic void onDenied(List<String> permissions, boolean never) {if (never) {} else {}}});}
}

==================结束===============

工具方法:
 

    /** 判断程序是否在后台运行 */public static boolean isRunBackground(Context context) {ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {if (appProcess.processName.equals(context.getPackageName())) {if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {// 表明程序在后台运行return true;} else {return false;}}}return false;}

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

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

相关文章

el-tree多个树进行节点同步联动(完整版)

2024.1.11今天我学习了如何对多个el-tree树进行相同节点的联动效果&#xff0c;如图&#xff1a; 这边有两棵树&#xff0c;我们发现第一个树和第二个树之间会有重复的指标&#xff0c;当我们选中第一个树的指标&#xff0c;我们希望第二个树如果也有重复的指标也能进行勾选上&…

Qt 调试体统输出报警声

文章目录 前言一、方法1 使用 Qsound1.添加都文件 直接报错2.解决这个错误 添加 QT multimedia3. 加入代码又遇到新的错误小结 二、第二种方法1.引入库 总结 前言 遇到一个需求&#xff0c;使用Qt输出报警声&#xff0c;于是试一试能调用的方法。 一、方法1 使用 Qsound 1.…

什么是金融RPA?金融RPA解决什么问题?金融RPA实施难点在哪里?

什么是金融RPA&#xff1f;金融RPA&#xff0c;即金融领域的机器人流程自动化&#xff0c;是一种利用软件机器人来代替人工完成重复性劳动任务的技术。它能够通过模仿最终用户在电脑上的手动操作方式&#xff0c;实现自动化处理大量重复、规则明确的业务流程&#xff0c;如账务…

44-js return返回值,全局作用域,局部作用域,隐式作用域,变量的生命周期,delete释放内存

1.return返回值:函数执行后剩下结果就是返回值。 function fn(a,b,c){//return返回值return(a+b+c);// console.log("aaa"); //return之后的值都不在执行了// alert("bbb"); //return之后的值不在执行了}console.log(fn(1,2,3)*10); 2.作用…

低静态功耗的音频功率放大器D7368GS,适用于便携式立体声收录机应用

D7368是专为便携式立体声收录机而设计的音频功率放大器集成电路。 主要特点&#xff1a; ● 低静态功耗&#xff1a; Icco6 6mA(Typ) (Vcc6V) ● 电压增益高&#xff1a;40dB ( 典型值)。 ● 工作电源电压范围宽&#xff1a;Vcc2~10V. . ● 外围使用元件少( 仅需三个电容)。 ●…

软件测试|如何在Linux中下载和安装软件包

简介 在Linux操作系统中&#xff0c;下载和安装软件包是一项基本任务。不同的Linux发行版可能有不同的包管理工具和方式&#xff0c;但总体流程是类似的。以下是在Linux中下载和安装软件包的详细步骤。 步骤1&#xff1a;选择适当的包管理工具 因为Linux有不同的发行版本&am…

活动回顾∣“全邻友好,艺术大咖交流会”——员村街开展社区微型养老博览会长者文艺汇演活动

为进一步营造邻里守望&#xff0c;共建美好社区的氛围&#xff0c;促进社区长者参与社区服务&#xff0c;展示社区长者健康、积极向上的精神风貌&#xff0c;2024年1月10日&#xff0c;员村街开展“全邻友好&#xff0c;艺术大咖交流会”——微型养老博览会活动&#xff0c;让长…

Docker安装Redis 配置文件映射以及密码设置

安装直接docker pull redis即可&#xff0c;默认redis最新版 设置两个配置文件路径 mkdir -p /root/docker/redis/data mkdir -p /root/docker/redis/conf touch redis.conf // 容器挂载用conf配置文件 bind 0.0.0.0 protected-mode yes port 6379 tcp-backlog 511 timeout…

轴组【CAN】

如果有126个轴&#xff0c;你程序里挨个添加轴很麻烦。 可以用轴组批量添加。【数组】 CAN驱动器 0x164 就是下个驱动器 p_CAN主站地址:ADR(IoConfig_Globals.CANopen_Manager_SoftMotion);p_CAN从站地址1:ADR(IoConfig_Globals.DMA882_CAN);p_CAN从站地址2:ADR(IoConfig_Gl…

Swin Transformer 学习笔记(附代码)

论文地址&#xff1a;https://arxiv.org/pdf/2103.14030.pdf 代码地址&#xff1a; GitHub - microsoft/Swin-Transformer: This is an official implementation for "Swin Transformer: Hierarchical Vision Transformer using Shifted Windows". 1.是什么&#x…

libignition-gazebo-diff-drive-system.so是什么

因该就是个动态链接库&#xff0c;库文件之类 而且就是gazebo6版本也就是ign 这个版本的动态链接库有个特点&#xff1a;全部都是以.so结尾&#xff0c;所以很可能ign的插件plugin都是带.so的 abcdegx.so elvikorflsd.so fvlwirjgiojf.so等

Android可换行的RadioGroup

Android可换行的RadioGroup,有时候需要换行显示的单选列表&#xff0c;当然可以有多种实现方式&#xff0c;比如recycleview或者listview实现&#xff0c;本文采用的是RadioGrouprediobutton方式实现。 一、首先自定义view public class WrapRadioGroup extends RadioGroup {pr…

经典算法-模拟退火算法求解旅行商问题TSP

经典算法-模拟退火算法求解旅行商问题TSP 旅行商问题&#xff08;Traveling Salesman Problem, TSP&#xff09;是组合优化中的经典问题。简单地说&#xff0c;一个旅行商需要访问N个城市&#xff0c;并返回到出发城市&#xff0c;问题是找到最短的可能路线&#xff0c;使得每…

【第一次使用finalshell连接虚拟机内的centos】小白处理方式

第一次使用finalshell连接centos7的时候&#xff0c;因为都是新环境什么都没有配置&#xff0c;所以就需要安装finalshell和对新的centos7 进行一些配置。 安装finalshel&#xff0c;默认不安装d盘&#xff0c;就需要对安装路径做一下调整&#xff0c;其余都是下一步默认安装的…

【AIGC】2023年生成式AI发展综述

文章目录 一、文本生成 & 智能问答二、AI绘画三、音频生成四、视频生成五、三维生成 & 数字人5.1 通用三维生成5.2 数字人 展望&#xff1a;通用人工智能趋势 2023年是人工智能内容生成&#xff08;AIGC&#xff09;技术飞速发展的一年。从年初ChatGPT一炮打响&#xf…

大模型学习与实践笔记(二)

一、代码仓库&#xff1a; InternLM: https://github.com/InternLM/InternLM/ 课程讲师&#xff1a;宋志学大佬&#xff0c;d2l-ai-solutions-manual 开源项目负责人 二、Lagent框架 三、基于InternLM的智能对话 3.1 环境配置&#xff1a; cuda11.7 pytorch2.0.1 其他环境…

C++每日一练(15):简单幂计算

题目描述 输入两个数a和b&#xff0c;求a的b次方。 输入 输入两个整数a&#xff0c;b&#xff08;1<a<10&#xff0c;1<b<15&#xff09;。 输出 输出一个正整数&#xff0c;该值<1000000000000。 输入样例 3 3 输出样例 27 参考答案 #include<bits/stdc.h&…

CDH 6.3启动失败,由于日志写入权限原因导致cloudera-scm-server.log未生成

CDH 6.3启动失败&#xff0c;CM之前都能正常启动&#xff0c;服务器重启后&#xff0c;启动出现异常&#xff0c;需要排查具体错误&#xff0c;查看日志&#xff0c;发现日志cloudera-scm-server.log也未生成&#xff0c;不好定位具体原因。于是查看cloudera-scm-server状态&am…

CVE-2023-36025 Windows SmartScreen 安全功能绕过漏洞

CVE-2023-36025是微软于11月补丁日发布的安全更新中修复Windows SmartScreen安全功能绕过漏洞。攻击者可以通过诱导用户单击特制的URL来利用该漏洞&#xff0c;对目标系统进行攻击。成功利用该漏洞的攻击者能够绕过Windows Defender SmartScreen检查及其相关提示。该漏洞的攻击…

PCIe进阶之Gen3 Physical Layer Receive Logic(一)

1 文章概述 本篇文章是接着前面两篇文章进一步研究Gen3 Physical Layer Receive Logic的实现,具体包含Differential Receiver,CDR(Clock and Data Recovery)和Receiver Clock Compensation Logic 三个部分的介绍和解析。 1.1 Differential Receiver Gen3的Differential …