网络音乐播放器
V1.0
设计说明书
北京华康嘉合科技有限公司
摘 要
当今社会的生活节奏越来越快,随着硬件移动设备的越来越先进,人们对移动设备的要求也越来越高,从以前的追求技术到现在的追求视觉,因此,也逐步的提高了对系统的要求,本文主要是对Android系统上一的款音乐播放器应用程序的设计。Android是一个开源的系统,它底层是基于Linux的操作系统,本论文的音乐播放器采用了Android开源系统技术,利用Java语言和Eclipse编辑工具对播放器进行编写。同时给出了详细的系统设计过程、部分界面图及主要功能运行流程图,本文还对高度过程中遇到的问题和解决方法进行了详细的讨论,该音乐播放器集播放、暂停、停止、上一首、下一首、音量调节、歌词显示等功能于一体,性能良好,在Android系统中能运行。该播放器还拥有对手机文件浏览器的访问功能、歌曲播放模式、以及歌词开闭状态的友好设置。
第一章 引 言
1.1 项目背景
当今社会的生活节奏越来越快,人们对手机的要求也越来越高,由于手机市场发展迅速,使得手机操作系统也出现了不同各类,现在的市场上主要有三个手机操作系统,Windows mobile,symbian,以及谷歌的Android操作系统,其中占有开放源代码优势的Android系统有最大的发展前景。那么能否在手机上拥有自己编写的个性音乐播放器呢?能的,谷歌Android系统就能做到。本文的音乐播放器就是基于谷歌Android手机平台的播放器。
Android:是谷歌于2007年公布的开放式源代码手机系统,它的开放性就优于其它封闭式的手机系统,因此,任何人都可能根据自己的喜好将手机系统中的所有功能重新编写。这使得越来越多的人关注这个操作系统。本次作品音乐播放器就是基于Android平台的。
随着计算机的广泛运用,手机市场的迅速发展,各种音频视频资源也在网上广为流传,这些资源看似平常,但已经渐渐成为人们生活中必不可少的一部分了。于是各种手机播放器也紧跟着发展起来,但是很多播放器一味追求外观花哨,功能庞大,对用户的手机造成了很多资源浪费,比如CPU,内存等的占用率过高,在用户需要多任务操作时,受到了不小的影响,带来了许多不便,而对于大多数普通用户,许多功能用不上,形同虚设。针对以上各种弊端,选择了开发多语种的音频视频播放器,将各种性能优化,继承播放器的常用功能,满足一般用户(如听歌,看电影)的需求,除了能播放常见格式的语音视频文件,高级功能:还能播放RMVB格式的视频文件。此外,还能支持中文、英文等语言界面。
要研究了各种市场上流行的手机播放器,了解它们各自的插件及编码方式,还有各种播放器播放的特别格式文件,分析各种编码的优缺点以及各种播放器本身存在的缺陷和特点,编写出功能实用,使用方便快捷的播放器。目前已经实现的功能有能播放常见音频文件的功能,如MP3,WAV,等,拥有播放菜单,能选择播放清单,具备一般播放器的功能,如快进,快退,音量调节等。播放模式也比较完善,有单曲,顺序,循环,随机播放等模式。
1.2 编写目的
现今社会生活紧张,而欣赏音乐是其中最好的舒缓压力的方式之一,本项目的目的是开发一个可以播放主流音乐文件格式,的播放器,本设计 的实现的这主要功能是播放Mp3,Wav多种格式的音乐文件,并且能够控制播放,暂停,停止,上一曲,下一曲,音量调节,视觉外观,播放列表和歌曲文件的管理操作等多种播放控制功能,界面简明,操作简单。
本项目是一款基于Android手机平台的音乐播放器,使Android手机拥有个性的多媒体播放器,使手机显得更生动灵活化,与人们更为接近,让手机主人随时随地处于音乐视频的旋律之中。使人们的生活更加多样化。也使设计者更加熟练Android的技术和其它在市场上的特点
1.3 网络流行音乐播放器简介
本小节举例介绍目前网络上流行的几款音乐播放器,比如国产千千静听,酷狗音乐等。比较分析了它们各自特有的功能,此外还集中介绍了常见的几种编码格式以及它们各自的特点。
1.3.1 千千静听
千千静听是一款专为用户定制的全新一代的免费听歌下载音乐播放器软件。提供百万首歌曲免费试听下载,拥有最新、最流行的歌曲,提供第一时间音乐资讯;超高品质(320kbps)的音乐歌曲下载,给耳朵更优质的享受;超炫的智能语音搜歌功能让听歌更加快捷;免费的手机铃声歌曲下载;轻松拖拽歌词,保持歌词同步,支持边听边唱;支持在线播放下载;流量限额提醒功能。
软件特色:1、高精度音质,完美还原听觉 ;2、在线自动下载歌词,卡拉OK式同步显示 ;3、软件小、运行快、支持众多插件,自由编辑歌词,由你做主;4、自由转换MP3、WMA,APE,WAV等多种音频格式 ,批量修改歌曲标签信息;5、个性化皮肤,多种视觉效果享受永远免费。
1.3.2 酷狗音乐
酷狗音乐是中国领先的数字音乐交互服务提供商,互联网技术创新的领军企业,致力于为互联网用户和数字音乐产业发展提供最佳的解决方案,公司的使命是成为亚太地区最大的数字音乐销售推广企业。自公司创建以来,一直在数字音乐发展上大胆尝试,先后与几十家唱片公司、版权管理机构合作探索发展,积累了数万首数字音乐版权,并在推动广范围的跨行业、跨平台合作上做出努力,在艰巨的全球音乐数字化进程中做出自身的贡献。全球最受欢迎的免费中文播放软件,流行音乐搜索平台。
软件特色: 1、迷你界面、界面更酷、绚丽流行;保持了Windows Vista和XP下的完美表现,让人耳目一新;2、卡拉OK酷狗独创“卡拉OK”歌词显示,多种模式,边听边唱,让你听歌更好玩;3、支持本地音乐播放完美音质,支持所有的音频文件,本地文件拖放,同时支持网络高速下载和本地播放;4、超强搜索和下载优化歌曲搜索引擎,提高搜索准确度;智能化节约带宽,可关闭网络功能;5、流行音乐资讯酷狗榜单家族、狗友推荐、酷吧、狗窝,最新流行音乐一网打尽,好听的音乐来“找”你;6、个性化手机炫铃DIY,让拥有张扬个性的铃声7、音频格式我选择我的歌曲我制作,音质音效我决定8、收音机动感音乐识别体验精选多家电台,收听全球风云变化,更能识别电台中的音乐。
第二章 系统需求分析
2.1 功能需求(用例图分析)
根据项目的目标,我们可获得项目系统的基本需求,以下从不同角度来描述系统的需求,并且使用用例图来描述,系统的功能需求,我们分成四部分来概括,即播放器的基本控制需要,播放列表管理需求,播放器友好性需求和播放器扩展卡需求。以下分别描述:
2.1.1 播放器的基本控制需求
图2.1 播放器基本控制图
用例名称:播放 参与者:用户 目标:使得用户可以播放在播放列表中选中的歌曲 前置条件:播放器正在运行 基本事件流:1.用户单击“播放”按钮 2.播放器将播放列表中的当前的歌曲
用例名称:暂停 参与者:用户 目标:使得用户可以暂停正在播放的歌曲 前置条件:歌曲正在播放且未停止和暂停 基本事件流:1.用户单击“暂停”按钮 2.播放器将暂停当前的歌曲
用例名称:停止 参与者:用户 目标:使得用户可以停止正在播放的歌曲 前置条件:歌曲正在播放或暂停 基本事件流:1.用户单击“停止”按钮 2.播放器将停止当前播放的歌曲
用例名称:上一首/下一首
参与者:用户 目标:使得用户可以听上一首或下一首歌曲 前置条件:歌曲正在播放或暂停 基本事件流:1.用户单击“上一首或下一首”按钮 2.播放器将播放上一首或下一首歌曲
用例名称:播放清单 参与者:用户 目标:使得用户可以进入播放清单 前置条件:程序在运行 基本事件流:1.用户单击“清单”按钮 2.播放器进入清单列表
2.1.2 播放清单列表管理需求
当用户选中列表中某一项歌曲,就有的需求:
图2.2 播放器清单
用例名称:播放 参与者:用户 目标:使得程序播放选中的歌曲 前置条件:程序运行在播放菜单选项中 基本事件流:1.用户单击“播放”按钮 2.播放器进入播放状态
用例名称:详细 参与者:用户 目标:使得程序显示歌曲详情 前置条件:程序运行在播放菜单选项中 基本事件流:1.用户单击“详细”按钮 2.显示歌曲详细状态
用例名称:增加 参与者:用户 目标:使得程序进入手机扩展SD卡
前置条件:程序运行在播放菜单选项中 基本事件流:1.用户单击“增加”按钮 2.播放器进入手机扩展SD卡
用例名称:移除/全部移除
参与者:用户 目标:使选中的歌曲被移除 前置条件:程序运行在播放菜单选项中 基本事件流:1.用户单击“移除/全部移除”按钮 2.播放器移除选中歌曲/全部移除歌曲
用例名称:设定 参与者:用户 目标:使得程序进入播放器设定状态 前置条件:程序运行在播放菜单选项中 基本事件流:1.用户单击“设定”按钮 2.播放器进入设定界面
2.1.3 播放友好性需求
图2.3 播放器设定
用例名称:播放模式 参与者:用户 目标:使得程序进入播放模式设定状态 前置条件:程序运行在播放器设定界面中 基本事件流:1.用户单击“顺序、随机、单曲”按钮 2.播放器进入选中模式播放状态
用例名称:歌词显示 参与者:用户 目标:使得程序进入播放器歌词设置状态 前置条件:程序运行在播设定界面 基本事件流:1.用户单击“歌词开关按钮”按钮 2.播放器显示或关闭歌词
2.1.4 播放器扩展卡需求
图2.4 文件浏览器
用例名称:SDcard
参与者:用户 目标:使得程序进入SDcard目录
前置条件:程序运行目录界面 基本事件流:1.用户单击“Sdcard”选项 2.程序进入Sdcard目录下
用例名称:System
参与者:用户 目标:使得程序进入System目录
前置条件:程序运行目录界面 基本事件流:1.用户单击“System”选项 2.程序进入System目录下
2.1.5 功能需求(时序图)分析
音乐播放器的时序图分析如(图)
2.2 系统结构图和流程图
(1)音乐播放器的系统流程图(图2.5.1)
图2.5.1 流程图
(2)系统功能表(表2.1)和系统功能结构图(图2.5.2)
功能类别 子功能 子功能 播放列表
播放列表菜单 退出播放 从扩展卡寻找歌曲 歌曲菜单
播放->进入播放界面
删除->数据库同步更新
重命名->数据库同步更新
向上、下移动->数据库同步更新
播放界面
播放 播放歌曲->线程启动->时间更新
暂停 暂停歌曲->线程暂停->时间暂停
停止 停止歌曲->线程停止->时间停止
上一首 播放列表索引变化->寻找上一ID歌曲
下一首 播放列表索引变化->寻找下一ID歌曲
播放界面菜单
返回到播放列表 返回到主菜单 从扩展卡寻找歌曲 退出播放器 隐藏播放界面 主菜单 退出程序 程序退出 进入播放列表 显示播放列表
表2.1 功能表
图2.5.2 系统功能结构图
2.3 系统界面需求
播放器界面要求布局合理,颜色舒适,控制按钮友好,为了减少开发工程量,图片素材多数为公司项目素材(图2.6)
图2.6 播放器界面
说明:左下角为清单按钮 右下角为程序退出按钮
蓝色条为音轨
2.4 系统性能需求
根据Android手机系统要求无响应时间为5秒,所以就有如下性能要求:
(1)当要求歌曲播放时,程序响应时间最长不能超过5秒
(2)当要求歌曲暂停时,程序响应时间最长不能超过5秒
(3)当要求歌曲停止时,程序响应时间最长不能超过5秒
(4)当要求歌曲上/下一首时,程序响应时间最长不能超过5秒
(5)当要求进行清单列表时,程序响应时间最长不能超过5秒
2.5 运行环境需求
操作系统:Android手机基于Linux操作系统
支持环境:Android 1.5 - 2.0.1版本
开发环境:Eclipse 3.5 ADT 0.95
第三章 Android数据库设计
数据结构组织和数据库文件设计要根据不同用途,使用要求等,来决定数据的整体组织形式等一系列问题。
数据库,顾名思义,是存放数据的仓库。只不过这个仓库是在计算机存储设备上,而且数据是按一定的格式存放的。数据库中的数据按一定数据模型组织、描述和存储,具有较小的重复度、较高的数据性和易扩展性,并且可以被在一定范围内的各种用户共享。在涉及数据库的软件开发中,需要根据有待解决的问题性质、规模,以及所采用的前端程序创建工具等,做出合适的数据库类型选择
3.1 数据库及字段属性设计
3.1.1 字段设计(表、图)
file_table 主要是保存歌曲名字、类型、路径
字段说明:Id 歌曲id号 fileName 歌曲名字 filePath 歌曲路径 sort 歌曲类型(表3.1、图3.1.1)
Android自带一个MediaStore封闭类 专门来存储媒体信息
通过Uri EXTERNAL_CONTENT_URI 来访问SDcard中的歌曲详细信息。
存放媒体信息如TITLE(标题)、ARTIST(艺术家)、ALBUM(专辑)、SIZE(大小 )(表3.2、图3.1.2)
属性 数据类型 允许空 主键 _Id INTEGER Not null Primary key fileName TEXT Not null filePath TEXT sort INTEGER
表3.1
属性 数据类型 允许空 主键 _ID INTEGER Not null Primary key TITLE TEXT Not null ARTIST TEXT ALBUM TEXT SIZE LONG
表3.2
图3.1.1 歌曲列表
图3.1.2 歌曲详细
3.1.2 音乐播放器E-R图
音乐播放器 E-R图(图3.1.3)
图3.1.3 E-R图
3.2 数据库连接
这里将介绍如何进行Android数据库连接,Android中自带SQLite数据库,这是一个十分小型的数据库,这样正适合Android这种移动平台使用。
Android数据库存储的位置在data/data/<项目文件夹>/databases/目录下 Android是利用ContentProvider作为内容提供商,SQLiteOpenHelper数据库帮助类来进行对数据库的创建和操作。通过Context.getContentResolver()方法直接对数据库进行操作。程序中数据库类为DBHelper extends SQLiteOpenHelper(继承关系),内容提供类DBProvider extends ContentProvider(继承关系)
3.2.1 创建数据库
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异常
3.2.2 操作数据库
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;
}
// 数据库更新操作
@Override
public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
int i = 0;
try {
i = db.update(FileColumn.TABLE, values, selection, null);return i;
} catch (Exception ex) {}
return 0;
}
3.2.3 数据显示
程序是利用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;}
第四章 Android项目介绍
4.1 什么是Android?
4.1.1 Android简介
Android一词的本义指“机器人”,同时也是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件。目前最好的是Android2.0的摩托罗拉Droid
Android是基于Linux内核的软件平台和操作系统,早期由Google开发(在华注册商标名为“安致”),后由开放手机联盟(Open Handset Alliance)开发。它采用了软件堆层(software stack,又名以软件叠层)的架构,主要分为三部分。低层以Linux内核工作为基础,只提供基本功能;其他的应用软件则由各公司自行开发,以Java作为编写程序的一部分。另外,为了推广此技术,Google和其它几十个手机公司建立了开放手机联盟。Android在未公开之前常被传闻为Google电话或gPhone。大多传闻认为Google开发的是自己的手机电话产品,而不是一套软件平台。到了2010年1月,Google开始发表自家品牌手机电话的Nexus One。目前最新SDK版本为Android 2.1
4.1.2 Android Features特性
Android系统有如下的几大特性:
·应用程序框架 支持组件的重用与替换
·Dalvik虚拟机 专门为移动设备做了优化
·内部集成浏览器 该浏览器基于开源的WebKit引擎
·优化的图形库 包括2D和3D图形库,3D图形库基于OpenGL ES
·SQLite 用作结构化的数据存储
·多媒体支持 包括常见的音频、视频和静态印象文件格式(如 MPEG4, H.2, MP3, AAC, AMR, JPG, PNG, GIF)
·GSM电话(依赖于硬件)
·蓝牙Bluetooth, EDGE, 3G, and WiFi (依赖于硬件)
·照相机,GPS,指南针,和加速度计 (依赖于硬件)
·丰富的开发环境 包括设备模拟器,调试工具,内存及性能分析图表,和Eclipse集成开发环境插件
4.1.3 Android基本框架(Android Architecture)
图 4.1 Android Architecture
(1) Applications
Application Android会同一个核心应用程序包一起发布,该应用程序包包括email客户端,SMS短消息程序,日历,地图,浏览器,联系人管理程序等。所有的应用程序都是用JAVA编写的。
(2) Application FrameWork
开发者完全可以访问核心应用程序所使用的API框架。该应用程序架构用来简化组件软件的重用;任何一个应用程序都可以发布它的功能块并且任何其它的应用程序都可以使用其所发布的功能块(不过得遵循框架的安全性)。该应用程序重用机制使得组建可以被用户替换。
所有的应用程序都由一系列的服务和系统组成,包括:
· 可扩展的视图(Views )可以用来建应用程序,包括列表(lists),网格(grids),文本框(text boxes),按钮(buttons),甚至包括一个可嵌入的web浏览器
·内容管理器(Content Providers )使得应用程序可以访问另一个应用程序的数据(如联系人数据库),或者共享它们自己的数据。
·资源管理器(Resource Manager)提供非代码资源的访问,如本地字符串,图形,和分层文件(layout files )。
·通知管理器(Notification Manager)使得应用程序可以在状态栏中显示客户通知信息。
·活动类管理器(Activity Manager)用来管理应用程序生命周期并提供常用的导航回退功能。
(3) Libraries库
Android 包括一个被 Android 系统中各种不同组件所使用的 C/C++ 库集。该库通过 Android 应用程序框架为开发者提供服务。以下是一些主要的核心库:
系统 C 库- 一个从 BSD 继承来的标准 C 系统函数库( libc ),专门为基于 embedded linux 的设备定制。 媒体库- 基于 PacketVideo OpenCORE;该库支持录放,并且可以录制许多流行的音频视频格式,还有静态印像文件包括MPEG4, H.2, MP3, AAC, AMR, JPG, PNG。 Surface Manager - 对显示子系统的管理,并且为多个应用程序提供2D和3D图层的无缝融合。 LibWebCore - 一个最新的web浏览器引擎用来支持Android浏览器和一个可嵌入的web视图。 SGL - 一个内置的2D图形引擎 3D libraries - 基于OpenGL ES 1.0 APIs实现;该库可以使用硬件3D加速(如果可用)或者使用高度优化的3D软加速。 FreeType - 位图(bitmap)和向量(vector)字体显示。 SQLite 一个对于所有应用程序可用,功能强劲的轻型关系型数据库引擎。
(4) Android Runtime
Android 包括了一个核心库,该核心库提供了JAVA编程语言核心库的大多数功能。
每一个Android应用程序都在它自己的进程中运行,都拥有一个的Dalvik虚拟机实例。Dalvik是针对于同时高效地运行多个VMs来实现的。Dalvik虚拟机执行.dex的Dalvik可执行文件,该格式文件针对最小内存使用做了优化。该虚拟机是基于寄存器的,所有的类都经由JAVA汇编器编译,然后通过SDK中的dx工具转化成.dex格式由虚拟机执行。
Dalvik虚拟机依赖于linux的一些功能,比如线程机制和底层内存管理机制。
(5) Linux内核
Android 的核心系统服务依赖于 Linux 2.6 内核,如安全性,内存管理,进程管理,网络协议栈和驱动模型。 Linux 内核也同时作为硬件和软件堆栈之间的硬件抽象层。未来发展 老牌智能手机软件平台制造商Symbian发言人则表示:Google的android只不过是另一个linux,symbian对其它软件与其形成的竞争并不感到担心。除了北美之外,Symbian在其它地区智能手机市场都占有大部分市场份额。 与iPhone相似,Android采用WebKit浏览器引擎,具备触摸屏、高级图形显示和上网功能,用户能够在手机上查看电子邮件、搜索网址和观看视频节目等,比iPhone等其他手机更强调搜索功能,界面更强大,可以说是一种融入全部Web应用的单一平台。
但其最震撼人心之处在于Android手机系统的开放性和服务免费。Android是一个对第三方软件完全开放的平台,开发者在为其开发程序时拥有更大的自由度,突破了iPhone等只能添加为数不多的固定软件的枷锁;同时与Windows Mobile、Symbian等厂商不同,Android操作系统免费向开发人员提供,这样可节省近三成成本。 Android项目目前正在从手机运营商、手机厂商、开发者和消费者那里获得大力支持。谷歌移动平台主管安迪·鲁宾(Andy Rubin)表示,与软件开发合作伙伴的密切接触正在进行中。从去年11月开始,谷歌开始向服务提供商、芯片厂商和手机销售商提供Android平台,并组建“开放手机联盟”,其成员超过30家。市场前景 Google手机于08年10月22日正式上市,与运营商捆绑的合约价为179美元(约合人民币1200元),现有的T-Mobile用户可以通过网络订购。在10月22日发布当天,将有22个国家和地区可以买到谷歌手机。在11月,将增至27个国家和地区。
谷歌手机将只能在T-Mobile网络内使用,将会有SIM卡锁定。T-Mobile USA提供了两种流量和短信近曝光的moto sholes(也有人称之为moto tao)将搭载最新的android2.0操作系统包月计划。第一档为25美元,包括不的网络流量,以及一定数量的短信;第二档为35美元,包括不的网络流量和不限数量的短信。G1支持各种谷歌的服务,包括Gmail、Google Maps、、Google日历和Google Talk,内置Chrome Lite浏览器。使用这款手机也需要Gmail账号。 “我爱死我的G1了!”谷歌联合创始人拉里·佩奇(Larry Page)憧憬:“对于我来说,谷歌手机最激动人心的一点就是它的未来。它的功能很强,正如几年前的电脑一样。你可以上网,安装软件。” T-Mobile USA为德国电信旗下移动子公司,运营GSM/HSPA网络,拥有用户近3000万。此次发布的谷歌手机采用高通MSM7201A处理器,支持7.2Mbps下载速率,美国运营商3G网络设定的套餐速率一般可达1Mbps以上。MSM7201A为单芯片、双核,整合硬件加速多媒体功能、支持3D图形,300万像素的摄像功能可以扫描条形码,并且有GPS功能。 在美国四大移动运营商中,T-Mobile USA处于相对弱势的地位,不过T-Mobile在欧洲有更为强势的是CDMA EV-DO网络,而T-Mobile USA和苹果iPhone的独家运营商AT&T为GSM/HSPA网络,后者在2005年12月就推出了全球第一个HSDPA商用服务。T-Mobile USA今年5月方才在纽约推出了3G服务,目前已经在奥斯汀、巴尔的摩、波士顿、达拉斯、休斯敦、拉斯维加斯、迈阿密、明尼阿波利斯、凤凰城、波特兰、圣安东尼奥和圣地亚哥等12个城市增加了3G覆盖,公司计划年底前将3G覆盖的城市从目前的13个增加到27个,能够为其超过2/3的用户提供3G服务。
4.1.4 Android系统的四大组件
在Android系统中,为我们提供了四大基本组件,每个组件是一个视图,但是有些是可见的,有些是不可见的视图,像Activity,ContentProvider是可见的视图,Service和BroadcastReceiver是不可见的,它们只在系统的后台运行。下面分别介绍四大组件:
(1)Activity 简介
在Android系统中Activity提供可视化的用户界面,一个Android应用通常由多个Activity组成。多个Activity组成了Activity栈(Stack),当前活动的Activity处于栈顶。Activity有自己的生命周期,由Android系统来控制。
(2)Service 简介
顾名思义Service就是运行在后台的一种服务程序,一般很少和用户交互,因此没有可视化界面定义一个Service类比较简单,只要继承Service类,实现其生命周期中的方法就可以了。一个定义好的Service必须在AndroidManifest.xml配置文件注册,通过元素声明才能使用.Service有自己的生命周期,我们可以调用startService()启动一个Service或者bindService()方法来绑定一个存在的Service (3)Broadcast Receiver 简介
Broadcast Receiver 顾名思义广播接收器,它和事件处理机制类似,只不过事件处理机制是程序组件级别的(例如,某个按钮的单击事件),而广播事件处理机制是系统级别的。到目前为止我们可以使用Intent来启动一个程序组件,我们还可以通过使用sendBroadcast()方法来发起一个系统级别的事件广播来传递消息。我们可以在你的应用程序中实现Broadcast Receiver来监听和响应这些广播的Intent
(4)ContentProvider简介
Content Provider 用来保存和检索数据,并且使应用程序之间相互访问数据成为可能。它是跨应用程序共享数据的唯一方法。
Android 为常用的数据类型(如:音视频、图片和联系方式等)提供了大量的Content Provider。它们被定义在android.provider包下面。通过这样定义好的ContentProvider 我们可以方便的进行数据操作。当然我们必须拥有适当的权限。我们也可以自己来定ContentProvider共享我们的数据,方便用户的访问
4.2 搭建Android开发环境
任何事物要运行,都要有它的环境,Android也有它的环境才能够运行,下面介绍Android的开发环境配置.
搭建开发环境需要的软件:
1.操作系统:Windows XP或Linux
2.软件包:Android SDK(Software Development kit Java Development kit) 、ADT(Android Develoopment Tool)
3.IDE环境:Eclipse IDE+ADT Eclipse3.3以上
4.JDK:Java Runtime Environment虚拟机 、(JDK)Java Development kit
安装步骤如下:
第一步:安装Java虚拟机sun-java6-jdk版本
第二步:安装Eclipse3.5工具 官网http://www.eclipse.org/downloads/
选择版本(图4.2):进行安装
图 4.2
第三步:安装Android SDK:首先要下载SDK,可以在这个网址下载Http://developer.android.com/sdk ,选择相应的系统进行安装
图 4.3
第四步:安装Android ADT插件
运行Eclipse,选择help->install new software 选择add,将会弹出一个框
图 4.4
点击OK,选择要安装的软件,占next,然后选择接受协议,直到安装成功,重启Eclipse软件,设置Android SDK Home,Window->refrence
图 4.5
在SDK location中输入SDK Tools路径:D:\\android software\\android-sdk-windows 点击OK
这样Android环境就已经搭建成功了。
4.3 Android常用工具的使用
4.3.1 命令行的使用
创建Android Virtual Devices(AVD)
使用android list target命令列出当前可用的SDK版本
android create avd -n -t [- ] ...模拟器(Emulator)的使用
启动和停止模拟器
emulator -avd Android Debug Bridge(ADB)的使用
查询当前模拟器实例数量
adb devices
本地机器和模拟器之间相互拷贝文件
D:\\>adb push d:\est.txt /sdcard/
D:\\>adb pull /sdcard/test.txt d:/
安装apk应用程序
adb push d:\est.apk /sdcard/
adb install test.apk
使用shell命令
在DOS命令行输入adb shell 便进入shell命令行了
可以使用exit退出shell
4.3.2 Dalvik Debug Monitor Service (DDMS)的使用
在DOS命令窗口,输入ddms会弹出如下图所示界面,Android编辑工具的可视化界面(图4.6)
图 4.6
4.4 Android 音乐播放器的工程
4.4.1 Android项目
Android的四大基本组件:Activity(活动),Service(服务),BroadcastReceiver(广播),ContentProvider(内容提供者),各组件之间要进行切换需要一个意图或企图Intent类,通过启动StartIntent()方法来使各组件进行跳转
Android的五大布局方式:LinearLayout(线性布局) FrameLayout(帧布局) TableLayout(表格布局) AbsoluteLayout(绝对布局) RelativeLayout(相对布局)
五种布局方式可以相互嵌套,Android各种漂亮的界面都是通过嵌套布局而实现的。
Android的线程,以及线程之间通信的中介:Handler类
Android数据库:在第三章已经介绍过了。这里不再介绍
Android配置文件:AndroidManifest.Xml及res资源文件中各种属性 布局方式 引用的资源等
Android系统将插件ADT集成到了Eclipse工具上,因此,一个Android程序启动后,系统会启动一个模拟器(Emulator)(图4.7),该模拟器是一款手机板的样式,拥有手机硬件的基本操作。我们也可以将右边的键盘通过代码属性设置将其隐藏,界面的大小可自由设定,目前最大支持800X600的分辨率。
图 4.7 android模拟器
4.4.2 Android工程程序结构
Android工程基本结构目录包括:src (源代码)、gen(Android系统自动生成的常量)、Res(资源文件):主要存放程序界面的布局配置(.xml)文件和图片资源。AndroidMainfes.xml 是四大组件的驱动配置文件,有它的存在,Android程序的四大组件才可以正常的跳转。Android资源的类型和布局(图4.7)
图 4.7
下图4.8.1 -图4.8.5为音乐播放器代码结构和各界面的配置文件,图像资源等,图4.8.1 为一个Android工程所必须的结构,图4.8.2为该播放器的.Java文件,图4.8.3为播放器所用到的字符串,字体大小,字的颜色等配置文件,图4.8.4为 该播放器的各种界面的布局配置文件,图4.8.5为该播放器的图片资源。
图 4.8.1
图 4.8.2 图 4.8.3 图 4.8.4 图 4.8.5
4.4.3 AndroidManifest.xml文件
Android系统的任何一个程序启动都需要AndroidManifest.xml来启动程序,任何一个新建的工程目录都会自动生成一个AndroidManifest.xml文件,此配置文件是整个程序能够正常运行的核心,它里面包含了Android SDK的版本,程序运行的默认Activity,当程序中的任何一个组件触发事件后,系统都会自动的去AndroidManifest.xml中寻找标识来作出相应的操作。任何一个AndroidManifest.Xml文件的格式都应为:
Android系统有一个编码的规定,支持的编码是"utf-8",当程序中出现乱码是,我们须将其编码格式转化为"utf-8".在 AndroidManifest.xml中会在第一行声明一句:。它是该系统支持的版本和编码。在第二行定义了我们需要使用的架构,该架构来自xmlns:android="http://schemas.android.com/apk/res/android"
xmlns(XML namespace)是一个命名空间,它就像一条河的源头一样能让我们找到系统架构,每一个配置文件必须有这个xmlns,否则程序中的所使用的所有资源将无法找到。
在application元素我们定义android:icon="@drawable/icon"
android:label="@string/app_name",android:icon是程序在手机中显示的图片,我们运用@drawable/icon表示了对res/drawable目录下的的引用。@string/app_name表示了对res/value目录下string.Xml中定义的app_name参数的引用。
这是系统确定的首先要启动的Activity是PlayRackActivity。
在intent-filter选项中,有action和category等等属性,我们需要定义action的值为android.intent.action.MAIN,category的值为android.intent.category.LAUNCHER,它们是系统的值,程序在解析到这些常用后就可以确定首先要启动的Activity。当我们需要通过一个组件触发另一个组件时,我们将设定action和category的其它属性值,系统会根据我们设定的属性值去AndroidManifest.Xml的application 中寻找标识,任何一个Activity的action和category是唯一,所以程序在任何时候都能唯一启动一个Activity,这样,不同的Activity之间的跳转就实现了。
在AndroidManifest.Xml中有一个根结点,它是我们需要定义的ADT版本,例如我们将其值设定为android:minSdkVersion="4",则表示此Android工程所用的版本为1.6,Android还有1.1、1.5、1.6、2.0、2.1这几个版本。如果我们需要对网络进行访问,比如打开一个网页,刚我还需要设置一个网络访问权限uses-permission,将其的值设置为android:name="android.permission.INTERNET,我们就可以访问网络了。当然uses-permission还有很多其它的权限,例如GPS定位权限,浏览器数据存取权限com.android.browser.permission.READ_HISTORY_BOOKMARKS等等。
当程序的任何一个组件要用到时,都必须在AndroidManifest.Xml文件中声明。四大组件要使用前都需要声明,其声明方式如下:
其中声明provider时还需要声明其授权 authorities。每个组件里面还有很多的属性,会根据程序的具体需要定义不同的属性。过滤器intent-filter 有两种启动方式来启动界面:
(1) 显示方式
显示方式是在代码中的直接启动组件,启动时会声明Intent,在它的构造方法Intent(组件1,组件2)中直接指定一个组件的名字,然后调用方法startIntent(intent)以启动指定的组件。
(2) 隐式方式
隐式方式是通过过滤器来过滤完成的,启动的组件必须满足action和category的条件才能够启动该组件。这些属性是在AndroidManifest.Xml文件中声明的。两种启动方式都可以通过程序setAction(ACTION常量)和startActivity(intent)或配置文件两种方式来实现组件的跳转。
第五章 播放器系统功能详细设计
5.1音乐播放器主界面功能实现
5.1.1 播放器主界面
播放器主界面(图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布局文件代码结构如下:
在绝对布局下嵌套两种线性布局和,第一个实现了标题和歌曲名的显示位置,通过布局设置绝对坐标来控制标题的位置。每个布局内可以放置多种Widget(窗体部件)例如:等。每个Widget内有多种属性,可以设置该Widget的坐标,大小,背景和颜色等参数。在播放界面中,歌词显示为居中,实现方法代码如下:android:gravity="center"android:layout_height="wrap_content" android:layout_width="fill_parent"> android:textColor="#8deeee" android:id="@+id/lrcText" android:layout_width="wrap_content">
属性:
orientation="horizontal":此线性布局的子部件为水平方式布局 Layout_width="fill_content" :布局的宽度为填满父布局
Layout_height="wrap_content" :布局的高度子由窗体的大小决定
窗体TextView 文本 :textColor="8deeee" 设置文本显示的颜色RGB为 "8deeee"
TextSize为默认大小
5.1.2 播放界面音轨的实现
播放器音轨SeekBar(如下图)
Android系统自带SeekBar(如下图)
图 5.2
不管是从界面外观还是从功能上,系统自带的SeekBar往往不能满足用户的需要。所以我在这里自定义了一个音轨SeekBar,
在play_rack.Xml配置文件中,SeekBar的代码如下:
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="15px"android:paddingTop="5px" android:paddingBottom="5px" android:progress="0"
android:max="100" android:secondaryProgress="0">
上面代码中有参数android:thumb="@drawable/thumb" 为音轨游标的图片资源android:progressDrawable="@drawable/seekbar_style"为SeekBar条的风格style。引用了drawable中的seekbay_style.xml文件,seekbay_style.Xml是自定义的配置文件,算法如下:
-
android:endColor="#a0ffcb00" android:angle="270" />
配置文件中三个Item项依次决定了SeekBar的三层背景,从最下层的灰色到最上层的蓝色。通过各种属性设置了SeekBar的倾斜度,两端圆半径,角度,中心位置,起始,中心和结束的颜色,游标的起始位置。通过这些属性设置,就自定义一个如上图一的SeekBar音轨.
播放器最重要的一部分就是音轨与歌曲进度同步的实现。音轨设置了两个TextView用来显示当前歌曲播放的进度时间和歌曲的长度(图5.3)
图 5.3
音轨对象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.1.3 播放器播放、暂停、停止等功能
图 5.4
如图5.4所示:各按钮水平放置,用的是布局中的线性布局LinearLayout,用方法setOrientation(horizontal);将其设置为水平。LinearLayout中依次放置播放,暂停,停止,上、下一曲按钮属性。配置文件代码结构如下:
android的媒体播放原理:android源程序已经为我们封装好了一个接口类,叫MediaPlayer。该接口在执行行需要一个数据源,通过如下四个步骤:
第一步:MediaPlayer.reset();复位操作,为以后的媒体准备播放作准备。
第二步:传入歌曲数据源,这里也是一个数据流 MediaPlayer.setDataSource(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.2 播放列表功能
播放列表界面(如图5.5)
图 5.5
布局层次关系如下:
在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,该界面将在下一节介绍。
歌曲列表是从播放主界面跳转过来的,能跳到该歌曲列表是前提是数据有歌曲列表的存在。因为每次歌曲列表显示时会查询数据库中的歌曲列表。如果不存在刚会提示是空列表,选择到SDCard中添加歌曲(如图5.6)
图 5.6
中间为一个Dialog对话框,具有Acitivty的属性,但是于界面的一个视图,该对话框中放置了一个布局文件。
Dialog的创建:AlertDialog.Builder,AlertDialog alert =builder.create();alert.show();
该 Dialog上有两个菜单选项,第一个为“从SD卡”,点击会跳转到SDcard界面中。
5.3 菜单功能
菜单界面(如图5.7)
图 5.7
5.3.1 菜单界面
在Menu.Xml配置文件中,布局结构如下:
在程序中的Menu.Java中有List容器,该容器可以存放String类型的字符,如下:List seclect_items = new ArrayList();seclect_items.add("播放");
seclect_items.add("详细");
seclect_items.add("新增");
seclect_items.add("移除");
seclect_items.add("全部移除");
seclect_items.add("设置");
然后通过ListView.setAdapter();方法将这些参数设置到界面中去,可以看到与界面显示效果相同!
该菜单每一行有一张图片和一个菜单选项(如图5.8)
图 5.8
ListAdapter继承一个BaseAdapter,实现里面的getView()方法,再对其进行扩展。
View getView(int position, View convertView, ViewGroup parent) {
convertView = inflater.inflate(R.layout.file_row, null);holder.text = (TextView) convertView.findViewById(R.id.text);holder.icon = (ImageView) convertView.findViewById(R.id.image_Icon);
convertView.setTag(holder);
}
ListAdapter每一行都是一个LineaLayout布局,水平放置一个图片一个String。这种算法的实现在前面已经讨论过,这里不再讨论。
5.3.2 菜单功能实现
菜单有6个功能:播放,详细,新增,移除,全部移除,设置。各功能都是通过鼠标点击或触屏触发事件。
播放功能:点击后事件触发,传入歌曲名字,让程序操作该名字进行播放。
详细功能:点击后事件触发,传入歌曲名字,跳转到下一界面,显示该歌曲的详细信息。
新增功能:点击后事件触发,进入到SDCard中,进行歌曲添加选择。
移除功能:点击后事件触发。从数据库中删除选中的歌曲。
全部移除:点击后事件触发,删除播放列表。
设置功能:点击后事件触发,进入到播放设置列表。
选择移除菜单选项时,出现(图5.9.1)的Dialog、选择全部移除菜单选项时,出现(图5.9.2)的Dialog
图 5.9.1 图 5.9.2
删除单首歌曲算法:是对数据库进行单项操作。通过歌曲名字删歌曲,算法如下:
del_One(String musicName) {
ContentResolver cr = getContentResolver();
Uri uri = DBProvider.CONTENT_URI;
String where = "fileName=?";
String[] selectionArgs = { musicName };
cr.delete(uri, where, selectionArgs);
}
选择“是”后,执行代码:
Intent intent = new Intent(Menu.this,PlayListActivity.class);
startActivity(intent);声明一个Intent,并指明要跳转的界面类,然后启动Intent。
5.4 播放设置界面
5.4.1 界面实现
图 5.10
配置文件setting.Xml布局结构如下:
最外层的LinearLayout里面嵌套多层LineaLayout,子LinearLayout里面嵌套着单选按钮RatioGroup 和开关按钮ToggleButton。RatioGroup 里面嵌套着3个RatioButton,即界面上显示的(单曲循环、随机播放、顺序播放)。
(1)播放模式
用的是一个组件RadioGroup,这个组件有单项选择的功能,里面有RadioButton项,多个RadioButton项只能同时选中一个,该 播放器播放模式有单曲循环,随机播放,顺序播放等功能。MediaPlayer有一个,它监听着歌曲是否正在播放或者是否播放完成,当歌曲播放完成时,会触发方法OnCompletionListener(),在该方法里面可以处理歌曲播放完成后的操作。RadioGroup可以进行单项选择操作,如图(5.11)
图 5.11
通过RadioButton.isChecked(),如果返回true,刚该项被选中。
(2)歌词设置
歌词是否显示是一个开关按钮ToggleButton实现的,有ON和OFF状态,当为ON时,歌词显示,为OFF时,歌词关闭。如图(5.12):
图 5.12
ToogleButton同样有一个,可以获得ToogleButton的不同状态。使用前对它进行实例化(ToggleButton) View.findViewById(R.id.ly_lrc);并且用ToggleButton.isChecked();获得开关状态。
播放模式状态和歌词显示状态的操作结果都将以一个标志,被写在一个配置文件中,这是关于Android的存储方式,将在后面主要介绍。
5.4.2 歌词显示实现
本播放器以歌词格式.Lrc的文件。我们查看.Lrc文件中的歌词格式为:
[00:16.18]呼吸着 你的香水味
即是以“时间+歌词”的格式存储。
下面将介绍如何将.Lrc中的歌词读取出来并存储在Android的配文件中
(1).xml配置文件的存储
Android系统目录结构如下图:
图 5.13
我们可以看到一个目录为sdcard ,该目录即为扩展卡,里面预先存放着音频文件和.Lrc歌词文件,我们定义一个BufferedReader buffer=new BufferedReader(new FileReader(new File("/sdcard/"+ musicName + ".lrc")));指定.Lrc文件存在的路径,并将文件读取到BufferReader中。由于我们要分别存放时间和歌词,所以我们应该定义两个List容器来存放时间和歌词。在读取lrc时,每次读取一行,再用算法将时间和歌词分开后放到一个数组里面,并分别存放在两个list中。由于歌曲在播放时会存在界面之间的跳转,所以歌词必须固定存放在一个文件中,而不能作为一个对象,因此,我们将两个时间List和歌词List再写进一个配置文件中. Android提供给我们一个共享文件的类SharedPreferences。它有一个方法getSharedPreferences(参数1,参数2),参数1为写进时的标记,便于在从其中读取出来时的标记,参数2为读取模式,有只写模式(MODE_WORLD_WRITEABLE)和只读模式(MODE_WORLD_READABLE),在写之前将其置入编辑状态,用静态方法SharedPreferences.Editor editor = sp.edit();然后对象editor可以存入一个HashMap类型的键值,即putString(KEY, VALUES),这样,我们可以将List中的对象转化成一样长的字符中放进配置文件中. 当写入成功时,android系统会自动在目录data/data/工程包名/shared_prefs/目录下生成一个配置文件如(图5.14)
图 5.14
打开播放模式的配置文件.xml,文件中是以map的形式存储。键名 , 而它的值是is_Radom。如下图:
(2).xml配置文件的读取
我们仍以播放模式读取为例:当需要用到播放模式的确定时,我们将读取.Xml文件,同样用共享文件类SharedPreferences 通过用方法getSharedPreferences("SET_MSG",MODE_WORLD_READABLE),并且是只读方式获得.Xml的文件内容。SharedPreferences的对象调用方法getString("sigle_Play", null),方法返回一个String类型的值,即是我们以前存储进去的String值。此方法当该标记不存在时会默认返回一个null值。获得成功后我们就可以运用当前的值再对程序进行操作了。
5.5 手机扩展卡的访问
程序实现了文件浏览器的功能,作为一个文件浏览器,应该具有浏览的功能,当程序运行到浏览界面时,会有各文件的目录显示及图标标识。从文件浏览器中我们能看到各文件,而且能对其进行操作,本程序是专为播放器添加歌曲而设计的,因此功能仅限于对媒体文件的浏览,和含有媒体文件的目录的浏览。所以功能比较局限。
当显示菜单界面时,通过新增选项进入到文件浏览器中,或者当播放列表为空时,会提示进入文件浏览器进行歌曲新增操作。
5.5.1 文件浏览器界面
图5.15 图5.16
图 5.17
文件浏览器界面布局格式类似上面介绍的菜单,只是在界面的第一行新增了一个返回根目录的功能。由于程序只关系到目录/sdcard的目录下的文件,所以用程序屏蔽了其它的目录,这里只显示两个目录/sdcard和/system。播放器只需要用到媒体文件,所以代码也屏蔽了其它文件的子目录。当选中sdcard会进入到图5.16,该目录下只显示媒体文件,如.Mp3,和sdcard下的子目录。选中system会进入到图5.17,该目录会显示system下的各级子目录。当有媒体文件时才会出现添加Dialog。
当要添加选中的歌曲时,程序有自动判断功能,首先弹出Dialog(图5.18)。点击确定按钮后,程序会查询数据库中的歌曲,调用方法query(fileName),根据歌曲名字查询,如果歌曲不存在,则调用方法insertMusic(file),如果该歌曲名字已经存在,则弹出Dialog对话框(图5.19),当添加成功后,程序会跳转到播放列表中以显示添加结果。
图5.18 图5.19
5.5.2 文件浏览器功能实现
程序中,文件浏览器类为FileExplorerActivity继承了ListActivity,此Activity是一个ListView界面。整个界面是一个ListView布局,而每一行是一个LinearLayout水平方式布局,上面将放置一个图片和一个文件全路径。该文件全路径被存放到数据库中,以便歌曲播放能查询到歌曲路径源(图5.20)
图 5.20
该ListView实现了自动判断的功能,即程序可以通过访问扩展卡中的文件属性而自动识别文件属性。如上图所示:当为一个Mp3格式文件时,则前面图标显示mp3图标,当为一个文件目录时,则图标标识为一个文件。
文件浏览器是用递归算法实现的,方法fillWithRoot() 是返回根目录的列表。
fill(File[] files)返回子路径列表。算法如下:
items = new ArrayList(); items.add(getString(R.string.to_top));
for (File file : files) {
if (file.isDirectory()) {
if ((file.getPath().indexOf("/sdcard")) != -1
|| (file.getPath().indexOf("/system")) != -1)
items.add(file.getPath());}
if ((file.getPath().indexOf(".mp3")) != -1||(file.getPath().indexOf(".wav"))!=-1) {
items.add(file.getPath());
}}
//将文件路径显示在界面中
setListAdapter(new MusicAdapter(this, items));
本程序只让显示.Mp3和.Wav格式的媒体文件。
5.6 数据存储方式
在播放器正常运行时,由于各界面存在相互跳转,为了避免数据在界面跳转的过程中丢失,我们需要将一些数据进行临时存储或者永久存储。
Android作为一种手机操作系统,提供了如下几种存取数据的方式:Preference(配置)、File(文件)、SQLite数据和网络 。
另外,在Android中各个应用程序组件之间是相互的,彼此的数据不能共享。为了实现数据的共享,Android提供了Content Provider组件来实现应用程序之间数据的共享
5.6.1 SharedPreferences
Preference Preference提供了一种轻量级的数据存取方法,一般数据比较少,一些简单的配置信息。它以“键-值”(是一个Map)对的方式,将数据保存在一个XML配置文件中
使用到的接口(详细内容见文档)
android.content .SharedPreferences提供了保存数据的方法
android.content .SharedPreferences.Editor提供了获得数据的方法
以播放器中的播放模式存取为例:
(1).xml配置文件的读取
我们仍以播放模式读取为例:当需要用到播放模式的确定时,我们将读取.Xml文件,同样用共享文件类SharedPreferences 通过用方法getSharedPreferences("SET_MSG",MODE_WORLD_READABLE),并且是只读方式获得.Xml的文件内容。SharedPreferences的对象调用方法getString("sigle_Play", null),方法返回一个String类型的值,即是我们以前存储进去的String值。此方法当该标记不存在时会默认返回一个null值。获得成功后我们就可以运用当前的值再对程序进行操作了。
(2).xml配置文件的存储
类SharedPreferences。它有一个方法getSharedPreferences(参数1,参数2),参数1为写进时的标记,便于在从其中读取出来时的标记,参数2为读取模式,有只写模式(MODE_WORLD_WRITEABLE)和只读模式(MODE_WORLD_READABLE),在写之前将其置入编辑状态,用静态方法SharedPreferences.Editor editor = sp.edit();然后对象editor可以存入一个HashMap类型的键值,即putString(KEY, VALUES),这样,我们可以将List中的对象转化成一样长的字符中放进配置文件中。当写入成功时,android系统会自动在目录data/data/工程包名/shared_prefs/目录下生成一个配置文件
5.6.2 File存储方式
我们可以将一些数据直接以文件的形式保存在设备中。例如,一些文本文件、PDF文件、音视频文件和图片等。Android提供了文件读写的方法
方法Context.openFileInput()
获得标准Java文件输入流(FileInputStream)
Context.openFileOutput()
获得标准Java文件输出流(FileOutputStream)
Resources.openRawResource (R.raw.myDataFile)
方法返回InputStream。
5.6.3 SQLiteDatabase数据库
SQLite是一个嵌入式数据库引擎,针对内存等资源有限的设备(如手机、PDA、MP3)提供的一种高效的数据库引擎 SQLite数据库不像其它的数据库(如:Oracle),它没有服务器进程。所有的内容包含在同一个单文件中。该文件是跨平台的可以自由拷贝。基于其自身的先天优势,SQLite在嵌入式领域得到了广泛应用
SQLiteDatabase类
SQLiteDatabase代表一个数据库对象,提供了操作数据库的一些方法
常用方法(图5.21)
图 5.21
SQLiteOpenHelper类
SQLiteOpenHelper是SQLiteDatabase的一个帮助类,用来管理数据库的创建和版本更新。一般的用法是定义一个类继承之,并实现其两个抽象方法onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)两个抽象方法来创建和更新数据库
常用方法(图5.22)
图 5.22
参 考 书 籍
《Java API文档》
《Android 系统原理及开发要点详解》 作者:韩超,梁泉 著
《Android SDK开发范例大全》 作者:郭宏志 著
《Android Google API开发文档》 作者:Google官方
《Android Application Development》 出版社: O’Reilly
《Java编程思想think of java》 作者:Bruce Eckel
参 考 文 献
[1] 张孝祥著. java就业培训教程[M].北京:清华大学出版社,2007.
[2] 余志龙编著.Google Android SDK开发范例大全[M].北京:人民邮电出版社,2009-7-1.
[3] E2ECloud工作室著.深入浅出Google Android[M].北京:人民邮电出版社,2009-08-1.
[4] 靳岩 姚尚朗著.Google Android开发入门与实战[M].北京:清华大学出版社,2009-07-01.
[5] 高昂著.支持动态语言的Android平台[M].北京:人民邮电出版社,2009-05-07.
[6] eoe.Android开发社区.http://www.eoeandroid.com/. 2010-04-10.
[7] JavaEye论坛.http://www.javaeye.com/forums. 2010-04-15.
[8] Android API文档.http://androidappdocs.appspot.com/index.html. 2010-04-10.
[9] 高焕堂编.Android 应用框架原理与程式设计(第三版)[M].北京:清华大学出版社,2008-10-03
[10] 杨丰盛主编.Android 应用开发揭秘[M].西安:机械工业出版社,2010-01-25
[11] XML解析方式DOM、SAX之比较.http://wghjay.javaeye.com/blog/519955.2009-11-18.
名词术语:
Android 基于Linux操作系统的手机平台
ADT Android Development Tool Anroid开发工具
IDE Intergrate Design Environment 集成开发环境
ADB Android Debug Bridge 调试桥
AVD Android Virtual Devices Android虚拟设备
DDMS Dalvik Debug Monitor Service 调试监视服务
AIDL Android Interface Description Language
Android接口描述语言
xmlns XML NamePace XML命名空间