Android 扫描SD卡内所有MP3(音频)文件

摘要:
android.供应商.联系人.合同.联系人。CONTENT_ URI在Android机器中,系统将根据SD卡中的所有当前MP3文件定期更新(创建)音频文件信息数据库。它不在SD卡中。根计算机可以通过R.E.Manager查看相关数据库。

    这段时间一个MP3小项目,其中有一个功能就是扫描SD卡内所有MP3文件。

在这儿我首先就想到了一个方法:遍历SD卡内所有目录或文件

1.遍历SD卡内所有目录或文件

Android 扫描SD卡内所有MP3(音频)文件第1张Android 扫描SD卡内所有MP3(音频)文件第2张
package com.wenhao.test.sddemo;

import java.io.File;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainDemo extends Activity {
    /** Called when the activity is first created. */
    
    private Button button = null;
    private File path;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
           
        button = (Button)findViewById(R.id.mybutton);
        
        //检测SD卡是否存在
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            path = Environment.getExternalStorageDirectory();
        }else{
            Toast.makeText(this, "没有SD卡", Toast.LENGTH_LONG).show();
            finish();
        }
        
        button.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub                                
                getAllFiles(path);
            }
        });
        
    }
    
    // 遍历接收一个文件路径,然后把文件子目录中的所有文件遍历并输出来 
    private void getAllFiles(File root){  
        File files[] = root.listFiles();  
        if(files != null){  
            for (File f : files){  
                if(f.isDirectory()){  
                    getAllFiles(f);  
                }else{  
                    System.out.println(f);  
                }  
            }  
        }  
    }  
      
}
View Code

但是这样做,我们先扫描所有文件或目录,然后将其加入到我们自己的数据库里。由于遍历全部文件或目录效率很低,所以这种方法不可取,这里只是顺带提及一下这个可行的方法。

2.利用Android系统自建数据库

上一篇文章里我们用到Android系统自建的数据库,使用ContentProvider提供联系人数据。

android.provider.ContactsContract.Contacts.CONTENT_URI

在Android机中,系统会根据SD卡内的目前所有MP3文件,定时更新(新建)音频文件信息数据库。这个数据在哪儿呢?

并不在SD卡里,root后的机器通过R.E.管理器就可以看到相关数据库了。

/data/data/com.android.providers.media/databases/external.db

我的手机(魅族MX2)external.db里面的表

Android 扫描SD卡内所有MP3(音频)文件第3张

Android 扫描SD卡内所有MP3(音频)文件第4张

 将external.db用工具打开,

Android 扫描SD卡内所有MP3(音频)文件第5张

 红色框就是音频文件的相关属性,一般能包含音频文件的大部分属性,若其中没有包含你要的属性,你可以自建数据库。否则,你可以利用此数据库,可以减少一部分代码。

 由于我的音频属性中包含自带数据库中没有的属性,如:path,folder,format,channels,kbps,hz属性。

因此我选则了自建数据库。

下面是一段利用自带数据库获取SD卡内所有音频文件的路径代码:

Android 扫描SD卡内所有MP3(音频)文件第6张Android 扫描SD卡内所有MP3(音频)文件第7张
    /**
     * 获取SD卡内所有音频文件的路径
     * 有多少条记录,List就有多大
     * @return
     *         ScanInfo类型的表
     */
    public List<ScanInfo> searchAllDirectory() {
        List<ScanInfo> list = new ArrayList<ScanInfo>();
        StringBuffer sb = new StringBuffer();//存放data的缓存
        //要返回的列(属性)
        String[] projection = { MediaStore.Audio.Media.DISPLAY_NAME,MediaStore.Audio.Media.DATA };
        /*
         * 参数:
         * uri 提供内容的地址
         * projection 查询要返回的列
         * selection 查询where字句
         * selectionArgs 查询条件属性值
         * sortOrder 结果排序规则
         */
        Cursor cr = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, null,null, MediaStore.Audio.Media.DISPLAY_NAME);
        String displayName = null;
        String data = null;
        while (cr.moveToNext()) {//移动到下一刻度,返回boolean类型值
            displayName = cr.getString(cr.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));//音频文件名
            data = cr.getString(cr.getColumnIndex(MediaStore.Audio.Media.DATA));//音频文件路径+文件名
            if(data!=null&&displayName!=null){
                data = data.replace(displayName, " ");// 替换文件名留下它的上一级目录
            }
            
            if (!sb.toString().contains(data)) {
                list.add(new ScanInfo(data, true));//默认全部勾选
                sb.append(data);//加入到缓存里
            }
        }
        cr.close();//关闭游标
        return list;
    }
View Code

如果是获取音频文件其他属性也可类似用此方法。

好了,最后一个问题<当你往sd卡中添加一些音频文件的时候,android没有自动及时将它刷新到数据库中。那么我们怎么让它手动刷新呢,如下:
Android 扫描SD卡内所有MP3(音频)文件第8张Android 扫描SD卡内所有MP3(音频)文件第9张
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED); 
        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); 
        intentFilter.addDataScheme("file"); 
        scanReceiver = new ScanSdFilesReceiver(); 
        registerReceiver(scanReceiver, intentFilter); 
        sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); 
  
  
