Android Studio实现简单音乐播放功能的示例代码

作者:ttt汤圆 时间:2021-09-14 19:51:45 

项目要求

基于Broadcast,BroadcastReceiver等与广播相关的知识实现简单的音乐播放功能,包括音乐的播放、暂停、切换、进度选择、音量调整。

设计效果

(进度条时间刷新功能还没有实现)

Android Studio实现简单音乐播放功能的示例代码

实现思路

  • 音乐服务端负责播放音乐和收发广播的功能。当音乐服务端作为 * 时,只能接收到主页面广播的控制消息;作为发送器时,向主页面发送歌曲信息更新的消息

  • 主页面负责进度条以及音量按钮的监听,同时也有收发广播的功能。当主页面作为 * 时,只能接收到音乐服务端广播的歌曲信息更新的消息;作为发送器时,向音乐服务端发送对歌曲播放的控制消息。

项目结构图

Android Studio实现简单音乐播放功能的示例代码

主要代码

1 主页面


package com.example.dell.musicbox3;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;

public class MainActivity extends Activity implements View.OnClickListener
{
// 获取界面中显示歌曲标题、作者文本框
TextView title, author;
// 播放/暂停、停止按钮
ImageButton play, next, last;
// 声明音量管理器
public AudioManager mAudioManager = null;
// 定义进度条
public static SeekBar audioSeekBar = null;
// 定义音量大小
public SeekBar audioVolume = null;

ActivityReceiver activityReceiver;

public static final String CTL_ACTION = "org.crazyit.action.CTL_ACTION";

public static final String UPDATE_ACTION = "org.crazyit.action.UPDATE_ACTION";
// 定义音乐的播放状态,0x11代表没有播放;0x12代表正在播放;0x13代表暂停
int status = 0x11;
String[] titleStrs = new String[] { "龙卷风", "可爱女人", "星晴" };
String[] authorStrs = new String[] { "JayChou", "JayChou", "JayChou" };

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.layout);

// 获取程序界面界面中的两个按钮
play = (ImageButton) this.findViewById(R.id.play);
last = (ImageButton) this.findViewById(R.id.last);
next = (ImageButton) this.findViewById(R.id.next);
audioVolume = (SeekBar) findViewById(R.id.seekBar2);
audioSeekBar = (SeekBar) findViewById(R.id.seekBar1);
title = (TextView) findViewById(R.id.title);
author = (TextView) findViewById(R.id.author);

// 为两个按钮的单击事件添加 *
play.setOnClickListener(this);
last.setOnClickListener(this);
next.setOnClickListener(this);

// 播放进度监听
audioSeekBar.setOnSeekBarChangeListener(new SeekBarChangeEvent());
// 退出后再次进去程序时,进度条保持持续更新
if (MusicService.mPlayer != null) {
// 设置进度条的最大值
MainActivity.audioSeekBar.setMax(MusicService.mPlayer.getDuration());
audioSeekBar.setProgress(MusicService.mPlayer.getCurrentPosition());
}
// 得到当前音量对象
mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
// 把当前音量值赋给进度条
audioVolume.setProgress(mAudioManager
.getStreamVolume(AudioManager.STREAM_MUSIC));
// 监听音量
audioVolume.setOnSeekBarChangeListener(new AudioVolumeChangeEvent());

activityReceiver = new ActivityReceiver();
// 创建IntentFilter
IntentFilter filter = new IntentFilter();
// 指定BroadcastReceiver监听的Action
filter.addAction(UPDATE_ACTION);
// 注册BroadcastReceiver
registerReceiver(activityReceiver, filter);

Intent intent = new Intent(this, MusicService.class);
// 启动后台Service
startService(intent);
}

// 音量监听
class AudioVolumeChangeEvent implements SeekBar.OnSeekBarChangeListener {

@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress,
0);
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {

}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {

}

}

// 播放进度监听,别忘了Service里面还有个进度条刷新
class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener {

@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// 假设改变源于用户拖动
if (fromUser) {
MusicService.mPlayer.seekTo(progress);
// 当进度条的值改变时,音乐播放器从新的位置开始播放
}
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
MusicService.mPlayer.pause();
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
MusicService.mPlayer.start();
}

}

