本地音乐播放器(三)

mainActivity (ui)代码!
package cn.tedu.music_player_3.ui;

import java.util.List;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import cn.tedu.music_player_3.R;
import cn.tedu.music_player_3.adapter.MusicAdapter;
import cn.tedu.music_player_3.app.MusicPlayerApplication;
import cn.tedu.music_player_3.entity.Music;
import cn.tedu.music_player_3.service.PlayMusicService;
import cn.tedu.music_player_3.util.CommonUtils;
import cn.tedu.music_player_3.util.Consts;

public class MainActivity extends Activity
implements Consts, OnClickListener, OnItemClickListener, OnSeekBarChangeListener {
/**
* ImageButton:播放/暂停
*/
private ImageButton ibPlayOrPause;
/**
* ImageButton:下一首
*/
private ImageButton ibNext;
/**
* ImageButton:上一首
*/
private ImageButton ibPrevious;
/**
* TextView:当前播放的歌曲的标题
*/
private TextView tvMusicTitle;
/**
* TextView:当前播放的歌曲的时长
*/
private TextView tvMusicDuration;
/**
* SeekBar:当前播放进度
*/
private SeekBar sbMusicProgress;
/**
* TextView:当前播放到的时间
*/
private TextView tvMusicCurrentPosition;
/**
* ListView:歌曲列表控件
*/
private ListView lvMusics;
/**
* Application
*/
private MusicPlayerApplication app;
/**
* 数据
*/
private List musics;
/**
* MusicAdapter
*/
private MusicAdapter musicAdapter;
/**
* 广播接收者
*/
private BroadcastReceiver receiver;
/**
* 当前播放的歌曲的索引
*/
private int currentMusicIndex;
/**
* 是否正在拖进度条
*/
private boolean isTrackingTouch;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 激活Service
    Intent intent = new Intent(this, PlayMusicService.class);
    startService(intent);

    // 初始化控件
    setViews();

    // 显示ListView
    showMusicList();

    // 为控件配置监听器
    setListeners();

    // 注册广播接收者
    regBroadcastReceiver();
}

/**
 * 初始化控件
 */
private void setViews() {
    lvMusics = (ListView) findViewById(R.id.lv_musics);
    ibPlayOrPause = (ImageButton) findViewById(R.id.ib_play_or_pause);
    ibPrevious = (ImageButton) findViewById(R.id.ib_previous);
    ibNext = (ImageButton) findViewById(R.id.ib_next);
    tvMusicTitle = (TextView) findViewById(R.id.tv_music_title);
    tvMusicDuration = (TextView) findViewById(R.id.tv_music_duration);
    sbMusicProgress = (SeekBar) findViewById(R.id.sb_music_progress);
    tvMusicCurrentPosition = (TextView) findViewById(R.id.tv_music_current_position);
}

/**
 * 显示ListView
 */
private void showMusicList() {
    app = (MusicPlayerApplication) getApplication();
    musics = app.getMusics();
    musicAdapter = new MusicAdapter(this, musics);
    lvMusics.setAdapter(musicAdapter);
}

/**
 * 配置监听器
 */
private void setListeners() {
    ibPlayOrPause.setOnClickListener(this);
    ibPrevious.setOnClickListener(this);
    ibNext.setOnClickListener(this);

    lvMusics.setOnItemClickListener(this);

    sbMusicProgress.setOnSeekBarChangeListener(this);
}

/**
 * 注册广播接收者
 */
private void regBroadcastReceiver() {
    receiver = new InnerReceiver();
    IntentFilter filter = new IntentFilter();
    filter.addAction(ACTION_SET_AS_PAUSE_STATE);
    filter.addAction(ACTION_SET_AS_PLAY_STATE);
    filter.addAction(ACTION_UPDATE_PROGRESS);
    registerReceiver(receiver, filter);
}

/**
 * Intent:用于表示广播中发送的信息
 */
private Intent broadcastIntent = new Intent();

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.ib_play_or_pause:
        // 发送广播到Service:播放或暂停
        broadcastIntent.setAction(ACTION_PLAY_OR_PAUSE);
        sendBroadcast(broadcastIntent);
        break;

    case R.id.ib_previous:
        // 发送广播到Service:播放上一首
        broadcastIntent.setAction(ACTION_PREVIOUS);
        sendBroadcast(broadcastIntent);
        break;

    case R.id.ib_next:
        // 发送广播到Service:播放下一首
        broadcastIntent.setAction(ACTION_NEXT);
        sendBroadcast(broadcastIntent);
        break;
    }
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    // 发送广播到Service:播放指定的歌曲
    broadcastIntent.setAction(ACTION_PLAY_POSITION);
    broadcastIntent.putExtra(EXTRA_MUSIC_INDEX, position);
    sendBroadcast(broadcastIntent);
}

