终于把这两个功能做出来了,先把效果图展示给大家。一个是能把音乐名字按字母顺序排列分类,还能查找(主要是查找现在页面上已经存在的音乐,以后在升级的时候可能会有后台服务搜索网络歌曲)。另外一个功能是查找本地本地歌曲,找到后放在自己的文件夹下边(其实这个音乐播放器所有的样式或者是功能都是参考的酷狗音乐播放器~~(⊙o⊙)…只是参考!!!很多地方需要改进,也没有人家做的好看实用)。做这两个功能尤其是自定义扫描音乐,遇到很多问题。中间还有一次升级系统到5.0,结果被坑了,好多东西不兼容。
下边介绍我的思路。较之第一版很多地方有修改!
第一版启动应用的时候就自动扫描手机上所有声音文件,这样做特别乱。改进后可以选择扫描文件夹下的音乐。扫描后放到自己的文件夹。
android系统中文件的树形加载代码如下:
public class FileListActivity extends BaseActivity { //记录文件名字 private List<String> pathName = new ArrayList<String>(); //记录非文件夹位置 private List<Boolean> pArray = new ArrayList<Boolean>(); //存放文件夹完整路径 private List<String> filePath = new ArrayList<String>(); private MyFileListAdapter mAdapter; private List<HashMap<String, Object>> data; private ListView list_route_music; //用于记录当前文件夹的路径 private static String choose_path = ""; private TextView back; private TextView began_scan; @Override public void onCorpusSelected(Music music) { } @Override protected void initDate() { mApplication = (MyApplication) getApplication(); data = new ArrayList<HashMap<String, Object>>(); File file = Environment.getExternalStorageDirectory(); choose_path = file.getPath(); readfile(choose_path); setData(); mAdapter = new MyFileListAdapter(FileListActivity.this, data, R.layout.item_file_name, new String[]{"path_text"}, new int[]{R.id.path_text}); } @Override protected void initView() { setContentView(R.layout.activity_file_list); back = (TextView)findViewById(R.id.back); began_scan = (TextView)findViewById(R.id.began_scan); list_route_music = (ListView)findViewById(R.id.list_route_music); list_route_music.setAdapter(mAdapter); } @Override protected void initEvent() { list_route_music.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { choose_path += File.separator + pathName.get(arg2);//用于记录每次选择的路径 if((Boolean) data.get(arg2).get("isvisble")){ readfile(choose_path); setData(); Message msg = new Message(); msg.what = Constants.FRESH; mHandler.sendMessage(msg); } } }); began_scan.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mApplication.setChoose_path(mAdapter.choose_file_path); Intent intent = new Intent(); intent.setClass(FileListActivity.this, ScanMusicActivity.class); intent.putExtra("flag_scan", 1); startActivity(intent); } }); //返回事件,返回到上层文件 back.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { File file = new File(choose_path); //得到当前文件的上层文件路径 choose_path = file.getParent(); if(choose_path.endsWith("/")){//判断如果到了最上层文件夹后返回页面 FileListActivity.this.finish(); }else{ readfile(choose_path); setData(); Message msg = new Message(); msg.what = Constants.FRESH; mHandler.sendMessage(msg); } } }); } public void readfile(String path) { pathName.clear(); pArray.clear();//用于设置文件夹图标是否显示 filePath.clear(); choose_path = path; File file = new File(path); if (!file.isDirectory()) {//判断是不是根文件夹,不是根文件夹直接放到List中 pathName.add(path); pArray.add(false); filePath.add(path); } else if (file.isDirectory()) {//是根文件夹列出文件夹里的文件 String[] filelist = file.list(); for (int i = 0; i < filelist.length; i++) { File readfile = new File(path + File.separator + filelist[i]); if (!readfile.isDirectory()) {//判断是不是根文件夹 pathName.add( filelist[i]); pArray.add(false); filePath.add(readfile.getPath()); } else if (readfile.isDirectory()) {//是根文件夹直接放到List中 pathName.add( filelist[i]); pArray.add(true); filePath.add(readfile.getPath()); } } } } //封装数据 private void setData(){ data.clear(); for(int i = 0; i < pathName.size(); i++){ HashMap<String,Object> map = new HashMap<String, Object>(); map.put("path_text",pathName.get(i)); map.put("ischecked",false); map.put("isvisble", pArray.get(i)); map.put("parent_path", filePath.get(i)); data.add(map); } } //刷新界面 private Handler mHandler = new Handler(){ public void handleMessage(Message msg){ switch (msg.what) { case Constants.FRESH: mAdapter.notifyDataSetChanged(); break; default: break; } } }; @Override public void onBackPressed() { File file = new File(choose_path); //得到当前文件夹的父文件夹 choose_path = file.getParent(); //判断如果到了最上层文件夹后返回页面 if(choose_path.endsWith("/")){ super.onBackPressed(); }else{ readfile(choose_path); setData(); Message msg = new Message(); msg.what = Constants.FRESH; mHandler.sendMessage(msg); } } }
然后开始选择文件夹扫描:
如果刚开始选择的是全盘扫描则:
private void scanMusicByAuto(){ musiclist.clear(); Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; //游标查询手机上所有的音乐 Cursor cursor = mActivity.getContentResolver().query(uri, null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER); FileUtils.createDirFile(Constants.FILE_PATH); if(cursor == null || cursor.getCount() <= 0){ mApplication.setMusiclist(musiclist); }else{ while(cursor.moveToNext()){ String oldpath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)); Music music = new Music(); music.setId(cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media._ID))); //歌曲ID String musicName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)); music.setTitle(musicName);//歌曲的名称 music.setAlbum(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM))); //歌曲的专辑名 music.setArtists(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST))); //歌曲的歌手名 music.setTimes(toTime(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION))));//歌曲的总播放时长 music.setPath(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)));//歌曲文件的路径 music.setSize(cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)));//歌曲文件的大小 if(oldpath.contains(Constants.FILE_PATH)){ //复制音乐到自己的文件夹下边 FileUtils.copyFile(oldpath, Constants.FILE_PATH + musicName + ".mp3"); }else{ } //把查找到的音乐放到list中 musiclist.add(music); } if(cursor != null){ cursor.close(); cursor = null; } } }
如果选择的是固定文件夹扫描则:
private void scanMusicByOneself(){ musiclist.clear(); String uri; ContentResolver mResolver = mActivity.getContentResolver(); Cursor cursor = mResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER); int i = 0; int cursorCount = cursor.getCount(); FileUtils.createDirFile(Constants.FILE_PATH); if (cursorCount > 0 && choose_path != null && choose_path.size() > 0){ int k = 0; cursor.moveToFirst(); while (i < cursorCount){ //歌曲文件的路径 :MediaStore.Audio.Media.DATA uri = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)); for(int j = 0; j < choose_path.size(); j++){ if(uri.contains(choose_path.get(j))){ Music music = new Music(); music.setId(cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media._ID))); //歌曲ID String musicName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)); music.setTitle(musicName);//歌曲的名称 music.setAlbum(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM))); //歌曲的专辑名 music.setArtists(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST))); //歌曲的歌手名 music.setTimes(toTime(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION))));//歌曲的总播放时长 music.setPath(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)));//歌曲文件的路径 music.setSize(cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)));//歌曲文件的大小 if(uri.contains(Constants.FILE_PATH)){ }else{ //复制音乐到自己的文件夹下边 FileUtils.copyFile(uri, Constants.FILE_PATH + musicName + ".mp3"); } musiclist.add(music); } } i++; cursor.moveToNext(); } if(cursor != null){ cursor.close(); cursor = null; } } }
扫描完成,就在我庆幸的时候问题出现了!!!虽然扫描成功了,但是再回到主界面使用游标读取媒体数据库中自己音乐的时候,没有任何数据!!!郁闷久,第二天奇迹般的能找到了!!!!再测试还是找不到!我就想我昨天晚上回家玩手机,手机没电了,会不会手机重启就好了!发现果然是这样~~
android在启动的时候会启动MediaScannerService扫描系统上的多媒体文件,然后将这些多媒体文件的信息加入到多媒体数据库中,应用程序要取得这些多媒体信息就是从这个多媒体数据库里面去取的,并不是从SD卡中取。也就是说,如果开机后增加或删除了一些多媒体,这个多媒体数据库是不会自动刷新的。
下边是我手动刷新媒体数据库代码:
private void scanSdCard(){ /** *使用这个动作需要加权限 <protected-broadcast android:name="android.intent.action.MEDIA_MOUNTED" /> */ // mActivity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, // Uri.parse("file://" + Environment.getExternalStorageDirectory().getAbsolutePath()))); <span style="white-space:pre"> </span>//4.4以上使用这个 <span style="white-space:pre"> </span>mActivity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, <span style="white-space:pre"> </span>Uri.parse("file://" + Environment.getExternalStorageDirectory().getAbsolutePath()))); }
就是在这个地方也很坑!中途升级一次升之前是4.1,系统升到了5.0,上边的那个动作就不行了,然后用同事手机测试他手机是4.3上下两个都不行(关于这个以后还要在研究一下到底是什么情况)
这些都做完了,,刷新完后还要再使用游标读取一次刷新后的音乐信息!我就懒省事了,不写广播了,直至使用了两次查询(一次查询是为了复制自己需要的音乐,另一次查询是查找手机多媒体数据库中自己需要的音乐)
查询完了然后就直接把音乐排好序,set到mApplication.setMusiclist(musiclist);以后直接拿出来使用!关于排序这块是看了大神的demo进行修改应用到自己项目中这里是网址:http://blog.csdn.net/xiaanming/article/details/12684155
这里可以下载源码:
http://download.csdn.net/detail/yan943789510/8728909