2013-06-19 106 views
24

我遇到了一個奇怪的問題 - 我一直在我的應用程序中使用GCM很長一段時間,一切都很完美。但是,在發佈Google Play之前,我將我的應用程序包名稱從com.android.testapp更改爲com.android.recognition,並且在此GCM停止工作後。起初,我得到了en錯誤GCM sender id not set on constructor,並通過覆蓋getSenderIds(Context context)來修復它,但現在我無法獲得註冊ID。以下是來自logcat的消息: enter image description here如何解決Google雲消息傳遞註冊錯誤:SERVICE_NOT_AVAILABLE?

我該如何解決這個問題?當我換了新包裝我換到新的包一切都在清單文件:

<receiver 
     android:name="com.google.android.gcm.GCMBroadcastReceiver" 
     android:permission="com.google.android.c2dm.permission.SEND" > 
     <intent-filter> 
      <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
      <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 
      <category android:name="com.android.recognition" /> 
     </intent-filter> 
    </receiver> 

那麼,什麼是這背後的問題?是否可以重命名應用程序包導致此問題還是有其他原因?

+0

你在模擬器上工作嗎?哪個模擬器? –

+0

@PankajKumar我正在使用真實設備:Kindle Fire和LG NEXUS 4.And nothing works – MainstreamDeveloper00

+0

對我來說,我看起來很奇怪。我必須嘗試幾次。有時候,我需要強制關閉應用程序。然後它工作。 –

回答

30

SERVICE_NOT_AVAILABLE錯誤表示GCM Service在當前不可用。等一段時間後再試。

很多時候會發生這種情況(以我的經驗),所以不用擔心。


查看GCMConstants GCM Lib類。

/** 
    * The device can't read the response, or there was a 500/503 from the 
    * server that can be retried later. The application should use exponential 
    * back off and retry. 
    */ 
    public static final String ERROR_SERVICE_NOT_AVAILABLE = 
      "SERVICE_NOT_AVAILABLE"; 

詳細的調查看GCMBaseIntentServicehandleRegistration()

private void handleRegistration(final Context context, Intent intent) { 
     String registrationId = intent.getStringExtra(EXTRA_REGISTRATION_ID); 
     String error = intent.getStringExtra(EXTRA_ERROR); 
     String unregistered = intent.getStringExtra(EXTRA_UNREGISTERED); 
     Log.d(TAG, "handleRegistration: registrationId = " + registrationId + 
       ", error = " + error + ", unregistered = " + unregistered); 

     // registration succeeded 
     if (registrationId != null) { 
      GCMRegistrar.resetBackoff(context); 
      GCMRegistrar.setRegistrationId(context, registrationId); 
      onRegistered(context, registrationId); 
      return; 
     } 

     // unregistration succeeded 
     if (unregistered != null) { 
      // Remember we are unregistered 
      GCMRegistrar.resetBackoff(context); 
      String oldRegistrationId = 
        GCMRegistrar.clearRegistrationId(context); 
      onUnregistered(context, oldRegistrationId); 
      return; 
     } 

     // last operation (registration or unregistration) returned an error; 
     Log.d(TAG, "Registration error: " + error); 
     // Registration failed 
     if (ERROR_SERVICE_NOT_AVAILABLE.equals(error)) { 
      boolean retry = onRecoverableError(context, error); 
      if (retry) { 
       int backoffTimeMs = GCMRegistrar.getBackoff(context); 
       int nextAttempt = backoffTimeMs/2 + 
         sRandom.nextInt(backoffTimeMs); 
       Log.d(TAG, "Scheduling registration retry, backoff = " + 
         nextAttempt + " (" + backoffTimeMs + ")"); 
       Intent retryIntent = 
         new Intent(INTENT_FROM_GCM_LIBRARY_RETRY); 
       retryIntent.putExtra(EXTRA_TOKEN, TOKEN); 
       PendingIntent retryPendingIntent = PendingIntent 
         .getBroadcast(context, 0, retryIntent, 0); 
       AlarmManager am = (AlarmManager) 
         context.getSystemService(Context.ALARM_SERVICE); 
       am.set(AlarmManager.ELAPSED_REALTIME, 
         SystemClock.elapsedRealtime() + nextAttempt, 
         retryPendingIntent); 
       // Next retry should wait longer. 
       if (backoffTimeMs < MAX_BACKOFF_MS) { 
        GCMRegistrar.setBackoff(context, backoffTimeMs * 2); 
       } 
      } else { 
       Log.d(TAG, "Not retrying failed operation"); 
      } 
     } else { 
      // Unrecoverable error, notify app 
      onError(context, error); 
     } 
    } 
