Question

I am working in application that needs make a synchronization every night. I use Alarm Manager that calls a BroadcastReceiver at the hour that I want. The problem is that I cant make a synchronization if the application is running in foreground to avoid losing data. So I need to know in Broadcast Receiver if the app is running in foreground to cancel this synchronization.

I tried solutions that I found in StackOverflow: Checking if an Android application is running in the background But this parameter is always false in BroadcastReceiver, but true in activites.

Can anyone tell me which is the problem? What am I doing bad?

Really thanks!

Was it helpful?

Solution

Try this way hope this works for you

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;
    }

}

Add this permission

<uses-permission android:name="android.permission.GET_TASKS" />

OTHER TIPS

What do you mean by "the application is running in foreground"?

If you mean there is an Activity currently displayed on the screen, then the easiest way would be to make a base Activity class that sets a global boolean in your `Application' class.

Custom Application class:

public class MyApp extends Application
{
    public boolean isInForeground = false;
}

Custom base Activity class:

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;
    }
}

I assume you are not synchronising from your BroadcastReceiver - you should instead be launching a Service to do the synchronisation. Otherwise the system might kill your app - you must not be doing any long-running tasks in a BroadcastReceiver.

So before you launch your sync service, check the application boolean to see if your app is "in foreground". Alternatively, move the check inside the sync service, which has the advantage of making the BroadcastReceiver even simpler (I am always in favour of trying to make the receivers have as little logic as possible).


This method has the advantages that it is simple to use, understand, and requires no extra permissions.

in case you don't want to do anything if app in foreground you could simply turn off the receiver on your activity onStart method:

ComponentName receiver = new ComponentName(context, MyReceiver.class);
context.getPackageManager().setComponentEnabledSetting(receiver,
        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
        PackageManager.DONT_KILL_APP);

and you could turn it on onStop method:

ComponentName receiver = new ComponentName(context, MyReceiver.class);
context.getPackageManager().setComponentEnabledSetting(receiver,
        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
        PackageManager.DONT_KILL_APP);

and if receiver is turned off, no alarms will come to it, and your code will not be executed

That method tells you whether any of your activities in your app are currently in the foreground. If you check your MyApplication.isActivityVisible() method from the broadcast receiver, then that should work fine. If its returning false, then maybes no activities are showing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top