音乐播放器应用代码实现

时间:2022-08-13 10:13:24

一、技术点

  1、从手机内存中读取出来并显示

   1.   从数据库中查询所有音乐数据,保存到List集合当中,List当中存放的是Mp3Info对象
   2.   定义一个List集合,把对象添加到工具类返回的对象List集合当中
   3.   通过定义一个musicAdapter,调用setAdpter方法,将list集合里面的数据数据显示到列表当中


  2、点击音乐列表的每一项,播放一个音乐。

      1.给每一个条目添加一个点击事件setOnItemClickListener

  3、音乐播放过程中,进度条随着音乐的进度动

          1.设置SeekBar 的监听事件 ,音乐播放时,seekBar跟着改变-
  

  4、点击播放,暂停,音乐停止播放,上一首,下一首,切换歌曲,第一首和最后一首给出提示

      1 ,当我们点击时播放音乐,然后一直播放直到我们点击了暂停的按钮,所以我们想到使用服务定义一个MusicSeriver


二,读取手机内存的工具类

            

package com.testopensourceapplication.Utils;




import android.content.Context;
import android.database.Cursor;
import android.provider.MediaStore;


import com.testopensourceapplication.model.Mp3Info;


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


public class MediaUtil {
/**
* 用于从数据库中查询歌曲的信息,保存在List当中
*
* @return
*/
public static List<Mp3Info> getMp3Infos(Context context) {
Cursor cursor = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
List<Mp3Info> mp3Infos = new ArrayList<Mp3Info>();




for (int i = 0; i < cursor.getCount(); i++) {
cursor.moveToNext();
Mp3Info mp3Info = new Mp3Info();
long id = cursor.getLong(cursor
.getColumnIndex(MediaStore.Audio.Media._ID));//音乐id
String title = cursor.getString((cursor
.getColumnIndex(MediaStore.Audio.Media.TITLE)));//音乐标题
String artist = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.ARTIST));//艺术家
long duration = cursor.getLong(cursor
.getColumnIndex(MediaStore.Audio.Media.DURATION));//时长
long size = cursor.getLong(cursor
.getColumnIndex(MediaStore.Audio.Media.SIZE));//文件大小
String url = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.DATA));//文件路径
int isMusic = cursor.getInt(cursor
.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));//是否为音乐
if (isMusic != 0) {//只把音乐添加到集合当中


mp3Info.setId(id);
mp3Info.setTitle(title);
mp3Info.setArtist(artist);
mp3Info.setDuration(duration);
mp3Info.setSize(size);
mp3Info.setUrl(url);


mp3Infos.add(mp3Info);
}
}
return mp3Infos;
}




/**
* 格式化时间,将毫秒转换为分:秒格式
* @param time
* @return
*/
public static String formatTime(long time) {
String min = time / (1000 * 60) + "";
String sec = time % (1000 * 60) + "";
if (min.length() < 2) {
min = "0" + time / (1000 * 60) + "";
} else {
min = time / (1000 * 60) + "";
}
if (sec.length() == 4) {
sec = "0" + (time % (1000 * 60)) + "";
} else if (sec.length() == 3) {
sec = "00" + (time % (1000 * 60)) + "";
} else if (sec.length() == 2) {
sec = "000" + (time % (1000 * 60)) + "";
} else if (sec.length() == 1) {
sec = "0000" + (time % (1000 * 60)) + "";
}
return min + ":" + sec.trim().substring(0, 2);
}
}

      

3,Map3info.class

package com.testopensourceapplication.model;


public class Mp3Info {
public long id;//音乐id
public String title;//音乐标题
public String artist;//艺术家
public long duration; //时长
public long size ;//文件大小
public String url;//文件路径
public int  isMusic;//是否为音乐
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
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 long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getIsMusic() {
return isMusic;
}
public void setIsMusic(int isMusic) {
this.isMusic = isMusic;
}


}



4 MusicService.class

package com.testopensourceapplication.Service;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.IBinder;

import com.testopensourceapplication.Utils.MusicConstant;
import com.testopensourceapplication.activity.MusicActivity;

import java.io.IOException;

public class MusicSeriver extends Service implements InmusicSeriver {

   MediaPlayer mediaplay;  //媒体播放器  boolean isplaying = false; //是否在播放音乐的标志    @Override
   public IBinder onBind(Intent intent) {
      // TODO Auto-generated method stub  return null;
   }


