Application se bloque lorsqu'il reçoit le message de GCM la première fois, les messages suivants sont traités sans erreur.
-
12-12-2019 - |
Question
J'ai deux applications installées sur mon émulateur.L'application "Manager" envoie un message à GCM.L'autre application appelée "planificateur" reçoit le message et affiche une notification à l'utilisateur.
Lorsque j'ai les deux applications fonctionnant en même temps sur l'émulateur, l'application Manager fonctionne bien.Toutefois, l'application Planificateur se bloque après les processus généracodagcode GCMIntentService
, cela ne se produit que sur le premier message.Tous les messages restants sont traités sans que l'application se bloque.
Aucune erreur n'est imprimée dans le logcat.
questions
- y a-t-il une manipulation des exceptions pour GCminterService?
- Si l'application n'est pas visible et que GCminterService appelle une fonction pour ouvrir une activité.Peut-il cracer le programme?
- Si j'ai deux applications exécutées sur l'émulateur en même temps, cela pourrait-il poser problème avec l'émulateur?
Voici le code GCMintSerive:
/** * {@link IntentService} responsible for handling GCM messages. */ public class GCMIntentService extends GCMBaseIntentService { @SuppressWarnings("hiding") private static final String TAG = "GCMIntentService"; // Request code public static final int CUSTOM_REQUEST_CODE_ENTER_TEXT = 666; public GCMIntentService() { super(SENDER_ID); } @Override protected void onRegistered(Context context, String registrationId) { Log.i(TAG, "Device registered: " + "regId = " + registrationId); // displayMessage(context, getString(R.string.gcm_registered)); ServerUtilities.register(context, registrationId); displayError(context, "Device registered for Notifications from Anime Convention"); System.out.println("Device registered: " + "regId = " + registrationId); } @Override protected void onUnregistered(Context context, String registrationId) { Log.i(TAG, "Device unregistered"); // displayMessage(context, getString(R.string.gcm_unregistered)); if (GCMRegistrar.isRegisteredOnServer(context)) { ServerUtilities.unregister(context, registrationId); System.out.println("Device Unregistered: " + "regId = " + registrationId); } else { // This callback results from the call to unregister made on // ServerUtilities when the registration to the server failed. Log.i(TAG, "Ignoring unregister callback"); } } @Override protected void onMessage(Context context, Intent intent) { Log.i(TAG, "Received message"); //String message = getString(R.string.gcm_message); System.out.println("onMessage: "); Bundle extras = intent.getExtras(); String message =extras.getString("message"); String event_id_from_server =extras.getString("server_id"); // displayMessage(context, message); generateNotification(context, message); saveMsg(message); System.out.println("server id is "+ event_id_from_server); updateLocalDatabase(event_id_from_server); } @Override protected void onDeletedMessages(Context context, int total) { Log.i(TAG, "Received deleted messages notification"); String message = getString(R.string.gcm_deleted, total); // displayMessage(context, message); // notifies user generateNotification(context, message); } @Override public void onError(Context context, String errorId) { Log.i(TAG, "Received error: " + errorId); if(errorId.equals("ACCOUNT_MISSING")){ String error="Anime Convention Scheduler was unable to register your device for notifications. You need to add a GMAIL account to the phone inorder to use this service. Then use the Options Menu to register"; displayError(context, error); displayMessage(context, error); } // save using saved preferences than display. if(errorId.equals("SERVICE_NOT_AVAILABLE")){ String error="Google Cloud Messageing Service is not currently available"; displayError(context, error); } // save using saved preferences than display. if(errorId.equals("AUTHENTICATION_FAILED")){ String error="Google Cloud Messageing did not recognized your password. Please re-enter your password for your GMAIL account"; displayError(context, error); } // save using saved preferences than display. if(errorId.equals("PHONE_REGISTRATION_ERROR") || errorId.equals("INVALID_PARAMETERS")){ String error="Your phone does not support Google Cloud Messageing. You will not receive notifications from Anime Convention"; displayError(context, error); } } @Override protected boolean onRecoverableError(Context context, String errorId) { // log message Log.i(TAG, "Received recoverable error: " + errorId); // displayMessage(context, getString(R.string.gcm_recoverable_error, errorId)); return super.onRecoverableError(context, errorId); } /** * Issues a notification to inform the user that server has sent a message. */ private static void generateNotification(Context context, String message) { int icon = R.drawable.icon; long when = System.currentTimeMillis(); NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); Notification notification = new Notification(icon, message, when); String title = context.getString(R.string.app_name); Intent notificationIntent = new Intent(context, TabBarExample.class); // set intent so it does not start a new activity notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0); notification.setLatestEventInfo(context, title, message, intent); notification.flags |= Notification.FLAG_AUTO_CANCEL; notificationManager.notify(0, notification); } private String handleMessage(Intent intent) { String id = intent.toString(); String message = null; try { JSONObject json = new JSONObject(id); message = json.getString("message_id"); } catch (JSONException e) { e.printStackTrace(); } return message; } public void saveMsg(String msg) { boolean worked = true; try { NotificationsDatabase entry = new NotificationsDatabase(GCMIntentService.this); entry.open(); java.util.Date date= new java.util.Date(); Timestamp x = new Timestamp(date.getTime()); String timeStamp=x.toLocaleString(); entry.createEntry(msg,timeStamp); entry.close(); NoteAdapter note = null; note.notifyDataSetChanged(); NewsRowAdapter nra = null; nra.notifyDataSetChanged(); AlertAdapter aa=null; aa.notifyDataSetChanged(); } catch (Exception e) { worked = false; String error = e.toString(); System.out.println(error); } finally { if (worked) { } } } @Override public void onDestroy() { GCMRegistrar.onDestroy(GCMIntentService.this.getApplicationContext()); super.onDestroy(); } public void updateLocalDatabase(String serverId){ List<Alerts> listAlerts; int server_id=Integer.parseInt(serverId); DatabaseSqlite entry = new DatabaseSqlite (GCMIntentService.this); entry.open(); listAlerts = entry.getData(); entry.close(); int alerts=listAlerts.size(); for (int i = 0; i < alerts; i++) { Alerts item = listAlerts.get(i); int remote_id =item.getRemoteServerId(); String eventName=item.getEventName(); int local_id=item.getRowId(); if(server_id ==remote_id){ //update database with new info // Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag Intent intent = new Intent(GCMIntentService.this, UpdateLocalDatabase.class); intent.putExtra("server_id", server_id); intent.putExtra("local_id", local_id); intent.putExtra("event_name", eventName); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } } } }
La solution
Il y avait deux problèmes avec le code qui a créé ce problème.
-
Je n'avais pas de condition qui vérifiait si event_id_from_server était null ou vide dans l'application.
-
Lorsque vous envoyez un message à GCM, ils ne doivent pas être nuls ou "".Qui bloque le service. Donc, je devais créer cette condition dans le PHP pour les messages qui n'ont pas eu d'identifiant associé à eux:
si (! $ id || $ id=="") {
$fields = array( 'registration_ids' => $registrationIDs, 'data' => array("message" => $message), 'delay_while_idle'=> false, 'collapse_key'=>'core_update' ); }else{ $fields = array( 'registration_ids' => $registrationIDs, 'data' => array("message" => $message,"server_id"=>$id), 'delay_while_idle'=> false, 'collapse_key'=>'core_update' ); }