Khoa Nguyễn Khoa Nguyễn - 3 years ago 100
Java Question

GCM getToken() sends java.io.IOException: TIMEOUT on some devices

I am implementing push notifications, but I receive TIMEOUT exception when calling getToken.

This issue only happen on some devices as SC-03D (4.0).

Here's my IntentService which I use to register token:

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);
}
}

Answer Source

You need to try registering the token Using Exponential Back-Off

Following code might help you

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
            }
    }

For more information see this

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download