GCM Google官方示例的简单介绍和使用

准备工作

翻墙

  先翻墙,翻不了墙一切都白搭……

Google账号

  • 申请Google账号
  • 进入Google开发管理台
  • 创建工程(Google管理台上的Project)
  • 开启Google Cloud Messaging API。

Demo工程

  参考google官方指导文档,在google中搜索GCM,或者直接点击此处打开。本文均以Android为例,打开页面后,点击左上方的”TRY IT ON ANDROID”按钮,进入针对安卓的指导页。以下步骤官方指导写的比较详细的,本文就不赘述,一笔带过,有需要注意的会补充。

  1. 下载Android示例工程
      下载下来是个压缩包,GCM的工程目录为google-services-master/android/gcm,简单介绍下各个类的作用:

    • MyGcmListenerService.java
      GCM接收监听服务类,接收GCM发过来的通知消息,并显示到手机状态栏中。
      对应的AndroidManifest.xml配置如下:

      <!-- [START gcm_receiver] -->
      <receiver
        android:name="com.google.android.gms.gcm.GcmReceiver"android:exported="true"android:permission="com.google.android.c2dm.permission.SEND"><intent-filter><action android:name="com.google.android.c2dm.intent.RECEIVE"/><category android:name="gcm.play.android.samples.com.gcmquickstart"/></intent-filter>
      </receiver>
      <!-- [END gcm_receiver] -->
      <!-- [START gcm_listener] -->
      <service
        android:name=".MyGcmListenerService"android:exported="false"><intent-filter><action android:name="com.google.android.c2dm.intent.RECEIVE"/></intent-filter>
      </service>
      <!-- [END gcm_listener] -->

    GcmReceiver接收,然后发送给GcmListenerService,我们在GcmListenerServcie的实现类中处理收到的gcm消息。Google官方对GcmReceiver的解释(原文链接):

    WakefulBroadcastReceiver that receives GCM messages and delivers them to an application-specific GcmListenerService subclass.

    如何将通知消息展示到状态栏:

    Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_stat_ic_notification).setContentTitle("GCM Message").setContentText(message + count).setAutoCancel(true).setSound(defaultSoundUri).setContentIntent(pendingIntent);NotificationManager notificationManager =(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);int notificationId = Integer.parseInt(("" + System.currentTimeMillis()).substring(10));
    notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    • RegistrationIntentService.java
      向GCM服务器进行设备注册,获取注册token,该token会作为通知消息接收设备的标识,该类中还进行了topics的订购。
    • MyInstanceIDListenerService.java
      接收token更新通知,收到通知后会重新通过RegistrationIntentService获取新的token。
    • GcmSender.java
      推送消息发送类,通过该类向GCM发送HTTP消息,GCM再推送给终端设备。该类并不是必需的,下文也提到了,可以通过Postman等工具直接发送HTTP消息。
  2. 下载配置文件。
      下载过程中会给出API Key和Sender ID。(没记住也没关系,管理台上也可以查到,分别对应API Key和Project number)

  3. 将配置文件放入工程

    注意,工程下载好后,里面默认代码使用的API Key以及Sender ID需要修改。

    API Key: GcmSender.java(模拟服务器向Google发送推送消息使用,后面可以不用main函数,直接用浏览器插件发消息的方式,更方便点。)

    Sender ID:RegistrationIntentService.java(代码默认使用的是”R.string.gcm_defaultSenderId”)。

  4. 安装并运行示例App
      工程打开时会向Google注册,并获取注册Token,logcat日志中会打出来。后面发送消息时以获取到的token作为客户端设备标识。

02-23 10:39:18.709 19735-19763/gcm.play.android.samples.com.gcmquickstart I/RegIntentService: GCM Registration Token:dnbhEeyYCWg:APA91bH_yYRmgPsuzpC7qMKp86JV3jR5d...Iw6VvPHilRa2d9u7sW4Xs6El2S1nsqtGM4yO2vVjHv-nSs_DkF3-sdn3b...7mxrbdsyl5xb53

发送通知消息

  下载下来的工程中GcmSender.java这个类就是专门发消息的,Google的指导中有给出调用其Main函数的命令,本文推荐直接通过浏览器插件或工具发送(反正就是个HTTPS的消息,用什么发都一样,对吧)。
  推荐”Postman”,通过Chrome网上应用店安装,有独立的应用版本。

消息内容如下:
其中消息头中的key为API Key(Google管理台上可以查),token为上文第四步中提到的注册token。

  • 消息1:发给某一个topic,to为topic的名称(可以实现群发)。
    参考链接:https://developers.google.com/cloud-messaging/topic-messaging
