安卓音乐播放器开发含源代码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于an droid平台的音乐播放器开发
实验报告
学生姓名:_______ 温从林 _________________
学号: ___________________________________
班级:计自1201 _____________
第一章引言
1.1项目背景
当今社会的生活节奏越来越快,人们对手机的要求也越来越高,由于手机市场发展迅速,使得手机操作系统也出现了不同各类,现在的市场上主要有三个手机操作系统,Win dowsmobile,symbia n,以及谷歌的An droid操作系统,其中占有开放源代码优势的An droid系统有最大的发展前景。
那么能否在手机上拥有自己编写的个性音乐播放器呢?能的,谷歌An droid系统就能做到。
本文的音乐播放器就是基于谷歌An droid手机平台的播放器。
An droid :是谷歌于2007年公布的开放式源代码手机系统,它的开放性就优于其它封闭式的手机系统,因此,任何人都可能根据自己的喜好将手机系统中的所有功能重新编写。
这使得越来越多的人关注这个操作系统。
本次作品音乐播放器就是基于An droid平台的。
1.2编写目的
现今社会生活紧张,而欣赏音乐是其中最好的舒缓压力的方式之一,本项目的目的是开发一个可以播放主流音乐文件格式的播放器,本设计实现的主要功能是播放Mp3 Wav多种格式的音乐文件,并且能够控制播放,暂停,停止,播放列等基本播放控制功能,界面简明,操作简单。
本项目是一款基于An droid手机平台的音乐播放器,使An droid手机拥有个性的
多媒体播放器,使手机显得更生动灵活化,与人们更为接近,让手机主人随时随地处于音乐视频的旋律之中。
使人们的生活更加多样化。
也使设计者更加熟练An droid的技术和其它在市场上的特点。
1.3开发环境
Eclipse、An droid SDK 320
第二章系统需求分析
2.1功能需求(用例图分析)
根据项目的目标,我们可获得项目系统的基本需求,以下从不同角度来描述系统的需求,并且使用用例图来描述,系统的功能需求,我们分成四部分来概括,即播放器的基本控制需要,播放列表管理需求,播放器友好性需求和播放器扩展卡需求。
以下分别描述:
2.1.1播放器的用例图
假设安装了音乐播放器的用户是系统的主要设计对象,其拥有以下操作,
启动软件、播放音乐、暂停播放、停止播放、退出软件,其用例图如下
图2.1 播放器基本用例图
2.1.2用例分析
用例名称:退出
参与者:用户
目标:使得用户退出或者后台播放音乐
前置条件:程序在运行
基本事件流:1.用户按返回键
2. 播放器退出或者进入后台播放
第三章概要设计
3.1软件播放流程图
Stepl.启动软件后,软件自动检索手机和sd卡的音频文件,并组织显示成列表
Step2.点击列表的歌曲名字。
Step3.播放音乐。
Step4.点击暂停,音乐暂停
Step5.点击播放转到step3
Step6.点击停止停止播放音乐
Step7 .点击退出。
自动检索手机中
暂停/退出软件
图3.1音乐播放器流
第四章界面展示
4.1 软件部署
系统编译生成apk 文件,将apk 文件拷到手机或者sd 卡中,直接打开即可安装。
4.2 启动软件
打开软件后的界面
4.3 歌曲列表界面
歌曲列表界面
4.4 播放界面
4.5 收藏界面
4.6 在线搜索音乐界面
第五章结论
(1) 通过本次幵发解决了诸如SD卡音乐文件搜索并显示、联网搜索歌曲等难题,对安卓的开发有了更深入的认识。
(2) 通过对Android 手机平台的音乐播放器软件的开发,使我对Android 音乐播放器系统的整体设计有一个深入的了解,对整个流程也会有一个清晰的认识。
开发Android 音乐播放器,要抓住开发的核心部分,音乐播放器大体由播放主界面、播放列表、菜单、播放设置、文件浏览、歌曲搜索六大核心组成。
(3) 本次程序设计,对播放器的系统结构框架做了精心的构思与设计,采用主要开发工具是Eclips4.0+Java 语言的支持,Android Development Tool 的插件,和
Android SDK2.1 版本的全面结合,才使整个音乐播放器系统得以实现
第五章部分源代码
以下给出功能实现代码,布局,风格等代码量过大,放在压缩文件中
MainActivity.java:
package
import
import
import
import
import
import
import
import
import
import
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
requestWindowFeature(Window. FEATURE_NO_TITLE);
setContentView(yout. fragment_main );
Thread thread = new Thread() {
public void run() {
try {
sleep (2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
finish();
Intent intent = new Intent(MainActivity. this , MusicActivity. class ); startActivity(intent);
}
};
thread.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu. main , menu);
return true ;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) { //
Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId();
if (id == R.id. action_settings ) {
return true ;
}
return super .onOptionsItemSelected(item);
}
* A placeholder fragment containing a simple view. */
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(yout. fragment_main false );
, container, return rootView;
}
}
}
BandanActivity.java
package ;
import
import
import
import
import
import
import
import
import
import
import
import
import
super .onCreate(savedInstanceState);
setContentView(yout. bangdanmusic_list );
listview = (ListView) findViewById(R.id. bangdan_music_list );
listview .setOnItemClickListener( new MusicListOnClickListener()); ShowMp3List(); }
*显示MP3言息,其中」ds 保存了所有音乐文件的_ID ,用来确定到底要播放哪一首歌曲,
_titles 存放音乐名,用来显示在播放界面,
*而_path 存放音乐文件的路径(删除文件时会用到)
*/
private void ShowMp3List() {
// 用游标查找媒体详细信息
this .getContentResolver().query(
DISPLAY_NAME , // 显示名称 ,4
cursor.moveToFirst();
/** 分别将各个标题数组实例化 **/ _ids = new int [cursor.getCount()];
_titles = new String[cursor.getCount()];
_artists = new String[cursor.getCount()];
_path =
new Strin g[cursor.getCo un t()]; _album =
new Strin g[cursor.getCo un t()]; private
ListView listview ; private
String musicpath ; private
int _ids []; // 存放音乐文件的 id 数组 private
String _titles []; // 存放音乐文件的标题数组 private
String _artists []; // 存放音乐艺术家的标题数组 private
String[] _path ; // 存放音乐路径的标题数组 private
String[] _times ; // 存放总时间的标题数组 private
String[] _album ; // 存放专辑的标题数组 private
int _sizes []; // 存放文件大小的标题数组 private String[] displayname ; // 存放名称的标题数组
@Override
protected void onCreate(Bundle savedInstanceState) {
extends Activity { public class BangdanActivity
Cursor cursor = EXTERNAL_CONTENT new String[] {
TITLE ,
DURATION ,
ARTIST , , UR ,I
// 标题,游标从 0读取 // 持续时间 ,1 // 艺术家 ,2 // id ,3 DATA ,
ALBUM_ID , ALBUM ,
SIZE }, null
/** 将游标移到第一位 **/ // 数据, 5 // 专辑名称 ID ,6
// 专辑 ,7 , null ART IST ); // 大小 ,8
_times = new Strin g[cursor.getCo un t()];
_displa yn ame = new Strin g[cursor.getCo un t()];
_sizes = new int [cursor.getCount()];
到的内容格式为/mnt/sdcard/[ 子文件夹名/]音乐文件名,而我们想要得到
的是/sdcard/[ 子文件夹名]音乐文件名
*/
for (int i = 0; i < cursor.getCount(); i++) {
_ids [i] = cursor.getInt(3);
_titles [i] = cursor.getStri ng(0);
_artists [i] = cursor.getStri ng(2);
_path [i] = cursor.getString(5).substring(4);
/***** 以下是为提供音乐详细信息而生成的******/
_album [i] = cursor.getString(7);
_times [i] = toTime(cursor.getInt(1));
_sizes [i] = cursor.getInt(8);
_displa yn ame [i] = cursor.getStri ng(4);
cursor.moveToNext();
}
listview .setAdapter( new MusicListAdapter( this , cursor));
}
/**时间的转换*/
public String toTime( int time) {
time /= 1000;
int minute = time / 60;
int second = time % 60;
minute %= 60;
/**返回结果用string 的format方法把时间转换成字符类型**/
return Stri ng. format ("%02d:%02d" , min ute, seco nd);
}
/**音乐列表添加监听器,点击之后播放音乐*/
public class MusicList On ClickListe ner impleme nts On ItemClickListe ner { @Override
public void on ltemClick(AdapterView<?>argO, View view, int positi on, long id) {
musicpath ="/mnt" +_path [position];
playMusic( musicpath );
/*putExtraMusic(positio n); */
Intent intent = new Inten t(Ba ngda nActivity. this PlayMusicActivity. class );
startActivity(i ntent);
fin ish();
}
}
public void playMusic(String musicpath) {
try {
MediaPlayer mp = new MediaPlayer();
mp.reset();
mp.setDataSource(musicpath);
mp.prepare();
mp.start();
} catch (Exception e){
Toast. makeText (getApplicationContext(), Toast. LENGTH_SHOR)T.show();
}
}
public void putExtraMusic( int position) { Intent intent
Intent(BangdanActivity. this ,PlayMusicActivity. class );
/*intent.putExtra("_ids", _ids);
intent.putExtra("_path", _path);
intent.putExtra("_titles", _titles);
intent.putExtra("_artists", _artists);
intent.putExtra("position", position);
startActivity(intent);
finish();*/
intent = new Intent();
Bundle bundle = new Bundle();
bundle.putInt( "position" , 25);
intent.putExtras(bundle);
intent.setClass(BangdanActivity. this , PlayMusicActivity. class ); startActivity(intent);
finish();
}
@Override
protected void onStop() {
super .onStop();
}
private long exitTime = 0;
public boolean onKeyDown( int keyCode, KeyEvent event) {
if (keyCode == KeyEvent. KEYCODE_BACK && event.getAction() KeyEvent.
ACTION_DOWN){
if ((System. currentTimeMillis ()- exitTime ) > 2000){
Toast. makeText (getApplicationContext(), " 再按一次退出程序 Toast.
LENGTH_SHOR)T.show();
exitTime = System. currentTimeMillis ();
else {
finish();
System. exit (0);
}
return true ;
无法播放此文件
new
}
return super .onKeyDown(keyCode, event);
}
}
CollectionActivity.java
public class CollectionActivity extends ExpandableListActivity { @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 一级条目
List<Map<String, String>>groups=new ArrayList<Map<String,String>>();
Map<String, String> group1=new HashMap<String, String>();
group1.put("group"," 【歌手】");
Map<String, String> group2=new HashMap<String, String>();
group2.put("group"," 【专辑】");
groups.add(group1);
groups.add(group2);
// 二组条目
List<List<Map<String, String>>> childs=new
ArrayList<List<Map<String,String>>>();
// 第一组二级科目数据
List<Map<String, String>> ArrayList<Map<String,String>>(); Map<String, String> item1=new HashMap<String, String>(); item1.put("child"," 林俊杰");
Map<String, String> item2=new HashMap<String, String>(); item2.put("child"," 周杰伦");
child1.add(item1);
child1.add(item2);
// 第二组二级科目数据
List<Map<String, String>> ArrayList<Map<String,String>>(); Map<String, String> item3=new HashMap<String, String>(); item3.put("child","<< 因你而在>>");
Map<String, String> item4=new HashMap<String, String>(); item4.put("child","<< 流行主教>>");
Map<String, String> item5=new HashMap<String, String>(); item5.put("child","<< 第二天堂>>");
child2.add(item3);
child2.add(item4);
child2.add(item5);
childs.add(child1); child1=new child2=new
childs.add(child2);
//SimpleExpandableListAdapter
构造函数参数
//1.content
//2. 一级条目数据
//3. 一级条目布局文件
// 4 . 一级条目Key
//5. 一级条目显示信息控件id
//6. 二级条目数据
//7. 二级条目布局文件
//8. 二级条目Key
//9. 二级条目显示信息控件id
setListAdapter(adapter);
}
private long exitTime = 0;
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK&& event.getAction() KeyEvent.ACTION_DOWN){
if((System.currentTimeMillis()-exitTime) >
2000){ Toast.makeText(getApplicationContext(), " 再按一次退出程序", Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
}
else { finish();
System.exit(0);
}
return true;
}
return super.onKeyDown(keyCode, event);
}
/**
* 初始化菜单
*/
public boolean onMenuKeyDown(int keyCode, KeyEvent event) { if(keyCode==KeyEvent.KEYCODE_MENU&& event.getAction() = KeyEvent.ACTION_DOWN){
Toast.makeText(getApplicationContext(), " 未定义菜单" Toast.LENGTH_SHORT).show();
}
return true;
}
}
Contsant.java
public class Contsant {
* 获取屏幕的大小0:宽度1 :高度
}**/
public static int[] getScreen(Context context) { WindowManager windowManager
context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics(); display.getMetrics(outMetrics);
return new int[] { (int) (outMetrics.density * outMetrics.widthPixels), (int)
(outMetrics.density * outMetrics.heightPixels) };
}
/**
获取文件的后缀名,返回大写
**/ public static String getSuffix(String str) {
int i = stIndexOf('.');
if (i != -1) {
return str.substring(i + 1).toUpperCase(); } return str;
}
/**
格式化文件大小Byte->MB
**/
public static String formatByteToMB(int size){ float mb=size/1024f/1024f;
return String.format("%.2f",mb);
LRCbean.java
package
/** 歌词实体*/
public class LRCbean {
private int beginTime = 0; // 开始时间
public int getBeginTime() {
return beginTime;
}
public void setBeginTime( int beginTime) { this .beginTime = beginTime;
}
public int getLineTime() {
return lineTime;
(WindowManager)
public void setLineTime( int lineTime) { this .lineTime = lineTime;
}
public String getLrcBody() { return lrcBody;
public void setLrcBody(String lrcBody) {
this .lrcBody = lrcBody;
}
private int lineTime = 0;
private String lrcBody = null ; // 歌词实体}
MDialog.java
* 自定义的对话框
*/
public class MDialog extends Dialog {
public MDialog(Context context) {
super(context);
}
public MDialog(Context context, int theme) { super(context, theme);
}
public static class Builder {
private Context context;
private int mIcon = -1; // 提示图标
private CharSequence mTitle; // 提示标题
private CharSequence mMessage;// 提示内容
private CharSequence mPositiveButtonText;// private
CharSequence mNegativeButtonText;// private
CharSequence mNeutralButtonText; // private boolean
mCancelable = true;//
private int mViewSpacingLeft; private int mViewSpacingTop;
private int mViewSpacingRight;
private int mViewSpacingBottom;
private boolean mViewSpacingSpecified = false; // 提示内容View
private View mView; private OnClickListener mPositiveButtonClickListener, mNegativeButtonClickListener, mNeutralButtonClickListener;
private OnCancelListener mCancelListener;// private OnKeyListener mKeyListener; //
取消键事件按键处理
确定按钮文本拒绝按钮文本中间按钮文本
是否启用取消键
public Builder(Context context) {
this.context = context;
}
public Builder setMessage(CharSequence message) { this.mMessage = message;
return this;
}
public Builder setMessage(int message) { this.mMessage = context.getText(message);
return this;
}
public Builder setTitle(int title) {
this.mTitle = context.getText(title); return this;
}
public Builder setTitle(CharSequence title) {
this.mTitle = title;
return this;
}
public Builder setIcon(int icon) {
this.mIcon = icon;
return this;
}
public Builder setView(View view) {
this.mView = view;
mViewSpacingSpecified = false;
return this;
}
public Builder setView(View view, int left, int top, int right, int bottom) {
this.mView = view;
this.mViewSpacingLeft = left; this.mViewSpacingTop = top; this.mViewSpacingRight = right; this.mViewSpacingBottom = bottom; mViewSpacingSpecified = true; return this; }
public Builder setPositiveButton(int textId,
final OnClickListener listener) { this.mPositiveButtonText = context.getText(textId);
this.mPositiveButtonClickListener = listener; return this;
}
public Builder setPositiveButton(String text,
final OnClickListener listener) { this.mPositiveButtonText = text;
this.mPositiveButtonClickListener = listener; return this;
}
public Builder setNeutralButton(int textId,
final OnClickListener listener) { this.mNeutralButtonText = context.getText(textId);
this.mNeutralButtonClickListener = listener; return this;
}
public Builder setNeutralButton(String text,
final OnClickListener listener) { this.mNeutralButtonText = text;
this.mNeutralButtonClickListener = listener; return this;
}
public Builder setNegativeButton(int textId,
final OnClickListener listener) { this.mNegativeButtonText = context.getText(textId);
this.mNegativeButtonClickListener = listener; return this;
}
public Builder setNegativeButton(String text,
final OnClickListener listener) { this.mNegativeButtonText = text;
this.mNegativeButtonClickListener = listener; return this;
}
public Builder setCancelable(boolean cancelable) { this.mCancelable = cancelable;
return this;
}
public Builder setOnCancelListener(OnCancelListener listener) { this.mCancelListener = listener;
return this;
}
public Builder setOnKeyListener(OnKeyListener listener) { this.mKeyListener = listener;
return this;
}
public MDialog create() {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(YOUT_INFLATER_SERVICE);
dialog.setCancelable(mCancelable);
// 设置取消键事件
if (mCancelListener != null) {
dialog.setOnCancelListener(mCancelListener);
}
// 设置键盘监听事件
if (mKeyListener != null) { dialog.setOnKeyListener(mKeyListener);
}
// 获取对话框布局
layout.setLayoutParams(new
LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
// 设置标题
// 设置图标
if (mIcon != -1) {
}
int count = 0;
// 设置确定按钮
count++;
// 设置拒绝按钮
count++;
// 设置中间按钮
count++;
if(count==0){
}
// 一个按钮时,显示两边空间
if (count == 1) {
}
// 设置提示消息
if (!TextUtils.isEmpty(mMessage)) {
} else {
}
// 设置提示内容布局
if (mView != null) {
if (mViewSpacingSpecified) {
customPanel.setPadding(mViewSpacingLeft, mViewSpacingTop,mViewSpacingRight, mViewSpacingBottom);
}
customPanel.addView(mView);
} else {
}
dialog.setContentView(layout);
return dialog;
}
public MDialog show() {
MDialog dialog = create();
dialog.show();
return dialog;
}
private boolean setButton(View layout, mPositiveButtonText2, int id,
final Dialog dialog, final OnClickListener listener) {
CharSequence if (!TextUtils.isEmpty(mPositiveButtonText2)) {
final Button button1 = (Button) layout.findViewById(id);
button1.setText(mPositiveButtonText2);
if (listener != null) {
button1.setOnClickListener(new View.OnClickListener()
{ public void onClick(View v) {
listener.onClick(dialog,DialogInterface.BUTTON_POSITIVE);
}
});
}else{
// 默认事件为关闭对话框button1.setOnClickListener(new
View.OnClickListener() { public void onClick(View v) {
dialog.cancel(); dialog.dismiss();
}
});
}
return true;
} else { layout.findViewById(id).setVisibility(View.GONE); return false;
}
}
}
}
MusicActivity.java
/* 以Tabhost+RadioGroup 组合*/
public class MusicActivity extends TabActivity OnCheckedChangeListener{
private TabHost tabhost;
private RadioGroup radiogroup;
@Override
implements
requestWindowFeature(Window.FEATURE_NO_TITLE); tabhost=getTabHost(); radiogroup.setOnCheckedChangeListener(this); radiogroup.setClickable(true);
tabhost.addTab(tabhost.newTabSpec("local_music").setIndicator("local_musi c").setContent(new Intent(this,MusicListActivity.class)));
tabhost.addTab(tabhost.newTabSpec("my_collect").setIndicator("my_collect" ).setContent(new Intent(this,CollectionActivity.class)));
tabhost.addTab(tabhost.newTabSpec("net_music").setIndicator("net_music"). setContent(new Intent(this,NetMusicActivity.class)));
}
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { tabhost.setCurrentTabByTag("local_music");
break; tabhost.setCurrentTabByTag("my_collect"); break; tabhost.setCurrentTabByTag("net_music"); break;
}
}
}
MusicListActivity.java
public class MusicListActivity extends Activity {
/** 音乐列表 **/
private LayoutParams params; private Toast toast; // 提示 public static final int Ringtone = 0; public static final int Alarm = 1; public static final int Notification = 2; private TextView timers;// 显示倒计时的文字 public MusicListAdapter adapter; @Override
private ListView listview; private String musicpath; private int _ids[]; // private String _titles[]; // private String _artists[]; // private String[] _path; // private String[] _times; // private String[] _album; // private int _sizes[]; // private String[] _displayname;// private int num; //num private LayoutInflater inflater;//
存放音乐文件的 id 数组 存放音乐文件的标题数组 存放音乐艺术家的标题数组 存放音乐路过的标题数组 存放总时间的标题数组 存放专辑的标题数组 存放文件大小的标题数组 存放名称的标题数组
确定一个标识 装载布局
/** 选择子项点击事件***/ listview.setOnItemClickListener(new MusicListOnClickListener());
listview.setOnCreateContextMenuListener(new
MusicListContextListener());
inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
params = new
LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);
ShowMp3List();
}
/**显示MP3信息,其中」ds保存了所有音乐文件的_ID,用来确定到底要播放哪一首歌曲,
_titles 存放音乐名,用来显示在播放界面,
_path 存放音乐文件的路径(删除文件时会用到) 。
**/
private void ShowMp3List() {
/** 用游标查找媒体详细信息**/
Cursor cursor = this.getContentResolver().query(
/** 判断游标是否为空,有些地方即使没有音乐也会报异常。
而且游标不稳定。
稍有不慎就出错了,其次,如果用户没有音乐的话,不妨可以告知用户没有音乐让用户添加进去*/ if (cursor!= null && cursor.getCount() == 0) {
final MDialog xfdialog = new MDialog.Builder(MusicListActivity.this).setTitle(" 提示:").setMessage(" 你的手机
未找到音乐,请添加音乐").setPositiveButton(" 确定", null).create();
xfdialog.show();
return;
}
/** 将游标移到第一位**/
cursor.moveToFirst();
/** 分别将各个标题数组实例化**/
_ids = new int[cursor.getCount()];//
_titles = new String[cursor.getCount()];
_artists = new String[cursor.getCount()];
_path = new String[cursor.getCount()];
_album = new String[cursor.getCount()];
_times = new String[cursor.getCount()];
_displayname = new String[cursor.getCount()]; _sizes = new int[cursor.getCount()];
到的内容格式为/mnt/sdcard/[ 子文件夹名/] 音乐文件名,的是/sdcard/[ 子文件夹名] 音乐文件名
**/
for (int i = 0; i < cursor.getCount(); i++) {
_ids[i] = cursor.getInt(3);
_titles[i] = cursor.getString(0);
_artists[i] = cursor.getString(2); _path[i] =
cursor.getString(5).substring(4);
/** 以下是为提供音乐详细信息而生成的**/
_album[i] = cursor.getString(7);
_times[i] = toTime(cursor.getInt(1));
_sizes[i] = cursor.getInt(8);
_displayname[i] = cursor.getString(4);
cursor.moveToNext();
/** 一直将游标往下走**/
}
listview.setAdapter(new MusicListAdapter(this, cursor));
}
/** 时间的转换**/
public String toTime(int time) {
time /= 1000;
int minute = time / 60;
int second = time % 60;
minute %= 60;
/** 返回结果用string 的format 方法把时间转换成字符类型**/ return
String.format("%02d:%02d", minute, second);
}
/** 音乐列表添加监听器,点击之后播放音乐*/ public class
MusicListOnClickListener implements OnItemClickListener { @Override public void onItemClick(AdapterView<?> arg0, View view, long id) {
playMusic(position);
}
}
/** 长按Listview 后弹出菜单**/ private class MusicListContextListener OnCreateContextMenuListener {
@Override
public void onCreateContextMenu(ContextMenu v,ContextMenuInfo info) {
SongItemDialog();
/** 当显示AdapterView 的上下文菜单时,为onCreateContextMenu(ContextMenu, View, ContextMenuInfo) 回调函数提供的额外的菜单信息.**/
final AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) info; 而我们想要得到
int position,
implements menu, View
num = menuInfo.position;
}
}
/** 根据Position 播放音乐**/ public void playMusicII(int position)
{ musicpath="/mnt"+_path[position]; try{
MediaPlayer mp = new MediaPlayer();
mp.reset();
mp.setDataSource(musicpath);
mp.prepare();
mp.start();
}catch(Exception e){
Toast.makeText(getApplicationContext()," 无法播放此文件",
Toast.LENGTH_SHORT).show();
}
}
/** 根据Position 播放音乐**/ public void playMusic(int position) {
Intent intent = new Intent(MusicListActivity.this,PlayMusicActivity.class);
intent.putExtra("_ids", _ids); intent.putExtra("_titles", _titles); intent.putExtra("_artists",
_artists); intent.putExtra("_path", _path); intent.putExtra("_album",_album);
intent.putExtra("position", position); startActivity(intent);
finish();
}
/** 用户长按列表或者按住最右边的倒三角形发生的事件**/ private void SongItemDialog() { String[] menustring = new String[] { " 播放选中音乐", " 收藏选中音乐", " 查看歌曲信息" ," 删除选中歌曲"};
ListView menulist = new ListView(MusicListActivity.this);
menulist.setCacheColorHint(Color.TRANSPARENT); menulist.setDividerHeight(1);
menulist.setLayoutParams(new
LayoutParams(Contsant.getScreen(MusicListActivity.this)[0] /
2,LayoutParams.WRAP_CONTENT));
xfdialog.show();
menulist.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
xfdialog.cancel();
xfdialog.dismiss();
if (position==0) {
playMusic(num);
}else if (position==1) {
CollectMusic(num);
}else if (position==2) {
ShowMusicInfo(num);
}else if (position==3) {
DeleteMusic(num);
}
}
});
}
private void ShowMusicInfo(int location) {
}
private void CollectMusic(int location){
Toast.makeText(getApplicationContext(), " 收藏成功Toast.LENGTH_SHORT).show();
}
private void DeleteMusic(int location){
Toast.makeText(getApplicationContext(), " 删除成功Toast.LENGTH_SHORT).show();
}
/** 退出程序方法**/
private long exitTime = 0;
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction()
KeyEvent.ACTION_DOWN){
if((System.currentTimeMillis()-exitTime) > 2000){
Toast.makeText(getApplicationContext(), "
再按一次退出程序", Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
}
else { finish();
System.exit(0);
return true;
}
return super.onKeyDown(keyCode, event);
}
}
NetMusicActivity.java
/* 以Tabhost+RadioGroup 组合*/
public class NetMusicActivity extends TabActivity
implements OnCheckedChangeListener{
private TabHost tabhost;
private RadioGroup radiogroup;
@Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); tabhost=getTabHost();
radiogroup.setOnCheckedChangeListener(this); radiogroup.setClickable(true);
tabhost.addTab(tabhost.newTabSpec("bangdan").setIndicator("bangdan").setC ontent(new
Intent(this,SingerActivity.class)));
tabhost.addTab(tabhost.newTabSpec("tuijian").setIndicator("tuijian").setC ontent(new
Intent(this,SingerActivity.class)));
tabhost.addTab(tabhost.newTabSpec("gedan").setIndicator("gedan").setConte nt(new
Intent(this,SingerActivity.class)));
tabhost.addTab(tabhost.newTabSpec("geshou").setIndicator("geshou").setCon tent(new
Intent(this,SingerActivity.class)));
tabhost.addTab(tabhost.newTabSpec("diantai").setIndicator("diantai").setC ontent(new
Intent(this,SingerActivity.class)));
}
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) {
tabhost.setCurrentTabByTag("bangdan");
break;
tabhost.setCurrentTabByTag("tuijian");
break;
tabhost.setCurrentTabByTag("gedan"); tabhost.setCurrentTabByTag("geshou");
tabhost.setCurrentTabByTag("diantai");
break;
PlayMusicActivity.java /** 播放音乐界面**/ public class
PlayMusicActivity extends Activity { private
RelativeLayout ll_player_voice; private
RelativeLayout music_all; private int[] _ids; //
private String[] _artists; // private String[] _titles; // private String[]_album; // private TextView musicnames; // private TextView artisting; // private ImageButton play_btn;// private ImageButton last_btn;// private ImageButton next_btn;// private TextView playtimes = null; 临时音乐id 艺术家标题专辑音乐名艺术家播放按钮上一首下一首
// private TextView durationTime = null;// private SeekBar seekbar; //
private SeekBar sp_player_voice;// private int position; // private int currentPosition;// private int duration; // private ImageView album; // private ImageButton LoopBtn = null; private ImageButton RandomBtm = null; private ImageButton ibtn_player_list;
已播放时间
歌曲时间
进度条
调节音量
定义一个位置,
当前播放位置
总时间
专辑
//
//
private ImageButton ibtn_player_control_menu; private static final int PLAY = 1; // private static final int PAUSE = 2; // private static final int STOP = 3; // private static final int PROGRESS_CHANGE = 4;// private static final int STATE_PLAY = 1; // private static final int STATE_PAUSE = 2; // public static final int LOOP_NONE = 0; // public static final int LOOP_ONE = 1; // public static final int LOOP_ALL = 2; // public static int loop_flag = LOOP_NONE; public static boolean random_flag = false; public static int[] randomIDs = null;
用于定位用户点击列表曲首
循环
随机
定义播放状态
暂停状态停
止
进度条改变播放
状态设为 1 暂停
状态设为2
不循环
单体循环
全部循环。