java - GCM getToken() 发送 java.io.IOException : TIMEOUT on some devices

标签 java android google-cloud-messaging

我正在实现推送通知,但在调用 getToken 时收到 TIMEOUT 异常。

此问题仅发生在某些设备上,如 SC-03D (4.0)。

这是我用来注册 token 的 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);
    }
}

最佳答案

您需要尝试使用指数回退来注册 token

下面的代码可能对你有帮助

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

关于java - GCM getToken() 发送 java.io.IOException : TIMEOUT on some devices,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35051864/

相关文章:

java - 从通过java连接到同一路由器的另一台计算机访问SQL服务器数据库?

java - 使用 JSOUP 库在 Java 中读取 <br>、<ul>、<li>、<p> 等标签时如何保留它们的含义?

android - SharedPreferences.getInt ("cumulative", 0) catch 22 - 如何解决?

google-cloud-messaging - 设备订阅已过期 - 修复

java - Android 2.1 的 Android Base64 解码

java - 在圆形 JLabel 图像周围创建可点击区域

android - 信标的广告率是否会影响检测器应用程序的电池

android - 现在 SSLSocketFactory 在 Android 上已被弃用,处理客户端证书身份验证的最佳方法是什么?

java - MyGCMListenerService 中要写什么?

android - GCM : How do you subscribe a device to a topic?