private class InnerReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // 获取广播中的Action
        String action = intent.getAction();
        // 判断Action
        if (ACTION_SET_AS_PAUSE_STATE.equals(action)) {
            // -- 操作:设置为暂停状态 --
            // 将按钮设置为“播放”
            ibPlayOrPause.setImageResource(android.R.drawable.ic_media_play);
        } else if (ACTION_SET_AS_PLAY_STATE.equals(action)) {
            // -- 操作:设置为播放状态 --
            // 将按钮设置为“暂停”
            ibPlayOrPause.setImageResource(android.R.drawable.ic_media_pause);
            // 获取当前正在播放的歌曲的索引
            currentMusicIndex = intent.getIntExtra(EXTRA_MUSIC_INDEX, 0);
            // 设置显示歌曲的标题
            tvMusicTitle.setText("正在播放:" + musics.get(currentMusicIndex).getName());
            // 设置显示歌曲的时长
            tvMusicDuration.setText(CommonUtils.getFormattedTime(musics.get(currentMusicIndex).getDuration()));
        } else if (ACTION_UPDATE_PROGRESS.equals(action)) {
            // -- 更新进度 --
            // 获取当前播放到的位置
            int currentPosition = intent.getIntExtra(EXTRA_CURRENT_POSITION, 0);
            // 需要更新到的进度值
            int progress = currentPosition * 100 / musics.get(currentMusicIndex).getDuration();
            // 判断用户是否正在拖进度条,如果在拖,则不更新SeekBar
            if (!isTrackingTouch) {
                // 更新SeekBar:当前播放到的进度
                sbMusicProgress.setProgress(progress);
            }
            // 更新TextView:当前播放到的时间
            tvMusicCurrentPosition.setText(CommonUtils.getFormattedTime(currentPosition));
        }
    }
}

@Override
protected void onDestroy() {
    // 取消注册广播接收者
    if (receiver != null) {
        unregisterReceiver(receiver);
        receiver = null;
    }

    super.onDestroy();
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
    // 标识:开始拖进度
    isTrackingTouch = true;
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
    // 标识:已停止拖进度
    isTrackingTouch = false;
    // 发送广播到Service:从指定的进度开始播放
    broadcastIntent.setAction(ACTION_PLAY_FROM_PROGRESS);
    broadcastIntent.putExtra(EXTRA_PROGRESS, sbMusicProgress.getProgress());
    sendBroadcast(broadcastIntent);
}

@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
/**
 * 当按下回退键时,不finish此activity,将其隐藏到后台,只有点击notification中的关闭按钮时才会关闭此activity
 */
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode==KeyEvent.KEYCODE_BACK){
        moveTaskToBack(false);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

}

自定义Baseadater代码;
package cn.tedu.music_player_3.adapter;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;

public abstract class BaseAdapter
extends android.widget.BaseAdapter {
private Context context;
private List data;
private LayoutInflater inflater;

public BaseAdapter(Context context, List<T> data) {
    super();
    setContext(context);
    setData(data);
    setLayoutInflater();
}

public void setContext(Context context) {
    if(context == null) {
        throw new IllegalArgumentException("参数Context不允许为null!!!");
    }
    this.context = context;
}

public Context getContext() {
    return this.context;
}

public void setData(List<T> data) {
    if(data == null) {
        data = new ArrayList<T>();
    }
    this.data = data;
}

public List<T> getData() {
    return this.data;
}

public void setLayoutInflater() {
    inflater = LayoutInflater.from(this.context);
}

public LayoutInflater getLayoutInflater() {
    return this.inflater;
}

@Override
public int getCount() {
    return data.size();
}

@Override
public Object getItem(int position) {
    return null;
}

@Override
public long getItemId(int position) {
    return 0;
}

}

Musciadapter 代码!

package cn.tedu.music_player_3.adapter;

import java.util.List;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import cn.tedu.music_player_3.R;
import cn.tedu.music_player_3.entity.Music;
import cn.tedu.music_player_3.util.CommonUtils;

