GCM getToken() 在某些设备上发送 java.io.IOException: TIMEOUT。

3

我正在实现推送通知功能,但在调用 getToken 时出现 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);
    }
}
2个回答

4

您需要尝试使用指数退避注册令牌

以下代码可能对您有所帮助

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

了解更多信息,请查看此链接


嗨@Ayaanp,使用你的解决方案仍然出现了超时错误。 - Khoa Nguyễn
你的意思是你根本没有收到注册令牌吗?还是在一两次尝试后才收到一个? - Ayaanp
是的,我根本没有收到注册令牌。超时错误总是在尝试次数从1->5的情况下发生。 - Khoa Nguyễn
你能添加日志跟踪吗? - Ayaanp
嗨,请检查文件 https://www.dropbox.com/s/5liha9dzuvdxyd5/log%20%281%29?dl=0 - Khoa Nguyễn
显示剩余7条评论

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接