道招

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

更新时间:
上一篇:window10的android studio一直卡在灰色的 loading devices,无法选择设备怎么解决下一篇:从PWA消息推送调试经历来看PWA现状,PWA凉了,凉透了吗?

相关文章

Twitter将发布app支持firefox系统

Twitter已经发表声明称,等到firefox os的手机投入市场后,其将发布firefox os版的twitter官方app。从官方得知,firefox os版的twitter将和其它版本的一样, 阅读更多…

我的生活充满腾讯QQ

很多人不喜欢QQ的山寨,但是不可质疑的是,它一直在山寨但是从未被超越。 我喜欢google的一切免费,但是我不喜欢它的那种喜欢把产品开发出来,但是长时间不改进,甚至放任不管(可能是我片面的想法)的做 阅读更多…

忘记Google APP(谷歌企业邮箱、日历等)账号密码解决方案

Google的APP的确不错,特别是他们的免费的企业邮局,及谷歌企业邮箱,非常的好用。 我每个域名差不多都已经申请了他们的企业邮局。但是往往企业邮局多了,又闲置了,不经常使用,长期的忘记密码,更 阅读更多…

貌似twitter的手机客户端要增加广告了

看上去twitter马上要在手机客户端里面植入广告了,提示用户装app的广告。Circa的创始人Matt Galligan曝出了一个含有app安装按钮的广告。 原文如下: twitter最近 阅读更多…

app开发者最想去的10所大学

计算机科学专业的人才很适合从事App开发,如果去一些顶级大学进修可以帮助你找到一份好工作、开发出世界上最热门的App。所以BI统计了2012年世界上最优秀的计算机科学大学。   10 普林斯顿大学 阅读更多…

中国工商银行开通微信银行

工行终于开通了微信银行,今天我登陆才知道滴,其实是7月28日开通滴。。。 在互联网方面,我不得不佩服招行,它是我知道最快的,它的微信银行功能也是最强的。以下是工行的微信银行的功能。不能绑定 阅读更多…

关注道招网公众帐号
联系博主