scheduling alarm for every second in android 5.1
Asked Answered
L

7

13


I want to run alarm service for every second in my application.It is working fine below 5.1 version. but it is not triggering in 5.1 devices. I am using commonsware wakeful intent service.The logcat message is saying that "Suspiciously short interval 1000 millis; expanding to 60 seconds". How can I poll for every second in 5.1? Can anybody suggest me how to achieve this?

Explanation little bit more:

My use case is I need to do some operation for every 30 minutes interval. AFAIK For this Using alarm manager is efficient way, but here

1)I need to display the count down timer to the user. (Timer task,Count down timer,ScheduledExecutorService is pretty useful for this)
2) I need to notify the user for every 30minutes(via notification) even if the app is in background.(Alarm Service is enough for this)

but here my problem is when the app is in background,when you swipe out the application from recents( i.e.,application process is killed) none of the services or timers,handlers,executor services will not work). In this case how can I notify the user after completion of 30 minutes. Please guide me if I am thinking in wrong way.

Thanks,
Chaitanya

Landlubber answered 28/4, 2015 at 8:53 Comment(4)
use TimerTask this is made for such need.Dragging
Whats wrong with my question? May I know the reason behind downvote?Landlubber
I think they downvoted because the logcat pretty much says it all, but I think this question is okay.Frissell
in 5.1 devices, you can call alarm once again from onReceive every second.. its work like 1 second timer and its doesn't effect when app kill from recent.. i face same issue but in that way i can solve it...best of luckKneeland
F
8

This is normal behavior in Android Lollipop.

Suspiciously short interval 1000 millis; expanding to 60 seconds

Tells you that the system does not like those short time intervals anymore.

Issue #161244 documented that:

This is working as intended, though is at present inadequately documented (and we're aware of that side of the problem).

Speaking very generally: short-period and near-future alarms are startlingly costly in battery; apps that require short-period or near-future work should use other mechanisms to schedule their activity.

So don't use an AlarmService for this. Prefer a thread or Executors or TimerTask or something else:

// Using Handler
new Handler().postDelayed(runnable, TimeUnit.SECONDS.toMillis(1));

// Using Executors
Executors.newSingleThreadScheduledExecutor().schedule(runnable, 1, TimeUnit.SECONDS);
Frissell answered 28/4, 2015 at 8:58 Comment(7)
What if the task must be run even if the device is asleep or the application is not running?Kirchner
You can't setup a service that triggers an alarm every second, period (for reasons exposed above). See the alternatives above or the official reference: developer.android.com/training/scheduling/alarms.html#set or just use a longer interval.Frissell
I'm not talking every second, sorry. I'm talking any period of time less than 1 minute (e.g. 25 seconds), as the log message seems to imply. Do postDelayed and Executors work even if the device is asleep, or the application is not running anymore?Kirchner
I don't think so. Even if they are threads, those threads are part of your application's group process. Use a Service to achieve what you want.Frissell
OK... but the service would need to be rescheduled e.g. every 25 seconds... so, uhm, what should be used to reschedule it, if the AlarmManager is not capable of doing that?Kirchner
Sure, the AlarmManager is right for what you want to achieve (it is a Service).Frissell
"Do postDelayed and Executors work even if the device is asleep" nothing works when device is asleep - device is asleep so why do you expect to do something?Guthrie
C
5

Why would you do that?
Use an handler instead:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        // do your stuff here, called every second
        mHandler.postDelayed(this, 1000);
    }
};

// start it with:
mHandler.post(runnable);

And use the following to stop your 1 sec timer:

mHandler.removeCallbacks(runnable);
Ciapas answered 28/4, 2015 at 9:2 Comment(2)
Hey @lazy-ninja Can you check my updated question. and suggest meLandlubber
Thanks. The solution works as expected. AlarmManager cannot be forced to be fired at exact times.Lungworm
F
1

Use both 1 and 2:

  • Use the AlarmManager for the role of alerting the user at an interval greater than one minute (such as the requested 30 minutes)

  • If the notification triggers an activity where you need to show updates is in the foreground, then also do something cheap, like postDelayed(), to give the user periodic updates in that activity

Fredfreda answered 28/4, 2015 at 11:4 Comment(2)
Thank you for your suggestion. I did the same it is working fine as I expected.Landlubber
chaitu would you please help me what you did ?Cavite
H
0

I dont exactly understand your use case but setting alarm for every second is overkill. You can use Timer. Take a look into this class.

Herbie answered 28/4, 2015 at 8:57 Comment(0)
Y
0

This is a reported issue for Android 5.1 that happens whenever you try to set an alarm for an interval less than 60000 milliseconds.

This warning happens because setting a very low interval like this will drain your battery very fast.

Project member on the platform said:

Speaking very generally: short-period and near-future alarms are startlingly costly in battery; apps that require short-period or near-future work should use other mechanisms to schedule their activity.

That's why it is not recommended to use Alarm in your case.

According to your Question update. You want to keep your background service Awake even if the user manually swiped it from the recent apps list. This can be done simple using the START_STICKY flag such as the following. Add this code to your service in onStartCommand method:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
} 

Source: answer

Yonder answered 28/4, 2015 at 8:59 Comment(1)
I'm using START_STICKY but when I close the app my service get skilled anyway. I think this is not a reliable solution.Taxeme
G
0

Try These Steps.

  1. Use a Alarmmaager periodical after 1 min
  2. Inside that alarm manager use a handler that call after some seconds and perform your task.

Remember

Its not a Good Idea, As the alarm manager is not aware of the current situation of the device, e.g., it does not consider if the device is connected to a power plug, idle or connected to a network Also the alarm manager waste of resources because its doesn't care about when the device has more resources available.

Grassquit answered 23/6, 2015 at 11:12 Comment(0)
C
-2

I've successfully changed the minimum AlarmManager interval from 1 minute to 30 seconds.

On your device copy /system/framework/services.jar to your computer. Extract classes.dex from it, open with Winrar for example.

 

Download baksmali

java -jar baksmali.jar -o extractfolder classes.dex

edit extractfolder\com\android\server\AlarmManagerService$Constants.smali

Replace all values 0xea60 (60000ms /1min in hex) to however many ms you want the minimum interval to be example 30seconds 0x7530

Save and Smali back to classes.dex

java -Xmx512M -jar smali.jar extractfolder -o classes.dex

Open services.jar again in Winrar, delete classes.dex and drag the newly created classes.dex into services.jar.

Copy back to /system/framework/services.jar

Restart device.

Also on my Samsung device, having the word alarm OR alert(not tested) in the package name adds it to a whitelist. My alarms are fired exactly when I do this.

Coign answered 1/11, 2016 at 14:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.