清單文件加權(quán)限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Mainactivity代碼
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView name;
private Button last;
private Button play;
private Button stop;
private Button next;
private static SeekBar progress;
private RelativeLayout bottom;
private Button bendi;
private RelativeLayout top;
private ListView listview;
private List<Music> list;
private ServiceConnection connection;
private Button just_one;
private static MyMusicService.MusicBiner biner;
public static Handler handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what == 111) {
int i = msg.arg1;
progress.setProgress(i);
} else if (msg.what == 810) {
biner.callpause();
}
else if (msg.what == 820) {
biner.callrestart();
}
else if (msg.what == 830) {
biner.calllast();
}
else if (msg.what == 840) {
biner.callnext();
}
else if (msg.what == 728) {
biner.callnext();
}
}
};
@TargetApi(Build.VERSION_CODES.M)
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
requestPermissions(new String []{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE},100);
list = MusicUtils.getlist(this);
initView();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.notify.pause");
intentFilter.addAction("com.notify.play");
intentFilter.addAction("com.notify.last");
intentFilter.addAction("com.notify.next");
MyReceiver myReceiver = new MyReceiver();
registerReceiver(myReceiver, intentFilter);
Intent intent1 = new Intent(MainActivity.this, MyMusicService.class);
startService(intent1);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
biner.callplay(i);
progress.setMax((int) list.get(i).getDuration());
}
});
//啟動(dòng)
Intent intent = new Intent(this, MyMusicService.class);
startService(intent);
connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
biner = (MyMusicService.MusicBiner) iBinder;
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
bindService(intent, connection, Service.BIND_AUTO_CREATE);
progress.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if (b) {
biner.callseek(i);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if(connection!=null){
unbindService(connection);
}
}
private void initView() {
name = (TextView) findViewById(R.id.name);
last = (Button) findViewById(R.id.last);
play = (Button) findViewById(R.id.play);
stop = (Button) findViewById(R.id.stop);
next = (Button) findViewById(R.id.next);
progress = (SeekBar) findViewById(R.id.progress);
bottom = (RelativeLayout) findViewById(R.id.bottom);
bendi = (Button) findViewById(R.id.bendi);
top = (RelativeLayout) findViewById(R.id.top);
listview = (ListView) findViewById(R.id.listview);
last.setOnClickListener(this);
play.setOnClickListener(this);
stop.setOnClickListener(this);
next.setOnClickListener(this);
bendi.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.last:
biner.calllast();
break;
case R.id.play:
biner.callrestart();
break;
case R.id.stop:
biner.callpause();
break;
case R.id.next:
biner.callnext();
break;
case R.id.bendi:
MyAdapter myAdapter = new MyAdapter(list, MainActivity.this);
listview.setAdapter(myAdapter);
break;
}
}
}
Main布局代碼
<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"
android:padding="20dp"
>
<RelativeLayout
android:id="@+id/bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
>
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minLines="1" />
<Button
android:id="@+id/last"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="last"
/>
<Button
android:id="@+id/play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/last"
android:text="play"
/>
<Button
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/play"
android:text="stop"
/>
<Button
android:id="@+id/next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/stop"
android:layout_centerVertical="true"
android:text="next"
/>
<SeekBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/play"
android:layout_marginTop="20dp"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/top"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/bendi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="加載本地音樂(lè)"
/>
<Button
android:id="@+id/just_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="單曲循環(huán)"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/top"
android:layout_above="@id/bottom"
/>
</RelativeLayout>
musiclayout代碼
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
>
<TextView
android:id="@+id/music_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:text="未知歌曲"/>
<TextView
android:id="@+id/person_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/music_name"
android:textSize="16dp"
android:text="未知歌手"/>
<TextView
android:id="@+id/music_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:textSize="18dp"
android:text="歌曲時(shí)長(zhǎng)"/>
</RelativeLayout>
notificationlayout代碼
<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_weight="1"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="0dp">
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/Button_pause_Broad"
android:text="暫停"
/>
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/Button_restart_Broad"
android:text="繼續(xù)播放"
/>
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/Button_last_Broad"
android:text="上一首"
/>
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/Button_next_Broad"
android:text="下一首"
/>
</LinearLayout>
</LinearLayout>
Music實(shí)體類
public class Music {
private String title;
private String artist;
private String data;
private long duration;
private int size;
private int position;
public Music(String title, String artist, String data, long duration, int size, int position) {
this.title = title;
this.artist = artist;
this.data = data;
this.duration = duration;
this.size = size;
this.position = position;
}
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 getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
}
Music工具類
public class MusicUtils {
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public static List<Music> getlist(Context context) {
List<Music> list = new ArrayList<>();
int position = 0;
ContentResolver resolver = context.getContentResolver();
Cursor cursor = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));
int size = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE));
position++;
Music music = new Music(title, artist, data, duration, size, position);
list.add(music);
}
cursor.close();
return list;
} else {
Toast.makeText(context, "沒(méi)有資源", Toast.LENGTH_SHORT).show();
}
return null;
}
}
適配器代碼
public class MyAdapter extends BaseAdapter {
private List<Music> list;
private LayoutInflater layoutInflater;
private Context context;
public MyAdapter(List<Music> list, Context context) {
this.list = list;
this.context = context;
layoutInflater=LayoutInflater.from(context);
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int i) {
return list.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
if(view==null){
view = layoutInflater.inflate(R.layout.musiclayout, null);
viewHolder=new ViewHolder();
viewHolder.first=view.findViewById(R.id.music_name);
viewHolder.second=view.findViewById(R.id.person_name);
viewHolder.third=view.findViewById(R.id.music_time);
view.setTag(viewHolder);
}
else{
viewHolder = (ViewHolder) view.getTag();
}
viewHolder.first.setText(list.get(i).getTitle());
viewHolder.second.setText(list.get(i).getArtist());
long duration = list.get(i).getDuration();
long fen=duration/60000;
long miao=(duration%60000)/1000;
viewHolder.third.setText(fen+"分"+miao+"秒");
return view;
}
class ViewHolder{
TextView first,second,third;
}
}
服務(wù)代碼
public class MyMusicService extends Service {
private MediaPlayer mediaPlayer;
private List<Music> list;
private int index;
private Handler handler = new Handler();
private Notification.Builder builder;
public MyMusicService() {
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onCreate() {
super.onCreate();
mediaPlayer = new MediaPlayer();
list = MusicUtils.getlist(getApplicationContext());
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
MusicBiner musicBiner = new MusicBiner();
return musicBiner;
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
builder = new Notification.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
RemoteViews views = new RemoteViews(getPackageName(), R.layout.notificationlayout);
//第一個(gè)按鈕的點(diǎn)擊邏輯
/**
* 通過(guò)一個(gè)PendingIntent 發(fā)送一個(gè)intent.
* getBroadcast的方法是跳往廣播的一個(gè)intent.
* getBroadcast的參數(shù),1,上下文,2是請(qǐng)求碼唯一即可,3,intent對(duì)象,4,PendingIntent的創(chuàng)建方式.
* setOnClickPendingIntent.這個(gè)方法可以給組件設(shè)置一個(gè)點(diǎn)擊事件.參數(shù):1,組件id,2pendingIntent對(duì)象
* 也就是點(diǎn)擊以后要跳轉(zhuǎn)到何方.
*/
Intent intent1 = new Intent();
intent1.setAction("com.notify.pause");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 150, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.Button_pause_Broad, pendingIntent);
Intent intent2 = new Intent();
intent2.setAction("com.notify.play");
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(this, 160, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.Button_restart_Broad, pendingIntent2);
Intent intent3 = new Intent();
intent3.setAction("com.notify.last");
PendingIntent pendingIntent3 = PendingIntent.getBroadcast(this, 170, intent3, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.Button_last_Broad, pendingIntent3);
Intent intent4 = new Intent();
intent4.setAction("com.notify.next");
PendingIntent pendingIntent4 = PendingIntent.getBroadcast(this, 180, intent4, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.Button_next_Broad, pendingIntent4);
//設(shè)置通知的布局
builder.setContent(views);
// builder.setCustomContentView(views);
//開(kāi)始一個(gè)前臺(tái)服務(wù)
startForeground(1, builder.build());
return super.onStartCommand(intent, flags, startId);
}
public class MusicBiner extends Binder {
public void callplay(int position) {
playmusic(position);
index = position;
}
public void callpause() {
pause();
}
public void callrestart() {
restart();
}
public void calllast() {
last();
}
public void callnext() {
next();
}
public void callseek(int i) {
seek(i);
}
}
public void seek(int i) {
mediaPlayer.seekTo(i);
}
public void next() {
if (++index > list.size() - 1) {
index = 0;
}
playmusic(index);
}
public void last() {
if (--index < 0) {
index = list.size() - 1;
}
playmusic(index);
}
public void restart() {
mediaPlayer.start();
}
public void pause() {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
}
public void playmusic(final int position) {
mediaPlayer.reset();
Music music = list.get(position);
try {
mediaPlayer.setDataSource(music.getData());
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(final MediaPlayer mediaPlayer) {
mediaPlayer.start();
Timer timer = new Timer();//定時(shí)器 走進(jìn)度條
timer.schedule(new TimerTask() {
@Override
public void run() {
int currentPosition = mediaPlayer.getCurrentPosition();
Message message = Message.obtain();
message.arg1 = currentPosition;
message.what = 111;
MainActivity.handler.sendMessage(message);
if(currentPosition==mediaPlayer.getDuration()){
MainActivity.handler.sendEmptyMessage(728);
}
}
}, 0, 1000);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
廣播代碼
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.i("TAG","進(jìn)來(lái)了廣播");
if(action.equals("com.notify.pause")){
MainActivity.handler.sendEmptyMessage(810);
}
else if(action.equals("com.notify.play")){
MainActivity.handler.sendEmptyMessage(820);
}
else if(action.equals("com.notify.last")){
MainActivity.handler.sendEmptyMessage(830);
}
else if(action.equals("com.notify.next")){
MainActivity.handler.sendEmptyMessage(840);
}
}
}