android操作sdcard中的多媒体文件(二)——音乐列表的更新

简介:

android操作sdcard中的多媒体文件(二)——音乐列表的更新

原文地址

在上一篇随笔中,我介绍了如何在程序中查询sdcard内的多媒体文件,并且显示到播放列表中,但是,如果在sdcard内删除、增加一些多媒体文件,如何让播放列表也更新呢,这里我分享一下自己在项目中的一些解决方法,希望对大家有所帮助。                                     

  首先,我简单介绍一下android是如何扫描sdcard内的多媒体信息的,详细请阅读stay的博文:http://www.cnblogs.com/stay/articles/1957571.html
  当android的系统启动的时候,系统会自动扫描sdcard内的多媒体文件,并把获得的信息保存在一个系统数据库中,以后在其他程序中如果想要访问多媒体文件的信息,其实就是在这个数据库中进行的,而不是直接去sdcard中取,理解了这一点以后,问题也随着而来:如果我在开机状态下在sdcard内增加、删除一些多媒体文件,系统会不会自动扫描一次呢?答案是否定的,也就是说,当你改变sdcard内的多媒体文件时,保存多媒体信息的系统数据库文件是不会动态更新的。
  那么如何让多媒体数据库中的数据更新呢?我们可以采用广播机制来实现:在应用程序中发送一个广播,让android系统扫描sdcard并更新多媒体数据库        
private  void  scanSdCard(){
        IntentFilter intentfilter = new  IntentFilter( Intent.ACTION_MEDIA_SCANNER_STARTED);
        intentfilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
        intentfilter.addDataScheme( "file" );
        scanSdReceiver = new  ScanSdReceiver();
        registerReceiver(scanSdReceiver, intentfilter);
        sendBroadcast( new  Intent(Intent.ACTION_MEDIA_MOUNTED,
                Uri.parse( "file://"  + Environment.getExternalStorageDirectory().getAbsolutePath()))); }
  其中ScanSdReceiver是一个自定义的广播接收器,继承自BroadCastReceiver,因为android系统开始扫描sdcard以及扫描完毕时都会发送一个系统广播来表示当前扫描的状态,这样我们就可以很方便通过判断当前的扫描状态加一些自己的逻辑操作,ScanSdReceiver的代码如下:
public  class  ScanSdReceiver extends BroadcastReceiver {
 
    private  AlertDialog.Builder  builder = null ;
    private  AlertDialog ad = null ;
    private  int  count1;
    private  int  count2;
    private  int  count;
    @Override
    public  void  onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if  (Intent.ACTION_MEDIA_SCANNER_STARTED. equals (action)){
            Cursor c1 = context.getContentResolver()
            .query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                    new  String[]{MediaStore.Audio.Media.TITLE,
                    MediaStore.Audio.Media.DURATION,
                    MediaStore.Audio.Media.ARTIST,
                    MediaStore.Audio.Media._ID,
                    MediaStore.Audio.Media.DISPLAY_NAME },
                    null , null , null );
            count1 = c1.getCount();
            System. out .println( "count:" +count);
            builder = new  AlertDialog.Builder(context);
            builder.setMessage( "正在扫描存储卡..." );
            ad = builder.create();
            ad.show();
           
        } else  if (Intent.ACTION_MEDIA_SCANNER_FINISHED. equals (action)){
            Cursor c2 = context.getContentResolver()
            .query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                    new  String[]{MediaStore.Audio.Media.TITLE,
                    MediaStore.Audio.Media.DURATION,
                    MediaStore.Audio.Media.ARTIST,
                    MediaStore.Audio.Media._ID,
                    MediaStore.Audio.Media.DISPLAY_NAME },
                    null , null , null );
            count2 = c2.getCount();
            count = count2-count1;
            ad.cancel();
            if  (count>=0){
                Toast.makeText(context, "共增加"  +
                        count + "首歌曲" , Toast.LENGTH_LONG).show();
            } else  {
                Toast.makeText(context, "共减少"  +
                        count + "首歌曲" , Toast.LENGTH_LONG).show();
            }  
        }  
    }
}
  
  
  这里我们定义了两个Cursor对象,分别用来存储扫描前后的多媒体信息,并给出相应的提示。  
  以前有很多朋友问过我,为什么扫描以后播放列表中的数据条数没有发生相应的改变。要实现播放列表在扫描后更新,必须重新读取多媒体信息到Cursor中,并且重新设置adapter,最后还要调用XXXAdapter.notifyDataSetChanged()来通知UI更新。(可以参考第一张的内容)
  上面的操作都是手动在SDCARD中添加或着删除多媒体文件,下面介绍如何在列表中删除SDCARD中的多媒体文件。
  在上一篇随笔中,我们使用了系统提供的ContentProvider来查询sdcard中的多媒体文件,我们同样可以使用这个ContentProvider来进行删除操作: 
