Android播放器的制作---畅想音乐播放器

本人接触android零零碎碎也有一个月多了,我自己觉得也应该自己独立去做一些东西了,当然太难的我肯定不行,所以我就选择了播放器的制作。播放器虽然不是什么大项目,但是涉及的方面还是比较全的,例如Service,Broadcast,ContentProvider等等,如果深入地制作,比如说SQLite,Http也是能涉及到的。

该播放器的图片效果如下:


1.设计UI,这部分说简单也简单,说难也不难。UI设计是UI设计师应该做的事,我们是不用管太多的,所以做的界面不需要尽善尽美,只要不是太丑就行了,我是找了几张图片,用ps加工了一下。

2.设置欢迎界面,新建一个WelcomeActivity,然后在AndroidMainifest.xml中注册WelcomeActivity,然后用handler实现跳转

    handler=new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent intent=new Intent(WelcomeActivity.this,MainActivity.class);
                startActivity(intent);
                WelcomeActivity.this.finish();
            }
        },1500);

3.设计MainAcivity的视图文件activity.xml,里面主要是一个ListView和一个操作栏文件。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@mipmap/bg1"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <ListView
        android:id="@+id/music_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1">

    </ListView>
    <RelativeLayout

        android:id="@+id/operate_menu"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_gravity="bottom"
        android:padding="0dp"
        android:gravity="bottom"
        android:background="@color/half_transparent"
        >
        <ImageView
            android:layout_marginLeft="3dp"
            android:id="@+id/music_album"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@mipmap/music_album"/>
        <com.zhanghao.freemusicversion_one.UI.widget.MyTextView
            android:id="@+id/music_name"
            android:layout_width="75dp"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/music_album"
            android:clickable="true"
            android:singleLine="true"
            android:ellipsize="marquee"
            android:textColor="@color/black"
            android:layout_marginTop="4dp"
            android:text="@string/music_name"/>
        <TextView
            android:id="@+id/player_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/music_album"
            android:layout_below="@+id/music_name"
            android:text="@string/player_name"
            android:layout_marginTop="3dp"
            android:textSize="12sp"
            android:layout_marginLeft="2dp"
            android:textColor="@color/gray"/>
        <ImageButton
            android:id="@+id/play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/play_btn_click"
            android:background="@color/transparent"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            />
        <ImageButton
            android:id="@+id/next"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/next_btn_click"
            android:background="@color/transparent"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/play"
            android:layout_marginLeft="11dp"

            />
        <ImageButton
            android:id="@+id/play_queue"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/playqueue_btn_click"
            android:background="@color/transparent"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"/>
    </RelativeLayout>

</LinearLayout>


4.为listView创建数据源,然后创建适配器

* 数据源的创建,用ContentResolver()获取sd卡上的音乐信息

    public static  ArrayList<MusicBean> getMusicBeans(Context context){
        //用ContentResolver获取音乐的基本信息
        Cursor cursor=context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null,null,null,MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
        ArrayList<MusicBean> list=new ArrayList<>();
        MusicBean musicBean;
        for(int i=0;i<cursor.getCount();i++){
            cursor.moveToNext();
            musicBean=new MusicBean();
            musicBean.setId(cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID)));
            musicBean.setAlbum(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM)));
            musicBean.setArtist(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)));
            musicBean.setDisplay(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME)));
            musicBean.setDuration(cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)));
            musicBean.setSize(cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE)));
            musicBean.setTitle(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)));
            musicBean.setUrl(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)));
            musicBean.setIs_Music(cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC)));
            if(musicBean.getIs_Music()==1)
                    list.add(musicBean);


        }

        return list;
    }
* 创建适配器MusicListAdapter.class,这是继承于BaseAdapter的

public class MusicListAdapter extends BaseAdapter {
    private Context context;
    private ArrayList<MusicBean> list;
    public MusicListAdapter(Context context, ArrayList<MusicBean> list) {
            this.context=context;
            this.list=list;
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Holder holder;
        if(convertView==null){
            holder=new Holder();
            convertView=(View)LayoutInflater.from(context).inflate(R.layout.music_list_item,null);
            holder.item_music_id= (TextView) convertView.findViewById(R.id.item_music_id);
            holder.item_music_name= (MyTextView) convertView.findViewById(R.id.item_music_name);
            holder.item_music_artist= (TextView) convertView.findViewById(R.id.item_music_artist);
            convertView.setTag(holder);
        }
        else{
            holder= (Holder) convertView.getTag();
        }
        holder.item_music_id.setText(position+"");
        holder.item_music_name.setText(list.get(position).getTitle());
        holder.item_music_artist.setText(list.get(position).getArtist());
        return convertView;
    }
    class Holder{
        TextView item_music_id;
        MyTextView item_music_name;
        TextView item_music_artist;
    }
}

