2016-01-28 44 views
2

我正在實現推送通知,但在調用getToken時收到TIMEOUT異常。GCM getToken()在某些設備上發送java.io.IOException:TIMEOUT

此問題僅在某些設備上發生,如SC-03D(4.0)。

這裏是我的IntentService我使用註冊標記:

public class RegistrationIntentService extends IntentService { 

private static final String TAG = "GCM"; 
public static final String TOKEN_ID = "registration_id"; 

/** 
* Constructor 
*/ 
public RegistrationIntentService() { 
    super(TAG); 
} 

@Override 
protected void onHandleIntent(Intent intent) { 
    try { 
     // In the (unlikely) event that multiple refresh operations occur simultaneously, ensure that they are processed sequentially. 
     synchronized (TAG) { 
      // Initially this call goes out to the network to retrieve the token, subsequent calls are local. 
      InstanceID instanceID = InstanceID.getInstance(this); 
      String gcm_sender_id = getString(R.string.gcm_sender_id); 
      String token = instanceID.getToken(gcm_sender_id, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); 
      String storageToken = PrefsHelper.getTokenId(this); 
      Log.d(TAG, "GCM Registration Token: " + token); 
     } 
    } catch (Exception e) { 
     Log.d(TAG, "Failed to complete token refresh", e); 
    } 
} 

回答

3

你需要嘗試註冊令牌使用指數回退

下面的代碼可以幫助你

public class RegistrationIntentService extends IntentService { 

    private static final String TAG = "GCM"; 
    public static final String TOKEN_ID = "registration_id"; 
    private final static int MAX_ATTEMPTS = 5; 
    private final static int BACKOFF_MILLI_SECONDS = 2000; 

    /** 
    * Constructor 
    */ 
    public RegistrationIntentService() { 
     super(TAG); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 

      // In the (unlikely) event that multiple refresh operations occur simultaneously, ensure that they are processed sequentially. 
      synchronized (TAG) { 
       Random random = new Random(); 
       String token = null; 
       InstanceID instanceID = InstanceID.getInstance(this); 
       long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000); 
       for (int i = 1; i <= MAX_ATTEMPTS; i++) { 
        try { 
         token = instanceID.getToken(getString(R.string.gcm_sender_id);, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); 
         if(null != token && !token.isEmpty()) { 
          break; 
         } 
        } catch (IOException e) { 
         //Log exception 
        } 
        if (i == MAX_ATTEMPTS) { 
          break; 
         } 
         try { 
          Thread.sleep(backoff); 
         } catch (InterruptedException e1) { 
          break; 
         } 
        // increase backoff exponentially 
        backoff *= 2; 
       } 
       // further processing for token goes here 
      } 
    } 

對於更多信息see this

+0

非常感謝@Ayaanp。我會嘗試與您的解決方案:) –

+0

嗨@Ayaanp,超時錯誤仍然發生與您的解決方案。 –

+0

你的意思是說你根本沒有收到註冊令牌?或者在一次或兩次嘗試後得到一個? – Ayaanp

1

上一篇解決方案几乎正確;如果你確實得到了令牌,那麼缺失的部分實際上是打破了重試:

for (int i = 1; i <= MAX_ATTEMPTS; i++) { 

      try{ 

       _token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); 


       if (!(_token == null || _token.isEmpty())) { 
        break; 
       } 
      } 
      catch (IOException e){ 

       Log.d(TAG, "Couldn't get token; waiting "+String.valueOf(backoff) + "ms"); 

       if (i == MAX_ATTEMPTS) { 
        break; 
       } 

       try { 
        Thread.sleep(backoff); 
       } 
       catch (InterruptedException e1) { 
        break; 
       } 

      } 

      backoff *= 2; 

     } 

     if(_token == null){ 

      //Couldn't get the token!!! 
     }