比起云服务器、云数据库、云存储等等方式将文件存储至云端,网盘的WebDAV协议对新手就友好的多,不仅仅有免部署使用方式简单等等原因,更重要是免费,国内首推坚果云网盘!

三个注意点:

  • 使用第三方库Sardine进行操作
  • 添加网络访问权限
  • 子线程进行云端请求

特别说明:

本文采用分—总结构展示代码(除gradle文件),即先展示局部代码,并说明其用法和作用;小节结尾处再给出该部分对应文件的完整代码布局XML源文件在文末。

一、添加依赖

在gradle(Moudle)中添加第三方库Sardine所需依赖。

// 添加sardine库来使用WebDAV协议
implementation 'com.thegrizzlylabs.sardine-android:sardine-android:0.8'
implementation("com.squareup.okhttp3:okhttp:4.9.0")

二、声明网络权限

<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.demo_webdav">// 额外添加网络权限<uses-permission android:name="android.permission.INTERNET" /><application...</application>
</manifest>

三、创建操作网盘的方法

Sardine操作WebDAV协议的常用方法请参考常用方法一览

3.1初始化连接,返回一个可共用的Sardine对象

// 与坚果云WebDAV服务器建立连接,返回sardine对象以进行操作
fun initSardine(): OkHttpSardine {val sardine = OkHttpSardine()// 此处的账号和第三方密码口令均请填入自己的// 坚果云的账号val userName = "demo_webdav@163.com"// 授权给第三方应用的密码口令val passWord = "aqkgubiy4z55rc6p"// 建立连接sardine.setCredentials(userName, passWord)// 返回sardine对象return sardine
}

在坚果云生成第三方应用密码口令的方式请参考坚果云官方文档

3.2新建文件夹/目录至云端

fun createDir(sardine: OkHttpSardine) {val dirPath = "https://dav.jianguoyun.com/dav/我的坚果云/demo_webdav文件夹"sardine.createDirectory(dirPath)
}

3.3检查云端文件存在性

fun checkExistence(sardine: OkHttpSardine): Boolean {val dirPath = "https://dav.jianguoyun.com/dav/我的坚果云/demo_webdav文件夹"return sardine.exists(dirPath)
}

3.4上传文件至云端:将String变量转换为byte字节数组上传至网盘

fun uploadFile(sardine: OkHttpSardine, fileContent: String) {val filePath = "https://dav.jianguoyun.com/dav/我的坚果云/demo_webdav文件夹/测试文本.txt"// 将变量转变为byte字节数组,以传输到网盘val data = fileContent.toByteArray()sardine.put(filePath, data)
}

3.5下载云端文件方法:以输入流的形式读取,并转换为String变量存储

fun downloadFile(sardine: OkHttpSardine): String {val filePath = "https://dav.jianguoyun.com/dav/我的坚果云/demo_webdav文件夹/测试文本.txt"val download = sardine.get(filePath)// 以输入流的形式读取下载的文件,并转换为字符串val fileContent = BufferedReader(InputStreamReader(download)).useLines { lines ->val results = StringBuilder()lines.forEach {results.append(it)}results.toString()}return fileContent
}

3.6重命名或移动文件(夹)的方法:

fun moveOrRenameFile(sardine: OkHttpSardine) {val oldPath = "https://dav.jianguoyun.com/dav/我的坚果云/demo_webdav文件夹"val newPath = "https://dav.jianguoyun.com/dav/我的坚果云/renamed_or_moved_demo_webdav文件夹"sardine.move(oldPath, newPath)
}

3.7删除云端文件(夹)方法:

fun deleteFile(sardine: OkHttpSardine) {val filePath = "https://dav.jianguoyun.com/dav/我的坚果云/moved_demo_webdav文件夹"sardine.delete(filePath)
}

四、MainActivity中调用

4.1布局预览

4.2绑定视图控件

val show = findViewById<TextView>(R.id.show)
val createButton = findViewById<Button>(R.id.create)
val uploadButton = findViewById<Button>(R.id.upload)
val downloadButton = findViewById<Button>(R.id.download)
val renameButton = findViewById<Button>(R.id.rename)
val deleteButton = findViewById<Button>(R.id.delete)

