Android GCM基本实现

Roo*_*242 28 android google-cloud-messaging

更新:我修复了下面代码中的问题,所以这是一个很好的基本工作示例,说明如何使用GCM


所以,我正在尝试将Android GCM应用到我的应用中.以下是我添加到清单中的相关部分:

<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="20" />

<permission
    android:name=".permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name=".permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
Run Code Online (Sandbox Code Playgroud)

...

<receiver
    android:name="com.google.android.gcm.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" />
        <category android:name="com.badbob.app.gmctestapp" />
    </intent-filter>
</receiver>

<service android:name=".GCMIntentService" />
Run Code Online (Sandbox Code Playgroud)

我已将以下代码添加到我的主要活动的onCreate中:

    GCMRegistrar.checkDevice( this );
    GCMRegistrar.checkManifest( this );
    final String regId = GCMRegistrar.getRegistrationId( this );
    if( regId.equals( "" ) ) {
        GCMRegistrar.register( this, GCM_SENDER_ID );
    }
    else {
        Log.v( LOG_TAG, "Already registered" );
    }
Run Code Online (Sandbox Code Playgroud)

我也GCMIntenetService像这样创建了这个类:

public class GCMIntentService extends GCMBaseIntentService {

    private static final String LOG_TAG = "GetAClue::GCMIntentService";

    public GCMIntentService() {
        super( GCM_SENDER_ID );
        // TODO Auto-generated constructor stub
        Log.i( LOG_TAG, "GCMIntentService constructor called" );
    }

    @Override
    protected void onError( Context arg0, String errorId ) {
        // TODO Auto-generated method stub
        Log.i( LOG_TAG, "GCMIntentService onError called: " + errorId );
    }

    @Override
    protected void onMessage( Context arg0, Intent intent ) {
        // TODO Auto-generated method stub
        Log.i( LOG_TAG, "GCMIntentService onMessage called" );
        Log.i( LOG_TAG, "Message is: " + intent.getStringExtra( "message" ) );
    }

    @Override
    protected void onRegistered( Context arg0, String registrationId ) {
        // TODO Auto-generated method stub
        Log.i( LOG_TAG, "GCMIntentService onRegistered called" );
        Log.i( LOG_TAG, "Registration id is: " + registrationId );
    }

    @Override
    protected void onUnregistered( Context arg0, String registrationId ) {
        // TODO Auto-generated method stub
        Log.i( LOG_TAG, "GCMIntentService onUnregistered called" );
        Log.i( LOG_TAG, "Registration id is: " + registrationId );
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行这个时,我在LogCat中得到它:

07-11 11:28:46.340: V/GCMRegistrar(27435): Registering receiver
07-11 11:28:46.370: D/GCMRegistrar(27435): resetting backoff for com.badbob.app.getacluebeta
07-11 11:28:46.380: V/GCMRegistrar(27435): Registering app com.badbob.app.getacluebeta of senders 128205395388
Run Code Online (Sandbox Code Playgroud)

从我从其他职位收集我应该得到一个注册ID LogCat,但是我"米不是.而且onRegistered()GCMIntentService不会被调用.所以我在做什么错?

Rya*_*ray 18

这是不正确的

protected GCMIntentService( String senderId ) {         
super(senderId);}
Run Code Online (Sandbox Code Playgroud)

正如它在文档中所述.你必须为GCMIntentService声明一个PUBLIC,NO ARGUMENT构造函数.否则,后台意图服务无法正确实例化GCMIntentService.

public GCMIntentService(){
super(senderID);}
Run Code Online (Sandbox Code Playgroud)

senderID可以是硬编码常量字符串,因为它不再随新GCM而改变.使用正确的senderID也非常重要.24小时足以让你自己活跃,所以如果我的上述解决方案不起作用,你使用的是不正确的senderID.其他一切看起来都很棒.

当您浏览Google API访问权限页面时,senderID位于您的网络浏览器的网址中.单击GCM,浏览器URL中将显示一个12位数字.这是正确使用的密钥.不是你的API密钥.这是在App服务器端使用的.

  • 文档说明'min_sdk'是否为16而不是可以省略它.但是OP正在使用'min_sdk'= 8 (2认同)

red*_*cta 8

我也有这个恼人的bug,直到现在.问题是,我在另一个包中声明了intentservice ...即使我在android清单中声明了名称并且没有放置classnotfound异常......也没有找到任何错误......所以我确保了intentservice位于root包中.