La aplicación se bloquea cuando se recibe el mensaje de GCM primera vez, el que se Procesan los Mensajes sin errores

StackOverflow https://stackoverflow.com//questions/12684361

Pregunta

Tengo dos aplicaciones instaladas en mi emulador.El "manager" de la aplicación envía un mensaje a GCM.La otra aplicación llamada "programador" recibe el mensaje y muestra una notificación al usuario.

Cuando tengo dos aplicaciones al mismo tiempo en el emulador, el administrador de app funciona bien.Sin embargo, el programador de la aplicación se bloquea después de GCMIntentService los procesos de onMessage(); Esto sólo sucede en el primer mensaje.Todos los demás mensajes son procesados sin el bloqueo de aplicación.

No hay errores impresos en el logcat.

Preguntas

  1. Hay excepciones para GCMIntentService?
  2. Si la aplicación no es visible y GCMIntentService llama a una función para abrir una Actividad.Puede que se bloquee el programa?
  3. Si tengo dos aplicaciones que se están ejecutando en el emulador, al mismo tiempo, podría ser un problema con el emulador?

Aquí está el GCMIntentSerive código:

/**
 * {@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);
            }
        }                   
    }
}
¿Fue útil?

Solución

Había dos problemas con el código que ha creado este problema.

  1. Yo no tenía una condición que se comprueba si event_id_from_server fue nulo o vacío en la aplicación.

  2. Cuando envía un Mensaje a GCM, que no debe ser null o "".Que se bloquea el servicio.Así que necesitaba para crear esta condición en el php para los mensajes que no tienen un id asociado con ellos:

    if(!$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'
    );
    
    }
    
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top