4.3设置点击事件及真机测试

        注:与网络请求有关的函数,需要放到子线程中进行!

// 启动一个子线程
thread {// 在这内部写真正实现功能的函数
}

1.创建文件夹按钮

createButton.setOnClickListener {// 启动子线程thread {// 连接到坚果云WebDAV服务器,并返回sardine对象val sardine = initSardine()// 文件夹不存在则创建一个if (!checkExistence(sardine)) {createDir(sardine)}}
}


2.上传文件按钮

uploadButton.setOnClickListener {// 启动子线程thread {val sardine = initSardine()uploadFile(sardine, "demo_webdav的测试文本,这将生成为一个txt文本存在WebDAV服务器端")}// Toast一下提醒已上传Toast.makeText(this, "已上传", Toast.LENGTH_SHORT).show()
}


3.下载文件按钮

downloadButton.setOnClickListener {var fileContent = ""// 启动子线程thread {val sardine = initSardine()fileContent = downloadFile(sardine)}.join()  // 阻塞子线程,以取得fileContent的值// 将fileContent的值赋予show文本控件显示出来show.text = fileContent
}


4.(移动)重命名文件夹按钮

renameButton.setOnClickListener {// 启动子线程thread {val sardine = initSardine()moveOrRenameFile(sardine)}// Toast一下提醒已重命名Toast.makeText(this, "已重命名", Toast.LENGTH_SHORT).show()
}


5.删除文件夹按钮

deleteButton.setOnClickListener {// 启动子线程thread {val sardine = initSardine()deleteFile(sardine)}// Toast一下提醒已删除Toast.makeText(this, "已删除", Toast.LENGTH_SHORT).show()
}


         MainActivity完整代码

