18

I start AlarmManager with PendingIntent and on few phones Alarm is not responding. On some devices is working ok on others it fails. I have made a few tests on different phones.

Nexus works ok, also Samsung Galaxy S4 zoom (4.2) works ok.

Samsung note 2 (4.3) works ok.

OPPO (4.4.4) alarm dies.

I have also implemented broadcast receivers which are working as they should on all devices.

    Log.v(TAG, "START ALARM");

    Intent intentAlarm = new Intent(context, AlarmReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(), 0, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT);

    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, 1000, 5000, pendingIntent);
Roberto Tellez Ibarra
  • 2,146
  • 3
  • 18
  • 34
5er
  • 2,506
  • 7
  • 32
  • 49
  • alarm dies meaning pending intent is not called after timer expiry ? What is the logcat say after alarm expiry ? can you post the logs. – Meher Jul 04 '15 at 08:28
  • 1
    yes its true, pending intent is not called. I can provide logs, but later (don't have the phone at me). – 5er Jul 04 '15 at 08:30
  • For versions higher than API 19: I start Alarm with `setExact` and then when is executed I start alarm again with `setExact`... It seems that is working... Will try and post the solution. – 5er Jul 07 '15 at 08:50
  • doesnt matter you can call this emthod safely with no worries – Ilja KO Jul 07 '15 at 16:58
  • I have a similar issue with a Huwaie 330 (not the best phone) with Android 4.2. The answer below by Rupesh seems to apply and given this phone has problems with a number of standard Android Apps like GPS Tracker which relies on alarms I assume it is a firmware bug. – David George Nov 01 '15 at 19:56

9 Answers9

7

Check whether the app is in stopped state.When the app is in stopped state it wont receive any alarm or events.

Also, I guess it might be OEM/manufacturer specific firmware/OS issue.To check whether the alarm has being actually schedule use adb shell dumpsys alarm and check whether your app alarm has being actually scheduled.

To check whether it is in stopped state use the following command:

adb shell dumpsys package "com.package.name" and check "stopped=true"

To know more about stopped state refer:

Launch controls on stopped applications

Starting from Android 3.1, the system's package manager keeps track of applications that are in a stopped state and provides a means of controlling their launch from background processes and other applications.

Note that an application's stopped state is not the same as an Activity's stopped state. The system manages those two stopped states separately.

The platform defines two new intent flags that let a sender specify whether the Intent should be allowed to activate components in stopped application.

FLAG_INCLUDE_STOPPED_PACKAGES — Include intent filters of stopped applications in the list of potential targets to resolve against. FLAG_EXCLUDE_STOPPED_PACKAGES — Exclude intent filters of stopped applications from the list of potential targets. When neither or both of these flags is defined in an intent, the default behavior is to include filters of stopped applications in the list of potential targets.

Note that the system adds FLAG_EXCLUDE_STOPPED_PACKAGES to all broadcast intents. It does this to prevent broadcasts from background services from inadvertently or unnecessarily launching components of stoppped applications. A background service or application can override this behavior by adding the FLAG_INCLUDE_STOPPED_PACKAGES flag to broadcast intents that should be allowed to activate stopped applications.

Applications are in a stopped state when they are first installed but are not yet launched and when they are manually stopped by the user (in Manage Applications).

Please note stopped state is different from app process not running.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
rupesh jain
  • 3,410
  • 1
  • 14
  • 22
  • 1
    is this really true? Isnt the propose of alarms, that you can stop app also restart device, and alarm will be alive if its set properly? It works for me in this way, for all tested phones (with exception for 4.4.4). – 5er Jul 07 '15 at 08:45
  • yes i smell bullshit...the alarm is not bound to xour activitys running state – Ilja KO Jul 07 '15 at 09:49
  • @IljaKO it not related to activity state..it is related to application state...when application is in stopped state all its components are disabled(stopped state is different from app process not running)...please read the docs carefully... – rupesh jain Jul 07 '15 at 15:09
  • LOL read code again he is targeting a broadcast receiver to be run when alarm goes off...anyway his pending intent could also start an activity if he declares an activity to response to actions or if he explicitly names an activity class to be started...read more carefully about system wide broadcasts and intent and also about action filters ... how do you else start an activity from the launcher? by retrieving thats the same as if an alarm would do that action ;) – Ilja KO Jul 07 '15 at 16:06
  • Maybe you just understood this System of Broadcasts, Receivers, Intents, Action filter and whatnot wrong till now;) – Ilja KO Jul 07 '15 at 16:09
  • @IljaKO it doesnot matter whether it is an activity or a broadcast receiver...when the apps is in stopped state all the components are disabled...you can write a small app and test it... – rupesh jain Jul 07 '15 at 16:38
  • my appologies to you...youre right removed downvote and upvoted your answer Im really sorry – Ilja KO Jul 07 '15 at 16:57
  • ok, but how than broadcast receiver works? Sorry but I really dont get it. **Uff and app is not in stopped state, otherwise other broadcast receivers wouldn't work** – 5er Jul 07 '15 at 17:13
  • @5er can you please whether the alarm has being actually schedule by using adb shell dumpsys alarm command and check whether the alarm was actually scheduled by the system..it might be OEM specific firmware issue... – rupesh jain Jul 07 '15 at 19:18
  • @rupeshjain, will do and let you know – 5er Jul 07 '15 at 21:16
  • @rupeshjain, you were right. The app on the specific phone is in stopped state. `stopped=true`. So any idea how to prevent app to go in stopped state? And why on earth this happens only on this particular phone? And why on earth Broadcast receivers are working? crazzzy... – 5er Jul 09 '15 at 20:01
  • some broadcast events which have FLAG_INCLUDE_STOPPED_PACKAGES are delivered to stopped apps too..also you need to launch the app once to remove it from stopped state..it might be firmware issue too – rupesh jain Jul 09 '15 at 20:32
