使用Service後臺服務實現播放器
package com.example.day121lx;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;
import android.widget.RemoteViews;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class MyService extends Service {
private MediaPlayer mediaPlayer;
private int index=0;
private int playmusic=1;
private List<Music> list=new ArrayList<>();
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
mediaPlayer = new MediaPlayer();
list = MusicUtil.getDate(this);
}
class MyBinder extends Binder{
public void callplay(int position){
play(position);
}
//暫停播放 在Fragment裏邊調用方法
public int zt(){
mediaPlayer.pause();
return 0;
}
//繼續播放 在Fragment裏邊調用方法
public int jx(){
mediaPlayer.start();
return 0;
}
//上一首 在Fragment裏邊調用方法
public void shang(){
if (--index<=0){
index=list.size()-1;
}
play(index);
}
//下一首 在Fragment裏邊調用方法
public void next(){
if (++index>=list.size()){
index=list.size();
index=0;
}
play(index);
}
//進度條
public void seekbar(int p){
mediaPlayer.seekTo(p);
}
//進度條最大值
public int getMax(){
return mediaPlayer.getDuration();
}
//進度條當前位置
public int getp(){
return mediaPlayer.getCurrentPosition();
}
//判斷播放模式 在Fragment裏邊調用方法
public void flish(int i){
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
switch (playmusic){
case MusicUtil.SHUNXU:
next();
break;
case MusicUtil.SUIJI:
int i = new Random().nextInt(list.size());
play(i);
break;
case MusicUtil.DANQU:
play(index);
break;
}
}
});
playmusic=i;
//註冊廣播
MyBro myBro = new MyBro();//廣播接收者
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.wang");
registerReceiver(myBro,intentFilter);
}
}
@SuppressLint("WrongConstant")
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//通知上邊音樂界面
Notification.Builder builder = new Notification.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
//遠程佈局
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.inf_layout);
builder.setCustomContentView(remoteViews);
Intent intent1 = new Intent();
intent1.setAction("com.wang");
PendingIntent broadcast = PendingIntent.getBroadcast(this, 0, intent1, 0);
remoteViews.setOnClickPendingIntent(R.id.zanting,broadcast);
startForeground(1,builder.build());
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
//開始播放音樂 在Fragment裏邊調用方法
public void play(int position){
mediaPlayer.reset();
index=position;
try {
mediaPlayer.setDataSource(list.get(position).getData());
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
//廣播接收者
class MyBro extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals("com.wang")){
mediaPlayer.pause();
}
}
}
}
自定義封裝Music類
package com.example.day121lx;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import java.util.ArrayList;
import java.util.List;
public class MusicUtil {
public static final int DANQU=3;
public static final int SUIJI=2;
public static final int SHUNXU=1;
public static List<Music> getDate(Context context) {
List<Music> list = new ArrayList<>();
//內容解析者
ContentResolver contentResolver = context.getContentResolver();
//查詢本地音樂文件
Cursor query = contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
if (query != null) {
while (query.moveToNext()) {
String title = query.getString(query.getColumnIndex(MediaStore.Audio.Media.TITLE));
String artist = query.getString(query.getColumnIndex(MediaStore.Audio.Media.ARTIST));
String duration = query.getString(query.getColumnIndex(MediaStore.Audio.Media.DURATION));
String data = query.getString(query.getColumnIndex(MediaStore.Audio.Media.DATA));
String size = query.getString(query.getColumnIndex(MediaStore.Audio.Media.SIZE));
String albumId = query.getString(query.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
Music music = new Music(title, artist, duration, data, size, albumId);
list.add(music);
}
query.close();
}
return list;
}
//獲取專輯圖片
public static String getPic(Context context,String albumId){
ContentResolver contentResolver = context.getContentResolver();
Uri parse = Uri.parse("content://media/external/audio/albums/" + albumId);
Cursor query = contentResolver.query(parse, null, null, null, null);
if (query!=null){
boolean b = query.moveToNext();
if (b){
String album_art = query.getString(query.getColumnIndex("album_art"));
return album_art;
}
query.close();
}
return null;
}
//同步音樂時長
public static String fmtTime(String s){
int i = Integer.parseInt(s);
if (i / 1000 % 60 < 10){
return i / 1000 / 60 +":0" + i / 1000 % 60;
}
return i /1000 /60 +":" + i / 1000 % 60;
}
}
利用Fragment+RadioGroup實現頁面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Main4Activity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/a11"
android:layout_weight="8"
android:orientation="vertical"
></LinearLayout>
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="bottom"
android:id="@+id/group"
>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="音樂"
android:button="@null"
android:drawableTop="@drawable/style1"
android:gravity="center"
android:layout_weight="1"
android:id="@+id/a1"
></RadioButton>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="音樂"
android:gravity="center"
android:drawableTop="@drawable/style1"
android:button="@null"
android:layout_weight="1"
android:id="@+id/a2"
></RadioButton>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="音樂"
android:drawableTop="@drawable/style1"
android:gravity="center"
android:layout_weight="1"
android:button="@null"
android:id="@+id/a3"
></RadioButton>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="音樂"
android:button="@null"
android:gravity="center"
android:drawableTop="@drawable/style1"
android:layout_weight="1"
android:id="@+id/a4"
></RadioButton>
</RadioGroup>
</LinearLayout>
blic class Main4Activity extends AppCompatActivity {
private LinearLayout a11;
private RadioGroup group;
private RadioButton a1;
private RadioButton a2;
private RadioButton a3;
private RadioButton a4;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
FragmentManager supportFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.a11,new BlankFragment4());
fragmentTransaction.commit();
a11 = (LinearLayout) findViewById(R.id.a11);
group = (RadioGroup) findViewById(R.id.group);
a1 = (RadioButton) findViewById(R.id.a1);
a2 = (RadioButton) findViewById(R.id.a2);
a3 = (RadioButton) findViewById(R.id.a3);
a4 = (RadioButton) findViewById(R.id.a4);
group.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId){
case R.id.a1:
FragmentManager supportFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.a11,new BlankFragment4());
fragmentTransaction.commit();
break;
case R.id.a2:
FragmentManager supportFragmentManager1 = getSupportFragmentManager();
FragmentTransaction fragmentTransaction1 = supportFragmentManager1.beginTransaction();
fragmentTransaction1.replace(R.id.a11,new BlankFragment5());
fragmentTransaction1.commit();
break;
}
}
});
}
}
自定義Music類
package com.example.day121lx;
public class Music {
private String title;
private String artist;
private String duartion;
private String data;
private String size;
private String albumId;
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public String toString() {
return "Music{" +
"title='" + title + '\'' +
", artist='" + artist + '\'' +
", duartion='" + duartion + '\'' +
", data='" + data + '\'' +
", size='" + size + '\'' +
", albumId='" + albumId + '\'' +
", id=" + id +
'}';
}
public Music(Integer id) {
this.id = id;
}
public Music(String title, String artist, String duartion, String data, String size, String albumId) {
this.title = title;
this.artist = artist;
this.duartion = duartion;
this.data = data;
this.size = size;
this.albumId = albumId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getDuartion() {
return duartion;
}
public void setDuartion(String duartion) {
this.duartion = duartion;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
public String getAlbumId() {
return albumId;
}
public void setAlbumId(String albumId) {
this.albumId = albumId;
}
public Music() {
}
}
適配器
package com.example.day121lx;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.util.List;
public class MyAdapter extends BaseAdapter {
private List<Music> list;
private Context context;
public MyAdapter(List<Music> list, Context context) {
this.list = list;
this.context = context;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder=null;
if (convertView==null){
holder=new ViewHolder();
convertView = convertView.inflate(context, R.layout.lv_layout, null);
holder.title = convertView.findViewById(R.id.title);
holder.artist = convertView.findViewById(R.id.artist);
holder.duration = convertView.findViewById(R.id.duration);
holder.lv_img = convertView.findViewById(R.id.lv_img);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
Music music=list.get(position);
holder.artist.setText(music.getArtist());
holder.title.setText(music.getTitle());
holder.duration.setText(MusicUtil.fmtTime(list.get(position).getDuartion()));
Glide.with(context).load(MusicUtil.getPic(context,music.getAlbumId())).into(holder.lv_img);
return convertView;
}
class ViewHolder{
TextView title;
TextView artist;
TextView duration;
ImageView lv_img;
}
}
音樂展示佈局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@mipmap/ic_launcher"
android:id="@+id/lv_img"
></ImageView>
<TextView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="111"
android:id="@+id/title"
></TextView>
<TextView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="222"
android:id="@+id/artist"
android:layout_marginLeft="100dp"
></TextView>
<TextView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="333"
android:id="@+id/duration"
android:layout_marginTop="30dp"
android:layout_marginLeft="-100dp"
></TextView>
</LinearLayout>
</LinearLayout>
Fragment音樂界面整體效果佈局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
tools:context=".BlankFragment4">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/lv"
android:layout_weight="8"
></ListView>
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/seekbar"
></SeekBar>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/shangyishou"
android:id="@+id/shang"
android:layout_marginLeft="80dp"
></ImageView>
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/bofang2"
android:id="@+id/bofang"
></ImageView>
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/bofang2"
android:id="@+id/bofang1"
></ImageView>
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/xiayishou"
android:id="@+id/next"
></ImageView>
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/moshi"
android:id="@+id/model"
></ImageView>
</LinearLayout>
</LinearLayout>
Fragment代碼
package com.example.day121lx;
import android.Manifest;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
/**
* A simple {@link Fragment} subclass.
*/
public class BlankFragment4 extends Fragment {
private List<Music> list;
private ListView lv;
private ImageView shang;//上一首
private ImageView next;//下一首
private ImageView bofang;
private SeekBar seekbar;
private ImageView bofang1;
private ImageView model;//模式
private Timer timer;
private MyService.MyBinder myBinder;
public BlankFragment4() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View inflate = inflater.inflate(R.layout.fragment_blank_fragment4, container, false);
lv = (ListView)inflate. findViewById(R.id.lv);
seekbar = (SeekBar)inflate. findViewById(R.id.seekbar);
shang = (ImageView)inflate. findViewById(R.id.shang);
next = (ImageView)inflate. findViewById(R.id.next);
bofang1 = (ImageView)inflate. findViewById(R.id.bofang1);
bofang = (ImageView) inflate.findViewById(R.id.bofang);
model = (ImageView) inflate.findViewById(R.id.model);
//初始化List
list=new ArrayList<>();
//模式點擊事件
model.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//使用popWindow彈窗實現
final PopupWindow popupWindow = new PopupWindow();
popupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
//單曲循環
View inflate1 = LayoutInflater.from(getActivity()).inflate(R.layout.pop_layout, null);
final TextView danqu = inflate1.findViewById(R.id.pop_danqu);
danqu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myBinder.flish(MusicUtil.DANQU);
Toast.makeText(getActivity(), "單曲循環", Toast.LENGTH_SHORT).show();
popupWindow.dismiss();
}
});
//隨機播放
TextView suiji = inflate1.findViewById(R.id.pop_suiji);
suiji.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myBinder.flish(MusicUtil.SUIJI);
Toast.makeText(getActivity(), "隨機播放", Toast.LENGTH_SHORT).show();
popupWindow.dismiss();
}
});
TextView shunxu = inflate1.findViewById(R.id.pop_shunxu);
shunxu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myBinder.flish(MusicUtil.SHUNXU);
Toast.makeText(getActivity(), "順序播放", Toast.LENGTH_SHORT).show();
popupWindow.dismiss();
}
});
//內容
popupWindow.setContentView(inflate1);
//點擊對話框消失
popupWindow.setOutsideTouchable(true);
popupWindow.showAsDropDown(model,0,-350);
}
});
//進度條
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser){
//後臺服務調用方法
myBinder.seekbar(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
//點擊暫停更換圖片
bofang.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myBinder.zt();
bofang.setImageResource(R.drawable.bofang2);
bofang1.setImageResource(R.drawable.bofang2);
}
});
//點擊繼續圖片更換
bofang1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myBinder.jx();
bofang1.setImageResource(R.drawable.bofang1);
}
});
//上一首
shang.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myBinder.shang();
}
});
//下一首
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myBinder.next();
}
});
//啓動一個後臺服務
Intent intent = new Intent(getActivity(),MyService.class);
getActivity().startService(intent);
//跟Service服務進行綁定
ServiceConnection serviceConnection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder= (MyService.MyBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
getActivity().bindService(intent,serviceConnection,Context.BIND_ABOVE_CLIENT);
//版本判斷
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
//讀取SD卡權限
requestPermissions(new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE},100);
}
//ListView點擊事件
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//調用服務方法
myBinder.callplay(position);
bofang.setImageResource(R.drawable.bofang1);
myBinder.flish(position);
if (timer==null){
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
//設置進度條進度
seekbar.setMax(myBinder.getMax());
seekbar.setProgress(myBinder.getp());
}
},0,1000);
}
}
});
// Inflate the layout for this fragment
return inflate;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
//判斷是否同意讀取sd卡
if (requestCode==100&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
list = MusicUtil.getDate(getActivity());
MyAdapter myAdapter = new MyAdapter(list,getActivity());
lv.setAdapter(myAdapter);
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}