Android应用开发--MP3音乐播放器Service实现(2)

path = mp3Infos.get(current).getUrl();

play(0);

}else {

mediaPlayer.seekTo(0);

current = 0;

Intent sendIntent = new Intent(UPDATE_ACTION);

sendIntent.putExtra(“current”, current);

// 发送广播,将被Activity组件中的BroadcastReceiver接收到

sendBroadcast(sendIntent);

}

} else if(status == 4) { //随机播放

current = getRandomIndex(mp3Infos.size() - 1);

System.out.println(“currentIndex ->” + current);

Intent sendIntent = new Intent(UPDATE_ACTION);

sendIntent.putExtra(“current”, current);

// 发送广播,将被Activity组件中的BroadcastReceiver接收到

sendBroadcast(sendIntent);

path = mp3Infos.get(current).getUrl();

play(0);

}

}

});

myReceiver = new MyReceiver();

IntentFilter filter = new IntentFilter();

filter.addAction(PlayerActivity.CTL_ACTION);

registerReceiver(myReceiver, filter);

}

/**

  • 获取随机位置

  • @param end

  • @return

*/

protected int getRandomIndex(int end) {

int index = (int) (Math.random() * end);

return index;

}

@Override

public IBinder onBind(Intent arg0) {

return null;

}

@Override

public void onStart(Intent intent, int startId) {

path = intent.getStringExtra(“url”); //歌曲路径

current = intent.getIntExtra(“listPosition”, -1); //当前播放歌曲的在mp3Infos的位置

msg = intent.getIntExtra(“MSG”, 0); //播放信息

if (msg == AppConstant.PlayerMsg.PLAY_MSG) { //直接播放音乐

play(0);

} else if (msg == AppConstant.PlayerMsg.PAUSE_MSG) { //暂停

pause();

} else if (msg == AppConstant.PlayerMsg.STOP_MSG) { //停止

stop();

} else if (msg == AppConstant.PlayerMsg.CONTINUE_MSG) { //继续播放

resume();

} else if (msg == AppConstant.PlayerMsg.PRIVIOUS_MSG) { //上一首

previous();

} else if (msg == AppConstant.PlayerMsg.NEXT_MSG) { //下一首

next();

} else if (msg == AppConstant.PlayerMsg.PROGRESS_CHANGE) { //进度更新

currentTime = intent.getIntExtra(“progress”, -1);

play(currentTime);

} else if (msg == AppConstant.PlayerMsg.PLAYING_MSG) {

handler.sendEmptyMessage(1);

}

super.onStart(intent, startId);

}

/**

  • 播放音乐

  • @param position

*/

private void play(int currentTime) {

try {

mediaPlayer.reset();// 把各项参数恢复到初始状态

mediaPlayer.setDataSource(path);

mediaPlayer.prepare(); // 进行缓冲

mediaPlayer.setOnPreparedListener(new PreparedListener(currentTime));// 注册一个监听器

handler.sendEmptyMessage(1);

} catch (Exception e) {

e.printStackTrace();

}

}

/**

  • 暂停音乐

*/

private void pause() {

if (mediaPlayer != null && mediaPlayer.isPlaying()) {

mediaPlayer.pause();

isPause = true;

}

}

private void resume() {

if (isPause) {

mediaPlayer.start();

isPause = false;

}

}

/**

  • 上一首

*/

private void previous() {

Intent sendIntent = new Intent(UPDATE_ACTION);

sendIntent.putExtra(“current”, current);

// 发送广播,将被Activity组件中的BroadcastReceiver接收到

sendBroadcast(sendIntent);

play(0);

}

/**

  • 下一首

*/

private void next() {

Intent sendIntent = new Intent(UPDATE_ACTION);

sendIntent.putExtra(“current”, current);

// 发送广播,将被Activity组件中的BroadcastReceiver接收到

sendBroadcast(sendIntent);

play(0);

}

/**

  • 停止音乐

*/

private void stop() {

if (mediaPlayer != null) {

mediaPlayer.stop();

try {

mediaPlayer.prepare(); // 在调用stop后如果需要再次通过start进行播放,需要之前调用prepare函数

} catch (Exception e) {

e.printStackTrace();

}

}

}

@Override

public void onDestroy() {

if (mediaPlayer != null) {

mediaPlayer.stop();

mediaPlayer.release();

mediaPlayer = null;

}

}

/**

  • 实现一个OnPrepareLister接口,当音乐准备好的时候开始播放

*/

private final class PreparedListener implements OnPreparedListener {

private int currentTime;

public PreparedListener(int currentTime) {

this.currentTime = currentTime;

}

@Override

public void onPrepared(MediaPlayer mp) {

mediaPlayer.start(); // 开始播放

if (currentTime > 0) { // 如果音乐不是从头播放

mediaPlayer.seekTo(currentTime);

}

Intent intent = new Intent();

intent.setAction(MUSIC_DURATION);

duration = mediaPlayer.getDuration();

intent.putExtra(“duration”, duration); //通过Intent来传递歌曲的总长度

sendBroadcast(intent);

}

}

public class MyReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

int control = intent.getIntExtra(“control”, -1);

switch (control) {

case 1:

status = 1; // 将播放状态置为1表示:单曲循环

break;

case 2:

status = 2; //将播放状态置为2表示:全部循环

break;

case 3:

status = 3; //将播放状态置为3表示:顺序播放

break;

case 4:

status = 4; //将播放状态置为4表示:随机播放

break;

}

}

}

}

以上的代码要注意的是在Service在被调用startService()方法会在回调onStart(),服务是不会被多次创建的,但会多次调用onStart方法,然而通过Intent传过来的数据,也只能在onStart方法内来接收。

似乎关于Service类没什么可说的,简单来说服务是我们看不见的东西,只是在后台不断运行的程序,音乐播放通过服务来实现,才不会在界面不可见的时候停掉,这是音乐播放器使用Service的原因。

第一阶段的音乐播放器开发已经到现在全部介绍完,第二阶段会实现歌词的显示和网络相关的下载和搜索,在这一阶段也会对UI进行一些细微的美化,尽量去尝试实现更炫的效果,比如提供主题的切换,界面切换的动画等等。小巫需要继续去学习,然后把所有东西分享给学习Android的朋友们,感谢你们的关注,让我们一起共同学习进步。

第二阶段具体会什么时候启动,还没有明确的时间,因为最近开始忙起来了,所以尽情等待吧。哇咔咔
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

Android开发除了flutter还有什么是必须掌握的吗?

相信大多数从事Android开发的朋友们越来越发现,找工作越来越难了,面试的要求越来越高了

除了基础扎实的java知识,数据结构算法,设计模式还要求会底层源码,NDK技术,性能调优,还有会些小程序和跨平台,比如说flutter,以思维脑图的方式展示在下图;

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

战项目、讲解视频,并且会持续更新!**

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

Android开发除了flutter还有什么是必须掌握的吗?

相信大多数从事Android开发的朋友们越来越发现,找工作越来越难了,面试的要求越来越高了

除了基础扎实的java知识,数据结构算法,设计模式还要求会底层源码,NDK技术,性能调优,还有会些小程序和跨平台,比如说flutter,以思维脑图的方式展示在下图;

[外链图片转存中…(img-1nG40ZSU-1712221573111)]

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值