android - GcmListenerService.onMessageReceived 未调用

标签 android service google-cloud-messaging

我正在尝试从服务器向我的应用程序获取消息。 我有这个服务器 url,它向所有用户发送消息: https://taub-prayer-ramym.c9.io/send?message=123

我的应用程序的 token 已在服务器中注册...但我遇到一个问题,即未调用我的 GcmListenerService 实现中的 onMessageReceived() 方法。

我的 list :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.atheel.prayer" >

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="21" />

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
    <uses-permission android:name="com.example.atheel.prayer.permission.C2D_MESSAGE"/>
    <uses-permission android:name="com.google.android.c2dm.permission.SEND"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <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" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                <category android:name="com.example.atheel.prayer" />
            </intent-filter>
        </receiver>
        <service
            android:name="com.example.atheel.prayer.MyGcmListenerService"
            android:exported="false" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </service>
        <service
            android:name="com.example.atheel.prayer.MyInstanceIDListenerService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.android.gms.iid.InstanceID"/>
            </intent-filter>
        </service>
        <service android:exported="false" android:name="com.example.atheel.prayer.RegistrationIntentService"/>

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".EmptyStatus"
            android:label="@string/title_activity_empty_status" >
        </activity>
        <activity
            android:name=".UnEmpty"
            android:label="@string/title_activity_un_empty" >
        </activity>
    </application>

</manifest>

我的 GCMListener :

public class MyGcmListenerService extends GcmListenerService {
    private static final String TAG = "MyGcmListenerService";
    File notificationsFile;
    private String sessionForAppClosed;

    // [START receive_message]
    @Override
    public void onMessageReceived(String from, Bundle data) {
        Log.i(TAG,"Message Received!!!!!!!!!");
        System.out.print("***************Message Received!!!!!!!!!");
    }
}

谁能想到为什么它不起作用?

最佳答案

我想您已经阅读了 official documentation用于 GCM 支持。我还建议您阅读 this文章。

与我的 GCM 代码相比,您缺少了这一行

<action android:name="com.google.android.c2dm.intent.GCM_RECEIVED_ACTION"/> 

来自 GcmReceiver 类。我也没有看到有关 gcm 版本的元标记:

<meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version"/>

我做的第三件不同的事情是权限规范:

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
    <permission
    android:name="your.package.permission.C2D_MESSAGE"
    android:protectionLevel="signature"/>

我还记得在某些网络上 gcm 根本不起作用。这是一件奇怪的事情,但您可以阅读更多相关信息 here .

编辑:由于问题仍未解决,我在下面添加了用于接收 GCM 的工作代码。请注意,我假设该应用已在谷歌服务中成功注册,防火墙未被阻止并且应用服务器已成功将消息发送到谷歌服务器: GcmBroadcastReceiver - 用于接收 CGM 消息

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    ComponentName comp = new ComponentName(context.getPackageName(),GcmIntentService.class.getName());
    startWakefulService(context, (intent.setComponent(comp)));
    setResultCode(Activity.RESULT_OK);
}

该组件调用以下服务

public class GcmIntentService extends IntentService {

public GcmIntentService() {
    super(App.getStr(R.string.gcm_sender_id)); // this integer is provided when registering the application 
}

@Override
protected void onHandleIntent(Intent intent) {
    Bundle extras = intent.getExtras();
    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
    String messageType = gcm.getMessageType(intent);
    if (!extras.isEmpty()) {
        if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
            sendNotification(extras);
        } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
            sendNotification(extras);
        } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
            // here you can do your work
            }
        }
    }
    GcmBroadcastReceiver.completeWakefulIntent(intent);
}

PS:请注意,我的解决方案很大程度上受到互联网上其他解决方案的启发,例如 this one


关于android - GcmListenerService.onMessageReceived 未调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32285610/

相关文章:

android - GCM 可以向其发送推送通知的最大设备数

android - com.google.android.gcm.GCMBaseIntentService 在哪里?

java - Ubuntu 接管 Android。我们现在要用 GCC 还是 Android 的 Java NDK/SDK?

android - 改造 java.net.ProtocolException : Expected ':status' header not present

android - 如何在 Android 中使用 SimpleAdapter 滚动 ListView 项目时停止执行 getView() 方法

android - 将图像叠加到相机预览 SurfaceView 上以及如何保存它们?

c# - 从 C# Windows 服务(用托管代码编写)调用 C++ dll(非托管代码)

android - 如果服务在另一个进程中,如何绑定(bind)服务?

symfony - 如何将 token 存储作为参数传递给 Symfony 3.4 中的事件监听器

java - 当使用 Smack 4.1.0 API 作为 Google 的 GCM CCS 的 XMPP 客户端时,SecurityMode.required 不工作