public class MusicAdapter extends BaseAdapter {

public MusicAdapter(Context context, List<Music> data) {
    super(context, data);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    Music music = getData().get(position);

    ViewHolder holder;
    if(convertView == null) {
        convertView = getLayoutInflater().inflate(R.layout.music_item, null);
        holder = new ViewHolder();
        holder.tvName = (TextView) convertView.findViewById(R.id.tv_music_item_name);
        holder.tvDuration = (TextView) convertView.findViewById(R.id.tv_music_item_duration);
        holder.tvArtist = (TextView) convertView.findViewById(R.id.tv_music_item_artist);
        holder.tvAlbum = (TextView) convertView.findViewById(R.id.tv_music_item_album);
        holder.ivImage = (ImageView) convertView.findViewById(R.id.iv_music_item_image);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    holder.tvName.setText(music.getName());
    holder.tvArtist.setText(music.getArtist());
    holder.tvAlbum.setText(music.getAlbum());
    holder.tvDuration.setText(CommonUtils.getFormattedTime(music.getDuration()));

    if(music.getAlbumArt() == null) {
        holder.ivImage.setImageResource(R.drawable.ic_launcher);
    } else {
        Bitmap bm = BitmapFactory.decodeFile(music.getAlbumArt());
        holder.ivImage.setImageBitmap(bm);
    }

    return convertView;
}

class ViewHolder {
    TextView tvName;
    TextView tvDuration;
    TextView tvArtist;
    TextView tvAlbum;
    ImageView ivImage;
}

}

MusicAplayerAppliction 代码:

package cn.tedu.music_player_3.adapter;

import java.util.List;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import cn.tedu.music_player_3.R;
import cn.tedu.music_player_3.entity.Music;
import cn.tedu.music_player_3.util.CommonUtils;

public class MusicAdapter extends BaseAdapter {

public MusicAdapter(Context context, List<Music> data) {
    super(context, data);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    Music music = getData().get(position);

    ViewHolder holder;
    if(convertView == null) {
        convertView = getLayoutInflater().inflate(R.layout.music_item, null);
        holder = new ViewHolder();
        holder.tvName = (TextView) convertView.findViewById(R.id.tv_music_item_name);
        holder.tvDuration = (TextView) convertView.findViewById(R.id.tv_music_item_duration);
        holder.tvArtist = (TextView) convertView.findViewById(R.id.tv_music_item_artist);
        holder.tvAlbum = (TextView) convertView.findViewById(R.id.tv_music_item_album);
        holder.ivImage = (ImageView) convertView.findViewById(R.id.iv_music_item_image);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    holder.tvName.setText(music.getName());
    holder.tvArtist.setText(music.getArtist());
    holder.tvAlbum.setText(music.getAlbum());
    holder.tvDuration.setText(CommonUtils.getFormattedTime(music.getDuration()));

    if(music.getAlbumArt() == null) {
        holder.ivImage.setImageResource(R.drawable.ic_launcher);
    } else {
        Bitmap bm = BitmapFactory.decodeFile(music.getAlbumArt());
        holder.ivImage.setImageBitmap(bm);
    }

    return convertView;
}

class ViewHolder {
    TextView tvName;
    TextView tvDuration;
    TextView tvArtist;
    TextView tvAlbum;
    ImageView ivImage;
}

}

IDao 代码;
package cn.tedu.music_player_3.dal;

import java.util.List;

public interface IDao {
/**
* 获取数据
*
* @return 数据的List集合
*/
List getData();
}

MediaStoreMusicDao 类代码

package cn.tedu.music_player_3.dal;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;
import cn.tedu.music_player_3.entity.Music;

class MediaStoreMusicDao implements IDao {
private Context context;

public MediaStoreMusicDao(Context context) {
    super();
    this.context = context;
}

@Override
public List<Music> getData() {
    // 1. 准备初始条件
    // 1.1. 声明返回值
    List<Music> musics = new ArrayList<Music>();
    // 1.2. 准备ContentResolver
    ContentResolver cr = context.getContentResolver();
    // 1.3. 准备Uri
    Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;

    // 2. 执行业务
    // 2.1. 执行查询,获取Cursor
    String[] projection = {
        "_id", // 0
        "title", // 1
        "_data", // 2
        "_size", // 3
        "duration", // 4
        "album", // 5
        "artist", // 6
        "album_artist", // 7
        "album_key" // 8
    };
    Cursor c = cr.query(uri, projection, null, null, null);
    // 2.2. 遍历Cursor,读取每一首歌曲信息,创建为Music对象,并添加到List集合中
    if(c != null) {
        if(c.moveToFirst()) {
            Log.i("tedu", "读取歌曲信息... ...");
            for(; !c.isAfterLast(); c.moveToNext()) {
                Music music = new Music();
                music.setId(c.getLong(0));
                music.setName(c.getString(1));
                music.setPath(c.getString(2));
                music.setSize(c.getInt(3));
                music.setDuration(c.getInt(4));
                music.setAlbum(c.getString(5));
                music.setArtist(c.getString(6));
                music.setAlbumArtist(c.getString(7));
                music.setAlbumKey(c.getString(8));
                music.setAlbumArt(getAlbumArtByKey(music.getAlbumKey()));
                Log.d("tedu", "" + music);
                musics.add(music);
            }
            Log.i("tedu", "读取歌曲信息完成!");
        }
        // 2.3. 释放相关资源
        c.close();
        c = null;
    }

    // 3. 返回结果
    return musics;
}

/**
 * 根据album_key获取album_art
 * @param albumKey
 * @return album_art字段的值,即歌曲内置图片的路径,该返回值可能为null
 */
private String getAlbumArtByKey(String albumKey) {
    // 判断参数是否有效
    if(albumKey == null) {
        return null;
    }

    // 声明返回值
    String albumArt = null;
    // 准备ContentResolver
    ContentResolver cr = context.getContentResolver();
    // 准备Uri
    Uri uri = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI;

    // 执行查询
    String[] projection = { "album_art" };
    String selection = "album_key=?";
    String[] selectionArgs = { albumKey };
    Cursor c = cr.query(uri, projection, selection, selectionArgs, null);

    // 处理数据
    if(c != null) {
        if(c.moveToFirst()) {
            albumArt = c.getString(0);
        }
        // 释放资源
        c.close();
        c = null;
    }

    // 返回
    return albumArt;
}

}

MusicDaoFactory 类
package cn.tedu.music_player_3.dal;

import android.content.Context;
import cn.tedu.music_player_3.entity.Music;

public class MusicDaoFactory {
private MusicDaoFactory() {
super();
}

public static IDao<Music> newInstance(Context context) {
    return new MediaStoreMusicDao(context);
}

}

SDCardMusicDao类代码:
package cn.tedu.music_player_3.dal;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import android.os.Environment;
import android.util.Log;
import cn.tedu.music_player_3.entity.Music;

/**
* 歌曲数据的访问类
* @author chengheng
* @version 2.0
*/
public class SDCardMusicDao implements IDao {
/**
* 扫描sdcard中Music下所有.mp3文件
* @return 扫描到的Music对象的List集合,该返回值永不为null
*/
@Override
public List getData() {
// 准备返回值
List musics = new ArrayList();

    // 扫描sdcard中Music下所有.mp3文件
    if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
        File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
        if (dir.exists()) {
            File[] files = dir.listFiles();
            if (files != null && files.length > 0) {
                for (int i = 0; i < files.length; i++) {
                    if (files[i].isFile()) {
                        if (files[i].getName().toLowerCase(Locale.CHINA).endsWith(".mp3")) {
                            Music music = new Music();
                            music.setPath(files[i].getAbsolutePath());
                            music.setName(files[i].getName().substring(0, files[i].getName().length() - 4));
                            Log.v("tedu", "" + music);
                            musics.add(music);
                        }
                    }
                }
            } else {
                Log.w("tedu", "Music文件夹下没有有效的文件!");
            }
        } else {
            Log.w("tedu", "sdcard下Music文件夹不存在!无法扫描到歌曲!");
        }
    } else {
        Log.w("tedu", "sdcard没有正确挂载!无法访问!");
    }

