http://www.cnblogs.com/zchajax/archive/2011/04/26/2029832.html


================================================

最近做了一个android音乐播放器,个人感觉最难的就是“后台播放”以及有关“播放列表”的部分,但是总算是找到了实现的方式。不同的人实现的方式可能不一样,这里我就分享一下自己对“播放列表”这个模块的一些实现方法,“后台播放”会在下一篇博文中进行介绍,希望大家也能分享一下自己的一些思路。

android使用ContentProvider来支持不同应用程序的数据共享,为了方便其他应用程序对sdcard中的数据进行操作,sdcard也提供了ContentProvider接口,这里就以访问音频文件为例,视频以及图片的操作也类似,这里就不在赘述。

  访问sdcard中的音频文件的URI为MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,为了使播放列表显示所以音乐文件的信息,这里需要查询sdcard里的音频文件,并把查询到的信息保存在Cursor中,具体代码如下:  

                                      ?                
<pre>Cursor c = this .getContentResolver().</pre> <pre>query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,</pre> /*这个字符串数组表示要查询的列*/
?
new String[]{MediaStore.Video.Media.TITLE, //音乐名 MediaStore.Audio.Media.DURATION, //音乐的总时间 MediaStore.Audio.Media.ARTIST, //艺术家 MediaStore.Audio.Media._ID, //id号 MediaStore.Audio.Media.DISPLAY_NAME, //音乐文件名 MediaStore.Audio.Media.DATA          //音乐文件的路径 }, null ,                       //查询条件,相当于sql中的where语句 null ,                       //查询条件中使用到的数据 null );                      //查询结果的排序方式
  通过MediaStore.Audio.Media.XXX来访问音乐文件的一些信息,这里只列出了一部分,可以根据需要进行增添和删除。
至此,Cursor c就已经保存了sdcard内所以音频文件的信息,下面的操作就是围绕这个Cursor展开的。
首先定义三个数组:
                               ?              
private int [] _ids;     //存放音乐文件的id数组 private String[] _titles;  //存放音乐文件的标题数组 private String[] _path; //存放音乐文件的路径
_ids保存了所有音乐文件的_ID,用来确定到底要播放哪一首歌曲,_titles存放音乐名,用来显示在播放界面,而_path存
放音乐文件的路径(删除文件时会用到)。
  接下来再定义一个变量,用来定位选择的是哪一首音乐:
private int pos;
  接下来将音乐文件的信息存放在相应的数组中:  
          
                                             ?                  
c.moveToFirst(); _ids = new int [c.getCount()]; _titles = new String[c.getCount()]; _path = new String[c.getCount()]; for ( int i=0;i<c.getCount();i++){ _ids[i] = c.getInt(3);           _titles[i] = c.getString(0); _path[i] = c.getString(5).substring(4); c.moveToNext(); }        
有人可能会问为什么获取路径的格式是_path[i]=c.geString(5).substring(4)?因为MediaStore.Audio.Media.DATA
得到的内容格式为/mnt/sdcard/[子文件夹名/]音乐文件名,而我们想要得到的是/sdcard/[子文件夹名]音乐文件名,
所以要做相应的裁剪操作。
  接下来把Cursor中的信息显示到listview中:
          
                                             ?                  
MusicListAdapter adapter = new MusicListAdapter( this , c); listview.setAdapter(adapter);
MusicListAdapter是一个自定义的Adapter,继承自BaseAdapter,这里只贴出代码,不做讲解。
          
                                             ?                  
package com.alex.video; import android.content.Context; import android.database.Cursor; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class MusicListAdapter extends BaseAdapter{ private Context myCon; private Cursor myCur; private int pos=-1; public MusicListAdapter(Context con,Cursor cur){ this .myCon = con; this .myCur = cur; } @Override public int getCount() { return this .myCur.getCount(); } @Override public Object getItem( int position) { return position; } @Override public long getItemId( int position) { return position; } @Override public View getView( int position, View convertView, ViewGroup parent) { convertView = LayoutInflater.from(myCon).inflate(R.layout.musiclist, null ); myCur.moveToPosition(position); TextView videoTitle = (TextView)convertView.findViewById(R.id.musictitle); if (myCur.getString(0).length()>24){ try { String musicTitle = bSubstring(myCur.getString(0).trim(),24); videoTitle.setText(musicTitle); } catch (Exception e) { e.printStackTrace(); } } else { videoTitle.setText(myCur.getString(0).trim()); } TextView videoArtist = (TextView)convertView.findViewById(R.id.musicartist); if (myCur.getString(2).equals( "<unknown>" )){ videoArtist.setText( "未知艺术家" ); } else { videoArtist.setText(myCur.getString(2)); } TextView videoTime = (TextView)convertView.findViewById(R.id.musictime); videoTime.setText(toTime(myCur.getInt(1))); ImageView videoItem = (ImageView)convertView.findViewById(R.id.musicitem); videoItem.setImageResource(R.drawable.item); return convertView; } /*时间格式转换*/ 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); } /*字符串裁剪*/ public static String bSubstring(String s, int length) throws Exception { byte [] bytes = s.getBytes( "Unicode" ); int n = 0; // 表示当前的字节数 int i = 2; // 要截取的字节数,从第3个字节开始 for (; i < bytes.length && n < length; i++) { // 奇数位置,如3、5、7等,为UCS2编码中两个字节的第二个字节 if (i % 2 == 1) { n++; // 在UCS2第二个字节时n加1 } else { // 当UCS2编码的第一个字节不等于0时,该UCS2字符为汉字,一个汉字算两个字节 if (bytes[i] != 0) { n++; } } } // 如果i为奇数时,处理成偶数 if (i % 2 == 1) { // 该UCS2字符是汉字时,去掉这个截一半的汉字 if (bytes[i - 1] != 0) i = i - 1; // 该UCS2字符是字母或数字,则保留该字符 else i = i + 1; } return new String(bytes, 0, i, "Unicode" ); } }

这样,音乐的信息就显示在了列表中了

下一节将讲解更新列表的操作。

更多相关文章

  1. Android应用实例之----基于Service与ContentProvider的音乐播放
  2. C基础—函数指针,联合体,枚举,结构体和结构体指针
  3. android 将时长毫秒转化为分钟和秒
  4. Android流量统计
  5. android音乐文件乱码显示问题解决
  6. Android(安卓)MP4取得播放时长的方法
  7. android 操作sdcard中的多媒体文件(一)——音乐列表的制作
  8. Android(安卓)mediaplayer 播放本地音乐文件
  9. 从Android设备获取实时截屏

随机推荐

  1. Android Studio笔记(2)——快捷键
  2. 第二章 Android动态加载、热更新、热修复
  3. Android background tint颜色渲染
  4. Android DiskLruCache完全解析,硬盘缓存的
  5. webview 笔记二(android和js交互、包括链
  6. Android全埋点解决方案-认识
  7. Android里Context的使用
  8. Android异步处理常用方法
  9. android上实现Junit单元测试
  10. .net平台借助第三方推送服务在推送Androi