Как передать данные из 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);
}