   @Override
   public void onCreate() {
      // TODO Auto-generated method stub  mediaplay =new MediaPlayer();

      super.onCreate();
   }



   @Override
   public void onDestroy() {
      // TODO Auto-generated method stub  super.onDestroy();
   }




   @Override
   public int onStartCommand(Intent intent, int flags, int startId) {
      // TODO Auto-generated method stub  String url =intent.getStringExtra("url");
      int zhuangtai =intent.getIntExtra("MSG", 1000);
      if(zhuangtai==1){   // 播放音乐时   play(url);

      }else if(zhuangtai==3){  //暂停播放  int progress =intent.getIntExtra("progress", -1);
         if(progress!=-1){

            mediaplay.seekTo(progress);

         }
         mediaplay.pause();;

      }else if(zhuangtai==2){  //继续播放音乐时  int progress =intent.getIntExtra("progress", -1);

         if(progress!=-1){

            mediaplay.seekTo(progress);
         }
         mediaplay.start();
      }


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


   public void play(String url) {
      // TODO Auto-generated method stub   try {

         isplaying = false;
         try {
            Thread.sleep(200);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }

         mediaplay.reset();
         mediaplay.setDataSource(url);
         mediaplay.prepareAsync();
         mediaplay.setOnPreparedListener(new OnPreparedListener() {

            public void onPrepared(MediaPlayer mp) {
               // TODO Auto-generated method stub  mediaplay.start();
               isplaying = true;
               new Thread(new Runnable() {

                  public void run() {
                     // TODO Auto-generated method stub  while(isplaying){
                        try {
                           Thread.sleep(200);
                        } catch (InterruptedException e) {
                           // TODO Auto-generated catch block  e.printStackTrace();
                        }
                        Intent intent =new Intent(MusicActivity.MUSIC_ACTION);
                        intent.putExtra("data", MusicActivity.PLAY_PROGRESS);
                        intent.putExtra("result", mediaplay.getCurrentPosition());  //发送当前的进度  sendBroadcast(intent);
                     }
                  }
               }).start();
            }
         });
         mediaplay.setOnCompletionListener(new OnCompletionListener() {

            public void onCompletion(MediaPlayer mp) {
               // TODO Auto-generated method stub  Intent  intent =new Intent(MusicActivity.MUSIC_ACTION);
               intent.putExtra("data", MusicConstant.PLAY_OVER);
               sendBroadcast(intent);  //发送这个广播 表示已经播放完了  isplaying = false;;
            }
         });


      } catch (IOException e) {
         // TODO Auto-generated catch block  e.printStackTrace();
      }

   }


   public void pause() {
      // TODO Auto-generated method stub  mediaplay.pause();

   }


   public void stop() {
      // TODO Auto-generated method stub   }


   public void playContinue() {


   }




}


5, 存放常量的类

  
package com.testopensourceapplication.Utils;

public class MusicConstant {
    public static final int PLAY_OVER = 4; //播放结束 }




6. MusicActivity.class


package com.testopensourceapplication.activity;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.testopensourceapplication.Adapter.musicAdapter;
import com.testopensourceapplication.Service.MusicSeriver;
import com.testopensourceapplication.Utils.MediaUtil;
import com.testopensourceapplication.Utils.MusicConstant;
import com.testopensourceapplication.model.Mp3Info;
import com.testopensourceapplication.uidemo.R;

import java.util.List;

public class MusicActivity extends AppCompatActivity {
    ListView music_lv;
    List<Mp3Info> datas;
    musicAdapter adapter;
    boolean isPlay = false;
    MediaUtil util =new MediaUtil();
    ImageView btnPlay;

    ImageView btnPause;

    ImageView Btnup;
    ImageView Btndown;

    SeekBar seekbar;
    TextView strnttime;
    TextView endtime;
    public static final int STARTPLAY = 1;
    public static final int PLAY = 2;
    public static final int PAUSE = 3;
    public static final String MUSIC_ACTION = "com.he.duqu"; //监听的频道  public static final String SONG_DATA = "datasource";  //时长  public static final int PLAY_PROGRESS = 6; //播放进度   boolean bool =false;
    public int s=0;
    Mp3Info mp3info;

    MusicReiver musicreiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_music);


        initMusicReceiver();
        datas=util.getMp3Infos(this);

