Android练习项目 Mp3播放器实现(二)

来源:互联网 发布:香港买西服 知乎 编辑:程序博客网 时间:2024/06/07 09:43

在经过几天的折腾之后,迎来了Mp3播放器的第二篇博客,这篇文章主要将如何实现播放器的播放,下一首,上一首,顺序播放,循环播放,随机播放,单曲循环等操作。
其实操作的过程中主要是通过参数的传递来实现功能的。
在activity里面互相传参有很多中方法,但对于activity和service进行交互有些方法并不适合,通过对Broadcast和BroadcastReceiver等操作,来控制播放的实现。
我们先设定好广播,然后通过发送信号来进行传递数据。
主要在activity里面动态注册广播,通过传递播放的顺序选择,Mp3的url,Mp3播放的位置到service里面,service里面接受传来的广播,获得参数,在进行对应的操作。
还有一个要解决的问题就是,如何通过service将播放的时间和歌曲信息反馈到activity里面,然后更新标题,时间,所以就是参数在service和activity之间进行传递,在程序中通过handle来处理程序的更新数据,通过handle来和activity交互,但由于没有开启线程,所以十分耗时的操作可能不适合,在下一个版本可能需要着手解决这个问题。
所以对于广播的处理就显得比较重要了。

先将作出的效果粘贴出来,目前还没有歌词等处理。
单曲循环
暂停
列表循环
列表显示

对于里面流程的处理十分重要,需要不断的调试,这是最为花费功夫的。
activity_main.xml布局文件

<?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"><ListView    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:id="@+id/listviewmusic"></ListView></LinearLayout>

主要功能通过展示listview来显示内容。
自定义子部局:
listmusic.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:layout_width="match_parent"              android:layout_height="60dp"              android:orientation="vertical">    <TextView        android:layout_width="70dp"        android:layout_height="wrap_content"        android:textAppearance="?android:attr/textAppearanceSmall"        android:text="Small Text"        android:id="@+id/MusicID"        android:gravity="center"        android:layout_alignParentLeft="true"        android:layout_alignParentStart="true"        android:layout_alignParentBottom="true"        android:layout_alignParentTop="true"/>    <TextView        android:layout_width="200dp"        android:layout_height="wrap_content"        android:textAppearance="?android:attr/textAppearanceSmall"        android:text="Small Text"        android:id="@+id/Musictitle"        android:textStyle="bold"        android:layout_alignParentTop="true"        android:layout_toRightOf="@+id/MusicID"        android:layout_toEndOf="@+id/MusicID"        android:layout_marginLeft="20dp"        android:layout_marginTop="10dp"        android:textSize="15dp"        android:singleLine="true"        android:ellipsize="end"/>    <TextView        android:layout_width="220dp"        android:layout_height="wrap_content"        android:textAppearance="?android:attr/textAppearanceSmall"        android:text="Small Text"        android:id="@+id/MusicArtist"        android:textColor="#878383"        android:layout_toRightOf="@+id/MusicID"        android:layout_toEndOf="@+id/MusicID"        android:layout_marginLeft="20dp"        android:layout_below="@+id/Musictitle"        android:layout_marginTop="7dp"        android:textSize="12dp"        android:ellipsize="end"        android:singleLine="true"/>    <ImageView        android:layout_width="25dp"        android:layout_height="25dp"        android:id="@+id/MusicIcon"        android:layout_centerVertical="true"        android:layout_alignParentRight="true"        android:layout_alignParentEnd="true"        android:layout_marginRight="30dp"        /></RelativeLayout>

MainActivity.java
主要获取mp3文件,对于里面出现的Mp3infos这个类,参考我上篇文章,这篇文章没有修改。