    // 返回
    return musics;
}

}

实体类 Music 代码:

package cn.tedu.music_player_3.entity;

public class Music {

private long id;
private String name;
private String path;
private int size;
private int duration;
private String album;
private String artist;
private String albumArtist;
private String albumKey;
private String albumArt;

public long getId() {
    return id;
}

public void setId(long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getPath() {
    return path;
}

public void setPath(String path) {
    this.path = path;
}

public int getSize() {
    return size;
}

public void setSize(int size) {
    this.size = size;
}

public int getDuration() {
    return duration;
}

public void setDuration(int duration) {
    this.duration = duration;
}

public String getAlbum() {
    return album;
}

public void setAlbum(String album) {
    this.album = album;
}

public String getArtist() {
    return artist;
}

public void setArtist(String artist) {
    this.artist = artist;
}

public String getAlbumArtist() {
    return albumArtist;
}

public void setAlbumArtist(String albumArtist) {
    this.albumArtist = albumArtist;
}

public String getAlbumKey() {
    return albumKey;
}

public void setAlbumKey(String albumKey) {
    this.albumKey = albumKey;
}

public String getAlbumArt() {
    return albumArt;
}

public void setAlbumArt(String albumArt) {
    this.albumArt = albumArt;
}

@Override
public String toString() {
    return "Music [id=" + id + ", name=" + name + ", path=" + path + ", size=" + size + ", duration=" + duration
            + ", album=" + album + ", artist=" + artist + ", albumArtist=" + albumArtist + ", albumKey=" + albumKey
            + ", albumArt=" + albumArt + "]";
}

}

PlayMusicService 类代码:

package cn.tedu.music_player_3.service;

import java.io.IOException;
import java.util.List;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.IBinder;
import cn.tedu.music_player_3.app.MusicPlayerApplication;
import cn.tedu.music_player_3.entity.Music;
import cn.tedu.music_player_3.util.Consts;

public class PlayMusicService extends Service implements Consts {
/**
* 广播接收者
*/
private BroadcastReceiver receiver;
/**
* MediaPlayer
*/
private MediaPlayer player;
/**
* 歌曲数据的List集合
*/
private List musics;
/**
* Application
*/
private MusicPlayerApplication app;
/**
* 当前播放的歌曲的索引
*/
private int currentMusicIndex;
/**
* 暂停时的播放位置
*/
private int pausePosition;
/**
* Intent:用于表示广播中发送的信息
*/
private Intent broadcastIntent = new Intent();
/**
* 更新进度的线程
*/
private UpdateProgressThread updateProgressThread;

@Override
public void onCreate() {
    // 获取歌曲数据
    app = (MusicPlayerApplication) getApplication();
    musics = app.getMusics();

    // 初始化播放器
    player = new MediaPlayer();

    // 为MediaPlayer配置监听器
    player.setOnCompletionListener(new OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            next();
        }
    });

