栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

android 集成 firebase 推送

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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传给自家的后端

        
            
                
            
        
        
        
        
        

**

3.MyFirebaseMessagingService:

**


class MyFirebaseMessagingService : FirebaseMessagingService() {
    private val PUSH_CHANNEL_ID = "ID"
    private val PUSH_CHANNEL_NAME = "peacock"
    private val mNotificationId = 1000
    private var mNotificationManager: NotificationManager? = null
    override fun onCreate() {
        super.onCreate()
        mNotificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        if (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: Intent
        if (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 , 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 ActivityManager
        val packageName = context.applicationContext.packageName

        val appProcesses = activityManager
            .runningAppProcesses ?: return true
        for (appProcess in appProcesses) {
            if (appProcess.processName == packageName && appProcess.importance ==
                ActivityManager.RunningAppProcessInfo.importANCE_FOREGROUND
            ) {
                return false
            }
        }
        return true
    }

    
    private fun subToken(token: String) {
        OkGo.post(Constant.URL_FIRE_base_TOKEN)
            .headers(getHeaders(applicationContext))
            .params("token", token)
            .execute(object : GsonCallBack>() {
                override fun onSuccess(response: baseResponse) {
                    if (response.isSuccess()) {

                    }
                }

                override fun onFail(response: Response?, 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 token
            val 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()
                //false
                LoginActivity.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("开通知").set/confirm/iText("确定")
                .setOnStarDialogClickListener(object : StarDialogClickListener {
                    override fun onCancel() {

                    }

                    override fun on/confirm/i() {
                        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



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)
    }
}


@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private fun isEnabledV19(context: Context): Boolean {
    val mAppOps = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
    val appInfo = context.applicationInfo
    val pkg = context.applicationContext.packageName
    val uid = appInfo.uid
    var appOpsClass: Class<*>? = null
    try {
        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 Int
        return checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) as Int ==
                AppOpsManager.MODE_ALLOWED
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return false
}



private fun isEnableV26(context: Context): Boolean {
    val appInfo = context.applicationInfo
    val pkg = context.applicationContext.packageName
    val uid = appInfo.uid
    return try {
        val notificationManager =
            context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val sServiceField = notificationManager.javaClass.getDeclaredMethod("getService")
        sServiceField.isAccessible = true
        val sService = sServiceField.invoke(notificationManager)
        val method = sService.javaClass.getDeclaredMethod(
            "areNotificationsEnabledForPackage",
            String::class.java,
            Integer.TYPE
        )
        method.isAccessible = true
        method.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.4
        localIntent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
        localIntent.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_VIEW
            localIntent.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);

不用谢……

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/759225.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号