【问题标题】:how to resolve Android gcm notifications duplicate messages如何解决 Android gcm 通知重复消息
【发布时间】:2014-04-23 10:16:33
【问题描述】:

您好,我从 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;
    }

}

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

【问题讨论】:

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


    【解决方案1】:

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

    根据GCM reference 的说法:

    规范 ID

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

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

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

    更多信息here

    【讨论】:

    • 感谢您的回复。但是如何使用Canonical id plz你能分享我的代码吗
    • 我认为这个链接可能对你有帮助,它不是关于代码(仅),它更像是一个过程:stackoverflow.com/questions/12808959/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 2016-07-24
    • 1970-01-01
    • 1970-01-01
    • 2016-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多