5

There could be a couple of different issues at work here:

  • The type of alarm you are requesting (ELAPSED_REALTIME) will not wake up the device to deliver the alarm. Instead, if it expires while the device is sleeping it will be delivered the next time the device wakes.
  • The triggerAtMillis value of 1000 is requesting the first alarm at 1 second after boot of the device. If the device has already been up and running and you request this alarm, the first alarm may not fire and could cause the subsequent ones to not get scheduled. This is just a guess, I've not verified by looking at the 4.4.4 AOSP sources

The alarm handling was changed in API 19 (Android 4.4) to handle collating of alarm timers (all are inexact by default) and this change could have affected things for the 2nd bullet. You might try changing the triggerAtMillis value to be (SystemClock.elapsedRealtime() + 1000)

Note that if you need the device to wake from sleep, you'll need to use a _WAKEUP alarm variant and also have your BroadcastReceiver take a wake lock which your Service or Activity releases when it is done handling the alarm.

Larry Schiefer
  • 15,687
  • 2
  • 27
  • 33
  • You'll need to be more specific about what you are seeing or not seeing. Right now you've only said "it doesn't work." Is the `BroadcastReceiver` you created a `PendingIntent` to trigger get run? What is the device doing at the time the alarm (should) expire? What are you seeing in the logs? – Larry Schiefer Jul 02 '15 at 12:19
  • I try yours two suggestion ((SystemClock.elapsedRealtime() and _WAKEUP) , and alarm is not invoked in (4.4.4). But it is true that alarm is changed in API 19. Now I will check those changes. – 5er Jul 02 '15 at 12:36
  • With the alarm being "inexact", your alarm could be delayed for quite some time. For a repeating alarm, the first one can be delayed the most then usually the subsequent ones come close the desired interval after that. But, in API 19 the system is more aggressive about how it handles inexact alarms (now the default). I've seen this stretch out several minutes - so you may need to wait 5-10 minutes after the time you expect the alarm to expire before saying the alarm didn't fire. – Larry Schiefer Jul 02 '15 at 12:53
  • I have waited for a day or much longer (on installed app), and as I said the alarm didn't fire. It is true that it can have some delays, but on OPPO (4.4.4) alarm didn't fire at all. If the alarm would fire I would see that in file where I store events. – 5er Jul 02 '15 at 14:40
  • I suggest breaking it down and verifying if your `BroadcastReceiver` is triggered properly first. Then dig into the things your app does after that point. – Larry Schiefer Jul 02 '15 at 14:46
3

This is only a guess but I think the issue has to do with the API. Starting with KitKat, the system messes up the AlarmManager. Perhaps consider trying using something else for systems at abd above kitkat.

"Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested. "

Taken from http://developer.android.com/reference/android/app/AlarmManager.html

Andy
  • 337
  • 5
  • 16
1

Your alarms will continue to exist after your app is closed normally. If it is force stopped, or your device restarted, or an update for your app is installed, or your app is uninstalled, they will be lost. You can create BroadcastReceivers for some of those situations to recreate your alarms.

Also, setInexactRepeating is exactly that: inexact. When that alarm fires is implementation dependent and can not be precisely predicted.

TBridges42
  • 1,849
  • 1
  • 19
  • 29
  • Your comment is not true. If you set Alarms and BroadcastReceivers will live – 5er Jul 07 '15 at 17:19
  • 1
    No, that means you receive an intent when the system is done booting. You still have to catch that intent with a BroadcastReceiver and then recreate your alarms – TBridges42 Jul 07 '15 at 18:26
  • Ouch, you are right. That's true. My apologies. I am doing that... however that is not the case. – 5er Jul 07 '15 at 21:19
0

Try the following:

1) Add teh Wake_lock permission to your manifest.