https://gcm-http.googleapis.com/gcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{"to": "/topics/foo-bar","data": {"message": "This is a GCM Topic Message!",}
}
  • 消息2:指定发送给一个设备,to即上文提到的注册token。
https://gcm-http.googleapis.com/gcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{"to": "token","data": {"message": "This is a GCM token Message!",}
}
  • 消息3:发送给多个设备,token1、token2即上文提到的注册token。
https://gcm-http.googleapis.com/gcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{"registration_ids": ["token1","token2"],"data": {"message": "This is a GCM token Message!",}
}

可能遇到的问题

  1. Gradle编译不过,提示无法下载play-services-gcm:8.4.0。
    可能jcenter还没有收录这个版本(也可能是网络问题),尝试使用早一点的版本,例如build.gradle文件中改为8.3.0就好了。顺便提醒下别忘了在SDK Manager中,安装Extras下面的Google Play services,这个组件默认是不安装的。

  2. 使用命令行调用main函数的方式发送消息,连接超时或失败。
    没用到proxy,使用postman等工具发送。

  3. app运行过程中,日志打印Notification.xxx方法找不到。
    升级android sdk到最新版本,官网下载的代码依赖的sdk是比较新的。

  4. 发给topics的消息终端无法收到
    Google给的消息示例中to的值为/topics/foo-bar,实际测试时发现是收不到这个推送消息的,查看RegistrationIntentService.java代码发现针对topics的消息,需要在获取到token后,订购相应的topics(默认只订购了/topics/global,所以发向/topics/foo-bar的收不到)。
    相关代码:

/*** Subscribe to any GCM topics of interest, as defined by the TOPICS constant.** @param token GCM token* @throws IOException if unable to reach the GCM PubSub service*/
// [START subscribe_topics]
private void subscribeTopics(String token) throws IOException {GcmPubSub pubSub = GcmPubSub.getInstance(this);for (String topic : TOPICS) {pubSub.subscribe(token, "/topics/" + topic, null);}
}
// [END subscribe_topics]

几个常用参数

1. 在收到多条推送消息时,状态栏如何控制弹多条还是保持一条。

MyGcmListenerService.java中,弹出状态栏消息时会设置一个notification ID,不同ID会弹出不同的通知,同一个ID会一直刷新同一个通知。
设置固定的ID就可以做到”收到xx条新消息”这种提示啦。

notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());

2. App最小化或Activity销毁后,点击状态栏通知要打开指定的Activity

MyGcmListenerService.java中,”PendingIntent.FLAG_ONE_SHOT”改为”PendingIntent.FLAG_UPDATE_CURRENT”(或者”0”?)即可,具体每个flag的含义参考其注释。

Intent intent = new Intent(this, Main2Activity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT);
/*** Flag indicating that this PendingIntent can be used only once.* For use with {@link #getActivity}, {@link #getBroadcast}, and* {@link #getService}. <p>If set, after* {@link #send()} is called on it, it will be automatically* canceled for you and any future attempt to send through it will fail.*/
public static final int FLAG_ONE_SHOT = 1<<30;
/*** Flag indicating that if the described PendingIntent does not* already exist, then simply return null instead of creating it.* For use with {@link #getActivity}, {@link #getBroadcast}, and* {@link #getService}.*/
public static final int FLAG_NO_CREATE = 1<<29;
/*** Flag indicating that if the described PendingIntent already exists,* the current one should be canceled before generating a new one.* For use with {@link #getActivity}, {@link #getBroadcast}, and* {@link #getService}. <p>You can use* this to retrieve a new PendingIntent when you are only changing the* extra data in the Intent; by canceling the previous pending intent,* this ensures that only entities given the new data will be able to* launch it.  If this assurance is not an issue, consider* {@link #FLAG_UPDATE_CURRENT}.*/
public static final int FLAG_CANCEL_CURRENT = 1<<28;
/*** Flag indicating that if the described PendingIntent already exists,* then keep it but replace its extra data with what is in this new* Intent. For use with {@link #getActivity}, {@link #getBroadcast}, and* {@link #getService}. <p>This can be used if you are creating intents where only the* extras change, and don't care that any entities that received your* previous PendingIntent will be able to launch it with your new* extras even if they are not explicitly given to it.*/
public static final int FLAG_UPDATE_CURRENT = 1<<27;/*** Flag indicating that the created PendingIntent should be immutable.* This means that the additional intent argument passed to the send* methods to fill in unpopulated properties of this intent will be* ignored.*/
public static final int FLAG_IMMUTABLE = 1<<26;