* 绑定数据

    list= MediaUtils.getMusicBeans(this); //获取listView中需要使用的数据
        /**
         * 设置listView的适配器
         */
        adapter=new MusicListAdapter(this,list);
        listView.setAdapter(adapter);



5.实现音乐的播放功能:

音乐的播放是在后台执行的,所以必须创建一个MusicPlayService.class类,在Service里面实现播放器的功能暂停,下一首等等。

public class MusicPlayService extends Service {
    private  MyBroadcast myBroadcast;
    private MediaPlayer mediaPlayer=null;
    private String music_url;//音乐路径



    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        mediaPlayer=new MediaPlayer();//创建一个播放器

        //注册广播
        registerBroadcast();
    }

    /**
     * 注册广播

     * @return
     */
     public void registerBroadcast(){
        myBroadcast=new MyBroadcast();
         IntentFilter intentFilter=new IntentFilter();
         intentFilter.addAction(ActionContant.First_Open);

         registerReceiver(myBroadcast,intentFilter);
     }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        /**
         * 首次启动
         */
        Log.i("info","onStartCommand");
        if(intent.getAction().equals(ActionContant.First_Open)){
            Log.i("info","error");
            if(mediaPlayer!=null){
                mediaPlayer.release();
                mediaPlayer=new MediaPlayer();
            }
            music_url = intent.getStringExtra(Constant.Music_Uri);
            OpenMediaPlayer();

            /**
             * 发送广播
             */
            Intent intent1=new Intent();
            intent1.setAction(ActionContant.First_Open);
            sendBroadcast(intent1);
        }
        else if(intent.getAction()==ActionContant.Pause){
            Pause();

        }
        else if(intent.getAction()==ActionContant.Wake){
            Awake();
        }
        else if(intent.getAction()==ActionContant.Next){
            music_url=intent.getStringExtra(Constant.Music_Uri);
            Next();
        }



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

    /**
     * 设置MediaPlayer数据来源
     */
    public void OpenMediaPlayer(){
        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {

                    Intent intent=new Intent();
                    intent.setAction(ActionContant.Music_Play_Finish);
                    intent.putExtra(Constant.Is_play_finish,true);
                    sendBroadcast(intent);
            }
        });
        try {
            mediaPlayer.setDataSource(this, Uri.parse(music_url));

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

        try {
            mediaPlayer.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }

        mediaPlayer.start();

    }

    /**
     * 暂停
     */
    public void Pause(){
        mediaPlayer.pause();
    }

    /**
     * 唤醒
     * @param
     * @param
     */
    public void Awake(){
        mediaPlayer.start();
    }

    /**
     *下一首
     */
    public void Next(){
       mediaPlayer.reset();

        try {
            mediaPlayer.setDataSource(this,Uri.parse(music_url));
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            mediaPlayer.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
        mediaPlayer.start();



    }
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);

    }

    @Override
    public void onDestroy() {
        Log.i("info","Service_Destroy");
        super.onDestroy();
        mediaPlayer.release();

    }
}

6.设置播放等按钮的点击事件,这方面就不贴代码了,原因是比较简单,但是就是要处理好各部分之间的逻辑关系。

7.获取专辑图片并显示在界面上:

 /**
     * 获取专辑图片
     * @param context
     * @param music_id
     * @return
     */
    public static Bitmap getAlbumBitmap(Context context,long music_id){
        Bitmap bitmap;
        String Music_album="content://media/external/audio/media/"+music_id+"/"+"albumart";
        Uri uri=Uri.parse(Music_album);
        ParcelFileDescriptor parcelFileDescriptor= null;
        try {
            parcelFileDescriptor = context.getContentResolver().openFileDescriptor(uri,"r");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        if(parcelFileDescriptor!=null){
            FileDescriptor fileDescriptor=parcelFileDescriptor.getFileDescriptor();
            bitmap=BitmapFactory.decodeFileDescriptor(fileDescriptor);
        }
        else{
            bitmap=BitmapFactory.decodeResource(context.getResources(), R.mipmap.music_album);
        }

        return bitmap;
    }

OK,畅想音乐播放器第一版就结束了,后续还会有更复杂的版本,大约两周的时间更新一个大版本,请继续关注该博客。

需要源码的请加qq 2372126585 或者发送邮件到该QQ的邮箱,互相学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值