+3

「等一段時間再試。」我有三天的錯誤已經在不同的設備上 – MainstreamDeveloper00

+2

我在一天內沒有遇到這個問題。如果你面對這個問題3天,它可能也有其他一些問題..你有沒有在prev的相同的代碼獲得成功? –

+0

「我在我的應用程序中使用GCM很長一段時間,一切都很完美」我在我的問題中寫了關於它的問題 – MainstreamDeveloper00

18

確保您在清單的權限部分改變了包名:

<permission android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE" 
    android:protectionLevel="signature" /> 
<uses-permission android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE" /> 

我不得不因類似的錯誤到該部分中的包名不正確。

+0

使用' '如果你在manifest xml中有'package'屬性? – Bootstrapper

+0

@ user2104070不,權限必須包含軟件包名稱。 – Eran

+0

所以如果我有不同的構建(在Android Studio中),那麼我需要爲每個版本維護單獨的AndroidManifest版本(因爲包名稱會不同)? – Bootstrapper

40

問題得到解答,在我的情況下,它稍微複雜一點。

  1. 檢查你有一個活躍的互聯網連接
  2. 檢查您是否具有Internet權限在您的清單
  3. 確保包名是正確的,因爲葉蘭提到
  4. 設備時間是正確的設置。即使一切都很完美,但如果設備時鐘設置不正確,它將會失敗。

錯誤的時鐘給我造成的問題。 :)

+1

我忘了激活wifi!謝謝 – JCarlos

+0

是的,我放棄了wifi連接,並沒有意識到它。謝謝。 – ndland

+0

4分節省了我的時間 –

3

我有同樣的問題,但沒有上述解決方案在我的情況下解決了這個問題。幸運的是,我最近解決了這個問題,我想解釋一下如何跳轉它可以幫助其他人:

在我的情況中,我在自定義應用程序類中註冊推送服務(在任何活動之前執行並且我認爲是由於這有些東西沒有被初始化)。將它改爲主要活動解決了問題。

public class MyCustomApp extends Application { 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     PushService.register(this); //BAD IDEA, don't register pushes in Application Class 
    } 

} 
3

我有類似的問題。在Google Nexus(Android 4.4.2)上工作得很好,但在Samsung galaxy s3(Android 4.1.2)上沒有。 我在三星註冊時獲得了SERVICE_NOT_AVAILABLE。原來三星的時間已經到了。它沒有設置爲使用網絡時間自動更新。一旦我修好GCM就像魅力一樣。謝謝 - Umesh製作

12

對我來說 - 設備時間是不正確的。我改變了設備設置,使用「自動日期&時間」,再次嘗試,一切都很好。

乾杯

+2

與downvoters地獄,這也是我的情況是什麼問題。 –

3

對我來說有連接問題。更改Internet連接解決我的問題

+1

這也解決了我的問題。我認爲這是一個很好的暗示,當你看到'SERVICE_NOT_AVAILABLE'錯誤時,你應該確保你的網絡正常工作。 –

3

對於我來說,我已經通過檢查「限制後臺數據」在我的Galaxy S4數據使用量的選項打開的「背景數據訪問」谷歌的服務。只要我把它解決cellarer網絡上的問題。在無線上它工作正常。

+1

對我來說,問題是我沒有連接到本地WIFI。我知道這聽起來很愚蠢,但我想說的是網絡可能成爲問題。 –

3

在我的情況下,解決辦法是增加一個新的意向篩選器操作,註冊,到清單,每​​

<receiver 
     android:name=".RemoteNotificationReceiver" 
     android:permission="com.getset.getset.c2dm.permission.SEND" > 
     <intent-filter> 
      <action android:name="com.getset.getset.c2dm.intent.RECEIVE" /> 
      <action android:name="com.getset.getset.c2dm.intent.REGISTRATION" /> 
      <category android:name="com.getset.getset" /> 
     </intent-filter> 
    </receiver> 

我不得不承認,我很驚訝,這個作品,因爲它是從教程中遺漏,但是將它取出肯定會將成功的註冊ID變成異常。

注意:在使用Nexus 5的API 21(棒棒糖)仿真器。

+1

它在新文檔中列出了這個:https://developers.google.com/cloud-messaging/android/client – Almo

16

