更新记录

1.0.4(2024-03-23)

解决下载部分链接时app卡死问题

1.0.3(2024-03-02)

更新许可协议

1.0.2(2024-02-28)

解决部分bug
支持headers请求头设置,支持安卓、iOS
修改示例错误

查看更多

平台兼容性

Android Android CPU类型 iOS
适用版本区间:4.4 - 14.0 armeabi-v7a:支持,arm64-v8a:支持,x86:未测试 适用版本区间:11 - 17

原生插件通用使用流程:

  1. 购买插件,选择该插件绑定的项目。
  2. 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
  3. 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
  4. 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
  5. 开发完毕后正式云打包

付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios

注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择


该插件仅用于解决uni.downloadFile后台下载中断问题

如遇问题请提供详细信息如系统版本和型号、复现步骤、代码片段等

由于安卓11开始,限制了sd卡读写权限,导致下载到类似/storage/emulated/0/xxx目录时会报错,这个问题必须添加相关权限且动态调用后用户同意才能解决,参考链接:https://ask.dcloud.net.cn/article/40626 ,插件去除了原有的READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE权限申请,需要自行控制

导入插件

const syczuanReq = uni.requireNativePlugin("syczuan-request");

使用方式

因安卓端支持队列下载而iOS不支持,因此示例对安卓和iOS平台做了判断处理

此插件为原生模块,需要先引入模块,使用参考如下

<template>
  <view class="download_plugin">
    <text @click="getDownloadTasker" class="tool_btn"
      >Tag Count: {{ taskering }}</text
    >
    <view class="tasker_list" v-for="(item, index) of taskerList" :key="index">
      <view
        class="progress"
        :style="{ width: getProgress(item.pro.progress, 750) }"
      >
      </view>
      <text class="progress_text" v-if="item.pro.progress > 0">
        {{ item.pro.progress }}%
      </text>
      <view class="left">
        <text class="title">{{ item.fileName }}</text>
      </view>
      <view class="right">
        <text class="right_text" @click="startDownload(item, index)">下载</text>
        <text class="right_text" @click="cancelDownloadTag(item.tag, index)">
          取消
        </text>
      </view>
    </view>
    <view class="button_list">
      <view class="progress" :style="progressW"></view>
      <text class="btn cancel_btn" @click="cancelDownloadAll">CancelAll</text>
      <text class="btn download_btn" @click="startAll">DownloadAll</text>
    </view>
  </view>
</template>
<script>
const syczuanReq = uni.requireNativePlugin("syczuan-request");
export default {
  data() {
    return {
      link: "下载地址",
      // 初始化配置
      initConfig: {
        // 最大并行任务数
        maxTasker: 5,
        // 开启阻塞下载
        obstruct: false,
      },
      // 下载任务队列
      taskerList: [],
      // 下载任务数
      taskering: 0,
    };
  },
  async onLoad() {
    if (this.isIOS) {
      this.initConfig.maxTasker = 1;
    } else {
      syczuanReq.init(this.initConfig);
    }

    let filePath = await getPrivateFolder("test");
    for (let i = 0; i < this.initConfig.maxTasker; i++) {
      const parameter = {
        url: this.link,
        fileName: `test-doc${i}.pdf`,
        filePath: filePath,
        tag: `tag${i}`,
        // 设置请求头
        headers: {
          // Referer: "",
        },
        pro: {},
        result: {},
      };
      this.taskerList.push(parameter);
    }
  },
  onUnload() {
    this.cancelDownloadAll();
  },
  methods: {
    // 开始下载全部
    startAll() {
      if (this.getDownloadTasker().length) {
        this.cancelDownloadAll();
      }
      for (let i = 0; i < this.taskerList.length; i++) {
        let tasker = this.taskerList[i];
        this.$set(this.taskerList, i, {
          ...tasker,
        });
        syczuanReq.startDownload(
          tasker,
          (e) => {
            this.taskerList[i].pro = e;
          },
          (res) => {
            this.taskerList[i].result = res;
          }
        );
      }
    },

    // 开始下载
    startDownload(parameter, index) {
      syczuanReq.startDownload(
        parameter,
        (e) => {
          this.taskerList[index].pro = e;
        },
        (res) => {
          this.taskerList[index].result = res;
        }
      );
    },
    // 取消默认下载
    cancelDownload() {
      syczuanReq.cancelDownload();
    },
    // 取消指定tag的下载
    cancelDownloadTag(tag, index) {
      if (this.isIOS) {
        return this.cancelDownload();
      }
      syczuanReq.cancelDownloadTag(tag);
      // 重置下载进度
      this.taskerList[index].pro = {};
    },
    // 取消所有下载
    cancelDownloadAll() {
      if (this.isIOS) {
        return this.cancelDownload();
      }
      syczuanReq.cancelDownloadAll();
      // 重置下载进度
      this.taskerList = this.taskerList.map((e) => {
        e.pro = {};
        return e;
      });
    },
    // 获取当前下载tag
    getDownloadTasker() {
      if (this.isIOS) {
        return [];
      }
      const list = syczuanReq.getDownloadTasker();
      this.taskering = list.length;
      console.log(list);
      return list;
    },
    // 获取下载进度条px
    getProgress(progress, num) {
      const toPX = (progress / 100) * uni.$u.getPx(`${num}rpx`);
      return toPX + "px";
    },
  },
  computed: {
    isIOS() {
      return uni.getSystemInfoSync().platform === "ios";
    },
  },
};
</script>

