本文共 24404 字,大约阅读时间需要 81 分钟。
基于媒体库音乐播放器V1.0 基于媒体库音乐播放器 Version 1.0 泸职院信息系·华卫 默认排序 按标题排序 按时长排序 播放模式: 顺序 单曲循环 随机
package com.zjs.ms_music_player_v01.ui;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.animation.Animation;import android.view.animation.AnimationUtils;import android.widget.ImageView;import com.zjs.ms_music_player_v01.R;/** * 启动界面类 * */public class SplashScreenActivity extends Activity { /** * 动画对象 */ private Animation animation; /** * 音乐图标图像控件 */ private ImageView ivMusicIcon; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 利用布局资源文件设置用户界面 setContentView(R.layout.activity_splash_screen); // 通过资源标识获得控件实例 ivMusicIcon = findViewById(R.id.iv_music_icon); // 加载动画资源文件,创建动画对象 animation = AnimationUtils.loadAnimation(this, R.anim.animator); // 让音乐图标图像控件启动动画 ivMusicIcon.startAnimation(animation); // 给动画对象设置监听器 animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { // 启动主界面 startActivity(new Intent(SplashScreenActivity.this, MainActivity.class)); // 关闭启动界面 finish(); } @Override public void onAnimationRepeat(Animation animation) { } }); }}
package com.zjs.ms_music_player_v01.service;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.os.IBinder;import com.zjs.ms_music_player_v01.R;import com.zjs.ms_music_player_v01.app.AppConstants;import com.zjs.ms_music_player_v01.app.MusicPlayerApplication;import com.zjs.ms_music_player_v01.entity.Music;import java.io.IOException;import java.util.List;import java.util.Random;/** * 音乐服务类 */public class MusicPlayService extends Service implements AppConstants { /** * 媒体播放器 */ private MediaPlayer mp; /** * 音乐列表(数据源) */ private ListmusicList; /** * 音乐文件名 */ private String musicName; /** * 更新音乐播放进度的线程 */ private Thread thread; /** * 线程循环控制变量 */ private boolean isRunning; /** * 音乐播放器应用程序 */ private MusicPlayerApplication app; /** * 音乐广播接收器 */ private MusicReceiver receiver; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); // 获取获得音乐播放器应用程序对象 app = (MusicPlayerApplication) getApplication(); // 获取音乐列表(数据源) musicList = app.getMusicList(); // 创建媒体播放器 mp = new MediaPlayer(); // 给媒体播放器起注册完成监听器 mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { // 切换到下一首音乐 nextMusic(); } }); // 设置线程循环控制变量为真 isRunning = true; // 创建线程更新播放进度 thread = new Thread(new Runnable() { @Override public void run() { while (isRunning) { // 判断音乐是否在播放 if (mp.isPlaying()) { // 设置音乐当前播放位置 app.setCurrentPosition(mp.getCurrentPosition()); // 创建意图 Intent intent = new Intent(); // 设置广播频道:更新播放进度 intent.setAction(INTENT_ACTION_UPDATE_PROGRESS); // 让意图携带播放时长 intent.putExtra(DURATION, mp.getDuration()); // 让意图携带控制图标(暂停图标) intent.putExtra(CONTROL_ICON, R.drawable.pause_button_selector); // 按意图发送广播 sendBroadcast(intent); } // 让线程睡眠500毫秒 try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } }); // 启动线程 thread.start(); // 创建音乐广播接收者 receiver = new MusicReceiver(); // 创建意图过滤器 IntentFilter filter = new IntentFilter(); // 通过意图过滤器添加广播频道 filter.addAction(INTENT_ACTION_PLAY_OR_PAUSE); filter.addAction(INTENT_ACTION_PLAY); filter.addAction(INTENT_ACTION_PREVIOUS); filter.addAction(INTENT_ACTION_NEXT); filter.addAction(INTENT_ACTION_USER_CHANGE_PROGRESS); // 注册广播接收者 registerReceiver(receiver, filter); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // 返回非粘性服务 return Service.START_NOT_STICKY; } /** * 上一首音乐 */ private void previousMusic() { // 更新音乐索引 if (app.getCurrentMusicIndex() > 0) { app.setCurrentMusicIndex(app.getCurrentMusicIndex() - 1); } else { app.setCurrentMusicIndex(musicList.size() - 1); } // 当前播放位置归零 app.setCurrentPosition(0); // 调用播放方法 play(); } /** * 下一首音乐 */ private void nextMusic() { // 根据播放模式来更新音乐索引 switch (app.getPlayMode()) { // 顺序播放模式 case PLAY_MODE_ORDER: if (app.getCurrentMusicIndex() < musicList.size() - 1) { app.setCurrentMusicIndex(app.getCurrentMusicIndex() + 1); } else { app.setCurrentMusicIndex(0); } break; // 随机播放模式 case PLAY_MODE_RANDOM: // 随机设置索引 app.setCurrentMusicIndex(new Random().nextInt(app.getMusicList().size())); break; // 单曲循环模式 case PLAY_MODE_LOOP: // 音乐索引保持不变 break; } // 当前播放位置归零 app.setCurrentPosition(0); // 调用播放方法 play(); } /** * 播放方法 */ private void play() { try { // 重置播放器 mp.reset(); // 获取当前播放的音乐名 musicName = musicList.get(app.getCurrentMusicIndex()).getData(); // 设置播放源 mp.setDataSource(musicName); // 缓冲播放源,加载到内存 mp.prepare(); // 定位到暂停时的播放位置 mp.seekTo(app.getCurrentPosition()); // 启动音乐的播放 mp.start(); } catch (IOException e) { e.printStackTrace(); } } /** * 暂停方法 */ private void pause() { // 暂停播放 mp.pause(); // 保存当前音乐播放位置 app.setCurrentPosition(mp.getCurrentPosition()); /* 发送广播给前台MainActivity,更改图标、更改播放进度 */ // 创建意图 Intent intent = new Intent(); // 设置广播频道:更新播放进度 intent.setAction(INTENT_ACTION_UPDATE_PROGRESS); // 让意图携带播放时长 intent.putExtra(DURATION, mp.getDuration()); // 让意图携带控制图标(播放图标) intent.putExtra(CONTROL_ICON, R.drawable.play_button_selector); // 按意图发送广播 sendBroadcast(intent); } /** * 音乐广播接收者 */ private class MusicReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // 获取意图动作(广播频道) String action = intent.getAction(); // 当广播频道非空时进行判断 if (action != null) { // 根据不同广播频道执行不同的操作 switch (action) { case INTENT_ACTION_PLAY: // 播放进度值归零 app.setCurrentPosition(0); // 调用播放方法 play(); break; case INTENT_ACTION_PLAY_OR_PAUSE: // 判断音乐是否在播放 if (mp.isPlaying()) { pause(); } else { play(); } break; case INTENT_ACTION_PREVIOUS: // 切换到上一首音乐 previousMusic(); break; case INTENT_ACTION_NEXT: // 切换到下一首音乐 nextMusic(); break; case INTENT_ACTION_USER_CHANGE_PROGRESS: // 根据拖拽条的进度值计算当前播放位置 app.setCurrentPosition(app.getProgressChangedByUser() * mp.getDuration() / 100); // 根据音乐当前播放位置开始播放音乐 play(); break; } } } } /** * 销毁回调方法 */ @Override public void onDestroy() { super.onDestroy(); // 释放媒体播放器 if (mp != null) { mp.release(); mp = null; } // 注销广播接收者 unregisterReceiver(receiver); // 设置线程循环控制变量 isRunning = false; // 销毁子线程 thread = null; }}
package com.zjs.ms_music_player_v01.entity;/** * 音乐实体类 */public class Music { /** * 标识符 */ private long id; /** * 音乐数据(完整文件名) */ private String data; /** * 音乐显示名称 */ private String displayName; /** * 音乐标题 */ private String title; /** * 音乐播放时长 */ private int duration; /** * 音乐图标键值 */ private String albumKey; /** * 演唱者或演奏者 */ private String artist; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getData() { return data; } public void setData(String data) { this.data = data; } public String getDisplayName() { return displayName; } public void setDisplayName(String displayName) { this.displayName = displayName; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public int getDuration() { return duration; } public void setDuration(int duration) { this.duration = duration; } public String getAlbumKey() { return albumKey; } public void setAlbumKey(String albumKey) { this.albumKey = albumKey; } public String getArtist() { return artist; } public void setArtist(String artist) { this.artist = artist; } @Override public String toString() { return "Music{" + "id=" + id + ", data='" + data + '\'' + ", displayName='" + displayName + '\'' + ", title='" + title + '\'' + ", duration=" + duration + ", albumKey='" + albumKey + '\'' + ", artist='" + artist + '\'' + '}'; }}
package com.zjs.ms_music_player_v01.dal;import android.content.ContentResolver;import android.content.Context;import android.database.Cursor;import android.provider.MediaStore;import com.zjs.ms_music_player_v01.entity.Music;import java.util.ArrayList;import java.util.List;/** * 音乐数据访问对象 */public class MusicDao { /** * 上下文环境 */ private Context context; /** * 构造方法:指定使用该MusicDao的上下文环境 * * @param context */ public MusicDao(Context context) { this.context = context; } /** * 获取音乐数据列表 * * @return */ public ListgetMusicList() { /* 1. 访问媒体库,获取音频游标对象 */ // 获取内容解析者,对媒体库这个内容提供者进行操作 ContentResolver resolver = context.getContentResolver(); // 实现查询(筛选播放时长不低于1分钟的音频),获取游标对象,作为数据源 Cursor cursor = resolver.query( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, // 参数1:查询目标 new String[]{MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DURATION, MediaStore.Audio.Media.ALBUM_KEY, MediaStore.Audio.Media.ARTIST}, // 参数2:查询字段列表 MediaStore.Audio.Media.DURATION + " >= ?", // 参数3:查询条件,包含占位符 new String[]{"60000"}, // 参数4:占位符对应的值列表 null // 参数:排序字段 ); /* 2. 将游标对象转换成音乐列表 */ List musicList = null; if (cursor.getCount() > 0) { musicList = new ArrayList<>(); while (cursor.moveToNext()) { // 实例化音乐对象 Music music = new Music(); // 设置音乐对象属性 music.setId(cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID))); music.setData(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA))); music.setDisplayName(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME))); music.setTitle(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE))); music.setDuration(cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION))); music.setAlbumKey(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_KEY))); music.setArtist(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST))); // 将音乐对象添加到音乐列表 musicList.add(music); } } // 关闭游标 if (cursor != null && !cursor.isClosed()) { cursor.close(); } // 返回音乐列表 return musicList; }}
package com.zjs.ms_music_player_v01.bll;import android.content.Context;import com.zjs.ms_music_player_v01.dal.MusicDao;import com.zjs.ms_music_player_v01.entity.Music;import java.util.List;/** * 音乐业务类 */public class MusicBiz { /** * 上下文环境 */ private Context context; public MusicBiz(Context context) { this.context = context; } /** * 获取音乐列表 * * @return */ public ListgetMusicList() { return new MusicDao(context).getMusicList(); }}
package com.zjs.ms_music_player_v01.app;import android.app.Application;import android.content.SharedPreferences;import com.zjs.ms_music_player_v01.bll.MusicBiz;import com.zjs.ms_music_player_v01.entity.Music;import java.text.SimpleDateFormat;import java.util.Collections;import java.util.Comparator;import java.util.List;/** * 音乐播放器应用程序类 */public class MusicPlayerApplication extends Application implements AppConstants{ /** * 简单日期格式 */ private SimpleDateFormat sdf; /** * 音乐列表(播放数据源) */ private ListmusicList; /** * 当前音乐索引 */ private int currentMusicIndex; /** * 音乐当前播放位置 */ private int currentPosition; /** * 播放模式 */ private int playMode; /** * 用户修改的播放进度 */ private int progressChangedByUser; @Override public void onCreate() { super.onCreate(); // 实例化简单日期对象 sdf = new SimpleDateFormat("mm:ss"); // 获得音乐列表(数据源) musicList = new MusicBiz(this).getMusicList(); // 读取排序设置 SharedPreferences sp = getSharedPreferences(USER_CONFIG, MODE_PRIVATE); String orderBy = sp.getString("order-by", "default"); if (orderBy.equals("default")) { // 默认排序 Collections.sort(musicList, new Comparator () { @Override public int compare(Music lhs, Music rhs) { return (int) (lhs.getId() - rhs.getId()); } }); } else if (orderBy.equals("title")) { // 按标题排序 Collections.sort(musicList, new Comparator () { @Override public int compare(Music lhs, Music rhs) { return lhs.getTitle().compareTo(rhs.getTitle()); } }); } else if (orderBy.equals("duration")) { // 按音乐时长排序 Collections.sort(musicList, new Comparator () { @Override public int compare(Music lhs, Music rhs) { return lhs.getDuration() - rhs.getDuration(); } }); } } public int getCurrentMusicIndex() { return currentMusicIndex; } public void setCurrentMusicIndex(int currentMusicIndex) { this.currentMusicIndex = currentMusicIndex; } public int getCurrentPosition() { return currentPosition; } public void setCurrentPosition(int currentPosition) { this.currentPosition = currentPosition; } public int getPlayMode() { return playMode; } public void setPlayMode(int playMode) { this.playMode = playMode; } public int getProgressChangedByUser() { return progressChangedByUser; } public void setProgressChangedByUser(int progressChangedByUser) { this.progressChangedByUser = progressChangedByUser; } /** * 获取格式化时间 * * @param time 单位是毫秒 * @return mm:ss格式的时间 */ public String getFormatTime(int time) { return sdf.format(time); } /** * 获取音乐列表 * * @return */ public List getMusicList() { // 返回音乐里列表 return musicList; }}
package com.zjs.ms_music_player_v01.app;/** * 应用程序常量接口 */public interface AppConstants { /** * 应用程序标记 */ String TAG = "net.hw.ms_music_player"; /** * 广播频道常量:播放上一首 */ String INTENT_ACTION_PREVIOUS = TAG + ".intent.action.PREVIOUS"; /** * 广播频道常量:播放下一首 */ String INTENT_ACTION_NEXT = TAG + ".intent.action.NEXT"; /** * 广播频道常量:播放或暂停 */ String INTENT_ACTION_PLAY_OR_PAUSE = TAG + ".intent.action.PLAY_OR_PAUSE"; /** * 广播频道常量:播放 */ String INTENT_ACTION_PLAY = TAG + ".intent.action.PLAY"; /** * 广播频道常量:更新播放进度 */ String INTENT_ACTION_UPDATE_PROGRESS = TAG + ".intent.action.UPDATE_PROGRESS"; /** * 广播频道常量:用户改变播放进度 */ String INTENT_ACTION_USER_CHANGE_PROGRESS = TAG + ".intent.action.USER_CHANGE_PROGRESS"; /** * 控制图标常量:播放或暂停 */ String CONTROL_ICON = "control_icon"; /** * 播放时长常量 */ String DURATION = "duration"; /** * 播放模式:顺序播放 */ int PLAY_MODE_ORDER = 0; /** * 播放模式:随机播放 */ int PLAY_MODE_RANDOM = 1; /** * 播放模式:单曲循环 */ int PLAY_MODE_LOOP = 2; /** * 用户配置文件名 */ String USER_CONFIG = "user-config";}
package com.zjs.ms_music_player_v01.adapter;import android.app.Activity;import android.content.ContentResolver;import android.content.Context;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.provider.MediaStore;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;import com.zjs.ms_music_player_v01.R;import com.zjs.ms_music_player_v01.app.MusicPlayerApplication;import com.zjs.ms_music_player_v01.entity.Music;import java.util.ArrayList;import java.util.List;/** * 音乐适配器 * * Created by howard on 2018/1/22. */public class MusicAdapter extends BaseAdapter { /** * 上下文环境 */ private Context context; /** * 音乐列表 */ private ListmusicList; /** * 音乐播放器应用程序 */ private MusicPlayerApplication app; /** * 构造方法 * * @param context * @param musicList */ public MusicAdapter(Context context, List musicList) { this.context = context; if (musicList == null) { musicList = new ArrayList<>(); } this.musicList = musicList; // 获取应用程序对象 app = (MusicPlayerApplication) ((Activity)context).getApplication(); } /** * 获取列表项个数 * * @return */ @Override public int getCount() { return musicList.size(); } /** * 获取列表项对象 * * @param position * @return */ @Override public Object getItem(int position) { return musicList.get(position); } /** * 获取列表项标识符 * * @param position * @return */ @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // 声明视图容器 ViewHolder holder; // 判断转换视图是否为空 if (convertView == null) { // 通过布局填充器将列表项模板映射成转换视图 convertView = LayoutInflater.from(context).inflate(R.layout.music_list_item, null); // 实例化视图容器 holder = new ViewHolder(); // 获取视图容器里控件实例 holder.ivImage = convertView.findViewById(R.id.iv_image); holder.tvArtist = convertView.findViewById(R.id.tv_artist); holder.tvDisplayName = convertView.findViewById(R.id.tv_display_name); holder.tvDuration = convertView.findViewById(R.id.tv_duration); // 将视图容器附加到转换视图 convertView.setTag(holder); } else { // 从转换视图里获取视图容器 holder = (ViewHolder) convertView.getTag(); } // 获取音乐数据 final Music music = musicList.get(position); /* 设置视图容器里控件属性 */ // 设置专辑封面图片 Bitmap cover = getAlbumCover(music.getAlbumKey()); if (cover != null) { holder.ivImage.setImageBitmap(cover); } else { holder.ivImage.setImageResource(R.drawable.music); } // 设置演唱者 holder.tvArtist.setText(music.getArtist()); // 设置显示名 holder.tvDisplayName.setText(music.getDisplayName().substring(0, music.getDisplayName().lastIndexOf("."))); // 设置播放时长 holder.tvDuration.setText(app.getFormatTime(music.getDuration())); // 返回转换视图 return convertView; } /** * 视图容器 */ private static class ViewHolder { ImageView ivImage; // 音乐专辑图片 TextView tvArtist; // 演唱者标签 TextView tvDuration; // 音乐时长标签 TextView tvDisplayName; // 音乐显示名标签 } /** * 按专辑键获取专辑图片 * * @param albumKey * @return */ private Bitmap getAlbumCover(String albumKey) { // 声明位图对象 Bitmap bitmap = null; // 获取内容解析者 ContentResolver resolver = context.getContentResolver(); // 按albumKey查询 Cursor cursor = resolver.query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, // 查询目标 new String[] { MediaStore.Audio.Albums.ALBUM_ART }, // 投影字段 MediaStore.Audio.Albums.ALBUM_KEY + " = ?", // 筛选条件 new String[] { albumKey }, // 条件参数 null // 排序字段 ); // 移到第一条记录 if (cursor.moveToFirst()) { // 获取专辑封面图片路径 String albumPath = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART)); // 解析生成位图对象 bitmap = BitmapFactory.decodeFile(albumPath); } // 返回位图对象 return bitmap; }}
转载地址:http://ijtki.baihongyu.com/