上一篇文章对近期做的小闹钟做了功能阐述,现在来总结下整个开发过程中所用到的一些知识点:

  1.TimePicker的监听

    TimePicker控件是整个应用的核心,其它的操作都得基于对该控件的正确操控。对该控件的操作重要就是为其设置监听器,在监听事件中获取用户设置的时间。

private Calendar calendar=Calendar.getInstance();//创建calendar对象
private class OnTimeChangedListenerImpl implements OnTimeChangedListener{@Overridepublic void onTimeChanged(TimePicker view, int hour_of_day, int minutes) {// TODO Auto-generated method stubcalendar.setTimeInMillis(System.currentTimeMillis());//将timePciker的当前时间转换为Calender对象calendar.set(Calendar.HOUR_OF_DAY,hour_of_day);//设置小时calendar.set(Calendar.MINUTE,minutes);//设置分钟calendar.set(Calendar.SECOND,0);//设置秒calendar.set(Calendar.MILLISECOND,0);//设置毫秒hour=hour_of_day;//保存设置的小时minute=minutes;//保存设置的分钟
        }}

  该设计中使用Calendar类来代表特定的时间(即用户设定的闹钟时间)。Calendar类是一个抽象类,其构造方法的权限是protected,所以无法通过构造方法来创建对象,因此只能调用getInstance()进行创建。通过setTime()和getTime()两个方法实现Date和Calendar类之间的转换。

  2.PendingIntent的使用

    本设计中通过PendingIntent实现定时发送广播,从而实现闹钟功能:

Intent intent=new Intent(MainActivity.this,MyAlarmReceiver.class);//指定跳转的Inetentintent.setAction("com.example.action.setalarm");//指定intent的actionPendingIntent sender=PendingIntent.getBroadcast(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);//指定PendingIntent
alarm.set(AlarmManager.RTC_WAKEUP,MainActivity.this.calendar.getTimeInMillis(),sender);//设置闹钟

  PendingIntent字面意思为:未决定的、待定的Intent。这是第一次接触到PendingIntent,在网上也看了很多资料,但都感觉糊里糊涂的,后来看到一官网的定义,就恍然大悟了:An Intent is something that is used right now; a PendingIntent is something that may create an Intent in the future. You will use a PendingIntent with Notifications, AlarmManager, etc.关键的是其中的in the future,结合本实例,也就是当闹钟时间到的时候,PendingIntent携带的Broadcast才会被广播出去。

  3.利用Cursor数据库查询音频文件列表

  用户可以选择设备的SD卡上的音频文件作为闹钟的铃声,本设计中通过Cursor实现这一功能:

//获取SD卡上的音频文件public void scannerMusic(){//查询媒体数据库Cursor cursor=MainActivity.this.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);//遍历数据库if(cursor.moveToFirst()){while(!cursor.isAfterLast()){int id=cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));//获取歌曲编号int trackid=cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));//获取歌曲IDString album=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));//获取歌曲专辑名String artist=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));//获取歌曲歌手名String url=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));//获取歌曲路径String duration=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));//获取歌曲播放时长int size=cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));//获取歌曲大小String disName=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));//获取歌曲文件显示名字
                items.add(disName);urls.add(url);//保存歌曲路径
                cursor.moveToNext();}cursor.close();}fileList=new ArrayAdapter<String>(this,R.layout.list_item,items);}

  android设备在加载SD卡时候会自动将文件分类存放,其中音频文件就存放在MediaStore数据库中,可以通过ContentResolver来调用这些封装好的接口,接着调用qurey()方法就可以获得音频文件的列表及相关信息,query()方法原型为:

query(_uri, prjs, selections, selectArgs, order);

  该方法第一个参数为:要查询的数据库的名称加上表的名称。第二个参数为从表中选择的列。第三个参数为查询条件。第五个参数为排序条件。

  获取所有音频文件后,将音频文件的名称和相对应的路径保存在动态数组中,方便后期的调用。

  4.SharePreference完成数据存储

  本设计中用户选定了音频文件后,需要在另一个activity播放,因此用到了SharePreference来储存用户选择的音频对应的路径。

SharedPreferences sp=getSharedPreferences("mrsoft",MODE_PRIVATE);//获得私有类型的SharedPreferences
Editor editor=sp.edit();//获得Editor对象//editor对象采用KEY-VALUE形式存放editor.putString("musicurl", urls.get(item));//增加音乐地址
editor.commit();//确认提交

  SharePreferences是应用程序内部轻量级的储存方案,最常被用来储存应用的配置参数。采用SharePreference保存数据,实质上就是采用XML文件进行储存,存放的路径为:/data/data/<package name>/shared_prefs。SharePreference使用起来很方便:利用getSharePreferences()获取SharePreferences对象,该方法获取的对象可以被同应用程序下的其它组件访问。该方法有两个参数,第一个参数设定共享文件的名称,第二个参数设定共享文件的类型。接着通过edit()方法获得Editor对象,再利用Editor对象的putString()方法增加要保存的值,最后调用commit()方法提交。相应地,当需要读取已保存的数据时候可以调用getstring()方法。

  5.Adapter、AlertDialog、ListView结合使用

  Adapter其实就是数据和视图之间的桥梁,数据经过Adapter进行相应的处理后送到视图上显示出来。本设计用到的是一个String类型的数组适配器:

