2014-08-05 3 views
10

Это действительно раздражает меня. У меня есть приложение, которое использует GCM. У меня есть люди, жалующиеся, что они не могут войти из-за ошибки. Позвольте мне показать вам, как я делаю вход в систему:GCM Register SERVICE_NOT_AVAILABLE

// Login Activity 
//.... 
public void onClickLoginButton (View v) { 

    // Do some stuff... 

    new GCMRegister().execute(); //AsyncTask 
} 

private class GCMRegister extends AsyncTask<Void, Void, Integer> { 

    @Override 
    protected Integer doInBackground (Void... params) { 
     ConnectivityManager connMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); 
     NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); 

     if (networkInfo != null && networkInfo.isConnected()) { 
      try { 
       //Get GCM Registration key 
       registrationId = googleCloud.register(Settings.PROJECT_NUMBER); 
      } catch (Exception e) { 
       Log.e("GCMRegister", e.toString()); 
       return -1; 
      } 
      return 1; 
     } else { 
      return -3; 
     } 
    } 

    @Override 
    protected void onPostExecute(Integer result) { 
     if (result == 1) { 
      new LoginAsync().execute(); // Another AsyncTask to check in my database if user is valid and save its key 
     } else { 
      user.setEnabled(true); 
      password.setEnabled(true); 
      login.setEnabled(true); 
      if (result == -1) { 
       Toast.makeText(Login.this, "A problem occured login in", Toast.LENGTH_LONG).show(); 
      } else if (result == -3) { 
       Toast.makeText(Login.this, "I need an internet connection", Toast.LENGTH_LONG).show(); 
      } 
     } 
    } 

Так много людей жалуются они не могут войти в систему из-за «возникла проблема Логин» ошибка, которая указывает на то, что GCM терпит неудачу в реестре. Даже я с моим устройством Android 4.4.2 не может сделать это сначала. Мне нужно попытаться войти в систему 2 или 3 раза, пока это не сработает (и Im в хорошей связи). Ошибка в моем LogCat:

08-04 21:29:10.922: E/GCMRegister(18182): java.io.IOException: SERVICE_NOT_AVAILABLE 

Так что же случилось с моим кодом? Это сводит меня с ума.

ответ

15

Мы столкнулись с той же проблемой, когда пользователи не могут войти в систему в первый раз, но могут войти в систему после второго или третьего момента, независимо от скорости сети.

Мы сделали обходное решение, используя Thread.sleep и повторяя его несколько раз, до получения идентификатора GCM.

int noOfAttemptsAllowed = 5; // Number of Retries allowed 
    int noOfAttempts = 0;   // Number of tries done 
    bool stopFetching = false;  // Flag to denote if it has to be retried or not 
    String regId = "";    


    while (!stopFetching) 
    { 
     noOfAttempts ++; 
     GCMRegistrar.register(getApplicationContext(), "XXXX_SOME_KEY_XXXX"); 
     try 
     { 
      // Leave some time here for the register to be 
      // registered before going to the next line 
      Thread.sleep(2000); // Set this timing based on trial. 
    } catch (InterruptedException e) { 
    e.printStackTrace(); 
    } 
     try 
     { 
      // Get the registration ID 
      regId = GCMRegistrar.getRegistrationId(LoginActivity.this); 
     } catch (Exception e) {} 


     if (!regId.isEmpty() || noOfAttempts > noOfAttemptsAllowed) 
     { 
      // If registration ID obtained or No Of tries exceeded, stop fetching 
      stopFetching = true; 
     } 
     if (!regId.isEmpty()) 
     { 
      // If registration ID Obtained, save to shared preferences 
      saveRegIDToSharedPreferences(); 
     } 


    } 

