1. import java.io.File;
  2. import java.io.FilenameFilter;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import android.app.ListActivity;
  6. import android.apps.service.PlayerService;
  7. import android.content.Intent;
  8. import android.media.AudioManager;
  9. import android.os.Bundle;
  10. import android.view.View;
  11. import android.view.View.OnClickListener;
  12. import android.widget.ArrayAdapter;
  13. import android.widget.Button;
  14. import android.widget.SeekBar;
  15. import android.widget.Toast;
  16. public class TestMediaPlayer extends ListActivity {
  17. /* 前段时间刚学习Android时就觉得MediaPlayer是个很神奇的东西,就试着做了个简单的音乐播放器。
  18. * 支持后台播放、进度条拖放、音量控制、读取sdCard音乐文件进行播放等。
  19. * */
  20. private Button playButton = null;
  21. private Button mFrontButton = null;
  22. private Button mLastButton = null;
  23. private Button exit = null;
  24. /* 声明音量管理器 */
  25. private AudioManager mAudioManager = null;
  26. /* 定义进度条 */
  27. public static SeekBar audioSeekBar = null;
  28. /* 定义音量大小 */
  29. private SeekBar audioVolume = null;
  30. /* 定于一个数据播放列表,用来存放从指定文件中搜索到的文件 */
  31. public static List<String> mMusicList = new ArrayList<String>();
  32. /* 定义音乐存放路径 */
  33. //  private static final String MUSIC_PATH = new String("/mnt/sdcard/"); //android 2.2
  34. private static final String MUSIC_PATH = new String("/sdcard/");//android 2.1
  35. /* 定义在播放列表中的当前选择项 */
  36. public static int currentListItme = 0;
  37. @Override
  38. public void onCreate(Bundle savedInstanceState) {
  39. super.onCreate(savedInstanceState);
  40. setContentView(R.layout.main);
  41. /* 更新列表 */
  42. musicList();
  43. /* 得到控件 */
  44. playButton = (Button) findViewById(R.id.StartMusic);
  45. mFrontButton = (Button) findViewById(R.id.FrontButton);
  46. mLastButton = (Button) findViewById(R.id.LastMusic);
  47. audioVolume = (SeekBar) findViewById(R.id.audioVolume);
  48. exit = (Button)findViewById(R.id.exit);
  49. audioSeekBar = (SeekBar) findViewById(R.id.seekbar01);
  50. /* 播放、暂停监听 */
  51. playButton.setOnClickListener(new OnClickListener() {
  52. @Override
  53. public void onClick(View v) {
  54. playMusic(AppConstant.PlayerMag.PAUSE);
  55. }
  56. });
  57. /* 监听下一首 */
  58. mFrontButton.setOnClickListener(new OnClickListener() {
  59. @Override
  60. public void onClick(View v) {
  61. nextMusic();
  62. }
  63. });
  64. /* 监听上一首 */
  65. mLastButton.setOnClickListener(new View.OnClickListener() {
  66. @Override
  67. public void onClick(View v) {
  68. FrontMusic();
  69. }
  70. });
  71. /*退出监听*/
  72. exit.setOnClickListener(new OnClickListener() {
  73. @Override
  74. public void onClick(View v) {
  75. Intent intent = new Intent();
  76. intent.setClass(TestMediaPlayer.this, PlayerService.class);
  77. stopService(intent);//停止Service
  78. try {
  79. TestMediaPlayer.this.finish();//关闭当前Activity
  80. } catch (Throwable e) {
  81. e.printStackTrace();
  82. }
  83. }
  84. });
  85. /* 播放进度监听 */
  86. audioSeekBar.setOnSeekBarChangeListener(new SeekBarChangeEvent());
  87. /*退出后再次进去程序时,进度条保持持续更新*/
  88. if(PlayerService.mMediaPlayer!=null){
  89. //设置进度条最大值
  90. TestMediaPlayer.audioSeekBar.setMax(PlayerService.mMediaPlayer.getDuration());
  91. audioSeekBar.setProgress(PlayerService.mMediaPlayer.getCurrentPosition());
  92. }
  93. /* 得到当前音量对象 */
  94. mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
  95. /* 把当前音量值赋给进度条 */
  96. audioVolume.setProgress(mAudioManager
  97. .getStreamVolume(AudioManager.STREAM_MUSIC));
  98. /* 监听音量 */
  99. audioVolume.setOnSeekBarChangeListener(new AudioVolumeChangeEvent());
  100. }
  101. public void playMusic(int action) {
  102. Intent intent = new Intent();
  103. intent.putExtra("MSG", action);
  104. intent.setClass(TestMediaPlayer.this, PlayerService.class);
  105. /* 启动service service要在AndroidManifest.xml注册如:<service></service>*/
  106. startService(intent);
  107. }
  108. /* 检测sdcard MP3文件并加入到List列表 */
  109. public void musicList() {
  110. // 先清除list中的缓存
  111. mMusicList.clear();
  112. /* 从指定的路径中读取文件,并与播放列表关联 */
  113. File home = new File(MUSIC_PATH);
  114. System.out.println(home.canRead());
  115. /* 读取指定类型的文件,在本程序,指定播放类型为mp3 */
  116. if (home.listFiles(new MusicFilter()).length > 0) {
  117. /* 读取文件 */
  118. for (File file : home.listFiles(new MusicFilter())) {
  119. mMusicList.add(file.getName());
  120. }
  121. /* 播放文件与播放列表关联 */
  122. ArrayAdapter<String> musicList = new ArrayAdapter<String>(
  123. TestMediaPlayer.this, R.layout.musictime, mMusicList);
  124. setListAdapter(musicList);
  125. }
  126. }
  127. /* 音量监听 */
  128. class AudioVolumeChangeEvent implements SeekBar.OnSeekBarChangeListener {
  129. @Override
  130. public void onProgressChanged(SeekBar seekBar, int progress,
  131. boolean fromUser) {
  132. // mAudioManager.adjustVolume(AudioManager.ADJUST_LOWER, 0);
  133. mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress,
  134. 0);
  135. }
  136. @Override
  137. public void onStartTrackingTouch(SeekBar seekBar) {
  138. }
  139. @Override
  140. public void onStopTrackingTouch(SeekBar seekBar) {
  141. }
  142. }
  143. /* 音乐选择监听 */
  144. @Override
  145. protected void onListItemClick(android.widget.ListView l, View v,
  146. int position, long id) {
  147. super.onListItemClick(l, v, position, id);
  148. currentListItme = position;
  149. playMusic(AppConstant.PlayerMag.PLAY_MAG);
  150. }
  151. /* 播放下一首 */
  152. private void nextMusic() {
  153. if (++currentListItme >= mMusicList.size()) {
  154. Toast.makeText(TestMediaPlayer.this, "已到最后一首歌曲", Toast.LENGTH_SHORT)
  155. .show();
  156. currentListItme = mMusicList.size() - 1;
  157. } else {
  158. playMusic(AppConstant.PlayerMag.PLAY_MAG);
  159. }
  160. }
  161. /* 播放上一首歌曲 */
  162. private void FrontMusic() {
  163. if (--currentListItme >= 0) {
  164. playMusic(AppConstant.PlayerMag.PLAY_MAG);
  165. } else {
  166. Toast.makeText(TestMediaPlayer.this, "已到第一首歌曲", Toast.LENGTH_SHORT)
  167. .show();
  168. currentListItme = 0;
  169. }
  170. }
  171. }
  172. /* 播放文件选择类 */
  173. class MusicFilter implements FilenameFilter {
  174. public boolean accept(File dir, String name) {
  175. /* 指定扩展名类型 ,可以加其他的音乐格式*/
  176. return (name.endsWith(".mp3"));
  177. }
  178. }
  179. /* 拖放进度监听 ,别忘了Service里面还有个进度条刷新*/
  180. class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener {
  181. @Override
  182. public void onProgressChanged(SeekBar seekBar, int progress,
  183. boolean fromUser) {
  184. /*假设改变源于用户拖动*/
  185. if (fromUser) {
  186. PlayerService.mMediaPlayer.seekTo(progress);// 当进度条的值改变时,音乐播放器从新的位置开始播放
  187. }
  188. }
  189. @Override
  190. public void onStartTrackingTouch(SeekBar seekBar) {
  191. PlayerService.mMediaPlayer.pause(); // 开始拖动进度条时,音乐暂停播放
  192. }
  193. @Override
  194. public void onStopTrackingTouch(SeekBar seekBar) {
  195. PlayerService.mMediaPlayer.start(); // 停止拖动进度条时,音乐开始播放
  196. }
  197. }

