音乐播放器--简单实现播放、暂停、随机播放、音乐进度条(第一版)
2016-05-11 00:00
696 查看
界面如下:
说明一下实现这个音乐播放器的思路。
首先,打开应用后查找手机上所有的音乐,放在Application中。这样做避免以后查找播放音乐的时候使用静态变量(上个应用就是应为大量使用静态变量,内存消耗太大,Activity老是被回收,所以这次直接把要使用的数据放在Application,使用的时候再取出来)
获取手机上所有音乐(有个缺点,就是所有是声音的文件都查找出来了,这部分以后还要优化,优化成自定义扫描目录,获获取手机上歌曲。)
代码如下:
在Activity中获取歌曲代码如下:
第二步:当点击播放音乐的时候,传递给Service音乐id,在后台打开音乐。代码如下:
1、在<manifest>中
声明<service>
2、创建自己的Service
接下来是细节问题,比如进度条改变,暂停音乐,继续播放。。
1、进度条改变是通过Service不断发送广播,然后在Activity中接收广播
2、底部的暂停播放按钮事件
3、下一首事件代码
这里可以下载源码:http://download.csdn.net/detail/yan943789510/8615689
说明一下实现这个音乐播放器的思路。
首先,打开应用后查找手机上所有的音乐,放在Application中。这样做避免以后查找播放音乐的时候使用静态变量(上个应用就是应为大量使用静态变量,内存消耗太大,Activity老是被回收,所以这次直接把要使用的数据放在Application,使用的时候再取出来)
获取手机上所有音乐(有个缺点,就是所有是声音的文件都查找出来了,这部分以后还要优化,优化成自定义扫描目录,获获取手机上歌曲。)
代码如下:
<pre name="code" class="java"> private List<Music> musiclist; @Override public void onCreate() { super.onCreate(); searchMusicONPhone(); } /** * 查找手机上所有歌曲 */ private void searchMusicONPhone(){ Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER); musiclist = new ArrayList<Music>(); if(cursor == null || cursor.getCount() <= 0){ setMusiclist(musiclist); }else{ while(cursor.moveToNext()){ Music music = new Music(); music.setId(cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media._ID))); //歌曲ID music.setTitle(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)));//歌曲的名称 music.setAlbum(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM))); //歌曲的专辑名 music.setArtists(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST))); //歌曲的歌手名 music.setTimes(toTime(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION))));//歌曲的总播放时长 music.setPath(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)));//歌曲文件的路径 music.setSize(cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)));//歌曲文件的大小 musiclist.add(music); } setMusiclist(musiclist); } if(cursor != null){ cursor.close(); cursor = null; } } public List<Music> getMusiclist() { return musiclist; } public void setMusiclist(List<Music> musiclist) { this.musiclist = musiclist; }
在Activity中获取歌曲代码如下:
mApplication = (MyApplication)getApplication(); musiclist = mApplication.getMusiclist();
第二步:当点击播放音乐的时候,传递给Service音乐id,在后台打开音乐。代码如下:
1、在<manifest>中
声明<service>
<service android:name="com.mini.service.MusicService"> <intent-filter> <action android:name="com.app.media.music_service"/> </intent-filter> </service>
2、创建自己的Service
package com.mini.service; import java.io.IOException; import java.util.List; import com.mini.MyApplication; import com.mini.R; import com.mini.activity.base.BaseActivity; import com.mini.bean.Music; import com.mini.constans.Constants; import android.annotation.SuppressLint; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.media.MediaPlayer.OnPreparedListener; import android.net.Uri; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.provider.MediaStore; @SuppressLint("HandlerLeak") public class MusicService extends Service implements MediaPlayer.OnCompletionListener { private MyApplication mApplication; private List<Music> mList; private MediaPlayer mPlayer; private int op; private Uri uri; private int id; private int position; private int currentTime; private Handler mHandler; private int duration; @Override public void onCreate() { super.onCreate(); mApplication = (MyApplication)getApplication(); mList = mApplication.getMusiclist(); if(mPlayer != null){ mPlayer.reset(); mPlayer.release(); mPlayer = null; } mPlayer = new MediaPlayer(); mPlayer.setOnCompletionListener(this); } @SuppressWarnings("deprecation") @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); position = intent.getIntExtra("idOption", -1); if(position == -1){ }else{ playMusic(); } op = intent.getIntExtra("op", -1); switch (op) { case Constants.MUSIC_PLAY: playing(); break; case Constants.MUSIC_PAUSE: pause(); break; case Constants.MUSIC_STOP: stop(); break; case Constants.PROGRESS_CHANGE: currentTime = intent.getExtras().getInt("progress"); mPlayer.seekTo(currentTime); break; case -1: setUp(); initBorderCastService(); break; default: break; } } /** * 初始化歌曲信息、进度条 */ private void setUp(){ final Intent intent = new Intent(); intent.setAction(Constants.MUSIC_DURATION); try { if(!mPlayer.isPlaying()){ mPlayer.prepare(); } mPlayer.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mHandler.sendEmptyMessage(1); } }); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } duration = mPlayer.getDuration(); intent.putExtra("duration", duration); sendBroadcast(intent); } /** * 初始化广播机制 */ private void initBorderCastService(){ final Intent intent = new Intent(); intent.setAction(Constants.MUSIC_CURRENT); if(mHandler == null){ mHandler = new Handler(){ public void handleMessage(Message msg){ if(msg.what == 1){ currentTime = mPlayer.getCurrentPosition(); intent.putExtra("currentTime", currentTime); if(position == -1){ intent.putExtra("position",intent.getIntExtra("position", -1)); }else{ intent.putExtra("position",position); } sendBroadcast(intent); } mHandler.sendEmptyMessageDelayed(1, 1000); } }; } } /** * 播放歌曲 */ private void playing(){ if(mPlayer != null){ mPlayer.start(); } } /**暂停*/ private void pause() { if (mPlayer != null) { mPlayer.pause(); } } /** 停止*/ private void stop() { if (mPlayer != null) { mPlayer.stop(); try { mPlayer.prepare(); mPlayer.seekTo(0); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } mHandler.removeMessages(1); } } @Override public IBinder onBind(Intent intent) { return null; } private static int i; @Override public void onCompletion(MediaPlayer mp) { nextMusic(); } private void nextMusic() { switch (BaseActivity.loop_method) { case Constants.LOOP_ONE: break; case Constants.LOOP_ALL: if (position == mList.size()-1) { position = 0; } else if (position < mList.size()-1) { position++; } break; case Constants.LOOP_NONE: position = BaseActivity.mRandomID(); break; default: break; } playMusic(); setUp(); initBorderCastService(); playing(); } public void playMusic(){ id = mList.get(position).getId(); uri = Uri.withAppendedPath(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id + ""); try { mPlayer.reset(); mPlayer.setDataSource(this,uri); mPlayer.prepare(); mPlayer.start(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } 3、播放事件 /** * 随机播放音乐事件 */ radom_begin_music.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { myPosition = mRandomID(); Intent intent = new Intent(); intent.setAction("com.app.media.music_service"); intent.putExtra("idOption", myPosition); startService(intent); flag = Constants.MUSIC_PAUSE; } });
接下来是细节问题,比如进度条改变,暂停音乐,继续播放。。
1、进度条改变是通过Service不断发送广播,然后在Activity中接收广播
/** * 接收广播,更新歌曲的进度 */ protected BroadcastReceiver musicReceiver = new BroadcastReceiver(){ @Override public void onReceive(Context context, Intent intent) { String actionString = intent.getAction(); if(actionString.equals(Constants.MUSIC_CURRENT)){ currentPosition = intent.getExtras().getInt("currentTime"); position = intent.getExtras().getInt("position"); music_durtion_sBar.setProgress(currentPosition); music_preform_time.setText(toTime(currentPosition)); bottomUpdate(); }else if(actionString.equals(Constants.MUSIC_DURATION)){ duration = intent.getExtras().getInt("duration"); music_durtion_sBar.setMax(duration); } } };
2、底部的暂停播放按钮事件
/** * 底部播放暂停按钮 */ bottom_play_btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { switch (flag) { case Constants.MUSIC_PAUSE: pause(); break; case Constants.MUSIC_PLAY: play(); break; default: break; } } }); /** * 播放音乐 */ public void play() { flag = Constants.MUSIC_PAUSE; bottom_play_btn.setBackgroundResource(R.drawable.bottom_play); Intent intent = new Intent(); intent.setAction("com.app.media.music_service"); intent.putExtra("op", Constants.MUSIC_PLAY);// 向服务传递数据 startService(intent); } /** * 暂停 */ public void pause() { flag = Constants.MUSIC_PLAY; bottom_play_btn.setBackgroundResource(R.drawable.bottom_pause); Intent intent = new Intent(); intent.setAction("com.app.media.music_service"); intent.putExtra("op", Constants.MUSIC_PAUSE); startService(intent); }
3、下一首事件代码
/** * 下一首 */ public void nextOne() { stop(); setup(); playNext(); } public void playNext() { flag = Constants.MUSIC_PAUSE; int music_id = position; switch (loop_method) { case Constants.LOOP_ONE: music_id = position; break; case Constants.LOOP_ALL: if (position == musiclist.size()-1) { position = 0; music_id = position; } else if (position < musiclist.size()-1) { position++; music_id = position; } break; case Constants.LOOP_NONE: music_id = mRandomID(); break; default: break; } bottom_play_btn.setBackgroundResource(R.drawable.bottom_play); Intent intent = new Intent(); intent.setAction("com.app.media.music_service"); intent.putExtra("idOption", music_id);// 向服务传递数据 startService(intent); } /** * 停止播放音乐 */ private void stop() { unregisterReceiver(musicReceiver); Intent intent = new Intent(); intent.setAction("com.app.media.music_service"); intent.putExtra("op", Constants.MUSIC_STOP); startService(intent); } /** * 初始化 */ private void setup() { init(); }
这里可以下载源码:http://download.csdn.net/detail/yan943789510/8615689
相关文章推荐
- Service Intent must be explicit--服务的intent必须使用显示传递
- app启动前闪现白屏、黑屏问题解决
- MySql数据库连接失败--org.apache.tomcat.dbcp.dbcp.SQLNestedException
- 使用Navicat for MySql导入.CSV文件
- java传值与传引用学习
- gson转list
- android刷新媒体数据库
- 基础总结篇之一:Activity生命周期
- Swift 项目中可能用到的第三方框架
- mysql导入导出数据中文乱码解决方法小结
- 移动互联网下的社群模式背后的隐患
- 选择蜂窝教育IOS培训 为自己“充电”
- 小代码
- BZOJ 3530 【Sdoi2014】 数数
- QQ通信原理
- linux下创建oracle表空间
- Linux命令(基本)
- Openwrt下获取进程pid的实用shell
- day5-simple ftp
- 什么是 Polymer 【1】