如何解决Android gcm通知重复邮件

时间:2014-04-23 10:16:33

标签: android google-cloud-messaging android-notifications

您好我从gcm服务器收到重复通知,如何解决

public class RegisterActivity{

    private GoogleCloudMessaging gcm;
    Context context;
    String regId;
    private static final String REG_ID = "regId";
    private static final String APP_VERSION = "appVersion";
    static final String TAG = "Register Activity";
    private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
    private GCMRegistrationCallBack registeredActivity;
    private Error error;


    public void registerGCM(Context _context)
    {
        context = _context;
        if(!checkPlayServices()){
            Log.e(TAG, "This device is not supported.");
            return;
        }
        registeredActivity = (GCMRegistrationCallBack) _context;
        gcm = GoogleCloudMessaging.getInstance(context);
        regId = getRegistrationId(context);

        if(TextUtils.isEmpty(regId))
        {
             registerInBackground();

              Log.d("RegisterActivity",
                  "registerGCM - successfully registered with GCM server - regId: "
                      + regId);
        }
        else 
        {
            registeredActivity.didFinishRegisteringWithGCM(regId);
        }
    }

    private String  getRegistrationId(Context context) 
    {
        final SharedPreferences prefs = context.getSharedPreferences(
                GCMRegistrationCallBack.class.getSimpleName(), Context.MODE_PRIVATE);
        String registrationId = prefs.getString(REG_ID, "");
        if (registrationId.isEmpty()) {
              Log.i(TAG, "Registration not found.");
              return "";
            }
         int registeredVersion = prefs.getInt(APP_VERSION, Integer.MIN_VALUE);
            int currentVersion = getAppVersion(context);
            if (registeredVersion != currentVersion) {
              Log.i(TAG, "App version changed.");
              return "";
            }
            return registrationId;
    }

    private static int getAppVersion(Context context) {
        try {
          PackageInfo packageInfo = context.getPackageManager()
              .getPackageInfo(context.getPackageName(), 0);
          return packageInfo.versionCode;
        } catch (NameNotFoundException e) {
          Log.d("RegisterActivity",
              "I never expected this! Going down, going down!" + e);
          throw new RuntimeException(e);
        }
      }

    private void registerInBackground() {
        new AsyncTask<Void, Void, String>() {
          @Override
          protected String doInBackground(Void... params) {
            try {
              if (gcm == null) {
                gcm = GoogleCloudMessaging.getInstance(context);
              }
              regId = gcm.register(Config.GOOGLE_PROJECT_ID);
              storeRegistrationId(context, regId);
            }
            catch(UnknownHostException _exception)
            {
                error = new Error("UnknownHostException");
                callErrorCallBackOnMainThread();

            }
            catch(SocketTimeoutException _exception)
            {
                error = new Error("SocketTimeoutException");
                callErrorCallBackOnMainThread();

            }
            catch (IOException _exception) {

                error = new Error(_exception.getMessage());
                callErrorCallBackOnMainThread();

            }
            catch(Exception _exception)
            {
                error = new Error("unknown exception");
                callErrorCallBackOnMainThread();

            }
            return regId;
          }

          @Override
          protected void onPostExecute(String msg) {
              if(!TextUtils.isEmpty(msg))
                  registeredActivity.didFinishRegisteringWithGCM(regId);
          }
        }.execute(null, null, null);
      }

    private void callErrorCallBackOnMainThread()
    {
        Activity regAvtivity = (Activity)registeredActivity;

        regAvtivity.runOnUiThread(new Runnable() 
        {
            public void run() 
            {
                registeredActivity.didFailedToReceiveRegistrationId(error);
            }
        });
    }

    private void storeRegistrationId(Context context, String regId) {
        final SharedPreferences prefs = context.getSharedPreferences(
                GCMRegistrationCallBack.class.getSimpleName(), Context.MODE_PRIVATE);
        int appVersion = getAppVersion(context);
        Log.i(TAG, "Saving regId on app version " + appVersion);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString(REG_ID, regId);
        editor.putInt(APP_VERSION, appVersion);
        editor.commit();
      }

    /**
     * Check the device to make sure it has the Google Play Services APK. If
     * it doesn't, display a dialog that allows users to download the APK from
     * the Google Play Store or enable it in the device's system settings.
     */
    private boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                GooglePlayServicesUtil.getErrorDialog(resultCode,  (Activity)context,
                        PLAY_SERVICES_RESOLUTION_REQUEST).show();
            } else {
                Log.i(TAG, "This device is not supported.");

            }
            return false;
        }
        return true;
    }

}

以上获取注册号的代码请纠正我的错误......但有时候我会收到重复通知。 谢谢

1 个答案:

答案 0 :(得分:3)

您应该使用Canonical IDs。这可能是因为您为同一设备注册了多个ID。使用规范ID会将您的ID设置为您最后一次注册。

根据GCM reference关于此:

  

Canonical ID

     

在服务器端,只要应用程序运行良好,一切都应该正常工作。但是,如果应用程序中的错误触发了同一设备的多次注册,则可能很难协调状态,并且您最终可能会收到重复的消息。

     

GCM提供了一个名为“规范注册ID”的工具,可以轻松地从这些情况中恢复。规范注册ID定义为应用程序请求的最后一次注册的ID。这是服务器在向设备发送消息时应使用的ID。

     

如果稍后尝试使用不同的注册ID发送消息,GCM将照常处理请求,但它将在响应的registration_id字段中包含规范注册ID。确保使用此规范ID替换存储在服务器中的注册ID,因为您使用的ID最终将停止工作。

更多信息here