// 自定义的BroadcastReceiver,负责监听从Service传回来的广播
public class ActivityReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
// 获取Intent中的update消息,update代表播放状态
int update = intent.getIntExtra("update", -1);
// 获取Intent中的current消息,current代表当前正在播放的歌曲
int current = intent.getIntExtra("current", -1);
if (current >= 0)
{
title.setText(titleStrs[current]);
author.setText(authorStrs[current]);
}
switch (update)
{
case 0x11:
play.setImageResource(R.drawable.play);
status = 0x11;
break;
// 控制系统进入播放状态
case 0x12:
// 播放状态下设置使用暂停图标
play.setImageResource(R.drawable.pause);
// 设置当前状态
status = 0x12;
break;
// 控制系统进入暂停状态
case 0x13:
// 暂停状态下设置使用播放图标
play.setImageResource(R.drawable.play);
// 设置当前状态
status = 0x13;
break;
}
}
}
@Override
public void onClick(View source)
{
// 创建Intent
Intent intent = new Intent("org.crazyit.action.CTL_ACTION");
switch (source.getId())
{
// 按下播放/暂停按钮
case R.id.play:
intent.putExtra("control", 1);
break;
case R.id.last:
intent.putExtra("control", 2);
break;
//按下上一首按钮
case R.id.next:
intent.putExtra("control", 3);
break;
}
// 发送广播,将被Service组件中的BroadcastReceiver接收到
sendBroadcast(intent);
}

}

2 音乐服务端


package com.example.dell.musicbox3;

import java.io.IOException;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.IBinder;

public class MusicService extends Service implements Runnable
{
MyReceiver serviceReceiver;
//asset文件管理对象
AssetManager am;
String[] musics = new String[] { "周杰倫 - 龙卷风.mp3", "周杰倫 - 星晴.mp3", "周杰倫 - 可爱女人.mp3" };
public static MediaPlayer mPlayer;
// 当前的状态,0x11代表没有播放;0x12代表正在播放;0x13代表暂停
int status = 0x11;
// 记录当前正在播放的音乐
int current = 0;
@Override
//非绑定式服务
public IBinder onBind(Intent intent)
{
return null;
}
@Override
//定义初始化函数
public void onCreate()
{
super.onCreate();
//获取asset文件夹里的所有歌曲
am = getAssets();
// 创建具有筛选功能的服务端 *
serviceReceiver = new MyReceiver();
// 创建IntentFilter过滤器
IntentFilter filter = new IntentFilter();
//使音乐服务端的 * 只能接收客户端发来的CTL_ACTION消息
filter.addAction(MainActivity.CTL_ACTION);
//注册带有此筛选器且名字叫做serviceReceiver的 *
registerReceiver(serviceReceiver, filter);
// 创建MediaPlayer
mPlayer = new MediaPlayer();
// 为MediaPlayer播放完成事件绑定 *
mPlayer.setOnCompletionListener(new OnCompletionListener() // ①
{
@Override
public void onCompletion(MediaPlayer mp)
{
current++;
if (current >= 3)
{
current = 0;
}
//发送广播通知Activity更改文本框
Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);
sendIntent.putExtra("current", current);
// 发送广播,将被Activity组件中的BroadcastReceiver接收到
sendBroadcast(sendIntent);
// 准备并播放音乐
prepareAndPlay(musics[current]);
}
});
}
public class MyReceiver extends BroadcastReceiver
{
@Override
public void onReceive(final Context context, Intent intent)
{
int control = intent.getIntExtra("control", -1);
switch (control)
{
// 播放或暂停
case 1:
// 原来处于没有播放状态
if (status == 0x11)
{
// 准备并播放音乐
prepareAndPlay(musics[current]);
status = 0x12;
}
// 原来处于播放状态
else if (status == 0x12)
{
// 暂停
mPlayer.pause();
// 改变为暂停状态
status = 0x13;
}
// 原来处于暂停状态
else if (status == 0x13)
{
// 播放
mPlayer.start();
// 改变状态
status = 0x12;
}
break;
// 停止声音
case 2:
//上一首切换
if (current <= 0) {
//停止播放
mPlayer.stop();
//修改current
current = musics.length-1;
//播放
prepareAndPlay(musics[current]);
status = 0x12;
}
else{
mPlayer.stop();
current--;
prepareAndPlay(musics[current]);
status = 0x12;
}
break;
//下一首切换
case 3:
if (current >= 2) {
mPlayer.stop();
current = 0;
prepareAndPlay(musics[current]);
status = 0x12;
}
else{
mPlayer.stop();
current++;
prepareAndPlay(musics[current]);
status = 0x12;
}
break;

}
// 广播通知Activity更改图标、文本框
Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);
sendIntent.putExtra("update", status);
sendIntent.putExtra("current", current);
// 发送广播,将被Activity组件中的BroadcastReceiver接收到
sendBroadcast(sendIntent);
}
}
private void prepareAndPlay(String music) {
try {
// 打开指定音乐文件
AssetFileDescriptor afd = am.openFd(music);
mPlayer.reset();
// 使用MediaPlayer加载指定的声音文件。
mPlayer.setDataSource(afd.getFileDescriptor(),
afd.getStartOffset(), afd.getLength());
// 准备声音
mPlayer.prepare();
// 播放
mPlayer.start();
// 设置进度条最大值
MainActivity.audioSeekBar.setMax(MusicService.mPlayer.getDuration());
new Thread(this).start();
} catch (IOException e) {
e.printStackTrace();
}
}

