如何开发一款Android闹钟应用?

        Android里面实现定时任务的方式有多种,比如常用的Handler、Timer、Thread、ScheduledExecutorService,虽然这几种方法都可以实现,但是用来处理定时任务(闹钟)并不理想。

        Handler一般用于通知UI线程刷新UI,Timer用来做定时器,比如计数,这两种方式只适合处理短时间的计时任务。线程Thread可以Sleep,但是会阻塞主线程,ScheduledExecutorService主要用来周期性处理任务队列,比如它的实现类Executors.newSingleThreadScheduledExecutor可以用来处理app的批量安装、卸载,Executors.newScheduledThreadPool(int size)用来并发周期性处理耗时任务。

        那么用什么api来实现比较好呢?Android为我们推荐android.app.AlarmManager,文档里有note描述:

The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running. For normal timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler

知道AlarmManager后,那么问题来了,该如何使用该类去实现定时任务呢?

AlarmManager有以下API:

    /*
     * Schedule an alarm
     */
    public void set(int type, long triggerAtMillis, PendingIntent operation) 

    /*
     * Schedule an repeating alarm
     */
    public void setRepeating(int type, long triggerAtMillis,
            long intervalMillis, PendingIntent operation) 

    /*
     * Schedule an alarm to be delivered within a given window of time.
     */
    public void setWindow(int type, long windowStartMillis, long windowLengthMillis,
            PendingIntent operation)

    /*
     *Schedule an alarm to be delivered precisely at the stated time.
     */
    public void setExact(int type, long triggerAtMillis, PendingIntent operation)

    /*
     * Schedule a repeating alarm that has inexact trigger time requirements;
     */
    public void setInexactRepeating(int type, long triggerAtMillis,
            long intervalMillis, PendingIntent operation) 

    /*
     * Remove any alarms with a matching
     */
    public void cancel(PendingIntent operation)

通过文档描述可知实现单次任务可以使用set()、setWindow()、setExact方法,实现重复任务可以使用setRepeating()和setInexactRepeating(),下面使用set和setrepeating方法来测试,由于方法参数中均涉及到类PendingIntent ,所以先来研究下该类的使用方法。

PendingIntent 是一个有着明确action的意图,这里介绍三种最常用的api

/*
 * Retrieve a PendingIntent that will start a new activity, like calling
 * {@link Context#startActivity(Intent) Context.startActivity(Intent)}.
 */
public static PendingIntent getActivity(Context context, int requestCode,Intent intent, int flags)

/*
 * Retrieve a PendingIntent that will perform a broadcast, like calling
 * {@link Context#sendBroadcast(Intent) Context.sendBroadcast()}.
 */
public static PendingIntent getBroadcast(Context context, int requestCode,Intent intent, int flags)

/*
 * Retrieve a PendingIntent that will start a service, like calling
 * {@link Context#startService Context.startService()}. 
 */
public static PendingIntent getService(Context context, int requestCode,Intent intent, int flags)

利用这三个函数可以在任务时间到时根据业务需求分别触发Activity、Broadcast和Service,其中中参数requestCode需要保证唯一性,否则会出现闹钟不响应问题。下面就编写一个测试案例,实现单次闹钟和重复闹钟。

    /**
     * 设置单次闹钟,5秒后响应,然后发送广播"mytestbroadcast"
     * AlarmManager.ELAPSED_REALTIME_WAKEUP :从设备开机后开始计时
     */
    private void testSet(){
        Intent intent = new Intent("mytestbroadcast");
        PendingIntent sender = PendingIntent.getBroadcast(mContext, getUniqueCode(), intent,PendingIntent.FLAG_UPDATE_CURRENT);
        alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+5000, sender);
    }
    
    /**
     * 设置单次闹钟,5秒后响应第一次,然后每隔10s响应一次,每次响应时发送广播"mytestbroadcast"
     * AlarmManager.ELAPSED_REALTIME_WAKEUP :从设备开机后开始计时
     */
    private void testSetRepeat(){
        Intent intent = new Intent("mytestbroadcast");
        PendingIntent sender = PendingIntent.getBroadcast(mContext, getUniqueCode(), intent,PendingIntent.FLAG_UPDATE_CURRENT);
        alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+5000,10000, sender);
    }

这样写看上去没有问题,但是真正在机器上运行时会发现,闹钟响应的时间不准确,特备是时间间隔越长的闹钟,时间的偏离让人无法捉摸。到底是什么原因导致set和setRepeating不准确?.............百思不得姐...........翻阅了很多文章之后终于有结论了,原来android为了优化系统性能,对任务的调度做了处理,当你设置一个闹钟后,系统会协调系统资源后重新计算闹钟响起的时间,这个时间差没有准确的计算,从而导致的闹钟不准确问题。

那么为什么手机rom里的闹钟应用不存在这个问题呢?比如小米/华为自带的闹钟就不存在这种问题,方案可能有两个:

1.rom应用一般是厂家自己开发,Framework层可能会做特殊处理,比如新增api供自己调用,这个第三方app是不知道的。

2.应用自身做处理,规避系统级的问题。

对于第二种解法,到底该如何去做?做法可能有很多,我在开发的过程中想到了一种(如果有其他方法,请回复交流交流哦),下面做详细介绍:

AlarmManager设置单次任务的方法不只一种,如setWindow,setExact,api介绍都可以实现精确任务,实测之后发现setWindow是可以的,setExact好像不可以(时间有点久,有点记不清了。。),这样的话实现单次闹钟就没有多大问题了。但是重复的闹钟该如何实现呢?  想了想其实很简单,重复的闹钟也是由单个闹钟组成的,只不过这些闹钟是按照特定的时间排序了而已。