service类

首先建议不要把播放音乐放在Activity中,因为关闭Activity后就不能实现后台播放。所以播放音乐要放在Service中,我们只需要管理Activity与Service间的通信就好了。下面就是个Service类。直接看注释和代码:

  1. package android.apps.service;
  2. import java.io.IOException;
  3. import android.app.Service;
  4. import android.content.Intent;
  5. import android.media.MediaPlayer;
  6. import android.net.Uri;
  7. import android.os.IBinder;
  8. import android.widget.Toast;
  9. import android.apps.*;
  10. public class PlayerService extends Service implements Runnable,
  11. MediaPlayer.OnCompletionListener {
  12. /* 定于一个多媒体对象 */
  13. public static MediaPlayer mMediaPlayer = null;
  14. // 是否单曲循环
  15. private static boolean isLoop = false;
  16. // 用户操作
  17. private int MSG;
  18. /* 定义要播放的文件夹路径 */
  19. private static final String MUSIC_PATH = new String("/sdcard/");
  20. @Override
  21. public IBinder onBind(Intent intent) {
  22. return null;// 这里的绑定没的用,上篇我贴出了如何将activity与service绑定的代码
  23. }
  24. @Override
  25. public void onCreate() {
  26. super.onCreate();
  27. if (mMediaPlayer != null) {
  28. mMediaPlayer.reset();
  29. mMediaPlayer.release();
  30. mMediaPlayer = null;
  31. }
  32. mMediaPlayer = new MediaPlayer();
  33. /* 监听播放是否完成 */
  34. mMediaPlayer.setOnCompletionListener(this);
  35. }
  36. @Override
  37. public void onDestroy() {
  38. super.onDestroy();
  39. if (mMediaPlayer != null) {
  40. mMediaPlayer.stop();
  41. mMediaPlayer.release();
  42. mMediaPlayer = null;
  43. }
  44. System.out.println("service onDestroy");
  45. }
  46. /*启动service时执行的方法*/
  47. @Override
  48. public int onStartCommand(Intent intent, int flags, int startId) {
  49. /*得到从startService传来的动作,后是默认参数,这里是我自定义的常量*/
  50. MSG = intent.getIntExtra("MSG", AppConstant.PlayerMag.PLAY_MAG);
  51. if (MSG == AppConstant.PlayerMag.PLAY_MAG) {
  52. playMusic();
  53. }
  54. if (MSG == AppConstant.PlayerMag.PAUSE) {
  55. if (mMediaPlayer.isPlaying()) {// 正在播放
  56. mMediaPlayer.pause();// 暂停
  57. } else {// 没有播放
  58. mMediaPlayer.start();
  59. }
  60. }
  61. return super.onStartCommand(intent, flags, startId);
  62. }
  63. @SuppressWarnings("static-access")
  64. public void playMusic() {
  65. try {
  66. /* 重置多媒体 */
  67. mMediaPlayer.reset();
  68. /* 读取mp3文件 */
  69. mMediaPlayer.setDataSource(MUSIC_PATH+TestMediaPlayer.mMusicList.get(TestMediaPlayer.currentListItme));
  70. //          Uri uri = Uri.parse(MUSIC_PATH+TestMediaPlayer.mMusicList.get(TestMediaPlayer.currentListItme));
  71. //
  72. //          mMediaPlayer.create(PlayerService.this,uri);
  73. /* 准备播放 */
  74. mMediaPlayer.prepare();
  75. /* 开始播放 */
  76. mMediaPlayer.start();
  77. /* 是否单曲循环 */
  78. mMediaPlayer.setLooping(isLoop);
  79. // 设置进度条最大值
  80. TestMediaPlayer.audioSeekBar.setMax(PlayerService.mMediaPlayer
  81. .getDuration());
  82. new Thread(this).start();
  83. } catch (IOException e) {
  84. }
  85. }
  86. // 刷新进度条
  87. @Override
  88. public void run() {
  89. int CurrentPosition = 0;// 设置默认进度条当前位置
  90. int total = mMediaPlayer.getDuration();//
  91. while (mMediaPlayer != null && CurrentPosition < total) {
  92. try {
  93. Thread.sleep(1000);
  94. if (mMediaPlayer != null) {
  95. CurrentPosition = mMediaPlayer.getCurrentPosition();
  96. }
  97. } catch (InterruptedException e) {
  98. e.printStackTrace();
  99. }
  100. TestMediaPlayer.audioSeekBar.setProgress(CurrentPosition);
  101. }
  102. }
  103. @Override
  104. public void onCompletion(MediaPlayer mp) {
  105. /* 播放完当前歌曲,自动播放下一首 */
  106. if (++TestMediaPlayer.currentListItme >= TestMediaPlayer.mMusicList
  107. .size()) {
  108. Toast.makeText(PlayerService.this, "已到最后一首歌曲", Toast.LENGTH_SHORT)
  109. .show();
  110. TestMediaPlayer.currentListItme--;
  111. TestMediaPlayer.audioSeekBar.setMax(0);
  112. } else {
  113. playMusic();
  114. }
  115. }
  116. }