        btnPlay=(ImageView) findViewById(R.id.btnPlay);
        btnPause=(ImageView) findViewById(R.id.btnPause);
        Btnup=(ImageView) findViewById(R.id.Btnup);
        Btndown=(ImageView) findViewById(R.id.Btndown);
        seekbar=(SeekBar) findViewById(R.id.seekbar);
        strnttime=(TextView) findViewById(R.id.strnttime);
        endtime=(TextView) findViewById(R.id.endtime);
        music_lv=(ListView) findViewById(R.id.music_lv);



        adapter =new musicAdapter(this,datas);
        music_lv.setAdapter(adapter);

        music_lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                                    long arg3) {
                mp3info=datas.get(arg2);
                s=arg2;

                seekbar.setMax((int) mp3info.duration);  //得到歌的时长   endtime.setText(MediaUtil.formatTime(mp3info.duration));
                seekbar.setProgress(0);  //初始值为0  adapter.setIndex(s);
                adapter.notifyDataSetChanged();

                Log.i("TGB", mp3info.toString());
                Intent intent =new Intent();
                intent.putExtra("url", mp3info.getUrl());
                intent.putExtra("MSG", STARTPLAY);

                btnPause.setImageResource(R.drawable.play);
                isPlay = true;
                // TODO Auto-generated method stub  intent.setClass(MusicActivity.this,MusicSeriver.class);
                startService(intent);

            }

        });

        seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

            public void onStopTrackingTouch(SeekBar seekBar) {  //执行到拖动的位置  // TODO Auto-generated method stub  Intent intent =new Intent(MusicActivity.this,MusicSeriver.class);
                intent.putExtra("progress", seekBar.getProgress()); //传递 seekBar 的位置 得到拖动的位置 seekBar.getProgress()   //如果是暂停的时候 拖动 SeekBar 还是不播放  //如果是播放的状态 拖动的时候,会在停止的位置继续播放  if(isPlay){
                    intent.putExtra("MSG", MusicActivity.PLAY); //继续播放  }else{
                    intent.putExtra("MSG", MusicActivity.PAUSE);
                }
                startService(intent);

            }

            public void onStartTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub   }

            public void onProgressChanged(SeekBar seekBar, int progress,
                                          boolean fromUser) {
                // TODO Auto-generated method stub   }
        });
    }

    public void initMusicReceiver(){  //接受广播  musicreiver =new MusicReiver();
        IntentFilter ifile =new IntentFilter();
        ifile.addAction(MusicActivity.MUSIC_ACTION);
        registerReceiver(musicreiver, ifile);
    }


    //绑定的点击事件  public void myclick(View view){
        switch (view.getId()) {
            case R.id.btnPause:  {
                if(s!=0){
                    if(isPlay){  //点这个就暂停了  Intent intent =new Intent();
                        intent.putExtra("MSG",PAUSE);
                        isPlay = false;
                        btnPause.setImageResource(R.drawable.stop);
                        intent.setClass(MusicActivity.this,MusicSeriver.class);
                        startService(intent);
                    }else{
                        Intent intent1 =new Intent();
                        intent1.putExtra("MSG", PLAY);
                        isPlay = true;
                        btnPause.setImageResource(R.drawable.play);
                        intent1.setClass(MusicActivity.this,MusicSeriver.class);
                        startService(intent1);
                    }
                }
                else{
                    Intent intent1 =new Intent(MusicActivity.this,MusicSeriver.class);
                    intent1.putExtra("MSG", STARTPLAY);
                    intent1.putExtra("url", datas.get(0).url);
                    seekbar.setMax((int)datas.get(0).getDuration());
                    isPlay = true;
                    btnPause.setImageResource(R.drawable.play);
                    s++;
                    startService(intent1);
                }

                break;
            }
            case R.id.Btnup:{
                playNext(true);
                break;
            }
            case R.id.Btndown:{

                playNext(false);
                break;
            }
            default:
                break;
        }
    }

    // bool 是false 表示播放上一首 true 表示播放下一首  public void playNext(boolean bool){

        if(bool){
            if(s>=1){
                Intent intent3 =new Intent(MusicActivity.this,MusicSeriver.class);
                intent3.putExtra("url", datas.get(--s).url);
                intent3.putExtra("MSG", STARTPLAY);
                seekbar.setMax((int)datas.get(s).getDuration());  //得到歌的时长  endtime.setText(MediaUtil.formatTime(datas.get(s).duration));  //设置点击下一曲 歌的时长  adapter.setIndex(s);
                adapter.notifyDataSetChanged();
                startService(intent3);
            }else{
                Toast.makeText(MusicActivity.this, "已经是第一首了", Toast.LENGTH_LONG).show();
                return;
            }

        }else{

            if(s<datas.size()-1){
                Intent intent3 =new Intent(MusicActivity.this,MusicSeriver.class);
                intent3.putExtra("url", datas.get(++s).url);
                intent3.putExtra("MSG", STARTPLAY);
                endtime.setText(MediaUtil.formatTime(datas.get(s).duration));
                seekbar.setMax((int)datas.get(s).getDuration());  //得到歌的时长  adapter.setIndex(s);

                btnPause.setImageResource(R.drawable.play);
                isPlay = true;

                adapter.notifyDataSetChanged();

                startService(intent3);
            }else{
                Toast.makeText(MusicActivity.this, "已经是最后一首了", Toast.LENGTH_LONG).show();
                return;
            }


        }
    }



    private final class MusicReiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub  int flag =intent.getIntExtra("data", -1);
            Log.i("TGB", flag+"");
            if(flag== MusicConstant.PLAY_OVER){

                playNext(false);
            }else if(flag==PLAY_PROGRESS){  //如果等于正在播放的进度   seekbar.setProgress(intent.getIntExtra("result",0));
                strnttime.setText(MediaUtil.formatTime(intent.getIntExtra("result",0)));
            }

        }

    }

}