<style scoped>
.download_plugin {
  width: 750rpx;
  display: flex;
  align-items: center;
  margin-bottom: 80px;
}

.button_list {
  width: 680rpx;
  padding: 0px 40rpx;
  background-color: #ffffff;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-direction: row;
  position: fixed;
  left: 35rpx;
  bottom: 10px;
  box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.2);
}

.button_list .btn {
  width: 300rpx;
  font-size: 16px;
  text-align: center;
  line-height: 50px;
  height: 50px;
  border-radius: 4px;
  font-weight: bold;
}

.button_list .download_btn {
  color: #0075ec;
}

.button_list .cancel_btn {
  color: #b43609;
}

.tool_btn {
  padding: 10px 30rpx;
  background-color: #0075ec;
  border-radius: 4px;
  color: #ffffff;
  font-size: 14px;
  margin-right: 20rpx;
  margin-bottom: 10px;
}

.tasker_list {
  width: 750rpx;
  padding: 0px 30rpx;
  height: 100px;
  position: relative;
  border-bottom: 1px solid #dddddd;
  display: flex;
  align-items: center;
  flex-direction: row;
  justify-content: space-between;
}

.tasker_list .progress {
  position: absolute;
  bottom: 0px;
  left: 0pxpx;
  background-color: rgba(30, 118, 218, 0.608);
  height: 100px;
}

.tasker_list .progress_text {
  position: absolute;
  color: #979797;
  font-size: 12px;
  bottom: 5px;
  right: 50rpx;
}

.tasker_list .left .title {
  font-size: 16px;
  color: #00081c;
}
.tasker_list .right {
  display: flex;
  align-items: center;
  flex-direction: row;
}
.tasker_list .right .right_text {
  font-size: 14px;
  color: #00081c;
  margin-right: 20rpx;
  padding: 10px 30rpx;
  background-color: #dddddd;
}
</style>

初始化下载(仅安卓)

syczuanReq.init(Object)

Object参数说明

参数 类型 必填 说明
maxTasker Number 下载最大并行数,默认 1
obstruct Boolean 阻塞下载,true:请求下载的tag已存在当前下载队列时阻止重复下载 false:请求下载的tag已存在当前下载队列时重新下载

开始下载

syczuanReq.startDownload(Object,CallProgress,CallResult)

Object参数说明

参数 类型 必填 说明
url String 下载链接
fileName String 完整文件名(包括文件后缀)
filePath String 需存储文件的路径
tag String (仅安卓)下载任务对应的tag,用于取消、重新下载等,默认: default
headers Object 设置请求头

CallProgress返回参数说明

参数 类型 说明
progress Number 当前下载进度,0-100
size Number 文件原始字节数(Byte)
current Number 当前已下载字节数(Byte)

CallResult返回参数说明

参数 类型 说明
status Number 请求状态码 200: 请求成功 400: 请求失败
data String|Object 请求数据 status:200=> data.filePath:文件路径 size:文件大小(Byte) fileName:文件名 tag:(仅安卓)下载任务tag status:400 => 空字符串
msg String status:200=> msg:success status:400=> msg:报错信息

通过tag取消下载(仅安卓)

syczuanReq.cancelDownloadTag(tag)

取消默认tag下载

安卓下 仅未指定下载tag时调用,类似于syczuanReq.cancelDownloadTag("default")

syczuanReq.cancelDownload()

取消所有下载(仅安卓)

syczuanReq.cancelDownloadAll()

获取正处于下载队列的tag列表(仅安卓)

syczuanReq.getDownloadTasker()

隐私、权限声明

1. 本插件需要申请的系统权限列表:

网络请求权限

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT License

Copyright (c) 2024 syczuan

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问