参数封装

  1. /**
  2. * @把参数这样封装易于管理和阅读
  3. *
  4. */
  5. public interface AppConstant {
  6. public class PlayerMag{
  7. public static final int PLAY_MAG=1;//开始播放
  8. public static final int PAUSE=2;//暂停播放
  9. }
  10. }

详细代码下载:http://download.csdn.net/source/3318587

android开发之MediaPlayer+Service MP3播放器的更多相关文章

  1. Android开发之Mediaplayer

    Android提供了常见的音频.视频的编码.解码机制.借助于多媒体类MediaPlayer的支持,开发者能够非常方便在在应用中播放音频.视频.本篇博客主要解说在Android平台下怎样播放一个音频文件 ...

  2. Android开发之MediaPlayer和SurfaceView组成视频播放器

    SurfaceView 使用双缓冲技术 是个重量级的组件 只要不可见,就不会创建,可见时,才会创建 只要不可见,就会销毁 SurfaceView一旦不可见,就会被销毁,一旦可见,就会被创建,销毁时停止 ...

  3. Android开发之MediaPlayer类

    官网关于MediaPlayer类的使用简介:

  4. Android开发之AudioManager(音频管理器)具体解释

    AudioManager简单介绍: AudioManager类提供了訪问音量和振铃器mode控制. 使用Context.getSystemService(Context.AUDIO_SERVICE)来 ...

  5. 【Android】利用安卓的数据接口、多媒体处理编写内存卡Mp3播放器app

    通过调用安卓的MediaPlayer能够直接完毕Mp3等主流音频的播放,同一时候利用ContentResolver与Cursor能够直接读取安卓内在数据库的信息.直接获取当前sdcard中全部音频的列 ...

  6. Android开发之bindService()侦听service内部状态

    在Android开发之bindService()通信的基础上,实现bindService()方法侦听service内部状态. 实现侦听service内部状态,使用的是回调机制 1.首先实现一个接口 p ...

  7. Android开发之MdiaPlayer详解

    Android开发之MdiaPlayer详解 MediaPlayer类可用于控制音频/视频文件或流的播放,我曾在<Android开发之基于Service的音乐播放器>一文中介绍过它的使用. ...

  8. Android开发之旅3:android架构

    引言 通过前面两篇: Android 开发之旅:环境搭建及HelloWorld Android 开发之旅:HelloWorld项目的目录结构 我们对android有了个大致的了解,知道如何搭建andr ...

  9. [置顶] Android开发之MediaPlayerService服务详解(一)

    前面一节我们分析了Binder通信相关的两个重要类:ProcessState 和 IPCThreadState.ProcessState负责打开Binder 驱动,每个进程只有一个.而 IPCThre ...

