以前在Android 4.0时,alarmManager 没什么问题。后来android为了优化系统耗电情况,引入了doze模式,参见此页

https://developer.android.com/training/monitoring-device-state/doze-standby

简单地说,系统会长时间待机后,会自动进入doze模式,这种模式里,alarmManager啥的都不好用了,系统会自动从doze模式转出来一小段时间,把刚在在doze里被忽略的事件(比如说alarmManager)执行。这样一来,alarmManager根本无法定时调用了。

其实,对于每个应用,这个模式是可以配置的,一般在 Settings > Battery > Battery Optimization,也可以用代码打开设置页面,让用户设置,下面是一段别人写的代码:

 Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:user.zhuku.com"));
startActivity(intent);

但是在android wear手表上,比如华为 watch2,是没有这个设置项的,也就是说,手表放置在桌子上,不使用,一段时间后,所有应用一定会停用。经过测试发现,手表进入doze模式后,的确如开发文档说的那样,定时唤醒系统,并且频率越来越低。

试了好多方法,比如JobService,setAndAllowWhileIdle 在 华为手表上,都无法越过这个限制。

好在手表有一个设定,就是带在手上后,系统就不会进入doze模式了,不知道是使用的什么方法判断的手表是否带在手上。

测试基于 华为 watch 2 ,andoroid 8.0 ,android wear 2.x,

手表长时间不带的话,会进入doze模式,后台任务都会停止,好在我们的应用是要求用户一直呆在手上,所以不用介意手表doze后的情况。
手表进入doze后,再次移动手表,系统会立即唤醒,后台任务可以继续正常执行,满足我们的需求 :用户白天带上手表,系统执行跟踪;晚上摘下,系统doze后停止跟踪;第二天再次带上时,系统继续跟踪。

由于手表带在手上时,手表存在一定的移动,所以系统不会doze,理论上可以使用任何后台技术实现需求。我们的demo中,使用的是系统alarm+后台service 的方案。 系统中有3个alarm,第一个负责添加 sersor listener, 第二个负责移除 sensor listener,第三个负责触发网络请求,发送数据。这3个alarm定期向service中的线程发送message,触发相应操作。

为了减少耗电,目前是每分钟开启监控30秒,关闭监控30秒。为了减少数据库的数据量,目前是每3秒录入一次数据。

demo是一款 在手表上独立运行的应用。充满电后,可满足一个白天12小时的使用(wifi条件下)(大约20小时以上?)(晚上会进入doze,耗电很少)。

另外华为手表目前没有发现 doze的白名单设置。

demo仅仅验证了方案的可行性,具体实现时需要优化。比如把service bind上,去掉handler的使用。再比如针对新的alarm机制调整alarm的注册和使用。再比如 对 front service 的notification界面 进行动态调整,让用户在通知栏看到更多的跟踪信息。

