Android源码个个击破之-多媒体扫描-创新互联
最近公司产品有个需求:检测到U盘插入,只扫描U盘里的歌曲(音频文件)。
目前创新互联公司已为上千余家的企业提供了网站建设、域名、虚拟空间、网站托管、服务器租用、企业网站设计、东丰网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。1.技术要点1-adb指令得出U盘存储的真实路径:
监听U盘挂载(ACTION_MEDIA_MOUNTED)后,执行shell指令。
File file = new File("mnt/media_rw/usb_otg"); if(file.exists()){ ShellUtils.ShellResult shellResult = ShellUtils.execCommand("ls -l mnt/media_rw/usb_otg", true); if(!TextUtils.isEmpty(shellResult.successMsg)){ MusicScanUtil.U_PATH = shellResult.successMsg.split("usb_otg ->")[1].trim(); SPUtil.put(SPUtilKeys.U_PATH,MusicScanUtil.U_PATH); context.sendBroadcast(new Intent(MusicUIRefreshReceiver.ACTION)); Toast.makeText(context, "U盘已经插入:" + usb.getAbsolutePath(), Toast.LENGTH_SHORT).show(); }
最终MusicScanUtil.U_PATH存储的就是类似storage/EFDE-UEYT或者 storage/78634982792这种路径,不同型号的U盘不一样。
之所以要得出这个路径,是因为“context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,...)”扫描出来媒体文件,不光有内部存储的,还有SD卡和U盘上的,可以根据多媒体数据库表中的_data字段结合这个路径过滤U盘中的歌曲。
在测试的过程中,发现U盘里如果文件越多,媒体文件(视频)越多,则音频文件扫描出来的越慢。
优化1:检索数据库优化
getContentResolver().query()方法加上路径过滤条件。
//selection: 指定查询条件 String selection = MediaStore.Audio.Media.DATA + " like ?"; String[] selectionArgs = {MusicScanUtil.U_PATH + "%"}; Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, muiscInfoArray, selection, selectionArgs, null);
%相当于*,属于通配符。
优化2:多媒体文件扫描优化
分析多媒体数据库,会发现files表,不管啥文件,都会往里写东西。于是研究源码,看看这个数据库表是如何一步一步加载出来的。
MediaStore类介绍
MediaStore 与Media.EXTERNAL_CONTENT_URI
https://www.jianshu.com/p/c391ce8b6541
关于MediaStore.Files
多媒体数据库
https://www.jianshu.com/p/90832a323221
手机 db-wal db-shm 文件是什么数据?
外接存储OTG
音乐播放器基本功能
android中通知系统扫描系统媒体文件的几种方法
常见的15种音频格式
android存储路径
Android MediaProvider数据库模式(对数据库的每个表,每个字段做了详尽的注释。)
Android多媒体数据库详解
多媒体数据库扫描源码分析
Android media媒体库分析之:MediaProvider
Android MediaProvider,MediaScanner媒体文件扫描源码解析
Android开发——MediaProvider源码分析(1)(十分详细)
深入理解MediaScanner
加快U盘扫描的办法
1) http://cprs.patentstar.com.cn/Search/Detail?ANE=9CID3ADA9GEC9GGH7ECA9GDA8FCAAHGACIHAAHBA9IAB9GAB (该方法适用于提前知道目录情况,哪些目录有媒体文 件,哪些目录没有)
2)http://blog.sina.com.cn/s/blog_768100030101pohn.html
此博文有一处写错的地方:
,这里应该调用的是MediaScanner.cpp文件,不是java文件。
此博文提出的最值得借鉴的方法是,MediaScanner.java的scanFile方法,非媒体文件就不要进行数据库操作了,我修改代码如下:
@Override public void scanFile(String path, long lastModified, long fileSize, boolean isDirectory, boolean noMedia) { // This is the callback funtion from native codes. // Log.v(TAG, "scanFile: "+path); Log.i("CZLog","scanFile: " + path); //CZFIX 增加588到622行代码 (在操作数据库之前提前判断媒体文件,不进行数据库操作。2019.7.20) boolean nextStep = true; try { FileEntry entry = beginFile(path, null, lastModified, fileSize, isDirectory, noMedia); // if this file was just inserted via mtp, set the rowid to zero // (even though it already exists in the database), to trigger // the correct code path for updating its entry if (mMtpObjectHandle != 0) { entry.mRowId = 0; } // rescan for metadata if file was modified since last scan if (entry != null) { if (noMedia) { nextStep = false; Log.i("CZLog","nextStep111111 = " + nextStep); } else { boolean isaudio = MediaFile.isAudioFileType(mFileType); boolean isvideo = MediaFile.isVideoFileType(mFileType); boolean isimage = MediaFile.isImageFileType(mFileType); if (isaudio || isvideo || isimage) { nextStep = true; }else{ nextStep = false; Log.i("CZLog","nextStep222222 = " + nextStep); } } }else{ nextStep = false; Log.i("CZLog","nextStep33333 = " + nextStep); } } catch (Exception e) { Log.e(TAG, "RemoteException in MediaScanner.scanFile()", e); nextStep = false; Log.i("CZLog","nextStep444444 = " + nextStep); } Log.i("CZLog","nextStep final= " + nextStep); if(nextStep == false) return; doScanFile(path, null, lastModified, fileSize, isDirectory, false, noMedia); }
在doScanFile方法之前,我会判断文件是否是媒体文件,如果不是则不执行doScanFile,也就省略了数据库的操作。经测试,U盘扫描速度有所提高,但是200多首歌,扫描完还是得1分多钟。不知道到底是哪里慢呢?
***同一U盘,首次插入设备,数据库查询不到歌曲信息,但是后面再插入(中间不得插入其他U盘),数据库就会有缓存信息,此时U盘仍然会重新扫描一遍,然后更新数据库。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
文章题目:Android源码个个击破之-多媒体扫描-创新互联
文章位置:http://ybzwz.com/article/ddcgsp.html