Je reçois cette erreur du moniteur Android d'Android Studio. Cette erreur apparaît lorsque j'envoie une notification Push via GCM, dans un périphérique réel, et que l'application n'a pas encore été lancée ou qu'elle a été forcée de s'arrêter. Hier, tout fonctionne bien, aujourd'hui ne fonctionne pas du tout (fonctionne uniquement si l'application est exécutée en arrière-plan ou au premier plan).
Je pense que cela peut être une erreur AndroidManifest
, mais j'en ai marre de chercher le problème et je ne trouve rien.
Manifeste
<manifest
xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.flagg327.guicomaipu">
...
<application
Android:allowBackup="true"
Android:icon="@mipmap/ic_launcher"
Android:label="@string/app_name"
Android:supportsRtl="true"
Android:theme="@style/AppTheme">
...
<!--GOOGLE CLOUD MESSAGE-->
<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="Android.intent.action.BOOT_COMPLETED"/>
<action Android:name="com.google.Android.c2dm.intent.RECEIVE" />
<!-- for Gingerbread GSF backward compat -->
<action Android:name="com.google.Android.c2dm.intent.REGISTRATION" />
<category Android:name="com.flagg327.guicomaipu" />
</intent-filter>
</receiver>
<service
Android:name="com.flagg327.guicomaipu.gcm.RegistrationService"
Android:exported="false" />
<service
Android:name="com.flagg327.guicomaipu.gcm.TokenRefreshListenerService"
Android:exported="false">
<intent-filter>
<action
Android:name="com.google.Android.gms.iid.InstanceID" />
</intent-filter>
</service>
<service
Android:name="com.flagg327.guicomaipu.gcm.NotificacionsListenerService"
Android:exported="false" >
<intent-filter>
<action Android:name="com.google.Android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
</aplication>
<permission
Android:name="com.flagg327.guicomaipu.C2D_MESSAGE"
Android:protectionLevel="signature" />
<uses-permission Android:name="com.flagg327.guicomaipu.permission.C2D_MESSAGE" />
<uses-permission Android:name="com.google.Android.c2dm.permission.RECEIVE" />
<uses-permission Android:name="Android.permission.RECEIVE_BOOT_COMPLETED"/>
TokenRefreshListenerService.Java
Les «jetons d'inscription» sont mis à jour tous les jours. C’est parce que chaque application Android utilisant GCM doit disposer d’un InstanceIDListenerService qui gère ces mises à jour.
public class TokenRefreshListenerService extends InstanceIDListenerService{
@Override
public void onTokenRefresh() {
// Launch the registration process.
Intent i = new Intent(this, RegistrationService.class);
startService(i);
}
}
NotificacionsListenerService.Java
GCM affiche automatiquement les notifications Push, mais uniquement si l'application associée dispose d'un GCMListenerService
public class NotificacionsListenerService extends GcmListenerService {
@Override
public void onMessageReceived(String from, Bundle data) {
Log.d("A", "onMessageReceived()");
// Do something
}
}
RegistrationService.Java
GCM identifie les appareils Android à l'aide de cartes d'enregistrement («jetons»). Mon application doit pouvoir être enregistrée à partir de chaque appareil Android sur lequel elle est installée.
public class RegistrationService extends IntentService {
/**
* Constructor
*/
public RegistrationService() {
super("RegistrationService");
}
@Override
protected void onHandleIntent(Intent intent) {
// Generate or download the registration 'token'.
InstanceID myID = InstanceID.getInstance(this);
String registrationToken = null;
try {
// Get the registration 'token'.
registrationToken = myID.getToken(
getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE,
null
);
// Subscribe to a topic. The app is able now to receive notifications from this topic.
GcmPubSub subscription = GcmPubSub.getInstance(this);
subscription.subscribe(registrationToken, "/topics/guico_maipu_topic", null);
} catch (IOException e) {
e.printStackTrace();
}
Log.e("Registration Token", registrationToken);
}
}
Erreur
Cette erreur apparaît lorsque j'envoie une notification Push via python.
09-13 21:21:44.800 1851-1851/? W/GCM-DMM: broadcast intent callback: result=CANCELLED forIntent { act=com.google.Android.c2dm.intent.RECEIVE pkg=com.flagg327.guicomaipu (has extras) }
Hier travaillait ... Une idée? Merci pour votre temps.
J'ai eu la même erreur
09-13 21:21:44.800 1851-1851/? W/GCM-DMM: broadcast intent callback: result=CANCELLED forIntent { act=com.google.Android.c2dm.intent.RECEIVE pkg=com.XXX.XXX (has extras) }
après avoir tué l'application.
Après quelques recherches, j'ai réalisé qu'il ne s'agissait que d'un "problème de débogage". Un "APK signé" gère correctement la diffusion même si l'application a été fermée.
J'espère que ça aide!
Alors ... j'ai résolu le problème. Le problème était que le périphérique n'est pas enregistré pour recevoir GCM si l'application est fermée de force ou si l'application n'a jamais été ouverte depuis le démarrage du périphérique. La solution est simple: enregistrez le périphérique au démarrage du téléphone. Pour cela, j'ai implémenté une BroadcastReceiver
et commencé un enregistrement de processus à l'intérieur.
Les modifications:
Ajouté à AndroidManifest
<receiver Android:name="com.flagg327.guicomaipu.gcm.OnBootBroadcastReceiver">
<intent-filter >
<action Android:name="Android.intent.action.BOOT_COMPLETED" />
<category Android:name="Android.intent.category.HOME" />
</intent-filter>
</receiver>
OnBootBroadcastReceiver.Java
public class OnBootBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent("com.flagg327.guicomaipu.gcm.RegistrationService");
i.setClass(context, RegistrationService.class);
context.startService(i);
}
}
Ainsi, au démarrage, le périphérique s'enregistrera sur le serveur GCM et pourra recevoir toute notification Push de mon serveur. J'espère que cela est utile.
Après avoir compris pourquoi cela se produit, il semble que cela se produise si vous supprimez l'application depuis Android Studio.
Si vous ouvrez l'application depuis le lanceur et la balayez, votre application recevra toujours des notifications.
(Testé sur OnePlus One avec FCM et non GCM)
Étant donné qu'aucune des réponses ne fournit de lien officiel, j'ai décidé de demander à l'équipe de Firebase de me donner une réponse officielle.
Il semble que vous ayez un problème lorsque votre application est arrêtée de force ou tué. En fait, cela fonctionne comme prévu. Le framework Android indique que les applications qui ont été arrêtées (c'est-à-dire qui ont été tuées/arrêtées dans Paramètres) ne doivent pas être démarrées sans un utilisateur explicite interaction. La FCM suit cette recommandation et donc ses services ne commencera pas aussi bien. Cela signifie également que les messages ne seront pas reçu (FirebaseMessagingService ne sera pas appelé) lorsque l'application est en état "tué". Voici quelques liens utiles pour que vous puissiez avoir un meilleure compréhension sur ce sujet: https://developer.Android.com/about/versions/Android-3.1#launchcontrolshttps://github.com/firebase/quickstart-Android/issues/368#issuecomment-343567506
En somme:
REMARQUE: même la question concerne GCM, mais FCM renvoie exactement la même erreur dans le titre de la question.
Je faisais également face au problème. Lorsque je supprime une application de la pile, notification Push non reçue. Après de nombreux travaux sur Google, j'ai constaté que peu de téléphones avaient une fonction d'optimisation de la batterie, ce qui désactivait l'exécution en arrière-plan des applications. Lorsque j'active cette fonctionnalité, mon application peut également s'exécuter en arrière-plan. La notification push fonctionne bien. Seules quelques applications telles que What's application, etc. peuvent uniquement disposer de la fonctionnalité d'activation par défaut. Vous pouvez consulter cette URL ci-dessous.
En effet, votre application est optimisée pour l'utilisation de la batterie afin de la désactiver et de recevoir une notification même si votre application ne s'exécute pas en arrière-plan.
Ajouter cette autorisation à manifester
<uses-permission
Android:name="Android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
Lors du premier lancement de votre application, demandez à l'utilisateur l'autorisation d'ignorer cette application pour optimiser la batterie.
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent intent = new Intent();
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
}
}