Android 本地文件查找问题

想要将Android手机中的某个类型的文件查找出来,罗列出来,比如doc的word文件,可是使用遍历查找的方法实在是太慢了,我用了17秒才能将某个类型的文件遍历完,这样太慢了,请问如何才能快速的找出来。我的目的是为了实现文件上传功能的文件选择,如果调用文件管理器的话,有时候有些文件很难找到,所以想将某个类型的文件展示在listview给用户查看,供用户选择。求大神给出主意,如何实才能更好更快的让用户把需要上传的文件选择上

阅读 7.3k
2 个回答

全盘检索

Gradle:

dependencies {
    compile 'commons-io:commons-io:2.4'
}
private static void listFiles(){
        File sdRoot = new File(Environment.getExternalStorageDirectory() + "/");
        Collection<File> collection = FileUtils.listFiles(sdRoot, new String[]{"png"}, true);
        for (File item : collection) {
            Log.d("Name: ",item.getName()+"");
            Log.d("Path: ", item.getAbsolutePath() + "");
        }
    }

检索我个人的手机目录png文件,一共3772个 ,耗时8.7秒。

---------跑---马---灯---------

这样全盘检索显然不符合使用习惯。
我们只需要检索有意义的某些目录。
这里你可以自定义需要检索的目录,或者建立过滤器过滤系统目录和常用软件的缓存目录,来大幅提高检索效率。


2015年12月7日补充。

很抱歉最近较忙,没来回复。
你如果是只要doc格式的word格式,可以使用Android的Intent对象来限定MIME类型,非指定类型无法选择。
同时该功能有一个 最近 列表,会自动显示近期新添加的符合定义类型的文件。

类型参考:http://www.w3school.com.cn/media/media_mimeref.asp

事件监听里引用 FilePicker.pickWordFile(context,REQUEST_WORD_CODE);
REQUEST_WORD_CODE 定义一个int型,任意数值均可,用于后续接收判定。

public class FilePicker {

    @TargetApi(Build.VERSION_CODES.KITKAT)
    public static void pickWordFile(Context context, int REQUEST_WORD_CODE) {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("application/msword");       // .doc .dot等word文件
        //intent.setType("application/vnd.ms-excel");       // .xls .xla .xlt 等 Excel 文件
        //intent.setType("image/*");        //所有图片文件
        //intent.setType("image/jpeg");      // jpeg文件,类推。
        ((Activity) context).startActivityForResult(intent, REQUEST_WORD_CODE);
    }

    /**
     * 以下各类文件路径获取
     * */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public static String getPath(final Context context, final Uri uri) {

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
            }
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                return getDataColumn(context, contentUri, null, null);
            }
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }
                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };
                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();
            return getDataColumn(context, uri, null, null);
        }
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }
        return null;
    }

    public static boolean isExternalStorageDocument(Uri uri) {
        Log.d("aauu ","isExternalStorageDocument");
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    public static boolean isDownloadsDocument(Uri uri) {
        Log.d("aauu ","isDownloadsDocument");
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    public static boolean isMediaDocument(Uri uri) {
        Log.d("aauu ","isMediaDocument");
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    public static boolean isGooglePhotosUri(Uri uri) {
        Log.d("aauu ","isGooglePhotosUri");
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }
}

重写onActivityResult用于接收文件选择器选择回来的文件路径

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    
        if(resultCode == RESULT_OK){
            switch (requestCode){
                case REQUEST_WORD_CODE: 
                    Uri uri = data.getData();
                    Log.d("TAG"," Uri : " + uri );
                    String path = FilePicker.getPath(getApplicationContext(), uri);
                    Log.d("TAG"," Path: " + path);
                    //...
                    // 你自己要处理的事件
                    //...
                    break;
                default:
                    break;
            }
        }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题