一步一步实现音乐播放器

过年前我已经做过一个android版音乐播放器,模仿音乐播放器项目,这个播放器基本功能已经实现,但是最大的问题是播放代码放在了activity中处理的,当推出音乐播放界面的时候,音乐是需要继续播放,当带过来电话时音乐需要暂停,打完电话继续播放,所以以前的版本还是有很大问题的,今天决定一步一步实现一个功能齐全的播放器,把播放控制代码放在service中。

首先来实现这样一个简单的界面:

新建一个android项目,如图所示:

把项目中用到的图片拷贝到drawable目录下,编写main.xml

<?xml version="1.0" encoding="utf-8"?> <TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:padding="5dp" > <TabWidget android:id="@android:id/tabs" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="5dp" /> </LinearLayout> </TabHost>
编写MainActivity类

public class MainActivity extends TabActivity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.main); Resources res = getResources(); TabHost tabHost = getTabHost(); TabHost.TabSpec spec; Intent intent; intent = new Intent().setClass(this, ListActivity.class); spec = tabHost.newTabSpec("音乐").setIndicator("音乐", res.getDrawable(R.drawable.item)) .setContent(intent); tabHost.addTab(spec); intent = new Intent().setClass(this, ArtistsActivity.class); spec = tabHost.newTabSpec("艺术家").setIndicator("艺术家", res.getDrawable(R.drawable.artist)) .setContent(intent); tabHost.addTab(spec); intent = new Intent().setClass(this, AlbumsActivity.class); spec = tabHost.newTabSpec("专辑").setIndicator("专辑", res.getDrawable(R.drawable.album)) .setContent(intent); tabHost.addTab(spec); intent = new Intent().setClass(this, SongsActivity.class); spec = tabHost.newTabSpec("最近播放").setIndicator("最近播放", res.getDrawable(R.drawable.album)) .setContent(intent); tabHost.addTab(spec); tabHost.setCurrentTab(0); } } 注意这里要继承的是TabActivity,关于TabHost的用法不做过多介绍,官网有。最后分别建立其他用到的activity和使用的xml布局文件,不要忘记在manifest中注册,

这样上面的主界面就完成了。

下面看一下怎么遍历音乐文件,通过listview展现到界面上,

在相应目录下建立MusicList类,这是一个普通类,为了加载音乐文件

public class MusicList { public static List<Music> getMusicData(Context context){ List<Music> musicList=new ArrayList<Music>(); ContentResolver cr=context.getContentResolver(); if(cr!=null){ //获取所有歌曲 Cursor cursor=cr.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null,null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER); if(null==cursor){ return null; } if(cursor.moveToFirst()){ do{ Music m=new Music(); String title=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)); String singer=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)); if("<unknown>".equals(singer)){ singer="未知艺术家"; } String album=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM)); long size=cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE)); long time=cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)); String url=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)); String name=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME)); m.setTitle(title); m.setSinger(singer); m.setAlbum(album); m.setSize(size); m.setTime(time); m.setUrl(url); m.setName(name); musicList.add(m); }while(cursor.moveToNext()); } } return musicList; } } 这里是通过ContentResolver得到的音乐信息,因为系统为了便于应用程序间音乐信息的共享,提供了ContentProvder,所以我就没有遍历SD卡下的音乐文件。
Music类:

public class Music { private String title; private String singer; private String album; private String url; private long size; private long time; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getSinger() { return singer; } public void setSinger(String singer) { this.singer = singer; } public String getAlbum() { return album; } public void setAlbum(String album) { this.album = album; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public long getSize() { return size; } public void setSize(long size) { this.size = size; } public long getTime() { return time; } public void setTime(long time) { this.time = time; } } 因为要用到自定义适配器,所以在layout下先建立一个和适配器匹配的xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="2dip" android:background="#00000000" android:orientation="horizontal" > <ImageView android:id="@+id/music_item_image" android:layout_width="40dp" android:layout_height="40dp" android:layout_gravity="center" android:background="@drawable/item" android:paddingRight="10dip" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="60dip" android:layout_weight="1" android:layout_marginLeft="3dp" android:gravity="center_vertical" android:orientation="vertical" > <TextView android:id="@+id/music_item_name" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:textColor="#ffffff" android:textSize="18dp" android:text="依然爱你" android:textStyle="bold" /> <TextView android:id="@+id/music_item_singer" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginTop="5dip" android:textColor="#ffffff" android:text="王力宏" android:textSize="12dp" /> </LinearLayout> <TextView android:id="@+id/music_item_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:paddingRight="5dip" android:text="03:42" android:textColor="#ffffff" /> </LinearLayout> 接下来是自定义的适配器MusicAdapter

public class MusicAdapter extends BaseAdapter { private List<Music> listMusic; private Context context; public MusicAdapter(Context context,List<Music> listMusic){ this.context=context; this.listMusic=listMusic; } public void setListItem(List<Music> listMusic){ this.listMusic=listMusic; } @Override public int getCount() { // TODO Auto-generated method stub return listMusic.size(); } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return listMusic.get(arg0); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub if(convertView==null){ convertView=LayoutInflater.from(context).inflate(R.layout.music_item, null); } Music m=listMusic.get(position); //音乐名 TextView textMusicName=(TextView) convertView.findViewById(R.id.music_item_name); textMusicName.setText(m.getName()); //歌手 TextView textMusicSinger=(TextView) convertView.findViewById(R.id.music_item_singer); textMusicSinger.setText(m.getSinger()); //持续时间 TextView textMusicTime=(TextView) convertView.findViewById(R.id.music_item_time); textMusicTime.setText(toTime((int)m.getTime())); return convertView; } /** * 时间格式转换 * @param time * @return */ public String toTime(int time) { time /= 1000; int minute = time / 60; int hour = minute / 60; int second = time % 60; minute %= 60; return String.format("%02d:%02d", minute, second); } } 时间格式的转换是我从网上找到的,直接调用toTime方法能得到格式化后的时间了。

最后是在ListActivity添加适配器:

public class ListActivity extends Activity { private ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.listmusic); listView= (ListView) this.findViewById(R.id.listAllMusic); List<Music> listMusic=MusicList.getMusicData(getApplicationContext()); MusicAdapter adapter=new MusicAdapter(this, listMusic); listView.setAdapter(adapter); } }
这样音乐文件就会加载上来了,看看效果吧:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值