android操作sdcard中的多媒体文件(一)——音乐列表的制作
android操作sdcard中的多媒体文件(一)——音乐列表的制作
最近做了一个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"); } } |
这样,音乐的信息就显示在了列表中了
下一节将讲解更新列表的操作。
android操作sdcard中的多媒体文件(一)——音乐列表的制作的更多相关文章
- android操作sdcard中的多媒体文件(二)——音乐列表的更新
android操作sdcard中的多媒体文件(二)——音乐列表的更新 原文地址 在上一篇随笔中,我介绍了如何在程序中查询sdcard内的多媒体文件,并且显示到播放列表中,但是,如果在sdcard内删除 ...
- Android 获取SDCard中某个目录下图片
本文介绍Android开发中如何获取SDCard中某目录下的所有图片并显示出来,下面的我们提供的这个函数是通用的,只要提供路径就可以查询出该目录下所有图片的路径信息,并保存到一个List<Str ...
- Android 遍历sdcard中指定文件夹下的图片(jpg,jpeg,png)
File scanner5Directory = new File(Environment.getExternalStorageDirectory().getPath() + "/scann ...
- android从sdcard中读取bitmap
String sdcard_path=Environment.getExternalStorageDirectory().getCanonicalPath(); String file_path=sd ...
- 如何在Android的ListView中构建CheckBox和RadioButton列表(支持单选和多选的投票项目示例)
引言 我们在android的APP开发中有时候会碰到提供一个选项列表供用户选择的需求,如在投票类型的项目中,我们提供一些主题给用户选择,每个主题有若干选项,用户对这些主题的选项进行选择,然后提交. 本 ...
- android操作sqlite数据库及心得
写这篇文章主要是网上的对sqlite的操作太多且太杂,非常多时候都不能非常好的运用到自己的项目中,结构不清晰,我自己写了一篇适合刚刚接触的人看的操作方法. 近来用android时要将一些数据保存起来, ...
- 用Vue来实现音乐播放器(二十三):音乐列表
当我们将音乐列表往上滑的时候 我们上面的歌手图片部分也会变小 当我们将音乐列表向下拉的时候 我们的图片会放大 当我们将音乐列表向上滑的时候 我们的图片有一个高斯模糊的效果 并且随着我们的列 ...
- Android 4.3实现类似iOS在音乐播放过程中如果有来电则音乐声音渐小铃声渐大的效果
目前Android的实现是:有来电时,音乐声音直接停止,铃声直接直接使用设置的铃声音量进行铃声播放. Android 4.3实现类似iOS在音乐播放过程中如果有来电则音乐声音渐小铃声渐大的效果. 如果 ...
- Android学习笔记之数据的Sdcard存储方法及操作sdcard的工具类
FileService.java也就是操作sdcard的工具类: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ...
随机推荐
- HDU 4460
http://acm.hdu.edu.cn/showproblem.php?pid=4460 水题一道,oj时间卡的非常奇怪,把spfa的queue开成全局卡线过,别的全挂了,迪杰斯特拉的手写堆都超时 ...
- [转]LUA C 互调
组件工厂 ------3D游戏研发 LUA和C之间的函数调用 1.1 从C程序调用LUA函数 LUA的函数和普通变量一样也是First Class Variable类型,可以看作函数指针变量参与栈操作 ...
- 【转】Fast Entity Component System
http://entity-systems.wikidot.com/fast-entity-component-system Summary Create a generic System class ...
- Android 学习第1课,JDK工具包的安装
1. jdk 的下载 目前为止,jdk的最新版是jdk8,http://www.oracle.com/technetwork/java/javase/downloads/index.html 到这里下 ...
- Web前端学习笔记(001)
....编号 ........类别 ............条目 ................明细....................时间 一.Web前端学习笔记 ...
- HPCC 登录总结
最近开始做NGS的分析,数据明显更大,在自己的机子上面做有些不现实了,需要登录高性能计算机. 1. 目录结构: home directory: /auto/rcf-40/USERNAME -- onl ...
- JS中onpropertychange和onchange事件区别小结
当一个HTML元素的属性用js改变的时候,都能通过onpropertychange来捕获.例如一个文本text对象的value属性被页面的脚本修改的时候,onchange无法捕获到,而onproper ...
- XACT_ABORT 用法
首先创建一张表 Create Table TranTable( Id INT IDENTITY(1,1) PRIMARY KEY, Priority TINYINT--最大值255) 1. ...
- linux 解压命令大全
.tar 解包:tar xvf FileName.tar 打包:tar cvf FileName.tar DirName (注:tar是打包,不是压缩!) --------------- .gz 解压 ...
- Java 前端加密传输后端解密以及验证码功能
目录(?)[-] 加密解密 1 前端js加密概述 2 前后端加密解密 21 引用的js加密库 22 js加密解密 23 Java端加密解密PKCS5Padding与js的Pkcs7一致 验证码 1 概 ...