布局
主界面的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<TextView
android:id="@+id/head"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="卤 蛋 的 音 乐"
android:gravity="center"
android:textColor="#FF5722"
android:textSize="30sp"
/>
<ListView
android:id="@+id/lv"
android:layout_above="@+id/footer"
android:layout_below="@+id/head"
android:layout_width="match_parent"
android:layout_height="match_parent"></ListView>
<RelativeLayout
android:id="@+id/footer"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="100dp">
<ImageView
android:id="@+id/footer_pic"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@mipmap/ic_launcher"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"/>
<TextView
android:layout_marginTop="5dp"
android:id="@+id/footer_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是歌曲的名字"
android:layout_toRightOf="@+id/footer_pic"
android:layout_marginLeft="20dp"
android:textColor="#000"/>
<SeekBar
android:id="@+id/footer_seekbar"
android:layout_width="350dp"
android:layout_height="wrap_content"
android:layout_below="@+id/footer_name"
android:layout_marginLeft="20dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="@+id/footer_pic" />
<ImageButton
android:id="@+id/footer_list"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/playbar_btn_playlist"
android:layout_below="@id/footer_seekbar"
android:layout_toRightOf="@id/footer_pic"
android:layout_marginLeft="20dp"/>
<ImageButton
android:id="@+id/footer_left"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/playbar_btn_prev"
android:layout_below="@id/footer_seekbar"
android:layout_toRightOf="@id/footer_list"
android:layout_marginLeft="20dp"/>
<ImageButton
android:id="@+id/footer_start"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/playbar_btn_play"
android:layout_below="@id/footer_seekbar"
android:layout_toRightOf="@id/footer_left"
android:layout_marginLeft="20dp"
/>
<ImageButton
android:id="@+id/footer_stop"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/stop"
android:layout_below="@id/footer_seekbar"
android:layout_toRightOf="@id/footer_left"
android:layout_marginLeft="20dp"
android:visibility="gone"
/>
<ImageButton
android:id="@+id/footer_right"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/playbar_btn_next"
android:layout_below="@id/footer_seekbar"
android:layout_alignParentRight="true"
android:layout_marginRight="70dp"
android:layout_marginLeft="20dp"/>
</RelativeLayout>
</RelativeLayout>
条目的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@mipmap/ic_launcher"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"/>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/iv"
android:layout_marginTop="10dp"
android:text="歌曲的名字"
android:layout_marginLeft="15dp"
android:textSize="20sp"
android:textColor="#000"/>
<TextView
android:layout_marginLeft="40dp"
android:id="@+id/author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="歌手"
android:layout_below="@+id/title"
android:layout_toRightOf="@+id/iv"
android:layout_marginTop="40dp"/>
<TextView
android:layout_marginLeft="40dp"
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="歌曲的时长"
android:layout_below="@+id/title"
android:layout_alignParentRight="true"
android:layout_marginTop="40dp"/>
</RelativeLayout>
``
### 通知的布局
```java
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/footer_pic"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@mipmap/ic_launcher"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"/>
<TextView
android:layout_marginTop="5dp"
android:id="@+id/notification_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是歌曲的名字"
android:layout_toRightOf="@+id/footer_pic"
android:layout_marginLeft="20dp"
android:textColor="#000"/>
<ImageButton
android:id="@+id/notification_left"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/playbar_btn_prev"
android:layout_below="@id/notification_name"
android:layout_marginLeft="100dp"/>
<ImageButton
android:id="@+id/notification_start"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/playbar_btn_play"
android:layout_below="@id/notification_name"
android:layout_toRightOf="@id/notification_left"
android:layout_marginLeft="20dp"
/>
<ImageButton
android:id="@+id/notification_stop"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/stop"
android:layout_below="@id/notification_name"
android:layout_toRightOf="@id/notification_start"
android:layout_marginLeft="20dp"
/>
<ImageButton
android:layout_toRightOf="@+id/notification_stop"
android:id="@+id/notification_right"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/playbar_btn_next"
android:layout_below="@id/notification_name"
android:layout_marginRight="70dp"
android:layout_marginLeft="20dp"/>
</RelativeLayout>
代码
JavaBean
package com.example.day1024demo;
public class JavaBean {
private String title;
private String astist;
private String duration;
private String data;
private String siez;
public JavaBean() {
}
public JavaBean(String title, String astist, String duration, String data, String siez) {
this.title = title;
this.astist = astist;
this.duration = duration;
this.data = data;
this.siez = siez;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAstist() {
return astist;
}
public void setAstist(String astist) {
this.astist = astist;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public String getSiez() {
return siez;
}
public void setSiez(String siez) {
this.siez = siez;
}
@Override
public String toString() {
return "JavaBean{" +
"title='" + title + '\'' +
", astist='" + astist + '\'' +
", duration='" + duration + '\'' +
", data='" + data + '\'' +
", siez='" + siez + '\'' +
'}';
}
}
工具类
package com.example.day1024demo;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.provider.MediaStore;
import java.util.ArrayList;
import java.util.List;
public class MusicUtils {
public static List<JavaBean> totalist = new ArrayList<>();
public static final int ORDER = 0;
public static final int RANDOM = 1;
public static final int SINGLE = 2;
public static List<JavaBean> message(Context context){
List<JavaBean> totalist1 = 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));
if (Integer.parseInt(size)>1024*80){
JavaBean javaBean = new JavaBean(title,artist,duration,data,size);
totalist1.add(javaBean);
}
}
}
return totalist1;
}
}
适配器
package com.example.day1024demo;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.List;
public class MyAdapter extends BaseAdapter {
private List<JavaBean> totalist;
private Context context;
private LayoutInflater layoutInflater;
public MyAdapter(List<JavaBean> totalist, Context context) {
this.totalist = totalist;
this.context = context;
layoutInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return totalist.size();
}
@Override
public Object getItem(int position) {
return totalist.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 = layoutInflater.inflate(R.layout.layout_item,null);
holder.title = convertView.findViewById(R.id.title);
holder.author = convertView.findViewById(R.id.author);
holder.time = convertView.findViewById(R.id.time);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
int i = Integer.parseInt(totalist.get(position).getDuration());
String s;
if (i/1000%60 > 10){
s= i/1000/60+":"+i/1000%60;
}else{
s= i/1000/60+":0"+i/1000%60;
}
holder.time.setText(s);
holder.author.setText(totalist.get(position).getAstist());
holder.title.setText(totalist.get(position).getTitle());
return convertView;
}
class ViewHolder{
TextView title;
TextView author;
TextView time;
}
}
Main
package com.example.day1024demo;
import android.Manifest;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
private TextView head;
private ListView lv;
private RelativeLayout footer;
private ImageView footerPic;
public static TextView footerName;
private static SeekBar footerSeekbar;
private ImageButton footerList;
private ImageButton footerLeft;
private static ImageButton footerStart;
private static ImageButton footerStop;
private ImageButton footerRight;
public static Timer timer;
private MyAdapter myAdapter;
private static List<JavaBean> list;
public static int index = 0;
public static MyService.MyMusic binder;
private static String TAG = "MainActivity";
public static Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
if (msg.what == 100){
footerStart.setVisibility(View.GONE);
footerStop.setVisibility(View.VISIBLE);
Log.i(TAG, "handleMessage: 播放音乐");
binder.callplay(index);
}
if (msg.what == 200){
footerStart.setVisibility(View.VISIBLE);
footerStop.setVisibility(View.GONE);
Log.i(TAG, "handleMessage: 暂停音乐");
binder.callpause();
}
if (msg.what == 300){
Log.i(TAG, "handleMessage: 下一首音乐");
binder.callnext();
timer();
}
if (msg.what == 400){
Log.i(TAG, "handleMessage: 上一首音乐");
binder.callback();
timer();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chushi();
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},100);
MusicReceiver musicReceiver = new MusicReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.ludan.start");
intentFilter.addAction("com.ludan.pause");
intentFilter.addAction("com.ludan.next");
intentFilter.addAction("com.ludan.back");
registerReceiver(musicReceiver,intentFilter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
footerSeekbar.setMax(binder.callsetMax());
index = position;
Log.i(TAG, "onItemClick: "+binder.toString());
footerName.setText(list.get(position).getTitle());
binder.callplay(position);
timer();
}
});
}
public static void timer() {
if (timer!=null){
timer.cancel();
}
footerSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser){
binder.callsetmusic(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
footerSeekbar.setProgress(binder.callsetprogress());
}
},0,100);
}
private void start() {
Intent intent = new Intent(this, MyService.class);
startService(intent);
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
binder = (MyService.MyMusic) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
bindService(intent,connection, Service.BIND_AUTO_CREATE);
}
private void chushi() {
head = (TextView) findViewById(R.id.head);
lv = (ListView) findViewById(R.id.lv);
footer = (RelativeLayout) findViewById(R.id.footer);
footerPic = (ImageView) findViewById(R.id.footer_pic);
footerName = (TextView) findViewById(R.id.footer_name);
footerSeekbar = (SeekBar) findViewById(R.id.footer_seekbar);
footerList = (ImageButton) findViewById(R.id.footer_list);
footerLeft = (ImageButton) findViewById(R.id.footer_left);
footerStart = (ImageButton) findViewById(R.id.footer_start);
footerStop = (ImageButton) findViewById(R.id.footer_stop);
footerRight = (ImageButton) findViewById(R.id.footer_right);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 100 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
start();
list = MusicUtils.message(this);
myAdapter = new MyAdapter(list,this);
lv.setAdapter(myAdapter);
}
}
}
Service服务
package com.example.day1024demo;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.RemoteViews;
import java.io.IOException;
import java.util.List;
public class MyService extends Service {
private static final String TAG = "MyService";
public static List<JavaBean> list;
private static MediaPlayer mediaPlayer;
private static int index;
private static Notification build;
private static RemoteViews remoteViews;
public MyService() {
}
@Override
public void onCreate() {
mediaPlayer = new MediaPlayer();
list = MusicUtils.message(this);
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Notification.Builder builder = new Notification.Builder(this);
builder.setSmallIcon(R.drawable.ic_launcher_background);
remoteViews = new RemoteViews(getPackageName(), R.layout.layout_notification);
Intent intent1 = new Intent();
intent1.setAction("com.ludan.start");
PendingIntent broadcast = PendingIntent.getBroadcast(this, 100, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.notification_start,broadcast);
Intent intent2 = new Intent();
intent2.setAction("com.ludan.pause");
PendingIntent broadcast1 = PendingIntent.getBroadcast(this, 110, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.notification_stop,broadcast1);
Intent intent3 = new Intent();
intent3.setAction("com.ludan.next");
PendingIntent broadcast2 = PendingIntent.getBroadcast(this, 120, intent3, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.notification_right,broadcast2);
Intent intent4 = new Intent();
intent4.setAction("com.ludan.back");
PendingIntent broadcast3 = PendingIntent.getBroadcast(this, 130, intent4, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.notification_left,broadcast3);
build = builder.build();
builder.setCustomContentView(remoteViews);
startForeground(10,build);
return super.onStartCommand(intent, flags, startId);
}
public class MyMusic extends Binder {
public void callplay(int i){
play(i);
}
public void callpause(){
pause();
}
public void callnext(){
next();
}
public void callback(){
back();
}
public int callsetMax(){
return setMax();
};
public int callsetprogress(){
return setprogress();
};
public void callsetmusic(int s){
setmusic(s);
}
}
@Override
public IBinder onBind(Intent intent) {
return new MyMusic();
}
public void play(int i){
index = i;
MainActivity.footerName.setText(list.get(index).getTitle());
remoteViews.setTextViewText(R.id.notification_name,list.get(i).getTitle());
startForeground(10,build);
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(list.get(i).getData());
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
public void pause(){
mediaPlayer.pause();
}
public void next(){
MainActivity.footerName.setText(list.get(index).getTitle());
if (++index > list.size()-1){
index = 0;
}else{
play(index);
}
}
public void back(){
MainActivity.footerName.setText(list.get(index).getTitle());
if (--index<0){
index = list.size()-1;
}else{
play(index);
}
}
public int setMax (){
return Integer.parseInt(list.get(index).getDuration());
};
public int setprogress(){
return mediaPlayer.getCurrentPosition();
};
public void setmusic(int s){
mediaPlayer.seekTo(s);
};
}
广播
package com.example.day1024demo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.util.Log;
public class MusicReceiver extends BroadcastReceiver {
private static final String TAG = "MusicReceiver";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.ludan.start")){
Log.i(TAG, "onReceive: 播放");
MainActivity.handler.sendEmptyMessage(100);
}else if (intent.getAction().equals("com.ludan.pause")){
Log.i(TAG, "onReceive: 暂停");
MainActivity.handler.sendEmptyMessage(200);
}else if (intent.getAction().equals("com.ludan.next")){
Log.i(TAG, "onReceive: 下一首");
MainActivity.handler.sendEmptyMessage(300);
}else if (intent.getAction().equals("com.ludan.back")){
Log.i(TAG, "onReceive: 上一首");
MainActivity.handler.sendEmptyMessage(400);
}
}
}