摘 要
当今社会的生活节奏越来越快,随着硬件移动设备的越来越先进,人们对移动设备的要求也越来越高,从以前的追求技术到现在的追求视觉,因此,也逐步的提高了对系统的要求,本文主要是对Android系统上音乐播放器应用程序的设计与实现进行讨论。本论文的音乐播放器采用了Android开源系统技术,利用Java语言和Eclipse编辑工具对播放器进行编写,同时给出了详细的系统设计过程、部分界面图及主要功能运行流程图,本文还对开发过程中遇到的问题和解决方法进行了详细的讨论,该音乐播放器集播放、暂停、停止、上一首、下一首、音量调节、歌词显示等功能于一体,性能良好,在Android系统中能独立运行。该播放器还拥有对手机文件浏览器的访问功能、歌曲播放模式、以及歌词开闭状态的友好设置。通过对基于Android平台下的播放器的设计,了解音乐播放器的设计的原理和实现的相关技术,掌握了Android编程思想以及基本的应用组件,对以后从事Android开发有很大的帮助。
关键字:Android;开源系统;音乐播放器;Java
Abstract
In todays society pace of life more and more quickly, with hardware mobile devices are becoming more and more advanced, people on mobile equipment requirements are increasingly high, from the former the pursuit of technology to present the pursuit of vision, therefore, it is also gradually improve the system requirements, this paper is mainly to the Android system music player applications design and implementation are discussed. In this paper the music player using the Android open source system technology, the use of Java and Eclipse editing tool for players to write, and at the same time, gives the detailed system design process, part of the interface diagram and main function operation flow diagram, this paper also on the development process met the question and the solution methods are discussed in detail, this music player set play, pause, stop, a, a, volume control, lyrics display function at an organic whole, the performance good, in Android system can operate independently. The player has to mobile phone file browser access function, songs play mode, and the lyrics open close friendly Settings. Through the Android platform based on the design of the player, understanding the music player, the design principle and implementation of related technologies, master the Android programming thought and basic application components, for future development in Android will be of great help.
Key word: Android; Open source system; Music player; JAVA
毕业论文(设计)原创性声明
本人所呈交的毕业论文(设计)是我在导师的指导下进行的研究工作及取得的研究成果。据我所知,除文中已经注明引用的内容外,本论文(设计)不包含其他个人已经发表或撰写过的研究成果。对本论文(设计)的研究做出重要贡献的个人和集体,均已在文中作了明确说明并表示谢意。
作者签名: 日期:
毕业论文(设计)授权使用说明
本论文(设计)作者完全了解**学院有关保留、使用毕业论文(设计)的规定,学校有权保留论文(设计)并向相关部门送交论文(设计)的电子版和纸质版。有权将论文(设计)用于非赢利目的的少量复制并允许论文(设计)进入学校图书馆被查阅。学校可以公布论文(设计)的全部或部分内容。保密的论文(设计)在解密后适用本规定。
?
作者签名: 指导教师签名:
日期: 日期:
注 意 事 项
1.设计(论文)的内容包括:
1)封面(按教务处制定的标准封面格式制作)
2)原创性声明
3)中文摘要(300字左右)、关键词
4)外文摘要、关键词
5)目次页(附件不统一编入)
6)论文主体部分:引言(或绪论)、正文、结论
7)参考文献
8)致谢
9)附录(对论文支持必要时)
2.论文字数要求:理工类设计(论文)正文字数不少于1万字(不包括图纸、程序清单等),文科类论文正文字数不少于1.2万字。
3.附件包括:任务书、开题报告、外文译文、译文原文(复印件)。
4.文字、图表要求:
1)文字通顺,语言流畅,书写字迹工整,打印字体及大小符合要求,无错别字,不准请他人代写
2)工程设计类题目的图纸,要求部分用尺规绘制,部分用计算机绘制,所有图纸应符合国家技术标准规范。图表整洁,布局合理,文字注释必须使用工程字书写,不准用徒手画
3)毕业论文须用A4单面打印,论文50页以上的双面打印
4)图表应绘制于无格子的页面上
5)软件工程类课题应有程序清单,并提供电子文档
5.装订顺序
1)设计(论文)
2)附件:按照任务书、开题报告、外文译文、译文原文(复印件)次序装订
3)其它
目录
第一章 引言 3
1.1. 选题目的及意义 3
1.2. 项目背景 4
第二章 系统需求分析 4
2.1. 功能需求 4
2.2. 系统界面需求 7
2.3. 系统性能需求 8
2.4. 运行环境需求 8
第三章 安卓项目介绍 9
3.1. 安卓简介及优点 9
3.2. 搭建安卓开发环境 10
3.3. Andriod 音乐播放器项目工程设计 12
第四章 安卓数据库设计 16
4.1. 数据库及字段属性 16
4.2. 数据库连接 18
第五章 播放器系统功能的实现 20
5.1. 播放器主界面功能实现 20
5.2. 播放列表显示 27
5.3. 菜单功能实现 28
5.4. 播放界面实现 29
5.5. 歌词显示 30
5.6. 手机扩展卡的访问 31
第六章 系统测试 32
第七章 总结 33
引言
选题目的及意义
当今社会的生活节奏越来越快,人们对手机的要求也越来越高,由于手机市场发展迅速,使得手机操作系统也出现了不同各类,现在的市场上主要有三个手机操作系统有塞班
图 2-1
如上图2-1所示:本软件主界面用户功能控制需求有播放、暂停、停止、上一曲、下一期、音量控制、静音控制、界面歌词显示、进入播放清单、播放文件、退出功能。
当用户选中某一首歌曲的时候操作功能如图2-2所示:
图 2-2
如图2-2所示:当用户需要对特定某首歌曲进行操作时,播放器提供的功能有播放、详细属性、加入铃声库、增加歌曲、从播放器音乐列表移除、把全部歌曲从音乐列表中移除、进入设定界面功能。
循环播放友好型有三种:单曲循环、顺序循环和随机循环。如下图所示:
图 2.3
播放器扩展卡需求
播放器扩展卡需求是用户对播放器音乐对手机的文件浏览器的需求。文件浏览器可以搜寻手机音乐、SD卡音乐。目标是手机和内存卡上的mp3格式或WAV格式的音乐文件。如图2.4所示:
图 2.4
系统界面需求
用户界面是一个应用程序很重要的一面——它直接影响程序的使用价值。对于大多数用户来说,用户界面就是他们对一个产品的大致的了解。所以对他们来说,一个内部设计良好但用户界面不好的应用程序就是一个不好的程序。
说到底一句话:一个优秀的用户界面即是一个直观的、对用户透明的界面:用户在首次接触了这个软件后就觉得一目了然,不需要多少培训就可以方便地上手使用,而且用户在使用过程中甚至会获得愉悦快乐的心情。说起来很简单,可是在实际开发中,真正能够做到这一点却很不容易的。为了减少工作量本播放器界面为个人项目设计素材。
播放器主界面如图2.5所示:
图 2.5
系统性能需求
根据Android手机系统要求无响应时间为5秒,所以就有如下性能要求:
当要求歌曲播放时,程序响应时间最长不能超过5秒
当要求歌曲暂停时,程序响应时间最长不能超过5秒
当要求歌曲停止时,程序响应时间最长不能超过5秒
当要求歌曲上/下一首时,程序响应时间最长不能超过5秒
当要求进行清单列表时,程序响应时间最长不能超过5秒
运行环境需求
操作系统:Android手机基于Linux操作系统
支持环境:Android 2.0.3 - 4.0.0版本
开发环境:Eclipse 3.5 ADT 0.95
第三章 安卓项目介绍
安卓简介及优点
安卓简介
图 3.1
Android一词的本义指“机器人”,如上图3.1所示。同时也是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件。
Android是基于Linux内核的软件平台和操作系统,早期由Google开发(在华注册商标名为“安致”),后由开放手机联盟(Open Handset Alliance)开发。它采用了软件堆层(software stack,又名以软件叠层)的架构,主要分为三部分。低层以Linux内核工作为基础,只提供基本功能;其他的应用软件则由各公司自行开发,以Java作为编写程序的一部分。另外,为了推广此技术,Google和其它几十个手机公司建立了开放手机联盟。
2010年10月份,谷歌宣布Android系统达到了第一个里程碑,即电子市场上获得官方数字认证的Android应用数量已经达到了10万个,Android系统的应用增长非常迅速。在2010年12月,谷歌正式发布了Android 2.3操作系统Gingerbread (姜饼)。
2011年1月,谷歌称每日的Android设备新用户数量达到了30万部,到2011年7月,这个数字增长到55万部,而Android系统设备的用户总数达到了1.35亿,Android系统已经成为智能手机领域占有量最高的系统。
2011年8月2日,Android手机已占据全球智能机市场48%的份额,并在亚太地区市场占据统治地位,终结了Symbian(塞班系统)的霸主地位,跃居全球第一。
2011年9月份,Android系统的应用数目已经达到了48万,而在智能手机市场,Android系统的占有率已经达到了43%。继续在排在移动操作系统首位。在本月19号,谷歌将会发布全新的Android 4.0操作系统,这款系统被谷歌命名为Ice Cream Sandwich(冰激凌三明治)。
2012年1月6日,谷歌Android Market已有10万开发者推出超过40万活跃的应用,大多数的应用程序为免费。Android Market应用程序商店目录在新年首周周末突破40万基准,距离突破30万应用仅4个月。而在2011年早些时候,Android Market从20万增加到30万应用也花了四个月。
安卓优点
Andriod 有如下八大优点:
应用程序框架 支持组件的重用与替换
Dalvik虚拟机 专门为移动设备做了优化
内部集成浏览器 该浏览器基于开源的WebKit引擎
优化的图形库 包括2D和3D图形库,3D图形库基于OpenGL ES SQLite 用作结构化的数据存储
多媒体支持 包括常见的音频、视频和静态印象文件格式(如 MPEG4, H.264, MP3, AAC, AMR, JPG, PNG, GIF)
GSM电话(依赖于硬件)蓝牙Bluetooth, EDGE, 3G, and WiFi (依赖于硬件)照相机,GPS,指南针,和加速度计 (依赖于硬件)
丰富的开发环境 包括设备模拟器,调试工具,内存及性能分析图表,和Eclipse集成开发环境插件
搭建安卓开发环境
任何事物要运行,都要有它的环境,Android也有它的环境才能够运行,下面介绍Android的开发环境配置。
搭建开发环境需要的软件有:
操作系统:Windows
软件包:Android SDK(Software Development kit Java Development kit) 、ADT(Android Develoopment Tool)
IDE环境:Eclipse IDE+ADT Eclipse2.3以上
JDK:Java Runtime Environment虚拟机 、(JDK)Java Development kit
安装步骤如下:
第一步:安装Java虚拟机sun-java6-jdk版本
第二步:安装Eclipse3.5工具 官网/downloads/
选择版本(图3.2):进行安装
图 3.2
第三步:安装Android SDK:首先要下载SDK,可以在这个网址下载Http:///sdk ,选择相应的系统进行安装.如3.3所示:
图 3.3
第四步:安装Android ADT插件
运行Eclipse,选择help-install new software 选择add,将会弹出一个对话框,点击OK,选择要安装的软件,占next,然后选择接受协议,直到安装成功,重启Eclipse软件,设置Android SDK Home,Window-refrence在SDK location中输入SDK Tools路径:D:\android software\android-sdk-windows 点击OK这样Android环境就已经搭建成功了,如图2.4所示:
图 3.4
Andriod 音乐播放器项目工程设计
Andriod 项目
Android的四大基本组件:Activity(活动),Service(服务),Broadcast Receiver(广播),Content Provider(内容提供者),各组件之间要进行切换需要一个意图或企图Intent类,通过启动Start Intent()方法来使各组件进行跳转。
Android的五大布局方式:Linear Layout(线性布局) Frame Layout(帧布局) Table Layout(表格布局) Absolute Layout(绝对布局) Relative Layout(相对布局)。五种布局方式可以相互嵌套,Android各种漂亮的界面都是通过嵌套布局而实现的。
Android的线程,以及线程之间通信的中介:Handler类
Android数据库:在第三章已经介绍过了。这里不再介绍
Android配置文件:Android Manifest.Xml及res资源文件中各种属性 布局方式 引用的资源等
Android系统将插件ADT集成到了Eclipse工具上,因此,一个Android程序启动后,系统会启动一个模拟器(Emulator)如下图3.5:
图 3.5
Andriod 工程程序设计
Android工程基本结构目录包括:src (源代码)、gen(Android系统自动生成的常量)、Res(资源文件):主要存放程序界面的布局配置(.xml)文件和图片资源。Android Mainfes.xml 是四大组件的驱动配置文件,有它的存在,Android程序的四大组件才可以正常的跳转。
下图3.6是音乐播放器代码结构:
图 3.6
图3.6内容为该播放器的.Java文件、播放器所用到的字符串,字体大小、字的颜色等配置文件、该播放器的各种界面的布局配置文件及该播放器的图片资源,如图3.7所示:
图 3.7
Android Manifest.xml文件
Android系统的任何一个程序启动都需要Android Manifest.xml来启动程序,任何一个新建的工程目录都会自动生成一个Android Manifest.xml文件,此配置文件是整个程序能够正常运行的核心,它里面包含了Android SDK的版本,程序运行的默认Activity,当程序中的任何一个组件触发事件后,系统都会自动的去Android Manifest.xml中寻找标识来作出相应的操作。任何一个Android Manifest.xml文件的格式都应为:
?xml version=1.0 encoding=utf-8?
manifest
application
activity
intent-filter
action/category/
/intent-filter
/activity
/application
uses-sdk /uses-permission /
/manifest
Android系统有一个编码的规定,支持的编码是utf-8,当程序中出现乱码是,我们须将其编码格式转化为utf-8.在 Android Manifest.xml中会在第一行声明一句:?xml version=1.0 encoding=utf-8?。它是该系统支持的版本和编码。在第二行定义了我们需要使用的架构,该架构来自xmlns:android=/apk/res/androidxmlns(XML name space)是一个命名空间。
在application元素我们定义android:icon=@drawable/icon
android:label=@string/app_name,android:icon是程序在手机中显示的图片,我们运用@drawable/icon表示了对res/drawable目录下的icon.png的引用。@string/app_name表示了对res/value目录下string.Xml中定义的app_name参数的引用。
activity android:name=.Play Rack Activity
intent-filter
action android:name=ent.action.MAIN/
category android:name=ent.category.LAUNCHER /
/intent-filter
/activity
这是系统确定的首先要启动的Activity是Play Rack Activity。
过滤器intent-filter 有两种启动方式来启动界面:
显示方式
显示方式是在代码中的直接启动组件,启动时会声明Intent,在它的构造方法Intent(组件1,组件2)中直接指定一个组件的名字,然后调用方法start Intent(intent)以启动指定的组件。
隐式方式
隐式方式是通过过滤器来过滤完成的,启动的组件必须满足action和category的条件才能够启动该组件。这些属性是在Android Manifest.Xml文件中声明的。两种启动方式都可以通过程序set Action(ACTION常量)和start Activity(intent)或配置文件两种方式来实现组件的跳转。
安卓数据库设计
数据结构组织和数据库文件设计要根据不同用途,使用要求等,来决定数据的整体组织形式等一系列问题。
数据库,顾名思义,是存放数据的仓库。只不过这个仓库是在计算机存储设备上,而且数据是按一定的格式存放的。数据库中的数据按一定数据模型组织、描述和存储,具有较小的重复度、较高的数据独立性和易扩展性,并且可以被在一定范围内的各种用户共享。在涉及数据库的软件开发中,需要根据有待解决的问题性质、规模,以及所采用的前端程序创建工具等,做出合适的数据库类型选择。
数据库及字段属性
字段设计
file_table 主要是保存歌曲名字、类型、路径
字段说明:Id 歌曲id号 fileName 歌曲名字 filePath 歌曲路径 sort 歌曲类型(表4.1、图4.2)
属性 数据类型 允许空 主键 _Id INTEGER Not null Primary key fileName TEXT Not null filePath TEXT sort INTEGER 表 4.1
列名 数据类型 长度 字段描述 _Id integer 5 编号,主键 groupid integer 5 组编号 Music-id integer 5 歌曲编号 表 4.2
Android自带一个MediaStore封闭类 专门来存储媒体信息
通过Uri EXTERNAL_CONTENT_URI 来访问SDcard中的歌曲详细信息。
存放媒体信息如TITLE(标题)、ARTIST(艺术家)、ALBUM(专辑)、SIZE(大小 )如图4.3与图4.4所示:
图 4.3 歌曲列表
图 4.4 歌曲属性
音乐播放器E-R图
音乐播放器 E-R(实体-联系:entity-relation图),歌曲的信息有歌曲名字、发行年份、流派名称、专辑名称、艺术家名称、曲目号码。歌曲的排列形成播放列表。列表有自己的编号,同时也给组成列表的歌曲名字分配编号。播放器通过函数查询歌曲数量,然后显示给用户。如图4.5所示:
图 4.5 音乐播放器E-R图
数据库连接
这里将介绍如何进行Android数据库连接,Android中自带SQLite数据库,这是一个十分小型的数据库,这样正适合Android这种移动平台使用。
Android数据库存储的位置在data/data/项目文件夹/databases/目录下 。Android是利用ContentProvider作为内容提供商,SQLiteOpenHelper数据库帮助类来进行对数据库的创建和操作。通过Context.getContentResolver()方法直接对数据库进行操作。程序中数据库类为DBHelper extends SQLite Open Helper(继承关系),内容提供类DBProvider extends Content Provider(继承关系)。
创建数据库
Android 提供了标准的数据库创建方式。继承SQLiteOpenHelper ,实现onCreate 和 onUpgrade 两个方法,有个好处就是便于数据库版本的升级,连接数据库的算法如下:
public DBHelper(Context context) {// 创建数据库
super(context, DATABASE_NAME,null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {// 创建时调用
db.execSQL(DATABASE_CREATE);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 版本更新时调用
db.execSQL(DROP TABLE IF EXISTS File_Table);
onCreate(db);
}
@Override // 在ContextProvider运行时自动创建数据库
public boolean onCreate() {
dbOpenHelper= new DBHelper(getContext());
return true;
}
数据库如果创建不成功则抛出FIleNotFoundException异常
操作数据库
Android对数据库的操作主要有插入、删除、更新、查询操作,在进行任何操作时都必须指定一个Uri,才能对相应的表进行数据操作。
//数据库删除操作
@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
try {
Db.delete(FileColumn.TABLE, arg1, arg2);
} catch (Exception ex) {
ex.printStackTrace();
}return 1;
}
@Override//数据库插入操作
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
long count = 0;
try { count = db.insert(FileColumn.TABLE, null, values);
} catch (Exception ex)
{ ex.printStackTrace(); }
if (count 0) return uri;
else return null;
}
数据显示
程序是利用Cursor游标类指向数据表中的某一项,然后进行查询数据,用Log日志显示出来。
@Override//数据库查询操作
public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
// 依次参数为:表名,查询字段,where语句,替换,group by(分组),having(分组条件),order by(排序)
Cursor cur = db.query(FileColumn.TABLE, projection, selection,selectionArgs, null, null, sortOrder);return cur;}
播放器系统功能的实现
播放器主界面功能实现
主界面是用户使用软件的的第一个视野图,也是用户对软件风格的第一印象图,很大影响用户对使用软件的评价,尤为重要。
主界面显示
播放器主界面如图5.1所示:
图 5.1
Android的每一个可视化界面,都有其的唯一的布局配置文件,该文件里面有各种布局方式,和各种资源文件如图像,文字,颜色的引用,程序在运行时,可以通过代码对各配置文件进行读取。这样就可以形成不同的可视化界面和炫丽的效果。播放器主界面是一个Activity,Android工程在每个activity启动的时候会首先执行Oncreate()方法,如下代码:
@Override
Public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.play_rack);}
该方法主要执行界面的初始化操作,Activity有个设置布局的方法:Context.setContentView(layoutResID),参数为资源ID,该Id在工程目录res/layout下,主界面布局文件名为play_rack。
下面为play_rack.xml布局文件代码结构如下:
?xml version=1.0 encoding=utf-8?
AbsoluteLayout
LinearLayout /LinearLayout
SeekBar/SeekBar
LinearLayout/LinearLayout
/AbsoluteLayout
在绝对布局AbsoluteLayout下嵌套两种线性布局LinearLayout和SeekBar,第一个LinearLayout实现了标题和歌曲名的显示位置,通过AbsoluteLayout布局设置LinearLayout绝对坐标来控制标题的位置。每个布局内可以放置多种Widget(窗体部件)例如:TextViewImageButton等。每个Widget内有多种属性,可以设置该Widget的坐标,大小,背景和颜色等参数。在播放界面中,歌词显示为居中,实现方法代码如下:
LinearLayout android:orientation=horizontal
android:gravity=centerandroid:layout_height=wrap_content android:layout_width=fill_parent
TextView android:layout_height=wrap_content
android:textColor=#8deeee android:id=@+id/lrcText
android:layout_width=wrap_content/TextView
/LinearLayout
属性:
orientation=horizontal:此线性布局的子部件为水平方式布局 Layout_width=fill_content :布局的宽度为填满父布局
Layout_height=wrap_content :布局的高度子由窗体的大小决定
窗体TextView 文本 :textColor=8deeee 设置文本显示的颜色RGB为 8deeee
TextSize为默认大小
播放器主界面音轨的实现
播放器音轨Seek Bar的实现如图5.2所示:
图 5.2 音轨
在play_rack.Xml配置文件中,SeekBar的代码如下:
SeekBar android:id=@+id/seekbar android:layout_width=245px
android:layout_height=20px android:layout_x=40px android:layout_y=260px
android:progressDrawable=@drawable/seekbar_style android:thumb=@drawable/thumb
android:paddingLeft=18px android:paddingRight=15pxandroid:paddingTop=5px android:paddingBottom=5px android:progress=0
android:max=100 android:secondaryProgress=0
/SeekBar
上面代码中有参数android:thumb=@drawable/thumb 为音轨游标的图片资源android:progressDrawable=@drawable/seekbar_style为SeekBar条的风格style。引用了drawable中的seekbay_style.xml文件,seekbay_style.Xml是自定义的配置文件,算法如下:
?xml version=1.0 encoding=utf-8?
layer-list xmlns:android=/apk/res/android
item android:id=@android:id/background
shapecorners android:radius=5dip /gradient android:startColor=#ff9d9e9d android:centerColor=#ff5a5d5a android:centerY=0.75 android:endColor=#ff747674 android:angle=270 //shape/item
item android:id=@android:id/secondaryProgress
clipshapecorners android:radius=5dip /
gradient android:startColor=#80ffd300 android:centerColor=#80ffb600 android:centerY=0.75
android:endColor=#a0ffcb00 android:angle=270 /
/shape/clip/item
item android:id=@android:id/progress
clipshapecorners android:radius=5dip /gradient android:startColor=#ff0099CCandroid:centerColor=#ff3399CC android:centerY=0.75android:endColor=#ff6699CC android:angle=270 //shape/clip/item
/layer-list
配置文件中三个Item项依次决定了SeekBar的三层背景。通过各种属性设置了SeekBar的倾斜度,两端圆半径,角度,中心位置,起始,中心和结束的颜色,游标的起始位置。通过这些属性设置,就自定义一个如上图5.2的SeekBar音轨.
音轨对象SeekBar在歌曲刚开始播放的时候调用方法SeekBar.setMax(),参数传入歌曲的长度。SeekBar.setProgress(1)设置游标的起始进度为1。然后程序运行如下代码:
private Runnable thread_One = new Runnable() {// 线程
public void run() {
int currently_Progress = seekBar.getProgress() + 1000; seekBar.setProgress(currently_Progress);
currently_Time.setText(getFileTime(mplayer.getCurrentPosit ion())); showLrcTwo(lrc_time, lrc_word);handler.postDelayed(thread_One, 1000);}};
Android的线程的开始是通过Handler类来进行的,Handler类是线程与线程之间通信的桥梁,实现Runnable接口会实现里面的run方法,当线程开始的时候,Runnable中的run方法会向Handler发一个Message消息,这样,Handler类就可以接收到run方法发送过来的不同的消息进行不同的代码处理。这样就达到了各线程之间的通信。要启动一个线程调用Handler的方法postDelayed(Runnable,1000)表示线程睡眠时间是1000ms 。
以上代码意思是让播放歌曲的线程每隔1000ms,即每1秒对音轨的TextView重新设置时间且让进度条前进1秒的进度。对音轨进行刷新。这样就实现了歌词同步功能SeekBar有一个监听器,该监听器的作用是一直保持着对进度条的监听,当我们用鼠标向SeekBar的各位置进行点击时,它会自动监听其位置,进行相应的位置显示。这也是进度条上的游标会不停的移动和歌词时间会不停的变动的原因。
播放器的播放、暂停、上一曲、下一曲等功能
播放器主界面功能有播放、暂停、停止、上一曲、下一曲、进入列表功能,如图5.3所示:
图 5.3
配置文件代码结构如下:
LinearLayout
ImageButton /ImageButton
ImageButton /ImageButton
ImageButton /ImageButton
ImageButton /ImageButton
ImageButton /ImageButton
/LinearLayout
android的媒体播放原理:android源程序已经为我们封装好了一个接口类,叫MediaPlayer。该接口在执行行需要一个数据源,通过如下四个步骤:
第一步:MediaPlayer.reset();复位操作,为以后的媒体准备播放作准备。:第二步:传入歌曲数据源,这里也是一个数据流Media Player.setData Source(String path);参数需要传一个路径,该接口类在收到路径后将其转化为数据源。
第三步:准备播放数据源,调用方法MediaPlayer.Prepare();
第四步:MediaPlayer.Start();播放数据源,该数据源播放后,不再与程序 有关,需要用MediaPlayer.Stop()方法让其停止或MediaPlayer.Start();让其启动;
歌曲数据源的获得:要获得数据源,需要我们提供给接口类一个歌曲存放路径,而这个路径已经被事先放到数据库里了,我们只需要进行数据库进行操作。将里面的路径取出。这里将调用PlayRackActivity的一个方法query();代码算法如下:
public String query() {
ContentResolver cr = getContentResolver();
Uri uri = DBProvider.CONTENT_URI;
String[] projection = { path };
String selection = fileName=?;
String[] selectionArgs = { selectName };
Cursor c=cr.query(uri,projection,selection, selectionArgs, null);
if (c.moveToFirst()) {
String path = c.getString(0);
return path;
}return null;
}
方法getContentResolver是包android.content.ContextWrapper里面的方法,它会自动的调用ContentProvider中的关联数据库,我们需用这个方法就可以操作数据库。数据库操作需要一个Uri 。Uri类似一个网络连接的Url。Uri是数据库唯一的标识,不同的Uri可以操作不同的数据库表。在查询数据库时需要传入一个当前播放的歌曲名字,通过歌曲名字来查询歌曲的路径。
播放列表显示
播放列表显示如图5.4所示:
图 5.4
在Android里面,有一个视图叫ListView,其特点是一个有BaseAdapter的属性,从下到下,或从左到右的显示方式。系统默认的方式每一行只显示一个TextView,本播放列表实现了自定义的方式,刚ListView的每一行显示一个音乐图片和一个歌曲名字。我们定义一个类MusicAdapter 继承了BaseAdapter,然后通过算法对这个适配器进行扩展,扩展成为第一行能显示一张图片和一个歌曲名字。由于BaseAdapter是一个抽象类,我们需要实现里面的抽象方法getView()。该方法返回一个View,即视图。视图可以显示在Activity上,所以就可以看到我们想要的歌曲列表界面。
ListView同样有一个监听器new onItemClickListener(){
@Override public void onItemClick(AdapterView? arg0, View arg1, int arg2,long arg3) {}},我们只要实现这个方法,就可以监听鼠标的点击事件,当鼠标点击到每一行时,可以通过ListView.getItemAtPositon(int position)得到该行上的信息。这样就可以通过Intent将数据传入到其它的Activity。本程序的思路是当鼠标点击一行,会跳转到另一个Activity里面,这个Activity和歌曲列表类似,也是一个ListView。
菜单功能实现
菜单功能的实现如图5.5所示:
图 5.5
菜单功能有播放、详细属性、新增歌曲、移除歌曲、全部移除、设置功能。各功能都是通过鼠标点击或触屏触发事件。
播放功能:点击后事件触发,传入歌曲名字,让程序操作该名字进行播放。
详细功能:点击后事件触发,传入歌曲名字,跳转到下一界面,显示该歌曲的详细信息。
新增功能:点击后事件触发,进入到SD Card中,进行歌曲添加选择。
移除功能:点击后事件触发。从数据库中删除选中的歌曲。
全部移除:点击后事件触发,删除播放列表。
设置功能:点击后事件触发,进入到播放设置列表。
在Menu.Xml配置文件中,布局结构如下:
?xml version=1.0 encoding=utf-8?
LinearLayout
LinearLayout
TextView /TextView
/LinearLayout
ListView /ListView
TextView /TextView
LinearLayout
ImageButton /ImageButton
/LinearLayout
/LinearLayout
在程序中的Menu.Java中有ListString容器,该容器可以存放String类型的字符,如下:
ListString seclect_items = new ArrayListString();
seclect_items.add(播放);
seclect_items.add(详细);
seclect_items.add(新增);
seclect_items.add(移除);
seclect_items.add(全部移除);
seclect_items.add(设置);
然后通过ListView.setAdapter();方法将这些参数设置到界面中去,可以看到与界面显示效果相同!
播放界面实现
播放界面的实现如图5.6所示:
图 5.6
配置文件setting.Xml布局结构如下:
?xml version=1.0 encoding=utf-8?
LinearLayout
RadioGroup
RadioButton /RadioButton
RadioButton /RadioButton
RadioButton /RadioButton
/RadioGroup
/LinearLayout
ToggleButton/
AbsoluteLayout
ImageButton/
ImageButton/
/AbsoluteLayout
最外层的LinearLayout里面嵌套多层LineaLayout,子LinearLayout里面嵌套着单选按钮RatioGroup 和开关按钮ToggleButton。RatioGroup 里面嵌套着3个RatioButton,即界面上显示的(单曲循环、随机播放、顺序播放)。
歌词显示
歌词显示界面如图5.7所示
图 5.7
歌词的播放以自下向上的滚动方式进行。播放模式状态和歌词显示状态的操作结果都将以一个标志,被写在一个配置文件中。本播放器以歌词格式.Lrc的文件。我们查看.Lrc文件中的歌词格式为:
[00:16.18] In the wall
即是以“时间+歌词”的格式存储。
Lrc中的歌词读取出来并存储在Android的配文件中
我们可以看到一个目录为sdcard ,该目录即为扩展卡,里面预先存放着音频文件和.Lrc歌词文件,我们定义一个BufferedReader buffer=new BufferedReader(new FileReader(new File(/sdcard/+ musicName + .lrc)));指定.Lrc文件存在的路径,并将文件读取到BufferReader中。由于我们要分别存放时间和歌词,所以我们应该定义两个ListString容器来存放时间和歌词。在读取lrc时,每次读取一行,再用算法将时间和歌词分开后放到一个数组里面,并分别存放在两个list中。由于歌曲在播放时会存在界面之间的跳转,所以歌词必须固定存放在一个文件中,而不能作为一个对象,因此,我们将两个时间List和歌词List再写进一个配置文件中.
Android提供给我们一个共享文件的类SharedPreferences。它有一个方法getSharedPreferences(参数1,参数2),参数1为写进时的标记,便于在从其中读取出来时的标记,参数2为读取模式,有只写模式(MODE_WORLD_WRITEABLE)和只读模式(MODE_WORLD_READABLE),在写之前将其置入编辑状态,用静态方法SharedPreferences.Editor editor = sp.edit();然后对象editor可以存入一个HashMapkey,values类型的键值,即putString(KEY, VALUES),这样,我们可以将List中的对象转化成一样长的字符中放进配置文件中.
手机扩展卡的访问
程序实现了文件浏览器的功能,作为一个文件浏览器,应该具有浏览的功能,当程序运行到浏览界面时,会有各文件的目录显示及图标标识。从文件浏览器中我们能看到各文件,而且能对其进行操作,本程序是专为播放器添加歌曲而设计的,因此功能仅限于对媒体文件的浏览,和含有媒体文件的目录的浏览。所以功能比较局限。
当显示菜单界面时,通过新增选项进入到文件浏览器中,或者当播放列表为空时,会提示进入文件浏览器进行歌曲新增操作。如图5.8所示:
图 5.8
文件浏览器界面布局格式类似上面介绍的菜单,只是在界面的第一行新增了一个返回根目录的功能。由于程序只关系到目录/sdcard的目录下的文件,所以用程序屏蔽了其它的目录,这里只显示两个目录/sdcard和/system。播放器只需要用到媒体文件,所以代码也屏蔽了其它文件的子目录。
当要添加选中的歌曲时,程序有自动判断功能,首先弹出Dialog。点击确定按钮后,程序会查询数据库中的歌曲,
文档评论(0)