使用MediaPlayer+Service+Broadcast完成音乐播放器

其中有添加了随机顺序和单曲

1.先把歌曲封装成一个类

public class Music {
    public static final int MODE_SIGNEL=0;//单曲的常量值
    public  static final int MODE_ORDER=1;//顺序的常量值
    public static final int MODE_RANDOM=2;//随机的常量值


    private String title;
    private String artist;
    private String duration;
    private String data;
    private String size;

    public Music() {
    }

    public Music(String title, String artist, String duration, String data, String size) {
        this.title = title;
        this.artist = artist;
        this.duration = duration;
        this.data = data;
        this.size = size;
    }

    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 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 getSize() {
        return size;
    }

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

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

2.封装查询本地歌曲的工具类

public class MusicUtil {
    public static List<Music> getMusic(Context context) {


        ArrayList<Music> music = new ArrayList<>();
        Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        ContentResolver contentResolver = context.getContentResolver();
        Cursor cursor = contentResolver.query(uri, 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 duration = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));
                String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
                String size = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE));
                Music music1 = new Music(title, artist, duration, data, size);
                music.add(music1) ;
                Toast.makeText(context,music+"",Toast.LENGTH_SHORT).show();

            }
        }


        return music;
    }
}
 //格式化时间
    public static String formatTime(int time) {
        if (time / 1000 % 60 < 10) {
            return time / 1000 / 60 + ":0" + time / 1000 % 60;
        } else {
            return time / 1000 / 60 + ":" + time / 1000 % 60;
        }
    }
}

3 .封装一个adapter类

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 viewHolder;
        if (convertView==null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.layout, null);
            viewHolder = new ViewHolder();
            viewHolder.title = convertView.findViewById(R.id.titleTextview);
            viewHolder.artist = convertView.findViewById(R.id.artist);
            viewHolder.duration = convertView.findViewById(R.id.data);
            convertView.setTag(viewHolder);
        }else{
            viewHolder = (ViewHolder)convertView.getTag();
        }
        viewHolder.title.setText(list.get(position).getTitle()+"");
        viewHolder.artist.setText(list.get(position).getArtist()+"");
        int data = Integer.parseInt(list.get(position).getDuration());
        String s = MusicUtils.formaTime(data);
        viewHolder.duration.setText(s);
        return convertView;
    }
    class ViewHolder{
        TextView title;
        TextView artist;
        TextView duration;
    }

4.adapter中的布局

<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:id="@+id/textview1"
        android:layout_width="149dp"
        android:layout_height="30dp"
        android:hint="歌名"></TextView>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:orientation="horizontal">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/textview2"
                android:layout_width="216dp"
                android:layout_height="match_parent"
                android:hint="歌手" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="right">
                <TextView
                    android:id="@+id/textview3"
                    android:layout_width="80dp"
                    android:layout_height="match_parent"
                    android:layout_gravity="right"
                    android:hint="时长"/>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

5.服务中的所有代码

public class MusicService extends Service {
    private MediaPlayer mediaPlayer;
    private List<Music>list;
    int index;
    private Notification.Builder builder;
    private int playmode = Music.MODE_ORDER;

