Google Cloud Messaging not working on 4.1.2 device

2020-01-29 09:24发布

问题:

I've implemented a simple GCM client and server. The client uses the current GCM client APIs (not the deprecated helper library). The server (C# & .NET) follows the corresponding server guidelines (using HTTP). My server runs on a machine within my company domain, so I'm connecting the client devices to a Wi-Fi access point inside the corporate network but with access to the Internet.

My problem in a nutshell is that notifications are received fine on 4.3+ handsets, but are never received on 4.1.2 handsets when connected to the corporate Wi-Fi network. If I connect a 4.1.2 device to our public guest Wi-Fi network the GCM messages are received as expected, but then the app can't connect to the corporate server.

I've seen some indications that GCM can fail when corporate networks have overly protective firewalls (e.g. here). But if it was just a firewall issue, surely the 4.3+ devices wouldn't receive any messages either?

Some additional details

My test handsets are as follows:

  • Asus Nexus 7 (4.4.2)
  • Samsung Galaxy S4 (4.4.2)
  • HTC One (4.3)
  • Samsung Galaxy S3 (4.1.2)
  • Motorola Razr HD (4.1.2)

The server has received valid registration IDs from all five devices. On a 15-second timer it sends out a single message addressed to all five registration IDS. The response always shows that 5 messages were sent with no errors and no changed registration IDs. However, it is always received on the first three devices listed above, and never on the last two (running 4.1.2). When I debug them, the broadcast receiver isn't getting invoked at all.

I've also verified that all five devices:

  • have Google Play Services 4.3.25
  • have no SIM, hence no cellular data, and are on the same WiFi network
  • have the correct date & time
  • are registered with the same Gmail test account
  • are running the same version of my client app
  • have all sync settings for their Google account enabled

回答1:

I've finally figured out what the problem is. The corporate firewall is blocking traffic on the native GCM port of 5228. (5229 and 5230 are also mentioned with relation to GCM but we're not seeing any attempted traffic on those ports at all.) This much is well documented elsewhere (just Google GCM port 5228).

What I can't find clearly documented anywhere, but we've figured out from our server logs and from running Connection Tracker on the handsets, is that newer versions of Android fall back to using port 443 (the standard HTTPS port) which most firewalls allow traffic through by default. This is how our devices running newer Android versions are working even behind the firewall. I don't know precisely what Android version introduced this port 443 fallback, but it's somewhere between 4.1.2 (not working) and 4.3 (working).



回答2:

I don't see the manifest entries above, but I ran into the exact issue a few days ago, the manifest package must match the C2D_MESSAGE permission package. ie.

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.foo.bar"
    android:versionCode="8"
    android:versionName="3.1">

...

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<permission android:name="com.foo.bar.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
<uses-permission android:name="com.foo.bar.permission.C2D_MESSAGE" />

In my case the declared package did not match in order to provide an upgrade path for a previous version of the application.