7、布局(图片和源码去這个地址下载:)

 activity_muscic.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:tools="http://schemas.android.com/tools"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:orientation="vertical"  android:background="@drawable/beijing2"  tools:context="com.testopensourceapplication.activity.MusicActivity">
    <ListView  android:id="@+id/music_lv"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:layout_weight="1"  />
    <LinearLayout  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:orientation="horizontal"  >

        <TextView  android:id="@+id/strnttime"  android:layout_width="43dp"  android:layout_height="wrap_content"  android:text="0:00" />

        <SeekBar  android:id="@+id/seekbar"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_weight="1"  />

        <TextView  android:id="@+id/endtime"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:text="02:17" />

    </LinearLayout>


    <LinearLayout  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:orientation="horizontal"  >


        <ImageView  android:id="@+id/Btnup"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_weight="1"  android:onClick="myclick"  android:src="@drawable/shang" />


        <ImageView  android:id="@+id/btnPlay"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:src="@drawable/play"  android:onClick="myclick"  android:layout_weight="1"  android:visibility="gone"  />
        <ImageView  android:id="@+id/btnPause"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:src="@drawable/play"  android:onClick="myclick"  android:layout_weight="1"  />


        <ImageView  android:id="@+id/Btndown"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_weight="1"  android:onClick="myclick"  android:src="@drawable/nextmusic" />
    </LinearLayout>

</LinearLayout>


  music_item.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:orientation="horizontal"  android:layout_height="match_parent">
    <ImageView  android:id="@+id/song_img"  android:layout_width="50dp"  android:layout_height="50dp"  android:src="@drawable/ic_speech_voice"  />


    <LinearLayout  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:orientation="vertical"   >
        <TextView  android:id="@+id/song_name"  android:layout_marginLeft="5dp"  android:layout_marginTop="3dp"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:text="冥明"  android:layout_weight="1" />
        <TextView  android:id="@+id/song_zuoze"  android:layout_marginLeft="5dp"  android:layout_marginTop="3dp"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:text="苏运莹"  android:layout_weight="1" />

    </LinearLayout>

    <LinearLayout  android:layout_height="wrap_content"  android:layout_width="wrap_content"  android:orientation="horizontal"  android:layout_marginLeft="20dp"  >
        <TextView  android:id="@+id/song_duration"  android:layout_marginLeft="170dp"  android:layout_marginTop="15dp"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:text="2"  android:layout_weight="1" />

    </LinearLayout>
</LinearLayout>


8、配置文件

<!-- 蓝牙权限 --> <uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

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



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

<service android:name="com.testopensourceapplication.Service.MusicSeriver"></service>

源码下载地址:项目可以直接运行:http://download.csdn.net/detail/pigseesunset/9700221