class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 绑定视图控件val show = findViewById<TextView>(R.id.show)val createButton = findViewById<Button>(R.id.create)val uploadButton = findViewById<Button>(R.id.upload)val downloadButton = findViewById<Button>(R.id.download)val renameButton = findViewById<Button>(R.id.rename)val deleteButton = findViewById<Button>(R.id.delete)// 设置创建文件夹按钮的点击事件createButton.setOnClickListener {// 启动子线程thread {// 连接到坚果云WebDAV服务器,并返回sardine对象val sardine = initSardine()// 文件夹不存在则创建一个if (!checkExistence(sardine)) {createDir(sardine)}}}// 设置上传文件按钮的点击事件uploadButton.setOnClickListener {// 启动子线程thread {val sardine = initSardine()uploadFile(sardine, "demo_webdav的测试文本,这将生成为一个txt文本存在WebDAV服务器端")}// Toast一下提醒已上传Toast.makeText(this, "已上传", Toast.LENGTH_SHORT).show()}// 设置下载文件按钮的点击事件downloadButton.setOnClickListener {var fileContent = ""// 启动子线程thread {val sardine = initSardine()fileContent = downloadFile(sardine)}.join()  // 阻塞子线程,以取得fileContent的值// 将fileContent的值赋予show文本控件显示出来show.text = fileContent}// 设置重命名文件夹按钮的点击事件renameButton.setOnClickListener {// 启动子线程thread {val sardine = initSardine()moveOrRenameFile(sardine)}// Toast一下提醒已重命名Toast.makeText(this, "已重命名", Toast.LENGTH_SHORT).show()}// 设置删除文件夹按钮的点击事件deleteButton.setOnClickListener {// 启动子线程thread {val sardine = initSardine()deleteFile(sardine)}// Toast一下提醒已删除Toast.makeText(this, "已删除", Toast.LENGTH_SHORT).show()}}// 与坚果云WebDAV服务器建立连接,返回sardine对象以进行操作fun initSardine(): OkHttpSardine {val sardine = OkHttpSardine()// 坚果云的账号邮箱val userName = "demo_webdav@163.com"// 授权给第三方应用的密码口令val passWord = "aqkgubiy4z55rc6p"// 建立连接sardine.setCredentials(userName, passWord)// 返回sardine对象return sardine}fun createDir(sardine: OkHttpSardine) {val dirPath = "https://dav.jianguoyun.com/dav/我的坚果云/demo_webdav文件夹"sardine.createDirectory(dirPath)}fun checkExistence(sardine: OkHttpSardine): Boolean {val dirPath = "https://dav.jianguoyun.com/dav/我的坚果云/demo_webdav文件夹"return sardine.exists(dirPath)}fun uploadFile(sardine: OkHttpSardine, fileContent: String) {val filePath = "https://dav.jianguoyun.com/dav/我的坚果云/demo_webdav文件夹/测试文本.txt"// 将变量转变为byte字节数组,以传输到网盘val data = fileContent.toByteArray()sardine.put(filePath, data)}fun downloadFile(sardine: OkHttpSardine): String {val filePath = "https://dav.jianguoyun.com/dav/我的坚果云/demo_webdav文件夹/测试文本.txt"val download = sardine.get(filePath)// 以文件流的形式读取下载的文件,并转换为字符串val fileContent = BufferedReader(InputStreamReader(download)).useLines { lines ->val results = StringBuilder()lines.forEach {results.append(it)}results.toString()}return fileContent}fun moveOrRenameFile(sardine: OkHttpSardine) {val oldPath = "https://dav.jianguoyun.com/dav/我的坚果云/demo_webdav文件夹"val newPath = "https://dav.jianguoyun.com/dav/我的坚果云/renamed_or_moved_demo_webdav文件夹"sardine.move(oldPath, newPath)}fun deleteFile(sardine: OkHttpSardine) {val filePath = "https://dav.jianguoyun.com/dav/我的坚果云/renamed_or_moved_demo_webdav文件夹"sardine.delete(filePath)}
}

        布局XML完整代码

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/show"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.39" /><Buttonandroid:id="@+id/create"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="50dp"android:text="创建文件夹"app:layout_constraintBottom_toTopOf="@+id/upload"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.5"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/show" /><Buttonandroid:id="@+id/upload"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="上传文件"app:layout_constraintBottom_toTopOf="@+id/download"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.5"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/create" /><Buttonandroid:id="@+id/download"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="下载文件"app:layout_constraintBottom_toTopOf="@+id/rename"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.5"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/upload" /><Buttonandroid:id="@+id/rename"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="重命名文件夹"app:layout_constraintBottom_toTopOf="@+id/delete"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.5"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/download" /><Buttonandroid:id="@+id/delete"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="删除文件夹"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.5"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/rename" /></androidx.constraintlayout.widget.ConstraintLayout>

如有疏忽遗漏之处,敬请指出

本文demo源码  github、gitee地址:

https://github.com/darlingxyz/demo_webdav

https://gitee.com/darlingxyz/demo_webdav

