安卓APP实战(四):音乐播放器及多Activity共享音乐播放器实现

安卓应用背景音乐使用 MediaPlayer实现。

MediaPlayer创建通过方法 MediaPlayer.create(context, resId);
context为音乐播放器的上下文,取用this.getApplication().getApplicationContext()的上下文可以防止持有外部类导致Activity无法回收。在调用create方法前必须保证MediaPlayer对象为状态为空。否则将会报错。可在调用前判断是否为空,不为空则调用MediaPlayer.reset()方法进行重置。

播放音乐 MediaPlayer.start()

暂停音乐 MediaPlayer.pause()

设置音乐播放完毕事件 mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
//do something…
}
});
顺序播放:
重置创建播放器,资源使用列表下一首->设置播放完毕事件->音乐播放
在播放完毕事件中回调整个方法。

随机播放:
与顺序播放区别在于,在创建播放器时随机获取列表中的资源

上一曲、下一曲
手动调用上述的方法即可。

进度条
使用mediaPlayer.getCurrentPosition()获取当前播放位置, mediaPlayer.getDuration()获取歌曲总长度,使用Timer进行不断发请求获取当前位置并渲染进度条控件即可。

多个界面共享音乐播放器

在写音乐播放器代码时,我想要音乐按钮不止在主界面可以使用,在数字选择界面,在数字书写界面等其他界面我也想能够随时控制音乐的播放与停止状态。即应用的所有界面共享同一个音乐播放器。

我的思路是定义一个BasicActivity类,将音乐播放器设置为静态对象,在所有Activity中均继承基本类,实现音乐播放器共享。布局文件中按钮有两种状态,音乐正在播放,音乐停止播放,当Activity切换时我们就需要根据当前播放状态去渲染音乐按钮,音乐按钮可以每个布局文件中定义,而我定义在了BasicActivity的布局文件中,并在其他布局文件中使用<include>标签引用,此功能实现代码如下。

当我们进入一个拥有音乐按钮的界面时,需要做三件事
1.调用setContentView设置布局文件 2.获取按钮并根据状态设置背景图片 3.播放音乐并设置播放完成切换歌曲事件

当进入主应用界面时第一次初始化音乐播放器开始播放音乐,在跳转后不改变音乐播放器状态,仅根据播放器状态渲染控件。
所以讲音乐播放和设置下一曲的调用放在主应用界面的Activity中,而渲染控件放在BasicActivity中进行。

效果是进入主界面即开始播放歌曲,之后任意切换界面都不影响音乐播放,并且每个界面都可以停止或播放歌曲。

若遇到程序报空指针错误,错误指向music_btn.setBackgroundResource(R.mipmap.btn_music1)等对控件操作的调用时,可能是在调用顺序上出了问题,在使用findViewById时还未调用setContentView,导致获取的控件是null。所以在使用findViewById时必须确认在此之前已经使用setContentView设置了主布局。

具体实现代码如下

BasicActivity

public class BasicActivity extends Activity {

    static boolean isPlay = true;  //播放状态
    static MediaPlayer mediaPlayer;  //音乐播放器
    static int musicIndex = 0;  //当前播放序号
    static Context context;  //上下文
    static int[] musicList = {R.raw.high_hopes, R.raw.don_t_miss_now, R.raw.don_t_you_worry_child};  //播放歌曲列表
    Button music_btn;  //前台按钮控件

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = this.getApplication().getApplicationContext();
        //通过id获取布局文件中按钮控件
        music_btn = (Button) findViewById(R.id.btn_music);
        //根据播放状态渲染按钮图片
        if (isPlay) {
            music_btn.setBackgroundResource(R.mipmap.btn_music1);
        } else {
            music_btn.setBackgroundResource(R.mipmap.btn_music2);
        }
		//内存监视器
        RefWatcher refWatcher = App.getRefWatcher(this);
        refWatcher.watch(this);
    }

//点击事件,将播放器状态置反并渲染按钮图片
    public void onClick(View v) {
        if (isPlay) {
            if (mediaPlayer != null) {
                mediaPlayer.pause();
                music_btn.setBackgroundResource(R.mipmap.btn_music2);
                isPlay = false;
            }
        } else {
            mediaPlayer.start();
            music_btn.setBackgroundResource(R.mipmap.btn_music1);
            isPlay = true;
        }
    }

