uni小程序, 嵌入原生app, 文件下载到指定目录的实现方式

uni小程序, 嵌入原生app, 文件下载到指定目录的实现方式

  • 实现该功能的时候, 两个问题需要解决, 1.uni.openDocument,只能打开几个常规后缀的文件 2. 下载文件下到了沙盒里面. _download开头的内部路径, 用户下次找不到了
    为解决这两个问题, 我也是做了很多尝试, 现在将最终实现方式记录分享, 希望对你有些帮助
  1. 使用 plus.runtime.openFile 打开文件, 没有文件格式限制, 遇到打不开的文件时, 会有异常回调可以使用, 提示用户安装相关软件即可.
  2. 利用plus.downloader.createDownload 下载文件文档上说明只能保存到_dowloads, _doc,等几个固定开头的沙盒文件夹里, 所以只能扩展原生Moudle, 将文件移动到Download文件夹下

一下是代码部分,仅供参考

  • 原生部分代码, 自定义Module,复制文件,一定要提前获取到用户的读写数据的权限!!!, 否则会提示权限问题, 文件无法复制
public class UniUesOaHeModule extends UniModule {

    /**
     * 输出日志
     */
    @UniJSMethod(uiThread = false)
    public void uniLog(String s) {
        XLog.debug(s);
    }

    /**
     * 沙盒文件移入媒体库
     */
    @UniJSMethod(uiThread = false)
    public void scanIntoMedia(String filePath, UniJSCallback callback) {
        if (StringUtil.isEmpty(filePath)) {
            if (callback != null) {
                JSONObject data = new JSONObject();
                data.put("code", "error");
                data.put("message", "文件路径不能为空");
                callback.invokeAndKeepAlive(data);
            }
        }
        if (mUniSDKInstance != null) {
            String[] split = filePath.split("/");
            String fileName = split[split.length -1];
            String targetPath = "/storage/emulated/0/Download/" + fileName;

            FileUtil fileUtil = FileUtil.INSTANCE;
            XLog.debug("开始转义目录");
            XLog.debug("由:[ " + filePath + " ] 转移至 : [ "+ targetPath + " ]");
            //tod
            fileUtil.copyFileWithFileChannel(new File(filePath), new File(targetPath));

            //对于小米来说, 拷贝到Downloads文件夹下, 系统就会自动扫描到了, 不知道其他机型怎么样
            //图片等常规文件,能出现在 `最近`里, dwg在Download里能找到, 但是不会在 `最近` 里显示,可能是系统原因
            Context context = mUniSDKInstance.getContext();
            Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            Uri contentUri = Uri.parse(targetPath);
            XLog.debug("将要扫描的地址是: " + contentUri.getPath());
            mediaScanIntent.setData(contentUri);
            context.sendBroadcast(mediaScanIntent);
            XLog.debug("发送扫描指令");
            if (callback != null) {
                JSONObject data = new JSONObject();
                data.put("code", "success");
                data.put("message", "添加到Download目录成功");
                data.put("filePathAfterMove", "file:/"+ targetPath);
                callback.invokeAndKeepAlive(data);
            }
        }else{
            XLog.debug("实例不存在");
            if (callback != null) {
                JSONObject data = new JSONObject();
                data.put("code", "error");
                data.put("message", "实例不存在");
                callback.invokeAndKeepAlive(data);
            }
        }

        /**
         * 下面的不管用, 可能是只能扫描固定的几个媒体库路径, 上面的直接复制到Downloads下, 不用扫描都能发现
         */
//
//        if (StringUtil.isEmpty(filePath)) {
//            if (callback != null) {
//                JSONObject data = new JSONObject();
//                data.put("code", "error");
//                data.put("message", "文件路径不能为空");
//                callback.invokeAndKeepAlive(data);
//            }
//        }
//        if (mUniSDKInstance != null) {
//            Context context = mUniSDKInstance.getContext();
//            try {
//                MediaScannerConnection.scanFile(context, new String[]{filePath}, null,
//                        new MediaScannerConnection.OnScanCompletedListener() {
//                            public void onScanCompleted(String path, Uri uri) {
//                                XLog.debug("扫描的路径是: " + path + ":");
//                                XLog.debug("返回的uri: " + uri);
//                                if (callback != null) {
//                                    JSONObject data = new JSONObject();
//                                    data.put("code", "success");
//                                    data.put("message", "媒体库扫描完成!!!!");
//                                    callback.invokeAndKeepAlive(data);
//                                }
//                            }
//                        });
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        } else {
//            if (callback != null) {
//                JSONObject data = new JSONObject();
//                data.put("code", "error");
//                data.put("message", "移入媒体库失败, 找不到mUniSDKInstance实例");
//                callback.invokeAndKeepAlive(data);
//            }
//        }
    }

}
  • FileUtil, 只贴这一个复制文件的函数
/**
     * 复制文件
     */
    fun copyFileWithFileChannel(fileSource: File, fileDest:File) {
        var fi: FileInputStream? = null
        var fo: FileOutputStream? = null
        var `in`: FileChannel? = null
        var out: FileChannel? = null
        try {
            fi = FileInputStream(fileSource)
            fo = FileOutputStream(fileDest)
            `in` = fi.channel//得到对应的文件通道
            out = fo.channel//得到对应的文件通道
            `in`!!.transferTo(0, `in`.size(), out)//连接两个通道,并且从in通道读取,然后写入out通道
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            try {
                fi!!.close()
                `in`!!.close()
                fo!!.close()
                out!!.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }

别忘记注册组件
UniSDKEngine.registerModule(“UniUesOaHeModule”, UniUesOaHeModule::class.java)

uni小程序代码, download2是最终使用的方法, 其他的是测试时使用的







你可能感兴趣的:(工作笔记,小程序,前端,java,uni小程序)