【Kotlin】Android-使用WebDAV协议云存储文件(详细)—附demo源码相关推荐

  1. android 活体识别人脸动作活体静默活体Demo源码实现讲解

    android 活体识别人脸动作活体静默活体Demo源码实现讲解 这里说活体是基于单目摄像头活体,适合所有普通安卓Android 单目摄像头的手机,双目的需要硬件支持,这里不讲述 . 百度网盘体验地址 ...

  2. Android 蓝牙hfp协议连接slc连接rfcomm连接源码分析(2)- HF侧发送和接受数据流程

    android-蓝牙A2dp-avrcp-hfp-opp-配对流程-ble-rfcomm源码流程 Android 蓝牙hfp初始化.rfcomm连接.slc连接.sco连接源代码分析大全 - 点击下载 ...

  3. android 融云 + 科大讯飞 实现仿微信语音消息转换为文字(附DEMO源码)

    融云SDK 使用很方便,简单配置就可以搭建即时通讯功能,配合科大讯飞的语音识别, 即可实现微信中语音消息转换为文字的功能 融云sdk的基本使用就不细说了, 网上很多资料 使用融云sdk自带的聊天会话界 ...

  4. Android - 弹幕实现原理(附Demo源码),kotlin爬虫

    2.在观看直播或视频的时候,我们经常能看到弹幕的效果.首先我们从布局上讲一下,其实非常简单,布局最下层是播放器视图,中间那层一般则是弹幕视图层,最上层是操作界面的视图层.这样一说大家的心里是不是就有一 ...

  5. Android 二维码 生成和识别(附Demo源码)

    Posted on 2013-08-25 23:15 泡泡糖 阅读( 20424) 评论( 7) 编辑 收藏 今天讲一下目前移动领域很常用的技术--二维码.现在大街小巷.各大网站都有二维码的踪迹,不管 ...

  6. Android BlueToothBLE入门(二)——设备的连接和通讯(附Demo源码地址)

    学更好的别人, 做更好的自己. --<微卡智享> 本文长度为7870字,预计阅读12分钟 前言 接<Android BlueToothBLE入门(一)--低功耗蓝牙介绍>上篇, ...

  7. Android - 弹幕实现原理(附Demo源码)

    3.核心代码就要来了.在这里有几点是需要说明的. (1)首先播放视频的话这里用到的是VideoView,使用起来也非常简单,先要设置一个视频文件的路径:String uri = "andro ...

  8. 蓝牙配对模式 java_【Android】蓝牙开发—— 经典蓝牙配对介绍(Java代码实现演示)附Demo源码...

    目录 前言 一.连接&配对方法介绍 二.演示:第一次连接蓝牙设备  &  直接与蓝牙设备建立配对 三.总结 四.补充 五.Demo案例源码地址: 前言 前面两篇文章[Android]蓝 ...

  9. 【Android】蓝牙开发—— 经典蓝牙配对介绍(Java代码实现演示)附Demo源码

    目录 前言 一.连接&配对方法介绍 二.演示:第一次连接蓝牙设备  &  直接与蓝牙设备建立配对 三.总结 四.补充 五.Demo案例源码地址: 前言 前面两篇文章[Android]蓝 ...

最新文章

  1. iOS UIModalPresentationFormSheet风格下的键盘隐藏
  2. Linux shell 常用命令
  3. Linux 权限管理之基本权限
  4. 秋色园QBlog技术原理解析:性能优化篇:打印页面SQL,全局的SQL语句优化(十三)...
  5. java 协议开发_用Java的NIO开发网络协议
  6. Sqlserver 索引
  7. linux系统一键安装php运行环境apache,mysql等
  8. InnoDB 存储引擎(8)——InnoDB 存储引擎文件
  9. HERO引擎传奇遇到的问题以及解决办法
  10. 华为数通HCIP笔记
  11. macbook视频格式转换_Mac视频格式转换器:6款最好的免费工具
  12. Win10中photoshop打开camera raw 报错
  13. DARPA到底是什么?一个能轻松将人类变成电子生化人的科技
  14. 2018-2019-1 20165309 20165312 20165330 实验一 开发环境的熟悉
  15. c语言自定义标识符do,C语言基础知识习题
  16. 成功时间管理软件推荐-DesktopCal和GTD
  17. VGG16各层处理过程
  18. 网页作业HTML+CSS+JS大作业——汽车租赁(47页) 加特效 web期末作业设计网页_汽车大学生网页设计作业成品
  19. Codeforce821E Okabe and El Psy Kongroo
  20. Linux时间子系统之Tick模拟层(Tick Sched)

热门文章

  1. 使用golang发送电子邮件
  2. 爱迪尔 门锁接口文档_爱迪尔门锁软件管理系统
  3. 音视频进阶教程|实现直播SEI补充增强信息
  4. Vmware虚拟机安装Linux系统(cent OS 7 64)
  5. 优步北京B组奖励政策
  6. E-puck2机器人系列教程
  7. 学习记录553@flowable候选人机制
  8. 【数据结构与算法】这或许是东半球分析十大排序算法最好的一篇文章
  9. jquery动态增加多行文本框并计算值
  10. 数据结构------顺序结构