使用GCM服务从不会调用BroadcastReceiver [英] BroadcastReceiver is never called using GCM service

查看:154
本文介绍了使用GCM服务从不会调用BroadcastReceiver的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图为推送通知实施GCM的新服务。
我已经看到一些关于该问题的类似帖子,其中大多数都指向缺少某些东西的Manifest。
找不到我在那里丢失的东西:



Manifest.xml 这是efecting的东西)

 < manifest xmlns:android =http://schemas.android.com/apk/res/ android
package =com.example.catchme2
android:versionCode =1
android:versionName =1.0>

< uses-sdk
android:minSdkVersion =12
android:targetSdkVersion =18/>
< uses-permission android:name =android.permission.INTERNET/>
< uses-permission android:name =android.permission.ACCESS_NETWORK_STATE/>
< uses-permission android:name =android.permission.WRITE_EXTERNAL_STORAGE/>
<使用权限android:name =com.google.android.providers.gsf.permission.READ_GSERVICES/>
< uses-permission android:name =android.permission.CALL_PHONE/>
<! - 以下两个权限不需要使用
Google Maps Android API v2,但建议您使用。 - >
< uses-permission android:name =android.permission.ACCESS_COARSE_LOCATION/>
< uses-permission android:name =android.permission.ACCESS_FINE_LOCATION/>
<使用权限android:name =android.permission.GET_ACCOUNTS/>
<使用权限android:name =android.permission.WAKE_LOCK/>
< uses-permission android:name =com.google.android.c2dm.permission.RECEIVE/>

< permission android:name =com.example.catchme2.permission.C2D_MESSAGE
android:protectionLevel =signature/>
< uses-permission android:name =com.example.catchme2.permission.C2D_MESSAGE/>


< uses-feature
android:glEsVersion =0x00020000
android:required =true/>
< application
android:allowBackup =true
android:icon =@ drawable / ic_launcher
android:label =@ string / app_name
android:theme =@ style / Theme.Sherlock
android:uiOptions =splitActionBarWhenNarrow>
< activity
android:name =com.example.catchme2.FbActivity
android:label =@ string / app_name
android:configChanges =orientation | screenSize
android:uiOptions =splitActionBarWhenNarrow>
< intent-filter>

< category android:name =android.intent.category.LAUNCHER/>
< / intent-filter>
< / activity>
< meta-data
android:name =com.google.android.gms.version
android:value =@ integer / google_play_services_version/>
< meta-data
android:name =com.google.android.maps.v2.API_KEY
android:value =MyAPIKEY/>
< meta-data android:name =com.facebook.sdk.ApplicationIdandroid:value =@ string / app_id/>
< activity android:name =com.facebook.LoginActivity>< / activity>
< activity android:name =MainActivity>< / activity>

< receiver
android:name =com.example.catchme2.GcmBroadcastReceiver
android:permission =com.google.android.c2dm.permission.SEND> ;
< intent-filter>
< action android:name =com.google.android.c2dm.intent.GCM_RECEIVED_ACTION/>
< category android:name =com.example.catchme2/>
< / intent-filter>
< / receiver>
< service android:name =com.example.catchme2.GcmIntentService
android:enabled =true/>
< / application>
< / manifest>

