Windows Azure NotificationHub+Firebase Cloud Message 实现消息推动(付源码)
前期项目一直用的是Windows azure NotificationHub+Google Cloud Message 实现消息推送, 但是GCM google已经不再推荐使用,慢慢就不再维护了, 现在Google 主推 FCM, 另一方面,google在android生态中的权限要求越来越严格,不像以前那样将权限声明在AndroidManifest中,在安装的时候做一次提醒就好了, 现在对于一些主要的权限需要动态申请并且用户同意才能使用,比如调用相机,使用电话本等等,同样对于后台的常驻服务也做了一定的限制,旨在提升android系统的用户体验以及提高电池的续航时间,在2018-11-1强制执行编译的Target SDK API Leve必须是26+,否则是不允许上Goolge Play , GCM也只支持到2019-11-1,之后就不再支持,项目老的推送服务要依赖于后台常驻Service。 基于以上原因我对当前的android项目做了一次全面升级。这里分享一下GCM到FCM的迁移过程。
我们的项目用的微软的Azure平台,自然所有的一切技术都围绕着Windows Azure 平台展开。 Web App, Web API 使用的是Azure Cloud Service, Mobile APP 使用的是Xamarin, 数据库使用的是Azure SQL Database, 是不是很微软系。
自然在消息推送的时候想到的还是Azure平台上的技术 Notification Hub。
名词解释:
GCM: Google Cloud Message.
FCM: Firebase Cloud Message.
迁移步骤
1. 创建一个Firebase 项目并且开启Firebase Cloud Messaging功能。
2. 在Azure上创建一个NotificationHub。
3.将Firebase和ConnectionHub关联上。
4.创建一个Xiamarin android APP 并关联上 NotificationHub和 Firebase Cloud Message。
5. 测试消息发送。
注意:由于需要连接到Firebase Cloud Message 牵涉到墙的问题,需要手机能够翻墙, 否则测试将不能成功,另外,在做FCM的设置也是寸步难行。
准备工作
1. 需要一个google账号,用于创建Firebase 项目并开启 Firebase Cloud Message。
2.需要一个azure账号,用于创建NotificationHub。
3.Visual Studio并且要安装Xamarin 插件。
4. 准备一个VPN 用于测试。
创建一个Firebase 项目并且开启Firebase Cloud Messaging功能
打开 Firebase 开发控制台https://console.firebase.google.com/添加一个项目 如图:
这里我创建一个项目叫:XamarinAndroidFCM。创建好后像下面这样:
这一步暂时就创建到这里,我们需要一个android app的Package 名称, 下面我们将创建一个android项目创建好以后再回来设置这个包的名称。
在Azure上创建一个NotificationHub
登录到Azure 在云端在左边的菜单中找到NotificationHub项, 点击想创建一个Notification Hub Namespaces, 然后进入NameSpace并且创建一个NotificaitonHub。
然后点击创建的NotificaitonHub名字进入设置界面,并且点击中间的菜单GCM(google),设置这个API key
这个key 来自上一步创建的Firebase 项目:
这样FCM 和Notifaction Hub就关联好了。
创建一个Xiamarin android APP 并关联上 NotificationHub和 Firebase Cloud Message
打开VS 创建一个xiamarin for Android的项目。创建好后如下:
打开项目将的配置文件:AndroidManifest.xml, 将里面的包名改成小写(这里很重要,如果不改成小写,你将不会收到任何消息,这是个坑,做GCM的时候也是一样, 测试了很多次才找出来这个原因)
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1"
android:versionName="1.0" package="xamarinandroidfcm.xamarinandroidfcm">
这里我们将这个包名“xamarinandroidfcm.xamarinandroidfcm” 填到第一步FCM中去 并保存。
保存完成后点击右边的google-service.json 文件下载到本地并加入到创建的android项目中
这样FCM的相关设置就完了。
在android的项目中做FCM 以及Azure NotificationHub的连接并接收消息
1. 添加相关的依赖包: Xamarin.Firebase.Messaging 和 Xamarin.Azure.NotificationHubs.Android
2. 设置google-service.json 的build action 为“GoogleServicesJson”(如果找不到这一项,重启一下VS重新设置就可以找到了)
3. 在AndroidManifest.xmal 的Application节点中加入以下配置:
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
如下:
4. 配置Notification Hub 账号到代码中。
在项目中创建一个Class 叫:Constants, 并创建两个常量用于保存NotificaiotnHub的连接字符串和名称。打开azrue中创建的Hub 点击左边的Access Policy,看到如下界面:
将DefaultListenSharedAccessSignature的Connection String值拷贝到刚刚创建的那个常量 ListenConnectionString 中。并把Notificaiton Hub的名字保存在
NotificationHubName中。
5.创建MyFirebaseIidService 服务类用于接收和刷新Firebase的token, 并将token以及tag注册到Notificationhub.
using System.Collections.Generic;
using Android.App;
using Android.Util;
using WindowsAzure.Messaging;
using Firebase.Iid; namespace XamarinAndroidFCM
{
[Service]
[IntentFilter(new[] {"com.google.firebase.INSTANCE_ID_EVENT"})]
public class MyFirebaseIidService : FirebaseInstanceIdService
{
private const string Tag = "MyFirebaseIIDService";
NotificationHub _hub; public override void OnTokenRefresh()
{
var refreshedToken = FirebaseInstanceId.Instance.Token;
Log.Debug(Tag, "FCM token: " + refreshedToken);
SendRegistrationToServer(refreshedToken);
} void SendRegistrationToServer(string token)
{
// Register with Notification Hubs
_hub = new NotificationHub(Constants.NotificationHubName,Constants.ListenConnectionString, this); var tags = new List<string>() { "" };
var regID = _hub.Register(token, tags.ToArray()).RegistrationId;
Log.Debug(Tag, $"Successful registration of ID {regID}");
}
}
}
6. 创建接收消息的服务:MyFirebaseMessagingService 用于接收消息并显示给用户:
using System;
using System.Linq;
using Android.App;
using Android.Content;
using Android.Util;
using Android.Widget;
using Firebase.Messaging; namespace XamarinAndroidFCM
{
[Service]
[IntentFilter(new[] {"com.google.firebase.MESSAGING_EVENT"})]
public class MyFirebaseMessagingService : FirebaseMessagingService
{
private const string Tag = "MyFirebaseMsgService";
public override void OnMessageReceived(RemoteMessage message)
{
Log.Debug(Tag, "From: " + message.From);
if (message.GetNotification() != null)
{
//These is how most messages will be received
Log.Debug(Tag, "Notification Message Body: " + message.GetNotification().Body);
SendNotification(message.GetNotification().Body);
}
else
{
//Only used for debugging payloads sent from the Azure portal
CreateNotification("Test FCM", message.Data.Values.First(), "15:30");
}
} void SendNotification(string messageBody)
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot); var notificationBuilder = new Notification.Builder(this)
.SetContentTitle("FCM Message")
.SetSmallIcon(Resource.Drawable.ic_launcher)
.SetContentText(messageBody)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent); var notificationManager = NotificationManager.FromContext(this);
notificationManager.Notify(0, notificationBuilder.Build());
} void CreateNotification(string title, string desc, string time)
{
var notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;
var uiIntent = new Intent(this, typeof(MainActivity));
var notification = new Notification(Resource.Mipmap.ic_launcher, title);
notification.Flags = NotificationFlags.AutoCancel;
notification.Defaults = NotificationDefaults.All;
notification.Vibrate = new long[] { 0, 100, 200, 300 };
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.JellyBean)
{
var contentView = new RemoteViews(PackageName, Resource.Layout.Custom_Notification);
contentView.SetTextViewText(Resource.Id.txtTitle, title);
contentView.SetTextViewText(Resource.Id.txtTime, time);
contentView.SetTextViewText(Resource.Id.txtContent, desc);
notification.BigContentView = contentView;
}
notification.SetLatestEventInfo(this, title, desc, PendingIntent.GetActivity(this, 0, uiIntent, PendingIntentFlags.UpdateCurrent)); var rnd = new Random();
var notificationId = rnd.Next(10000, 99999); notificationManager.Notify(notificationId, notification);
}
}
}
代码部分全部实现完成。
测试
打开模拟器或手机,设置代理, 调试应用, 并且再次打开Azure Notifiaciton Hub 进入到测试界面进行测试:
手机端接收到的消息如下:
总结,Notificaiton Hub + FCM发送消息比较简单,但是也有许多坑,设置比较多,比如应用包的大小写问题,翻墙的问题都是一些小的阻碍,但是这个消息推送还是比较稳定的, 适合一些国外的项目。 如果做国内的项目可以考虑Notification Hub+ 百度message来做消息推送,当然也可以用一些第三方的SDK来做。
源码下载地址: https://github.com/Xushlin/PushNotificaiton
Windows Azure NotificationHub+Firebase Cloud Message 实现消息推动(付源码)的更多相关文章
- [Xamarin.Android] 結合Windows Azure與Google cloud message 來實現Push Notification (转帖)
這一篇要討論如何使用Xamarin.Android 整合GCM以及Windows Azure來實作Android手機上的推播通知服務. 這篇文章比較著重概念的部分,在開始讀這篇之前,也可以先參考一下X ...
- [Windows Azure] Windows Azure Web Sites, Cloud Services, and VMs: When to use which?
This document provides guidance on how to make an informed decision in choosing between Windows Azur ...
- RocketMQ中PullConsumer的消息拉取源码分析
在PullConsumer中,有关消息的拉取RocketMQ提供了很多API,但总的来说分为两种,同步消息拉取和异步消息拉取 同步消息拉取以同步方式拉取消息都是通过DefaultMQPullConsu ...
- 一步步实现windows版ijkplayer系列文章之七——终结篇(附源码)
一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...
- 一步步实现windows版ijkplayer系列文章之二——Ijkplayer播放器源码分析之音视频输出——视频篇
一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...
- 微服务架构 | *2.3 Spring Cloud 启动及加载配置文件源码分析(以 Nacos 为例)
目录 前言 1. Spring Cloud 什么时候加载配置文件 2. 准备 Environment 配置环境 2.1 配置 Environment 环境 SpringApplication.prep ...
- windows azure Vm、cloud service、web application 如何选择可用的服务
windows azure 的web应用和虚拟机都经常用.我们经常把我们的网站部署上去.一般选择web应用或者开一个虚拟机.开一个虚拟机就会按照虚拟机的使用时间进行计费. 那么我们选择web部署在哪里 ...
- C# Socket异步实现消息发送--附带源码
前言 看了一百遍,不如动手写一遍. Socket这块使用不是特别熟悉,之前实现是公司有对应源码改改能用. 但是不理解实现的过程和步骤,然后最近有时间自己写个demo实现看看,熟悉熟悉Socket. 网 ...
- mfc 调用Windows的API函数实现同步异步串口通信(源码)
在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信.串口通信方便易行,应用广泛. 一般情况下,工控机和各智能仪表通过RS485总线进行通信.RS485的通信方式是半 ...
随机推荐
- GC参考手册 —— GC 调优(基础篇)
GC调优(Tuning Garbage Collection)和其他性能调优是同样的原理.初学者可能会被 200 多个 GC参数弄得一头雾水, 然后随便调整几个来试试结果,又或者修改几行代码来测试.其 ...
- 基于Jenkins Pipeline的ASP.NET Core持续集成实践
最近在公司实践持续集成,使用到了Jenkins的Pipeline来提高团队基于ASP.NET Core API服务的集成与部署效率,因此这里总结一下. 一.关于持续集成与Jenkins Pipelin ...
- Linux创建普通用户
声明:作者原创,转载注明出处. 作者:帅气陈吃苹果 1.创建用户,-m表示同时创建用户家目录 sudo useradd -m hadoop 2.为创建的hadoop用户设置密码 sudo passwd ...
- 【Java】广州三本秋招经历
前言 只有光头才能变强 离上次发文章已经快两个月时间了,最近一直忙着秋招的事.今天是2018年10月22日,对于互联网行业来说,秋招就基本结束了.我这边的流程也走完了(不再笔试/面试了),所以来写写我 ...
- 《k8s-1.13版本源码分析》- Informer 机制
源码分析系列文章已经开源到github,地址如下: github:https://github.com/farmer-hutao/k8s-source-code-analysis gitbook:ht ...
- Oracle 连接查询
1.什么是连接查询?(B) 很多时候我们需要查询的数据并不是来源于同一张表,而是来源于多张表,而这种一个查询需要对多张表进行操作,就成为连接查询. 2.如何进行表的连接查询? 连接查询有两种方式:SQ ...
- Android 启动优化
对与Android的项目来说,app的启动速度是非常重要的.因为用户打开你的app给别人的第一体验就是打开软件的速度.但是app的启动速度是比较难以缩短的,因为一般来说开发者在app的启动入口都会创建 ...
- Flutter 异常处理之图片篇
背景 说到异常处理,你可能直接会认为不就是 try-catch 的事情,至于写一篇文章单独来说明吗? 如果你是这么想的,那么本篇说不定会给你惊喜哦~ 而且本篇聚焦在图片的异常处理. 场景 学以致用,有 ...
- android Fragment中使用Toolbar
在Activity中可以直接使用 setSupportActionBar(toolbar); 就可以重写 onCreateOptionsMenu 和 onOptionsItemSelected 方法: ...
- brew 安装指定版本命令行工具 tmux 多版本实现
Homebrew 是 macOS 命令安装工具,其核心库里的命令行在 github homebrew-core 仓库上维护. 核心库命令大概有 5000 条左右,大部分的命令行工具只保留了最新版本的 ...