8001511072夏先国安卓大作业报告书

Android 酷儿音乐播放器设计报告书

8001511072夏先国安卓大作业报告书

南昌大学

大作业实验报告 题 目:专 业: 软 件 技 术 班 级: 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 -

8001511072夏先国安卓大作业报告书

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"?>

8001511072夏先国安卓大作业报告书

<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"

8001511072夏先国安卓大作业报告书

- 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"

8001511072夏先国安卓大作业报告书

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"

8001511072夏先国安卓大作业报告书

- 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所示。

8001511072夏先国安卓大作业报告书

图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 程序运行效果图

8001511072夏先国安卓大作业报告书

- 95 -

Android 酷儿音乐播放器设计报告书

8001511072夏先国安卓大作业报告书

- 96 -

Android 酷儿音乐播放器设计报告书

8001511072夏先国安卓大作业报告书

- 97 -

Android 酷儿音乐播放器设计报告书

8001511072夏先国安卓大作业报告书

- 98 -

Android 酷儿音乐播放器设计报告书

8001511072夏先国安卓大作业报告书

- 99 -

Android 酷儿音乐播放器设计报告书

8001511072夏先国安卓大作业报告书

- 100 -

Android 酷儿音乐播放器设计报告书

8001511072夏先国安卓大作业报告书

- 101 -

Android 酷儿音乐播放器设计报告书

8001511072夏先国安卓大作业报告书

- 102 -

Android 酷儿音乐播放器设计报告书

8001511072夏先国安卓大作业报告书

- 103 -

Android 酷儿音乐播放器设计报告书

4.2 程序调试过程

ADT工具附有LogCat工具,在函数的开始结束及分支处设置特定文字标记内容,即可以在LogCat工具中打印调试内容,这对于bug的判断及追踪有很大帮助,并了解程序的运行流程。图4-2是LogCat工具使用的截图。

8001511072夏先国安卓大作业报告书

- 104 -

Android 酷儿音乐播放器设计报告书

图4-2

8001511072夏先国安卓大作业报告书

- 105 -

Android 酷儿音乐播放器设计报告书

五、实验总结

由于对android的接触较少,所以也遇到了一些问题,无论是哪种语言首先要有自己的思路,接下来就是通过语言的实现。我主要遇到android的四大组件的理解和使用,刚开始不知道如何用相关的组件,而且android的组件相当的多,就老师上课讲的相关知识比较少,对于我们初学者学习比较困难,而且,只是不是那么的连贯和详细,上课的时间只是跟上老师再敲代码,实现一个具体的功能,但是不有真正的弄懂它的使用方法,所以,我们在课设中出现很多问题。今后安卓界面设计和java语言使用能力需要加强。

- 106 -

Android 酷儿音乐播放器设计报告书

六、参考资料 参考书籍

《android应用开发揭秘》 《android一日游》

《安卓开发实战经典》 部分参考资料来自

安卓技术论坛网站

安卓开发爱好者网站

百度文库

- 107 -

相关推荐