android开发之MediaPlayer+Service MP3播放器
- import java.io.File;
- import java.io.FilenameFilter;
- import java.util.ArrayList;
- import java.util.List;
- import android.app.ListActivity;
- import android.apps.service.PlayerService;
- import android.content.Intent;
- import android.media.AudioManager;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.ArrayAdapter;
- import android.widget.Button;
- import android.widget.SeekBar;
- import android.widget.Toast;
- public class TestMediaPlayer extends ListActivity {
- /* 前段时间刚学习Android时就觉得MediaPlayer是个很神奇的东西,就试着做了个简单的音乐播放器。
- * 支持后台播放、进度条拖放、音量控制、读取sdCard音乐文件进行播放等。
- * */
- private Button playButton = null;
- private Button mFrontButton = null;
- private Button mLastButton = null;
- private Button exit = null;
- /* 声明音量管理器 */
- private AudioManager mAudioManager = null;
- /* 定义进度条 */
- public static SeekBar audioSeekBar = null;
- /* 定义音量大小 */
- private SeekBar audioVolume = null;
- /* 定于一个数据播放列表,用来存放从指定文件中搜索到的文件 */
- public static List<String> mMusicList = new ArrayList<String>();
- /* 定义音乐存放路径 */
- // private static final String MUSIC_PATH = new String("/mnt/sdcard/"); //android 2.2
- private static final String MUSIC_PATH = new String("/sdcard/");//android 2.1
- /* 定义在播放列表中的当前选择项 */
- public static int currentListItme = 0;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- /* 更新列表 */
- musicList();
- /* 得到控件 */
- playButton = (Button) findViewById(R.id.StartMusic);
- mFrontButton = (Button) findViewById(R.id.FrontButton);
- mLastButton = (Button) findViewById(R.id.LastMusic);
- audioVolume = (SeekBar) findViewById(R.id.audioVolume);
- exit = (Button)findViewById(R.id.exit);
- audioSeekBar = (SeekBar) findViewById(R.id.seekbar01);
- /* 播放、暂停监听 */
- playButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- playMusic(AppConstant.PlayerMag.PAUSE);
- }
- });
- /* 监听下一首 */
- mFrontButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- nextMusic();
- }
- });
- /* 监听上一首 */
- mLastButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- FrontMusic();
- }
- });
- /*退出监听*/
- exit.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent();
- intent.setClass(TestMediaPlayer.this, PlayerService.class);
- stopService(intent);//停止Service
- try {
- TestMediaPlayer.this.finish();//关闭当前Activity
- } catch (Throwable e) {
- e.printStackTrace();
- }
- }
- });
- /* 播放进度监听 */
- audioSeekBar.setOnSeekBarChangeListener(new SeekBarChangeEvent());
- /*退出后再次进去程序时,进度条保持持续更新*/
- if(PlayerService.mMediaPlayer!=null){
- //设置进度条最大值
- TestMediaPlayer.audioSeekBar.setMax(PlayerService.mMediaPlayer.getDuration());
- audioSeekBar.setProgress(PlayerService.mMediaPlayer.getCurrentPosition());
- }
- /* 得到当前音量对象 */
- mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
- /* 把当前音量值赋给进度条 */
- audioVolume.setProgress(mAudioManager
- .getStreamVolume(AudioManager.STREAM_MUSIC));
- /* 监听音量 */
- audioVolume.setOnSeekBarChangeListener(new AudioVolumeChangeEvent());
- }
- public void playMusic(int action) {
- Intent intent = new Intent();
- intent.putExtra("MSG", action);
- intent.setClass(TestMediaPlayer.this, PlayerService.class);
- /* 启动service service要在AndroidManifest.xml注册如:<service></service>*/
- startService(intent);
- }
- /* 检测sdcard MP3文件并加入到List列表 */
- public void musicList() {
- // 先清除list中的缓存
- mMusicList.clear();
- /* 从指定的路径中读取文件,并与播放列表关联 */
- File home = new File(MUSIC_PATH);
- System.out.println(home.canRead());
- /* 读取指定类型的文件,在本程序,指定播放类型为mp3 */
- if (home.listFiles(new MusicFilter()).length > 0) {
- /* 读取文件 */
- for (File file : home.listFiles(new MusicFilter())) {
- mMusicList.add(file.getName());
- }
- /* 播放文件与播放列表关联 */
- ArrayAdapter<String> musicList = new ArrayAdapter<String>(
- TestMediaPlayer.this, R.layout.musictime, mMusicList);
- setListAdapter(musicList);
- }
- }
- /* 音量监听 */
- class AudioVolumeChangeEvent implements SeekBar.OnSeekBarChangeListener {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress,
- boolean fromUser) {
- // mAudioManager.adjustVolume(AudioManager.ADJUST_LOWER, 0);
- mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress,
- 0);
- }
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- }
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- }
- }
- /* 音乐选择监听 */
- @Override
- protected void onListItemClick(android.widget.ListView l, View v,
- int position, long id) {
- super.onListItemClick(l, v, position, id);
- currentListItme = position;
- playMusic(AppConstant.PlayerMag.PLAY_MAG);
- }
- /* 播放下一首 */
- private void nextMusic() {
- if (++currentListItme >= mMusicList.size()) {
- Toast.makeText(TestMediaPlayer.this, "已到最后一首歌曲", Toast.LENGTH_SHORT)
- .show();
- currentListItme = mMusicList.size() - 1;
- } else {
- playMusic(AppConstant.PlayerMag.PLAY_MAG);
- }
- }
- /* 播放上一首歌曲 */
- private void FrontMusic() {
- if (--currentListItme >= 0) {
- playMusic(AppConstant.PlayerMag.PLAY_MAG);
- } else {
- Toast.makeText(TestMediaPlayer.this, "已到第一首歌曲", Toast.LENGTH_SHORT)
- .show();
- currentListItme = 0;
- }
- }
- }
- /* 播放文件选择类 */
- class MusicFilter implements FilenameFilter {
- public boolean accept(File dir, String name) {
- /* 指定扩展名类型 ,可以加其他的音乐格式*/
- return (name.endsWith(".mp3"));
- }
- }
- /* 拖放进度监听 ,别忘了Service里面还有个进度条刷新*/
- class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress,
- boolean fromUser) {
- /*假设改变源于用户拖动*/
- if (fromUser) {
- PlayerService.mMediaPlayer.seekTo(progress);// 当进度条的值改变时,音乐播放器从新的位置开始播放
- }
- }
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- PlayerService.mMediaPlayer.pause(); // 开始拖动进度条时,音乐暂停播放
- }
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- PlayerService.mMediaPlayer.start(); // 停止拖动进度条时,音乐开始播放
- }
- }
service类
首先建议不要把播放音乐放在Activity中,因为关闭Activity后就不能实现后台播放。所以播放音乐要放在Service中,我们只需要管理Activity与Service间的通信就好了。下面就是个Service类。直接看注释和代码:
- package android.apps.service;
- import java.io.IOException;
- import android.app.Service;
- import android.content.Intent;
- import android.media.MediaPlayer;
- import android.net.Uri;
- import android.os.IBinder;
- import android.widget.Toast;
- import android.apps.*;
- public class PlayerService extends Service implements Runnable,
- MediaPlayer.OnCompletionListener {
- /* 定于一个多媒体对象 */
- public static MediaPlayer mMediaPlayer = null;
- // 是否单曲循环
- private static boolean isLoop = false;
- // 用户操作
- private int MSG;
- /* 定义要播放的文件夹路径 */
- private static final String MUSIC_PATH = new String("/sdcard/");
- @Override
- public IBinder onBind(Intent intent) {
- return null;// 这里的绑定没的用,上篇我贴出了如何将activity与service绑定的代码
- }
- @Override
- public void onCreate() {
- super.onCreate();
- if (mMediaPlayer != null) {
- mMediaPlayer.reset();
- mMediaPlayer.release();
- mMediaPlayer = null;
- }
- mMediaPlayer = new MediaPlayer();
- /* 监听播放是否完成 */
- mMediaPlayer.setOnCompletionListener(this);
- }
- @Override
- public void onDestroy() {
- super.onDestroy();
- if (mMediaPlayer != null) {
- mMediaPlayer.stop();
- mMediaPlayer.release();
- mMediaPlayer = null;
- }
- System.out.println("service onDestroy");
- }
- /*启动service时执行的方法*/
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- /*得到从startService传来的动作,后是默认参数,这里是我自定义的常量*/
- MSG = intent.getIntExtra("MSG", AppConstant.PlayerMag.PLAY_MAG);
- if (MSG == AppConstant.PlayerMag.PLAY_MAG) {
- playMusic();
- }
- if (MSG == AppConstant.PlayerMag.PAUSE) {
- if (mMediaPlayer.isPlaying()) {// 正在播放
- mMediaPlayer.pause();// 暂停
- } else {// 没有播放
- mMediaPlayer.start();
- }
- }
- return super.onStartCommand(intent, flags, startId);
- }
- @SuppressWarnings("static-access")
- public void playMusic() {
- try {
- /* 重置多媒体 */
- mMediaPlayer.reset();
- /* 读取mp3文件 */
- mMediaPlayer.setDataSource(MUSIC_PATH+TestMediaPlayer.mMusicList.get(TestMediaPlayer.currentListItme));
- // Uri uri = Uri.parse(MUSIC_PATH+TestMediaPlayer.mMusicList.get(TestMediaPlayer.currentListItme));
- //
- // mMediaPlayer.create(PlayerService.this,uri);
- /* 准备播放 */
- mMediaPlayer.prepare();
- /* 开始播放 */
- mMediaPlayer.start();
- /* 是否单曲循环 */
- mMediaPlayer.setLooping(isLoop);
- // 设置进度条最大值
- TestMediaPlayer.audioSeekBar.setMax(PlayerService.mMediaPlayer
- .getDuration());
- new Thread(this).start();
- } catch (IOException e) {
- }
- }
- // 刷新进度条
- @Override
- public void run() {
- int CurrentPosition = 0;// 设置默认进度条当前位置
- int total = mMediaPlayer.getDuration();//
- while (mMediaPlayer != null && CurrentPosition < total) {
- try {
- Thread.sleep(1000);
- if (mMediaPlayer != null) {
- CurrentPosition = mMediaPlayer.getCurrentPosition();
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- TestMediaPlayer.audioSeekBar.setProgress(CurrentPosition);
- }
- }
- @Override
- public void onCompletion(MediaPlayer mp) {
- /* 播放完当前歌曲,自动播放下一首 */
- if (++TestMediaPlayer.currentListItme >= TestMediaPlayer.mMusicList
- .size()) {
- Toast.makeText(PlayerService.this, "已到最后一首歌曲", Toast.LENGTH_SHORT)
- .show();
- TestMediaPlayer.currentListItme--;
- TestMediaPlayer.audioSeekBar.setMax(0);
- } else {
- playMusic();
- }
- }
- }
参数封装
- /**
- * @把参数这样封装易于管理和阅读
- *
- */
- public interface AppConstant {
- public class PlayerMag{
- public static final int PLAY_MAG=1;//开始播放
- public static final int PAUSE=2;//暂停播放
- }
- }
详细代码下载:http://download.csdn.net/source/3318587
android开发之MediaPlayer+Service MP3播放器的更多相关文章
- Android开发之Mediaplayer
Android提供了常见的音频.视频的编码.解码机制.借助于多媒体类MediaPlayer的支持,开发者能够非常方便在在应用中播放音频.视频.本篇博客主要解说在Android平台下怎样播放一个音频文件 ...
- Android开发之MediaPlayer和SurfaceView组成视频播放器
SurfaceView 使用双缓冲技术 是个重量级的组件 只要不可见,就不会创建,可见时,才会创建 只要不可见,就会销毁 SurfaceView一旦不可见,就会被销毁,一旦可见,就会被创建,销毁时停止 ...
- Android开发之MediaPlayer类
官网关于MediaPlayer类的使用简介:
- Android开发之AudioManager(音频管理器)具体解释
AudioManager简单介绍: AudioManager类提供了訪问音量和振铃器mode控制. 使用Context.getSystemService(Context.AUDIO_SERVICE)来 ...
- 【Android】利用安卓的数据接口、多媒体处理编写内存卡Mp3播放器app
通过调用安卓的MediaPlayer能够直接完毕Mp3等主流音频的播放,同一时候利用ContentResolver与Cursor能够直接读取安卓内在数据库的信息.直接获取当前sdcard中全部音频的列 ...
- Android开发之bindService()侦听service内部状态
在Android开发之bindService()通信的基础上,实现bindService()方法侦听service内部状态. 实现侦听service内部状态,使用的是回调机制 1.首先实现一个接口 p ...
- Android开发之MdiaPlayer详解
Android开发之MdiaPlayer详解 MediaPlayer类可用于控制音频/视频文件或流的播放,我曾在<Android开发之基于Service的音乐播放器>一文中介绍过它的使用. ...
- Android开发之旅3:android架构
引言 通过前面两篇: Android 开发之旅:环境搭建及HelloWorld Android 开发之旅:HelloWorld项目的目录结构 我们对android有了个大致的了解,知道如何搭建andr ...
- [置顶] Android开发之MediaPlayerService服务详解(一)
前面一节我们分析了Binder通信相关的两个重要类:ProcessState 和 IPCThreadState.ProcessState负责打开Binder 驱动,每个进程只有一个.而 IPCThre ...
随机推荐
- Boolean Expressions POJ - 2106 (表达式求值)
The objective of the program you are going to produce is to evaluate boolean expressions as the one ...
- 【UOJ 34】 #34. 多项式乘法 (FFT)
[分析] 这个只是用来放模板..[其实我还没完全懂的.. 迭代 代替 递归: #include<cstdio> #include<cstdlib> #include<cs ...
- POJ1741 Tree 树分治模板
http://poj.org/problem?id=1741 题意:一棵n个点的树,每条边有距离v,求该树中距离小于等于k的点的对数. dis[y]表示点y到根x的距离,v代表根到子树根的距离 ...
- BZOJ1001: [BeiJing2006]狼抓兔子 (最小割转最短路)
浅析最大最小定理在信息学竞赛中的应用---周东 ↑方法介绍 对于一个联通的平面图G(满足欧拉公式) 在s和t间新连一条边e; 然后建立一个原图的对偶图G*,G*中每一个点对应原图中每一个面,每一条边对 ...
- 【20181027T2】易水决【贪心+堆】
原题:loj6035 [错解] 全肝T1了没怎么想 [正解] 一眼贪心 先考虑\(b_i=0\)怎么做 可以模拟一个正常人的思维 开一个堆,记录每个任务需要的时间(包括等待),每次从中取出一个任务,表 ...
- 【最小表示法】BZOJ1398-寻找朋友
[题目大意] 判断两个字符串是否循环同构. [思路] 我一开始的做法是直接同时在两个字符串上求最小表示法,只有部分测试点能过,理由未知,以后再来思考. 现在做法:分别求出两个字符串的最小表示法,再比较 ...
- [bzoj1021][SHOI2008]Debt 循环的债务 (动态规划)
Description Alice. Bob和Cynthia总是为他们之间混乱的债务而烦恼,终于有一天,他们决定坐下来一起解决这个问题.不过,鉴别钞票的真伪是一件很麻烦的事情,于是他 们决定要在清还债 ...
- bzoj 2038 小z的袜子 莫队例题
莫队,利用可以快速地通过一个问题的答案得到另一问题的答案这一特性,合理地组织问题的求解顺序,将已解决的问题帮助解决当前问题,来优化时间复杂度. 典型用法:处理静态(无修改)离线区间查询问题. 线段树也 ...
- JSON 与 JS 对象的关系
很多人搞不清楚 JSON 和 Js 对象的关系,甚至连谁是谁都不清楚.简单来说: JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串. 如 var obj ...
- Codeforces Round #348 (VK Cup 2016 Round 2, Div. 2 Edition) E. Little Artem and Time Machine 树状数组
E. Little Artem and Time Machine 题目连接: http://www.codeforces.com/contest/669/problem/E Description L ...