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

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

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

              
Cursor c = this.getContentResolver().
query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
/*这个字符串数组表示要查询的列*/
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;}@Overridepublic int getCount() {return this.myCur.getCount();}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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 播放Raw文件夹下的音乐文件
  2. Android 扫描音乐文件、两种方式获取文件最新修改时间
  3. Android汉字转换成拼音
  4. 利用第三方jar包jaudiotagger实现与MediaMetadataRetriever类似
  5. 2019AndroidBAT.字节跳动74道高级面试第二篇
  6. android 字节数据的转换与处理
  7. Android Java汉字转拼音总结
  8. Android 中汉字转化为拼音
  9. Android 扫描SDCard上的音乐文件以及监听扫描事件

随机推荐

  1. Android中Preference的使用以及监听事件
  2. Android中使用log4j
  3. Android中数据存储的几种方法
  4. Android(安卓)touch 事件的分发和消费机
  5. Android的string-array数据源简单使用
  6. 转:Android实现矩形设置菜单
  7. Android开发:观察者模式应用实例
  8. Android(安卓)之修改主题theme(系统自带样
  9. android 常见布局及控件的属性详解
  10. Android(安卓)2.3 StatusBar 分析(二)