    // 注册广播接收者
    receiver = new InnerReceiver();
    IntentFilter filter = new IntentFilter();
    filter.addAction(ACTION_PLAY_OR_PAUSE);
    filter.addAction(ACTION_PREVIOUS);
    filter.addAction(ACTION_NEXT);
    filter.addAction(ACTION_PLAY_POSITION);
    filter.addAction(ACTION_PLAY_FROM_PROGRESS);
    registerReceiver(receiver, filter);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // 设置当前Service为非粘性的
    return START_NOT_STICKY;
}

@Override
public void onDestroy() {
    // 解除注册广播接收者
    if (receiver != null) {
        unregisterReceiver(receiver);
        receiver = null;
    }
    // 停止线程
    stopUpdateProgressThread();
    // 释放播放器资源
    if (player != null) {
        player.release();
        player = null;
    }
}

/**
 * 开启更新进度(发送广播让Activity更新)的线程
 */
private void startUpdateProgressThread() {
    if (updateProgressThread == null) {
        updateProgressThread = new UpdateProgressThread();
        updateProgressThread.setRunning(true);
        updateProgressThread.start();
    }
}

/**
 * 停止更新进度(发送广播让Activity更新)的线程
 */
private void stopUpdateProgressThread() {
    if (updateProgressThread != null) {
        updateProgressThread.setRunning(false);
        updateProgressThread = null;
    }
}

private class UpdateProgressThread extends Thread {
    private boolean isRunning;

    public void setRunning(boolean isRunning) {
        this.isRunning = isRunning;
    }

