美文网首页
Android 获取本机的Office文件

Android 获取本机的Office文件

作者: 晓风残月酒醒 | 来源:发表于2019-09-27 17:10 被阅读0次

    前面的那些我就不一一复述了,默认各位看官都是基础相当扎实的人,前段时间要求在本地获取到Office相关文件执行上传操作,但是采用mime_type的形式执行数据库查找的时候却一直在小米手机上搜索不到docx、pptx、xlsx这类文件,纵使添加了所有的mime_type也不起作用,这个时候就需要兵行险着,来点邪的了

    /**
     * 文档选择的bean对象
     */
    public class ChooseDocumentBean {
        private String displayName;                     // 展示的名称
        private String path;                            // 文件路径
        private String title;                           // 文件的标题
        private String dateAdded;                       // 文件的添加日期(从1970年开始,取出来的单位是秒)
        private String dateModified;                    // 文件的修改日期(从1970年开始,取出来的单位是秒)
        private String size;                            // 文件的存储容量
    
        private DocumentType fileType;                  // 文件的类型
        private int position;                           // 本文件在列表中的位置
    
        /**
         * 下面是这一堆私有成员变量的get和set方法,这里就不写了
         */
    }
    

    首先是单个的文档Bean对象,这里需要获取到文件的类型,最终都会在分线程中一一设置上去

    /**
     * 文件类型的标识类
     * 注意,后缀名的添加与最终搜索结果有直接的对应关系
     */
    public enum DocumentType {
        // 文本文件
        txt("txt"),
        // pdf文件
        pdf("pdf"),
        // doc文件
        doc("doc", "dot", "docx", "dotx", "docm", "dotm"),
        // ppt文件
        ppt("ppt", "pot", "pps", "ppa", "pptx", "ppsx", "potx", "ppam", "pptm", "potm", "ppsm"),
        // excel文件
        xls("xls", "xlt", "xla", "xlsx", "xltx", "xlsm", "xltm", "xlam", "xlsb");
    
        private String[] suffixArray;            // 文件后缀名
    
        DocumentType(String... suffix) {
            this.suffixArray = suffix;
        }
    
        public String[] getSuffix() {
            return suffixArray;
        }
    
        // 根据后缀名获取到对应的文件类型
        public static DocumentType getBySuffix(String suffix) {
            if (OffcnDataUtil.isEmpty(suffix)) return null;
            DocumentType fileType = null;
            // 统一采用小写字母执行操作
            switch (suffix.toLowerCase()) {
                case "txt":
                    fileType = txt;
                    break;
                case "pdf":
                    fileType = pdf;
                    break;
                case "doc":
                case "dot":
                case "docx":
                case "dotx":
                case "docm":
                case "dotm":
                    fileType = doc;
                    break;
                case "ppt":
                case "pot":
                case "pps":
                case "ppa":
                case "pptx":
                case "ppsx":
                case "potx":
                case "ppam":
                case "pptm":
                case "potm":
                case "ppsm":
                    fileType = ppt;
                    break;
                case "xls":
                case "xlt":
                case "xla":
                case "xlsx":
                case "xltx":
                case "xlsm":
                case "xltm":
                case "xlam":
                case "xlsb":
                    fileType = xls;
                    break;
            }
            return fileType;
        }
    }
    

    根据后缀名匹配到文档的类型,用于不同种类的文档获取,当然也可能有一些是多余的

    /**
     * 执行按照文档类型和关键字执行查找文档的方法
     * @param context               上下文对象
     * @param loadingCallBack       展示和隐藏loading的回调
     * @param fileTypeList          文档类型
     * @param keyword               文档名称关键字
     * @param resultCallBack        查询完毕的回调
     */
    public static void searchDocumentListByType(Context context, BaseLoadingCallBack loadingCallBack, List<DocumentType> fileTypeList, String keyword, AsyncTaskCallBack<List<ChooseDocumentBean>> resultCallBack) {
        if (context == null || fileTypeList == null || fileTypeList.size() == 0) {
            if (resultCallBack != null) {
                resultCallBack.onFailed("文档查询失败");
            }
            return;
        }
        if (loadingCallBack != null) {
            loadingCallBack.showLoading("文档查询中...", false);
        }
        Observable.create(new Observable.OnSubscribe<List<ChooseDocumentBean>>() {
            @Override
            public void call(Subscriber<? super List<ChooseDocumentBean>> subscriber) {
                List<ChooseDocumentBean> fileList = null;
                ContentResolver resolver = context.getContentResolver();
                Uri uri = MediaStore.Files.getContentUri("external");
                // 开始构建查询条件
                StringBuilder selectionBuilder = new StringBuilder("");
                // 判定搜索关键字为空
                boolean keyWordsEmpty = OffcnDataUtil.isEmpty(keyword);
                if (!keyWordsEmpty) {
                    selectionBuilder.append(MediaStore.Files.FileColumns.TITLE).append(" like '%").append(keyword).append("%'");
                    selectionBuilder.append(" and ( ");
                }
                // 追加文档类型的判定
                DocumentType fileType = null;
                for (int i = 0; i < fileTypeList.size(); i++) {
                    fileType = fileTypeList.get(i);
                    // 根据后缀名执行匹配操作
                    String[] suffix = fileType.getSuffix();
                    for (int j = 0; j < suffix.length; j++) {
                        // 除了第一种文档的第一个子类型,其余的都要加上“或”这个词
                        if (i != 0 || j != 0) {
                            selectionBuilder.append(" or ");
                        }
                        selectionBuilder.append(MediaStore.Files.FileColumns.DATA).append(" like '%.").append(suffix[j]).append("'");
                    }
                    // 如果关键字不为空,那么最后一个文档类型添加完毕之后,要加上小括号
                    if (!keyWordsEmpty && (i == fileTypeList.size() - 1)) {
                        selectionBuilder.append(" ) ");
                    }
                }
                Cursor cursor = resolver.query(uri, new String[]{MediaStore.Files.FileColumns.DATA, MediaStore.Files.FileColumns.TITLE, MediaStore.Files.FileColumns.DATE_ADDED, MediaStore.Files.FileColumns.DATE_MODIFIED, MediaStore.Files.FileColumns.SIZE}, selectionBuilder.toString(), null, MediaStore.Files.FileColumns.DATE_MODIFIED + " desc");
                if (cursor != null) {
                    fileList = new ArrayList<>(cursor.getCount());
                    while (cursor.moveToNext()) {
                        ChooseDocumentBean bean = new ChooseDocumentBean();
                        String path = cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA));
                        bean.setPath(path);
                        bean.setDisplayName(path.substring(path.lastIndexOf("/") + 1)); // cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.DISPLAY_NAME))
                        bean.setTitle(cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.TITLE)));
                        bean.setDateAdded(OffcnDateUtil.change2Md(cursor.getLong(cursor.getColumnIndex(MediaStore.Files.FileColumns.DATE_ADDED))));
                        bean.setDateModified(OffcnDateUtil.change2Md(cursor.getLong(cursor.getColumnIndex(MediaStore.Files.FileColumns.DATE_MODIFIED))));
                        bean.setSize(CacheCleanUtil.getFormatSize(cursor.getLong(cursor.getColumnIndex(MediaStore.Files.FileColumns.SIZE))));
                        bean.setPosition(fileList.size());
    
                        String fileName = bean.getDisplayName();
                        if (!OffcnDataUtil.isEmpty(fileName)) {
                            bean.setFileType(DocumentType.getBySuffix(fileName.substring(fileName.lastIndexOf(".") + 1)));
                        }
                        fileList.add(bean);
                    }
                    cursor.close();
                }
                subscriber.onNext(fileList);
                subscriber.onCompleted();
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<List<ChooseDocumentBean>>() {
            @Override
            public void onCompleted() {
                if (loadingCallBack != null) {
                    loadingCallBack.hidLoading();
                }
            }
    
            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
                if (resultCallBack != null) resultCallBack.onFailed(e.getMessage());
            }
    
            @Override
            public void onNext(List<ChooseDocumentBean> result) {
                if (resultCallBack != null) {
                    resultCallBack.onSuccess(result);
                }
            }
        });
    }
    

    查找文件这里采用的是Rxjava1.0的异步执行方案,搜索过程中采用的是文件的后缀名的匹配形式,放弃了mime_type的匹配操作,这样查找执行的操作会更慢一些(建议用loading阻断一下),但是结果更加准确,规避掉了部分机型上mime_type匹配隐藏的失败问题

    相关文章

      网友评论

          本文标题:Android 获取本机的Office文件

          本文链接:https://www.haomeiwen.com/subject/fgdauctx.html