【问题标题】:Application crashes when it receives message from GCM the first time, Subsequent Messages are Processed with no errors应用程序在第一次收到来自 GCM 的消息时崩溃,后续消息被处理且没有错误
【发布时间】:2012-10-02 04:02:02
【问题描述】:

我的模拟器上安装了两个应用程序。 “经理”应用程序向 GCM 发送消息。另一个名为“调度程序”的应用程序接收消息并向用户显示通知。

当我在模拟器上同时运行两个应用程序时,管理器应用程序运行良好。但是,调度程序应用程序在GCMIntentService 处理onMessage(); 后崩溃,这只发生在第一条消息上。所有剩余的消息都会在应用程序不崩溃的情况下得到处理。

logcat 中不会打印出任何错误。

问题

  1. GCMIntentService 是否有异常处理?
  2. 如果应用程序不可见并且 GCMIntentService 调用一个函数来打开一个 Activity。这会使程序崩溃吗?
  3. 如果我有两个应用同时在模拟器上运行,会不会是模拟器有问题?

这是 GCMIntentServe 代码:

/**
 * {@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);
            }
        }                   
    }
}

【问题讨论】:

    标签: android android-intent google-cloud-messaging


    【解决方案1】:

    导致此问题的代码存在两个问题。

    1. 我没有检查应用程序中的 event_id_from_server 是否为空或为空的条件。

    2. 当您向 GCM 发送消息时,它们不能为 null 或“”。这会使服务崩溃。 所以我需要在 php 中为没有关联 id 的消息创建这个条件:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-15
      • 1970-01-01
      • 2020-06-09
      • 2015-12-17
      • 1970-01-01
      • 1970-01-01
      • 2016-08-13
      相关资源
      最近更新 更多