- 简介
Android的多媒体框架包括支持播放多种常见的媒体类型,使您可以轻松地把音频、视频和图像集成到你的应用。你可以播放音频或视频媒体文件,这些文件是存储在你的应用程序的资源文件中的。应用程序的资源文件可以是文件系统中独立的文件,或通过网络连接获取的一个数据流,所有使用MediaPlayer APIS的资源文件。
注意:你只能在标准输出设备上播放音频数据。目前,标准输出设备是移动设备的扬声器或耳机。你不能在谈话音频调用期间播放声音文件。
三种播放方式
播放本地资源文件
public void playFromRes(View v){
MediaPlayer mp=MediaPlayer.create(this,R.raw.zhh);
mp.start();
}
播放系统文件
public void playFromSys(View v){
MediaPlayer mp=new MediaPlayer();
String path= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getPath()+"/zhh.mp3";
try {
mp.setDataSource(this, Uri.parse(path));//设置数据源
mp.prepare();//同步执行
mp.start();
} catch (IOException e) {
e.printStackTrace();
}
}
播放网络文件
public void playFromInternet(View v){
String path="http://fs.w.kugou.com/201904231441/48036033298fec2f60d6a81a8aeaca63/G137/M06/08/17/yQ0DAFuGdOCABiECAE4jb57rgmY473.mp3";//这个链接不可用了
MediaPlayer mp=new MediaPlayer();
try {
mp.setDataSource(this,Uri.parse(path));
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
mp.prepareAsync();//异步缓冲
} catch (IOException e) {
e.printStackTrace();
}
}
权限设置
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
状态转换图
简单的播放器实现
import android.media.MediaPlayer;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
/**
* 简单的播放器实现
*/
public class Main2Activity extends AppCompatActivity implements View.OnClickListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener {
private MediaPlayer mp;
private int index=0;//表示当前要播放音乐的索引
private ArrayList<String> musicList=new ArrayList<>();
private Button button_play,button_pause,button_next,button_prev;
private boolean isPause=false;//true表示暂停状态
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initView();
initMusic();
mp=new MediaPlayer();
mp.setOnPreparedListener(this);
mp.setOnErrorListener(this);
mp.setOnCompletionListener(this);
}
private void initView(){
button_play=findViewById(R.id.button6_play);
button_pause=findViewById(R.id.button7_pause);
button_next=findViewById(R.id.button5_next);
button_prev=findViewById(R.id.button4_prev);
button_play.setOnClickListener(this);
button_pause.setOnClickListener(this);
button_next.setOnClickListener(this);
button_prev.setOnClickListener(this);
}
public void initMusic(){
String root= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getPath();
musicList.add(root+ File.separator+"/zhh.mp3");
musicList.add(root+ File.separator+"/qjtx.mp3");
musicList.add(root+ File.separator+"/myhs.mp3");
musicList.add(root+ File.separator+"/cl.mp3");
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button6_play:
play();
break;
case R.id.button7_pause:
pause();
break;
case R.id.button5_next:
next();
break;
case R.id.button4_prev:
prev();
break;
default:
break;
}
}
//上一首
private void prev() {
if (index-1>=0){
index--;
}else {
index=musicList.size()-1;
}
start();
}
//下一首
private void next() {
if (index+1<musicList.size()){
index++;
}else {
index=0;
}
start();
}
//暂停
private void pause() {
if (mp.isPlaying()){
mp.pause();
isPause=true;
}
}
//播放
private void play() {
if (isPause){
mp.start();
isPause=false;
}else {
start();
}
}
//重头开始播放音乐
private void start(){
if(index<musicList.size()){
if (mp.isPlaying())mp.stop();
mp.reset();//重置
String musicPath= musicList.get(index);
try {
mp.setDataSource(musicPath);
mp.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mp!=null){
if (mp.isPlaying())mp.stop();
mp.release();
}
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mp.reset();
return true;
}
@Override
public void onCompletion(MediaPlayer mp) {
next();
}
}
权限
以服务的形式后台运行
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.os.IBinder;
import android.os.PowerManager;
import java.io.File;
import java.io.IOException;
public class MusicService extends Service implements MediaPlayer.OnPreparedListener {
public static final String ACTION_PLAY="com.my.ACTION_PLAY";
public static final String ACTION_PAUSE="com.my.ACTION_PAUSE";
public static final String ACTION_EXIT="com.my.ACTION_EXIT";
private WifiManager.WifiLock lock;
private MediaPlayer mediaPlayer;
public MusicService() {
}
@Override
public void onCreate() {
super.onCreate();
mediaPlayer=new MediaPlayer();
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
//保持WIFI正常工作
WifiManager wifiManager= (WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE);
lock= wifiManager.createWifiLock("mylock");
lock.acquire();
mediaPlayer.setOnPreparedListener(this);
}
@Override
public void onDestroy() {
super.onDestroy();
lock.release();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String action=intent.getAction();
if (ACTION_PLAY.equals(action)){
mediaPlayer.reset();
try {
mediaPlayer.setDataSource(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)+ File.separator+"qjtx.mp3");
mediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}else if (ACTION_PAUSE.equals(action)){
if (mediaPlayer.isPlaying()) mediaPlayer.pause();
}else if (ACTION_EXIT.equals(action)){
if (mediaPlayer.isPlaying())mediaPlayer.stop();
mediaPlayer.release();
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
}
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class Main3Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
}
public void play(View v){
Intent intent=new Intent(this,MusicService.class);
intent.setAction(MusicService.ACTION_PLAY);
startService(intent);
}
public void pause(View v){
Intent intent=new Intent(this,MusicService.class);
intent.setAction(MusicService.ACTION_PAUSE);
startService(intent);
}
public void exit(View v){
Intent intent=new Intent(this,MusicService.class);
intent.setAction(MusicService.ACTION_EXIT);
startService(intent);
}
}
作为前台服务运行
@TargetApi(Build.VERSION_CODES.O)
private void notification() {
String id ="channel_1";//channel的id
String description = "123";//channel的描述信息
int importance = NotificationManager.IMPORTANCE_LOW;//channel的重要性
NotificationChannel channel = new NotificationChannel(id, "123", importance);//生成channel
Notification.Builder builder=new Notification.Builder(this,id);
builder.setTicker("我的第一个音乐播放器");
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("我的音乐播放器");
builder.setContentInfo("正在播放");
PendingIntent pi=PendingIntent.getActivity(this,0,new Intent(this,Main3Activity.class),PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pi);
NotificationManager nm= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.createNotificationChannel(channel);
Notification notification=builder.build();
startForeground(0,notification);
nm.notify(0,notification);
}
注意,在sdk版本为25或25之前想在notification中添加一个点击事件 只要通过setContentIntent()传入一个PendingIntent就可以实现通知点击事件。但是26之后引入了一个叫NotificationChannel的类 在sdk版本为26的时候 我们不加这个东西 就设置用不了点击事件啦
具体分析参考博客:解决Fail to post notification on channel "null"的方法
从ContentResolver获取媒体内容
查询音乐列表
public void queryMusic(View v){
ContentResolver cr=getContentResolver();
Cursor c= cr.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null,null,null,null);
if(c!=null){
while (c.moveToNext()){
String url= c.getString(c.getColumnIndex(MediaStore.Audio.Media.DATA));
String songName= c.getString(c.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));
String artist= c.getString(c.getColumnIndex(MediaStore.Audio.Media.ARTIST));
System.out.println("路径:"+url);
System.out.println("歌名:"+songName);
System.out.println("歌手:"+artist);
System.out.println("---------------------");
}
}