Как узнать в BroadcastReceiver, если приложение работает на переднем плане?
Я работаю в приложении, которое нужно синхронизировать каждую ночь. Я использую Alarm Manager, который вызывает BroadcastReceiver в тот час, который я хочу. Проблема в том, что я не могу выполнить синхронизацию, если приложение работает на переднем плане, чтобы избежать потери данных. Поэтому мне нужно знать в Broadcast Receiver, если приложение работает на переднем плане, чтобы отменить эту синхронизацию.
Я пробовал решения, которые я нашел в StackOverflow:
Проверка наличия приложения Android в фоновом режиме
Но этот параметр всегда неверен в BroadcastReceiver, но действителен в действиях.
Может ли кто-нибудь сказать мне, в чем проблема? Что я делаю плохо?
На самом деле спасибо!
Ответы
Ответ 1
Попробуйте этот путь, надеюсь, что это сработает для вас.
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (isAppForground(context)) {
// App is in Foreground
} else {
// App is in Background
}
}
public boolean isAppForground(Context mContext) {
ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
if (!topActivity.getPackageName().equals(mContext.getPackageName())) {
return false;
}
}
return true;
}
}
Добавить это разрешение
<uses-permission android:name="android.permission.GET_TASKS" />
Ответ 2
Что значит "приложение работает на переднем плане"?
Если вы имеете в виду, что на экране отображается Activity
, то самым простым способом будет создание базового класса Activity
, который устанавливает глобальное логическое значение в вашем классе "Application".
Пользовательский Application
класс:
public class MyApp extends Application
{
public boolean isInForeground = false;
}
Пользовательский базовый класс Activity
:
abstract public class ABaseActivity extends Activity
{
@Override
protected void onResume()
{
super.onResume();
((MyApp)getApplication()).isInForeground = true;
}
@Override
protected void onPause()
{
super.onPause();
((MyApp)getApplication()).isInForeground = false;
}
}
Я предполагаю, что вы не синхронизировались с вашим BroadcastReceiver
- вместо этого вы должны запустить Service
для выполнения синхронизации. В противном случае система может убить ваше приложение - вы не должны выполнять какие-либо длительные задачи в BroadcastReceiver
.
Итак, перед запуском службы синхронизации проверьте приложение boolean, чтобы узнать, находится ли ваше приложение на переднем плане. В качестве альтернативы, переместите проверку внутри службы синхронизации, которая имеет то преимущество, что сделать BroadcastReceiver
еще проще (я всегда в пользу попыток сделать приемники как можно меньше логики).
Этот метод имеет те преимущества, которые он прост в использовании, понимании и не требует дополнительных разрешений.
Ответ 3
Этот метод сообщает вам, находится ли какая-либо из ваших действий в вашем приложении в настоящее время на переднем плане. Если вы проверите свой метод MyApplication.isActivityVisible() из широковещательного приемника, это должно работать нормально. Если он возвращает false, то maybes не показывает действия .
Ответ 4
в случае, если вы не хотите ничего делать, если приложение на переднем плане вы можете просто отключить приемник на вашем методе onStart:
ComponentName receiver = new ComponentName(context, MyReceiver.class);
context.getPackageManager().setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
и вы можете включить его методом onStop:
ComponentName receiver = new ComponentName(context, MyReceiver.class);
context.getPackageManager().setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
и если приемник выключен, к нему не будут подключены аварийные сигналы, и ваш код не будет выполнен