Устройство c2dm незарегистрированное автоматически - PullRequest
1 голос
/ 20 марта 2012

Я написал приложение, которое использует C2DM. Я могу зарегистрировать устройства и отправлять сообщения нормально, однако я получаю устройства, которые внезапно незарегистрированные, и, следовательно, перестают получать сообщения. Я думал, что смогу справиться с этим с кодом ниже, но кажется, что намерение «отменить регистрацию» не получено (это не подтверждено, но устройство не перерегистрировано).

Мои вопросы, это нормально для незарегистрированных устройств? Если да, отправляется ли на устройство сообщение об отмене регистрации? Как вы можете справиться с этим, не прерывая обслуживание? Другие тоже испытывают это? Я мог бы справиться с этим, когда пользователь нажимает кнопку в приложении для повторной регистрации, но я не хочу этого делать, если мне не нужно. Также рассмотрите возможность сохранения состояния устройств (зарегистрировано, не зарегистрировано) на сервере, а затем периодически проверяйте приложение, чтобы убедиться, что устройство все еще зарегистрировано.

Любая помощь будет оценена!

public class MyC2dmReceiver extends BroadcastReceiver {
private static String KEY = "c2dmPref";
private static String REGISTRATION_KEY = "registrationKey";
SharedPreferences prefs;

private Context context;

@Override
public void onReceive(Context context, Intent intent) {
    this.context = context;
    if (intent.getAction().equals(
            "com.google.android.c2dm.intent.REGISTRATION")) {
        handleRegistration(context, intent);
    } else if (intent.getAction().equals(
            "com.google.android.c2dm.intent.RECEIVE")) {
        handleMessage(context, intent);
    }
}

private void handleRegistration(Context context, Intent intent) {
    final SharedPreferences sharedPrefs = Util.getSharedPreferences(this.context);
    String email = sharedPrefs.getString(Util.ACCOUNT_NAME, "");//

    prefs = context.getSharedPreferences(KEY, Context.MODE_PRIVATE);
    //String email = prefs.getString("email_for_c2dm", "");//
    String registration = intent.getStringExtra("registration_id");
    if (intent.getStringExtra("error") != null) {
        // Registration failed, should try again later.
        Log.d("c2dm", "registration failed");
        String error = intent.getStringExtra("error");
        if (error == "SERVICE_NOT_AVAILABLE") {
            Log.d("c2dm", "SERVICE_NOT_AVAILABLE");
        } else if (error == "ACCOUNT_MISSING") {
            Log.d("c2dm", "ACCOUNT_MISSING");
        } else if (error == "AUTHENTICATION_FAILED") {
            Log.d("c2dm", "AUTHENTICATION_FAILED");
        } else if (error == "TOO_MANY_REGISTRATIONS") {
            Log.d("c2dm", "TOO_MANY_REGISTRATIONS");
        } else if (error == "INVALID_SENDER") {
            Log.d("c2dm", "INVALID_SENDER");
        } else if (error == "PHONE_REGISTRATION_ERROR") {
            Log.d("c2dm", "PHONE_REGISTRATION_ERROR");
        }
} else if (intent.getStringExtra("unregistered") != null) {
        // unregistration done, new messages from the authorized sender will
        // be rejected
        Log.d("c2dm", "unregistered");
        SharedPreferences c2dmPrefs=context.getSharedPreferences(KEY,     Context.MODE_PRIVATE);
        c2dmPrefs.edit().putString("registrationKey", "");
        c2dmPrefs.edit().commit();
                    //RegisterDevice launches the registration intent to get a new regKey
        RegisterDevice register=new      RegisterDevice(FirefighterLog.getInstance());
} else if (registration != null) {
        Log.d("c2dm", registration);
        updateServerRegId(registration))  //sends regID to server and stores
            Editor editor = context.getSharedPreferences(KEY,
                    Context.MODE_PRIVATE).edit();
            editor.putString(REGISTRATION_KEY, registration);
            editor.commit();
            Toast.makeText(context, "Device registered successfully",
                    Toast.LENGTH_LONG);
        }

ПРИМЕЧАНИЕ. UpdateServerRegId () отправляет новый regID на сервер и перезаписывает, если он уже существует. Я использую RequestFactory и отправляю его как сущность в appengine.

Манифест Android:

<uses-permission android:name="com.xxx.someapp.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <permission android:name="com.xxx.someapp.permission.C2D_MESSAGE"
              android:protectionLevel="signature" />

