参考博客:https://blog.csdn.net/cbbbc/article/details/46789151
Android的多媒体框架包括支持播放多种常见的媒体类型,使您可以轻松地把音频、视频和图像集成到你的应用。你可以播放音频或视频媒体文件,这些文件是存储在你的应用程序的资源文件中的。应用程序的资源文件可以是文件系统中独立的文件,或通过网络连接获取的一个数据流,所有使用MediaPlayer APIS的资源文件。
注意:你只能在啊标准输出设备上播放音频数据。目前,标准输出设备是移动设备的扬声器或耳机,你不能再桃花音频调用期播放声音文件。
下面是Android框架中用于播放声音的类。
MediaPlayer:这个类主要用于播放声音和视频
AudioManager:这个类主要管理音频和音频输出设备
清单文件声明:
Internet许可-如果你是用的是基于网络内容的流媒体播放器,你的应用程序必须请求访问网络:
< uses-permission android:name="android.permission.INTERNET"/>
如果你的播放应用需要组织屏幕变暗或组织处理器睡眠,或使用MediaPlayer.setScreenOnWhilePlaying()或MediaPlayer.setWakeMode()方法,你必须请求此权限:
< uses-permission android:name="android.permission.WAKE_LOCK"/>
媒体框架最重要的组件之一是MediaPlayer类。此类的一个对象可以通过最少的设置来获取,解码和播放音频和视频。 它支持几种不同的媒体来源,如:
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// 播放本地资源文件
public void playFromRes(View view) {
MediaPlayer mp = MediaPlayer.create(this,R.raw.m2);//做了mp.prepare();
mp.start();
}
//播放系统文件需要权限
public void playFromSys(View view) {
MediaPlayer mp = new MediaPlayer();
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)+"/m2.mp3";
try {
mp.setDataSource(this, Uri.parse(path));//设置数据源
mp.prepare();//同步执行
mp.start();
} catch (IOException e) {
e.printStackTrace();
}
}
//播放网络文件,需要权限
public void playFromInternet(View view) {
String path = "http://wsaudio.bssdlbig.kugou.com/1904241105/KRFl0-837FZsule-bChmqQ/1556161531/bss/extname/wsaudio/9c148f1eda56b3a4fde051e431954962.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();
}
}
}
使用MediaPlayer
MediaPlayer可能消耗大量的系统资源。因此你应该总是采取一些额外的错事来确保在一个MediaPlayer实例上不会挂起太长的事件,当以用完MediaPlayer时,应该调用release()来保证任何分配给MediaPlayer的系统资源被正确地释放
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 MainActivity2 extends AppCompatActivity implements View.OnClickListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener {
private MediaPlayer mp;
private int index = 0;//表示当前要播放的音乐的索引
private ArrayList musicList = new ArrayList<>();
private Button button_prev,button_play,button_pause,button_next;
private boolean isPause = true;//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_prev = (Button)findViewById(R.id.button_prev);
button_play = (Button)findViewById(R.id.button_play);
button_pause = (Button)findViewById(R.id.button_pause);
button_next = (Button)findViewById(R.id.button_next);
button_prev.setOnClickListener(this);
button_play.setOnClickListener(this);
button_pause.setOnClickListener(this);
button_next.setOnClickListener(this);
}
private void initMusic(){
String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getPath();
musicList.add(root + File.separator + "m1.mp3");
musicList.add(root + File.separator + "m2.mp3");
musicList.add(root + File.separator + "m3.mp3");
musicList.add(root + File.separator + "m4.mp3");
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button_play:
play();
break;
case R.id.button_pause:
pause();
break;
case R.id.button_next:
next();
break;
case R.id.button_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
布局:
如果你希望你的媒体在你的应用不出现在屏幕上时仍能在后台播放——也就是,你希望当用户与其它应用交互时仍能继续播放,那么你必须启动一个Service并且通过它来控制MediaPlayer实例。
权限:
< uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
package com.example.mediaapplication;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Environment;
import android.os.IBinder;
import java.io.File;
import java.io.IOException;
public class MusicService extends Service implements MediaPlayer.OnPreparedListener {
public static final String ACTION_PLAY = "com.example.ACTION_PLAY";
public static final String ACTION_PAUSE = "com.example.ACTION_PAUSE";
public static final String ACTION_EXIT = "com.example.ACTION_EXIT";
private MediaPlayer mediaPlayer;
public MusicService() {
}
@Override
public void onCreate() {
super.onCreate();
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(this);
}
@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+"m1.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) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
}
清单文件:
布局:
当你的MediaPlayer播放时,要保持CPU持续运行,在初始化MediaPlayer时需调用setWakeMode(),一旦你这样做了,MediaPlayer就会在播放时持有一个特定的锁,并在暂停或停止时释放它。
权限: < uses-permission android:name="android.permission.WAKE_LOCK"/>
使用唤醒锁
在后台播放媒体的应用时,当你的service正在运行时,设备可能进入休眠,因为Android刺痛在休眠时会试着节省电能,系统会试着关闭电话的任何不必要的特性,包括CPU和WIFI,然而,如果你的service正在播放或接收音乐,你就想阻止系统干涉你的播放工作,为了在上述情况下保证你的service继续运行,你必须使用“wakelocks”。
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.example.ACTION_PLAY";
public static final String ACTION_PAUSE = "com.example.ACTION_PAUSE";
public static final String ACTION_EXIT = "com.example.ACTION_EXIT";
private WifiManager.WifiLock lock;
private MediaPlayer mediaPlayer;
public MusicService() {
}
@Override
public void onCreate() {
super.onCreate();
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
lock = wifiManager.createWifiLock("mylock");
lock.acquire();
}
@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+"m1.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 void onDestroy() {
super.onDestroy();
lock.release();
}
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
}
修改Service中的以下内容
26以上版本需要加NotificationChannel,详见https://blog.csdn.net/weixin_40604111/article/details/78674563
@Override
public void onCreate() {
super.onCreate();
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
lock = wifiManager.createWifiLock("mylock");
lock.acquire();
notification();
}
private void notification() {
NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Notification.Builder builder = null;
if (Build.VERSION.SDK_INT >= 26) {
String id = "channel_1";
String description = "消息推送";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel(id, description, importance);
manager.createNotificationChannel(channel);
builder = new Notification.Builder(this,id);
}else {
builder = new Notification.Builder(this);
}
builder.setTicker("音乐播放器");
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("我的音乐播放器");
builder.setContentInfo("正在播放");
PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pi);
Notification notification = builder.build();
startForeground(0, notification);
manager.notify(0,notification);
}
@Override
public void onDestroy() {
super.onDestroy();
stopForeground(true);
lock.release();
}
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
public class MainActivity3 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
}
public void play(View view) {
Intent intent = new Intent(this,MusicService.class);
intent.setAction(MusicService.ACTION_PLAY);
startService(intent);
}
public void pause(View view) {
Intent intent = new Intent(this,MusicService.class);
intent.setAction(MusicService.ACTION_PAUSE);
startService(intent);
}
public void stop(View view) {
Intent intent = new Intent(this,MusicService.class);
intent.setAction(MusicService.ACTION_EXIT);
startService(intent);
}
}
运行结果:
//MusicService.java
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.annotation.RequiresApi;
import java.io.File;
import java.io.IOException;
public class MusicService extends Service implements MediaPlayer.OnPreparedListener, AudioManager.OnAudioFocusChangeListener {
public static final String ACTION_PLAY = "com.example.ACTION_PLAY";
public static final String ACTION_PAUSE = "com.example.ACTION_PAUSE";
public static final String ACTION_EXIT = "com.example.ACTION_EXIT";
public static final String ACTION_STOP = "com.example.ACTION_STOP";
private WifiManager.WifiLock lock;
private MediaPlayer mediaPlayer;
public MusicService() {
}
@Override
public void onCreate() {
super.onCreate();
//获取自身的焦点
AudioManager am = (AudioManager)getSystemService(AUDIO_SERVICE);
am.requestAudioFocus(this,AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN);
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(this);
}
private void initMediaPlayer() {
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
lock = wifiManager.createWifiLock("mylock");
lock.acquire();
notification();
}
@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+"m1.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();
}else if (ACTION_STOP.equals(action)){
if (mediaPlayer.isPlaying()) mediaPlayer.stop();
}
return super.onStartCommand(intent, flags, startId);
}
private void notification() {
NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Notification.Builder builder = null;
if (Build.VERSION.SDK_INT >= 26) {
String id = "channel_1";
String description = "消息推送";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel(id, description, importance);
manager.createNotificationChannel(channel);
builder = new Notification.Builder(this,id);
}else {
builder = new Notification.Builder(this);
}
builder.setTicker("音乐播放器");
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("我的音乐播放器");
builder.setContentInfo("正在播放");
PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pi);
Notification notification = builder.build();
startForeground(0, notification);
manager.notify(0,notification);
}
@Override
public void onDestroy() {
super.onDestroy();
stopForeground(true);
lock.release();
}
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
@Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange){
case AudioManager.AUDIOFOCUS_GAIN:
//已获取焦点
initMediaPlayer();
mediaPlayer.setVolume(1.0f,1.0f);
break;
case AudioManager.AUDIOFOCUS_LOSS:
//长期失去焦点
if (mediaPlayer!=null){
if (mediaPlayer.isPlaying()) mediaPlayer.stop();
mediaPlayer.release();
}
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
//失去了焦点,但很快会获得
if (mediaPlayer!=null){
if (mediaPlayer.isPlaying()) mediaPlayer.stop();
}
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
//允许低音量播放
if (mediaPlayer.isPlaying()) mediaPlayer.setVolume(0.1f,0.1f);
break;
}
}
}
//MusicIntentReceiver.java
public class MusicIntentReceiver extends BroadcastReceiver {
private static final String action = "android.media.AUDIO_BECOMING_NOISY";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(action)){
Intent intent1 = new Intent(MusicService.ACTION_STOP);
context.startService(intent);
}
}
}