Примечание:Thread.sleep и noOfAttemptsAllowed можно играть вокруг с на основе вашего дизайна и других параметров. У нас было время сна 7000, так что вероятность регистрации при первой попытке выше. Однако, если это не удастся, следующая попытка будет потреблять еще 7000 мс. Это может заставить пользователей думать, что ваше приложение работает медленно. Итак, играйте разумно с этими двумя значениями.

+0

Спасибо за ответ. Я попробую это. Вы читали какой-то официальный документ Google по этому поводу? Я не видел никаких официальных «сообщений» от google по этому вопросу, и это кажется довольно распространенным ...: s –

+0

Не прошли официальные документы. Но, найдя решение для нашей проблемы, мы определили, что требуется время сна между двумя строками кода. Вероятно, потому что GCMRegistrar.register - это асинхронный метод. Когда мы реализовали это решение, ошибка «GCM SERVICE UNAVAILABLE» прекратилась. –

+0

@ JoãoMenighin: Это сработало для вас? –

0
GoogleCloudMessaging gcm; 
String regId;  

private String setGCMModule() { 

    if (TextUtils.isEmpty(regId)) { 
     regId = registerGCM(); 
     Log.d("regId", "GCM RegId: " + regId); 
    } else { 
     Log.e(getApplicationContext() + "", 
       "Already Registered with GCM Server!"); 
    } 
    return regId; 
} 

public String registerGCM() { 

    gcm = GoogleCloudMessaging.getInstance(this); 
    regId = getRegistrationId(getContext()); 

    if (TextUtils.isEmpty(regId)) { 

     registerInBackground(); 

     Log.d("RegisterActivity", 
       "registerGCM - successfully registered with GCM server - regId: " 
         + regId); 
    } else { 
     Log.i(getApplicationContext() + "", 
       "RegId already available. RegId: " + regId); 

    } 
    return regId; 
} 

private String getRegistrationId(Context context) { 

    String registrationId = settings.getString(REG_ID, ""); 
    if (registrationId.isEmpty()) { 
     Log.i(TAG, "Registration not found."); 
     return ""; 
    } 
    int registeredVersion = settings.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) { 
      String msg = ""; 
      try { 
       if (gcm == null) { 
        gcm = GoogleCloudMessaging.getInstance(getContext()); 
       } 
       regId = gcm.register(Config.GOOGLE_PROJECT_ID); 

       storeRegistrationId(getContext(), regId); 
      } catch (IOException ex) { 
       msg = "Error :" + ex.getMessage(); 
       Log.d("RegisterActivity", "Error: " + msg); 
      } 
      Log.d("RegisterActivity", "AsyncTask completed: " + msg); 
      return msg; 
     } 

     @Override 
     protected void onPostExecute(String msg) { 

      // get new message here 

      Log.e(getApplicationContext() + "", 
        "Registered with GCM Server." + msg); 
     } 
    }.execute(null, null, null); 
} 

private void storeRegistrationId(Context context, String regId) { 

    int appVersion = getAppVersion(context); 
    Log.i(TAG, "Saving regId on app version " + appVersion); 
    settings.edit(); 
    editor.putString(REG_ID, regId); 
    editor.putInt(APP_VERSION, appVersion); 
    editor.commit(); 

} 
+0

надеюсь, что это поможет u :) –

0

1.You убедитесь класс GCMRegister() есть метод googleCloud.register в одном пакете (AndroidManifest.xml)

2.Uninstall приложения на мобильном телефоне.

3.Clean and Run Project.

4.Это работает!

5

Я столкнулся с этой проблемой. Моя проблема заключалась в том, что я делал это по методу onCreate моей деятельности. Я обнаружил, что контекст не был полностью реализован, и gcm не удалось зарегистрировать. Я предоставил getApplicationContext() для получения экземпляра GCM, и это позволило решить мою проблему.

Пример:

Использование контекста деятельности вызвал вопрос

GoogleCloudMessaging.getInstance(ActivityName.this) 

Использование контекста приложения устранить проблему

GoogleCloudMessaging.getInstance(getApplicationContext())