GCM getToken () envía java.io.IOException: TIMEOUT
Estoy implementando notificaciones push, pero recibo una excepción TIMEOUT al llamar a getToken.
He configurado la aplicación para GCM aquí y SENDER_ID es exactamente la proporcionada. Además, la clave de API de servidor se guardó en la parte de fondo.
- Visualización de emojis en el contenido de la notificación
- Los mensajes GCM de Android tardan demasiado en llegar
- ¿Cómo implementar múltiples notificaciones push de GCM en una sola aplicación?
- ¿Hay alguna manera de usar GCM en Android sin un servidor dedicado?
- Notificación de empuje abierta Actividad con la misma intención
¿Hay un número limitado de peticiones getToken? No tuve problemas al principio varios intentos al probar notificaciones push.
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();
Manifiesto de 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> ...
Dependencias agregadas al módulo build.gradle:
- Aplique el complemento: 'com.google.gms.google-services'
- Compile 'com.google.android.gms: play-services-gcm: 7.5.' +
Dependencias agregadas al build.gradle del proyecto:
- Classpath 'com.google.gms: google-services: 1.3.0-beta1'
- Consejos sobre GCM unregister
- ¿Cuáles son las razones por las que el ID de GCM no está disponible en algunos casos en android
- ID de registro GCM de Android longitud máxima
- ¿Por qué es necesario iniciar sesión en Google para que GCM funcione para dispositivos inferiores a 4.0.4?
- ¿Por qué la aplicación de mensajería recibe mensajes cuando se detiene la aplicación?
- Error de ACCOUNT_MISSING de GCM
- Mensajería en la nube de Google, incapaz de inicializar el receptor
- BroadcastReceiver no se llama cuando la pantalla está bloqueada en Android
Me encontré con este problema hoy y he aquí lo que hice para solucionar problemas.
En primer lugar, también estaba usando mi propio ID de remitente al intentar obtener el token. Así que en su lugar, intenté usar el ID del remitente de los ejemplos que Google proporciona getString(R.id.gcm_defaultSenderId)
Una vez que lo hice, empecé a recibir un mensaje de error diferente SERVICE_NOT_AVAILABLE
Hay varias preguntas de SO que abordar esto, pero el que me ayudó fue este .
gcm_defaultSenderId
WiFi y usé una conexión 4G en mi teléfono y funcionó con el gcm_defaultSenderId
y mi propio ID de remitente.
Antes del registro debe comprobar si google api está disponible con este fragmento de código o similar:
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance(); int resultCode = apiAvailability.isGooglePlayServicesAvailable(a); if (resultCode == ConnectionResult.SUCCESS) { //Do the getTokencall } else { //check the code }
Probablemente no estás recibiendo el código de resultado SUCCESS. Por ejemplo, si hay una actualización pendiente de google api.
Tuve este problema y me arreglaron después de intentarlo de nuevo.
Es posible que Play Services no esté disponible antes de registrarse, esta clase puede ayudarle:
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(); } } } }
- No se puede destruir el error de actividad
- Implementar ListView expandible con adaptador personalizado