BroadcastReceiver.class

  public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {

@Override
public void onReceive(Context context,Intent intent){
//明确指定GcmIntentService将处理意图。
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
//启动服务,保持设备在启动时保持清醒状态。
startWakefulService(context,(intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}

}

IntentService.class

  public class GcmIntentService extends IntentService {

public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder构建器;
static final String TAG =GCMDemo;

public GcmIntentService(String name){
super(GcmIntentService);


@Override
protected void onHandleIntent(意图意图){
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
// getMessageType()意图参数必须是您在BroadcastReceiver中收到
//的意图。
字符串messageType = gcm.getMessageType(intent);

if(!extras.isEmpty()){//具有不合格的效果Bundle
/ *
*根据消息类型过滤消息。由于GCM
*很可能会在未来使用新的消息类型进行扩展,只需忽略
*任何您不感兴趣的消息类型,或者您不需要
*认识。
* /
if(GoogleCloudMessaging。
MESSAGE_TYPE_SEND_ERROR.equals(messageType)){
sendNotification(Send error:+ extras.toString());
} else if(GoogleCloudMessaging。
MESSAGE_TYPE_DELETED.equals(messageType)){
sendNotification(服务器上的已删除邮件:+
extras.toString());
//如果是常规的GCM消息,请做一些工作。
} else if(GoogleCloudMessaging。
MESSAGE_TYPE_MESSAGE.equals(messageType)){
//此循环表示服务正在做某些工作。
for(int i = 0; i <5; i ++){
Log.i(TAG,Working ...+(i + 1)
+/ 5 @ + SystemClock.elapsedRealtime());
尝试{
Thread.sleep(5000);
} catch(InterruptedException e){
}
}
Log.i(TAG,Completed work @+ SystemClock.elapsedRealtime());
//发送收到的消息通知。
sendNotification(Received:+ extras.toString());
Log.i(TAG,Received:+ extras.toString());
}
}
//释放由WakefulBroadcastReceiver提供的唤醒锁。
GcmBroadcastReceiver.completeWakefulIntent(intent);


$ b private void sendNotification(String msg){
mNotificationManager =(NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);

PendingIntent contentIntent = PendingIntent.getActivity(this,0,
new Intent(this,FbActivity.class),0);

NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(GCM Notification)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg);

mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID,mBuilder.build());
}
}

我使用这一行发送massege:

  gcm.send(SENDER_ID +@ gcm.googleapis.com,id,data); 

sender_id是我在google api console上的项目编号,并且id始终相同(1) 。

解决方案

gcm.send 用于从应用程序发送GCM消息到您的服务器(通过GCM云连接服务器)。您的清单看起来很好,但为了让 gcm.send 做任何事情,您必须有一台服务器连接到GCM Cloud Connection Server。而且,由于您试图向服务器发送消息,因此您的设备中不会看到任何内容(即使消息已成功发送到您的服务器),并且不会调用BroadcastReceiver(除非您的服务器将消息发回给设备)。


I'm trying to implement the new service of GCM for push notifications. I've seen some similiar posts about that issue and most of them are pointing to the Manifest that missing something. Couldn't find what I'm missing there:

Manifest.xml (Original with all permisions etc.. in case that's efecting something)

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.catchme2"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="12"
        android:targetSdkVersion="18" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <!-- The following two permissions are not required to use
         Google Maps Android API v2, but are recommended. -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <permission android:name="com.example.catchme2.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="com.example.catchme2.permission.C2D_MESSAGE" />


    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true"/>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.Sherlock"
        android:uiOptions="splitActionBarWhenNarrow" >
        <activity
            android:name="com.example.catchme2.FbActivity"
            android:label="@string/app_name"
            android:configChanges="orientation|screenSize"
            android:uiOptions="splitActionBarWhenNarrow">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
          <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
          <meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value="MyAPIKEY"/>
        <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/app_id"/>
        <activity android:name="com.facebook.LoginActivity"></activity>
        <activity android:name="MainActivity"></activity>

        <receiver
            android:name="com.example.catchme2.GcmBroadcastReceiver"
            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" />
                <action android:name="com.google.android.c2dm.intent.GCM_RECEIVED_ACTION" />
                <category android:name="com.example.catchme2" />
            </intent-filter>
        </receiver>
        <service android:name="com.example.catchme2.GcmIntentService" 
            android:enabled="true"/>
    </application>
</manifest>

BroadcastReceiver.class

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // Explicitly specify that GcmIntentService will handle the intent.
        ComponentName comp = new ComponentName(context.getPackageName(),
                GcmIntentService.class.getName());
        // Start the service, keeping the device awake while it is launching.
        startWakefulService(context, (intent.setComponent(comp)));
        setResultCode(Activity.RESULT_OK);
    }

}

IntentService.class

public class GcmIntentService extends IntentService {

    public static final int NOTIFICATION_ID = 1;
    private NotificationManager mNotificationManager;
    NotificationCompat.Builder builder;
    static final String TAG = "GCMDemo";

    public GcmIntentService(String name) {
        super("GcmIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle extras = intent.getExtras();
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
        // The getMessageType() intent parameter must be the intent you received
        // in your BroadcastReceiver.
        String messageType = gcm.getMessageType(intent);

        if (!extras.isEmpty()) {  // has effect of unparcelling Bundle
            /*
             * Filter messages based on message type. Since it is likely that GCM
             * will be extended in the future with new message types, just ignore
             * any message types you're not interested in, or that you don't
             * recognize.
             */
            if (GoogleCloudMessaging.
                    MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
                sendNotification("Send error: " + extras.toString());
            } else if (GoogleCloudMessaging.
                    MESSAGE_TYPE_DELETED.equals(messageType)) {
                sendNotification("Deleted messages on server: " +
                        extras.toString());
            // If it's a regular GCM message, do some work.
            } else if (GoogleCloudMessaging.
                    MESSAGE_TYPE_MESSAGE.equals(messageType)) {
                // This loop represents the service doing some work.
                for (int i=0; i<5; i++) {
                    Log.i(TAG, "Working... " + (i+1)
                            + "/5 @ " + SystemClock.elapsedRealtime());
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                    }
                }
                Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
                // Post notification of received message.
                sendNotification("Received: " + extras.toString());
                Log.i(TAG, "Received: " + extras.toString());
            }
        }
        // Release the wake lock provided by the WakefulBroadcastReceiver.
        GcmBroadcastReceiver.completeWakefulIntent(intent);

    }

    private void sendNotification(String msg) {
        mNotificationManager = (NotificationManager)
                this.getSystemService(Context.NOTIFICATION_SERVICE);

        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, FbActivity.class), 0);

        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.ic_launcher)
        .setContentTitle("GCM Notification")
        .setStyle(new NotificationCompat.BigTextStyle()
        .bigText(msg))
        .setContentText(msg);

        mBuilder.setContentIntent(contentIntent);
        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
    }
}

I'm using this line to send the massege:

gcm.send(SENDER_ID + "@gcm.googleapis.com", id, data);

The sender_id is my project number at google api console, and the id is always the same (1).

解决方案

gcm.send is for sending GCM messages from your application to your server (via GCM Cloud Connection Server). Your manifest looks fine, but in order for gcm.send to do anything, you must have a server connected to GCM Cloud Connection Server. And since you are trying to send a message to the server, you won't see anything in your device (even if the message was sent successfully to your server) and BroadcastReceiver won't be called (unless your server sends a message back to the device).

这篇关于使用GCM服务从不会调用BroadcastReceiver的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