<uses-permission android:name="android.permission.WAKE_LOCK">

2) Change

alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, 1000, 5000, pendingIntent);

with

alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000, 5000, pendingIntent);
marbdq
  • 1,235
  • 8
  • 5
0

Could you show us the AlarmReceiver.class code? Maybe you need to use return START_STICKY; on your onStartCommand method?

slorangex
  • 1,334
  • 2
  • 12
  • 25
0

Try to place AlarmManager into background service.

Vlad
  • 3,465
  • 1
  • 31
  • 24
0
Try this it works when activity is not running..

        Calendar calendar = Calendar.getInstance();

        long timemills = calendar.getTimeInMillis();
        Intent myIntent = new Intent(this, TimeChangeReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent, 0);

        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

            alarmManager.set(AlarmManager.RTC, timemills, pendingIntent);
            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, timemills,
                    10000, pendingIntent);
Rohit Heera
  • 2,709
  • 2
  • 21
  • 31
0

i have also used Alarm Service in my project for preparative task in very 6 or 7 minutes. And it is running fine in all phone.

i have make a alarm Service like this:

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
import android.util.Log;

public class MyAlarmService {
    private static PendingIntent resetAlarm;
    private static String TAG="CellPoliceChildGPSAlarmService";
    private static AlarmManager am;
    public static void start(Context context) {
        try {
            // We want the alarm to go off 30 seconds from now.
            long firstTime = SystemClock.elapsedRealtime();

            // Create an IntentSender that will launch our service, to     be scheduled with the alarm manager.
            //resetAlarm = PendingIntent.getService(context, 0, new     Intent(context, Get_NonRootDetails.class), 0);
            resetAlarm = PendingIntent.getService(context, 0, new     Intent(context, CallNonRBackgroundService.class), 0);
            // Schedule the alarm!
            am = (AlarmManager)     context.getSystemService(Context.ALARM_SERVICE);
            Log.i(TAG, firstTime+"");
            am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,     firstTime, 10*1000*60, resetAlarm);
        } 
        catch (Exception e) {
            Log.v("CellInfo", "Exception while start the     MyAlarmService at: " + e.getMessage());
        } 
    }

    public static void stop(Context context) {
        try {
            // When interval going to change from web services
            am.cancel(resetAlarm);
        } 
        catch (Exception e) {
            Log.v("CellInfo", "Exception while start the     MyAlarmService at: " + e.getMessage());
        }
    }


}

I have called or start like this;

MyAlarmService.start(SplashActivity.this);

Given permission in Manifest:

<uses-permission android:name="android.permission.WAKE_LOCK">

    <service
            android:name="com.secure.DataCountService"
            android:enabled="true" >
            <intent-filter>
                <action     android:name="com.secure.MyService" />
            </intent-filter>
        </service>

For notifications i also used pending intents like;

    Intent notificationIntent = new Intent(context, DashBoardActivity.class);

        PendingIntent pendingIntent = PendingIntent.getActivity(context,     0, notificationIntent, 0);

        notification.setLatestEventInfo(context, contentTitle,     PushNotificationUtils.notiMsg, pendingIntent);
        notification.flags  |=  notification.FLAG_AUTO_CANCEL;
hitesh141
  • 963
  • 12
  • 25