Как передать данные из BroadcastReceiver в начатое действие?

у меня есть приложение для Android, которое нужно будить спорадически в течение дня.

для этого я использую AlarmManager для настройки PendingIntent и имею этот триггер BroadcastReceiver. Затем этот BroadcastReceiver запускает действие, чтобы вывести пользовательский интерфейс на передний план.

все вышеперечисленное, похоже, работает, поскольку активность запускается правильно; но я хотел бы, чтобы BroadcastReceiver уведомил активность, что она была запущена сигналом тревоги (в отличие от запуска пользователем). Для этого я пытаюсь из метода onReceive () BroadcastReceiver установить переменную в пакете extras намерения, таким образом:

    Intent i = new Intent(context, MyActivity.class);
    i.putExtra(wakeupKey, true);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(i);

в методе onResume () моей деятельности я затем ищу существование этой булевой переменной:

protected void onResume() {
    super.onResume();

    String wakeupKey = "blah";      
    if (getIntent()!=null && getIntent().getExtras()!=null)
        Log.d("app", "onResume at " + System.currentTimeMillis() + ":" + getIntent().getExtras().getBoolean(wakeupKey));
    else
        Log.d("app", "onResume at " + System.currentTimeMillis() + ": null");
}

getIntent ().getExtras() вызов onResume () всегда возвращает null - я, похоже, не в состоянии передать какие-либо дополнительные функции в этом пакете.

Если я использую тот же метод привязки экстр к PendingIntent, который запускает BroadcastReceiver однако, экстры проходят просто отлично.

может ли кто-нибудь сказать мне, что отличается от передачи пакета из BroadcastReceiver в Activity, в отличие от передачи пакета из Activity в BroadcastReceiver? Боюсь, я делаю что-то очень, очень неправильное...

5 ответов


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

в классе обслуживания, который расширяет BroadcastReceiver. Введите следующий код в onReceive()

Intent intent2open = new Intent(context, YourActivity.class);
intent2open.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent2open.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
String name = "KEY";
String value = "String you want to pass";
intent2open.putExtra(name, value);
context.startActivity(intent2open);

на FLAG_ACTIVITY_SINGLE_TOP убедитесь, что приложения не открываются повторно, если они уже открыты. Это означает, что" старое " намерение, которое открыло вашу активность в первую очередь, повторно используется и не будет содержать дополнительных значений. Вы должны поймать их в другом методе под названием onNewIntent() in YourActivity.

public class YourActivity extends Activity {
    private String memberFieldString;

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

         // Code doing your thing...
    } // End of onCreate()

    @Override
    protected void onNewIntent(Intent intent) {
    Log.d("YourActivity", "onNewIntent is called!");

    memberFieldString = intent.getStringExtra("KEY");

    super.onNewIntent(intent);
} // End of onNewIntent(Intent intent)

    @Override
    protected void onResume() {
        if (memberFieldString != null) {
            if (opstartsIntent.getStringExtra(KEY) != null) {
               Log.d("YourActivity", "memberFieldString: "+ memberFieldString);
            } else {
               Log.d("YourActivity", "The intent that started YourActivity did not have an extra string value");
            }
        }
    } // End of onResume()

}  // End of YourActivity

обратите внимание на два заявления if -onResume() не знает, называется ли он после OnCreate()->OnStart() OR onRestart()->onStart()
смотрите: http://www.anddev.org/images/android/activity_lifecycle.png

он просто используется для тестирования, если приложение запускается пользователем (намерение без дополнительных услуг) или BroadcastReceiver (намерение с дополнительными функциями).


этот BroadcastReceiver затем начинает Деятельности для приведения интерфейса к передний план.

это может быть суть вашей проблемы здесь. Попробуйте переопределить onNewIntent() и, видя, если Intent перешло к нему дополнительные. Если это так, то это из-за способа настройки действия в манифесте (например, вы используете singleTop) и то, что в данном конкретном случае активность уже существовала.

вы также можете рассмотреть возможность избавиться от i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); и посмотреть, если это меняет дела.

в результате то , что вы делаете-положить дополнительный в Intent на startActivity() -- должно работать просто отлично. На самом деле, вы можете увидеть примеры, что здесь. Это говорит о том, что это что-то фанк о деятельности (например,singleTop) или способ вызова действия (например,FLAG_ACTIVITY_NEW_TASK).

EDIT:

так как мои первые выстрелы не сработали, и учитывая ваш" любопытный " комментарий выше...

это немного похоже на PendingIntent -- С ними, если вы не предпримете шаги, вы не сможете обновлять дополнительные услуги.

по прихоти, попробуйте добавить второй <intent-filter> к вашей деятельности в манифесте, только на какой-то уникальной строке действия, и попробуйте начать свою деятельность с вашего приемника, используя это. Или просто бросьте строку действия в свой Intent что приемник использует для startActivity(), не возясь с манифестом.


вместо getIntent().getExtras().getBoolean(wakeupKey) более традиционно писать getIntent().getBooleanExtra(wakeupKey, defaultValue). Я не могу быть уверен, связано ли это с вашей проблемой, но есть некоторые вещи, связанные с созданием пакета внутри getExtras (), в котором я не уверен, поэтому в любом случае стоит попробовать.


установить флаг SingleTop работает (не смешивайтесь с другими флагами)

Intent intent = new Intent(ContextManager.getContext(),OrderList.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Bundle bundle = new Bundle();       

bundle.putString("username",username);
bundle.putString("password",password);

intent.putExtras(bundle);
startActivityForResult(intent,0); 

просто переопределите onNewIntent, как это, и пакет var будет доступен в методе onresume:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
}