安卓背景Wi-Fi扫描

5
我已经开始了大约一个月或两个月,我需要基于Wifi指纹定位开发一个室内定位系统。我需要一个应用程序定期扫描Wifi接入点并将结果数据发送到服务器。
到目前为止,我创建了一个应用程序,能够扫描Wifi接入点,并在检测到不同连接时获取结果。我正在使用广播接收器在主活动中完成这个过程。该应用程序也能够将数据发送到服务器。
现在我想将此过程移至后台的定期处理,即使智能手机处于睡眠模式下也可以。
我已经阅读了一些关于如何做到这一点的主题,但没有一个是清晰的。我的问题是什么是最好的方法来做到这一点?使用带有计时器/计时器任务的服务/IntentService?
谢谢。
编辑:感谢!!AlarmManager和Services工作得很好!

1
当前的答案并没有告诉你,你在手机休眠时还需要一个唤醒锁来使你的代码运行。 - Richard Le Mesurier
好的观点,我修改了我的回答。此外,“_WAKEUP”版本的闹钟也值得一提。 - Perry_ml
谢谢!我会尝试实现它。 - Sagat
你已经实现了吗?能帮我一下吗? - livemaker
2个回答

3
我认为 AlarmManager 可以满足您的需求,使用 setRepeating 设置某个任务每隔 X 时间重复执行。
安排一个重复的闹钟。注意:对于定时操作(ticks、timeouts等),使用Handler更容易,也更有效率。如果已经为同一IntentSender安排了闹钟,则首先会取消该闹钟。与set(int, long, PendingIntent)类似,但您还可以提供一个自动重复闹钟的时间间隔。此闹钟将继续重复,直到使用cancel(PendingIntent)明确删除为止。如果规定的触发时间是过去的,则根据过去的触发时间与重复间隔的距离而定,立即触发闹钟,触发次数取决于过去多久。如果闹钟被延迟(例如由于系统休眠而导致的非唤醒类型的闹钟),则尽快传递跳过的重复。之后,未来的闹钟将按照原始计划传递;它们不会随着时间而漂移。例如,如果您为每小时顶部设置了一个重复的闹钟,但手机从7:45到8:45处于睡眠状态,则在手机唤醒时将发送一个闹钟,然后下一个闹钟将在9:00发送。如果您的应用程序希望允许传递时间漂移,以保证至少某个时间间隔总是经过一些警报,则应采用一次性警报的方法,在处理每个警报传递时自己安排下一个警报。注意:从API 19开始,所有重复的闹钟都是不精确的。如果您的应用程序需要精确的交付时间,则必须使用一次性的准确闹钟,并按上述方式重新安排每次闹钟。目标SDK版本早于API 19的旧版应用程序将继续将其所有警报(包括重复的警报)视为精确。

参数

type ELAPSED_REALTIME、ELAPSED_REALTIME_WAKEUP、RTC或RTC_WAKEUP之一。

triggerAtMillis 以毫秒为单位的时间,该警报应首先响起,使用适当的时钟(取决于警报类型)。

intervalMillis 警报重复之间的毫秒间隔。

operation 警报响起时要执行的操作;通常来自IntentSender.getBroadcast()。

正如注释所说

注意:从API 19开始,所有重复警报都不精确。如果您的应用程序需要精确的传递时间,则必须使用一次性精确警报,每次按上述描述重新安排。目标SdkVersion早于API 19的旧版应用程序将继续将其所有警报(包括重复警报)视为精确。

但我认为如果不精确,你可能不太在意。


或者您可以使用 setInexactRepeating

安排一个具有不精确触发时间要求的重复闹钟;例如,每小时重复一次的闹钟,但不一定在每个小时的顶部重复。这些闹钟比setRepeating(int,long,long,PendingIntent)传统提供的严格重复更节能,因为系统可以调整闹钟的传递时间,使它们同时触发,避免设备不必要地从睡眠中唤醒。
您的闹钟的第一个触发器不会早于请求的时间,但可能在该时间之后几乎完整的间隔内不会发生。此外,虽然重复闹钟的总周期将如所请求,但任何两个连续触发闹钟之间的时间间隔可能会有所不同。如果您的应用程序需要非常低的抖动,请改用带有适当窗口的单次闹钟;请参见setWindow(int,long,long,PendingIntent)和setExact(int,long,PendingIntent)。
从API 19开始,所有重复闹钟都是不精确的。因为自API 3以来就提供了此方法,所以您的应用程序可以安全地调用它,并确保在当前和旧版Android上获得类似的行为。

参数

type ELAPSED_REALTIME、ELAPSED_REALTIME_WAKEUP、RTC 或 RTC_WAKEUP 中的一个。

triggerAtMillis 毫秒级时间,闹钟应该首次响起,使用适当的时钟(取决于闹钟类型)。这是不精确的:闹钟不会在此时间之前触发,但在第一次闹钟调用之前可能会有几乎整个闹钟间隔的延迟。

intervalMillis 闹钟重复的毫秒间隔。

在 API 19 之前,如果这是 INTERVAL_FIFTEEN_MINUTES、INTERVAL_HALF_HOUR、INTERVAL_HOUR、INTERVAL_HALF_DAY 或 INTERVAL_DAY 中的一个,则闹钟将与其他闹钟相位对齐,以减少唤醒次数。否则,闹钟将被设置为应用程序调用 setRepeating(int, long, long, PendingIntent) 的方式。从 API 19 开始,所有重复闹钟都是不精确的,并且可能会与其他闹钟批处理,无论其声明的重复间隔如何。操作 当闹钟响起时执行的操作;通常来自 IntentSender.getBroadcast()。

虽然我的回答旨在提供一种每隔X时间重复执行某个操作的通用方法,但正如其他人所指出的,您需要使用Wifi LockWake lock并将RTC_WAKEUP用作AlarmManager类型。

RTC_WAKEUP: 在System.currentTimeMillis()(UTC中的壁钟时间)中的闹钟时间, 将在其响起时唤醒设备。


0
将您的代码从Activity移动到Service。然后,使用AlarmManager定期启动服务。服务进行扫描并在完成时停止自身。然后在计时器到期时再次启动。
编辑:还要查看cpu lockwifi lock
编辑2:创建闹钟时,还要使用RTC_WAKEUP常量,以便即使设备处于睡眠模式,也会触发您的操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接