ArrayAdapter<String> fileList

fileList=new ArrayAdapter<String>(this,R.layout.list_item,items);

ArrayAdapter<String>里面有三个参数,第一个参数是上下文,也就是当前的activtiy,第二个参数是自定义的一个布局,说白了就是一个TextView,每一条数据都以这个布局文件的形式呈现出来,第三个参数就是要显示的数据。本设计将读取到的音频文件列表显示在一个alertdialog上,所以还需要设置Adapter与AlertDialog之间的连接:

builder.setAdapter(fileList,  new DialogInterface.OnClickListener(){@Overridepublic void onClick(DialogInterface dialog, int item) {}    });

fileList为数据适配器,第二个参数为ListView列表的单击事件监听器,当用户单击ListView列表上的内容,将采取相应的操作。

  6.Recording进行录音

    用户可以通过本应用录制自己喜欢的音频作为闹钟铃声。录音的操作和音频文件的播放差不多,实现起来也相对简单:

    private void startRecording(){    //获取MediaRecorder对象mRecorder=new MediaRecorder();//设置音频源为Micphone
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//设置封装格式
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//设置音频文件输出路径
        mRecorder.setOutputFile(mFileName);//设置编码格式
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);try{mRecorder.prepare();mRecorder.start();}catch(IOException e){e.printStackTrace();}}private void stopRecording(){try{mRecorder.stop();}catch(IllegalStateException e){e.printStackTrace();}mRecorder.release();//释放资源mRecorder=null;//清空MediaRecorder对象,这步不能少
    }

  录制过程和采用MediaPlayer播放音频过程很相似,值得注意的是,录音完毕后必须调用mRecorder.release()来释放资源,并清空mRecorder对象,否则用户再次进行录音操作时候会出现硬件资源冲突的异常,导致应用程序非正常关闭。

  7.BroadcastReceiver

    本设计通过BroadcastReceiver来启动“闹钟时间到”界面:

public class MyAlarmReceiver extends BroadcastReceiver
{@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stubif(intent.getAction().equals("com.example.action.setalarm")){Intent it=new Intent(context,AlarmMessage.class);//定制要跳转的activityit.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 传递一个新的任务标记context.startActivity(it);//启动Intent
        } }
}

  广播接收者(BroadcastReceiver)用于接收广播的Intent,通常一个广播Intent可以被订阅了该广播的多个BroadcastReceiver接收。广播是一种应用程序间进行消息传输的机制,而BroadcastReceiver是对发送出来的广播进行过滤接收并响应的一类组件,BroadcastReceiver自身并不实现图形化界面。每次广播到来时,都会重新创建BroadcastReceiver对象,并调用其onReceive方法,在该方法中不能进行一些相对耗时的操作,因为BroadcastReceiver的生命周期只有十秒钟左右的时间。有关广播的知识还有很多,这里不进行详细介绍。

  7.Vibrator

  本设计中,闹钟响起时,用户设备也伴随着震动现象。在android中,通过调用Vibrator类实现震动。

vibrator=(Vibrator) getSystemService(Context.VIBRATOR_SERVICE);//获取震动服务long pattern[]={100,400,100,400};//停止  开启  停止  开启//控制手机震动的毫秒数,其中第二个参数指定第一个数组参数的索引,-1表示只震动一次,非-1表示从指定下标(第二个参数)开始重复震动vibrator.vibrate(pattern,2);

  首先获取设备的震动服务,接着定义一个存放震动时间的数组,在Vibrator中,振动时间是以毫秒(1/1000秒)计算,因此可以通过数值的大小来控制震动的启停。最后调用vibrate方法来实现震动功能,该方法第二个参数为-1时表示只震动一次,为非-1时表示重复震动。

  8.ExitApplication

  本设计中,涉及到两个activity,因此当用户想要关闭应用时候,需要一次性将所有activity都关闭,如果在当前界面调用finish()方法,只能退出当期的activity。所以采用了以下方法来完成这一功能:

public class ExitApplication extends Application{private List<Activity> activityList=new LinkedList<Activity>();private static ExitApplication instance;private ExitApplication(){}//单例模式中,获取唯一的ExitApplication实例public static ExitApplication getInstance(){if(null == instance){instance = new ExitApplication();}return instance;}//添加activity到容器public void addActivity(Activity activity){activityList.add(activity);}//遍历所有Activity 并finishpublic void exit(){for(Activity activity:activityList){activity.finish();}System.exit(0);}
}

