Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Background wifi scanning in Android

I'd started for about a month or two and I've to develop an Indoor Positioning System based on Wifi fingerprinting. I need an app that periodically scans wifi APs and send the result data to a Server.

So far I created an app that it's able to scan wifi APs and get the results when different connections are detected. I'm doing this in main activity using a broadcast receiver. The app is also able to send the data to the server.

What I want now is move this process to a periodic process in background, even when the smartphone is in sleep mode.

I have already read some topics about how to do it but none was clear. My question is what is the best way to do this? Using a Service/IntentService with a Timer/TimerTask?

Thanks.

Edit: Thanks!! AlarmManager and Services work fine!

like image 399
Sagat Avatar asked Oct 21 '22 11:10

Sagat


1 Answers

I think an AlarmManager fits your needs, use setRepeating to set something to repeat every X time

Schedule a repeating alarm. Note: for timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler. If there is already an alarm scheduled for the same IntentSender, it will first be canceled.

Like set(int, long, PendingIntent), except you can also supply a period at which the alarm will automatically repeat. This alarm continues repeating until explicitly removed with cancel(PendingIntent). If the stated trigger time is in the past, the alarm will be triggered immediately, with an alarm count depending on how far in the past the trigger time is relative to the repeat interval.

If an alarm is delayed (by system sleep, for example, for non _WAKEUP alarm types), a skipped repeat will be delivered as soon as possible. After that, future alarms will be delivered according to the original schedule; they do not drift over time. For example, if you have set a recurring alarm for the top of every hour but the phone was asleep from 7:45 until 8:45, an alarm will be sent as soon as the phone awakens, then the next alarm will be sent at 9:00.

If your application wants to allow the delivery times to drift in order to guarantee that at least a certain time interval always elapses between alarms, then the approach to take is to use one-time alarms, scheduling the next one yourself when handling each alarm delivery.

Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.

Parameters

type One of ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC, or RTC_WAKEUP.

triggerAtMillis time in milliseconds that the alarm should first go off, using the appropriate clock (depending on the alarm type).

intervalMillis interval in milliseconds between subsequent repeats of the alarm.

operation Action to perform when the alarm goes off; typically comes from IntentSender.getBroadcast().

As the note says

Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.

But i don't think you care much if it's not precise.


Or you can use setInexactRepeating

Schedule a repeating alarm that has inexact trigger time requirements; for example, an alarm that repeats every hour, but not necessarily at the top of every hour. These alarms are more power-efficient than the strict recurrences traditionally supplied by setRepeating(int, long, long, PendingIntent), since the system can adjust alarms' delivery times to cause them to fire simultaneously, avoiding waking the device from sleep more than necessary.

Your alarm's first trigger will not be before the requested time, but it might not occur for almost a full interval after that time. In addition, while the overall period of the repeating alarm will be as requested, the time between any two successive firings of the alarm may vary. If your application demands very low jitter, use one-shot alarms with an appropriate window instead; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent).

As of API 19, all repeating alarms are inexact. Because this method has been available since API 3, your application can safely call it and be assured that it will get similar behavior on both current and older versions of Android.

Parameters

type One of ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC, or RTC_WAKEUP.

triggerAtMillis time in milliseconds that the alarm should first go off, using the appropriate clock (depending on the alarm type). This is inexact: the alarm will not fire before this time, but there may be a delay of almost an entire alarm interval before the first invocation of the alarm.

intervalMillis interval in milliseconds between subsequent repeats of the alarm.

Prior to API 19, if this is one of INTERVAL_FIFTEEN_MINUTES, INTERVAL_HALF_HOUR, INTERVAL_HOUR, INTERVAL_HALF_DAY, or INTERVAL_DAY then the alarm will be phase-aligned with other alarms to reduce the number of wakeups. Otherwise, the alarm will be set as though the application had called setRepeating(int, long, long, PendingIntent). As of API 19, all repeating alarms will be inexact and subject to batching with other alarms regardless of their stated repeat interval. operation Action to perform when the alarm goes off; typically comes from IntentSender.getBroadcast().

While my answer aim is to say a general way to repeat an action every X time, as other noticed, you will need Wifi Lock, Wake lock and use RTC_WAKEUP as AlarmManager type.

RTC_WAKEUP: Alarm time in System.currentTimeMillis() (wall clock time in UTC), which will wake up the device when it goes off.

like image 196
Marco Acierno Avatar answered Oct 23 '22 02:10

Marco Acierno