Android开发:闹钟响起时间不精准等问题

故事前言:

这学期快结束,安卓课程的期末大项目也来了。跟以往的现代操作系统应用开发课程一样,每次到这个时候就会觉得很蛋疼。因为要搞一个具有创新意义的项目,实在是太难了。毕竟生活圈太小,学校生活中遇到的人和事都很局限。

四人一组,和小组成员讨论了很久,谁也没有提出一个较好的想法。

队友A:实在不行就做个备忘录吧,把功能完善得好点。

队友B:不行,这idea实在是太low了。

我:备忘录确实有点low,但是现在时间也不多了,也快期末考了,再不确定下来都没时间复习了。

大家郁郁寡欢地下了课去食堂吃饭,在吃饭的时候不知什么原因突然就聊到了早上起床老是睡过头的事。这一点我深有感触啊,我就是那种放了很多个闹钟但还是容易睡过头的人。因为每天早上的闹钟响了之后,我怕吵醒室友总会以迅雷不及掩耳之势右滑屏幕关掉了闹钟,然后倒头继续睡,等待下一个闹钟响起。所以就会出现最后一个闹钟响完之后我还是继续睡的情况。。。

后来队友就发话了,要不我们就做个闹钟吧,跟手机自带的闹钟不一样,可以有多种模式,专门服务于那种意志力不坚定、容易赖床或者像我这样明明很想起床却因闹钟没听到或者闹钟停了而睡过头的人。

我一听表示很赞同,另外几个队友也表示可以,所以我们一拍即合,期末大项目就做闹钟了。

后来经过进一步的讨论后,我们确定了四种模式闹钟,分别为摇一摇、鬼畜音乐、心灵鸡汤和简单计算题。

摇一摇模式顾名思义,就是要摇动手机才能关闭闹钟,但是我们限制了次数至少为30次。在摇动手机的过程中,也算是给起床做了一定的准备,因为闹钟关闭的时候,手酸了,人也差不多醒了。

鬼畜音乐模式,其实就是对闹钟铃声做了点修改,不是顺序播放,而是随机乱序播放。往往有时候在梦中会跟着现实中的闹钟铃声一起哼,而错过了该起床的时间。所以乱序播放在这个时候起到了一定的效果,当你半睡半醒的时候,跟着闹钟一起哼,突然音风突变,从前奏跳到高潮,播放了几秒后,又跳到另一个进度播放……讲道理,听得很难受,强迫症慎选,不然分分钟砸手机!

心灵鸡汤模式,用户可选内置励志鸡汤或者自定义编译鸡汤,为了就是在关闭闹钟之前,能让用户看到一些比较激励人心、昂扬向上的鸡汤。例如:你努力前进的脚步,一定要快于父母老去的速度。当然了,简单地看一下就关闭闹钟,没那么简单,在闹钟关闭页面,会让你输入刚才出现的今日鸡汤,只有输入正确才能关闭闹钟。励志鸡汤是为了让大脑意识到起床的重要性,回答今日鸡汤是为了让用户通过手机打字来使得他们更快清醒,因为这需要大脑和双手的配合。

简单计算题模式,想必大家都知道。也就是做对一道计算题才能关闭闹钟,这里的计算题不是简单的小学口算题,而是包括括号在内的加减乘除四则运算题,每个数字不会超过100,这些表达式都是通过递归随机生成的,确保了每次都是新鲜的题目。

好了好了,现在进入我今天想要说的正题。在开发的过程中,我们主要遇到了以下几个问题:

  • 问题:多天重复同一个时间的闹钟设置问题

    解决办法:对于一个确定的闹钟时间,不管是一次性闹钟还是多天重复,抑或是每周重复闹钟,AlarmManager都只要调用一次setRepeating方法就够了。因为,设置闹钟间隔时间为24小时,也就是说每天到这个时间点,系统都会发出指定的广播,然后广播接收器那边可以再做进一步的判断处理。广播接收器里面先获取今天是星期几,然后通过根据activity跳转时传递的参数(这里是时钟和分钟),去数据库中读取该闹钟信息。如果今天有设置闹钟,那么让闹钟响,否则就不响。这样就处理了所有的闹钟响铃情况。

  • 问题:闹钟响起时间不精准的问题

    通过AlarmManager的setRepeating方法来设置闹钟,这种方式下的闹钟不够精准。因为从API 19开始,alarm的机制都是非准确传递,操作系统将会转换闹钟,来最小化唤醒和电池使用。setRepeating 方法在 API 19开始将会失去原来的效果。有一些新的API会支持严格准确的传递,如 setWindow(int, long, long, PendingIntent)和setExact(int, long, PendingIntent)。

    解决方法:在设置闹钟的时候对API进行判断,如果是小于API 19的版本,则直接调用setRepeating方法,否则就调用setExact方法,但由于setExact方法只执行一次,所以就得在一个闹钟响完之后,在广播接收器里再一次调用setExact方法,实现闹钟重复设置。

  • 问题:设置一个今天过期的时间,闹钟会立刻被触发

    在不选择闹钟时间是在周几响的情况下,处理方法是如果闹钟时间小于当前时间,则设置为明天,相反,如果闹钟时间大于当前时间,则设置为今天。但是,如果明确选择了闹钟时间为今天一个已过去的时间点,闹钟会立刻响起。显然这不符合实际情况。

    解决方法:在广播接收器里面对闹钟时间和当前时间进行比较判断,保证闹钟时间不会早于当前时间。

  • 问题:更新闹钟时删除旧闹钟的问题

    在更新闹钟时间的时候,应该先删除之前设置的闹钟,问题是要准确地删除之前的那个闹钟。

    解决方法:在使用PendingIntent.getBroadcast方法来获取一个PendingIntent实例对象的时候,传入的第二个参数id可以用来区分闹钟。由于在数据库中闹钟时间是闹钟表格的主键,所以可通过闹钟时间来构建唯一的id, 公式为id = hour*100+minute。每一个闹钟在设置的时候对应的Pendingintent的id都不同,因此在删除闹钟的时候,只要根据旧的闹钟时间,即可获取旧的PendingIntent对象的id,然后再保证删除的intent和原来的一样,这样就可以达到准确删除闹钟的目的。

  • 问题:锁屏情况下到达闹钟时间问题

    解决办法:首先在manifest.xml文件里声明在锁屏时唤醒屏幕的权限,, 然后在 onResume() 函数里获取 wake 锁,并且要在 onPause() 释放锁,否则程序会出错。为了让 activity 能显示在锁屏界面,需要把相应的 activity 的主题改为 @android:style/Theme.Wallpaper.NoTitleBar;

  • 问题:重启手机后闹钟管理器丢失问题

    解决办法:重启手机后之前设置的闹钟都会失效,因此解决办法是在重启时从数据库读取闹钟数据,将所有闹钟重新设置一次。为了能在重启后自动完成这个工作,需要注册一个广播接收器,当系统开机完成后会产生 ACTION_BOOT_COMPLETED 的广播,我们只需要在接收器里完成闹钟的重设工作即可;

  • 问题:前一个闹钟还没结束,下一个闹钟响了,导致程序出现bug

    解决办法:当闹钟的时间到时,在广播接收器里做一个判断,如果此时已经有一个闹钟的 activity 正在运行,则不启动新的闹钟的 activity。使用的是 ACTIVITY_SERVICE 服务的getRunningTasks() 方法来获得当前正在运行的任务列表。

你可能感兴趣的:(android开发)