Android 酷儿音乐播放器设计报告书
南昌大学
大作业实验报告 题 目:专 业: 软 件 技 术 班 级: 112 班 学 号: 8001511072 学生姓名:设计人数:起讫日期: 完成时间: 2013-6-7
- 1 -
Android 酷儿音乐播放器设计报告书
目录
目录 ............................................................................................................................................. - 2 -
一、引 言.................................................................................................................................... - 4 -
1.1 项目背景 ....................................................................................................................... - 4 -
1.2 安卓介绍 ....................................................................................................................... - 5 -
1.3 安卓组件介绍 ............................................................................................................... - 5 -
1.4 安卓XML文件的使用 ................................................................................................ - 6 -
1.5 编写目的 ....................................................................................................................... - 7 -
二、系统功能简介 ...................................................................................................................... - 8 -
2.1 功能需求分析 .............................................................................................................. - 8 -
2.1.1 播放器的基本控制需求 ............................................................................................ - 8 -
2.2 系统性能需求 .............................................................................................................. - 9 -
2.3 运行环境需求 ............................................................................................................ - 10 -
三、程序详细设计 .................................................................................................................... - 11 -
3.1 程序界面设计 ............................................................................................................. - 11 -
i、本地音乐列表界面 ............................................................................................... - 11 - ii、主界面设计 ......................................................................................................... - 12 - iii、播放界面设计 .................................................................................................... - 14 - iV、程序启动界面设计 ............................................................................................ - 17 -
3.2扫描本地音乐文件 ...................................................................................................... - 19 -
3.3 程序ctivity类的设计 ................................................................................................ - 26 -
AllMusicListActivity.java文件代码 .......................................................................... - 27 - MainActivity.java文件代码 ..................................................................................... - 34 - MyMusicListActivity.java文件代码 ........................................................................ - 39 - PlayMusicAcitivity.java文件代码 ............................................................................ - 46 - PlayMusicListActivity.java ........................................................................................ - 55 - PlayService.java ......................................................................................................... - 61 - StartActivity.java ........................................................................................................ - 65 - DataUtils.java ............................................................................................................. - 67 - DBHelper.java ............................................................................................................ - 72 - ImageUtils.java .......................................................................................................... - 73 - LyricView.java ........................................................................................................... - 76 - MusicDemo.java ........................................................................................................ - 79 - MyApplication.java .................................................................................................... - 81 - PlayUtils.java ............................................................................................................. - 83 - SongLyric.java ........................................................................................................... - 88 -
四、程序设计结果及测试分析 ................................................................................................ - 94 -
4.1 程序运行效果图 ......................................................................................................... - 95 -
4.2 程序调试过程 ........................................................................................................... - 104 - - 2 -
Android 酷儿音乐播放器设计报告书
五、实验总结 .......................................................................................................................... - 106 -
六、参考资料 .......................................................................................................................... - 107 -
- 3 -
Android 酷儿音乐播放器设计报告书
一、引 言
1.1 项目背景
当今社会的生活节奏越来越快,人们对手机的要求也越来越高,由于手机市场发展迅速,使得手机操作系统也出现了不同各类,现在的市场上主要有三四手机操作系统,symbian,ios,Windows mobile,以及谷歌的Android操作系统,其中占有开放源代码优势的Android系统有最大的发展前景。那么能否在手机上拥有自己编写的个性音乐播放器呢?答案是:肯定的,谷歌Android系统就能做到。本文的音乐播放器就是基于谷歌Android手机平台的播放器。
Android:是谷歌于20xx年公布的开放式源代码手机系统,它的开放性就优于其它封闭式的手机系统,因此,任何人都可能根据自己的喜好将手机系统中的所有功能重新编写。这使得越来越多的人关注这个操作系统。本次作品音乐播放器就是基于Android平台的。
随着计算机的广泛运用,手机市场的迅速发展,各种音频视频资源也在网上广为流传,这些资源看似平常,但已经渐渐成为人们生活中必不可少的一部分了。于是各种手机播放器也紧跟着发展起来,但是很多播放器一味追求外观花哨,功能庞大,对用户的手机造成了很多资源浪费,比如CPU,内存等的占用率过高,在用户需要多任务操作时,受到了不小的影响,带来了许多不便,而对于大多数普通用户,许多功能用不上,形同虚设。针对以上各种弊端,选择了开发多语种的音频视频播放器,将各种性能优化,继承播放器的常用功能,满足一般用户(如听歌,看电影)的需求,除了能播放常见格式的语音视频文件,高级功能:还能播放RMVB格式的视频文件。此外,还能支持中文、英文等语言界面。
要研究了各种市场上流行的手机播放器,了解它们各自的插件及编码方式,还有各种播放器播放的特别格式文件,分析各种编码的优缺点以及各种播放器本身存在的缺陷和特点,编写出功能实用,使用方便快捷的播放器。目前已经实现的功能有能播放常见音频文件的功能,如MP3,WAV等,拥有播放菜单,能选择播放清单,具备一般播放器的功能,如上一曲,下一曲等功能。
- 4 -
Android 酷儿音乐播放器设计报告书
1.2 安卓介绍
Android一词的本义指“机器人”,同时也是Google于20xx年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件。目前最好的是Android2.0的摩托罗拉Droid
Android是基于Linux内核的软件平台和操作系统,早期由Google开发(在华注册商标名为“安致”),后由开放手机联盟(Open Handset Alliance)开发。它采用了软件堆层(software stack,又名以软件叠层)的架构,主要分为三部分。低层以Linux内核工作为基础,只提供基本功能;其他的应用软件则由各公司自行开发,以Java作为编写程序的一部分。另外,为了推广此技术,Google和其它几十个手机公司建立了开放手机联盟。
1.3 安卓组件介绍
Activity —— 应用表示层(基类Activity)
应用程序中的每个屏幕都是通过继承和扩展基类Activity来实现的。
同一应用中的每个Activity是相互独立的。程序启动后显示的第一幅画面是应用程序的第一个Activity(默认窗口),而后可以根据需要从这个Activity启动另一个新的Activity。
Activity利用View来实现应用中的GUI(用户直接通过GUI和应用程序做交互)。Activity窗口内的可见内容通过基类View提供。使用Activity.setContentView()方法设置当前Activity中的View对象。
Service —— 没有可见的用户界面,但能够长时间运行于后台(基类Service)
运行于应用程序进程的主线程中,因此Service不会阻塞其他组件和用户界面。
Service是不能自己启动的,必须通过Context对象(如一个Activity)调用startService或bindService方法来启动(用这两种方法启动的Service的生命周期不同)。
Broadcast Receiver —— 用户接收广播通知的组件(基类BroadcastReceiver)
Android中的广播要么来自于系统,要么来自普通应用程序。
- 5 -
Android 酷儿音乐播放器设计报告书
很多事件都可能导致系统广播,如手机所在时区发生变化,电池电量低,用户改变系统语言设置等。
来自普通应用程序,如一个应用程序通知其他应用程序某些数据已经下载完毕。
Content Provider —— 为解决应用程序间数据通信、共享的问题(基类ContentProvider)
在Android中,每个应用程序都是用自己的用户ID并在自己的进程中运行。这样的好处是,可以有效地保护系统及应用程序,避免被其他不正常德应用程序所影响,每个进程都拥有独立的进程地址空间和虚拟空间。
Content Provider可以将应用程序特定的数据提供给另一个应用程序使用。其数据存储方式可以是Android文件系统、SQLite数据库或者其他合理的方式。
当数据需要在应用程序间共享时,我们就可以利用ContentProvider为数据定义一个URI。之后,其他应用程序对数据进行查询或者修改时,只需要从当前上下文对象获得一个ContentResolver, 然后传入响应的URI就可以了。
Intent —— 连接组件的纽带
以上4种基本组件中,除了Content Provider是通过Content Resolver激活外,其他3种组件Activity、Service和Broadcast Receiver都是由Intent异步消息激活的。
Intent在不同的组件之间传递消息,将一个组件的请求意图传给另一个组件。因此,Intent是包含具体请求信息的对象。
Intent是一种运行时绑定(runtime binding)机制,它能够在程序运行的过程中连接两个不同的组件。通过Intent,你的程序可以向Android表到某种请求或者意愿,Android会根据意愿的内容选择适当的组件来处理请求。
1.4 安卓XML文件的使用
在安卓工程中,大量使用了XML文件,比如界面布局文件,字符资源文件,风格style文件,简单图形文件等。
比如在界面布局文件中,通过指定控件的排列方式、间隔像素、对齐方式等,达到对页面进行布局的目的,同时使用特定编辑器,实时解析布局文件,到达所见即所得的目的。
在字符资源中,通过关键字编辑字符内容,这样可以在不修改代码的情况下,修改程序内容。同时,考虑多国语言的使用,更加容易替换字符内容,所以我们建议在代码的编写过程中,尽量少地在程序中使用特定语言字符,而是在字符资源文件中编写。
- 6 -
Android 酷儿音乐播放器设计报告书
在风格文件中,通过特定关键字,可以使界面呈现统一风格,同时减少重复代码的编写,减轻工作量。图形XML文件中可以实现一些矩形、椭圆形等图形文件,可以指定颜色和渐变颜色范围。
1.5 编写目的
现今社会生活紧张,而欣赏音乐是其中最好的舒缓压力的方式之一,本项目的目的是开发一个可以播放主流音乐文件格式的播放器,本设计的实现的这主要功能是播放mp3、wav多种格式的音乐文件,并且能够控制播放,暂停,停止,上一曲,下一曲,显示歌词,视觉外观,播放列表和歌曲文件的管理操作等多种播放控制功能,界面简明,操作简单。
本项目是一款基于Android手机平台的音乐播放器,使Android手机拥有个性的多媒体播放器,使手机显得更生动灵活化,与人们更为接近,让手机主人随时随地处于音乐视频的旋律之中。使人们的生活更加多样化。也使设计者更加熟练Android的技术和其它在市场上的特点。
- 7 -
Android 酷儿音乐播放器设计报告书
二、系统功能简介
2.1 功能需求分析
根据项目的目标,可获得项目系统的基本需求,以下从不同角度来描述系统的需求,并且使用用例图来描述,系统的功能需求,分成四部分来概括,即播放器的基本控制需要,播放列表管理需求,播放器友好性需求和播放器扩展卡需求。
2.1.1 播放器的基本控制需求
下面图2-1是音乐播放器的基本用例图,描述了程序的基本功能。
- 8 -
Android 酷儿音乐播放器设计报告书
图2-1-1播放器基本用例图
2.2 系统性能需求
根据Android手机系统要求无响应时间为5秒,所以就有如下性能要求:
(1)当要求歌曲播放时,程序响应时间最长不能超过5秒
(2)当要求歌曲暂停时,程序响应时间最长不能超过5秒
(3)当要求歌曲停止时,程序响应时间最长不能超过5秒
(4)当要求歌曲上/下一首时,程序响应时间最长不能超过5秒
(5)当要求进行清单列表时,程序响应时间最长不能超过5秒 - 9 -
Android 酷儿音乐播放器设计报告书
2.3 运行环境需求
操作系统:Android手机基于Linux操作系统 支持环境:Android 2.2及其以上版本 开发环境:Eclipse及ADT插件
- 10 -
Android 酷儿音乐播放器设计报告书
三、程序详细设计
3.1 程序界面设计
i、本地音乐列表界面
设计如下3-1图所示
图3-1本地音乐列表界面
本地音乐列表界面采用LinearLayout线性布局设计,首先是占据整个屏幕的高度和宽度,设置背景颜色,然后再在这里面定义ListView列表,设置每一个列表的高度宽度,颜色,默认值等。具体代码如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="/apk/res/android"
- 11 -
Android 酷儿音乐播放器设计报告书
android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#00000000" android:orientation="vertical" >
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent" android:layout_height="504dp" android:background="#00000000" android:divider="@drawable/divider" android:dividerHeight="1dp"
android:drawSelectorOnTop="false" android:footerDividersEnabled="false" android:headerDividersEnabled="false" android:scrollingCache="false" > </ListView>
</LinearLayout>
ii、主界面设计
如下3-2图所示
- 12 -
Android 酷儿音乐播放器设计报告书
图3-2主界面
主界面采用RelativeLayout相对布局器设计,设置背景图片,音乐列表相对位置主界面采用相对布局管理器代码如下
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="/apk/es/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/bg_blue" >
<RelativeLayout
android:id="@+id/LinearLayout1"
android:layout_width="fill_parent"
android:layout_height="538dp"
android:background="#00000000"
android:orientation="vertical" >
<TabWidget
android:id="@android:id/tabs"
- 13 -
Android 酷儿音乐播放器设计报告书
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/LinearLayout1" > </TabWidget>
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="fill_parent“
android:layout_height="fill_parent"
android:layout_below="@android:id/tabs"
android:layout_marginBottom="55dp"
android:background="#00000000" />
<LinearLayout
android:id="@+id/footer"
android:layout_width="fill_parent"
android:layout_height="55dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="@drawable/footer"
android:orientation="horizontal" >
<TextView
android:id="@+id/text_footet_playingMusic" android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:background="@drawable/footertext_select" android:padding="10dp“
android:text="@string/text_footerText"
android:textColor="@color/textColor" />
</LinearLayout>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/footer" />
</RelativeLayout>
</TabHost>
iii、播放界面设计
如下图3-3所示
- 14 -
Android 酷儿音乐播放器设计报告书
图3-3播放界面
播放界面采用相对布局管理器,首先设置背景图片,管理器占据整个屏幕。然后采用线性布局管理器嵌套LinearLayout,定义图片按钮button,定义文本显示组件,textview用来显示歌曲名称和歌词,这里如果系统中没有歌词,那么将显示默认的系统图片。另外这里涉及SeekBar的用法。在播放音乐或者视频的时候,都会有一个播放的即时进度条,显示当前多媒体的播放进度,同时,我们可以拖动这个进度条,超前播放或者延后播放,这个控件就是拖动条。在Android中我们使用SeekBar来实现进度拖动效果。具体布局设计见下面代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="/apk/res/android" android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/bg_blue" >
<ImageView
android:id="@+id/image_pic"
android:layout_width="200dp"
android:layout_height="150dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
- 15 -
Android 酷儿音乐播放器设计报告书
android:layout_marginTop="10dp"
android:background="#33AAAAAA"
android:contentDescription="@string/app_name" android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="8dp"
android:src="@drawable/pic" />
<TextView
android:id="@+id/text_musicName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/image_pic"
android:layout_centerHorizontal="true"
android:gravity="center"
android:text="@string/text_musicName"
android:textColor="@color/textColor"
android:textSize="16sp" />
<LinearLayout
android:id="@+id/layout_down"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="@drawable/footer"
android:gravity="center"
android:orientation="horizontal"
android:padding="5dp" >
<Button
android:id="@+id/button_last"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:background="@drawable/last_select"
android:contentDescription="@string/app_name" /> <Button
android:id="@+id/button_play"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:background="@drawable/play_select" - 16 -
Android 酷儿音乐播放器设计报告书
android:contentDescription="@string/app_name" /> <Button
android:id="@+id/button_next"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:background="@drawable/next_select"
android:contentDescription="@string/app_name" /> </LinearLayout>
<LinearLayout
android:id="@+id/seekBar_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@id/layout_down" >
<SeekBar
android:id="@+id/seekBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:maxHeight="4dp"
android:minHeight="3dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:progressDrawable="@drawable/seekbarcolors" android:thumb="@drawable/cursor"
android:thumbOffset="0dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/lrc_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/text_musicName"
android:layout_marginBottom="95dp"
android:background="#33AAAAAA" >
</LinearLayout>
</RelativeLayout>
iV、程序启动界面设计
如下图3-4
- 17 -
Android 酷儿音乐播放器设计报告书
图3-4程序启动界面
采用线性布局管理器LinearLayout后设置背景图片,定义TextView显示程序名称即‘酷儿音乐’以及文本显示属性大小颜色等,同时定义组件ProgressBar表示程序的运行进度 界面详细代码如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="/apk/res/android" android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/bg_start"
android:orientation="vertical" >
<TextView
android:id="@+id/text_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
- 18 -
Android 酷儿音乐播放器设计报告书
android:layout_marginTop="30dp"
android:layout_marginBottom="10dp"
android:text=
android:textSize="25sp"
android:textColor="@color/textColor" />
<ProgressBar
style="@android:style/Widget.ProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
</LinearLayout>
3.2扫描本地音乐文件
程序会对本地音乐文件夹进行扫描过滤,提取出mp3的文件以供播放,文件过滤类的内容如下:
package com.huazi.Mp3Player.Utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.provider.MediaStore;
import com.huazi.Mp3Player.MainActivity;
import com.huazi.Mp3Player.StartActivity;
public class DataUtils {
- 19 -
Android 酷儿音乐播放器设计报告书
public static void update_AllMusicData(ContentResolver resolver,Context context) { musicList.clear(); Cursor cursor
null, null, = null, private static List<MusicDemo> musicList = new ArrayList<MusicDemo>(); resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
while (cursor.moveToNext()) { // 歌曲的名称 String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
// 歌曲的歌手名 String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
// 歌曲文件的路径 String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
{
} musicList.add(new MusicDemo(name, path, artist)); DBHelper dbHelper = new DBHelper(context, "myData"); SQLiteDatabase db = dbHelper.getWritableDatabase(); db.execSQL("delete from all_music"); if (!musicList.isEmpty()) { for (Iterator<MusicDemo> iterator = musicList.iterator(); iterator.hasNext();) MusicDemo demo = (MusicDemo) iterator.next(); ContentValues values = new ContentValues(); values.put("name", demo.getName()); values.put("path", demo.getPath()); values.put("artist", demo.getArtist()); db.insert("all_music", null, values); - 20 -
Android 酷儿音乐播放器设计报告书
}
}
db.close();
}
public static void get_AllMusicListFD(Context context) {
if (!MyApplication.getAllMusicList().isEmpty()) {
MyApplication.getAllMusicList().clear();
}
DBHelper dbHelper = new DBHelper(context, "myData");
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select name,path,artist from all_music", null); while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex("name")); String path = cursor.getString(cursor.getColumnIndex("path")); String artist = cursor.getString(cursor.getColumnIndex("artist")); HashMap<String, Object> map = new HashMap<String, Object>(); map.put("name", name);
map.put("path", path);
map.put("artist", artist);
MyApplication.getAllMusicList().add(map);
}
cursor.close();
db.close();
}
public static void get_PlayMusicListFD() {
if (!MyApplication.getPlayMusicList().isEmpty()) {
MyApplication.getPlayMusicList().clear();
}
DBHelper dbHelper = new DBHelper(StartActivity.context, "myData"); SQLiteDatabase db = dbHelper.getReadableDatabase();
- 21 -
Android 酷儿音乐播放器设计报告书
null);
} Cursor cursor = db.rawQuery("Select name,path,artist from play_music", null); while (cursor.moveToNext()) { } db.close(); String name = cursor.getString(cursor.getColumnIndex("name")); String path = cursor.getString(cursor.getColumnIndex("path")); String artist = cursor.getString(cursor.getColumnIndex("artist")); HashMap<String, Object> map = new HashMap<String, Object>(); map.put("name", name); map.put("path", path); map.put("artist", artist); MyApplication.getPlayMusicList().add(map); System.out.println(name + path + artist); public static void get_HappyMusicListFD() { if (!MyApplication.getHappyMusicList().isEmpty()) { } DBHelper dbHelper = new DBHelper(StartActivity.context, "myData"); SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("Select name,path,artist from my_happy_music", MyApplication.getHappyMusicList().clear(); while (cursor.moveToNext()) { String name = cursor.getString(cursor.getColumnIndex("name")); String path = cursor.getString(cursor.getColumnIndex("path")); String artist = cursor.getString(cursor.getColumnIndex("artist")); HashMap<String, Object> map = new HashMap<String, Object>(); map.put("name", name); map.put("path", path); map.put("artist", artist); MyApplication.getHappyMusicList().add(map); - 22 -
Android 酷儿音乐播放器设计报告书
null);
} } db.close(); public static void get_QuietMusicListFD() { if (!MyApplication.getQuietMusicList().isEmpty()) { } DBHelper dbHelper = new DBHelper(StartActivity.context, "myData"); SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("Select name,path,artist from my_quiet_music", MyApplication.getQuietMusicList().clear(); } while (cursor.moveToNext()) { } db.close(); String name = cursor.getString(cursor.getColumnIndex("name")); String path = cursor.getString(cursor.getColumnIndex("path")); String artist = cursor.getString(cursor.getColumnIndex("artist")); HashMap<String, Object> map = new HashMap<String, Object>(); map.put("name", name); map.put("path", path); map.put("artist", artist); MyApplication.getQuietMusicList().add(map); public static void get_SadMusicListFD() { if (!MyApplication.getSadMusicList().isEmpty()) { } DBHelper dbHelper = new DBHelper(StartActivity.context, "myData"); SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("Select name,path,artist from my_sad_music", null); - 23 - MyApplication.getSadMusicList().clear();
Android 酷儿音乐播放器设计报告书
} while (cursor.moveToNext()) { } db.close(); String name = cursor.getString(cursor.getColumnIndex("name")); String path = cursor.getString(cursor.getColumnIndex("path")); String artist = cursor.getString(cursor.getColumnIndex("artist")); HashMap<String, Object> map = new HashMap<String, Object>(); map.put("name", name); map.put("path", path); map.put("artist", artist); MyApplication.getSadMusicList().add(map); public static void get_AllListsFD() { } get_AllMusicListFD(StartActivity.context); get_HappyMusicListFD(); get_PlayMusicListFD(); get_QuietMusicListFD(); get_SadMusicListFD(); public static void upData_Lists(Context context,String table_name) { List<HashMap<String, Object>> musicList = new ArrayList<HashMap<String, Object>>();
if (table_name.equals("play_music")) { } else if (table_name.equals("my_happy_music")) { } else if (table_name.equals("my_quiet_music")) { musicList = MyApplication.getQuietMusicList(); - 24 - musicList = MyApplication.getPlayMusicList(); musicList = MyApplication.getHappyMusicList();
Android 酷儿音乐播放器设计报告书
} else if (table_name.equals("my_sad_music")) { } else{ } SQLiteDatabase db = new DBHelper(context, "myData").getWritableDatabase(); db.execSQL("delete from " + table_name); db.execSQL("update sqlite_sequence SET seq = 0 where name = '"+ System.out.println("table name error!"); musicList = MyApplication.getSadMusicList(); table_name+"'");
for (Iterator<HashMap<String, Object>> iterator = musicList.iterator(); iterator.hasNext();) {
HashMap<String, Object> hashMap = (HashMap<String, Object>) iterator.next();
} public static void upData_allLists() { } upData_Lists(MainActivity.context,"play_music"); upData_Lists(MainActivity.context,"my_happy_music"); upData_Lists(MainActivity.context,"my_quiet_music"); upData_Lists(MainActivity.context,"my_sad_music"); } } db.close(); ContentValues values = new ContentValues(); values.put("name", (String) hashMap.get("name")); values.put("path", (String) hashMap.get("path")); values.put("artist", (String) hashMap.get("artist")); db.insert(table_name, null, values);
- 25 -
Android 酷儿音乐播放器设计报告书
3.3 程序ctivity类的设计
程序的界面MusicTestActivity类是程序的主要部分,设计到界面所有控件的操作及设计、程序的流程控制及音乐播放的核心部分。类的大纲如下图3-7所示。
图3-7
- 26 -
Android 酷儿音乐播放器设计报告书
Activity类文件具体如下
AllMusicListActivity.java文件代码 package com.huazi.Mp3Player;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.huazi.Mp3Player.Utils.DataUtils;
import com.huazi.Mp3Player.Utils.MyApplication; import com.huazi.Mp3Player.Utils.PlayUtils;
public class AllMusicListActivity extends ListActivity {
private ListView listView;
- 27 -
Android 酷儿音乐播放器设计报告书
private static MyListAdapter listAdapter;
public static Context context;
private ContentResolver resolver;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.allmusic_list_layout);
getWindow().setBackgroundDrawable(null);
listView = (ListView) findViewById(android.R.id.list);
context = this;
resolver = getContentResolver();
listAdapter = new MyListAdapter(this, MyApplication.getAllMusicList());
listView.setAdapter(listAdapter);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
HashMap<String, Object> map = MyApplication.getAllMusicList().get(position);
if (map.get("name").equals(PlayService.name) && MyApplication.playStatus == 1) {
Toast.makeText(context, "正在播放...", 0).show();
}else {
boolean b = PlayUtils.addMusicToList(context, map, MyApplication.getPlayMusicList());
if (b) {
PlayMusicListActivity.myListAdapter.notifyDataSetChanged(); PlayUtils.turnToPlay(map, context);
}
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 0, 0, "播放全部音乐");
menu.add(0, 1, 1, "更新本地乐库");
return super.onCreateOptionsMenu(menu);
}
@Override
- 28 -
Android 酷儿音乐播放器设计报告书
//
public boolean onOptionsItemSelected(MenuItem item) { } switch (item.getItemId()) { case 0: PlayUtils.turnToPlay_List(context, MyApplication.getAllMusicList()); break; case 1: new AllMusic_List_asyncTask(listAdapter).execute(); break; default: break; } return super.onOptionsItemSelected(item); public boolean onKeyDown(int keyCode, android.view.KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { backDialog(); } return false; }; public void backDialog() { AlertDialog.Builder builder = new Builder(this); builder.setMessage("确认退出吗?"); builder.setTitle("提示"); builder.setPositiveButton("确认", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); ((Activity) context).finish(); new AsyncTask<Void, Void, Void>(){ @Override protected Void doInBackground(Void... params) { if (MyApplication.playStatus != 0) { PlayService.stop(); PlayService.player.release(); } DataUtils.upData_allLists(); return null; } }.execute(); - 29 -
Android 酷儿音乐播放器设计报告书
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
public class MyListAdapter extends BaseAdapter {
private class buttonViewHolder {
TextView musicName;
ImageButton add;
ImageButton collect;
}
private ArrayList<HashMap<String, Object>> musicList;
private LayoutInflater mInflater;
private Context mContext;
private buttonViewHolder holder;
public MyListAdapter(Context context, List<HashMap<String, Object>> appList) { musicList = (ArrayList<HashMap<String, Object>>) appList;
mContext = context;
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return musicList.size();
}
public Object getItem(int position) {
return musicList.get(position);
}
public long getItemId(int position) {
return position;
- 30 -
Android 酷儿音乐播放器设计报告书
}
public void removeItem(int position) {
musicList.remove(position);
this.notifyDataSetChanged();
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView != null) {
holder = (buttonViewHolder) convertView.getTag();
} else {
convertView = mInflater.inflate(R.layout.allmusic_list_item_layout, null); holder = new buttonViewHolder();
holder.musicName = (TextView) convertView.findViewById(R.id.text_musicName);
holder.add = (ImageButton) convertView.findViewById(R.id.button_add);
holder.collect = (ImageButton) convertView.findViewById(R.id.button_collect);
convertView.setTag(holder);
}
HashMap<String, Object> itemInfo = musicList.get(position);
if (itemInfo != null) {
String aname = (String) itemInfo.get("name");
holder.musicName.setText(aname);
holder.add.setOnClickListener(new addOnClickListener(position));
holder.collect.setOnClickListener(new collectOnClickListener(position)); }
return convertView;
}
class collectOnClickListener implements OnClickListener {
int position;
public collectOnClickListener(int position) {
this.position = position;
}
public void onClick(View v) {
Builder builder = new AlertDialog.Builder(context);
builder.setIcon(R.drawable.collect);
- 31 -
Android 酷儿音乐播放器设计报告书
builder.setTitle(" 请选择收藏列表");
builder.setItems(new String[] { "轻音乐", "华语", "热歌" }, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
HashMap<String, Object> map = MyApplication.getAllMusicList().get(position);
boolean b;
switch (which) {
case 0:
b = PlayUtils.addMusicToList(context,map, MyApplication.getHappyMusicList());
break;
case 1:
b = PlayUtils.addMusicToList(context, map, MyApplication.getQuietMusicList());
break;
case 2:
b = PlayUtils.addMusicToList(context, map, MyApplication.getSadMusicList());
break;
default:
b = false;
break;
}
if (b) MyMusicListActivity.listAdapter.notifyDataSetChanged(); }
});
builder.create().show();
}
}
class addOnClickListener implements OnClickListener {
private int position;
public addOnClickListener(int position) {
this.position = position;
}
public void onClick(View v) {
HashMap<String, Object> map = - 32 -
Android 酷儿音乐播放器设计报告书
MyApplication.getAllMusicList().get(position);
boolean b = PlayUtils.addMusicToList(context, MyApplication.getPlayMusicList());
if (b) PlayMusicListActivity.myListAdapter.notifyDataSetChanged(); }
}
}
public class AllMusic_List_asyncTask extends AsyncTask<String, Void, Void> {
private ProgressDialog progressDialog;
private MyListAdapter listAdapter;
public AllMusic_List_asyncTask(MyListAdapter listAdapter) {
this.listAdapter = listAdapter;
progressDialog = new ProgressDialog(context);
}
@Override
protected void onPreExecute() {
progressDialog.setMessage("扫描所有音乐...");
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(false);
progressDialog.show();
super.onPreExecute();
}
@Override
protected Void doInBackground(String... params) {
DataUtils.update_AllMusicData(resolver,context);
DataUtils.get_AllMusicListFD(context);
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
}
@Override
protected void onPostExecute(Void result) {
listAdapter.notifyDataSetChanged();
progressDialog.dismiss();
map, - 33 -
Android 酷儿音乐播放器设计报告书
}
}
}
MainActivity.java文件代码
package com.huazi.Mp3Player;
import java.util.ArrayList;
import android.app.LocalActivityManager;
import android.app.TabActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener; import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.TabHost;
import android.widget.TabHost.OnTabChangeListener;
import android.widget.TextView;
import com.huazi.Mp3Player.Utils.MyApplication;
public class MainActivity extends TabActivity {
public static Context context;
private LocalActivityManager manager;
private TabHost tabHost;
private ViewPager viewPager;
public static TextView footer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main);
context = MainActivity.this;
footer = (TextView) findViewById(R.id.text_footet_playingMusic);
- 34 -
Android 酷儿音乐播放器设计报告书
manager = new LocalActivityManager(this, true);
manager.dispatchCreate(savedInstanceState);
this.loadTabHost();
this.loadViewPager();
tabHost.setCurrentTab(2);
footer.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
MainActivity.context.startActivity(new Intent(MainActivity.this, PlayMusicAcitivity.class));
}
});
}
@Override
protected void onResume() {
if (MyApplication.playStatus != 0) {
footer.setText(PlayService.name);
}
super.onResume();
}
public View getView(String id, Intent intent) {
return manager.startActivity(id, intent).getDecorView();
}
public void loadTabHost() {
tabHost = getTabHost();
tabHost.addTab(tabHost.newTabSpec("myMusic").setIndicator("我的音乐", getResources().getDrawable(R.drawable.xin_big)).setContent(new Intent(context, MyMusicListActivity.class)));
tabHost.addTab(tabHost.newTabSpec("allMusic").setIndicator("所有歌曲", getResources().getDrawable(R.drawable.all_tab)).setContent(new Intent(context, AllMusicListActivity.class)));
tabHost.addTab(tabHost.newTabSpec("playingMusic").setIndicator("播放列表", getResources().getDrawable(R.drawable.play_tab)).setContent(new Intent(context, PlayMusicListActivity.class)));
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
- 35 -
Android 酷儿音乐播放器设计报告书
} }); public void onTabChanged(String tabId) { if (tabId.equals("myMusic")) { viewPager.setCurrentItem(0); } if (tabId.equals("allMusic")) { viewPager.setCurrentItem(1); } if (tabId.equals("playingMusic")) { viewPager.setCurrentItem(2); } } public void loadViewPager() { viewPager = (ViewPager) findViewById(R.id.viewPager); final ArrayList<View> list = new ArrayList<View>(); list.add(getView("myMusic", new Intent(context, MyMusicListActivity.class))); list.add(getView("allMusic", new Intent(context, AllMusicListActivity.class))); list.add(getView("playingMusic", new Intent(context, PlayMusicListActivity.class))); viewPager.setAdapter(new PagerAdapter() { @Override public void destroyItem(View arg0, int arg1, Object arg2) { viewPager.removeView(list.get(arg1)); } @Override public Object instantiateItem(View arg0, int arg1) { ((ViewPager) arg0).addView(list.get(arg1)); return list.get(arg1); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public int getCount() { return list.size(); - 36 -
Android 酷儿音乐播放器设计报告书
}
@Override
public void finishUpdate(View arg0) {
// TODO Auto-generated method stub
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) { // TODO Auto-generated method stub
}
@Override
public Parcelable saveState() {
// TODO Auto-generated method stub
return null;
}
@Override
public void startUpdate(View arg0) {
// TODO Auto-generated method stub
}
});
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
public void onPageSelected(int arg0) {
tabHost.setCurrentTab(arg0);
}
public void onPageScrolled(int arg0, float arg1, int arg2) { }
public void onPageScrollStateChanged(int arg0) {
}
});
- 37 -
Android 酷儿音乐播放器设计报告书
} }
- 38 -
Android 酷儿音乐播放器设计报告书
MyMusicListActivity.java文件代码 package com.huazi.Mp3Player;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ExpandableListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import com.huazi.Mp3Player.Utils.DataUtils;
import com.huazi.Mp3Player.Utils.MyApplication;
import com.huazi.Mp3Player.Utils.PlayUtils;
public class MyMusicListActivity extends ExpandableListActivity {
private ExpandableListView myMusicListView;
private ArrayList<HashMap<String, Object>> groupsList; private List<List<HashMap<String, Object>>> childsList; public static MyMusicListAdapter listAdapter;
private static Context context;
@Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
- 39 -
Android 酷儿音乐播放器设计报告书
setContentView(R.layout.mymusic_list_layout);
myMusicListView = getExpandableListView();
context = this;
groupsList = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> group1 = new HashMap<String, Object>();
group1.put("name", "轻音乐");
HashMap<String, Object> group2 = new HashMap<String, Object>();
group2.put("name", "华语");
HashMap<String, Object> group3 = new HashMap<String, Object>();
group3.put("name", "热歌");
groupsList.add(group1);
groupsList.add(group2);
groupsList.add(group3);
childsList = new ArrayList<List<HashMap<String, Object>>>();
childsList.add(MyApplication.getHappyMusicList());
childsList.add(MyApplication.getQuietMusicList());
childsList.add(MyApplication.getSadMusicList());
listAdapter = new MyMusicListAdapter(this, groupsList, childsList);
myMusicListView.setAdapter(listAdapter);
}
public static Context getContext(){
return context;
}
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
HashMap<String, Object> map = childsList.get(groupPosition).get(childPosition); if (map.get("name").equals(PlayService.name) && MyApplication.playStatus == 1) { Toast.makeText(context, "正在播放...", 0).show();
}else {
boolean b = PlayUtils.addMusicToList(context, map, MyApplication.getPlayMusicList());
if (b) {
PlayMusicListActivity.myListAdapter.notifyDataSetChanged();
PlayUtils.turnToPlay(map, context);
}
}
return super.onChildClick(parent, v, groupPosition, childPosition, id);
- 40 -
Android 酷儿音乐播放器设计报告书
} public boolean onKeyDown(int keyCode, android.view.KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { backDialog();
}
return false;
};
@Override
protected void onDestroy() {
DataUtils.upData_allLists();
super.onDestroy();
}
public void backDialog() {
AlertDialog.Builder builder = new Builder(this);
builder.setMessage("确认退出吗?");
builder.setTitle("提示");
builder.setPositiveButton("确认", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
((Activity) context).finish();
new AsyncTask<Void, Void, Void>(){
@Override
protected Void doInBackground(Void... params) {
if (MyApplication.playStatus != 0) {
PlayService.stop();
// PlayService.player.release();
}
DataUtils.upData_allLists();
return null;
}
}.execute();
}
});
builder.setNegativeButton("取消", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
- 41 -
Android 酷儿音乐播放器设计报告书
dialog.dismiss();
}
});
builder.create().show();
}
class MyMusicListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<HashMap<String, Object>> groups;
private List<List<HashMap<String, Object>>> childs;
private childViewsHolder childHolder;
private GroupViewsHolder groupHolder;
public MyMusicListAdapter(Context context, List<HashMap<String, Object>> groups, List<List<HashMap<String, Object>>> childs) {
this.context = context;
this.groups = groups;
this.childs = childs;
}
private class childViewsHolder {
TextView childText;
ImageButton childButton;
}
public Object getChild(int arg0, int arg1) {
return childs.get(arg0).get(arg1);
}
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
public void removeChildItem(int groupPosition, int childPosition) {
childs.get(groupPosition).remove(childPosition);
this.notifyDataSetChanged();
}
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
- 42 -
Android 酷儿音乐播放器设计报告书
if (convertView != null) {
childHolder = (childViewsHolder) convertView.getTag();
} else {
childHolder = new childViewsHolder();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.mymusic_childs_layout, null);
childHolder.childText = (TextView) convertView.findViewById(R.id.text_childItem);
childHolder.childButton = (ImageButton) convertView.findViewById(R.id.button_deleteChildItem);
convertView.setTag(childHolder);
}
HashMap<String, Object> childItem = childs.get(groupPosition).get(childPosition);
if (childItem != null) {
String name = (String) childItem.get("name");
childHolder.childText.setText(name);
childHolder.childButton.setOnClickListener(new
childItemOnClick(groupPosition, childPosition));
}
return convertView;
}
public class childItemOnClick implements android.view.View.OnClickListener {
private int groupPosition;
private int childPosition;
public childItemOnClick(int groupPosition, int childposition) {
this.groupPosition = groupPosition;
this.childPosition = childposition;
}
public void onClick(View v) {
removeChildItem(groupPosition, childPosition);
}
}
public int getChildrenCount(int groupPosition) {
- 43 -
Android 酷儿音乐播放器设计报告书
return childs.get(groupPosition).size();
}
public Object getGroup(int groupPosition) {
return groups.get(groupPosition);
}
public int getGroupCount() {
return groups.size();
}
public long getGroupId(int groupPosition) {
return groupPosition;
}
private class GroupViewsHolder {
TextView groupText;
ImageButton groupButton;
}
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
if (convertView != null) {
groupHolder = (GroupViewsHolder) convertView.getTag();
} else {
groupHolder = new GroupViewsHolder();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.mymusic_groups_layout, null);
groupHolder.groupText = (TextView) convertView.findViewById(R.id.text_groupItem);
groupHolder.groupButton = (ImageButton) convertView.findViewById(R.id.button_playAll);
convertView.setTag(groupHolder);
}
HashMap<String, Object> map = groups.get(groupPosition);
if (map != null) {
String name = (String) map.get("name");
- 44 -
Android 酷儿音乐播放器设计报告书
groupHolder.groupText.setText(name);
groupHolder.groupButton.setOnClickListener(new
GroupOnClick(groupPosition));
}
return convertView;
}
class GroupOnClick implements View.OnClickListener {
private int position;
public GroupOnClick(int position) {
this.position = position;
}
public void onClick(View v) {
switch (position) {
case 0:
PlayUtils.turnToPlay_List(context,
MyApplication.getHappyMusicList());
break;
case 1:
PlayUtils.turnToPlay_List(context, MyApplication.getQuietMusicList()); break;
case 2:
PlayUtils.turnToPlay_List(context, MyApplication.getSadMusicList()); break;
default:
break;
}
}
}
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
- 45 -
Android 酷儿音乐播放器设计报告书
return true;
}
}
}
PlayMusicAcitivity.java文件代码 package com.huazi.Mp3Player;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView;
import android.widget.Toast;
import com.huazi.Mp3Player.Utils.LyricView;
import com.huazi.Mp3Player.Utils.MyApplication; - 46 -
Android 酷儿音乐播放器设计报告书
import com.huazi.Mp3Player.Utils.PlayUtils;
import com.huazi.Mp3Player.Utils.SongLyric;
public class PlayMusicAcitivity extends Activity {
static TextView musicTextView;
private Button lastButton;
public static Button playButton;
private Button nextButton;
static Context context;
public static SeekBar seekBar;
static ImageView musicImage;
static String name;
static String path;
static String artist;
static Handler handler;
public static Runnable runnable;
static boolean isChangeSeekbarP;
ContentResolver resolver;
static String SDRoot = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;
private static SongLyric lrc;
private static LyricView lrcView;
private static long time = 0;
private static LinearLayout lrcLayout;
private static String lrcPath;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.playmusic_layout);
context = this;
resolver = getContentResolver();
musicTextView = (TextView) findViewById(R.id.text_musicName);
lastButton = (Button) findViewById(R.id.button_last);
playButton = (Button) findViewById(R.id.button_play);
nextButton = (Button) findViewById(R.id.button_next);
seekBar = (SeekBar) findViewById(R.id.seekBar);
- 47 -
Android 酷儿音乐播放器设计报告书
musicImage = (ImageView) findViewById(R.id.image_pic);
lrcLayout = (LinearLayout) findViewById(R.id.lrc_layout);
lrcView = new LyricView(lrcLayout.getContext());
lrcLayout.addView(lrcView);
lastButton.setOnClickListener(new ButtonListener());
playButton.setOnClickListener(new ButtonListener());
nextButton.setOnClickListener(new ButtonListener());
seekBar.setOnSeekBarChangeListener(new onSeekBarListener());
handler = new Handler();
runnable = new Runnable() {
public void run() {
System.out.println(PlayService.player.getCurrentPosition()); if (MyApplication.playStatus == 1) {
seekBar.setMax(PlayService.player.getDuration());
seekBar.setProgress(PlayService.player.getCurrentPosition()); if (new File(lrcPath).exists()) {
lrc = new SongLyric(lrcPath);
lrc.setMaxTime(PlayService.player.getDuration()); lrcView.setLyric(lrc);
time = PlayService.player.getCurrentPosition(); lrcView.setTime(time);
lrcView.postInvalidate();
setTitle(SongLyric.longToString((int) time) + SongLyric.longToString((int) lrc.getMaxTime()));
}
}
if (!name.equals(PlayService.name)) {
name = PlayService.name;
path = PlayService.path;
artist = PlayService.artist;
musicTextView.setText(name);
musicImage.setImageResource(R.drawable.pic);
new imageTask().execute();
lrcPath = path.substring(0, path.length()-4) + ".lrc"; }
handler.postDelayed(this, 50);
}
};
if (MyApplication.getPlayMusicList().isEmpty()) {
"/" + - 48 -
Android 酷儿音乐播放器设计报告书
} name = null; path = null; } else { if (MyApplication.playStatus != 0) { name = PlayService.name; path = PlayService.path; artist = PlayService.artist; System.out.println(path); lrcPath = path.substring(0, path.length()-4) + ".lrc"; System.out.println(lrcPath); musicTextView.setText(name); new imageTask().execute(); if (MyApplication.playStatus == 1) { handler.post(runnable); playButton.setBackgroundResource(R.drawable.pause_select); } if (MyApplication.playStatus == 2) { playButton.setBackgroundResource(R.drawable.play_select); } for (int i = 0; i < MyApplication.getPlayMusicList().size(); i++) { if (name.equals(MyApplication.getPlayMusicList().get(i).get("name"))) { MyApplication.musicPosition = i; break; } } } else { HashMap<String, Object> map = MyApplication.getPlayMusicList().get(0); name = (String) map.get("name"); path = (String) map.get("path"); artist = (String) map.get("artist"); lrcPath = path.substring(0, path.length()-4) + ".lrc"; } } public static class imageTask extends AsyncTask<Object, Object, Object> { @Override protected Object doInBackground(Object... params) { File file = new File(SDRoot + "Mp3Player" + File.separator + artist + ".jpg"); System.out.println(file); - 49 -
Android 酷儿音乐播放器设计报告书
if (!file.exists()) {
System.out.println("-------->下载图片!!!<----------");
InputStream inputStream = PlayUtils.getInputstreamByKeyWord(artist); PlayUtils.write2SDFromInput("Mp3Player", artist + ".jpg", inputStream); }
return null;
}
@Override
protected void onPostExecute(Object result) {
Bitmap image = BitmapFactory.decodeFile(SDRoot + "Mp3Player" + File.separator + artist + ".jpg", null);
musicImage.setImageBitmap(image);
super.onPostExecute(result);
}
}
@Override
protected void onResume() {
if (MyApplication.playStatus == 1) {
handler.post(runnable);
}
super.onResume();
}
@Override
protected void onStop() {
handler.removeCallbacks(runnable);
super.onStop();
}
@Override
protected void onDestroy() {
handler.removeCallbacks(runnable);
super.onDestroy();
}
public static void getMusicInfo(int position) {
HashMap<String, Object> map = MyApplication.getPlayMusicList().get(position); name = (String) map.get("name");
path = (String) map.get("path");
artist = (String) map.get("artist");
lrcPath = path.substring(0, path.length()-4) + ".lrc";
- 50 -
Android 酷儿音乐播放器设计报告书
System.out.println("------------lrcPath>" + lrcPath);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 0, 0, "停止");
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch (item.getItemId()) {
case 0:
PlayService.stop();
handler.removeCallbacks(runnable);
seekBar.setProgress(0);
musicImage.setImageResource(R.drawable.pic);
playButton.setBackgroundResource(R.drawable.play_select);
MainActivity.footer.setText("正在播放的歌曲");
break;
default:
break;
}
return super.onMenuItemSelected(featureId, item);
}
private class ButtonListener implements OnClickListener {
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_last:
try {
Thread.sleep(80);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if (MyApplication.getPlayMusicList().size() > 1) {
handler.removeCallbacks(runnable);
PlayService.stop();
musicImage.setImageResource(R.drawable.pic);
MyApplication.musicPosition = MyApplication.musicPosition - 1 < 0 ? MyApplication.getPlayMusicList().size() - 1 : MyApplication.musicPosition - 1;
- 51 -
Android 酷儿音乐播放器设计报告书
getMusicInfo(MyApplication.musicPosition);
playMusic();
} else {
Toast.makeText(context, "没有上一首", 0).show();
}
break;
case R.id.button_play:
if (MyApplication.playStatus == 0) {
if (name == null) {
Toast.makeText(context, "没有歌曲", 0).show(); } else {
playMusic();
}
} else if (MyApplication.playStatus == 1) {
handler.removeCallbacks(runnable);
PlayService.pause();
playButton.setBackgroundResource(R.drawable.play_select); } else if (MyApplication.playStatus == 2) {
PlayService.goon();
handler.post(runnable);
playButton.setBackgroundResource(R.drawable.pause_select); }
break;
case R.id.button_next:
try {
Thread.sleep(80);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if (MyApplication.getPlayMusicList().size() > 1) {
handler.removeCallbacks(runnable);
PlayService.stop();
musicImage.setImageResource(R.drawable.pic);
next();
} else {
Toast.makeText(context, "没有下一首", 0).show();
}
break;
default:
break;
}
- 52 -
Android 酷儿音乐播放器设计报告书
}
}
public static void playMusic() {
Intent intent = new Intent(context, PlayService.class);
intent.putExtra("name", name);
intent.putExtra("path", path);
intent.putExtra("artist", artist);
context.startService(intent);
playButton.setBackgroundResource(R.drawable.pause_select);
musicTextView.setText(name);
TextView footer = (TextView) MainActivity.footer;
footer.setText(name);
handler.post(runnable);
new imageTask().execute();
}
public static void next() {
MyApplication.musicPosition = (MyApplication.musicPosition + 1) % MyApplication.getPlayMusicList().size();
getMusicInfo(MyApplication.musicPosition);
playMusic();
}
// PlayService中自动播放下一首歌曲用到的
public static HashMap<String, Object> getNextInfo() {
MyApplication.musicPosition = (MyApplication.musicPosition + 1) % MyApplication.getPlayMusicList().size();
HashMap<String, Object> map = MyApplication.getPlayMusicList().get(MyApplication.musicPosition);
return map;
}
private class onSeekBarListener implements OnSeekBarChangeListener {
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
- 53 -
Android 酷儿音乐播放器设计报告书
public void onStartTrackingTouch(SeekBar seekBar) { if (MyApplication.playStatus != 0) { handler.removeCallbacks(runnable); isChangeSeekbarP = true; } } public void onStopTrackingTouch(SeekBar seekBar) {
}
}
}
if (isChangeSeekbarP) { PlayService.player.seekTo(seekBar.getProgress()); handler.post(runnable); isChangeSeekbarP = false; } - 54 -
Android 酷儿音乐播放器设计报告书
PlayMusicListActivity.java
package com.huazi.Mp3Player;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.huazi.Mp3Player.Utils.DataUtils;
import com.huazi.Mp3Player.Utils.MyApplication; import com.huazi.Mp3Player.Utils.PlayUtils;
public class PlayMusicListActivity extends Activity {
public static ListView playMusicList;
public static MyListAdapter myListAdapter; public static Context context;
@Override
- 55 -
Android 酷儿音乐播放器设计报告书
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.playmusic_list_layout);
context = this;
playMusicList = (ListView) findViewById(R.id.playMusicList);
myListAdapter = new MyListAdapter(this, MyApplication.getPlayMusicList(), new int[] { R.id.text_playMusicName, R.id.button_delete });
playMusicList.setAdapter(myListAdapter);
playMusicList.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
HashMap<String, Object> map = MyApplication.getPlayMusicList().get(position);
if (map.get("name").equals(PlayService.name) && MyApplication.playStatus == 1) {
Toast.makeText(context, "正在播放...", 0).show();
}else {
PlayUtils.turnToPlay(map, context);
}
}
});
}
@Override
protected void onRestart() {
myListAdapter.notifyDataSetChanged();
super.onRestart();
}
@Override
protected void onResume() {
myListAdapter.notifyDataSetChanged();
myListAdapter.notifyDataSetInvalidated();
super.onResume();
}
@Override
- 56 -
Android 酷儿音乐播放器设计报告书
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 0, 0, R.string.text_deletePlayListMusics);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == 0) {
new emptyPlayMusicListTask(myListAdapter).execute();
}
return super.onOptionsItemSelected(item);
}
public class emptyPlayMusicListTask extends AsyncTask<Void, Void, Void> { MyListAdapter myListAdapter;
public emptyPlayMusicListTask(MyListAdapter myListAdapter) { this.myListAdapter = myListAdapter;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
MyApplication.getPlayMusicList().clear();
return null;
}
@Override
protected void onPostExecute(Void result) {
myListAdapter.notifyDataSetChanged();
PlayService.stop();
MainActivity.footer.setText("正在播放的歌曲");
super.onPostExecute(result);
}
}
@Override
public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {
- 57 -
Android 酷儿音乐播放器设计报告书
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { backDialog();
}
return false;
};
public void backDialog() {
AlertDialog.Builder builder = new Builder(this);
builder.setMessage("确认退出吗?");
builder.setTitle("提示");
builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
((Activity) context).finish();
new AsyncTask<Void, Void, Void>(){
@Override
protected Void doInBackground(Void... params) {
if (MyApplication.playStatus != 0) {
PlayService.stop();
// PlayService.player.release();
}
DataUtils.upData_allLists();
return null;
}
}.execute();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
public class MyListAdapter extends BaseAdapter {
private class buttonViewHolder {
TextView musicName;
- 58 -
Android 酷儿音乐播放器设计报告书
ImageButton delete;
}
private ArrayList<HashMap<String, Object>> musicList;
private LayoutInflater mInflater;
private Context mContext;
private int[] valueViewID;
private buttonViewHolder holder;
public MyListAdapter(Context context, List<HashMap<String, Object>> appList, int[] to) {
musicList = (ArrayList<HashMap<String, Object>>) appList;
mContext = context;
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
valueViewID = to;
}
public int getCount() {
return musicList.size();
}
public Object getItem(int position) {
return musicList.get(position);
}
public long getItemId(int position) {
return position;
}
public void removeItem(int position) {
if (musicList.get(position).get("name").equals(PlayService.name)) {
PlayService.stop();
TextView footer = (TextView) MainActivity.footer;
footer.setText("正在播放的歌曲");
}
musicList.remove(position);
this.notifyDataSetChanged();
}
- 59 -
Android 酷儿音乐播放器设计报告书
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView != null) {
holder = (buttonViewHolder) convertView.getTag();
} else {
convertView = mInflater.inflate(R.layout.playmusic_list_item_layout, null); holder = new buttonViewHolder();
holder.musicName = (TextView) convertView.findViewById(valueViewID[0]);
holder.delete = (ImageButton) convertView.findViewById(valueViewID[1]); convertView.setTag(holder);
}
HashMap<String, Object> itemInfo
MyApplication.getPlayMusicList().get(position);
if (itemInfo != null) {
String aname = (String) itemInfo.get("name");
holder.musicName.setText(aname);
holder.delete.setOnClickListener(new deleOnClickListener(position)); }
return convertView;
}
class deleOnClickListener implements OnClickListener {
private int position;
public deleOnClickListener(int position) {
this.position = position;
}
public void onClick(View v) {
removeItem(position);
}
}
}
}
= - 60 -
Android 酷儿音乐播放器设计报告书
PlayService.java
package com.huazi.Mp3Player;
import java.io.IOException;
import java.util.HashMap;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnPreparedListener; import android.os.IBinder;
import android.widget.Toast;
import com.huazi.Mp3Player.Utils.MyApplication;
public class PlayService extends Service {
public static MediaPlayer player;
public static String name;
static String path;
static String artist;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
System.out.println("Service,onCreate!"); if (player == null) {
player = new MediaPlayer();
}
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId) { super.onStart(intent, startId);
System.out.println("Service,onStart!"); - 61 -
Android 酷儿音乐播放器设计报告书
if (name == intent.getStringExtra("name")) {
Toast.makeText(PlayMusicAcitivity.context, "正在播放", 0).show();
} else {
name = intent.getStringExtra("name");
path = intent.getStringExtra("path");
artist = intent.getStringExtra("artist");
System.out.println(name+path+artist);
try {
play();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
player.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
player.reset();
MyApplication.playStatus = 0;
MyApplication.musicPosition = (MyApplication.musicPosition + MyApplication.getPlayMusicList().size();
HashMap<String, Object> map MyApplication.getPlayMusicList().get(MyApplication.musicPosition);
path = (String) map.get("path");
name = (String) map.get("name");
artist = (String) map.get("artist");
try {
play();
} catch (Exception e) {
System.out.println("播放有错误!");
% = - 62 - 1)
Android 酷儿音乐播放器设计报告书
}
}
});
}
void play() throws IllegalArgumentException, IllegalStateException, IOException { player.reset();
player.setDataSource(path);
player.prepareAsync();
player.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
if (player != null) {
player.start();
MyApplication.playStatus = 1;
for (int i = 0; i < MyApplication.getPlayMusicList().size(); i++) { if
(name.equals(MyApplication.getPlayMusicList().get(i).get("name"))) {
MyApplication.musicPosition = i;
break;
}
}
MainActivity.footer.setText(name);
MyApplication.playStatus = 1;
}
}
});
}
public static void pause() {
if (MyApplication.playStatus == 1) {
player.pause();
MyApplication.playStatus = 2;
}
}
public static void goon() {
if (MyApplication.playStatus != 0) {
player.start();
MyApplication.playStatus = 1;
}
}
- 63 -
Android 酷儿音乐播放器设计报告书
public static void stop() {
if (MyApplication.playStatus != 0) { player.stop();
MyApplication.playStatus = 0; }
}
}
- 64 -
Android 酷儿音乐播放器设计报告书
StartActivity.java
package com.huazi.Mp3Player;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Window;
import com.huazi.Mp3Player.Utils.DBHelper;
import com.huazi.Mp3Player.Utils.DataUtils;
import com.huazi.Mp3Player.Utils.MyApplication;
public class StartActivity extends Activity {
public static Context context;
private ContentResolver resolver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.start_layout);
context = this;
resolver = getContentResolver();
new AsyncTask<Void, Void, Void>(){
@Override
protected Void doInBackground(Void... params) {
SQLiteDatabase db = new DBHelper(context, "myData").getWritableDatabase();
db.execSQL("create table if not exists all_music (id integer primary key autoincrement not null, name varchar(50) , path varchar(100) , artist varchar(50))");
db.execSQL("create table if not exists play_music (id integer primary key autoincrement not null, name varchar(50) , path varchar(100) , artist varchar(50))");
db.execSQL("create table if not exists my_happy_music (id integer primary key autoincrement not null, name varchar(50) , path varchar(100) , artist varchar(50))");
db.execSQL("create table if not exists my_quiet_music (id integer primary key autoincrement not null, name varchar(50) , path varchar(100) , artist varchar(50))"); - 65 -
Android 酷儿音乐播放器设计报告书
db.execSQL("create table if not exists my_sad_music (id integer primary key autoincrement not null, name varchar(50) , path varchar(100) , artist varchar(50))"); db.close();
DataUtils.get_AllMusicListFD(context);
if (MyApplication.getAllMusicList().isEmpty()) {
DataUtils.update_AllMusicData(resolver,context);
}
DataUtils.get_AllListsFD();
return null;
}
@Override
protected void onPostExecute(Void result) {
startActivity(new Intent(context, MainActivity.class));
finish();
super.onPostExecute(result);
}
}.execute();
}
}
- 66 -
Android 酷儿音乐播放器设计报告书
DataUtils.java
package com.huazi.Mp3Player.Utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.provider.MediaStore;
import com.huazi.Mp3Player.MainActivity;
import com.huazi.Mp3Player.StartActivity;
public class DataUtils {
private static List<MusicDemo> musicList = new ArrayList<MusicDemo>();
public static void update_AllMusicData(ContentResolver resolver,Context context) { musicList.clear();
Cursor cursor
resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
while (cursor.moveToNext()) {
// 歌曲的名称
String name
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)); // 歌曲的歌手名
String artist
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)); // 歌曲文件的路径
String path
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)); musicList.add(new MusicDemo(name, path, artist));
}
DBHelper dbHelper = new DBHelper(context, "myData");
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.execSQL("delete from all_music");
= null, = = = - 67 -
Android 酷儿音乐播放器设计报告书
if (!musicList.isEmpty()) { for (Iterator<MusicDemo> iterator = musicList.iterator(); iterator.hasNext();) {
MusicDemo demo = (MusicDemo) iterator.next();
ContentValues values = new ContentValues();
values.put("name", demo.getName());
values.put("path", demo.getPath());
values.put("artist", demo.getArtist());
db.insert("all_music", null, values);
}
}
db.close();
}
public static void get_AllMusicListFD(Context context) {
if (!MyApplication.getAllMusicList().isEmpty()) {
MyApplication.getAllMusicList().clear();
}
DBHelper dbHelper = new DBHelper(context, "myData");
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select name,path,artist from all_music", null);
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex("name"));
String path = cursor.getString(cursor.getColumnIndex("path"));
String artist = cursor.getString(cursor.getColumnIndex("artist"));
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("name", name);
map.put("path", path);
map.put("artist", artist);
MyApplication.getAllMusicList().add(map);
}
cursor.close();
db.close();
}
public static void get_PlayMusicListFD() {
if (!MyApplication.getPlayMusicList().isEmpty()) {
MyApplication.getPlayMusicList().clear();
}
DBHelper dbHelper = new DBHelper(StartActivity.context, "myData");
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("Select name,path,artist from play_music", null); while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex("name"));
String path = cursor.getString(cursor.getColumnIndex("path"));
- 68 -
Android 酷儿音乐播放器设计报告书
} String artist = cursor.getString(cursor.getColumnIndex("artist")); HashMap<String, Object> map = new HashMap<String, Object>(); map.put("name", name); map.put("path", path); map.put("artist", artist); MyApplication.getPlayMusicList().add(map); System.out.println(name + path + artist); } db.close(); public static void get_HappyMusicListFD() { if (!MyApplication.getHappyMusicList().isEmpty()) { MyApplication.getHappyMusicList().clear(); } DBHelper dbHelper = new DBHelper(StartActivity.context, "myData"); SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("Select name,path,artist from my_happy_music", null); while (cursor.moveToNext()) { String name = cursor.getString(cursor.getColumnIndex("name")); String path = cursor.getString(cursor.getColumnIndex("path")); String artist = cursor.getString(cursor.getColumnIndex("artist")); HashMap<String, Object> map = new HashMap<String, Object>(); map.put("name", name); map.put("path", path); map.put("artist", artist); MyApplication.getHappyMusicList().add(map); } db.close(); } public static void get_QuietMusicListFD() { if (!MyApplication.getQuietMusicList().isEmpty()) { MyApplication.getQuietMusicList().clear(); } DBHelper dbHelper = new DBHelper(StartActivity.context, "myData"); SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("Select name,path,artist from my_quiet_music", null); while (cursor.moveToNext()) { String name = cursor.getString(cursor.getColumnIndex("name")); String path = cursor.getString(cursor.getColumnIndex("path")); String artist = cursor.getString(cursor.getColumnIndex("artist")); HashMap<String, Object> map = new HashMap<String, Object>(); map.put("name", name); - 69 -
Android 酷儿音乐播放器设计报告书
map.put("path", path);
map.put("artist", artist);
MyApplication.getQuietMusicList().add(map);
}
db.close();
}
public static void get_SadMusicListFD() {
if (!MyApplication.getSadMusicList().isEmpty()) {
MyApplication.getSadMusicList().clear();
}
DBHelper dbHelper = new DBHelper(StartActivity.context, "myData");
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("Select name,path,artist from my_sad_music", null); while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex("name"));
String path = cursor.getString(cursor.getColumnIndex("path"));
String artist = cursor.getString(cursor.getColumnIndex("artist"));
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("name", name);
map.put("path", path);
map.put("artist", artist);
MyApplication.getSadMusicList().add(map);
}
db.close();
}
public static void get_AllListsFD() {
get_AllMusicListFD(StartActivity.context);
get_HappyMusicListFD();
get_PlayMusicListFD();
get_QuietMusicListFD();
get_SadMusicListFD();
}
public static void upData_Lists(Context context,String table_name) {
List<HashMap<String, Object>> musicList = new ArrayList<HashMap<String, Object>>();
if (table_name.equals("play_music")) {
musicList = MyApplication.getPlayMusicList();
}
else if (table_name.equals("my_happy_music")) {
musicList = MyApplication.getHappyMusicList();
}
- 70 -
Android 酷儿音乐播放器设计报告书
else if (table_name.equals("my_quiet_music")) {
musicList = MyApplication.getQuietMusicList();
}
else if (table_name.equals("my_sad_music")) {
musicList = MyApplication.getSadMusicList();
}
else{
System.out.println("table name error!");
}
SQLiteDatabase db = new DBHelper(context, "myData").getWritableDatabase(); db.execSQL("delete from " + table_name);
db.execSQL("update sqlite_sequence SET seq = 0 where name = '"+ table_name+"'"); for (Iterator<HashMap<String, Object>> iterator = musicList.iterator(); iterator.hasNext();) {
HashMap<String, Object> hashMap = (HashMap<String, Object>) iterator.next(); ContentValues values = new ContentValues();
values.put("name", (String) hashMap.get("name"));
values.put("path", (String) hashMap.get("path"));
values.put("artist", (String) hashMap.get("artist"));
db.insert(table_name, null, values);
}
db.close();
}
public static void upData_allLists() {
upData_Lists(MainActivity.context,"play_music");
upData_Lists(MainActivity.context,"my_happy_music");
upData_Lists(MainActivity.context,"my_quiet_music");
upData_Lists(MainActivity.context,"my_sad_music");
}
}
- 71 -
Android 酷儿音乐播放器设计报告书
DBHelper.java
package com.huazi.Mp3Player.Utils;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class DBHelper extends SQLiteOpenHelper{
private static final int VERSION = 1;
public DBHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version);
}
public DBHelper(Context context, String name, int version){
this(context, name, null, version);
}
public DBHelper(Context context, String name){
this(context, name, VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
System.out.println("Create a Database!!!!!!!!!!!!!!!");
}
@Override
public void onOpen(SQLiteDatabase db) {
// TODO Auto-generated method stub
super.onOpen(db);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { System.out.println("Upgrade a Database");
}
}
- 72 -
Android 酷儿音乐播放器设计报告书
ImageUtils.java
package com.huazi.Mp3Player.Utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
public class ImageUtils {
private static String filename = null;
private static Map<String, String> imageMap = new HashMap<String, String>();
private ImageUtils() {
}
/**
* 将inputstream流写入path中名字为filename
*
* @param is
* 输入流
* @param path
* 要存放的路径
* @param filename
* 文件名
*/
public static void writeToLocal(InputStream is, String path) {
OutputStream os = null;
try {
os = new FileOutputStream(new File(path + filename));
byte[] b = new byte[4096];
int read = 0;
- 73 -
Android 酷儿音乐播放器设计报告书
while (-1 != (read = is.read(b, 0, 4096))) {
os.write(b, 0, read);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (os != null) {
os.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static InputStream getInputstreamByKeyWord(String keyword) {
InputStream iss = null;
InputStream is = null;
try {
String url = "/pics?query=" + URLEncoder.encode(keyword, "GB2312");
URL u = new URL(url);
URLConnection uc = u.openConnection();
is = uc.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "GB2312"));
String buffer = null;
StringBuilder sb = new StringBuilder();
- 74 -
Android 酷儿音乐播放器设计报告书
}
} while (null != (buffer = reader.readLine())) { sb.append(buffer); } String content = sb.toString(); int httpPoint = content.indexOf("src=\"http"); int titlePoint = content.indexOf("title", httpPoint); String imageUrl = content.substring(httpPoint + 5, titlePoint - 2); filename = imageUrl.substring(imageUrl.lastIndexOf("/") + 1); URL imageHttpUrl = new URL(imageUrl); URLConnection imageUrlConnection = imageHttpUrl.openConnection(); iss = imageUrlConnection.getInputStream(); } catch (Exception e) { e.printStackTrace(); } return iss; public static Map<String, String> generateImageFromSouGou(String path, String keyword) { InputStream is = getInputstreamByKeyWord(keyword); } imageMap.put(keyword, filename); writeToLocal(is, path); return imageMap; public static Map<String, String> generateImageFromSouGou(String keyword) { return generateImageFromSouGou("/", keyword); }
- 75 -
Android 酷儿音乐播放器设计报告书
LyricView.java
package com.huazi.Mp3Player.Utils;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public final class LyricView extends View {
public LyricView(Context context) { super(context);
}
// 歌词对象
private SongLyric lrc = null; // 当前播放时间
private long time = 0l;
// 字体画笔
private Paint fontPaint = null; // 当前歌词字体画笔
private Paint lrcPaint = null;
// 字体颜色
private int fontColor = Color.GRAY; // 当前歌词字体颜色
private int lrcColor = Color.WHITE; // 字体大小
private int fontSize = 12;
/**
* 设置歌词对象
*
* @param lrc
*/
public void setLyric(SongLyric lrc) { this.lrc = lrc;
}
/**
* 设置当前时间
*
* @param ms
- 76 -
Android 酷儿音乐播放器设计报告书
*/
public void setTime(long ms) {
this.time = ms;
}
/**
* 设置歌词字体颜色
*
* @param color
*/
public void setFontColor(int color) { this.fontColor = color;
}
/**
* 设置当前歌词字体颜色
*
* @param color
*/
public void setLyricColor(int color) { this.lrcColor = color;
}
/**
* 设置字体大小
*
* @param size
*/
public void setFontSize(int size) { this.fontSize = size;
}
/**
* 重绘视图
*/
@Override
protected void onDraw(Canvas c) { super.onDraw(c);
if (lrc != null) {
try {
if (fontPaint == null) {
fontPaint = new Paint(); }
if (lrcPaint == null) {
- 77 -
Android 酷儿音乐播放器设计报告书
}
}
}
lrcPaint = new Paint(); } fontPaint.setColor(fontColor); fontPaint.setTextSize(fontSize); lrcPaint.setColor(lrcColor); lrcPaint.setTextSize(fontSize); // 获取当前要播放歌词的索引 int cIndex = lrc.getIndex(time); // 计算绘制歌词y坐标 int h = getHeight() / 2 - cIndex * fontSize * 3 / 2 - (int) ((fontSize * 3 / 2) * (lrc.getOffset(time) / (float) lrc .getNextTime(time))); Long[] ts = lrc.getAllTimes(); // 循环绘制每一行歌词,当前播放歌词特殊绘制 for (Long l : ts) { c.drawText(lrc.get(l), 0, h, lrc.getIndex(l) == cIndex ? lrcPaint : fontPaint); h += fontSize * 3 / 2; } } catch (Exception e) { } - 78 -
Android 酷儿音乐播放器设计报告书
MusicDemo.java
package com.huazi.Mp3Player.Utils;
import java.io.Serializable;
public class MusicDemo implements Serializable{
- 79 - private static final long serialVersionUID = 1L; private String name; private String path; private String artist; public MusicDemo() { } public MusicDemo(String name, String path ,String artist) { } @Override public String toString() { } return "MusicDemo [name=" + name + ", path=" + path + ", artist=" + artist super(); this.name = name; this.path = path; this.artist = artist; // TODO Auto-generated constructor stub + "]"; public String getName() { } return name; public void setName(String name) { } this.name = name;
Android 酷儿音乐播放器设计报告书
public String getPath() {
return path;
}
public void setPath(String path) { this.path = path;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) { this.artist = artist;
}
}
- 80 -
Android 酷儿音乐播放器设计报告书
MyApplication.java
package com.huazi.Mp3Player.Utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Application;
public class MyApplication extends Application {
private static List<HashMap<String, Object>> playMusicList ArrayList<HashMap<String, Object>>();
private static List<HashMap<String, Object>> allMusicList ArrayList<HashMap<String, Object>>();
private static List<HashMap<String, Object>> happyMusicList ArrayList<HashMap<String, Object>>();
private static List<HashMap<String, Object>> quietMusicList ArrayList<HashMap<String, Object>>();
private static List<HashMap<String, Object>> sadMusicList ArrayList<HashMap<String, Object>>();
public static int playStatus ;
public static int musicPosition;
@Override
public void onCreate() {
super.onCreate();
}
public static List<HashMap<String, Object>> getPlayMusicList() {
return playMusicList;
}
public static List<HashMap<String, Object>> getAllMusicList() {
return allMusicList;
}
public static List<HashMap<String, Object>> getQuietMusicList() { return quietMusicList;
}
= new = new = new = new = new - 81 -
Android 酷儿音乐播放器设计报告书
public static List<HashMap<String, Object>> getSadMusicList() { return sadMusicList;
}
public static List<HashMap<String, Object>> getHappyMusicList() { return happyMusicList;
}
@Override
public void onTerminate() {
// TODO Auto-generated method stub
super.onTerminate();
}
}
- 82 -
Android 酷儿音乐播放器设计报告书
PlayUtils.java
package com.huazi.Mp3Player.Utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import android.content.Context;
import android.content.Intent;
import android.os.Environment;
import android.widget.TextView;
import android.widget.Toast;
import com.huazi.Mp3Player.MainActivity;
import com.huazi.Mp3Player.PlayMusicListActivity;
import com.huazi.Mp3Player.PlayService;
import com.huazi.Mp3Player.R;
public class PlayUtils {
public static boolean addMusicToList(Context context, HashMap<String, Object> map, List<HashMap<String, Object>> toList) {
if (new File((String) map.get("path")).exists()) {
if (toList.contains(map)) {
Toast.makeText(context, "播放列表已存在", 0).show();
return true;
} else {
toList.add(map);
Toast.makeText(context, "添加OK!", 0).show();
return true;
}
} else {
Toast.makeText(context, R.string.text_gequbucunzai, 0).show();
return false;
- 83 -
Android 酷儿音乐播放器设计报告书
}
}
public static void turnToPlay(HashMap<String, Object> map, Context context) {
String name = (String) map.get("name");
String path = (String) map.get("path");
String artist = (String) map.get("artist");
if (new File(path).exists()) {
Intent intent = new Intent(context, PlayService.class);
intent.putExtra("name", name);
intent.putExtra("path", path);
intent.putExtra("artist", artist);
context.startService(intent);
TextView footer = (TextView) MainActivity.footer;
footer.setText(name);
} else {
Toast.makeText(context, name + context.getResources().getString(R.string.text_gequbucunzai), 0).show();
}
}
public static void turnToPlay_List(Context context, List<HashMap<String, Object>> musicList) {
if (!musicList.isEmpty()) {
for (int i = 0; i < musicList.size(); i++) {
HashMap<String, Object> map = musicList.get(i);
if (new File((String) map.get("path")).exists()) {
if (!MyApplication.getPlayMusicList().contains(map)) {
MyApplication.getPlayMusicList().add(map);
}
} else {
String name = (String) map.get("name");
Toast.makeText(context, name + context.getResources().getString(R.string.text_gequbucunzai), 0).show();
}
}
PlayMusicListActivity.myListAdapter.notifyDataSetChanged();
HashMap<String, Object> map = musicList.get(0);
turnToPlay(map, context);
} else {
Toast.makeText(MainActivity.context, "该收藏夹中没有音乐", 0).show(); - 84 -
Android 酷儿音乐播放器设计报告书
}
}
public static InputStream getInputstreamByKeyWord(String keyword) {
InputStream iss = null;
InputStream is = null;
try {
String url = "/pics?query=" + URLEncoder.encode(keyword, "GB2312");
URL u = new URL(url);
URLConnection uc = u.openConnection();
is = uc.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "GB2312"));
String buffer = null;
StringBuilder sb = new StringBuilder();
while (null != (buffer = reader.readLine())) {
sb.append(buffer);
}
String content = sb.toString();
int httpPoint = content.indexOf("src=\"http");
int titlePoint = content.indexOf("title", httpPoint);
String imageUrl = content.substring(httpPoint + 5, titlePoint - 2);
// filename = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);
URL imageHttpUrl = new URL(imageUrl);
URLConnection imageUrlConnection = imageHttpUrl.openConnection();
iss = imageUrlConnection.getInputStream();
} catch (Exception e) {
- 85 -
Android 酷儿音乐播放器设计报告书
e.printStackTrace();
}
return iss;
}
public static String SDCardRoot
Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;
public static File creatSDDir(String dir) {
File dirFile = new File(SDCardRoot + dir + File.separator);
System.out.println(dirFile.mkdirs());
return dirFile;
}
public static File createFileInSDCard(String fileName, String dir) throws IOException { File file = new File(SDCardRoot + dir + File.separator + fileName);
System.out.println("file---->" + file);
boolean b = file.createNewFile();
System.out.println("---------->" + b);
return file;
}
public static File write2SDFromInput(String path, String fileName, InputStream input) {
File file = null;
OutputStream output = null;
try {
creatSDDir(path);
file = createFileInSDCard(fileName, path);
output = new FileOutputStream(file);
byte buffer[] = new byte[4 * 1024];
int temp;
while ((temp = input.read(buffer)) != -1) {
output.write(buffer, 0, temp);
}
output.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
output.close();
} catch (Exception e) {
= - 86 -
Android 酷儿音乐播放器设计报告书
e.printStackTrace(); } } return file; } public static String getLrcFile(Context context, String musicName, String musicPath) { String lrcFileName = musicName + ".lrc"; String lrcFilePath = musicPath.substring(0, -(musicName.length() + 4)) + lrcFileName; if (new File(lrcFilePath).exists()) {
return lrcFilePath;
} else {
return null;
}
}
}
- 87 -
Android 酷儿音乐播放器设计报告书
SongLyric.java
package com.huazi.Mp3Player.Utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 歌词对象
*
* @author samsung
*
*/
public final class SongLyric {
// 歌名
private String title = "";
// 歌手名
private String artist = "";
// 专辑名
private String album = "";
// 偏移时间
private long offset = 0;
// 最大时间
private long maxTime = 0;
// 歌词内容
private Map<Long, String> lrcs = new HashMap<Long, String>();
// 验证是否通过
private boolean valid = false;
public SongLyric(String url) {
File file = new File(url);
if (file.exists()) {
try {
// 构建读取器
BufferedReader br = new BufferedReader(new InputStreamReader( new FileInputStream(file), "gbk"));
String line = null;
- 88 -
Android 酷儿音乐播放器设计报告书
while ((line = br.readLine()) != null) { dealLine(line);
}
valid = true;
} catch (Exception e) {
System.out.println("Exception"); }
}
}
public String getTitle() {
return this.title;
}
public String getArtist() {
return this.artist;
}
public String getAlbum() {
return this.album;
}
public boolean isValid() {
return this.valid;
}
public long getMaxTime() {
return this.maxTime;
}
public void setMaxTime(long time) {
this.maxTime = time;
}
/**
* 获取该时间应当显示的歌词
*
* @param ls
* @return
*/
public String get(long ls) {
long time = ls + offset;
Long curr = -1l;
for (Long l : lrcs.keySet()) {
- 89 -
Android 酷儿音乐播放器设计报告书
curr = l > time ? curr : l < curr ? curr : l; }
return lrcs.get(curr);
}
/**
* 获取该时间所要显示的歌词初始时间的索引 *
* @param ls
* @return
*/
public int getIndex(long ls) {
Long[] ts = getAllTimes();
for (int i = 0; i < ts.length - 1; i++) {
if (ls + offset >= ts[i] && ls + offset < ts[i + 1]) { return i;
}
}
return ts.length - 1;
}
/**
* 获取该时间与歌词初始时间差值
*
* @param ls
* @return
*/
public int getOffset(long ls) {
Long[] ts = getAllTimes();
int index = getIndex(ls);
if (index < ts.length && index >= 0) {
return (int) (ls + offset - ts[index]);
}
return 0;
}
/**
* 获取该时间段播放的歌词共播放时间
*
* @param ls
* @return
*/
public int getNextTime(long ls) {
Long[] ts = getAllTimes();
- 90 -
Android 酷儿音乐播放器设计报告书
int index = getIndex(ls);
if (index < ts.length - 1) {
return (int) (ts[index + 1] - ts[index]);
}
return 0;
}
/**
* 处理歌词行
*
* @param line
*/
private void dealLine(String line) {
if (line != null && !line.equals("")) {
if (line.startsWith("[ti:")) {// 标题
title = line.substring(4, line.length() - 1);
} else if (line.startsWith("[ar:")) {// 歌手
artist = line.substring(4, line.length() - 1);
} else if (line.startsWith("[al:")) {// 专辑
album = line.substring(4, line.length() - 1);
} else if (line.startsWith("[offset:")) {// 专辑
offset = Long.parseLong(line.substring(8, line.length() - 1)); } else {
// 该行歌词内容
Pattern ptn = Pattern.compile("\\[(\\d{2}:\\d{2}\\.\\d{2})\\]"); Matcher mth = ptn.matcher(line);
while (mth.find()) {
// 得到时间点
long time = strToLong(mth.group(1));
// 得到时间点后的内容
String[] str = ptn.split(line);
String lrc = str.length > 0 ? str[str.length - 1] : ""; lrcs.put(time, lrc);
maxTime = maxTime > time ? maxTime : time; }
}
}
}
/**
* 将00:00.00格式的歌词时间转换为long
*
* @param timeStr
* @return
- 91 -
Android 酷儿音乐播放器设计报告书
*/
public static long strToLong(String timeStr) { String[] s = timeStr.split(":");
int min = Integer.parseInt(s[0]);
String[] ss = s[1].split("\\.");
int sec = Integer.parseInt(ss[0]);
int mill = Integer.parseInt(ss[1]);
return min * 60 * 1000 + sec * 1000 + mill * 10; }
/**
* 处理毫秒数,以00:00的方式返回
*
* @param ts
* @return
*/
public static String longToString(long ts) {
int time = (int) ts / 1000;
int ms = time % 60;
int ss = time / 60;
ss = ss > 99 ? 99 : ss;
StringBuffer str = new StringBuffer();
str.append(ss < 10 ? "0" + ss + ":" : ss + ":"); str.append(ms < 10 ? "0" + ms : ms + ""); return str.toString();
}
/**
* 获取顺序时间数组对象
*
* @return
*/
public Long[] getAllTimes() {
Long[] ts = new Long[lrcs.size()];
int index = 0;
for (Long l : lrcs.keySet()) {
ts[index++] = l;
}
for (int i = 0; i < ts.length - 1; i++) {
for (int j = i; j < ts.length; j++) {
if (ts[i] > ts[j]) {
Long tmp = ts[i];
ts[i] = ts[j];
ts[j] = tmp;
- 92 -
Android 酷儿音乐播放器设计报告书
} } } } } return ts;
- 93 -
Android 酷儿音乐播放器设计报告书
四、程序设计结果及测试分析
经过在手机上运行,程序可以流畅地播放音乐,无卡顿现象,可以从音乐列表的第一栏播放到最后一栏,实时准确地显示播放进度信。按钮上一曲、下一曲及停止都可以正确地作用,暂停按钮在音乐播放的时候可以正确显示并作用,当被点击之后,即显示为播放按钮,此时点击该按钮也可以正确播放音乐。
经测试,最终得到的程序可以在手机上运行,并无任何bug及程序不响应现象。
- 94 -
Android 酷儿音乐播放器设计报告书
4.1 程序运行效果图
- 95 -
Android 酷儿音乐播放器设计报告书
- 96 -
Android 酷儿音乐播放器设计报告书
- 97 -
Android 酷儿音乐播放器设计报告书
- 98 -
Android 酷儿音乐播放器设计报告书
、
- 99 -
Android 酷儿音乐播放器设计报告书
- 100 -
Android 酷儿音乐播放器设计报告书
- 101 -
Android 酷儿音乐播放器设计报告书
- 102 -
Android 酷儿音乐播放器设计报告书
- 103 -
Android 酷儿音乐播放器设计报告书
4.2 程序调试过程
ADT工具附有LogCat工具,在函数的开始结束及分支处设置特定文字标记内容,即可以在LogCat工具中打印调试内容,这对于bug的判断及追踪有很大帮助,并了解程序的运行流程。图4-2是LogCat工具使用的截图。
- 104 -
Android 酷儿音乐播放器设计报告书
图4-2
- 105 -
Android 酷儿音乐播放器设计报告书
五、实验总结
由于对android的接触较少,所以也遇到了一些问题,无论是哪种语言首先要有自己的思路,接下来就是通过语言的实现。我主要遇到android的四大组件的理解和使用,刚开始不知道如何用相关的组件,而且android的组件相当的多,就老师上课讲的相关知识比较少,对于我们初学者学习比较困难,而且,只是不是那么的连贯和详细,上课的时间只是跟上老师再敲代码,实现一个具体的功能,但是不有真正的弄懂它的使用方法,所以,我们在课设中出现很多问题。今后安卓界面设计和java语言使用能力需要加强。
- 106 -
Android 酷儿音乐播放器设计报告书
六、参考资料 参考书籍
《android应用开发揭秘》 《android一日游》
《安卓开发实战经典》 部分参考资料来自
安卓技术论坛网站
安卓开发爱好者网站
百度文库
- 107 -
供配电技术课程大作业报告书题目指导教师姓名学号日期机电工和系20xx20xx学年第2学期报告书格式要求一报告前置部分一摘要内容包括…
面向对象技术课程大作业设计报告书题目超市管理系统指导教师宋涛姓名学号日期20xx1122管理科学与工程学院20xx20xx学年第1…
关于仙林大学城饮料消费行为调查分析报告调查背景仙林大学城现在拥有的院校主要有南京大学南京师范大学南京财经大学南京邮电大学南京中医药…
数据库原理大作业作业题目小组成员指导教师提交时间一需求分析功能分析功能结构图提取数据过程以及结果二概念结构设计根据需求分析得到实体…
中国石油大学华东现代远程教育毕业大作业实践报告题目工商企业安全管理实践报告学习中心奥鹏学习中心年级专业网络09秋工商企业管理学生姓…
中国石油大学华东现代远程教育毕业大作业实践报告题目工商企业安全管理实践报告学习中心奥鹏学习中心年级专业网络09秋工商企业管理学生姓…
中国石油大学华东现代远程教育毕业大作业实践报告题目关于井下作业的实践报告学习中心胜利油田学习中心年级专业网络13秋工商管理学生姓名…
中国石油大学华东现代远程教育毕业大作业实践报告题目工商企业管理专业实践报告学习中心青岛校区学习中心年级专业工商企业管理学生姓名学号…
数据库原理大作业作业题目小组成员指导教师提交时间一需求分析功能分析功能结构图提取数据过程以及结果二概念结构设计根据需求分析得到实体…
中国石油大学华东现代远程教育毕业大作业实践报告题目6445井组实践报告学习中心胜利油田滨南学习中心年级专业网络11春油气开采技术学…