具体的实现思路可以通过一个例子说明,比如现在时间是上午10点,我设定一个每天早上7点中的闹钟,使用方法setWindow()和PendingIntent.getBroadcast()来实现,等到第二天的7点钟时,会有一个广播发出来,接收这个广播之后可以做响铃或者震动处理,接着是特别重要的一步,提醒完用户之后就要开始计算下次闹钟响铃的时间了,这样循环下去就像是接力赛一样,问题迎刃而解。

主要问题解决了,但是如果用户在同一时间设置了多个闹钟怎么办?作为一款人性化的app,允许用户这样操作,这是个不得不考虑的一个场景,那么该响应第一个还是最后一个闹钟?如果响应第一个该怎么办?如果响应最后一个该怎么办?问题的解决方法总不止一种,比如利用service的唯一性便可解决这个问题。当几个闹钟同时响应时,接收到广播后将闹钟转发至service,在service中建立一个队列,虽说是同时的闹钟,但总有先后顺序(已实测验证过),将这些闹钟加入队列,取第一个还是最后一个就看业务需求了,该问题便解决了。

到这为止整个软件的技术难点就已经打通了,接下来就是软件的架构和数据库设计问题。由于软件定位是闹钟类,所以整个构架不会很复杂,也没有必要非得引入各种牛X的框架,但是你要是有这个爱好,那也不反对,比如一些注解类的、图片缓存类的、网络请求类的、数据库类的、事件类的等等(volley/eventbus/afinal/thinkandroid/xutils/androidanimation....),下面图中做简要说明,由于涉及到公司隐私,所以把一些关键字用xxxx代替

   

这里一共分了13个包,具体的分类可视具体的业务而定,比如audio包,因为涉及到录音所以单独开辟了一个包来做录音功能的处理,接下来就是代码实现了。

思路都有了,编码不还简单?大家充分发挥自己就可以啦!!

如果大家有什么想法,欢迎回复交流~~~

 

 

转载于:https://my.oschina.net/wangyujue1991/blog/685336

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android Studio是一款非常流行的Android应用开发工具,可以用它来开发各种类型的应用程序,包括闹钟应用开发闹钟应用需要掌握Android的基本知识,如布局、控件、事件处理等。同时,还需要了解闹钟的相关知识,如时间、提醒方式等。在Android Studio中,可以使用AlarmManager类来实现闹钟功能,通过设置闹钟的时间和提醒方式,让用户在指定时间收到提醒。开发闹钟应用需要注意用户体验,如设置闹钟的界面设计、提醒方式的选择等,这些都需要考虑到用户的需求和习惯。 ### 回答2: Android Studio是一款专为Android应用开发而设计的强大集成开发环境。闹钟是一种常见的应用程序之一,可以在指定的时间点响起以提醒用户。下面是使用Android Studio开发闹钟的步骤: 1. 创建一个新的Android项目:打开Android Studio并创建一个新的Android项目。选择项目名称和存储位置,并选择所需的最低Android API级别。 2. 创建闹钟界面:使用XML布局文件创建闹钟界面。可以添加TextView显示当前时间,以及Button用于设置闹钟。 3. 设置闹钟功能:在Java代码中添加设置闹钟的功能。这可以通过使用AlarmManager和PendingIntent来实现。可以使用DatePicker和TimePicker选择日期和时间,并将其与AlarmManager进行关联。 4. 添加响铃功能:在闹钟时间到达时应该触发响铃功能。可以使用MediaPlayer来播放想要的铃声。可以设置马上停止或者稍后再停止的选项,以及设置响铃间隔。 5. 测试和调试:运行应用程序以测试闹钟功能。可以在模拟器或实际的Android设备上进行测试,并调试任何错误或问题。 6. 优化和改进:根据需要进行进一步的优化和改进。可以添加更多功能,例如重复闹钟,震动提醒等。 总结起来,使用Android Studio开发闹钟需要创建一个新的Android项目,设计闹钟界面,添加设置和响铃功能,进行测试和调试,以及最后优化和改进。这些步骤可以帮助开发者实现一个完整的闹钟应用程序。 ### 回答3: Android Studio 是开发Android应用程序的集成开发环境。想要开发一个闹钟应用程序,首先要创建一个新的Android项目。在项目中,需要设计一个界面来展示闹钟的时间和设置。 在Android Studio中,可以使用XML来设计界面。可以使用TextView来显示当前时间,使用Button来设置闹钟。可以将时间数据存储在一个变量中,并在TextView中动态显示。 在闹钟设置按钮的点击事件中,可以使用TimePickerDialog或DatePickerDialog来让用户选择闹钟的时间。可以将用户选择的时间保存在变量中,并更新TextView的显示。 在闹钟时间到达时,可以使用AlarmManager来触发一个广播,通知用户闹钟的响铃。可以在广播接收器中编写逻辑,实现闹钟响铃的功能。可以使用MediaPlayer来播放音乐或声音。 除了响铃功能,还可以设计其他功能,比如闹钟的重复设置、闹钟关闭按钮等等。可以根据需求在界面中添加相应的控件,并在代码中实现相应的逻辑。 在开发过程中,可以使用Android Studio的调试工具来调试应用程序,以及使用模拟器或真机测试应用程序的运行和效果。 最后,完成开发后,可以将应用程序导出为apk文件,然后安装在Android设备上使用。 总结来说,要在Android Studio开发一个闹钟应用程序,需要设计界面、处理用户操作、保存数据、触发闹钟响铃等等。在使用Android Studio的过程中,可以参考官方文档、在线教程以及社区论坛,结合自己的实践和创意,实现一个功能完善的闹钟应用程序。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值