Cannot do work in background periodically with alarmmanager












4















I want to call a service in background by the hour.



first problem is alarm manager is not working smoothly. Timer is terrible, sometimes early sometimes later.



second problem is, RemoteServiceException : Context.startForegroundService() did not then call Service.startForeground() , I cant understand why I get this exception



MainActivity



public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {

Intent intent1 = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) MainActivity.this.getSystemService(MainActivity.this.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 60 * 60 * 1000L, pendingIntent);
}
}


AlarmReceiver



public class AlarmReceiver extends BroadcastReceiver {

@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onReceive(Context context, Intent intent) {

Intent downloadService = new Intent(context, CallService.class);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(downloadService);
} else {
context.startService(downloadService);
}

}

}


CallService



public class CallService extends IntentService {

public CallService() {
super("");
}

public CallService(String name) {
super(name);
}

@Override
protected void onHandleIntent(Intent workIntent) {
Log.d("Now : ", Calendar.getInstance().getTime().toString());



}
}


Manifest



 <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">

<receiver android:name=".AlarmReceiver"/>

<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<service
android:name=".CallService"
android:exported="false"/>


Sorry for my terrible english. Thanks for any help or suggestion.
I dont know how can I do different way. I just only call a service periodically










share|improve this question

























  • Try job dispatcher or job schedule instead of alarmmanager. github.com/firebase/firebase-jobdispatcher-android . OR developer.android.com/topic/performance/scheduling

    – Akash Patel
    Jan 4 at 12:23
















4















I want to call a service in background by the hour.



first problem is alarm manager is not working smoothly. Timer is terrible, sometimes early sometimes later.



second problem is, RemoteServiceException : Context.startForegroundService() did not then call Service.startForeground() , I cant understand why I get this exception



MainActivity



public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {

Intent intent1 = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) MainActivity.this.getSystemService(MainActivity.this.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 60 * 60 * 1000L, pendingIntent);
}
}


AlarmReceiver



public class AlarmReceiver extends BroadcastReceiver {

@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onReceive(Context context, Intent intent) {

Intent downloadService = new Intent(context, CallService.class);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(downloadService);
} else {
context.startService(downloadService);
}

}

}


CallService



public class CallService extends IntentService {

public CallService() {
super("");
}

public CallService(String name) {
super(name);
}

@Override
protected void onHandleIntent(Intent workIntent) {
Log.d("Now : ", Calendar.getInstance().getTime().toString());



}
}


Manifest



 <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">

<receiver android:name=".AlarmReceiver"/>

<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<service
android:name=".CallService"
android:exported="false"/>


Sorry for my terrible english. Thanks for any help or suggestion.
I dont know how can I do different way. I just only call a service periodically










share|improve this question

























  • Try job dispatcher or job schedule instead of alarmmanager. github.com/firebase/firebase-jobdispatcher-android . OR developer.android.com/topic/performance/scheduling

    – Akash Patel
    Jan 4 at 12:23














4












4








4








I want to call a service in background by the hour.



first problem is alarm manager is not working smoothly. Timer is terrible, sometimes early sometimes later.



second problem is, RemoteServiceException : Context.startForegroundService() did not then call Service.startForeground() , I cant understand why I get this exception



MainActivity



public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {

Intent intent1 = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) MainActivity.this.getSystemService(MainActivity.this.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 60 * 60 * 1000L, pendingIntent);
}
}


AlarmReceiver



public class AlarmReceiver extends BroadcastReceiver {

@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onReceive(Context context, Intent intent) {

Intent downloadService = new Intent(context, CallService.class);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(downloadService);
} else {
context.startService(downloadService);
}

}

}


CallService



public class CallService extends IntentService {

public CallService() {
super("");
}

public CallService(String name) {
super(name);
}

@Override
protected void onHandleIntent(Intent workIntent) {
Log.d("Now : ", Calendar.getInstance().getTime().toString());



}
}


Manifest



 <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">

<receiver android:name=".AlarmReceiver"/>

<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<service
android:name=".CallService"
android:exported="false"/>


Sorry for my terrible english. Thanks for any help or suggestion.
I dont know how can I do different way. I just only call a service periodically










share|improve this question
















I want to call a service in background by the hour.



first problem is alarm manager is not working smoothly. Timer is terrible, sometimes early sometimes later.



second problem is, RemoteServiceException : Context.startForegroundService() did not then call Service.startForeground() , I cant understand why I get this exception



MainActivity



public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {

Intent intent1 = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) MainActivity.this.getSystemService(MainActivity.this.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 60 * 60 * 1000L, pendingIntent);
}
}


AlarmReceiver



