GCM在4.1版本上可用,但在2.3版本的Android上无法使用。

3

我遇到了GCM的问题,它在Nexus 7上运行得很好,但是当我在任何装有Gingerbread版本的设备上运行它时,onRegistered方法从来没有被调用。

请查看下面的代码实现:

GMCIntentService

public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = "GCMIntentService";

private RestHelper restRegisterGCM;
private String userRegisterGCMUrl = "User/SetGcm";

public GCMIntentService() {
    super(AppSettings.SENDER_ID);
}

/**
 * Method called on device registered
 **/
@Override
protected void onRegistered(Context context, String registrationId) {
    Log.i(TAG, "Device registered: regId = " + registrationId);
    // Util.displayMessage(context, "Your device registred with GCM");
    if (!GCMRegistrar.isRegisteredOnServer(this)) {

        restRegisterGCM = new RestHelper(userRegisterGCMUrl, RequestMethod.POST, context);
        restRegisterGCM.setHeader("UserName", AppSettings.getInstance().getUsername(context));
        restRegisterGCM.setHeader("Password", AppSettings.getInstance().getPassword(context));
        restRegisterGCM.setParameter("regId", registrationId);
        restRegisterGCM.execute();

    }
}

/**
 * Method called on device un registred
 * */
@Override
protected void onUnregistered(Context context, String registrationId) {
    Log.i(TAG, "Device unregistered");
}

/**
 * Method called on Receiving a new message
 * */
@Override
protected void onMessage(Context context, Intent intent) {
    Log.i(TAG, "Received message");
    String message = intent.getExtras().getString("Message");
    // notifies user
    generateNotification(context, message);
}

/**
 * Method called on receiving a deleted message
 * */
@Override
protected void onDeletedMessages(Context context, int total) {
    Log.i(TAG, "Received deleted messages notification");
}

/**
 * Method called on Error
 * */
@Override
public void onError(Context context, String errorId) {
    Log.i(TAG, "Received error: " + errorId);
    Toast.makeText(context, getString(R.string.gcm_error, errorId), Toast.LENGTH_SHORT).show();
}

@Override
protected boolean onRecoverableError(Context context, String errorId) {
    // log message
    Log.i(TAG, "Received recoverable error: " + errorId);
    Toast.makeText(context, getString(R.string.gcm_recoverable_error, errorId), Toast.LENGTH_SHORT).show();
    return super.onRecoverableError(context, errorId);
}

GMC注册方法

private void registerGCM() {

    // Make sure the device has the proper dependencies.
    GCMRegistrar.checkDevice(this);
    Boolean accountExists = false;

    AccountManager am = AccountManager.get(getApplicationContext());
    Account[] accounts = am.getAccounts();

    for (Account account : accounts) {

        if (account.type.equals("com.google")) {
            accountExists = true;
            break;
        }

    }
    if (accountExists) {

        // Get GCM registration id
        String regId = GCMRegistrar.getRegistrationId(this);

        // Check if regid already presents
        if (regId.equals("")) {
            // Registration is not present, register now with GCM
            GCMRegistrar.register(this, AppSettings.SENDER_ID);

        } else {
            // Device is already registered on GCM
            if (!GCMRegistrar.isRegisteredOnServer(this)) {

                restRegisterGCM = new RestHelper(userRegisterGCMUrl, RequestMethod.POST, EvadoFilipActivity.this);
                restRegisterGCM.setHeader("UserName", AppSettings.getInstance().getUsername(EvadoFilipActivity.this));
                restRegisterGCM.setHeader("Password", AppSettings.getInstance().getPassword(EvadoFilipActivity.this));
                restRegisterGCM.setParameter("regId", regId);
                restRegisterGCM.setPostExecuteMethod(2);
                restRegisterGCM.execute();

            }
        }
    } else
        Toast.makeText(this, R.string.gcm_google_account_missing, Toast.LENGTH_SHORT).show();

}

更新:

我重命名了包名,但忘记在我的类中进行更改:

public class GCMBroadcastReceiver extends com.google.android.gcm.GCMBroadcastReceiver{
@Override protected String getGCMIntentServiceClassName(Context context) {

(译文:)
    return "com.mypackage.services.GCMIntentService";
}
}

2个回答

2

我也遇到了同样的问题。我的代码能够在Nexus4(Kitkat)上工作,但无法从应用程序服务器(通过GCM服务器)接收通知。@Fr0g是对的,对于版本低于4.0.4的设备,你需要确保你的Google账户在设备上设置好才能使用GCM功能。 我在我的Galaxy Ace(2.3.4)上设置了Google账户,但犯了一个错误,就是我的Galaxy Ace中的账户和同步设置为“关闭”状态。当我将其打开并运行我的代码时,我成功收到了通知。


1
谢谢!我尝试了所有的东西,包括多个GCM示例应用程序,在我的2.3手机上都没有起作用。我知道我有一个有效的Google Play帐户,但没有考虑打开后台和自动同步(这是我很少使用的备用手机)。瞬间——大约收到了十几条“测试”消息。 - ExactaBox
@ExactaBox:很高兴我的回答能够帮到你。我也注意到了“全部”消息的轰炸。现在我需要在服务器端实现中使用“time_to_live”属性来避免这种情况(但这取决于您的应用程序模型)。此外,请测试您的应用程序与应用程序服务器之间的GCM连接是否足够良好。我经常发现有超时和使用WiFi时出现问题。如果您遇到与GCM相关的任何问题,请告诉我。祝一切顺利! - Basher51

1

请确保您已在测试设备上设置了用户帐户。GCM要求在注册GCM的设备上必须设置谷歌帐户,(我认为此要求适用于Android版本<4.0)。


两部手机都已经设置了账户,因此在上面的代码中进行了账户检查。 - Damir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接