当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();
}
同样,删除文件后要想播放列表同步更新,也必须执行刚才介绍的一系列操作。  

原位地址:http://www.cnblogs.com/zchajax/archive/2011/04/27/2030709.html

Android扫描SD卡中的文件的更多相关文章

  1. android 往sd卡中写入文件

    在调用前需要判断是否有写入权限 Environment类提供了比较丰富的方法 static File getDataDirectory() 获得android data的目录. static File ...

  2. Android 5.1.1在外置SD卡中创建文件夹

    Android 4.4之后WRITE_MEDIA_STORAGE 权限仅提供给系统应用,不再授予第三方App,WRITE_EXTERNAL_STORAGE 权限,仅仅用于授权用户写 primary e ...

  3. 【记录】尝试用android-logging-log4j去实现log输出内容到sd卡中的文件的功能

    [背景] 折腾: [记录]给Android中添加log日志输出到文件 期间,已经试了: [记录]尝试用android中microlog4android实现log输出到文件的功能 但是不好用. 然后就是 ...

  4. 与众不同 windows phone (37) - 8.0 文件系统: StorageFolder, StorageFile, 通过 Uri 引用文件, 获取 SD 卡中的文件

    [源码下载] 与众不同 windows phone (37) - 8.0 文件系统: StorageFolder, StorageFile, 通过 Uri 引用文件, 获取 SD 卡中的文件 作者:w ...

  5. android 读取sd卡中的图片

    一.获取读取SD卡的权限 <!--在SDCard中创建与删除文件权限  -->    <uses-permission android:name="android.perm ...

  6. Android获取SD卡中选中图片的路径(URL)

    最近在做一个图片上传的功能,需要提供上传图片在SD卡中的路径,在网上看了些例子,改改调试成功,代码很简单.其布局文件如下: [html]  view plain copy   <?xml ver ...

  7. android手机SD卡中的android_secure目录

    .android_secure 是官方app2sd的产物,删了之后装到sd卡中的软件就无法使用了.里面有非常多.asec的文件,都是装到SD卡上的软件,可是一般装到sd卡中的程序被卸载了.androi ...

  8. android 操作SD卡上的文件

    (1)说明:操作SD卡上的文件须要增加下面权限  在SD卡上创建和删除文件权限  <uses-permission android:name="android.permission.M ...

  9. 往SD卡中写文件的方法。

    package com.lixu.writetosd; import java.io.File; import java.io.FileOutputStream; import java.io.IOE ...

随机推荐

  1. Linux系统学习笔记:文件I/O

    Linux支持C语言中的标准I/O函数,同时它还提供了一套SUS标准的I/O库函数.和标准I/O不同,UNIX的I/O函数是不带缓冲的,即每个读写都调用内核中的一个系统调用.本篇总结UNIX的I/O并 ...

  2. OpenCV配置(Java)

    配置环境:MyEclipse2013+Jdk1.7(32位)+OpenCV 2.4.8+win8.1(64位) OpenCV安装路径:d:\Users\opencv为例 1.       导入Jar包 ...

  3. js数组的操作<转>

    转自 http://blog.csdn.net/xcxinghai/article/details/13502583 PS(个人理解): 1) 数组项的数据类型可以是混合多样的,同时可以含string ...

  4. MySQL表结构同步工具 mysql-schema-sync

    mysql-schema-sync 是一款使用go开发的.跨平台的.绿色无依赖的 MySQL 表结构自动同步工具.用于将线上(其他环境)数据库结构变化同步到测试(本地)环境! 可以解决多人开发,每人都 ...

  5. Android开发:自定义GridView/ListView数据源

    http://mobile.51cto.com/android-259861.htm 在开发中,我们常常会遇到比较复杂的GridView/ListView的布局,重新实现BaseAdapter不但能帮 ...

  6. Android 使用PopupWindow实现弹出菜单

    在本文当中,我将会与大家分享一个封装了PopupWindow实现弹出菜单的类,并说明它的实现与使用. 因对界面的需求,android原生的弹出菜单已不能满足我们的需求,自定义菜单成了我们的唯一选择,在 ...

  7. 【Lucene】挖掘相关搜索词

    搜索引擎中往往有一个可选的搜索词的列表,当搜索结果太少时,可以帮助用户扩展搜索内容,或者搜索结果太多的时候可以帮助用户深入定向搜索.一种方法是从搜索日志中挖掘字面相似的词作为相关搜索词列表.另一种方法 ...

  8. discuz方法赏析

    public static function limit($start, $limit = 0) { $limit = intval($limit > 0 ? $limit : 0); $sta ...

  9. 标头“Vary:Accept-Encoding”指定方法及其重要性分析

    原文地址:http://www.webkaka.com/blog/archives/how-to-set-Vary-Accept-Encoding-header.html 在webkaka的网站速度诊 ...

  10. 04737_C++程序设计_第2章_从结构到类的演变

    例2.1 使用成员函数的实例. #define _SCL_SECURE_NO_WARNINGS #include <iostream> using namespace std; struc ...