Android 4.4(API 19)闹钟管理与计步器功能

Android 4.4

好消息是从4.4开始,安卓系统自带计步传感器了,这样就再也不用我们自己通过监测加速传感器、重力传感器的数值变化去实现计步功能了,而且谷歌做的相当省电。
当然坏消息就是我们在使用AlarmManager启动闹钟的时候,时间可能就不准了,而且设置重复闹钟也可能不灵了 ==。

计步功能

SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
SensorEventListener sensorEventListener = new SensorEventListener() {

    @Override
    public void onSensorChanged(SensorEvent event) {
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {}
};

Sensor stepSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
sensorManager.registerListener(sensorEventListener, stepSensor, Sensor.TYPE_STEP_COUNTER, SensorManager.SENSOR_DELAY_UI);

其中,在onSensorChanged(SensorEvent event)函数中,event.values[0]表示从开机开始的第一次注册计步传感器到现在的累计步数,当然前提是不要调用
sensorManager.unregisterListener(sensorEventListener);,这样系统就会一直在后台运行计步功能。

PS:如果我们在很多个Activity或者Service里面都只有registerListener去注册计步传感器,而没有在他们Destroy的时候去调用unregisterListener注销传感器,那么,当传感器监测的数值发生变化的时候还是会去调用每个Listener中的onSensorChanged函数的,所以有的时候就会发生一些很莫名其妙的错误就是因为没有注销监听导致的,使得即使Activity或Service已经Destroy了,但是监听函数却还是有作用。如果我们需要后台一直运行计步功能,那么我们只要保留一个Listener没有被注销掉就好了,其他的使用完及时注销。

闹钟不准时

使用安卓系统自带的闹钟基本流程都是这样:
[S1].获取闹钟管理器
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

[S2].获取需要执行的活动的PendingIntent对象,通过调用其静态方法获得

PendingIntent.getActivity...
PendingIntent.getActivities...
PendingIntent.getService...
PendingIntent.getBroadcast...

[S3].通过AlarmManagerset方法可以指定在某时刻,或者是开机时间点之后的相对时刻来启动闹钟,就是执行PendingIntent对象中的内容。
可是从set函数的文档说明中可以看到:

Beginning in API 19, the trigger time passed to this method is treated as inexact: the alarm will not be delivered before this time, but may be deferred and delivered some time later. The OS will use this policy in order to “batch” alarms together across the entire system, minimizing the number of times the device needs to “wake up” and minimizing battery use. In general, alarms scheduled in the near future will not be deferred as long as alarms scheduled far in the future.

大概意思就是从Android 4.4开始,闹钟就变得不准时了,这样做的目的是为了减少因为频繁唤醒设备所带来的电量消耗,不过可以保证的一点就是,我们设置的闹钟只会晚于我们设定的时间去启动,而不会早于。

这也就是为什么闹钟不去准时启动的原因。

闹钟重复有问题

然而闹钟不准时却不仅仅如此。

AlarmManager里面有一个很好的方法就是setRepeating,这个方法顾名思义就是去设置一个循环重复启动的闹钟,每隔一定的时间间隔去启动。

但是,在该方法的说明里又看到了这样的内容:

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.

可见在API 19的版本中重复报警也是不准确的,不过文档中倒是给我们提供的一个解决方案,不去使用setRepeating方法,而是用set方法去模拟这个功能,在每一次闹钟启动的时候我们人为地去使用set设置下一次闹钟响铃的时间。
别说,这样做了之后闹钟还真是正常了好多呢。

解决办法

针对于Android闹钟启动时间不准时,可以把 setsetRepeating使用setExact来代替,这种只会启动一次闹钟,如果要设置重复,则应该使用上述的方法在每次启动闹钟的时候设置下一次的闹钟。

不过使用这种方法会增加系统的功耗。

但是闹钟的准时与否也和好多因素有关,我在实验的过程中就发现,手机是否在充电会有影响,充电时比较准,闹钟设置重复的间隔太小也会影响,通常间隔越大越会准时一些。

以上

Android 4.4是经历了什么,不过鱼与熊掌不可兼得,如果既要使用系统计步功能还要使用准时的闹钟功能的可就要好好考虑一下了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android4.4及以上版本中,可以使用WebAPI的方式来实现拍照上传功能。具体步骤如下: 1. 在HTML页面中添加一个input标签,设置type属性为file,capture属性为camera,用于调用摄像头拍照。 ```html <input type="file" accept="image/*" capture="camera" id="uploadInput"> ``` 2. 使用JavaScript获取input标签,并监听其change事件,获取拍照的图片文件对象。 ```javascript var uploadInput = document.getElementById('uploadInput'); uploadInput.addEventListener('change', function() { var file = uploadInput.files[0]; // ...将文件上传到服务器 }); ``` 3. 将获取到的图片文件对象转换为Base64编码的字符串,并将其作为图片的src属性显示在页面上。 ```javascript var reader = new FileReader(); reader.onload = function(e) { var imageData = e.target.result; var img = document.createElement('img'); img.src = imageData; document.body.appendChild(img); }; reader.readAsDataURL(file); ``` 4. 将Base64编码的图片数据发送到服务器,可以通过XMLHttpRequest对象发送POST请求,也可以使用jQuery等库进行简化操作。以下是一个示例代码,它可以将Base64编码的图片数据发送到服务器: ```javascript var xhr = new XMLHttpRequest(); xhr.open('POST', '/upload', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200) { alert('上传成功!'); } else { alert('上传失败!'); } } }; xhr.send('image=' + encodeURIComponent(imageData)); ``` 注意,这段代码中的上传路径为`/upload`,需要根据实际情况进行修改。另外,为了提高用户体验,可以在调用摄像头添加一个拍照的确认界面,让用户可以选择是否确认使用该照片。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值