本人接触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的邮箱,互相学习。