android 集成 firebase 推送
1、集成sdk
project
classpath 'com.google.gms:google-services:4.3.10'classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.0'
app
plugins {id 'com.android.application'id 'kotlin-android'id 'kotlin-android-extensions'id 'kotlin-kapt'id 'com.google.gms.google-services'id 'com.google.firebase.crashlytics'
}
implementation platform('com.google.firebase:firebase-bom:29.0.0')implementation 'com.google.firebase:firebase-analytics-ktx'implementation 'com.google.firebase:firebase-crashlytics'implementation 'com.google.firebase:firebase-messaging'
在android{}里面配置,防止编译不过
gradle.taskGraph.whenReady {tasks.each { task ->if (task.name.contains("uploadCrashlyticsMappingFile")) {task.enabled = false}}}
把xxx.json放到app目录下面,至此配置结束
2.在manifest.xml中配置,
MyFirebaseMessagingService用来获取推送过来的消息,以及token变化时,把token传给自家的后端
<serviceandroid:name=".base.MyFirebaseMessagingService"android:exported="false"><intent-filter><action android:name="com.google.firebase.MESSAGING_EVENT" /></intent-filter></service><!-- Set custom default icon. This is used when no icon is set for incoming notification messages.See README(https://goo.gl/l4GJaQ) for more. --><meta-dataandroid:name="com.google.firebase.messaging.default_notification_icon"android:resource="@drawable/bc_app_logo" /><!-- Set color used with incoming notification messages. This is used when no color is set for the incomingnotification message. See README(https://goo.gl/6BKBk7) for more. --><meta-dataandroid:name="com.google.firebase.messaging.default_notification_color"android:resource="@color/font_green" />
**
3.MyFirebaseMessagingService:
**
/*** @des* @date 2022/3/7* @author sam*/
class MyFirebaseMessagingService : FirebaseMessagingService() {private val PUSH_CHANNEL_ID = "ID"private val PUSH_CHANNEL_NAME = "peacock"private val mNotificationId = 1000private var mNotificationManager: NotificationManager? = nulloverride fun onCreate() {super.onCreate()mNotificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManagerif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {val channel = NotificationChannel(PUSH_CHANNEL_ID,PUSH_CHANNEL_NAME,NotificationManager.IMPORTANCE_HIGH)if (mNotificationManager != null) {mNotificationManager!!.createNotificationChannel(channel)}}}override fun onMessageReceived(p0: RemoteMessage) {super.onMessageReceived(p0)p0.notification?.body?.apply {if (!isRunBackground(applicationContext)) {sendNotification(p0.notification!!.body!!, p0)}}}override fun onNewToken(p0: String) {super.onNewToken(p0)Log.e("token changed--->",p0)subToken(p0)}/*** 在前台时,点击时的跳转逻辑,及推送通知*/private fun sendNotification(messageBody: String, remoteMessage: RemoteMessage) {val intent: Intentif (remoteMessage.data.isNotEmpty() && remoteMessage.data["type"] != null && remoteMessage.data["orderId"] != null) {//提现if (remoteMessage.data["type"] == "1") {intent = Intent(this, OrderDetailActivity::class.java)intent.putExtra("isShowOnly", false)intent.putExtra("orderId", remoteMessage.data["orderId"]!!.toInt())}//还款else if (remoteMessage.data["type"] == "2") {intent = Intent(this, RepaymentDetailActivity::class.java)intent.putExtra("orderId", remoteMessage.data["orderId"]!!.toInt())} else {Log.w("-->", "nothing")intent = Intent(this, SplashActivity::class.java)intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)}} else {intent = Intent(this, SplashActivity::class.java)intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)}val pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,PendingIntent.FLAG_ONE_SHOT)val defaultSoundUri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)val notificationBuilder: NotificationCompat.Builder =NotificationCompat.Builder(this, PUSH_CHANNEL_ID).setSmallIcon(R.drawable.bc_app_logo).setContentTitle(remoteMessage.notification?.title ?: "").setContentText(messageBody).setAutoCancel(true).setSound(defaultSoundUri).setContentIntent(pendingIntent)mNotificationManager?.notify(mNotificationId, notificationBuilder.build())}/*** 判断是在前台还是后台*/private fun isRunBackground(context: Context): Boolean {val activityManager = context.applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManagerval packageName = context.applicationContext.packageNameval appProcesses = activityManager.runningAppProcesses ?: return truefor (appProcess in appProcesses) {if (appProcess.processName == packageName && appProcess.importance ==ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {return false}}return true}/*** 发送token到服务器*/private fun subToken(token: String) {OkGo.post<String>(Constant.URL_FIRE_BASE_TOKEN).headers(getHeaders(applicationContext)).params("token", token).execute(object : GsonCallBack<BaseResponse<Any>>() {override fun onSuccess(response: BaseResponse<Any>) {if (response.isSuccess()) {}}override fun onFail(response: Response<String>?, e: JsonParseException?) {}})}
}
**
4.token删除及重新获取,这个地方是我自己的理解
**
我在退出登录的时候调用了deleteToken
在MainActivity里面调用了getToken,这样可以保证,MyFirebaseMessagingService 里面的onNewToken,当重新登录时候获取到
详细是这样的:
MainActivity的onCreate里面:FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->if (!task.isSuccessful) {Log.e("TAG", "Fetching FCM registration token failed", task.exception)return@OnCompleteListener}// Get new FCM registration tokenval token = task.result// Log and toast})
退出的时候:
R.id.tv_mine_exit -> {SPUtils.getInstance().clear()SPUtils.getInstance().putBooleanValue(SPUtils.IS_FIRST_RUN, false)FirebaseMessaging.getInstance().deleteToken()//清空后再存储activity?.finish()//falseLoginActivity.start(activity as AppCompatActivity, false)}
**
5.踩坑,重要
**
firebase当app前台的时候并不会显示通知,划线:不显示通知,这个害我郁闷好几天,咋收不到消息哩,,,有个逻辑需要自己处理:
1.当app在后台时,firebase消息展示通知栏,点击默认进Splash,这个没问题
2.当app在前台显示时,firebase不展示通知,需要自己处理逻辑
**
6.权限
**
目前至少国内手机默认不会给通知权限,需要自己写代码引导用户操作
具体代码如下:
调用方式:(dialog自己整)
if (!isNotifyEnabled(applicationContext)) {StarDialog(this).setTitle("notice").setContent("开通知").setConfirmText("确定").setOnStarDialogClickListener(object : StarDialogClickListener {override fun onCancel() {}override fun onConfirm() {startSetting(this@MainActivity)}}).show()}
import android.app.AppOpsManager
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
import androidx.annotation.RequiresApi/*** @des 通知工具* @date 2022/3/8* @author sam*/private const val CHECK_OP_NO_THROW = "checkOpNoThrow"
private const val OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION"//调用该方法获取是否开启通知栏权限
fun isNotifyEnabled(context: Context): Boolean {return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {isEnableV26(context)} else {isEnabledV19(context)}
}/*** 8.0以下判断** @param context api19 4.4及以上判断* @return*/
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private fun isEnabledV19(context: Context): Boolean {val mAppOps = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManagerval appInfo = context.applicationInfoval pkg = context.applicationContext.packageNameval uid = appInfo.uidvar appOpsClass: Class<*>? = nulltry {appOpsClass = Class.forName(AppOpsManager::class.java.name)val checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW,Integer.TYPE, Integer.TYPE, String::class.java)val opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION)val value = opPostNotificationValue[Int::class.java] as Intreturn checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) as Int ==AppOpsManager.MODE_ALLOWED} catch (e: Exception) {e.printStackTrace()}return false
}/*** 8.0及以上通知权限判断** @param context* @return*/
private fun isEnableV26(context: Context): Boolean {val appInfo = context.applicationInfoval pkg = context.applicationContext.packageNameval uid = appInfo.uidreturn try {val notificationManager =context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManagerval sServiceField = notificationManager.javaClass.getDeclaredMethod("getService")sServiceField.isAccessible = trueval sService = sServiceField.invoke(notificationManager)val method = sService.javaClass.getDeclaredMethod("areNotificationsEnabledForPackage",String::class.java,Integer.TYPE)method.isAccessible = truemethod.invoke(sService, pkg, uid) as Boolean} catch (e: Exception) {true}
}fun startSetting(context: Context) {val localIntent = Intent()//直接跳转到应用通知设置的代码:if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { //8.0及以上localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)localIntent.action = "android.settings.APPLICATION_DETAILS_SETTINGS"localIntent.data = Uri.fromParts("package", context.packageName, null)} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //5.0以上到8.0以下localIntent.action = "android.settings.APP_NOTIFICATION_SETTINGS"localIntent.putExtra("app_package", context.packageName)localIntent.putExtra("app_uid", context.applicationInfo.uid)} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { //4.4localIntent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGSlocalIntent.addCategory(Intent.CATEGORY_DEFAULT)localIntent.data = Uri.parse("package:" + context.packageName)} else {//4.4以下没有从app跳转到应用通知设置页面的Action,可考虑跳转到应用详情页面,localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)if (Build.VERSION.SDK_INT >= 9) {localIntent.action = "android.settings.APPLICATION_DETAILS_SETTINGS"localIntent.data = Uri.fromParts("package", context.packageName, null)} else if (Build.VERSION.SDK_INT <= 8) {localIntent.action = Intent.ACTION_VIEWlocalIntent.setClassName("com.android.settings","com.android.setting.InstalledAppDetails")localIntent.putExtra("com.android.settings.ApplicationPkgName", context.packageName)}}context.startActivity(localIntent)
}
**
补充:
**
我这边推送的后端格式大概是这样的:这里的token是我传给后端的
String registrationToken = "d1OjZra6RSqJcIhsu7bpA9:APA91bHb2oety9CW3R5kYDQjOfkd3HiOhYiW5tdoQrw2jxgMIrw6wGvD9utHbypGWi1uIpy9qTxc55KlI5acZTtoOs6a_mYUapOiLGSoiB8";Message message = Message.builder().setNotification(Notification.builder().setTitle("xxxxx").setBody("xxxxxxxx").build())//携带数据.putData("type", "1").putData("orderId", "285").setToken(registrationToken).build();String response = FirebaseMessaging.getInstance().send(message);
不用谢……
android 集成 firebase 推送相关推荐
- Android集成极光推送踩坑(二)升级篇
转载请标明出处 http://blog.csdn.net/mohan6/article/details/74133186 本文作者:[默寒的博客] 前言 前段时间针对集成极光推送写了篇文章( Andr ...
- Android集成极光推送和踩过的坑(一)
转载请标明出处 http://blog.csdn.net/mohan6/article/details/72960346 本文作者:[默寒的博客] 集成步骤以及集成过程遇到的坑: 这部分主要阐述了集成 ...
- Android集成华为推送教程
前言 目前Android应用在后台杀死进程之后,就收不到通知了,想要接收消息推送,需要集成各个厂商的推送SDK,本次讲解华为集成最新教程 1.配置AppGallery Connect 1)注册成为开发 ...
- Android - 集成华为推送
Android ~ 集成华为推送 功能流程如下图所示: 开发流程 一.配置AppGallery Connect 1.注册成为开发者 注册 实名认证 2.创建应用 创建项目 在项目下添加应用 3.生成签 ...
- Android 集成小米推送功能教程
1.前言 现在好多手机都有APP推送功能,也有好多第三方的SDK,那为什么还要集成只有小米手机好使的"小米推送"呢?因为在小米手机中,小米推送是"系统级通道", ...
- Android集成华为推送功能详细
1.前言 Android集成推送功能也算是有好几个SDK了,包括极光.个推.小米.百度云推送.但是真心感觉华为的文档写的太差,封装的也不好,别的开发文档看一两遍就能按照文档集成成功,而华为仔细看了几遍 ...
- Android 集成小米推送
前言 在Android开发中,消息推送功能的使用非常常见. 为了降低开发成本,使用第三方推送是现今较为流行的解决方案. 今天,我将手把手教大家如何在你的应用里集成小米推送 该文档基于小米推送官方Dem ...
- Android 集成极光推送和厂商通道
JPush 产品简介 Push 是经过考验的大规模 App 推送平台,每天推送消息量级为数百亿条. 开发者集成 SDK 后,可以通过调用 API 推送消息.同时,JPush 提供可视化的 web 端控 ...
- Android集成极光推送
话不多说先上图: 集成步骤: 1.新建Android Studio项目,因为之后会用到包名 2.建项目后登录极光推送开发者平台创建自己的应用 https://www.jiguang.cn/dev2/# ...
- Android 集成华为推送,集成小米推送,集成OPPO推送,集成vivo推送
最近有时间在我们的应用中集成了华为,小米,OPPO,vivo四大平台的推送,一切顺利. 这里做一个记录, 开撸: 一.华为推送 1.下载HMS Agent套件,解压如下: 找到GetHMSAgent_ ...
最新文章
- 亿级流量治理系列:常用的限流算法有哪些?
- java exif_照片EXIF信息的读取和改写的JAVA实现
- 小程序学习(2):vs code 安装插件
- python中的可迭代对象
- python读取json文件多个json数据_Python 加载包含多个JSON对象的JSON文件
- 《Python游戏趣味编程》 第9章 贪吃蛇
- 关于计算机航天生物的想像作文,未来的航天员想象作文
- 精译丨美国2017年最值得投资的7大共同基金
- USB控制相关批处理
- python编程的50种基础算法_Python入门教程:几种常见的Python算法实现
- android 命令pm 全称 packagemanager,关于android:PackageManager安装应用笔记
- 在Android终端模拟器中操作adb调试命令
- 苹果手机测距离_苹果没说谎:iPhone和火星车都在用激光雷达
- MTK机器原始OTA更新方法
- freemarer代码生成案例
- Matlab 2017a 安装、破解步骤
- 【ios】Settings 设置项
- HTML5技术:促使浏览器替代原生态应用
- Jav环境下shell脚本的调用
- 从零开始学Circos绘制圈图(一)