private class ScanSdFilesReceiver extends BroadcastReceiver { 
        public void onReceive(Context context, Intent intent) { 
            String action = intent.getAction(); 
            if (Intent.ACTION_MEDIA_SCANNER_STARTED.equals(action)) { 
                scanHandler.sendEmptyMessage(STARTED); 
            } 
            if (Intent.ACTION_MEDIA_SCANNER_FINISHED.equals(action)) { 
                scanHandler.sendEmptyMessage(FINISHED); 
            } 
        } 
    } 
  
  
private Handler scanHandler = new Handler() { 
        public void handleMessage(Message msg) { 
            super.handleMessage(msg); 
            switch (msg.what) { 
            case STARTED: 
                MyDialog scanDialog = new MyDialog(LocalList.this); 
                scanAlertDialog = scanDialog.scanFile(); 
                scanAlertDialog.show(); 
                Log.i(TAG, "showing"); 
                break; 
            case FINISHED: 
                ArrayList<Song> tempSongs = ReadFileList.readDataFromSD(LocalList.this, LOCAL); 
                if (tempSongs != null && tempSongs.size()>0) { 
                    if (songs != null && songs.size()>0) { 
                        songs.clear(); 
                        songs.addAll(tempSongs); 
                        songAdapter.notifyDataSetChanged(); 
                    }else { 
                        songs = new ArrayList<Song>(); 
                        songs.addAll(tempSongs); 
                        initSong_lv(); 
                    } 
                }else { 
                    Toast.makeText(LocalList.this, "SD卡中没有歌曲,请添加后再扫描", Toast.LENGTH_SHORT).show(); 
                } 
                Log.i(TAG, "finish"); 
                if (scanAlertDialog!=null && scanAlertDialog.isShowing()) { 
                    scanAlertDialog.dismiss(); 
                } 
                unregisterReceiver(scanReceiver); 
                break; 
            case DISMISS: 
                Log.i(TAG, "dismiss"); 
                if (scanAlertDialog!=null && scanAlertDialog.isShowing()) { 
                    scanAlertDialog.dismiss(); 
                } 
            default: 
                break; 
            } 
View Code

对于其他类型的文件,只要com.android.providers中有这种文件信息数据库,扫描SD卡内所有这种类型文件也可以同样这么做。

免责声明:文章转载自《Android 扫描SD卡内所有MP3(音频)文件》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇express 的安全中间件 helmet 简介echarts 加单位 加数字单位下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python(八):python使用lmdb数据库

一、入门代码 LMDB的全称是Lightning Memory-Mapped Database(快如闪电的内存映射数据库),它的文件结构简单,包含一个数据文件和一个锁文件: LMDB文件可以同时由多个进程打开,具有极高的数据存取速度,访问简单,不需要运行单独的数据库管理进程,只要在访问数据的代码里引用LMDB库,访问时给文件路径即可。 让系统访问大量小文...

FoxPro 数据库文件及记录命令

ADDTABLE 在当前数据库中添加一个自由表 APPEND 在表的末尾添加一个或多个新记录 APPEND FROM ARRAY 由数组添加记录到表中 APPEND FROM 从一个文件中读入记录,追加到当前表的尾部 APPEND GENERAL 从文件中导入OLE对象并将其放入通用字段中 APPEND MEMO 将文本文件的内容复制到备注字段中 APPE...

Oracle数据库导入导出总结(dmp文件)

Oracle 10G 管理页面(Oracle Enterprise Manager 10g): http://localhost:1158/emhttp://localhost:1158/em/console/logon/logon Oracle数据库导出:   (1)整个用户下的所有数据(dmp文件):    《导出》          exp 用户...

如何减小MS SQL Server的Log文件尺寸

对于MS SQL Server 2005以及MS SQL Server 2000来说,可以这样做 首先 1: use [数据库名称]; 2: exec sp_helpfile; 利用sp_helpfile查询可知道log 文件的逻辑名称,然后就可以利用DBCC来减小LOG文件 1: BACKUP LOG [数据库名] WITH TRUNCATE_ON...

Oracle数据库三种标准的备份方法

Oracle数据库的三种标准的备份方法: 1.导出/导入(EXP/IMP)。 2.热备份。 3.冷备份。 注释:导出备件是一种逻辑备份,冷备份和热备份是物理备份。 一、导出/导入(Export/Import) 利用Export可将数据从数据库中提取出来,利用Import则可将提取出来的数据送回到Oracle数据库中去。 1、简单导出数据(Export)和导...

Weblogic12c 单节点安装

第一节weblogic12c 的安装 WebLogic除了包括WebLogic Server服务器之外,还包括一些围绕WebLogic的产品,习惯上我们说的WebLogic是指WebLogic Server。WebLogic是美国bea公司出品的一个application server确切的说是一个基于Javaee架构的中间件,BEA WebLogi...