3

Android摸索记录--HMS消息推送

 2 years ago
source link: https://www.daozhao.com/10423.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Android摸索记录--HMS消息推送

如果您发现本文排版有问题,可以先点击下面的链接切换至老版进行查看!!!

Android摸索记录--HMS消息推送

我一直都对消息提醒内容类功能有点执念的,因为我希望自己能有各种眼线,能去四面八方获取我关注的内容,同时那些内容更新了能够及时通知给我,因此我比较喜欢捣鼓爬虫、消息提醒、消息推送、闹钟、日历之类的东西。

自己作为一个前端,尝试过几个前端的方式来实现消息推送的功能。

尝试一:PWA

PWA是service-worker的,可以用来push消息的,这个需要借助于浏览器,现在主流的是chrome,但是走谷歌的推送的话,如果手机没有科学上网就收不到消息。用firfox安装PWA的话效果还好一点,至少没有被墙。

鉴于感觉目前PWA已经不温不火了,之前的Instagram都在PWA推送用户使用app了,再加上如果浏览器进程被杀掉的话,消息推送应该也会受到影响,所以在很早的时候给道招网加入了PWA功能后简单用过一段时间后就没有继续深入尝试这个方案了。

尝试二:微信小程序

自己接入微信的access_token以及模板消息后也使用过一段时间,但是微信的很多高级api都需要企业认证的账号才能使用,再加上微信的进程也可能被手机系统给杀掉,当然劝退我的还是企业认证这个门槛。

尝试三:APP

为什么不搞个app呢,自己不是很喜欢app的吗?自己开始喜欢搞编程是为了什么,不就是因为看到了Android,充满了好奇吗?

说干就干,就走这条对前端来说更难的路,demo走起,先接入华为推送,作为原荣耀系的手机用户,接入华为推送这个系统级的功能,不用太担心进程被杀的问题。

接入HMS

项目级别build.gradle(只列举了HMS相关内容)

buildscript {
    ext.kotlin_version = '1.4.10'
    repositories {
        maven { url 'https://developer.huawei.com/repo/' }
    }
    dependencies {
        classpath 'com.huawei.agconnect:agcp:1.6.0.300'

    }
}

allprojects {
    repositories {
        google()
        maven { url 'https://developer.huawei.com/repo/' }
    }
}

app级别build.gradle(只列举了HMS相关内容)

plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'com.huawei.agconnect'
}

dependencies {
    // HMS Push kit
    implementation 'com.huawei.hms:push:6.3.0.302'
}

我是在fragment的编码的

import com.huawei.hms.aaid.HmsInstanceId
import com.huawei.hms.common.ApiException
import com.huawei.hms.push.HmsMessaging
import com.huawei.hms.push.HmsProfile

class DashboardFragment : Fragment(), View.OnClickListener {
    companion object {
        private const val TAG: String = "DashboardFragment"
        private const val GET_AAID = 1
        private const val DELETE_AAID = 2
        private const val CODELABS_ACTION: String = "com.daozhao.push.action"
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        dashboardViewModel =
            ViewModelProvider(this).get(DashboardViewModel::class.java)

        _binding = FragmentDashboardBinding.inflate(inflater, container, false)

        root = binding.root

        FirebaseApp.initializeApp(requireContext()!!)

        return root
    }

     fun showLog(log: String?) {
        activity?.runOnUiThread {
            val textView = root!!.findViewById<TextView?>(R.id.text_dashboard)
            textView.text = log
        }
    }

    private fun getToken() {
        showLog("getToken:begin")
        object : Thread() {
            override fun run() {
                try {
                    // read from agconnect-services.json
                    val appId = "xxx"

                    val token = HmsInstanceId.getInstance(mContext).getToken(appId, "HCM")
                    storeTokenProfile(token)
                } catch (e: ApiException) {
                    Log.e(TAG, "get token failed, $e")
                    showLog("get token failed, $e")
                }
            }
        }.start()
    }

    private fun storeTokenProfile(token: String?) {
        Log.i(TAG, "get token:$token")
        showLog("get token:$token")
        if (!TextUtils.isEmpty(token)) {
            // 将token存储在自己的服务器,方便后期推送
            sendRegTokenToServer(token);
            // 添加当前设备上的用户与应用的关系。
            val hmsProfileInstance: HmsProfile = HmsProfile.getInstance(mContext);
            if (hmsProfileInstance.isSupportProfile) {
                hmsProfileInstance.addProfile(HmsProfile.CUSTOM_PROFILE, "9105385871708200535")
                    .addOnCompleteListener { task ->
                        // 获取结果
                        if (task.isSuccessful){
                            Log.i(TAG, "add profile success.")
                        } else{
                            Log.e(TAG, "add profile failed: " + task.exception.message)
                        }
                    }
            }
        }
    }

    private fun sendRegTokenToServer(token: String?) {
        Log.i(TAG, "sending token to server. token:$token")
        // 借助Firebase获取一个唯一的id作为设备标识
        FirebaseInstallations.getInstance().id.addOnCompleteListener { it ->
            run {
                if (it.isComplete) {
                    var uuid = it.result.toString();
                    showLog("uuid complete " + uuid);

                    var formBody: FormBody.Builder = FormBody.Builder();
                    formBody.add("id", uuid);
                    formBody.add("pushToken",token);
                    val request: Request = Request.Builder()
                        .url("https://example.com/HMS/storePushToken")
                        .post(formBody.build())
                        .build()
                    val call: Call = client.newCall(request)
                    call.enqueue(object : Callback {
                        override fun onFailure(call: Call?, e: IOException?) {
                            showLog("fetch failed " + uuid)
                            Log.e(TAG, "fetch failed " + uuid);
                        }

                        @Throws(IOException::class)
                        override fun onResponse(call: Call?, response: Response) {
                            val result: String = response.body().string()
                            showLog("fetch success " + uuid)
                            Log.i(TAG, "fetch success " + uuid);
                        }
                    })
                }
            }
        }
    }
}

后面我们就可根据这个token进行推送消息了,消息可以分成通知消息和透传消息,服务端的发送消息的消息体如下 通知栏消息体示例:

{
    "validate_only": false,
    "message": {
        "android": {
            "notification": {
                "title": "test title",
                "body": "test body",
                "click_action": {
                    "type": 3
                }
            }
        },
        "token": ["pushtoken1"]
    }
}

透传消息体示例:

{
    "validate_only": false,
    "message": {
        "data": "{'param1':'value1','param2':'value2'}",
        "token": ["pushtoken1"]
    }
}

更多细节参考官网文档发送下行消息

文档中的pushToken就是在getToken中获取的内容,这样我们就发送消息至手机客户端了。

如果来不及开发自己的服务端,可以先用官网给的工具来发送调试消息

file

file

file


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK