day22 音乐播放器+通知+服务

读取手机联系人

package com.example.mp;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/**
 * 自定义工具类
 * 查询本地歌曲
 */
public class ReadMyMusic {
    public static List<MyMusic> read(Context con){
        List<MyMusic> list=new ArrayList<>();
        Uri uri= MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        ContentResolver cr = con.getContentResolver();
        Cursor query = cr.query(uri, null, null, null, null);
        if( query!=null){
//            Toast.makeText(con, "没有读取到数据。", Toast.LENGTH_SHORT).show();
//            return null;
//        }else{
            int index=0;
            while (query.moveToNext()) {
                String title = query.getString(query.getColumnIndex(MediaStore.Audio.Media.TITLE));
                Toast.makeText(con, "title" + title, Toast.LENGTH_SHORT).show();
                String artist = query.getString(query.getColumnIndex(MediaStore.Audio.Media.ARTIST));
                String duration = query.getString(query.getColumnIndex(MediaStore.Audio.Media.DURATION));
                String size = query.getString(query.getColumnIndex(MediaStore.Audio.Media.SIZE));
                String data = query.getString(query.getColumnIndex(MediaStore.Audio.Media.DATA));
                MyMusic mm = new MyMusic();
                mm.setSize(Integer.parseInt(size));
                mm.setTitle(title);
                mm.setArtist(artist);
                mm.setData(data);
                mm.setPosition(index);
                mm.setDuration(duration);
                index++;
                list.add(mm);
                Toast.makeText(con, mm.toString(), Toast.LENGTH_SHORT).show();
            }
            Toast.makeText(con, "读取完毕。"+list.size(), Toast.LENGTH_SHORT).show();
            query.close();

        }
        return list;
    }
}

自定义Music类存储读取到的手机联系人

package com.example.mp;

public class MyMusic {
    //作曲家
    private String Artist;

    private String title;
    private String data;
    private long size;
    private int position;
    private String duration;

    @Override
    public String toString() {
        return "MyMusic{" +
                "Artist='" + Artist + '\'' +
                ", title='" + title + '\'' +
                ", data='" + data + '\'' +
                ", size=" + size +
                ", position=" + position +
                ", duration='" + duration + '\'' +
                '}';
    }

    public String getDuration() {
        return duration;
    }

    public void setDuration(String duration) {
        this.duration = duration;
    }

    public String getArtist() {
        return Artist;
    }

    public void setArtist(String artist) {
        Artist = artist;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public long getSize() {
        return size;
    }

    public void setSize(long size) {
        this.size = size;
    }

    public int getPosition() {
        return position;
    }

    public void setPosition(int position) {
        this.position = position;
    }
}

自定义适配器

向GridView添加数据

package com.example.mp;

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 Context con;
    private List<MyMusic> list;

    private MyId mi;
    public MyAdapter(Context con, List<MyMusic> list) {
        this.con = con;
        this.list = list;
    }

    @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) {
        if( convertView==null){
            convertView= LayoutInflater.from(con).inflate(R.layout.mylayout,null);
            mi=new MyId();
            mi.artist=convertView.findViewById(R.id.layout_artist);
            mi.title=convertView.findViewById(R.id.layout_title);
            mi.data=convertView.findViewById(R.id.layout_data);
            mi.size=convertView.findViewById(R.id.layout_tsize);
            mi.position=convertView.findViewById(R.id.layout_position);
            mi.duration=convertView.findViewById(R.id.layout_duration);
            convertView.setTag(mi);
        }else{
            mi= (MyId) convertView.getTag();
        }
        mi.duration.setText(list.get(position).getDuration());
        mi.artist.setText(list.get(position).getArtist());
        mi.title.setText(list.get(position).getTitle());
//        mi.position.setText(list.get(position).getPosition());
        mi.data.setText(list.get(position).getData());
        mi.size.setText(list.get(position).getSize()+"");
        return convertView;
    }
    class MyId{
        private TextView artist;
        private TextView title;
        private TextView data;
        private TextView size;
        private TextView position;
        private TextView duration;
    }
}

主界面

package com.example.mp;

import android.Manifest;
import android.annotation.SuppressLint;
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.Build;
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.Button;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.SeekBar;

import com.example.mp.MyBroadCast.MyReceiver;
import com.example.mp.MyService.MyService;

import java.sql.Time;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity {
    private List<MyMusic> read=new ArrayList<>();
    private GridView gridView;
    public static MyService.MyBinder binder;
    private static int index;
    private int radomIndex=-1;
    private int along=-1;
    private SeekBar sb;
    private Button but;
    @SuppressLint("HandlerLeak")
    public static Handler han=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            //判断广播的四种意图。
            super.handleMessage(msg);
            switch( msg.what){
                case 111:
                    index=binder.MyStart(index);
                    break;
                case 222:
                    binder.MyStop();
                    break;
                case 333:
                    index=binder.MyUp(index);
                    break;
                case 444:
                    index=binder.MyNext(index);
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化控件
        gridView=findViewById(R.id.main_grid);
        sb=findViewById(R.id.main_seekBar);
        but=findViewById(R.id.main_button_radom);
        //判断手机版本
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},205);
        }
        //开启服务。
        Intent it = new Intent(this, MyService.class);
        startService(it);
        ServiceConnection ss = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                binder= (MyService.MyBinder) service;
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        };
        bindService(it,ss, Service.BIND_AUTO_CREATE);
        //设置条目点击事件
        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                index=position;
                sb.setMax(Integer.parseInt(read.get(position).getDuration()));
                binder.MyStart(position);
                final Timer timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        final int i = binder.GetPosition();
                        han.post(new Runnable() {
                            @Override
                            public void run() {
                                sb.setProgress(i);
                            }
                        });
                    }
                },0,1000);
            }
        });
        //开启广播
        IntentFilter itf = new IntentFilter();
        //设置意图
        itf.addAction("com.notification.start");
        itf.addAction("com.notification.pause");
        itf.addAction("com.notification.next");
        itf.addAction("com.notification.up");
        MyReceiver mr = new MyReceiver();
        registerReceiver(mr,itf);

        //设置进度条滑动监听
        sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if( fromUser){
                    binder.Seek(progress);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }

    //请求权限
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if( requestCode==205&&grantResults[0]== PackageManager.PERMISSION_GRANTED){
            read = ReadMyMusic.read(MainActivity.this);
            MyAdapter aaa = new MyAdapter(MainActivity.this, read);
            gridView.setAdapter(aaa);
        }
    }
    //按钮添加点击事件。
    public void click(View view) {
        switch( view.getId()) {
            case R.id.main_button_start:
                binder.MyStart(index);
                break;
            case R.id.main_button_pause:
                binder.MyStop();
                break;
            case R.id.main_button_next:
                if( radomIndex!=-1){
                    Random random = new Random();
                    int radomIndex = random.nextInt(read.size() - 1) % (read.size() - 1-0+ 1) + 0;
                    binder.MyNext(radomIndex);
                }else{
                    index=binder.MyNext(index);
                }
                break;
            case R.id.main_button_up:
                if( radomIndex!=-1){
                    Random random = new Random();
                    int radomIndex = random.nextInt(read.size() - 1) % (read.size() - 1-0+ 1) + 0;
                    binder.MyNext(radomIndex);
                }else{
                    index=binder.MyNext(index);
                }
                break;
            case R.id.main_button_radom:
//                radomIndex=
                /**
                 * 以产生[10,99]范围内的随机数为例
                 *
                 * int min=10;
                 * int max=99;
                 * Random random = new Random();
                 * int num = random.nextInt(max)%(max-min+1) + min;
                 */
                if( but.getText().equals("随机播放")) {
                    Random random = new Random();
                    int radomIndex = random.nextInt(read.size() - 1) % (read.size() - 1 - 0 + 1) + 0;
                    binder.MyNext(radomIndex);
                    along=-1;
                    but.setText("正常播放");
                }else if( but.getText().equals("正常播放")){
                    radomIndex=-1;
                    but.setText("单曲循环");
                    index=binder.MyNext(index);
                }else if( but.getText().equals("单曲循环")){
                    along=index;
                    but.setText("随机播放");
                }
                break;
        }
    }
}

自定义服务器

在后台维护音乐播放器

package com.example.mp.MyService;

import android.app.Notification;
import android.app.NotificationManager;
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.widget.RemoteViews;

import com.example.mp.MyMusic;
import com.example.mp.R;
import com.example.mp.ReadMyMusic;

import java.io.IOException;
import java.util.List;

public class MyService extends Service {
    private List<MyMusic> list;
    private MediaPlayer mp;
    private int currentPosition;
    public MyService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        list= ReadMyMusic.read(getApplicationContext());
        mp=new MediaPlayer();

        mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {

            }
        });
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        NotificationManager ss = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        Notification.Builder builder = new Notification.Builder(getApplicationContext());
        builder.setSmallIcon(R.mipmap.ic_launcher_round);
        RemoteViews rv = new RemoteViews(getPackageName(), R.layout.mynotification);

        Intent it1 = new Intent();
        it1.setAction("com.notification.start");
        PendingIntent broadcast1 = PendingIntent.getBroadcast(getApplicationContext(), 111, it1,
                PendingIntent.FLAG_UPDATE_CURRENT);
        rv.setOnClickPendingIntent(R.id.notification_start,broadcast1);

        Intent it2 = new Intent();
        it2.setAction("com.notification.pause");
        PendingIntent broadcast2 = PendingIntent.getBroadcast(getApplicationContext(), 222, it2,
                PendingIntent.FLAG_UPDATE_CURRENT);
        rv.setOnClickPendingIntent(R.id.notification_pause,broadcast2);

        Intent it3 = new Intent();
        it3.setAction("com.notification.up");
        PendingIntent broadcast3 = PendingIntent.getBroadcast(getApplicationContext(), 333, it3,
                PendingIntent.FLAG_UPDATE_CURRENT);
        rv.setOnClickPendingIntent(R.id.notification_up,broadcast3);

        Intent it4 = new Intent();
        it4.setAction("com.notification.next");
        PendingIntent broadcast4 = PendingIntent.getBroadcast(getApplicationContext(), 444, it4,
                PendingIntent.FLAG_UPDATE_CURRENT);
        rv.setOnClickPendingIntent(R.id.notification_next,broadcast4);

         builder.setCustomContentView(rv);
        startForeground(310,builder.build());
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new MyBinder();
    }
    //可以从外部调用该类,并通过里面的方法实现播放和切换音乐的功能。
    public class MyBinder extends Binder{
        public int MyStart( int position){
            return start(position);
        }
        public void MyStop( ){
            stop();
        }
        public int MyNext( int position){
            return next(position);
        }
        public int MyUp( int position){
            return up(position);
        }
        public int GetPosition( ){
            return getPosition();
        }
        public void Seek( int position){
            setSeekTo(position);
        }
    }

    private int start(int position){
        mp.reset();
        try {
            mp.setDataSource(list.get(position).getData());
            mp.prepareAsync();
            mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mp.start();
                }
            });
            return position;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return position;
    }
    private void stop(){
        if( mp.isPlaying()) {
            mp.pause();
        }else{
            mp.start();
        }
    }
    private int next(int position){
        position++;
        if( position>=list.size()){
            position=0;
        }
        return start(position);
    }
    private int up( int position){
        position--;
        if( position<0){
            position=list.size()-1;
        }
        return start(position);
    }
    private int getPosition( ){
        if( mp.isPlaying()){
             currentPosition= mp.getCurrentPosition();
        }
        return currentPosition;
    }
    private void setSeekTo( int position){
        if( mp.isPlaying()){
            mp.seekTo(position);
        }
    }
}

广播

通知并能实现控制音乐播放器的操作

package com.example.mp.MyBroadCast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import com.example.mp.MainActivity;

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        if( intent.getAction().equals("com.notification.start")){
            MainActivity.han.sendEmptyMessage(111);
        }else if(intent.getAction().equals("com.notification.pause")){
            MainActivity.han.sendEmptyMessage(222);
        }else if( intent.getAction().equals("com.notification.up")){
            MainActivity.han.sendEmptyMessage(333);
        }else if( intent.getAction().equals("com.notification.next")){
            MainActivity.han.sendEmptyMessage(444);
        }
    }
}

mainActivity布局

<?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">

    <GridView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/main_grid"
        android:numColumns="2"
        android:layout_above="@id/main_seekBar"
        >

    </GridView>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/main_linear"
        android:orientation="vertical"
        android:layout_alignParentBottom="true"
        >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            >
            <Button
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="开始"
                android:id="@+id/main_button_start"
                android:onClick="click"
                />
            <Button
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="暂停"
                android:id="@+id/main_button_pause"
                android:onClick="click"
                />
            <Button
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="上一首"
                android:id="@+id/main_button_up"
                android:onClick="click"
                />
            <Button
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="下一首"
                android:id="@+id/main_button_next"
                android:onClick="click"
                />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            >
            <Button
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="随机播放"
                android:id="@+id/main_button_radom"
                android:onClick="click"
                />
        </LinearLayout>
    </LinearLayout>
    <SeekBar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@id/main_linear"
        android:id="@+id/main_seekBar"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        />

</RelativeLayout>

自定义GridView布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="歌名:"
        android:id="@+id/layout_title"
        />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="作曲家:"
        android:id="@+id/layout_artist"
        />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="地址:"
        android:id="@+id/layout_data"
        />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="大小:"
        android:id="@+id/layout_tsize"
        />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="时长:"
        android:id="@+id/layout_duration"
        />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="编号:"
        android:id="@+id/layout_position"
        />
</LinearLayout>

通知布局

包含了四个按钮

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    >
    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="开始"
        android:id="@+id/notification_start"
        />
    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="暂停"
        android:id="@+id/notification_pause"
        />
    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="上一首"
        android:id="@+id/notification_up"
        />
    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="下一首"
        android:id="@+id/notification_next"
        />
</LinearLayout>

清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.mp">

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <receiver
            android:name=".MyBroadCast.MyReceiver"
            android:enabled="false"
            android:exported="false"></receiver>

        <service
            android:name=".MyService.MyService"
            android:enabled="true"
            android:exported="true" />

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

原谅博主懒得加注释。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值