package com.flashmusic;import android.app.Activity;import android.app.ActivityManager;import android.content.Context;import android.content.Intent;import android.database.Cursor;import android.os.Bundle;import android.provider.MediaStore;import android.view.View;import android.widget.AdapterView;import android.widget.ListView;import android.widget.SimpleAdapter;import com.flashmusic.tool.Mp3Info;import java.util.ArrayList;import java.util.HashMap;import java.util.List;public class MainActivity extends Activity implements AdapterView.OnItemClickListener {        //Music的listview控件        private ListView MusicList;        // 存储数据的数组列表        ArrayList<HashMap<String, Object>> MusiclistData = new ArrayList<HashMap<String, Object>>();        // 适配器        private SimpleAdapter MusicListAdapter;        //存放mp3信息        static  List<Mp3Info> mp3Infos;        @Override        public void onCreate(Bundle savedInstanceState) {                super.onCreate(savedInstanceState);                setContentView(R.layout.activity_main);                MusicList = (ListView) findViewById(R.id.listviewmusic);                mp3Infos = getMp3Infos();                GetData(mp3Infos);                MusicListAdapter = new SimpleAdapter(                        this,                        MusiclistData,                        R.layout.listmusic,                        new String[]{"ID", "Title", "Artist", "Icon"},                        new int[]{R.id.MusicID, R.id.Musictitle, R.id.MusicArtist, R.id.MusicIcon}                );                //赋予数据                MusicList.setAdapter(MusicListAdapter);                MusicList.setOnItemClickListener(MusiclistListen);        }        AdapterView.OnItemClickListener MusiclistListen = new AdapterView.OnItemClickListener() {                @Override                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {//                         //Toast.makeText(MainActivity.this, String.valueOf(l), Toast.LENGTH_SHORT).show();////                        //判断当前服务是否已经开启//                        if(isServiceRunning(getBaseContext(),"com.flashmusic.MusicService")){//                                stopService(new Intent(MainActivity.this, MusicService.class));//                        }//                        Intent intent   = new Intent();//                        intent.putExtra("url", mp3Infos.get(i).getUrl());//                        intent.putExtra("position",String.valueOf(i));//                        intent.setClass(MainActivity.this, MusicService.class);//                        //启动服务//                        startService(intent);                        Intent musicintent      = new Intent(MainActivity.this, MusicActivity.class);                        //当前播放的位置                        musicintent.putExtra("position", String.valueOf(i));                        MusicActivity.mp3Infos = mp3Infos;                   //     MusicActivity.musicserviceintent = intent;                        //启动音乐播放界面                        startActivity(musicintent);                }        };        //判断服务是否存在        public static boolean isServiceRunning(Context mContext,String className) {                boolean isRunning = false;                ActivityManager activityManager = (ActivityManager)                        mContext.getSystemService(Context.ACTIVITY_SERVICE);                List<ActivityManager.RunningServiceInfo> serviceList= activityManager.getRunningServices(50);                if (!(serviceList.size()>0)) {                        return false;                }                for (int i=0; i<serviceList.size(); i++) {                        String a =serviceList.get(i).service.getClassName();                        if (serviceList.get(i).service.getClassName().equals(className) == true) {                                isRunning = true;                                break;                        }                }                return isRunning;        }        public void GetData(List<Mp3Info> mp3Infos) {                for (int i = 0; i < mp3Infos.size(); i++) {                        HashMap<String, Object> map = new HashMap<String, Object>();                        map.put("ID",mp3Infos.get(i).getID());                        map.put("Title", mp3Infos.get(i).getTitle());                        map.put("Artist", mp3Infos.get(i).getArtist());                        map.put("Icon", R.drawable.musicicon);                        MusiclistData.add(map);                }        }        public List<Mp3Info> getMp3Infos() {                Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,                        MediaStore.Audio.Media.DEFAULT_SORT_ORDER);                int ID = 0;                List<Mp3Info> mp3Infos = new ArrayList<Mp3Info>();                for (int i = 0; i < cursor.getCount(); i++) {                        Mp3Info mp3Info = new Mp3Info();                        cursor.moveToNext();                        long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID));   //音乐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) {                                //只把音乐添加到集合当中                                ID++;                                mp3Info.setID(ID);                                mp3Info.setTitle(title);                                mp3Info.setArtist(artist);                                mp3Info.setDuration(duration);                                mp3Info.setSize(size);                                mp3Info.setUrl(url);                                mp3Infos.add(mp3Info);                        }                }                return mp3Infos;        }        @Override        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {        }}

musicplay.xml,播放界面的布局

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"                android:layout_width="fill_parent"                android:layout_height="fill_parent"                android:focusable="false"                android:orientation="horizontal"                android:background="@drawable/background">    <TextView        android:id="@+id/musictitle"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true"        android:textColor="#ffffff"        android:textSize="20dp"        android:textStyle="bold"        android:layout_marginTop="15dp"/>    <TextView        android:id="@+id/musicartist"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@+id/musictitle"        android:layout_centerHorizontal="true"        android:layout_marginTop="5dp"        android:textColor="#c6bbbb"/>    <LinearLayout        android:id="@+id/linearLayout"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:layout_alignParentLeft="true"        android:layout_alignParentStart="true"        android:layout_marginBottom="10dp">        <ImageView            android:id="@+id/musicplaymode"            android:layout_width="40dp"            android:layout_height="40dp"            android:layout_margin="10dp"            android:layout_weight="1"            android:src="@drawable/orderplay"/>        <ImageView            android:id="@+id/musicprevious"            android:layout_width="40dp"            android:layout_height="40dp"            android:layout_margin="10dp"            android:layout_weight="1"            android:src="@drawable/musicprevious"/>        <ImageView            android:id="@+id/musicplay"            android:layout_width="40dp"            android:layout_height="40dp"            android:layout_margin="10dp"            android:layout_weight="1"            android:src="@drawable/musicpause"/>        <ImageView            android:id="@+id/musicnext"            android:layout_width="40dp"            android:layout_height="40dp"            android:layout_margin="10dp"            android:layout_weight="1"            android:src="@drawable/musicnext"/>        <ImageView            android:id="@+id/musicplaymenu"            android:layout_width="40dp"            android:layout_height="40dp"            android:layout_margin="10dp"            android:layout_weight="1"            android:src="@drawable/menuplay"/>    </LinearLayout>    <LinearLayout        android:layout_width="fill_parent"        android:layout_height="60dp"        android:layout_above="@+id/linearLayout"        android:layout_alignParentLeft="true"        android:layout_alignParentStart="true"        android:gravity="center_vertical"        android:orientation="horizontal">        <TextView            android:id="@+id/playcurrenttime"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignBottom="@+id/MusicProgress"            android:layout_alignParentLeft="true"            android:layout_alignParentStart="true"            android:text="00:00"            android:textAppearance="?android:attr/textAppearanceSmall"/>        <SeekBar            android:id="@+id/MusicProgress"            android:layout_width="184dp"            android:layout_height="wrap_content"            android:layout_above="@+id/linearLayout"            android:layout_toRightOf="@+id/playcurrenttime"            android:layout_weight="0.16"            android:indeterminate="false"            android:max="100"/>        <TextView            android:id="@+id/playtime"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="00:00"            android:textAppearance="?android:attr/textAppearanceSmall"/>    </LinearLayout></RelativeLayout>

接下来就是MusicActivity.java
这里面有个东西我觉得非常好,就是用了static变量,来共享mp3infos文件信息,通过MainActivity函数来赋值进来,相当于不再需要另一块内存来存储数据了,service也是这样实现的,这样每次我们只需要将位置position传进去就能够解决问题了。

package com.flashmusic;import com.flashmusic.tool.PlayerMSG;import android.annotation.TargetApi;import android.app.Activity;import android.content.BroadcastReceiver;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.content.ServiceConnection;import android.os.Build;import android.os.Bundle;import android.os.Handler;import android.os.IBinder;import android.os.Message;import android.view.Menu;import android.view.View;import android.widget.ImageView;import android.widget.SeekBar;import android.widget.TextView;import android.widget.ThemedSpinnerAdapter;import android.widget.Toast;import com.flashmusic.tool.Mp3Info;import java.text.SimpleDateFormat;import java.util.Date;import java.util.List;import java.util.Locale;import java.util.Random;import java.util.TimeZone;public class MusicActivity extends Activity implements View.OnClickListener {    //mp3需要播放的数据    static List<Mp3Info> mp3Infos;    static Intent musicserviceintent;    //播放按钮    private ImageView MusicPlay;    //下一首    private ImageView MusicNext;    //上一首    private ImageView MusicPrevious;    //播放方式选择    private ImageView MusicMOde;    //播放菜单    private ImageView MusicMenu;    //显示总时间    private TextView MusicTime;    //显示当前时间    private TextView MusicCurrentTime;    //显示歌曲名    private TextView MusicTitle;    //显示歌曲艺术家    private TextView MusicArtist;    //进度条    SeekBar seekBar;    //广播    MusicPlayerReceiver musicPlayerReceiver;    private final int isorderplay = 0;//顺序播放    private final int islistloop = 1;//表示列表循环    private final int isrepeatone = 2;//单曲循环    private final int israndomplay = 3;//随机    public static final String UPDATE_ACTION = "com.flashmusic.action.UPDATE_ACTION";  //更新动作    public static final String CTL_ACTION = "com.flashmusic.action.CTL_ACTION";        //控制动作    public static final String MUSIC_CURRENT = "com.flashmusic.action.MUSIC_CURRENT";  //音乐当前时间改变动作    public static final String MUSIC_DURATION = "com.flashmusic.action.MUSIC_DURATION";//音乐播放长度改变动作    public static final String MUSIC_PLAYING = "com.flashmusic.action.MUSIC_PLAYING";  //音乐正在播放动作    public static final String REPEAT_ACTION = "com.flashmusic.action.REPEAT_ACTION";  //音乐重复播放动作    public static final String SHUFFLE_ACTION = "com.flashmusic.action.RANDOM_ACTION";//音乐随机播放动作    public static final String PLAY_STATUE = "com.flashmusic.action.PLAY_STATUE";      //更新播放状态    //是否绑定了对应的service    Boolean mBound = false;    //播放方式表识0表示顺序播放,1表示列表循环,2表示单曲循环,3表示随机,初始为顺序播放    int playmodeflag = 0;    //歌曲播放的位置,就能够获取位置    int position;    int currentTime;    int duration;//总时间    //记录鼠标点击了几次,播放和暂停状态    boolean playorpauseflag = false;    //播放服务    MusicService mService;    // 正在播放    private boolean isPlaying;    // 暂停    private boolean isPause;    //多线程,后台更新UI    Thread myThread;    //控制后台线程退出    boolean playStatus = true;    //转换毫秒数为时间模式,一般都是分钟数,音乐文件    public static String formatDuring(long mss) {        long days = mss / (1000 * 60 * 60 * 24);        long hours = (mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);        long minutes = (mss % (1000 * 60 * 60)) / (1000 * 60);        long seconds = (mss % (1000 * 60)) / 1000;        return String.format("%02d", minutes) + ":" + String.format("%02d", seconds);    }    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.musicplay);        //初始化控件        InitView();        //获得传过来的值        Intent intent = getIntent();        position = Integer.parseInt(intent.getStringExtra("position"));        MusicArtist.setText(mp3Infos.get(position).getArtist());        MusicTitle.setText(mp3Infos.get(position).getTitle());        //注册广播        musicPlayerReceiver = new MusicPlayerReceiver();        IntentFilter filter = new IntentFilter();        filter.addAction(UPDATE_ACTION);        filter.addAction(MUSIC_CURRENT);        filter.addAction(MUSIC_DURATION);        filter.addAction(PLAY_STATUE);        registerReceiver(musicPlayerReceiver, filter);        //设置响应事件        MusicNext.setOnClickListener(this);        MusicPrevious.setOnClickListener(this);        MusicMenu.setOnClickListener(this);        MusicMOde.setOnClickListener(this);        MusicPlay.setOnClickListener(this);        seekBar.setOnSeekBarChangeListener(seekBarChangeListener);        PlayMusic();    }    //初始化控件    void InitView() {        MusicPlay = (ImageView) findViewById(R.id.musicplay);        MusicNext = (ImageView) findViewById(R.id.musicnext);        MusicPrevious = (ImageView) findViewById(R.id.musicprevious);        MusicMenu = (ImageView) findViewById(R.id.musicplaymenu);        MusicMOde = (ImageView) findViewById(R.id.musicplaymode);        MusicTime = (TextView) findViewById(R.id.playtime);        MusicCurrentTime = (TextView) findViewById(R.id.playcurrenttime);        MusicTitle = (TextView) findViewById(R.id.musictitle);        MusicArtist = (TextView) findViewById(R.id.musicartist);        seekBar = (SeekBar) findViewById(R.id.MusicProgress);    }    @TargetApi(Build.VERSION_CODES.LOLLIPOP)    @Override    public void onClick(View v) {        Intent intent = new Intent();        switch (v.getId()) {            case R.id.musicplay:                if (isPlaying) {                    MusicPlay.setImageDrawable(getResources().getDrawable(R.drawable.musicpause, null));                    intent.setClass(MusicActivity.this, MusicService.class);                    intent.putExtra("MSG", PlayerMSG.MSG.PAUSE_MSG);                    startService(intent);                    isPlaying = false;                } else {                    MusicPlay.setImageDrawable(getResources().getDrawable(R.drawable.musicplay, null));                    intent.setClass(MusicActivity.this, MusicService.class);                    intent.putExtra("MSG", PlayerMSG.MSG.CONTINUE_MSG);                    startService(intent);                    isPlaying = true;                }                break;            case R.id.musicplaymode:                setPlayMOde();                break;            case R.id.musicnext:                PlayNextMusic();                break;            case R.id.musicprevious:                PlayPreviousMusic();                break;            case R.id.musicplaymenu:                break;            default:                break;        }    }    @TargetApi(Build.VERSION_CODES.LOLLIPOP)    void setPlayMOde() {        playmodeflag++;        Intent intent = new Intent(CTL_ACTION);        intent.putExtra("control", playmodeflag);        sendBroadcast(intent);        switch (playmodeflag) {            case isorderplay:                MusicMOde.setImageDrawable(getResources().getDrawable(R.drawable.orderplay, null));                break;            case islistloop:                MusicMOde.setImageDrawable(getResources().getDrawable(R.drawable.repeatplay, null));                break;            case isrepeatone:                MusicMOde.setImageDrawable(getResources().getDrawable(R.drawable.repeatoneplay, null));                break;            case israndomplay:                MusicMOde.setImageDrawable(getResources().getDrawable(R.drawable.randomplay, null));                playmodeflag = -1;                break;            default:                break;        }    }    SeekBar.OnSeekBarChangeListener seekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {        //停止拖动事件        @Override        public void onStopTrackingTouch(SeekBar seekBar) {            //手动调节进度            // TODO Auto-generated method stub            //seekbar的拖动位置            int progress = seekBar.getProgress();            ChangeProgress(progress);            //调用service调节播放进度            //      mService.setProgress(max, dest);        }        //数值改变事件        @Override        public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {            // TODO Auto-generated method stub        }        //开始拖动事件        @Override        public void onStartTrackingTouch(SeekBar arg0) {            // TODO Auto-generated method stub        }    };    public void ChangeProgress(int progress) {        Intent intent = new Intent();        intent.setClass(MusicActivity.this, MusicService.class);        intent.putExtra("url", mp3Infos.get(position).getUrl());        intent.putExtra("position", position);        intent.putExtra("MSG", PlayerMSG.MSG.PROGRESS_CHANGE);        intent.putExtra("progress", progress);        startService(intent);    }    //播放音乐    @TargetApi(Build.VERSION_CODES.LOLLIPOP)    public void PlayMusic() {        isPlaying = true;        MusicPlay.setImageDrawable(getResources().getDrawable(R.drawable.musicplay, null));        // 开始播放的时候为顺序播放        Intent intent = new Intent();        intent.setClass(MusicActivity.this, MusicService.class);        intent.putExtra("url", mp3Infos.get(position).getUrl());        intent.putExtra("position", position);        intent.putExtra("MSG", PlayerMSG.MSG.PLAY_MSG);        MusicService.mp3Infos = mp3Infos;        startService(intent);    }    //播放上一首音乐    @TargetApi(Build.VERSION_CODES.LOLLIPOP)    public void PlayPreviousMusic() {        position = position - 1;        //   MusicPlay.setImageDrawable(getResources().getDrawable(R.drawable.musicpause,null));        if (position < 0) {            position = mp3Infos.size() - 1;        }        Mp3Info mp3Info = mp3Infos.get(position);        MusicTitle.setText(mp3Info.getTitle());        MusicArtist.setText(mp3Info.getArtist());        Intent intent = new Intent();        intent.setClass(MusicActivity.this, MusicService.class);        intent.putExtra("url", mp3Info.getUrl());        intent.putExtra("position", position);        intent.putExtra("MSG", PlayerMSG.MSG.PRIVIOUS_MSG);        startService(intent);        isPlaying = true;        MusicPlay.setImageDrawable(getResources().getDrawable(R.drawable.musicplay, null));    }    //播放下一首音乐    @TargetApi(Build.VERSION_CODES.LOLLIPOP)    public void PlayNextMusic() {        //判断是否是随机播放,因为随机播放设置后,playmodeflag变为-1了        if (playmodeflag == -1) {            Random random = new Random();            position = random.nextInt(mp3Infos.size());        } else            position = position + 1;        if (position >= mp3Infos.size())            position = 0;        Mp3Info mp3Info = mp3Infos.get(position);        MusicTitle.setText(mp3Info.getTitle());        MusicArtist.setText(mp3Info.getArtist());        Intent intent = new Intent();        intent.setClass(MusicActivity.this, MusicService.class);        intent.putExtra("url", mp3Info.getUrl());        intent.putExtra("position", position);        intent.putExtra("MSG", PlayerMSG.MSG.NEXT_MSG);        startService(intent);        MusicPlay.setImageDrawable(getResources().getDrawable(R.drawable.musicplay, null));        isPlaying = true;    }    public class MusicPlayerReceiver extends BroadcastReceiver {        @TargetApi(Build.VERSION_CODES.LOLLIPOP)        @Override        public void onReceive(Context context, Intent intent) {            String action = intent.getAction();            //当前时间更新            if (action.equals(MUSIC_CURRENT)) {                currentTime = intent.getIntExtra("currentTime", -1);                seekBar.setProgress(currentTime);                MusicCurrentTime.setText(formatDuring(currentTime));            } else if (action.equals(MUSIC_DURATION)) {                //总时间更新                duration = intent.getIntExtra("duration", -1);                seekBar.setMax(duration);                MusicTime.setText(formatDuring(duration));            } else if (action.equals(UPDATE_ACTION)) {                position = intent.getIntExtra("position", -1);                String url = mp3Infos.get(position).getUrl();                MusicTitle.setText(mp3Infos.get(position).getTitle());                MusicArtist.setText(mp3Infos.get(position).getArtist());                MusicTime.setText(formatDuring(mp3Infos.get(position).getDuration()));            } else if (action.equals(PLAY_STATUE)) {                boolean playstatue = intent.getBooleanExtra("playstatue", true);                if (playstatue) {                    MusicPlay.setImageDrawable(getResources().getDrawable(R.drawable.musicplay, null));                    isPlaying = true;                } else {                    MusicPlay.setImageDrawable(getResources().getDrawable(R.drawable.musicpause, null));                    isPlaying = false;                }            }        }    }    public void onDestroy() {        //销毁activity时,要记得销毁线程        playStatus = false;        super.onDestroy();    }}

这里面有许多细节,处理的过程就是不断调试。

最为重要的就是写service了,这个里面主要涉及到MP3的播放,暂停,切换,上一首,进行操作的主要是接受MusicActivity里面传过来的广播,然后进行判断,然后处理对应的函数。说的就是这么简单,但处理起来,并不是很好解决。
MusicService.java

package com.flashmusic;import com.flashmusic.tool.PlayerMSG;import android.app.Service;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.media.AudioManager;import android.media.MediaPlayer;import android.os.Binder;import android.os.Handler;import android.os.IBinder;import android.os.Message;import android.util.Log;import android.widget.Toast;import com.flashmusic.tool.Mp3Info;import java.util.ArrayList;import java.util.List;public class MusicService extends Service {    // mp3的绝对路径    private String path;    //当前播放位置    private int position;    //当前播放进度    private int currentTime;    private int msg;                //播放信息    private boolean isPause;    static List<Mp3Info> mp3Infos;    //存放Mp3Info对象的集合    private int duration;            //播放长度    int palyflag = 0;    //服务要发送的一些Action    public static final String UPDATE_ACTION = "com.flashmusic.action.UPDATE_ACTION";  //更新音乐播放曲目    public static final String CTL_ACTION = "com.flashmusic.action.CTL_ACTION";        //控制播放模式    public static final String MUSIC_CURRENT = "com.flashmusic.action.MUSIC_CURRENT";  //当前音乐播放时间更新    public static final String MUSIC_DURATION = "com.flashmusic.action.MUSIC_DURATION";//播放音乐长度更新    public static final String PLAY_STATUE = "com.flashmusic.action.PLAY_STATUE";      //更新播放状态    //播放音乐的媒体类    MediaPlayer mediaPlayer;    //广播接收器,接收来自MusicActivity的广播    private MusicReceiver musicReceiver;    IBinder musicBinder = new MyBinder();    //handler用来接收消息,来发送广播更新播放时间    private Handler mHandler = new Handler() {        public void handleMessage(Message msg) {            switch (msg.what) {                case 1:                    if (mediaPlayer != null) {                        currentTime = mediaPlayer.getCurrentPosition();                        Intent intent = new Intent();                        intent.setAction(MUSIC_CURRENT);                        intent.putExtra("currentTime", currentTime);                        sendBroadcast(intent); // 给PlayerActivity发送广播                        mHandler.sendEmptyMessageDelayed(1, 1000);                    }                    break;                default:                    break;            }        }        ;    };    class MyBinder extends Binder {        public Service getService() {            return MusicService.this;        }    }    @Override    public void onCreate() {        super.onCreate();        mediaPlayer = new MediaPlayer();        /**         * 设置音乐播放完成时的监听器         */        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {            @Override            public void onCompletion(MediaPlayer mp) {                Intent intent = new Intent(PLAY_STATUE);                // 发送播放完毕的信号,更新播放状态                intent.putExtra("playstatue", false);                sendBroadcast(intent);                //       Toast.makeText(getApplicationContext(),"服务完成了",Toast.LENGTH_SHORT).show();                if (palyflag == 2) {                    Intent loopintent = new Intent(PLAY_STATUE);                    // 发送播放完毕的信号,更新播放状态                    intent.putExtra("playstatue", true);                    sendBroadcast(loopintent);                    // 单曲循环                    mediaPlayer.start();                } else if (palyflag == 1) {                    // 列表循环                    position++;                    if (position > mp3Infos.size() - 1) {                        //变为第一首的位置继续播放                        position = 0;                    }                    Intent sendIntent = new Intent(UPDATE_ACTION);                    sendIntent.putExtra("position", position);                    // 发送广播,将被Activity组件中的BroadcastReceiver接收到                    sendBroadcast(sendIntent);                    path = mp3Infos.get(position).getUrl();                    play(0);                } else if (palyflag == 0) { // 顺序播放                    position++;    //下一首位置                    if (position <= mp3Infos.size() - 1) {                        Intent sendIntent = new Intent(UPDATE_ACTION);                        sendIntent.putExtra("position", position);                        // 发送广播,将被Activity组件中的BroadcastReceiver接收到                        sendBroadcast(sendIntent);                        path = mp3Infos.get(position).getUrl();                        play(0);                    } else {                        mediaPlayer.seekTo(0);                        position = 0;                        Intent sendIntent = new Intent(UPDATE_ACTION);                        sendIntent.putExtra("position", position);                        // 发送广播,将被Activity组件中的BroadcastReceiver接收到                        sendBroadcast(sendIntent);                    }                } else if (palyflag == 3) {    //随机播放                    position = getRandomIndex(mp3Infos.size() - 1);                    Intent sendIntent = new Intent(UPDATE_ACTION);                    sendIntent.putExtra("position", position);                    // 发送广播,将被Activity组件中的BroadcastReceiver接收到                    sendBroadcast(sendIntent);                    path = mp3Infos.get(position).getUrl();                    play(0);                }            }        });        musicReceiver = new MusicReceiver();        IntentFilter filter = new IntentFilter();        filter.addAction(CTL_ACTION);        //     filter.addAction(SHOW_LRC);        registerReceiver(musicReceiver, filter);    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        path = intent.getStringExtra("url");        //歌曲路径        position = intent.getIntExtra("position", -1);    //当前播放歌曲的在mp3Infos的位置        msg = intent.getIntExtra("MSG", 0);            //播放信息        if (msg == PlayerMSG.MSG.PLAY_MSG) {    //直接播放音乐            play(0);        } else if (msg == PlayerMSG.MSG.PAUSE_MSG) {    //暂停            pause();        } else if (msg == PlayerMSG.MSG.STOP_MSG) {        //停止            stop();        } else if (msg == PlayerMSG.MSG.CONTINUE_MSG) {    //继续播放            resume();        } else if (msg == PlayerMSG.MSG.PRIVIOUS_MSG) {    //上一首            previous();        } else if (msg == PlayerMSG.MSG.NEXT_MSG) {        //下一首            next();        } else if (msg == PlayerMSG.MSG.PROGRESS_CHANGE) {    //进度更新            currentTime = intent.getIntExtra("progress", -1);            play(currentTime);        } else if (msg == PlayerMSG.MSG.PLAYING_MSG) {            mHandler.sendEmptyMessage(1);        }        return super.onStartCommand(intent, flags, startId);    }    private void play(int currentTime) {        try {            mediaPlayer.reset();// 把各项参数恢复到初始状态            mediaPlayer.setDataSource(path);            mediaPlayer.prepare(); // 进行缓冲            mediaPlayer.setOnPreparedListener(new PreparedListener(currentTime));// 注册一个监听器            //更新播放状态            Intent intent = new Intent(PLAY_STATUE);            // 发送播放完毕的信号,更新播放状态            intent.putExtra("playstatue", true);            sendBroadcast(intent);            mHandler.sendEmptyMessage(1);        } catch (Exception e) {            e.printStackTrace();        }    }    //继续播放    private void resume() {        if (isPause) {            mediaPlayer.start();            isPause = false;        }    }    /**     * 上一首     */    private void previous() {        Intent sendIntent = new Intent(UPDATE_ACTION);        sendIntent.putExtra("position", position);        // 发送广播,将被Activity组件中的BroadcastReceiver接收到        sendBroadcast(sendIntent);        play(0);    }    /**     * 下一首     */    private void next() {        Intent sendIntent = new Intent(UPDATE_ACTION);        sendIntent.putExtra("position", position);        // 发送广播,将被Activity组件中的BroadcastReceiver接收到        sendBroadcast(sendIntent);        play(0);    }    private void pause() {        if (mediaPlayer != null && mediaPlayer.isPlaying()) {            mediaPlayer.pause();            isPause = true;        }    }    private void stop() {        if (mediaPlayer != null) {            mediaPlayer.stop();            try {                mediaPlayer.prepare(); // 在调用stop后如果需要再次通过start进行播放,需要之前调用prepare函数            } catch (Exception e) {                e.printStackTrace();            }        }    }    /**     * 实现一个OnPrepareLister接口,当音乐准备好的时候开始播放     */    private final class PreparedListener implements MediaPlayer.OnPreparedListener {        private int currentTime;        public PreparedListener(int currentTime) {            this.currentTime = currentTime;        }        @Override        public void onPrepared(MediaPlayer mp) {            mediaPlayer.start(); // 开始播放            if (currentTime > 0) { // 如果音乐不是从头播放                mediaPlayer.seekTo(currentTime);            }            Intent intent = new Intent();            intent.setAction(MUSIC_DURATION);            duration = mediaPlayer.getDuration();            intent.putExtra("duration", duration);    //通过Intent来传递歌曲的总长度            sendBroadcast(intent);        }    }    protected int getRandomIndex(int end) {        int index = (int) (Math.random() * end);        return index;    }    public class MusicReceiver extends BroadcastReceiver {        @Override        public void onReceive(Context context, Intent intent) {            int control = intent.getIntExtra("control", -1);            switch (control) {                case 0:                    palyflag = 0; // 顺序播放                    break;                case 1:                    palyflag = 1;    //列表循环                    break;                case 2:                    palyflag = 2;    //单曲循环                    break;                case 3:                    palyflag = 3;  //随机                    break;                default:                    break;//            if(action.equals(SHOW_LRC)){//                current = intent.getIntExtra("listPosition", -1);//                initLrc();            }        }    }    @Override    public IBinder onBind(Intent arg0) {        // TODO Auto-generated method stub        //当绑定后,返回一个musicBinder        return musicBinder;    }    @Override    public void onDestroy() {        if (mediaPlayer != null) {            mediaPlayer.stop();            mediaPlayer.release();            mediaPlayer = null;        }    }}

这些函数里面有个标识,其实有时候,我们并不想通过new一个类来处理信息,这个就是个很好的表示来解决问题。
PlayerMSG.java

package com.flashmusic.tool;/** * Created by zhouchenglin on 2016/4/18. */public class PlayerMSG {    public class MSG{        public static final int PLAY_MSG = 1;       //播放        public static final int PAUSE_MSG = 2;      //暂停        public static final int STOP_MSG = 3;       //停止        public static final int CONTINUE_MSG = 4;   //继续        public static final int PRIVIOUS_MSG = 5;   //上一首        public static final int NEXT_MSG = 6;       //下一首        public static final int PROGRESS_CHANGE = 7;//进度改变        public static final int PLAYING_MSG = 8;    //正在播放    }}

主要的内容就这么多,现在还未完成歌词显示,还有需要解决地问题,就是需要在子线程里面更新UI,这个需要重新考虑。
这篇博客,改变了上一篇博客里面的设计思路,让我掌握了广播的使用。

参考这篇文章,我就是参考大神之后修改的,站在巨人的肩膀上看世界

源码下载

0 0
原创粉丝点击