    @Override
    public void run() {
        while (isRunning) {
            if (player.isPlaying()) {
                // 发出广播:使Activity更新播放进度
                broadcastIntent.setAction(ACTION_UPDATE_PROGRESS);
                broadcastIntent.putExtra(EXTRA_CURRENT_POSITION, player.getCurrentPosition());
                sendBroadcast(broadcastIntent);
            }

            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

private class InnerReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // 获取广播的Action
        String action = intent.getAction();
        // 判断Action
        if (ACTION_PLAY_OR_PAUSE.equals(action)) {
            // -- 播放或暂停 --
            // 判断播放状态
            if (player.isPlaying()) {
                // 正在播放,则暂停
                pause();
            } else {
                // 没有播放,则播放
                play();
            }
        } else if (ACTION_PREVIOUS.equals(action)) {
            // 播放上一首
            previous();
        } else if (ACTION_NEXT.equals(action)) {
            // 播放下一首
            next();
        } else if (ACTION_PLAY_POSITION.equals(action)) {
            // 获取歌曲的position
            int position = intent.getIntExtra(EXTRA_MUSIC_INDEX, 0);
            // 播放指定的歌曲
            play(position);
        } else if(ACTION_PLAY_FROM_PROGRESS.equals(action)) {
            // 获取进度
            int progress = intent.getIntExtra(EXTRA_PROGRESS, 0);
            // 从指定的进度开始播放
            playFromProgress(progress);
        }
    }
}

/**
 * 播放歌曲
 */
private void play() {
    try {
        player.reset();
        player.setDataSource(musics.get(currentMusicIndex).getPath());
        player.prepare();
        player.seekTo(pausePosition);
        player.start();

        // 发出广播:使Activity将界面设置为播放状态
        broadcastIntent.setAction(ACTION_SET_AS_PLAY_STATE);
        broadcastIntent.putExtra(EXTRA_MUSIC_INDEX, currentMusicIndex);
        sendBroadcast(broadcastIntent);

        // 开启线程
        startUpdateProgressThread();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

/**
 * 播放指定的歌曲
 * 
 * @param position
 *            歌曲的索引位置
 */
private void play(int position) {
    currentMusicIndex = position;
    pausePosition = 0;
    play();
}

/**
 * 从指定的进度开始播放歌曲
 * @param progress 进度值
 */
private void playFromProgress(int progress) {
    // 设置播放的起点位置
    pausePosition = musics.get(currentMusicIndex).getDuration() * progress / 100;
    // 播放
    play();
}

/**
 * 暂停
 */
private void pause() {
    player.pause();
    pausePosition = player.getCurrentPosition();

    // 发出广播:使Activity将界面设置为暂停状态
    broadcastIntent.setAction(ACTION_SET_AS_PAUSE_STATE);
    sendBroadcast(broadcastIntent);

    // 停止线程
    stopUpdateProgressThread();
}

/**
 * 播放上一首
 */
private void previous() {
    currentMusicIndex--;
    if (currentMusicIndex < 0) {
        currentMusicIndex = musics.size() - 1;
    }
    pausePosition = 0;
    play();
}

/**
 * 播放下一首
 */
private void next() {
    currentMusicIndex++;
    if (currentMusicIndex >= musics.size()) {
        currentMusicIndex = 0;
    }
    pausePosition = 0;
    play();
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

}

工具类 CommonUtils代码
package cn.tedu.music_player_3.util;

import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Locale;
/**
* 通用工具类
*/
public class CommonUtils {
/**
* 格式化时间的工具
*/
private static SimpleDateFormat sdf = new SimpleDateFormat(“mm:ss”, Locale.CHINA);
/**
* 被格式化的时间对象
*/
private static Date date = new Date();

/**
 * 获取格式化后的时间
 * 
 * @param timeMillis
 *            时间值,取值为从1970-1-1 0:00:00至今的毫秒数
 * @return 格式化为mm:ss格式的字符串
 */
public static String getFormattedTime(long timeMillis) {
    // 设置时间
    date.setTime(timeMillis);
    // 返回格式化后的结果
    return sdf.format(date);
}

}

工具类Consts代码:
package cn.tedu.music_player_3.util;

public interface Consts {

String ACTION_PLAY_OR_PAUSE = "cn.tedu.intent.action.PLAY_OR_PAUSE";
String ACTION_PREVIOUS = "cn.tedu.intent.action.PREVIOUS";
String ACTION_NEXT = "cn.tedu.intent.action.NEXT";
String ACTION_PLAY_POSITION = "cn.tedu.intent.action.PLAY_POSITION";
String ACTION_PLAY_FROM_PROGRESS = "cn.tedu.intent.action.PLAY_FROM_PROGRESS";
String ACTION_SET_AS_PLAY_STATE = "cn.tedu.intent.action.SET_AS_PLAY_STATE";
String ACTION_SET_AS_PAUSE_STATE = "cn.tedu.intent.action.SET_AS_PAUSE_STATE";
String ACTION_UPDATE_PROGRESS = "cn.tedu.intent.action.UPDATE_PROGRESS";

/**
 * 歌曲的索引
 */
String EXTRA_MUSIC_INDEX = "position";
/**
 * 当前播放到的位置
 */
String EXTRA_CURRENT_POSITION = "current_position";
/**
 * 从多少进度开始播放
 */
String EXTRA_PROGRESS = "progress";

}

Activit_main.xml 代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值