随机推荐

  1. 2017/11/21 Leetcode 日记

    2017/11/21 Leetcode 日记 496. Next Greater Element I You are given two arrays (without duplicates) num ...

  2. Django 如何实现 如下 联表 JOIN 查询?

    SQL语句: select distinct a.device_hash, sum(b.cmn_merge_count) from (select distinct device_hash from ...

  3. Lisp em SCU - 4490 (强大的map用法)

    Time Limit: 1000 MS Memory Limit: 131072 K Description There are two lists and they may be intersect ...

  4. navicat批量导入数据

    1.excel表导入数据 根据数据表添加excel表内容 开始导入数据

  5. 理解面向消息中间件及JMS 以及 ActiveMQ例子

    为了帮助你理解ActiveMQ的意义,了解企业消息传送背景和历史是很重要的.讨论完企业消息传送,你将可以通过一个小例子了解JMS及其使用.这章的目的是简要回顾企业消息传送及JMS规范.如果你已经熟悉这 ...

  6. bzoj1375 双调路径

    Description 来越多,因此选择最佳路径是很现实的问题.城市的道路是双向的,每条道路有固定的旅行时间以及需要支付的费用.路径由连续的道路组成.总时间是各条道路旅行时间的和,总费用是各条道路所支 ...

  7. ACM -- 算法小结(一)利用数组存放实现排序

    利用数组存放实现排序    hodj1425   321MS   2011/08 题意:输入n个数字,要求输出从大到小排序的前m个数 解题技巧:利用大数存储在数组后面,小数存储在前面,倒序输出完成从大 ...

  8. [转]Intel haxm安装失败问题解决

    在安装Intel haxm为安卓模拟器加速时,会遇到提示VT-X未开启问题,问题提示如下图 工具/原料 Intel haxm 安卓模拟器 方法/步骤 1 确认你的处理器是否是Intel的,如果是AMD ...

  9. Codeforces Round #346 (Div. 2) B. Qualifying Contest 水题

    B. Qualifying Contest 题目连接: http://www.codeforces.com/contest/659/problem/B Description Very soon Be ...

  10. 用python slearning类库实现数据挖掘(python3.x)

    Summary of test0 data : source data source code : in test0 file reference : - Reference Website / - ...