Android Wear 2.0 AlarmManager 后台定时任务的更多相关文章

  1. Android Wear开发

    Android Wear从2014年3月发布到现在已经从1.0发展到2.0(目前还没正式发布).其产品定位也发化了巨大变化,因为Android Wear 1.0通讯方式只有蓝牙,限定了系统,比较依赖手 ...

  2. Android Wear计时器开发

    记得在2013年12月的时候,有系列文章是介绍怎么开发一个智能手表的App,让用户可以在足球比赛中记录停表时间.随着Android Wear的问世,在可穿戴设备中开发一款这样的App确实是个很不错的想 ...

  3. 如何开发Android Wear应用程序

    Android Wear是连接安卓手机和可穿戴产品的一个平台.自从今年上半年发布以来,Android Wear获得了大量关注,既有来自消费者的关注,也有来自开发商的关注,后者希望自己的应用程序已经准备 ...

  4. Android从5.0到9.0版本的主要变更

    https://www.jianshu.com/p/10bdbf883c46?utm_source=desktop&utm_medium=timeline Android5.0 1.虚拟机 在 ...

  5. Android 蓝牙4.0 BLE

    Android ble (Bluetooth Low Energy) 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才可以使用. BLE是蓝牙4.0的核心Profil ...

  6. Android Wear预览版——尝鲜

    前两天Google推出了Android Wear的SDK,稍稍的瞧了一眼,发现这个预览版的功能还是比较简单的,只有一个通知转发的功能,不过就这么一个功能,带来的效果却是Very Good~~ 功能:发 ...

  7. (转)Android Service 双进程常驻后台(2)

    最近项目用到Service常驻后台,研究了一下发现手Q和微信都是使用了双进程来保证一键清理后自动复活,copy网上双进程Service的例子,再结合onTrimMemory(),基本实现一键清理后自动 ...

  8. Android Wear 开发入门

    大家好,我是陆嘉杰,我是一名Android开发者.我想和大家进行一些技术交流,希望越来越多的人能和我成为好朋友. 大家都知道,智能手表是下一个开发的风口,而这方面的技术又属于前沿,所以和大家分享下An ...

  9. Android Wear开发 - 数据通讯 - 第零节 : 打包Wear应用(手机和手表应用如何连接)

    之所以将打包这一特殊的内容作为数据通讯的第零节,是因为如果没有通过配置打包的一些信息,则没有办法将手机端应用和手表端应用连接起来,则无法继续进行接下来的数据通讯的开发. 以下依然只针对Eclipse平 ...

随机推荐

  1. Flutter控制屏幕旋转

    特定页面旋转屏幕很简单: SystemChrome.setPreferredOrientations([ ... ]); 数组中是您要支持的屏幕方向. 如果想在特定页面固定横屏, 您可以这样写: @o ...

  2. Linux查看用户所属用户组

    1.查看当前用户所属用户组 [oracle@serverhl ~]$ groups oinstall dba 2.查看<user1>, <user2> 和 <user3& ...

  3. Spring Boot 2.x 编写 RESTful API (一) RESTful API 介绍 & RestController

    用Spring Boot编写RESTful API 学习笔记 RESTful API 介绍 REST 是 Representational State Transfer 的缩写 所有的东西都是资源,所 ...

  4. python的局部变量,全局变量,类变量,实例变量

    定义: a.全局变量:在模块内.在所有函数外面.在class外面,这就是全局变量. b.局部变量:在函数内.在class的方法内(未加self修饰的),这就是局部变量. c. 静态变量:在class内 ...

  5. [powershell]获取FCID&Port

    Get-InitiatorID Get-InitiatorPort

  6. 【HTTP】http协议一些重要的知识点

    一. HTTP状态码是用以表示网页服务器HTTP响应状态的3位数字代码.所有状态码的第一个数字代表了响应的五种状态之一.当用户试图通过HTTP或FTP协议访问一台运行主机上的内容时,Web服务器返回一 ...

  7. MongoDB常用配置项目

    systemLog:  destination: file  logAppend: true  path: /data/mongod/log/mongod-rs1.log processManagem ...

  8. 您必须知道的 Git 分支开发规范

    Git 是目前最流行的源代码管理工具. 为规范开发,保持代码提交记录以及 git 分支结构清晰,方便后续维护,现规范 git 的相关操作. 分支管理 分支命名 master 分支 master 为主分 ...

  9. Java基础 -- 深入理解Java类型信息(Class对象)与反射机制

    一 RTTI概念 认识Claa对象之前,先来了解一个概念,RTTI(Run-Time Type Identification)运行时类型识别,对于这个词一直是 C++ 中的概念,至于Java中出现RT ...

  10. wpf编写一个简单的PDF转换的程序

    wpf 调用Spire.Pdf将PDF文件转换为其他文件模式 首先在Nuget里下载该第三方包Spire.Pdf. 然后可以编写程序 //这里我调用的是解析成流模式,这是因为我要使用ProgressB ...