Как узнать в 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);

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