public class AlarmReceiver extends BroadcastReceiver {

@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onReceive(Context context, Intent intent) {

Intent downloadService = new Intent(context, CallService.class);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(downloadService);
} else {
context.startService(downloadService);
}

}

}


CallService



public class CallService extends IntentService {

public CallService() {
super("");
}

public CallService(String name) {
super(name);
}

@Override
protected void onHandleIntent(Intent workIntent) {
Log.d("Now : ", Calendar.getInstance().getTime().toString());



}
}


Manifest



 <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">

<receiver android:name=".AlarmReceiver"/>

<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<service
android:name=".CallService"
android:exported="false"/>


Sorry for my terrible english. Thanks for any help or suggestion.
I dont know how can I do different way. I just only call a service periodically







android broadcastreceiver alarmmanager android-intentservice






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 4 at 7:52









6155031

997929




997929










asked Jan 2 at 13:31









heraldherald

214




214













  • Try job dispatcher or job schedule instead of alarmmanager. github.com/firebase/firebase-jobdispatcher-android . OR developer.android.com/topic/performance/scheduling

    – Akash Patel
    Jan 4 at 12:23



















  • Try job dispatcher or job schedule instead of alarmmanager. github.com/firebase/firebase-jobdispatcher-android . OR developer.android.com/topic/performance/scheduling

    – Akash Patel
    Jan 4 at 12:23

















Try job dispatcher or job schedule instead of alarmmanager. github.com/firebase/firebase-jobdispatcher-android . OR developer.android.com/topic/performance/scheduling

– Akash Patel
Jan 4 at 12:23





Try job dispatcher or job schedule instead of alarmmanager. github.com/firebase/firebase-jobdispatcher-android . OR developer.android.com/topic/performance/scheduling

– Akash Patel
Jan 4 at 12:23












2 Answers
2






active

oldest

votes


















0














I had same problem with alarm manager.
You can switch to Interval of RxJava.



protected fun startCountdown(period: Long, timeUnit: TimeUnit): Observable<Long> {
return Observable.interval(period, timeUnit)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
}


usage;



startCountdown(MEDIA_LOCATION_CHANGE_PERIOD, TimeUnit.MILLISECONDS)
.subscribe {
fireSomethingUp()
}





share|improve this answer
























  • After termination of application, your rxjava will not be executed. AlarmManager and rxjava interval tottaly different things, that can't be compared.

    – HeyAlex
    Jan 4 at 13:55











  • @HeyAlex You have a point. I thought he has Service and will call rest from this Service.

    – Murat VAROL
    Jan 7 at 12:06



















0














AlarmManager will be works normally on api 27 (oreo 8.1) and less. Just setup with something like that:



public void setupAlarm(Context context, long triggerAtMillis) {
PendingIntent pendingIntent = getPendingIntent(context);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
alarmManager.set(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
} else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
} else {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
}
}


Don't forget that you need to setup your alarm again every time when your AlarmReceiver triggered. But that code will not be working on api 28 and more (pie 9.0). This is happening because of Power management feature introduced in Android Pie. Strict restrictions are introduced on the apps running in background. These restrictions are explained here. Try to use JobScheculer to invoke your foreground IntentService.



As about your second question. You need to make a notification in your CallService. Just add this onCreate to your IntentService:



@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel chan = new NotificationChannel("test", "your_channel_name", NotificationManager.IMPORTANCE_NONE);
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (manager != null) {
manager.createNotificationChannel(chan);
}

Notification.Builder notificationBuilder = new Notification.Builder(context, "test");
notificationBuilder.setOngoing(true);
notificationBuilder.setContentTitle("Updatig")
.setContentText("Wait for finish updating")
startForeground(NOTIFICATION_ID, notificationBuilder.build());
}
}


RemoteServiceException will be thrown if you will not call startForeground in service (you have 5 seconds to make this call) after startForegroundService.