    public MusicService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mediaPlayer = new MediaPlayer();
        list = MusicUtils.getMusic(this);
    }
    public class MusicBinder extends Binder{
        public void callPlay(int position){
            playMusic(position);
            index = position;
        }
        public void callPause(){
            pause();
        }
        public void callPlayNextMuic(){
            next();
        }
        public void callPlayNavMusic(){
         top();
        }
        public void callMode(int mode){
            playMode(mode);
        }

        private void playMode(int mode) {
            switch (mode){
                case  Music.MODE_SIGNEL:
                    playmode = Music.MODE_SIGNEL;
                    break;
                case  Music.MODE_ORDER:
                    playmode = Music.MODE_ORDER;
                    break;
                case  Music.MODE_RANDOM:
                    playmode = Music.MODE_RANDOM;
                    break;
            }
        }
        private void top(){
            index--;
            if (index<0){
                index = list.size()-1;
            }
            playMusic(index);
        }
        public void callRestart(){
            restart();
        }
        public void callseek(int progress){
            seek(progress);
        }

        private void seek(int progress) {
            mediaPlayer.seekTo(progress);
        }


    }
    //继续
    private void restart() {
        mediaPlayer.start();
    }
    //暂停
    private void pause() {
        if (mediaPlayer.isPlaying()){
            mediaPlayer.pause();
        }
    }

    private void playMusic(int position) {
        if (mediaPlayer.isPlaying()){
            mediaPlayer.start();
        }
        mediaPlayer.reset();
        Music music = list.get(position);
        try {
            mediaPlayer.setDataSource(music.getData());
            mediaPlayer.prepareAsync();
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mediaPlayer.start();
                    Timer timer = new Timer();
                    timer.schedule(new TimerTask() {
                        @Override
                        public void run() {
                            Message obtain = Message.obtain();
                            obtain.what=888;
                            obtain.arg1=mediaPlayer.getCurrentPosition();
                            MainActivity.handler.sendMessage(obtain);
                        }
                    },0,1000);
                }
            });
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    mode(playmode);
                }

                private void mode(int mode) {
                    switch (mode){
                        case Music.MODE_SIGNEL:
                            mediaPlayer.setLooping(true);
                            playMusic(index);
                            playmode = Music.MODE_SIGNEL;
                            break;
                        case Music.MODE_ORDER:
                            next();
                            playmode = Music.MODE_ORDER;
                            break;
                        case Music.MODE_RANDOM:
                            int i = new Random().nextInt(list.size());
                            playMusic(i);
                            index=i;
                            playmode = Music.MODE_RANDOM;
                            break;
                    }
                }


            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    private void next() {
        index++;
        if (index>list.size()-1){
            index=0;
        }
        playMusic(index);
    }


    @Override
    public IBinder onBind(Intent intent) {
       return new MusicBinder();
    }

    @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 remoteViews = new RemoteViews(getPackageName(), R.layout.layout2);
        Intent intent1 = new Intent();
        intent1.setAction("com.music.pause");
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 800, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.pause,pendingIntent);


        Intent intent2 = new Intent();
        intent2.setAction("com.music.restart");
        PendingIntent pendingIntent2 = PendingIntent.getBroadcast(this, 810, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.restart,pendingIntent2);


        Intent intent3 = new Intent();
        intent3.setAction("com.music.top");
        PendingIntent pendingIntent3 = PendingIntent.getBroadcast(this, 820, intent3, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.top,pendingIntent3);


        Intent intent4 = new Intent();
        intent4.setAction("com.music.down");
        PendingIntent pendingIntent4 = PendingIntent.getBroadcast(this, 830, intent4, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.down,pendingIntent4);

        builder.setCustomContentView(remoteViews);
        startForeground(1,builder.build());

        return super.onStartCommand(intent, flags, startId);
    }


}

6 .service中通知的布局文件

<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="wrap_content"
        android:layout_height="wrap_content"
        android:text="暂停"
        android:id="@+id/pause"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="继续"
        android:id="@+id/restart"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="上一首"
        android:id="@+id/top"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="下一首"
        android:id="@+id/down"/>

</LinearLayout>

7.广播的内容

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action.equals("com.music.pause")){
            MainActivity.handler.sendEmptyMessage(110);
        }else if (action.equals("com.music.restart")){
            MainActivity.handler.sendEmptyMessage(120);
        }else if (action.equals("com.music.top")){
            MainActivity.handler.sendEmptyMessage(130);
        }else if (action.equals("com.music.down")){
            MainActivity.handler.sendEmptyMessage(140);
        }
    }
}

8.MainActivity中的代码

public class MainActivity extends AppCompatActivity {
    private ListView listview;//ListView
    private Button pause;//暂停按钮
    private Button restart;//继续
    private Button top;//上一首
    private Button down;//下一首
    private Button lalala;//随机切换
    public static int playmode=0;//随机切换用到的常量值
    private List<Music>list;
    private static MusicService.MusicBinder binder;
    private ServiceConnection serviceConnection;
    private static SeekBar seekBar;
    public static Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //更新进度条
            if (msg.what==888){
                seekBar.setProgress(msg.arg1);
            }
            //通知中,按钮的实现
            if (msg.what==110){
                binder.callPause();
            }else if (msg.what==120){
                binder.callRestart();
            }else if (msg.what==130){
                binder.callPlayNavMusic();
            }else if (msg.what==140){
                binder.callPlayNextMuic();
            }
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listview = (ListView) findViewById(R.id.listview);
        pause = (Button) findViewById(R.id.pause);
        restart = (Button) findViewById(R.id.restart);
        top = (Button) findViewById(R.id.top);
        down = (Button) findViewById(R.id.down);
        seekBar = findViewById(R.id.seekBar);
        lalala = findViewById(R.id.lalala);

