javaandroidbackground-servicetimertaskforeground-service

Timer task with foreground service


I'm doing a timer task in main thread and I'm updating my ui every 15 seconds there. I'm also running another timer task in a foreground service (when the user turns it on. it is aimed for background operations like back up data) containing a notification which makes the timer task code to contiue running even when the app is closed. Is there anyway I could have the foreground service but stop that timer task.

I've already done something like this but it didn't work since it says the user is on screen because of that notification:

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = pm.isInteractive();
if(!isScreenOn){
    MainActivity.timer.cancel();
    MainActivity.timer.purge();
 }

Solution

  • You can do it with BroadcastReceiver.

    here is some setting use BroadcastReceiver.

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.myapp">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <!-- Other components -->
    
            <receiver
                android:name=".ScreenStateReceiver"
                android:enabled="true"
                android:exported="true">
                <intent-filter>
                    <action android:name="android.intent.action.SCREEN_OFF" />
                    <action android:name="android.intent.action.SCREEN_ON" />
                </intent-filter>
            </receiver>
        </application>
    
    </manifest>
    

    Add this permission to manifest

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

    ScreenStateReceiver.java file

    public class ScreenStateReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
                MainActivity.stopTimerTask();
            } else if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
                MainActivity.startTimerTaskIfNecessary();
            }
        }
    }
    
    // In your MainActivity
    public static void startTimerTaskIfNecessary() {
        if (timer == null) {
            timer = new Timer();
            // Schedule your task here
        }
    }
    
    public static void stopTimerTask() {
        if (timer != null) {
            timer.cancel();
            timer.purge();
            timer = null;
        }
    }
    

    MainActivity.java

    public class MainActivity extends AppCompatActivity {
        private ScreenStateReceiver screenStateReceiver;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            if (screenStateReceiver == null) {
                screenStateReceiver = new ScreenStateReceiver();
                IntentFilter filter = new IntentFilter();
                filter.addAction(Intent.ACTION_SCREEN_OFF);
                filter.addAction(Intent.ACTION_SCREEN_ON);
                registerReceiver(screenStateReceiver, filter);
            }
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            if (screenStateReceiver != null) {
                unregisterReceiver(screenStateReceiver);
                screenStateReceiver = null;
            }
        }
    }