zoukankan      html  css  js  c++  java
  • 1600802101

    一、音乐播放器界面截图,录屏

    模拟器

    手机(测试中发现部分机型有闪退情况,截图展示的手机型号为荣耀9)

    手机录屏

    https://www.bilibili.com/video/av39894045/

    二、功能代码

    该音乐播放器实现的功能有,播放,暂停,停止,切换上一首,下一首,扫描手机内存所有目录下的所有音乐文件,时间进度条显示,拖动进度条快进快退,下面依次展示这几个部分的代码:

    (1)播放暂停功能(使用同一个按钮,按下暂停改变为播放按钮,按下播放改变为暂停按钮)

            //播放暂停
            final ImageButton pause = (ImageButton) findViewById(R.id.pause);
            pause.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (!music_path.isEmpty()) {  // 如果已经点击了列表中的某个音乐,音乐路径是指定的
                        mediaPlayer.start();   //播放
                        isStop = false;
                        pause.setImageResource(android.R.drawable.ic_media_pause);  // 播放按钮和暂停按钮变换
                    }
                    if (mediaPlayer.isPlaying()) {
                        mediaPlayer.pause();  //暂停
                        isStop = true;
                        pause.setImageResource(android.R.drawable.ic_media_play);
                    }
                    if (music_path.isEmpty())  // 如果一开始没有点击列表选择音乐,音乐路径是空的,这时候需要给一个提示
                        Toast.makeText(getApplicationContext(), "点击音乐即可播放", Toast.LENGTH_SHORT).show();
                }
            });
    

    (2)停止播放功能

            // 停止播放
            final ImageButton stop = (ImageButton)findViewById(R.id.stop);
            stop.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mediaPlayer.reset();  // 停止播放
                    isStop = true;
                }
            });
    

    (3)切换上一首和下一首功能

            //切换上一曲和下一曲
            final ImageButton previous = (ImageButton) findViewById(R.id.previous);
            previous.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    music_index--;
                    changeMusic(music_index); // 调用changeMusic方法
                    pause.setImageResource(android.R.drawable.ic_media_pause);// 因为切歌后就开始播放了,所以播放暂停按钮要置为暂停的图标
                }
            });
            final ImageButton next = (ImageButton) findViewById(R.id.next);
            next.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    music_index++;
                    changeMusic(music_index);
                    pause.setImageResource(android.R.drawable.ic_media_pause);
                }
            });
        }
        
        // changeMusic方法用于切换音乐
        private void changeMusic(int index) {
            if (index < 0) {  // 处理边界问题
                music_index = index = list.size() - 1;
            } else if (index > list.size() - 1) {
                music_index = index = 0;
            }
            music_path = MusicPath[index];  // 获取音乐文件的路经
            try {
                mediaPlayer.reset(); // 切歌之前先重置,释放掉之前的资源
                mediaPlayer.setDataSource(music_path); // 指定音频文件路径
                mediaPlayer.prepare(); // 让mediaPlayer进入准备状态
                mediaPlayer.start();  // 开始播放
            } catch (IOException e) {
                e.printStackTrace();
            }
            seekBar.setProgress(0); //将进度条初始化
            seekBar.setMax(mediaPlayer.getDuration());//设置进度条最大值为音乐总时间
            totalTime.setText(formatTime(mediaPlayer.getDuration())); //显示音乐总时长
            updateProgress();//更新进度条
        }
    

    (4)扫描所有音乐文件,生成音乐列表并显示

            private String []MusicName = new String[100]; // 音乐文件名数组
            private String []MusicPath = new String[100]; // 音乐文件路径数组
    
            // 生成音乐列表
            list = new ArrayList<String>();
            try {
                Context context = this;
                Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,  null ,
                        null ,  null , MediaStore.Audio.Media.DEFAULT_SORT_ORDER);   // 使用系统提供的数据库查询接口,使用query方法查询所有音频文件
                int i = 0;
                if(cursor != null){
                    while (cursor.moveToNext()){
                        MusicName[i] = new String(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)));  // 获取音乐文件名
                        MusicPath[i] = new String(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)));   // 获取音乐文件路径
                        i = i + 1;
                    }
                }
            }catch (Exception e){
                Toast.makeText(getApplicationContext(), "获取音乐失败", Toast.LENGTH_SHORT).show();;
            }
            int i = 0;
            while(MusicName[i] != null){
                list.add(MusicName[i]);  // 将文件名写入列表
                i++;
            }
            // 设置ListView样式
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this,
                    android.R.layout.simple_list_item_single_choice,
                    list);
            ListView li = (ListView) findViewById(R.id.listView1);
            li.setAdapter(adapter);
            li.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
    

    (5)时间进度条显示功能

        private SeekBar seekBar;       // 时间进度条组件
        private TextView currentTime; // 播放当前时间
        private TextView totalTime;  // 音乐的总时间
        private Timer timer;   // 定时器
    
        // 用于实现进度条更新的Handler
        private Handler mHandler = new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message message) {
                // 展示进度条和当前时间
                int progress = mediaPlayer.getCurrentPosition();
                seekBar.setProgress(progress);
                currentTime.setText(formatTime(progress));
                // 定时发送数据
                updateProgress();
                return true;
            }
        });
        private void updateProgress() {
            // 使用Handler每间隔1s发送一次消息,通知进度条更新
            Message msg = Message.obtain();
            // 用当前播放时间除以总时间获取播放进度
            int progress = mediaPlayer.getCurrentPosition();
            msg.arg1 = progress;
            mHandler.sendMessageDelayed(msg, 1000);
        }
    
        //formatTime方法用于对时间进行格式化,形式是mm:ss
        private String formatTime(int length) {
            Date date = new Date(length);
            SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");
            String totalTime = sdf.format(date);
            return totalTime;
        }
    

    (6)拖动进度条快进快退功能

        seekBar.setOnSeekBarChangeListener(new MoveSeekBar());
        private boolean isSeekBarChanging;  //判断是否在滑动进度条,这个时候定时器是停止的
    
        // 滑动进度条
        public class MoveSeekBar implements SeekBar.OnSeekBarChangeListener {
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            }
            //滑动时,应当暂停后台定时器
            public void onStartTrackingTouch(SeekBar seekBar) {
                isSeekBarChanging = true;
            }
            //滑动结束后,重新设置值
            public void onStopTrackingTouch(SeekBar seekBar) {
                isSeekBarChanging = false;
                mediaPlayer.seekTo(seekBar.getProgress());
            }
        }
    

    三、coding链接

    https://git.dev.tencent.com/ysh1998/MusicPlayer.git

    四、apk链接

    https://dev.tencent.com/u/ysh1998/p/MusicPlayer/git/blob/master/app/app-release.apk

  • 相关阅读:
    JavaScript——DOM或以树形展示的Web页面
    数字金额大写和小写转换
    Jquery—Jquery异步功能实例
    哈希—— POJ 3349 Snowflake Snow Snowflakes
    字节和字符的差别
    Kali Linux 安全渗透教程&lt;第三更&gt;1.2 安全渗透所需工具
    Git基础
    LeetCode Implement Stack using Queues
    HDU 4421 Bit Magic(2-sat)
    js判段URL是否可用(js判段网络是否不可用)
  • 原文地址:https://www.cnblogs.com/ysh1998/p/10105002.html
Copyright © 2011-2022 走看看