【问题标题】:GCM Register SERVICE_NOT_AVAILABLEGCM 寄存器 SERVICE_NOT_AVAILABLE
【发布时间】:2015-04-08 17:30:44
【问题描述】:

这真的让我很烦。我有一个使用 GCM 的应用程序。我有人抱怨他们由于错误而无法登录。让我告诉你我是如何进行登录的:

// 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 次,直到它起作用(并且我连接良好)。我的 LogCat 上的错误是:

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

那么我的代码有什么问题?这让我发疯了。

【问题讨论】:

    标签: android google-cloud-messaging


    【解决方案1】:

    我们遇到了同样的问题,用户第一次无法登录,但在第二次或第三次之后可以登录,无论网络速度如何。

    我们使用Thread.sleep 做了一个变通方法并重试多次,直到收到 GCM ID。

      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.sleepnoOfAttemptsAllowed 可以根据您的设计和其他参数进行播放。我们的睡眠时间为 7000,因此第一次尝试注册的概率更高。但是,如果失败,下一次尝试将再消耗 7000 毫秒。这可能会导致用户认为您的应用程序运行缓慢。因此,明智地使用这两个值。

    【讨论】:

    • 感谢您的回答。我会试试这个。你有没有读过一些关于这个或任何东西的官方谷歌文件?我没有看到谷歌关于这个问题的任何官方“帖子”,这似乎很常见......:s
    • 还没有通过官方文档。但是在为我们的问题寻找解决方案时,我们发现两行代码之间需要一个睡眠时间。可能是因为 GCMRegistrar.register 是一个异步方法。当我们实施此解决方案时,GCM SERVICE UNAVAILABLE 错误停止发生。
    • 我仍然没有机会测试,但我想这将是最好的解决方法。将在赏金到期之前标记为正确答案,如果它不起作用,我会回来。谢谢 Nishanthi :)
    【解决方案2】:

    我也遇到过同样的问题。我的问题是我是在我的活动的 onCreate 方法上做的。我发现上下文没有完全实现,导致 gcm 无法成功注册。我提供了 getApplicationContext() 来获取 GCM 实例,这能够解决我的问题。

    例子:

    使用活动上下文会导致问题

    GoogleCloudMessaging.getInstance(ActivityName.this)
    

    使用应用程序上下文解决了我的问题

    GoogleCloudMessaging.getInstance(getApplicationContext())
    

    【讨论】:

      【解决方案3】:
      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();
      
      }
      

      【讨论】:

      • 希望对你有帮助:)
      【解决方案4】:

      1.确保类 GCMRegister () 在同一个包中有方法 googleCloud.register (AndroidManifest.xml)

      2.在手机上卸载应用程序。

      3.清理并运行项目。

      4. 成功了!!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-11
        • 1970-01-01
        • 1970-01-01
        • 2015-04-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多