接着在每个在Activity的onCreate()方法中调用ExitApplication.getInstance().addActivity(this)方法。这样就可以在任意一个activity退出时调用ExitApplication.getInstance().exit()方法,完全退出应用程序了。

转载于:https://www.cnblogs.com/dream550/p/3873916.html

android闹钟小案例之知识点总结相关推荐

  1. android studio小案例代码,AndroidStudio开发小相册实例

    郑州app开发AndroidStudio开发小相册实例代码如下. 布局代码如下: java代码如下: package cn.xhhkj.xhhkjtest; import android.app.Ac ...

  2. Android入门小案例,制作登陆页面跳转

    这个案例,主要目的是带着大家理解Android开发的基础知识,与UI布局以及点击事件,方便大家能更好的入门.至于如何创建一个Android项目这里就不在过多阐述.笔者这里使用的开发工具是IDEA,语言 ...

  3. android闹钟的需求分析,手机小闹钟需求分析

    Android 手机小闹钟 日常生活工作中,时常会有一些重要事情或日程安排,而闹钟作为一种提醒人们的工具,成为很多人生活中不可或缺的一部分. 本软件包括的功能有闹钟设置.闹钟创建.闹钟关闭等模块.本应 ...

  4. android小闹钟程序,Android实现闹钟小程序.pdf

    Android实实现现闹闹钟钟小小程程序序 这篇文章主要为大家详细介绍了Android实现闹钟小程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 最近写了 闹钟的程序,看到SharedPrefe ...

  5. 【Android笔记65】Android小案例之简易版的房贷计算器(附源代码)

    这篇文章,主要介绍如何使用Android实现一个简易版的房贷计算器小案例. 目录 一.房贷计算器 1.1.运行效果演示 1.2.前提准备 (1)等额本息和等额本金

  6. Python Selenium之等待元素小案例(用于某网站自动打开领取QQ名片赞)--文末有附selenium知识点以及对应学习文档网址

    ''' Author: Liang LastEditors: Liang Date: 2020-10-08 11:41:09 LastEditTime: 2020-10-21 13:46:21 Ema ...

  7. android 简易闹钟,android简易小闹钟

    实现效果:点击主活动上的按钮,弹出一个带有时间选择器的对话框(TimePickerDialog),设置时间后Toast"设置成功".到设置的时间后在AlarmActivity弹出显 ...

  8. Android学习之路(4)——小案例

    本案例完成一个装备案例 看下我们需要完成的效果: 登录界面(activity_register.xml) 信息界面(activity_info.xml) 角色界面(activity_char.xml) ...

  9. 【Android笔记41】使用Android实现一个简易版本的购物车小案例

    这篇文章,主要是使用Android实现一个简易版本的购物车小案例. 目录 一.购物车案例 1.1.创建主界面 (1)主界面布局样式 (2)商品列表Fragment

最新文章

  1. linux 学习 14 日志管理
  2. win8下cocos2dx-3.2+VS2012环境配置及项目创建
  3. 【空间数据库技术】ArcSDE 10.1安装配置与企业级地理空间数据库的建立及连接
  4. Vue Axios的配置 (高仿饿了么)
  5. Revit二次开发 - C#程序员的佳好选择
  6. 将input file的选择的文件清空的两种解决方案
  7. oracle 由非归档到归档模式
  8. 纯新手DSP编程--5.21--RTDX
  9. 网络通信之通过get/post方式提交参数给web应用
  10. c语言起点到目的地方法数,最短路径动态规划问题及C语言实现探讨
  11. 2022G2电站锅炉司炉考试试题及答案
  12. arcgis python计算面积_如何在ARCMAP里面计算面积
  13. 各大互联网公司开放平台一览
  14. cmaq实践学习-飓风案例运行bcon icon mcip cctm脚本修改运行
  15. SIRO Challenge 状态压缩 + DP 未解
  16. mongoDB--初识mongoDB安装过程
  17. 前端存储之cookie、localStorage、sessionStorage、indexDB
  18. 微信气泡主题设置_微信猫和老鼠主题皮肤怎么设置 华为手机设置气泡主题方法...
  19. day2(sdasdasdasdasd)
  20. 微信小程序授权登录和获取手机号功能(详细)

热门文章

  1. 安防流媒体无插件直播管理设计
  2. anaconda利用pip安装module
  3. appuim+python+MUMU模拟器连接方法
  4. U盘文件丢失了怎么办?一串英文字符即可快速帮你找回,秒学!
  5. Android Studio之Error:(158) Error: Expected resource of type id [ResourceType]
  6. 把linux当无线路由器用,基于树莓派的无线路由器改造
  7. matlab 怎么使用mathtype,教你怎样在Authorea里面使用MathType
  8. 计算机的主要配件是哪两个,组成计算机cpu的两大部件是什么
  9. VSCode 单文件编译 与 多文件编译(windows)
  10. HTTP之(二)HTTP协议简介