Передача данных из BroadcastReceiver в MainActivity работает правильно только один раз - PullRequest
0 голосов
/ 06 февраля 2011

У меня есть PushNotificationReceiver (extends BroadcastReceiver) и MainActivity. Получатель отправляет некоторые данные (например, строковое значение "New value") на MainActivity через Intent. Затем MainActivity обновляет свой TextView этим значением. Это работает нормально, пока я не изменю это значение TextView на какое-либо другое значение (например, сброслю его на "UNSPECIFIED") и переместлю упражнение на фон и снова на передний план. MainActivity восстановлен, и его TextView содержит "New value", однако я ожидал, что это будет "UNSPECIFIED" - , это проблема .

Что не так с моим приложением?

Весь прототип проекта можно скачать здесь .

Вот мой код MainActivity

private TextView tvValue;
private EditText etNewValue;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    tvValue = (TextView)findViewById(R.id.value);
    etNewValue = (EditText)findViewById(R.id.new_value);

    findViewById(R.id.reset).setOnClickListener(new OnClickListener() {         
        @Override
        public void onClick(View v) {
            tvValue.setText(getResources().getString(R.string.not_specified));
        }
    });

    findViewById(R.id.send_notification).setOnClickListener(new OnClickListener() {         
        @Override
        public void onClick(View v) {
            sendNotification(etNewValue.getText().toString());
        }
    });

    processDataFromBroadcast(getIntent());        
}

@Override
public void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    processDataFromBroadcast(intent);
}

private void sendNotification(String value){
    NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

    String title = "Proto App Notif";

    Notification notification = new Notification(
            android.R.drawable.ic_notification_overlay,
            title,
            System.currentTimeMillis());
    notification.flags |= Notification.FLAG_AUTO_CANCEL;

    Context ctxApp = getApplicationContext();

    Intent notificationIntent = new Intent()
        .setAction(PushNotificationReceiver.ACTION_NOTIFICATION)
        .putExtra("value", value);
    PendingIntent contentIntent = PendingIntent.getBroadcast(
            ctxApp, 
            0, 
            notificationIntent, 
            PendingIntent.FLAG_UPDATE_CURRENT);     

    notification.setLatestEventInfo(
            ctxApp,
            title,
            value,
            contentIntent);

    notification.audioStreamType = AudioManager.STREAM_NOTIFICATION;

    mNotificationManager.notify(1, notification);           
}

private void processDataFromBroadcast(Intent intent) {
    if (!intent.hasExtra("value")){
        return;
    }

    String val = intent.getStringExtra("value");

    tvValue.setText(val); // Updating my activity look
}

PushNotificationReceiver

private static final String LOG_CAT = "PushNotificationReceiver";
static final String ACTION_NOTIFICATION = "com.mobiwolf.proto.NOTIFICATION_RECEIVER";

@Override
public void onReceive(Context context, Intent intent) {
    if (!intent.getAction().equals(ACTION_NOTIFICATION)) {
        return;
    }

    String value = intent.getStringExtra("value");

    Log.d(LOG_CAT, "Received notification message: "+value); // Log always contains the value sent on first time

    Intent i = new Intent();
    i.setClass(context, MainActivity.class);
    i.putExtra("value", value);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    context.startActivity(i);
}

и манифест

    <receiver android:name="com.mobiwolf.proto.PushNotificationReceiver">
        <intent-filter>
            <action android:name="com.mobiwolf.proto.NOTIFICATION_RECEIVER" />
        </intent-filter>
    </receiver>    

    <activity android:name=".MainActivity"
              android:label="@string/app_name"
              android:launchMode="singleTask">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

Ответы [ 3 ]

1 голос
/ 09 марта 2011

Заменить

i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

от

i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | 
    Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
0 голосов
/ 11 мая 2012

Определите переменную public static boolean newUpdate;, установите ее на true прямо перед context.startActivity(i);.Затем, когда в вашем MainActivity вы проверяете, что у намерения есть extra с ним, также убедитесь, что newUpdate равно true, и если это так, сбросьте его на false и обновите поле TextView,Последняя функция будет выглядеть так:

private void processDataFromBroadcast(Intent intent) {
   if ( !intent.hasExtra("value") || (newUpdate == false) ){ //So only new updates are processed.
      return;
   }
   newUpdate = false; //This action will not be repeated unless another notification arrives
   String val = intent.getStringExtra("value");

   tvValue.setText(val); // Updating my activity look
}
0 голосов
/ 07 февраля 2011

Для решения этой проблемы я добавил глобальный статический триггер

  /**
  * This class triggers whether pushnotification was handled by MainActivity
  * (Preventing handling this push notification twice when the MainActivity 
  * is moved to background and restored from background
  */
  public final class PushNotifHandledTrigger {
private static boolean handled = true;

public static boolean wasHandled(){
    return handled;
}

public static void set(){
    handled = true;
}

public static void reset(){
    handled = false;
}
  }

Затем перед запуском startActivity я сбрасываю этот триггер и устанавливаю после обработки (и, конечно, выполняю обработку, только если триггер не установлен)

...