首先,这个播放器不是我想的,我是根据这个作者的博客教程来写的咯。。。也算是自己想啦,附上链接 http://blog.csdn.net/wwj_748/article/details/8899699
第一篇写的这些内容很简单,跟链接作者写的几乎一样。
他写的比较复杂,有些实现方式也不一样,所以自己写个博客记录一下...O(∩_∩)O~
这个播放器很简单,如果你是什么Api都不知道,看了这个两天就写完了,你可以边看边查相关的API是干嘛用的,如果之前都了解了相关的API,那么一天就能编完。
做一个播放器的大致思路是什么呢?播放器当然是要有播放的功能咯,这是我在废话。这个播放器是不带下载功能的,所以肯定是从你手机中获取已经存在的音乐。于是第一步就是获取手机中的音乐信息,这个跟播放器的界面没什么联系,那你可以把它写成一个工具类,叫做GetMusicListUtil,专门用来获取手机音乐信息的类。 上代码:
public class GetMusicListUtil {
/**
* 从手机中得到所有的音乐,放在list中保存
*
* @param context
* @return
* @author Yang
*/
public static List getMusicInfos(Context context)
{
Cursor cursor = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
List musicInfos = new ArrayList();
for(int i=0; i转换成List>的格式
* 为了给SimpleAdapter填充数据
*
* @param musicInfos
* @return
* @author Yang
*
*/
public static List> getMusicHashMaps(
List musicInfos)
{
List> musicHashMaps =
new ArrayList>();
for(Iterator iterator = musicInfos.iterator();iterator.hasNext();)
{
Mp3Info music = iterator.next();
HashMap map = new HashMap();
map.put("title", music.getTitle());
map.put("artist", music.getArtist());
map.put("size", String.valueOf(music.getSize()));
map.put("time", formatTime(music.getDuration()));
map.put("url", music.getUrl());
musicHashMaps.add(map);
}
return musicHashMaps;
}
}
相信大家都能看懂,Cursor对象进行查询,然后存到一个Mp3Info类型的List中,之所以下面还写了一个List
package org.com.ViPlayer;
public class Mp3Info
{
public long id;
public String title;
public String artist;
public long duration;
public long size;
public String url;
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;
}
}
一共只用到了这么多图片:背景,播放按钮图,下一首按钮图,前一首按钮图,音乐模式按钮图,音乐小图标。
然后就是主界面xml文件:
最上面放了四个按钮分别是 音乐模式、上一首、播放、下一首。这个界面就生成了,其中用到了一个Color.xml的文件,因为我的背景是黑色的,所以显示文字信息要用白色这种浅色。直接给一个Color文件,放在values文件下就行。这里面包含了不知道多少种颜色,请任意Get!
#FFFFFF
#FFFFF0
#FFFFE0
#FFFF00
#FFFAFA
#FFFAF0
#FFFACD
#FFF8DC
#FFF5EE
#FFF0F5
#FFEFD5
#FFEBCD
#FFE4E1
#FFE4C4
#FFE4B5
#FFDEAD
#FFDAB9
#FFD700
#FFC0CB
#FFB6C1
#FFA500
#FFA07A
#FF8C00
#FF7F50
#FF69B4
#FF6347
#FF4500
#FF1493
#FF00FF
#FF00FF
#FF0000
#FDF5E6
#FAFAD2
#FAF0E6
#FAEBD7
#FA8072
#F8F8FF
#F5FFFA
#F5F5F5
#F5F5DC
#F5DEB3
#F4A460
#F0FFFF
#F0FFF0
#F0F8FF
#F0E68C
#F08080
#EEE8AA
#EE82EE
#E9967A
#E6E6FA
#E0FFFF
#DEB887
#DDA0DD
#DCDCDC
#DC143C
#DB7093
#DAA520
#DA70D6
#D8BFD8
#D3D3D3
#D3D3D3
#D2B48C
#D2691E
#CD853F
#CD5C5C
#C71585
#C0C0C0
#BDB76B
#BC8F8F
#BA55D3
#B8860B
#B22222
#B0E0E6
#B0C4DE
#AFEEEE
#ADFF2F
#ADD8E6
#A9A9A9
#A9A9A9
#A52A2A
#A0522D
#9932CC
#98FB98
#9400D3
#9370DB
#90EE90
#8FBC8F
#8B4513
#8B008B
#8B0000
#8A2BE2
#87CEFA
#87CEEB
#808080
#808080
#808000
#800080
#800000
#7FFFD4
#7FFF00
#7CFC00
#7B68EE
#778899
#778899
#708090
#708090
#6B8E23
#6A5ACD
#696969
#696969
#66CDAA
#6495ED
#5F9EA0
#556B2F
#4B0082
#48D1CC
#483D8B
#4682B4
#4169E1
#40E0D0
#3CB371
#32CD32
#2F4F4F
#2F4F4F
#2E8B57
#228B22
#20B2AA
#1E90FF
#191970
#00FFFF
#00FFFF
#00FF7F
#00FF00
#00FA9A
#00CED1
#00BFFF
#008B8B
#008080
#008000
#006400
#0000FF
#0000CD
#00008B
#000080
#000000
这个播放器是不需要任何额外权限的。所以Manifest中除了Activity的信息不需要别的注册,Activity是自动生成的,所以就不用管咯......真开心...
现在我们生成了主界面,其实这个播放器因为很简单,所以只有这一个界面,另外有一个布局文件,是为了给主界面的音乐list布局的,名字叫做musi_list_item。里面只有音乐名字,歌手和时间这三项。下面就是这个xml文件咯:
首先要把我们获取到的音乐信息显示到主界面的listView控件中,只要在Activity的onCreate函数中使用Adapter对listView进行数据填充:
private SimpleAdapter adapter;
private List musicInfo;
private List> musicList;
musicInfo = GetMusicListUtil.getMusicInfos(MainActivity.this);
musicList = GetMusicListUtil.getMusicHashMaps(musicInfo);
adapter = new SimpleAdapter(MainActivity.this, musicList, R.layout.music_list_item,
new String[]{"title","artist","time"},
new int[]{R.id.title, R.id.Artist, R.id.duration});
listView.setAdapter(adapter);
经过这样的赋值,就可以把音乐的信息显示在list列表中了。我们这里用到的SimpleAdapter是最简单的一种,通常做项目的时候会自定义一个Adapter,继承自BaseAdapter,可以在其中进行一些操作,用的最多。比如想在listView列表中加入图片信息,建议自定义一个Adapter然后采用异步加载的方式。废话不多说,接着做。
现在我们已经把列表显示出来了,那么下一步就是点击一下列表,然后实现播放的功能,到这里为止,和原作者采用的方法都一样:
给listView添加OnItemClick事件:
listView.setOnItemClickListener(new MusicItemClickListener());
这个MusicItemClickLitener是自定义的一个类:
public class MusicItemClickListener implements OnItemClickListener
{
@Override
public void onItemClick(AdapterView> parent, View view, int position,
long id) {
if(musicInfo != null)
{
play.setBackgroundResource(R.drawable.pause);
Intent intent = new Intent();
intent.setAction("org.com.ViPlayer.MUSIC_SERVICE");
intent.putExtra("url", music.getUrl());
intent.putExtra("msg", 0);
startService(intent);
}
}
}
可以看出来,在item的点击事件中,启动播放音乐的服务,当点击音乐开始播放的时候,将播放按钮变成暂停按钮的图标,其中intent携带的msg这个信息传递的是0,暂定0为播放的意思,这个服务是单独写的一个类,叫做PlayerService,它继承自Service,但是如何知道上面Activity启动的是哪一个service呢,那就是intent.setAction("这个service的名字")这句话起的作用,我们能根据这个名字来调用service,就必须在AndroidManifest中注册这个service:
接下来我们实现这个PlayerService类:
package org.com.ViPlayer;
import java.util.List;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.IBinder;
public class PlayerService extends Service {
private MediaPlayer mediaPlayer;
//播放文件url
private String path;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//从上级页面取到音乐源
path = intent.getStringExtra("url");
int msg = intent.getIntExtra("msg", 0);
if(msg == 0)
{
//从头开始播放
play(0);
}
else if(msg == 1)
{
stop();
}
else if(msg == 2)
{
pause();
}
return super.onStartCommand(intent, flags, startId);
}
/**
* 播放音乐
*
* @param position
*/
public void play(int position)
{
try{
mediaPlayer.reset();
mediaPlayer.setDataSource(path);
mediaPlayer.prepare();
//注册监听器
mediaPlayer.setOnPreparedListener(new PreparedListener(position));
}catch(Exception e)
{
e.printStackTrace();
}
}
/**
* 暂停音乐
* 每次暂停isPause标识设为false并得到当前的播放位置
*/
public void pause()
{
if(mediaPlayer != null)
{
mediaPlayer.pause();
}
}
/**
* 停止音乐
* 这个stop和pause不一样,stop之后再想播放音乐要重新prepare一次
*
*/
public void stop()
{
if(mediaPlayer != null)
{
mediaPlayer.stop();
try
{
mediaPlayer.prepare();
}catch(Exception e)
{
e.printStackTrace();
}
}
}
@Override
public void onDestroy() {
if(mediaPlayer != null)
{
mediaPlayer.stop();
mediaPlayer.release();
}
}
private final class PreparedListener implements OnPreparedListener
{
private int position;
public PreparedListener(int positon)
{
this.position = positon;
}
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
//如果不是从头开始播放,找到当前位置
if(position >0)
{
mediaPlayer.seekTo(position);
}
}
}
}
下次继续实现的内容,下一篇的内容就非常简练化了,只要自己有想法就能直接做了:
1.播放完一个音乐之后,如何继续播放下一个。(给mediaPlayer添加歌曲完成事件)
2.实现前一首和后一首歌的播放。(获取当前点击位置,然后传递(位置-1)或(位置+1))
3.设定歌曲的播放模式。(设定模式标志变量,利用本地broadcast广播给service,实时变换模式。)
4.将当前播放歌曲的信息显示在界面下方。(同理利用licalBroadcastManager实现)