private  void  deleteMusic( int  position){
    this .getContentResolver().delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            MediaStore.Audio.Media._ID + "="  + _ids[position],
            null );
}
   其中“多媒体文件的ID”可以从_ids数组中取得(关于_ids数组请参考第一张的内容)。这样,我们是否就已经从SDCARD中删除了指定_ID的多媒体文件了呢?  其实当你打开FileExplorer时会发现,原来的文件并没有被删除,— —!杯具,搞了半天文件还在,我第一次遇到这个问题的时候也是纠结了老半天。。。
为什么没有被删除,原因是上面的删除操作只是删除了系统多媒体数据库中的相应记录,而并没有删除SDCAED中的文件(注意:多媒体信息数据库和SDCARD中的多媒体文件并不会自动保持同步),这个时候如果再次扫描SDCARD,你会发现刚才从播放列表中删除的行会再次出现。
   其实要想真正的从SDCARD中删除多媒体文件并不难,可能有朋友会想到这样的方法:遍历SDCARD中的多媒体文件,然后把想要删除的文件和其他文件逐一比较,找到文件路径,最后进行删除。这种方法是可以实现删除操作的,不过效率很低,如果SDCARD中的文件夹以及文件很多,也不知道要用掉多少时间。。
  在上一张中我们从多媒体数据库中读出来一项很重要的信息:MediaStore.Audio.Media.DATA
并且取得里面的字串并存放在了_path数组中,最终的数据格式为:/SDCARD/[子文件夹名]文件名 ,又了这个路径,我们就可以很方便的从SDCARD中删除多媒体文件了
private  void  deleteMusicFile( int  position){
    File file = new  File(_path[position]);
    file.delete();
}
   同样,删除文件后要想播放列表同步更新,也必须执行刚才介绍的一系列操作。  


本文转自Work Hard Work Smart博客园博客,原文链接:http://www.cnblogs.com/linlf03/p/3429420.html,如需转载请自行联系原作者
目录
相关文章
|
1月前
|
XML 缓存 Android开发
Android开发,使用kotlin学习多媒体功能(详细)
Android开发,使用kotlin学习多媒体功能(详细)
102 0
|
2天前
|
存储 Java API
Android系统 文件访问权限笔记
Android系统 文件访问权限笔记
29 1
|
2天前
|
移动开发 Java Unix
Android系统 自动加载自定义JAR文件
Android系统 自动加载自定义JAR文件
18 1
|
2天前
|
Shell Android开发
Android系统 adb shell push/pull 禁止特定文件
Android系统 adb shell push/pull 禁止特定文件
14 1
|
2天前
|
Android开发
Android源代码定制:添加customize.mk文件进行分项目和分客户的定制
Android源代码定制:添加customize.mk文件进行分项目和分客户的定制
2 0
|
2月前
|
JSON Java Go
|
4天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
24 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
26天前
|
Java Android开发
Android 开发获取通知栏权限时会出现两个应用图标
Android 开发获取通知栏权限时会出现两个应用图标
12 0
|
22小时前
|
数据库 Android开发 开发者
安卓应用开发:构建高效用户界面的策略
【4月更文挑战第24天】 在竞争激烈的移动应用市场中,一个流畅且响应迅速的用户界面(UI)是吸引和保留用户的关键。针对安卓平台,开发者面临着多样化的设备和系统版本,这增加了构建高效UI的复杂性。本文将深入分析安卓平台上构建高效用户界面的最佳实践,包括布局优化、资源管理和绘制性能的考量,旨在为开发者提供实用的技术指南,帮助他们创建更流畅的用户体验。