SERVICE_NOT_AVAILABLE是Google雲消息傳遞中最令人沮喪的問題之一。這是GoogleCloudMessaging.register(SENDER_ID)引發的異常,該函數調用爲設備註冊推送通知並返回註冊ID。

  1. SERVICE_NOT_AVAILABLE可能表示用戶的設備無法讀取註冊請求的響應或從服務器返回500/503錯誤代碼。開發人員無法修復此錯誤,因爲它處於Google的最終狀態,所以我們可以盲目地建議用戶在幾個小時內再試一次。
  2. 即使註冊成功,某些設備上也可能發生SERVICE_NOT_AVAILABLE。這可以通過在呼叫失敗時實施解決方法廣播接收器來捕獲令牌來解決。我實施了這個解決方法,它可能已經解決了一些用戶的問題,但我仍然收到很多其他的SERVICE_NOT_AVAILABLE投訴。
  3. SERVICE_NOT_AVAILABLE可能過期或丟失的谷歌Play服務庫設備上,因爲發生。在這種情況下,應用程序理論上可以通過打開相應的Google Play應用程序列表來通知用戶更新Google Play服務。但是,該應用並不知道這就是爲什麼SERVICE_NOT_AVAILABLE被拋出的原因,所以它不能盲目地將用戶重定向到Google Play上的Google Play服務應用頁面。
  4. 當設備的時鐘與網絡不同步時,可能會發生SERVICE_NOT_AVAILABLE。再次,開發人員無法知道這是確切的問題,所以我們可以盲目地建議用戶檢查他們的系統時鐘同步,希望他們是極少數時鐘不同步的人之一。
  5. 當有根用戶從設備中刪除環聊/ GTalk應用(因爲他們認爲它是英國媒體報道)時可能會發生SERVICE_NOT_AVAILABLE。 GCM由環聊/ GTalk實施和處理,因此無法在沒有GCM的情況下使用GCM。
  6. 如果用戶正在運行未安裝Google API的設備(如Amazon Kindle),則可能會發生SERVICE_NOT_AVAILABLE。這裏沒有什麼可做的,這些用戶永遠不會收到來自你的應用的推送通知。

瞭解更多: http://eladnava.com/google-cloud-messaging-extremely-unreliable/

這些單獨的問題就足以讓我開始尋找替代品GCM。我會每天或每兩天在我的應用程序上獲得一星評價,並在評論中包含引發SERVICE_NOT_AVAILABLE時顯示的錯誤消息。我無法幫助這些用戶,因爲他們中的大多數都是因爲他們無法控制的原因而收到的。

的替代谷歌雲端通訊

愛出風頭(https://pushy.me/)是一個獨立的推送通知網關,完全獨立GCM的。它像GCM一樣維護自己的後臺套接字連接,以接收推送通知。基礎協議是MQTT,它是一種極輕的pub/sub協議,利用很少的網絡帶寬和電池。

Pushy的一個巨大優勢是發送推送通知(從服務器)和註冊推送通知設備的代碼在GCM和Pushy之間實際上是可以互換的。這使得在實施GCM之後切換到Pushy非常容易,並且由於其不穩定性而不得不拋棄它。

(全面披露:我創辦了愛出風頭了我自己的項目,實現了許多應用程序會從這種服務中獲益)

+0

可以pushy.me告訴我什麼時候設備有一個活動連接到你的服務器,當它斷開連接。我只想發送推送到連接的設備。 – akshay202

+0

絕對!我們的設備信息API提供設備的最後活動設備狀態:https://pushy.me/docs/api/device –

0

我已經變成的「背景數據訪問」谷歌的服務。通過取消選中數據使用選項中的「限制後臺數據」它適用於我!

0

對我來說goolge封鎖了我的IP!我不得不重置我的DSL conn以從池中獲得新的IP,並且一切都恢復正常,idk爲什麼會阻止我,可能是因爲嘗試了很多應用程序?無論如何現在工作,我希望這可以幫助別人:)

2

對我來說,問題是電話沒有連接到互聯網。我斷開並連接到Wi-Fi,並測試了與瀏覽器的連接並再次測試。工作就像一個魅力:-)

0

對我來說,SERVICE_NOT_AVAILABLE問題是在我的應用程序項目中,因爲接收器類。 所以我解決了實現接收器後,如下所示。 <receiver android:name="receiver name" android:permission="com.google.android.c2dm.permission.SEND"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE"/> <action android:name="com.google.android.c2dm.intent.REGISTRATION"/> <category android:name="your package"/> </intent-filter> </receiver> 我希望能幫到你:-)。

-1

經過漫長的鬥爭,我設法解決了這個問題。 確保Google Play Services應用程序是最新的,並且您的手機上未禁用其後臺同步功能。

相關問題