GCM Google官方示例的简单介绍和使用相关推荐

  1. Android鬼点子-通过Google官方示例学NDK(4)

    如果你看遍了网上那些只是在C++里面输出一个 ' helloWorld ' 的NDK教程的话,可以看看本系列的文章,本系列是通过NDK的运用的例子来学习NDK. 如果对这方面感兴趣,可以看看前三篇. ...

  2. google官方mvp+dagger2架构详解

    原文链接:http://www.jianshu.com/p/01d3c014b0b1 1 前言 前段时间分享了一篇文章:google官方架构MVP解析与实战 ,针对这是对google官方示例架构的一个 ...

  3. ngRx 官方示例分析 - 2. Action 管理

    我们从 Action 名称开始. 解决 Action 名称冲突问题 在 ngRx 中,不同的 Action 需要一个 Action Type 进行区分,一般来说,这个 Action Type 是一个字 ...

  4. Java定时任务调度实战(2)Quart框架的简单介绍

    一.前言 在之前的文章<Java定时任务调度(1)TimerTask原理与实战>中已经介绍了一种实现定时任务调度的方法--Java原生提供的 TimerTask,这个工具适用于一些简单的业 ...

  5. 【Android 应用开发】Google 官方 EasyPermissions 权限申请库 ( 最简单用法 | 一行代码搞定权限申请 | 推荐用法 )

    文章目录 一.添加依赖 二.在 AndroidManifest.xml 中配置权限 三.权限申请最简单用法 四.推荐使用的用法 五.GitHub 地址 上一篇博客 [Android 应用开发]Goog ...

  6. Google FireBase的简单介绍

    Google FireBase的简单介绍和使用 一.FireBase是啥东东,可以吃嘛? FireBase官网(需要科学上网) 用官网简介的话来说就是:构建更出色应用和成功地扩大业务所需的工具和基础架 ...

  7. 【Android 内存优化】Bitmap 硬盘缓存 ( Google 官方 Bitmap 示例 | DiskLruCache 开源库 | 代码示例 )

    文章目录 一.Google 官方 Bitmap 相关示例参考 二.磁盘缓存类 DiskLruCache 三.磁盘缓存初始化 四.存储数据到磁盘缓存中 五.从磁盘缓存中读取数据 六. Android 1 ...

  8. python中pickle模块的用法_Python中json模块和pickle模块的简单介绍(附示例)

    本篇文章给大家带来的内容是关于Python中json模块和pickle模块的简单介绍(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. Python中的json模块和pickl ...

  9. php有lambda表达式吗,Python中lambda表达式的简单介绍(附示例)

    本篇文章给大家带来的内容是关于Python中lambda表达式的简单介绍(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 一:匿名函数的定义 lambda parameter ...

最新文章

  1. kali2020安装中文输入法(切换中文输入法)
  2. 史上最强 NIO 框架,没有之一!!!
  3. 宝塔显示linux inode,Linux显示inode的信息
  4. 脑细胞膜等效神经网路简单分类实例
  5. python核心编程第三版_Python之父:自学python,这3本书能节约你一大半时间编程...
  6. linux多线程时序问题,Linux时序竞态问题(sleep函数的实现)
  7. android谷歌打印插件下载地址,ARC Welder(App Runtime for Chrome)插件下载 附下载地址
  8. 牛客网Java刷题知识点之表达式类型的自动提升
  9. [转]Java杂谈(七)--接口amp; 组件、容器
  10. pygame游戏开发-简介
  11. 从“制造”到“智造”,南高齿携手锐捷打造“智能工厂”
  12. 关于hibernate的缓存使用
  13. 软件工程师成长为架构师必备的十项技能
  14. 全网最详细的Android11.0长按power键关机流程分析
  15. Cheat Enginee(CE)的详细使用指南~包含下载安装教程以及核心功能讲解
  16. 猜数字游戏 由计算机,猜数字游戏玩法
  17. 荣耀笔记本开机黑屏错误怎么U盘重装系统教学分享
  18. 社保随便挂靠,会判刑罚款您知道吗?
  19. 大陆中文网站流量排名前100
  20. 一些特殊字符的英文读法(ASCII 码, 希腊字母、符号)

热门文章

  1. kruskal java_Kruskal算法java版
  2. deep learning for the earth sciences 读书笔记
  3. python中if语句and和or用法_Python从入门到精通——一文读懂if语句用法
  4. 跳出任务管理的泥沼,拥抱甘特图的怀抱
  5. 数据库读写分离的理解
  6. AUC的计算方法及相关总结
  7. 宽带连接错误的处理办法651、691、623、678、645、720、721、718、734、769
  8. 一台计算机的完全限定域名,什么是完全限定域名?
  9. 计算机中英文打字文章,中英文混合文章
  10. 2022速看靓号邮箱购买大全 邮箱购买注意事项有哪些 怎么注册