//设置播放器播放完毕回调函数,进行歌曲切换
    public static void setPlayList() {
        try {
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    musicIndex++;
                    if (musicIndex >= musicList.length) {
                        musicIndex = 0;
                    }
                    playMusic(musicList[musicIndex]);
                    setPlayList();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

//播放歌曲,保证播放器为空后创建新的播放器,开始播放音乐
    public static void playMusic(int resId) {
        if (mediaPlayer != null) {
            mediaPlayer.reset();
        }
        mediaPlayer = MediaPlayer.create(context, resId);
        mediaPlayer.start();
   	 }
	}

-------------------------BasicLayout----------------------

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:layout_margin="10dp"
    android:layout_alignParentBottom="true"
    tools:context=".BasicActivity">

    <Button
        android:id="@+id/btn_music"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_margin="0dp"
        android:background="@drawable/btn_music"
        android:onClick="onClick" />

</RelativeLayout>

------------------------MainActivity----------------------

//继承了BasicActivity
public class MainActivity extends BasicActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
	//必须先设置视图,而后调用BasicActivity的onCreate函数
	//若顺序反过来将会报空指针错误,因为没有渲染前台控件,则没有音乐按钮
    setContentView(R.layout.activity_main);
    super.onCreate(savedInstanceState);
    playMusic(musicList[musicIndex]);
    setPlayList();
}
//跳转游戏选择界面
 public void OnPlay(View v) {
   	 startActivity(new Intent(MainActivity.this, SelectActivity.class));
 }
//跳转关于我们界面
	public void OnAbout(View v) {
    	startActivity(new Intent(MainActivity.this, AboutActivity.class));
	}
}

----------------------MainLayout----------------------

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/main_bg"
    tools:context="com.example.wangjy.activity.MainActivity">

    <Button
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_above="@+id/btn_about"
        android:layout_centerHorizontal="true"
        android:background="@drawable/btn_play"
        android:onClick="OnPlay" />

    <include layout="@layout/activity_basic" />

    <Button
        android:id="@+id/btn_about"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_margin="10dp"
        android:background="@drawable/btn_about"
        android:onClick="OnAbout" />

</RelativeLayout>
目录 第一章 引 言 - 1 - 1.1 项目背景 - 1 - 1.2 编写目的 - 2 - 第二章 系统需求分析 - 3 - 2.1 功能需求(用例图分析) - 3 - 2.1.1 播放器的基本控制需求 - 3 - 2.1.2 播放清单列表管理需求 - 5 - 2.1.3 播放友好性需求 - 7 - 2.1.4 播放器扩展卡需求 - 8 - 2.1.5 功能需求(时序图)分析 - 9 - 2.2 系统结构图和流程图 - 10 - 2.3 系统界面需求 - 11 - 2.4 系统性能需求 - 12 - 2.5 运行环境需求 - 12 - 第三章 Android数据库设计 - 13 - 3.1 数据库及字段属性设计 - 13 - 3.1.1 字段设计(表、图) - 13 - 3.1.2 音乐播放器E-R图 - 15 - 3.2 数据库连接 - 15 - 3.2.1 创建数据库 - 15 - 3.2.2 操作数据库 - 16 - 3.2.3 数据显示 - 17 - 第Android项目介绍 - 18 - 4.1 什么是Android? - 18 - 4.1.1 Android简介 - 18 - 4.1.2 Android Features特性 - 18 - 4.1.3 Android基本框架(Android Architecture) - 19 - 4.1.4 Android系统的大组件 - 22 - 4.2 搭建Android开发环境 - 23 - 4.3 Android常用工具的使用 - 25 - 4.3.1 命令行的使用 - 25 - 4.3.2 Dalvik Debug Monitor Service (DDMS)的使用 - 26 - 4.4 Android 音乐播放器的工程 - 26 - 4.4.1 Android项目 - 26 - 4.4.2 Android工程程序结构 - 27 - 4.4.3 AndroidManifest.xml文件 - 29 - 第五章 播放器系统功能详细设计 - 31 - 5.1音乐播放器主界面功能实现 - 31 - 5.1.1 播放器主界面 - 31 - 5.1.2 播放界面音轨的实现 - 32 - 5.1.3 播放器播放、暂停、停止等功能 - 35 - 5.2 播放列表功能 - 36 - 5.3 菜单功能 - 38 - 5.3.1 菜单界面 - 38 - 5.3.2 菜单功能实现 - 39 - 5.4 播放设置界面 - 41 - 5.4.1 界面实现 - 41 - 5.4.2 歌词显示实现 - 42 - 5.5 手机扩展卡的访问 - 44 - 5.5.1 文件浏览器界面 - 45 - 5.5.2 文件浏览器功能实现 - 46 - 5.6 数据存储方式 - 47 - 5.6.1 SharedPreferences - 47 - 5.6.2 File存储方式 - 48 - 5.6.3 SQLiteDatabase数据库 - 48 - 第六章 结 论 - 49 -
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值