让TinyPlayer播放本地音乐文件1

摘要:《深入浅出Google Android》第9章为有源头话水来——使用SQLite、ContentProvider与Preferences处理数据,这一章我们将来认识Android平台是如何对数据进行处理的。包括文件I/O操作,如何在程序中实现数据库相关的操作,以及如何使用Preferences来存取数据。本节为大家介绍让TinyPlayer播放本地音乐文件1。
标签:TinyPlayer Google Android 深入浅出Google Android
Oracle帮您准确洞察各个物流环节

9.5 让TinyPlayer播放本地音乐文件1

本节将实现用一个ListView显示存储卡内所有的音乐,并且可通过长按进行播放。在播放一首音乐的同时,也将更新音轨信息。有关如何在模拟器中虚拟SD卡的内容请参考附录C。

首先重构用户界面,将原有的用户界面装进一个垂直的LinearLayout中,并在其下面添加一个ListView来显示存储卡上的音乐。


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:id="@+id/ctrlandinfo" android:orientation="horizontal" ... <ListView android:id="@+id/audiolist" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> 然后实现功能部分,编辑TinyPlayer.java,添加如下字段。 ListView audioList; ContentResolver resolver; TextView title; TextView artist; TextView album; SharedPreferences sp; final static String PREF = "NOW_PLAYING"; final static String URI_KEY = "uri"; 在onCreate()方法中,对这些字段进行赋值,并注释掉给nowPlaying赋值的语句。我们将直接读取上一次播放音乐的URI信息,或者动态地根据用户操作更新当前播放的URI。

title = (TextView)findViewById(R.id.tracktitle); artist = (TextView)findViewById(R.id.trackartist); album = (TextView)findViewById(R.id.trackalbum); audioList = (ListView)findViewById(R.id.audiolist); resolver = getContentResolver(); /*设置当前播放的Uri*/ //nowPlaying = Uri.parse("http://www.5billion.com.cn/music.mp3"); //读取上一次播放的Uri sp = getSharedPreferences(PREF, 0); String uriString = sp.getString(URI_KEY, null); if (uriString == null) { nowPlaying = null; } else { nowPlaying = Uri.parse(uriString); } 每一次应用程序退出时,需要保存当前播放音乐的URI,将以下代码添加到onDestroy()方法中。

@Override public void onDestroy() { ... SharedPreferences.Editor editor = sp.edit(); editor.putString(URI_KEY,nowPlaying.toString()); editor.commit(); super.onDestroy(); } 还是在onCreate()方法的实现中,对SD卡内的音频文件进行查询并返回包含所有音频文件信息的Cursor,然后利用CursorAdapter填充audioList。

Cursor c = resolver.query( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null); CursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2,c, new String[] {MediaStore.Audio.AudioColumns.TITLE, MediaStore.Audio.AudioColumns.ARTIST}, new int[] {android.R.id.text1,android.R.id.text2}); audioList.setAdapter(adapter); 在Android平台中,所有的音/视频文件的相关信息都是以Content的形式提供给开发者的,这里用到了静态常量MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,它表示主外部存储器(即SD卡)内的所有音频文件的索引数据库的content://样式的URI。

为了处理用户长按事件以播放所选音频,还要为audioList设置一个长按事件的监听器。

audioList.setOnItemLongClickListener(new OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int pos, long id) { nowPlaying = Uri.withAppendedPath( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, "/"+String.valueOf(id)); Intent i = new Intent(MusicPlayService.MUSIC_CONTROL); i.setData(nowPlaying); i.putExtra("cmd",MusicPlayService.CMD_PLAY); sendBroadcast(i); return true; } });0 现在就可以看到SD卡内的音频文件信息显示在ListView上了,但却还不能通过长按来播放所选音频,其原因是,在MediaPlayService中还没有为其注册对应IntentFilter的Broadcast-Receiver。因此,还要修改MediaPlayService.java中注册CommandReceiver的语句,由于这里没有用到HTTP的结构,所以就直接对这个IntentFilter进行修改。

IntentFilter filter1 = new IntentFilter(); filter1.addAction(MUSIC_CONTROL); //filter1.addDataScheme("http"); try { filter1.addDataScheme("content"); filter1.addDataType("audio/*"); } catch (MalformedMimeTypeException e) { e.printStackTrace(); } registerReceiver(doCommand, filter1); 经过这样注册后,长按audioList的某一项后就可以对该音频进行播放了。剩下的就是显示更新音轨信息了。先在TinyPlayer.java中的内部类updateReceiver里定义一个更新音轨信息的方法updateTrackInfo()。

/*更新音轨信息*/ public void updateTrackInfo() { Cursor c = resolver.query(nowPlaying,null,null,null,null); int titleIndex = c.getColumnIndex(MediaStore.Audio.AudioColumns.TITLE); int artistIndex = c.getColumnIndex(MediaStore.Audio.AudioColumns.ARTIST); int albumIndex = c.getColumnIndex(MediaStore.Audio.AudioColumns.ALBUM); if (c.getCount() != 0) { c.moveToFirst(); title.setText(c.getString(titleIndex)); artist.setText(c.getString(artistIndex)); album.setText(c.getString(albumIndex)); } } 然后在更新到PLAYING状态时,调用此方法就可以每次播放时更新音轨信息了。最后TinyPlayer的效果如图9-11所示。至此,我们整个TinyPlayer的例子也就告一段落了。接下来读者可以自己练习,继续完善TinyPlayer的功能,如前进、后退、下一首、上一首、播放列表以及在后台播放时显示Notification等功能。

case MusicPlayService.STATUS_PLAYING: playPauseBtn.setImageResource(R.drawable.pauseselector); updateTrackInfo(); break; ...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值