  <receiver android:name=".C2DM.MyC2dmReceiver"     android:permission="com.google.android.c2dm.permission.SEND">
      <!-- Receive the actual message -->
      <intent-filter>
          <action android:name="com.google.android.c2dm.intent.RECEIVE" />
          <category android:name="com.xxx.someapp" />
      </intent-filter>
      <!-- Receive the registration id -->
      <intent-filter>
          <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
          <category android:name="com.xxx.someapp" />
      </intent-filter>
  </receiver>

1 Ответ

2 голосов
/ 21 марта 2012

Может ли это быть случаем, когда Google обновляет регистрационный идентификатор?Из документов C2DM для Поток жизненного цикла в разделе Включение C2DM ...

...

2. При регистрацииПри успешном выполнении сервер C2DM передает намерение РЕГИСТРАЦИЯ, которое дает приложению регистрационный идентификатор.

Приложение должно сохранить этот идентификатор для последующего использования. Обратите внимание, что Google может периодически обновлять регистрационный идентификатор, поэтому вы должны разработать свое приложение с учетом того, что намерение РЕГИСТРАЦИИ может вызываться несколько раз. Ваше приложение должно иметь возможность отвечать соответствующим образом.

...

Идентификатор регистрации действует до тех пор, пока приложение явно не отменит свою регистрацию, или пока Google не обновит регистрационный идентификатор для вашего приложения.

документация, в которой говорится, что в результате перерегистрации будет отправлено намерение с дополнительным «незарегистрированным».Единственное упомянутое время - это когда приложение явно отменяет регистрацию.

Глядя на ваш код, оно кажется неполным - неясно, как вы справляетесь с регистрацией или возможностью повторной регистрации (когда Google обновляетрегистрационный идентификатор, например).

В своем ответе на мой комментарий к вашему вопросу вы говорите, что это «обычно недели».Если бы вы сказали часы (или, возможно, даже дни), я бы, вероятно, отклонил бы мысль о том, что перерегистрация вызывает проблему.Однако для обновления регистрационного идентификатора Google недели вполне приемлемы.

Просто мысль.

РЕДАКТИРОВАТЬ: Ну, пока вы счастливычто updateServerRegId() работает правильно и обновляется с новым registration_id (при необходимости), тогда я не вижу ничего другого, на что можно указать пальцем.

Я все еще задаюсь вопросом, является ли это случаем поддержанияневерный (истекший) идентификатор регистрации однако.Просто посмотрим на документы дальше ...

Приложение получает широковещательную рассылку РЕГИСТРАЦИЯ всякий раз, когда сервер приложений пытается отправить ему сообщение.Но регистрационные идентификаторы могут быть несуществующими или недействительными по ряду причин:

  • Если приложение запускается впервые, оно еще не имеет регистрационного идентификатора.
  • Если приложение незарегистрировано, у него нет регистрационного идентификатора.
  • Сервер C2DM периодически обновляет регистрационные идентификаторы.

При условии, что первые два не применяются, оставляя только последние.

Вы говорите в своем первоначальном вопросе, что «я получаю устройства, которые неожиданно были незарегистрированными, и поэтому прекращаю получать сообщения».Вы смотрели на возможные коды ошибок в ответе 200 при отправке сообщений на эти устройства?Посмотрите на раздел кода ответа Как сервер приложений отправляет сообщения , это может дать вам лучшее представление о том, что происходит.

Кстати, одна вещь, возможно, не связанная (но я думал, что яупомяну это) ...

if (error == "SERVICE_NOT_AVAILABLE")

... не сравнивайте Strings с использованием ==, всегда используйте .equals(...).Если по пути вы получаете ошибки, сравнение строк ошибок таким способом не сработает, и вы можете что-то упустить.

...