16

I have requirement of pushing in app notification to user based on following logic.

  • Type A notification will be shown after every 24 hours.
  • Type B notification will be shown after every 7 days.
  • Type C notification will be shown after every 15 days.

I have used PeriodicWorkRequest work manager as follows, it's working fine until the device is restarted. Once device is restarted, my work is NOT getting triggered.

build.gradle ---

implementation 'android.arch.work:work-runtime:1.0.0-alpha04'

Java code

PeriodicWorkRequest showNotification =
                new PeriodicWorkRequest.Builder(ShowNotificationWorkManager.class, interval,
                        TimeUnit.HOURS)
                        .addTag(notificationType)
                        .setInputData(myData)
                        .build();

getWorkManger().enqueue(showNotification);
IgorGanapolsky
  • 26,189
  • 23
  • 116
  • 147
Tanmay Talekar
  • 169
  • 1
  • 3
  • 3
    Did you got the answer.. If yes Please post it. I am also facing the Same issue – Suresh Sep 12 '18 at 05:23
  • @Suresh Did you find the solution? Please post the answer, as I am also facing the same issue – Pravinsingh Waghela Feb 07 '20 at 09:16
  • make sure your app is not being battery optimized, that seems to be turned on by default for all apps https://github.com/googlecodelabs/android-workmanager/issues/22#issuecomment-643811014 – lasec0203 Jun 14 '20 at 20:09

7 Answers7

9

I've tried this code & worked with me on old APIs and new ones: This code which executes the service (workmanager) every 15 min when the device reboots. for AndroidManifest.xml file:

<receiver android:name=".WorkManagerStartReceiver" >
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
</receiver>

And on WorkManagerStartReceiver class:

public class WorkManagerStartReceiver extends BroadcastReceiver {
    WorkManager mWorkManager;

    @Override
    public void onReceive(Context context, Intent intent) {

        PeriodicWorkRequest.Builder myWorkBuilder =
                new PeriodicWorkRequest.Builder(TestWorker.class,
                        PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS,
                        TimeUnit.MILLISECONDS);

        PeriodicWorkRequest myWork = myWorkBuilder.build();
        mWorkManager = WorkManager.getInstance(context);
        mWorkManager.enqueue(myWork);

    }
}

While TestWorker.class is the class that extends Worker:

public class TestWorker extends Worker {

    public TestWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {

        //your work that you want to execute here
        return null;
    }
}

And this snippet (on MainActivity) that opens when the app opens if you want the service to start working when the app opens.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    PeriodicWorkRequest.Builder myWorkBuilder =
            new PeriodicWorkRequest.Builder(TestWorker.class,
                                            PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS,
                                            TimeUnit.MILLISECONDS);
    PeriodicWorkRequest myWork = myWorkBuilder.build();
    WorkManager.getInstance(MainActivity.this)
            .enqueueUniquePeriodicWork("testworker", ExistingPeriodicWorkPolicy.KEEP, myWork);
}
Aziz
  • 461
  • 7
  • 18
  • 4
    `WorkManager` already requests **BOOT_COMPLETED** in the Manifest merger. You do not have to declare this intent yourself. – IgorGanapolsky Jun 08 '20 at 20:01
1

You called getWorkManger().enqueue(showNotification). Instead, you should enqueue periodic work because yours is a Periodic Operation:

workManager = WorkManager.getInstance(this)
workManager.enqueueUniquePeriodicWork(
   WORKER_NAME, ExistingPeriodicWorkPolicy.KEEP, workRequest
 )
IgorGanapolsky
  • 26,189
  • 23
  • 116
  • 147
0

I've tried this and works also for HTC phones.

<receiver android:name=".WorkManagerStartReceiver" android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
                <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
            </intent-filter>
</receiver>
sajad abbasi
  • 1,988
  • 2
  • 22
  • 43
0

Note: In some new versions of android, the boot complete intent is protected which means only the android system can either call or listen for it. Im currently experiencing this problem as I want to restart my service on boot complete. It throws a SecurityException .

Ben Gab
  • 11
  • 2
-1

Please add the following permission in your android manifest

   <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
minato
  • 2,028
  • 1
  • 18
  • 30
-1

if PeriodicWorkRequest is not working after device is rebooting, you can fix this issue by doing these steps.

Simply define a BroadcastReceiver and schedule your WorKManager in onReceive(-) method.

public class WorkManagerStartReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

    Constraints constraints = new Constraints.Builder()
            .setRequiresCharging(false)
            .build();

    PeriodicWorkRequest saveRequest =
            new PeriodicWorkRequest.Builder(ToastWorker.class, 15, TimeUnit.MINUTES)
                    .setConstraints(constraints)
                    .build();

    WorkManager.getInstance(context)
            .enqueue(saveRequest);
 } }

Now define your BroadcastReceiver in manifest.xml file

<application
   ----
       >
    <activity android:name=".MainActivity"/>

    <receiver android:name=".WorkManagerStartReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
        </intent-filter>
    </receiver>

</application>

Hey don't forget to add boot permission in your manifest file android.permission.RECEIVE_BOOT_COMPLETED

Ankit Dubey
  • 1,000
  • 1
  • 8
  • 12
  • 1
    ~"**WorkManager doesn't really works after device is rebooted.**" Said who? It absolutely works. – IgorGanapolsky Jun 08 '20 at 19:53
  • @IgorGanapolsky Might be, in your case, it worked. Don't you think no of votes to question. seems this is repeatedly occurring problem. Anyway, I'll check. It is also possible, Android people fixed this issue in newer version of WorkManager – Ankit Dubey Jun 09 '20 at 07:46
-2

Periodic work request can scheduled once when app is started first time on the device. We can use shared preference to identify whether the app is started first time or not. Moreover, in order to repeat the work after boot, we can start the work in a BroadcastReceiver which will be triggered after rebooting device.

M Shafaei N
  • 409
  • 3
  • 6