// 刷新进度条
public void run() {
int CurrentPosition = 0;
int total = mPlayer.getDuration();
while (mPlayer != null && CurrentPosition < total) {
try {
Thread.sleep(1000);
if (mPlayer != null) {
CurrentPosition = mPlayer.getCurrentPosition();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
MainActivity.audioSeekBar.setProgress(CurrentPosition);
}
}
}

仓库链接

MusicBox

来源:https://blog.csdn.net/qq_44921821/article/details/105590579

标签:Android,Studio,音乐播放
0
投稿

猜你喜欢

  • Android编程之手机壁纸WallPaper设置方法示例

    2023-09-27 20:51:10
  • C#导出文本内容到word文档的方法

    2021-10-15 19:00:37
  • spring-boot-maven-plugin引入出现爆红(已解决)

    2021-06-06 12:05:35
  • Java的Spring框架中AOP项目的一般配置和部署教程

    2021-07-26 16:49:25
  • maven多个plugin相同phase的执行顺序

    2021-07-07 10:33:34
  • 解决springmvc关于前台日期作为实体类对象参数类型转换错误的问题

    2023-11-28 20:53:42
  • java web监听器统计在线用户及人数

    2023-12-14 14:42:52
  • c#扫描图片去黑边(扫描仪去黑边)

    2022-11-06 11:45:55
  • Java中的Static class详解及实例代码

    2023-12-24 18:19:40
  • Java利用POI实现导入导出Excel表格示例代码

    2023-05-15 03:02:19
  • Java结构性设计模式中的装饰器模式介绍使用

    2022-04-08 06:30:00
  • java实现Xml与json之间的相互转换操作示例

    2023-06-21 13:30:39
  • Java 高并发三:Java内存模型和线程安全详解

    2021-10-24 07:04:13
  • Java Fluent Mybatis实战之构建项目与代码生成篇上

    2022-06-10 00:10:33
  • Scala方法与函数使用和定义详解

    2021-10-05 06:34:12
  • Java如何基于ProcessBuilder类调用外部程序

    2023-11-27 20:19:57
  • Android RecyclerView使用ListAdapter高效刷新数据的操作方法

    2023-06-24 22:22:09
  • Java Bean 作用域及它的几种类型介绍

    2022-12-02 20:39:42
  • Android SwipeRefreshLayout超详细讲解

    2023-08-22 13:43:28
  • Java将字符串String转换为整型Int的两种方式

    2021-12-11 10:01:32
  • asp之家 软件编程 m.aspxhome.com