-
簡介
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("---------------------");
}
}