share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54007289%2fcannot-do-work-in-background-periodically-with-alarmmanager%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    I had same problem with alarm manager.
    You can switch to Interval of RxJava.



    protected fun startCountdown(period: Long, timeUnit: TimeUnit): Observable<Long> {
    return Observable.interval(period, timeUnit)
    .subscribeOn(Schedulers.io())
    .observeOn(Schedulers.io())
    }


    usage;



    startCountdown(MEDIA_LOCATION_CHANGE_PERIOD, TimeUnit.MILLISECONDS)
    .subscribe {
    fireSomethingUp()
    }





    share|improve this answer
























    • After termination of application, your rxjava will not be executed. AlarmManager and rxjava interval tottaly different things, that can't be compared.

      – HeyAlex
      Jan 4 at 13:55











    • @HeyAlex You have a point. I thought he has Service and will call rest from this Service.

      – Murat VAROL
      Jan 7 at 12:06
















    0














    I had same problem with alarm manager.
    You can switch to Interval of RxJava.



    protected fun startCountdown(period: Long, timeUnit: TimeUnit): Observable<Long> {
    return Observable.interval(period, timeUnit)
    .subscribeOn(Schedulers.io())
    .observeOn(Schedulers.io())
    }


    usage;



    startCountdown(MEDIA_LOCATION_CHANGE_PERIOD, TimeUnit.MILLISECONDS)
    .subscribe {
    fireSomethingUp()
    }





    share|improve this answer
























    • After termination of application, your rxjava will not be executed. AlarmManager and rxjava interval tottaly different things, that can't be compared.

      – HeyAlex
      Jan 4 at 13:55











    • @HeyAlex You have a point. I thought he has Service and will call rest from this Service.

      – Murat VAROL
      Jan 7 at 12:06














    0












    0








    0







    I had same problem with alarm manager.
    You can switch to Interval of RxJava.



    protected fun startCountdown(period: Long, timeUnit: TimeUnit): Observable<Long> {
    return Observable.interval(period, timeUnit)
    .subscribeOn(Schedulers.io())
    .observeOn(Schedulers.io())
    }


    usage;



    startCountdown(MEDIA_LOCATION_CHANGE_PERIOD, TimeUnit.MILLISECONDS)
    .subscribe {
    fireSomethingUp()
    }





    share|improve this answer













    I had same problem with alarm manager.
    You can switch to Interval of RxJava.



    protected fun startCountdown(period: Long, timeUnit: TimeUnit): Observable<Long> {
    return Observable.interval(period, timeUnit)
    .subscribeOn(Schedulers.io())
    .observeOn(Schedulers.io())
    }


    usage;



    startCountdown(MEDIA_LOCATION_CHANGE_PERIOD, TimeUnit.MILLISECONDS)
    .subscribe {
    fireSomethingUp()
    }






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Jan 4 at 8:03









    Murat VAROLMurat VAROL

    105212




    105212













    • After termination of application, your rxjava will not be executed. AlarmManager and rxjava interval tottaly different things, that can't be compared.

      – HeyAlex
      Jan 4 at 13:55











    • @HeyAlex You have a point. I thought he has Service and will call rest from this Service.

      – Murat VAROL
      Jan 7 at 12:06



















    • After termination of application, your rxjava will not be executed. AlarmManager and rxjava interval tottaly different things, that can't be compared.

      – HeyAlex
      Jan 4 at 13:55











    • @HeyAlex You have a point. I thought he has Service and will call rest from this Service.

      – Murat VAROL
      Jan 7 at 12:06

















    After termination of application, your rxjava will not be executed. AlarmManager and rxjava interval tottaly different things, that can't be compared.

    – HeyAlex
    Jan 4 at 13:55





    After termination of application, your rxjava will not be executed. AlarmManager and rxjava interval tottaly different things, that can't be compared.

    – HeyAlex
    Jan 4 at 13:55













    @HeyAlex You have a point. I thought he has Service and will call rest from this Service.

    – Murat VAROL
    Jan 7 at 12:06





    @HeyAlex You have a point. I thought he has Service and will call rest from this Service.

    – Murat VAROL
    Jan 7 at 12:06













    0














    AlarmManager will be works normally on api 27 (oreo 8.1) and less. Just setup with something like that:



    public void setupAlarm(Context context, long triggerAtMillis) {
    PendingIntent pendingIntent = getPendingIntent(context);
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
    alarmManager.set(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
    } else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
    alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
    } else {
    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
    }
    }


    Don't forget that you need to setup your alarm again every time when your AlarmReceiver triggered. But that code will not be working on api 28 and more (pie 9.0). This is happening because of Power management feature introduced in Android Pie. Strict restrictions are introduced on the apps running in background. These restrictions are explained here. Try to use JobScheculer to invoke your foreground IntentService.



    As about your second question. You need to make a notification in your CallService. Just add this onCreate to your IntentService:



    @Override
    public void onCreate() {
    super.onCreate();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    NotificationChannel chan = new NotificationChannel("test", "your_channel_name", NotificationManager.IMPORTANCE_NONE);
    NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    if (manager != null) {
    manager.createNotificationChannel(chan);
    }

    Notification.Builder notificationBuilder = new Notification.Builder(context, "test");
    notificationBuilder.setOngoing(true);
    notificationBuilder.setContentTitle("Updatig")
    .setContentText("Wait for finish updating")
    startForeground(NOTIFICATION_ID, notificationBuilder.build());
    }
    }


    RemoteServiceException will be thrown if you will not call startForeground in service (you have 5 seconds to make this call) after startForegroundService.






    share|improve this answer






























      0














      AlarmManager will be works normally on api 27 (oreo 8.1) and less. Just setup with something like that:



      public void setupAlarm(Context context, long triggerAtMillis) {
      PendingIntent pendingIntent = getPendingIntent(context);
      AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
      if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
      alarmManager.set(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
      } else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
      alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
      } else {
      alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
      }
      }


      Don't forget that you need to setup your alarm again every time when your AlarmReceiver triggered. But that code will not be working on api 28 and more (pie 9.0). This is happening because of Power management feature introduced in Android Pie. Strict restrictions are introduced on the apps running in background. These restrictions are explained here. Try to use JobScheculer to invoke your foreground IntentService.



      As about your second question. You need to make a notification in your CallService. Just add this onCreate to your IntentService:



      @Override
      public void onCreate() {
      super.onCreate();
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      NotificationChannel chan = new NotificationChannel("test", "your_channel_name", NotificationManager.IMPORTANCE_NONE);
      NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
      if (manager != null) {
      manager.createNotificationChannel(chan);
      }

      Notification.Builder notificationBuilder = new Notification.Builder(context, "test");
      notificationBuilder.setOngoing(true);
      notificationBuilder.setContentTitle("Updatig")
      .setContentText("Wait for finish updating")
      startForeground(NOTIFICATION_ID, notificationBuilder.build());
      }
      }


      RemoteServiceException will be thrown if you will not call startForeground in service (you have 5 seconds to make this call) after startForegroundService.






      share|improve this answer




























        0












        0








        0







        AlarmManager will be works normally on api 27 (oreo 8.1) and less. Just setup with something like that:



        public void setupAlarm(Context context, long triggerAtMillis) {
        PendingIntent pendingIntent = getPendingIntent(context);
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        alarmManager.set(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
        } else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
        } else {
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
        }
        }


        Don't forget that you need to setup your alarm again every time when your AlarmReceiver triggered. But that code will not be working on api 28 and more (pie 9.0). This is happening because of Power management feature introduced in Android Pie. Strict restrictions are introduced on the apps running in background. These restrictions are explained here. Try to use JobScheculer to invoke your foreground IntentService.



        As about your second question. You need to make a notification in your CallService. Just add this onCreate to your IntentService:



        @Override
        public void onCreate() {
        super.onCreate();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel chan = new NotificationChannel("test", "your_channel_name", NotificationManager.IMPORTANCE_NONE);
        NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        if (manager != null) {
        manager.createNotificationChannel(chan);
        }

        Notification.Builder notificationBuilder = new Notification.Builder(context, "test");
        notificationBuilder.setOngoing(true);
        notificationBuilder.setContentTitle("Updatig")
        .setContentText("Wait for finish updating")
        startForeground(NOTIFICATION_ID, notificationBuilder.build());
        }
        }


        RemoteServiceException will be thrown if you will not call startForeground in service (you have 5 seconds to make this call) after startForegroundService.






        share|improve this answer















        AlarmManager will be works normally on api 27 (oreo 8.1) and less. Just setup with something like that:



        public void setupAlarm(Context context, long triggerAtMillis) {
        PendingIntent pendingIntent = getPendingIntent(context);
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        alarmManager.set(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
        } else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
        } else {
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
        }
        }


        Don't forget that you need to setup your alarm again every time when your AlarmReceiver triggered. But that code will not be working on api 28 and more (pie 9.0). This is happening because of Power management feature introduced in Android Pie. Strict restrictions are introduced on the apps running in background. These restrictions are explained here. Try to use JobScheculer to invoke your foreground IntentService.



        As about your second question. You need to make a notification in your CallService. Just add this onCreate to your IntentService:



        @Override
        public void onCreate() {
        super.onCreate();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel chan = new NotificationChannel("test", "your_channel_name", NotificationManager.IMPORTANCE_NONE);
        NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        if (manager != null) {
        manager.createNotificationChannel(chan);
        }

        Notification.Builder notificationBuilder = new Notification.Builder(context, "test");
        notificationBuilder.setOngoing(true);
        notificationBuilder.setContentTitle("Updatig")
        .setContentText("Wait for finish updating")
        startForeground(NOTIFICATION_ID, notificationBuilder.build());
        }
        }


        RemoteServiceException will be thrown if you will not call startForeground in service (you have 5 seconds to make this call) after startForegroundService.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 4 at 18:11

























        answered Jan 4 at 8:15









        HeyAlexHeyAlex

        1,0381721




        1,0381721






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54007289%2fcannot-do-work-in-background-periodically-with-alarmmanager%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

            Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

            A Topological Invariant for $pi_3(U(n))$