        lalala.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int i = playmode%3;
                binder.callMode(i);
                playmode++;
                switch (i){
                    case Music.MODE_SIGNEL:
                        lalala.setText("单曲");
                        break;
                    case Music.MODE_ORDER:
                        lalala.setText("顺序");
                        break;
                    case Music.MODE_RANDOM:
                        lalala.setText("随机");
                        break;
                }
            }
        });
        //通知中的动态注册
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.music.pause");
        intentFilter.addAction("com.music.restart");
        intentFilter.addAction("com.music.top");
        intentFilter.addAction("com.music.down");
        MyReceiver myReceiver = new MyReceiver();
        registerReceiver(myReceiver,intentFilter);

        //动态添加权限
        requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);

        //Activity暂停
        pause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                binder.callPause();
            }
        });
//        Activity继续
        restart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                binder.callRestart();
            }
        });
//        Activity上一首
        top.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                binder.callPlayNavMusic();
            }
        });
//        Activity下一首
        down.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                binder.callPlayNextMuic();
            }
        });
    }
    //读取手机内存的权限
    @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();
        }
    }

    private void start() {
        list= MusicUtils.getMusic(MainActivity.this);
        MyAdapter myAdapter = new MyAdapter(list,this);
        listview.setAdapter(myAdapter);
        //点击listview条目播放音乐 进度条
        listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                binder.callPlay(position);
                //设置进度条最大值为歌曲的时长
                seekBar.setMax(Integer.parseInt(list.get(position).getDuration()));
            }
        });
        //进度条更改监听
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (fromUser){
                    binder.callseek(progress);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        Intent intent = new Intent(this, MusicService.class);
        startService(intent);
        serviceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                binder = (MusicService.MusicBinder) service;
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        };
        bindService(intent,serviceConnection, Service.BIND_AUTO_CREATE);
    }


}

9.MainActivity中的布局

<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"
    tools:context=".MainActivity"
    android:orientation="vertical">
    <ListView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="11"
        android:id="@+id/listview"></ListView>
    <SeekBar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/seekBar"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal">
        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="暂停"
            android:id="@+id/pause"/>
        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="继续"
            android:id="@+id/restart"/>
        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="上一首"
            android:id="@+id/top"/>
        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="下一首"
            android:id="@+id/down"/>
        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="顺序"
            android:id="@+id/lalala"/>
    </LinearLayout>



</LinearLayout>

10.清单文件

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.day019">

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

    <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=".Receive.MyReceiver"
            android:enabled="true"
            android:exported="true">
        </receiver>

        <service
            android:name=".Service.MusicService"
            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>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好,关于使用MediaPlayer和SurfaceView播放视频,可以按照以下步骤进行: 1. 在XML布局文件中添加SurfaceView控件: ``` <SurfaceView android:id="@+id/surface_view" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 2. 在Java代码中获取SurfaceView控件,创建MediaPlayer对象,并设置相关监听器: ``` // 获取SurfaceView控件 SurfaceView surfaceView = findViewById(R.id.surface_view); // 创建MediaPlayer对象 MediaPlayer mediaPlayer = new MediaPlayer(); // 设置SurfaceView作为MediaPlayer的显示界面 mediaPlayer.setDisplay(surfaceView.getHolder()); // 设置MediaPlayer的一些监听器 mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { // 视频准备完成后自动播放 mp.start(); } }); mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { // 视频播放完成后的处理 } }); mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { // MediaPlayer出错时的处理 return false; } }); ``` 3. 设置MediaPlayer的数据源、准备视频等操作: ``` try { // 设置MediaPlayer的数据源 mediaPlayer.setDataSource("video_path"); // 准备视频 mediaPlayer.prepare(); } catch (IOException e) { e.printStackTrace(); } ``` 4. 在需要的地方控制视频的播放、暂停、停止操作: ``` // 播放视频 mediaPlayer.start(); // 暂停视频 mediaPlayer.pause(); // 停止视频 mediaPlayer.stop(); ``` 希望以上步骤能帮到您。若有疑问,请随时咨询。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值