Android GCM getToken()发送java.io.IOException:超时

Android GCM getToken()发送java.io.IOException:超时,android,google-cloud-messaging,Android,Google Cloud Messaging,我正在实现推送通知,但调用getToken时收到超时异常 我已经为GCM设置了应用程序,发送者ID正是提供的那个。此外,服务器API密钥保存在后端部分 getToken请求的数量是否有限?在测试推送通知的最初几次尝试中,我没有遇到任何问题 new AsyncTask<Void, Void, Void>(){ @Override protected Void doInBackground(Void... params) { tr

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

我已经为GCM设置了应用程序,发送者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();
newasynctask(){
@凌驾
受保护的Void doInBackground(Void…参数){
试一试{
InstanceID实例=InstanceID.getInstance(mContext);
String registrationId=instance.getToken(Constants.GCM\u SENDER\u ID,
GoogleCloudMessaging.INSTANCE_ID_SCOPE,null);
SharedReferences sp=mContext.getSharedReferences(Constants.TOKEN\u DATA,Context.MODE\u PRIVATE);
SharedReferences.Editor=sp.edit();
editor.putString(Constants.REGISTRATION\u ID,registrationId);
commit();
NotificationsRegister.getInstance(mContext.register(registrationId);
}捕获(IOE异常){
e、 printStackTrace();
}
返回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> 
...

...
添加到模块build.gradle的依赖项:

  • 应用插件:“com.google.gms.googleservices”
  • 编译'com.google.android.gms:play services gcm:7.5.+'
添加到项目build.gradle的依赖项:

  • classpath'com.google.gms:googleservices:1.3.0-beta1'

我今天遇到了这个问题,下面是我所做的故障排除

首先,我在尝试获取令牌时也使用了自己的发送者ID。因此,我尝试使用Google提供的示例中的发送者ID
getString(R.ID.gcm\u defaultSenderId)

一旦我这样做了,我开始收到一条不同的错误消息
SERVICE\u NOT\u AVAILABLE

有几个问题可以解决这个问题,但帮助我的是


我关闭了WiFi并在手机上使用了4G连接,它与gcm\U defaultSenderId和我自己的发件人ID一起工作。

我遇到了这个问题,重试后得到了修复

注册前,您必须检查google api是否可用于此代码片段或类似代码:

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

您可能没有收到SUCCESS resultCode。例如,如果有一个挂起的google api更新。

在注册之前,播放服务可能不可用,此类可能会帮助您:

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

您不需要在清单中使用INTERNET权限吗?我从一开始就拥有它,但在编辑清单时忘记添加它。我更新了声明,这可能是您的网络(可能是防火墙?)的问题,但查看整个堆栈跟踪会有所帮助。