播放多媒体

    xiaoxiao2024-01-12  169

    播放多媒体

    手机上最常见的休闲方式毫无疑问就是听音乐了,随着移动设备的普及,越来越多人都可以随时享受优美的音乐。而Android在播放音频方面做了相当不错的支持,它提供了一套较为完整的API,使得开发者可以很轻松地编写出一个简易的音频播放器,下面我们就来具体地学习一下。

    MediaPlayer类简介

    在Android中播放音频文件一般都是使用MediaPlayer类来实现的,它对多种格式的音频文件提供了非常全面的控制方法,从而使得播放音乐的工作变得十分简单。下表列出了MediaPlayer类中一些较为常用的控制方法:

    BroadcastReceiver简介

    BroadcastReceiver 用于接收程序所发出的Broadcast Intent,与Activity、Service具有完整的生命周期不同,BroadcastReceiver本质上是一个监听器——它专门负责监听各程序所发出的Broadcast。因此BroadcastReceiver也就提供了让不同组件之间进行通信的新思路,比如程序有个Activity、Service,而且该Service是通过startService()方法启动的,通过BroadcastReceiver的帮助,程序就可以实现两者之间的通信了。

    基于Service的音乐播放器

    以一个音乐播放器为例,程序的音乐将会由后端运行的Service组件负责播放,当后端播放状态发生改变时,程序将会通过发送广播通知前端Activity更新界面,当用户单击前端Activity的界面按钮时,系统将通过发送广播通知后端Service来改变播放状态。

    前端Activity的界面很简单,它只有两个按钮,分别用于播放、暂停,代码如下:

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageButton android:id="@+id/play" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/play"/> <ImageButton android:id="@+id/stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/stop"/> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20dp" android:textColor="#ffffff" android:ellipsize="marquee" android:layout_weight="1" android:marqueeRepeatLimit="marquee_forever"/> <TextView android:id="@+id/author" android:textSize="12dp" android:gravity="center_vertical" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </LinearLayout>

    与之对应的是,该程序的后端Service也一样,它会在播放状态发生改变时对外发送广播,采用BroadcastReceiver监听来自前端Activity所发出的广播。后端代码如下:

    package org.crazyit.broadcast; 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 { MyReceiver serviceReceiver; AssetManager am; String[] musics = new String[] { "wish.mp3", "promise.mp3", "beautiful.mp3" }; MediaPlayer mPlayer; int status = 0x11; int current = 0; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); am = getAssets(); serviceReceiver = new MyReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction(MainActivity.CTL_ACTION); registerReceiver(serviceReceiver, filter); mPlayer = new MediaPlayer(); mPlayer.setOnCompletionListener(new OnCompletionListener() // ① { @Override public void onCompletion(MediaPlayer mp) { current++; if (current >= 3) { current = 0; } Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION); sendIntent.putExtra("current", current); 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 (status == 0x12 || status == 0x13) { mPlayer.stop(); status = 0x11; } } Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION); sendIntent.putExtra("update", status); sendIntent.putExtra("current", current); sendBroadcast(sendIntent); } } private void prepareAndPlay(String music) { try { AssetFileDescriptor afd = am.openFd(music); mPlayer.reset(); mPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); mPlayer.prepare(); mPlayer.start(); } catch (IOException e) { e.printStackTrace(); } } }

    除此之外,为了让音乐播放器能按顺序依次播放每首歌曲,程序为MediaPlayer增加了OnCompletionListener监听器,运行该程序,效果如下:

    由于该程序使用了Service来播放音乐,因此在用户退出后,后端也依然会播放音乐。

    该程序用到了两个BroadcastReceiver,但在程序中已经注册了两个BroadcastReceiver所监听的IntentFilter,因此无须在AndriodManifest.xml文件中注册这两个BroadcastReceiver了,只要注册所用的前端Activity,后端Service即可了。

    作者:陈翰鑫 原文链接:https://blog.csdn.net/kingaethelbald/article/details/90557591

    最新回复(0)