GCM getToken() 出现 java.io.IOException: TIMEOUT 错误

6

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

我已经为GCM设置了应用程序(在此处),SENDER_ID确切地是提供的那一个。此外,后端部分保存了服务器API密钥。

是否有getToken请求的限制?当测试推送通知时,最初几次尝试没有任何问题。

new AsyncTask<Void, Void, Void>(){

        @Override
        protected Void doInBackground(Void... params) {
            try {

                InstanceID instance = InstanceID.getInstance(mContext);

                String registrationId = instance.getToken(Constants.GCM_SENDER_ID,
                        GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

                SharedPreferences sp = mContext.getSharedPreferences(Constants.TOKEN_DATA, Context.MODE_PRIVATE);
                SharedPreferences.Editor editor = sp.edit();
                editor.putString(Constants.REGISTRATION_ID, registrationId);
                editor.commit();

                NotificationsRegister.getInstance(mContext).register(registrationId);
            } catch(IOException e) {
                e.printStackTrace();
            }

            return null;
        }
    }.execute();

Android清单文件:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myexample" >

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET"/>
<permission android:name="com.myexample.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
<uses-permission android:name="com.myexample.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

    <receiver
        android:name="com.google.android.gms.gcm.GcmReceiver"
        android:exported="true"
        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.myexample" />
        </intent-filter>
    </receiver>
    <service
        android:name=".helper.TutoriaGcmListenerService"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
    </service>
    <service
        android:name=".helper.TutoriaInstanceIDListenerService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.android.gms.iid.InstanceID"/>
        </intent-filter>
        </service> 
...

在Module的build.gradle中添加的依赖项:

  • 应用插件: 'com.google.gms.google-services'
  • 编译依赖项: 'com.google.android.gms:play-services-gcm:7.5.+'

在项目的build.gradle中添加的依赖项:

  • 类路径依赖项: 'com.google.gms:google-services:1.3.0-beta1'

你在清单文件中不需要INTERNET权限吗? - muratgu
我一开始就有这个,但当我编辑清单时忘记添加它。我更新了清单。 - blavi
可能是你的网络有问题(防火墙,也许?),但看到完整的堆栈跟踪会有所帮助。 - Koh
4个回答

3
我今天遇到了这个问题,以下是我用来排查的方法。
首先,当我尝试获取令牌时,也使用了自己的发件人ID。相反,我尝试使用Google提供的示例中的发件人ID getString(R.id.gcm_defaultSenderId) 这样做后,我开始收到一个不同的错误消息 SERVICE_NOT_AVAILABLE 有几个SO问题可以解决这个问题,但对我有帮助的是这一个
我关闭了WiFi并在手机上使用了4G连接,使用gcm_defaultSenderId和我的自己的发件人ID都可以工作。

2

在注册之前,您必须检查是否可以使用此代码片段或类似的代码来获取Google API:

GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
    int resultCode = apiAvailability.isGooglePlayServicesAvailable(a);
    if (resultCode == ConnectionResult.SUCCESS) { //Do the getTokencall  } else { //check the code }

可能是因为您没有收到成功的resultCode。例如,如果有一个Google API的待处理更新。


0

在注册之前,可能无法使用Play服务,这个类可以帮助你:

public class PlayServicesValidator {


private static final String TAG = PlayServicesValidator.class.getSimpleName();
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;


/**
 * Check the device to make sure it has the Google Play Services APK. If
 * it doesn't, display a dialog that allows users to download the APK from
 * the Google Play Store or enable it in the device's system settings.
 */
public static boolean areAvailable(Context context) {
    GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
    int resultCode = apiAvailability.isGooglePlayServicesAvailable(context);
    if (resultCode != ConnectionResult.SUCCESS) {
        return false;
    }
    return true;
}


/**
 * Only call if areAvailable was previously called and returned false
 * @param activity
 * @return
 */
public static boolean areRecoverable(Activity activity) {
    GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
    int resultCode = apiAvailability.isGooglePlayServicesAvailable(activity);
    if (resultCode != ConnectionResult.SUCCESS) {
        if (apiAvailability.isUserResolvableError(resultCode)) {
            return true;
        } else {
            return false;
        }
    }
    return true;
}


/**
 * Shows to the user a dialog to update play services
 * @param activity
 */
public static void recover(Activity activity) {
    GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
    int resultCode = apiAvailability.isGooglePlayServicesAvailable(activity);
    if (resultCode != ConnectionResult.SUCCESS) {
        if (apiAvailability.isUserResolvableError(resultCode)) {
            apiAvailability.getErrorDialog(activity, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST).show();
        }
    }
}
}

0

我曾经遇到过这个问题,后来再次尝试后解决了。


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