前期项目一直用的是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 实现消息推动(付源码)的更多相关文章

  1. [Xamarin.Android] 結合Windows Azure與Google cloud message 來實現Push Notification (转帖)

    這一篇要討論如何使用Xamarin.Android 整合GCM以及Windows Azure來實作Android手機上的推播通知服務. 這篇文章比較著重概念的部分,在開始讀這篇之前,也可以先參考一下X ...

  2. [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 ...

  3. RocketMQ中PullConsumer的消息拉取源码分析

    在PullConsumer中,有关消息的拉取RocketMQ提供了很多API,但总的来说分为两种,同步消息拉取和异步消息拉取 同步消息拉取以同步方式拉取消息都是通过DefaultMQPullConsu ...

  4. 一步步实现windows版ijkplayer系列文章之七——终结篇(附源码)

    一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...

  5. 一步步实现windows版ijkplayer系列文章之二——Ijkplayer播放器源码分析之音视频输出——视频篇

    一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...

  6. 微服务架构 | *2.3 Spring Cloud 启动及加载配置文件源码分析(以 Nacos 为例)

    目录 前言 1. Spring Cloud 什么时候加载配置文件 2. 准备 Environment 配置环境 2.1 配置 Environment 环境 SpringApplication.prep ...

  7. windows azure Vm、cloud service、web application 如何选择可用的服务

    windows azure 的web应用和虚拟机都经常用.我们经常把我们的网站部署上去.一般选择web应用或者开一个虚拟机.开一个虚拟机就会按照虚拟机的使用时间进行计费. 那么我们选择web部署在哪里 ...

  8. C# Socket异步实现消息发送--附带源码

    前言 看了一百遍,不如动手写一遍. Socket这块使用不是特别熟悉,之前实现是公司有对应源码改改能用. 但是不理解实现的过程和步骤,然后最近有时间自己写个demo实现看看,熟悉熟悉Socket. 网 ...

  9. mfc 调用Windows的API函数实现同步异步串口通信(源码)

    在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信.串口通信方便易行,应用广泛. 一般情况下,工控机和各智能仪表通过RS485总线进行通信.RS485的通信方式是半 ...

随机推荐

  1. GC参考手册 —— GC 调优(基础篇)

    GC调优(Tuning Garbage Collection)和其他性能调优是同样的原理.初学者可能会被 200 多个 GC参数弄得一头雾水, 然后随便调整几个来试试结果,又或者修改几行代码来测试.其 ...

  2. 基于Jenkins Pipeline的ASP.NET Core持续集成实践

    最近在公司实践持续集成,使用到了Jenkins的Pipeline来提高团队基于ASP.NET Core API服务的集成与部署效率,因此这里总结一下. 一.关于持续集成与Jenkins Pipelin ...

  3. Linux创建普通用户

    声明:作者原创,转载注明出处. 作者:帅气陈吃苹果 1.创建用户,-m表示同时创建用户家目录 sudo useradd -m hadoop 2.为创建的hadoop用户设置密码 sudo passwd ...

  4. 【Java】广州三本秋招经历

    前言 只有光头才能变强 离上次发文章已经快两个月时间了,最近一直忙着秋招的事.今天是2018年10月22日,对于互联网行业来说,秋招就基本结束了.我这边的流程也走完了(不再笔试/面试了),所以来写写我 ...

  5. 《k8s-1.13版本源码分析》- Informer 机制

    源码分析系列文章已经开源到github,地址如下: github:https://github.com/farmer-hutao/k8s-source-code-analysis gitbook:ht ...

  6. Oracle 连接查询

    1.什么是连接查询?(B) 很多时候我们需要查询的数据并不是来源于同一张表,而是来源于多张表,而这种一个查询需要对多张表进行操作,就成为连接查询. 2.如何进行表的连接查询? 连接查询有两种方式:SQ ...

  7. Android 启动优化

    对与Android的项目来说,app的启动速度是非常重要的.因为用户打开你的app给别人的第一体验就是打开软件的速度.但是app的启动速度是比较难以缩短的,因为一般来说开发者在app的启动入口都会创建 ...

  8. Flutter 异常处理之图片篇

    背景 说到异常处理,你可能直接会认为不就是 try-catch 的事情,至于写一篇文章单独来说明吗? 如果你是这么想的,那么本篇说不定会给你惊喜哦~ 而且本篇聚焦在图片的异常处理. 场景 学以致用,有 ...

  9. android Fragment中使用Toolbar

    在Activity中可以直接使用 setSupportActionBar(toolbar); 就可以重写 onCreateOptionsMenu 和 onOptionsItemSelected 方法: ...

  10. brew 安装指定版本命令行工具 tmux 多版本实现

    Homebrew 是 macOS 命令安装工具,其核心库里的命令行在 github homebrew-core 仓库上维护. 核心库命令大概有 5000 条左右,大部分的命令行工具只保留了最新版本的 ...