【Kotlin】Android-使用WebDAV协议云存储文件(详细)—附demo源码
比起云服务器、云数据库、云存储等等方式将文件存储至云端,网盘的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源码相关推荐
- android 活体识别人脸动作活体静默活体Demo源码实现讲解
android 活体识别人脸动作活体静默活体Demo源码实现讲解 这里说活体是基于单目摄像头活体,适合所有普通安卓Android 单目摄像头的手机,双目的需要硬件支持,这里不讲述 . 百度网盘体验地址 ...
- Android 蓝牙hfp协议连接slc连接rfcomm连接源码分析(2)- HF侧发送和接受数据流程
android-蓝牙A2dp-avrcp-hfp-opp-配对流程-ble-rfcomm源码流程 Android 蓝牙hfp初始化.rfcomm连接.slc连接.sco连接源代码分析大全 - 点击下载 ...
- android 融云 + 科大讯飞 实现仿微信语音消息转换为文字(附DEMO源码)
融云SDK 使用很方便,简单配置就可以搭建即时通讯功能,配合科大讯飞的语音识别, 即可实现微信中语音消息转换为文字的功能 融云sdk的基本使用就不细说了, 网上很多资料 使用融云sdk自带的聊天会话界 ...
- Android - 弹幕实现原理(附Demo源码),kotlin爬虫
2.在观看直播或视频的时候,我们经常能看到弹幕的效果.首先我们从布局上讲一下,其实非常简单,布局最下层是播放器视图,中间那层一般则是弹幕视图层,最上层是操作界面的视图层.这样一说大家的心里是不是就有一 ...
- Android 二维码 生成和识别(附Demo源码)
Posted on 2013-08-25 23:15 泡泡糖 阅读( 20424) 评论( 7) 编辑 收藏 今天讲一下目前移动领域很常用的技术--二维码.现在大街小巷.各大网站都有二维码的踪迹,不管 ...
- Android BlueToothBLE入门(二)——设备的连接和通讯(附Demo源码地址)
学更好的别人, 做更好的自己. --<微卡智享> 本文长度为7870字,预计阅读12分钟 前言 接<Android BlueToothBLE入门(一)--低功耗蓝牙介绍>上篇, ...
- Android - 弹幕实现原理(附Demo源码)
3.核心代码就要来了.在这里有几点是需要说明的. (1)首先播放视频的话这里用到的是VideoView,使用起来也非常简单,先要设置一个视频文件的路径:String uri = "andro ...
- 蓝牙配对模式 java_【Android】蓝牙开发—— 经典蓝牙配对介绍(Java代码实现演示)附Demo源码...
目录 前言 一.连接&配对方法介绍 二.演示:第一次连接蓝牙设备 & 直接与蓝牙设备建立配对 三.总结 四.补充 五.Demo案例源码地址: 前言 前面两篇文章[Android]蓝 ...
- 【Android】蓝牙开发—— 经典蓝牙配对介绍(Java代码实现演示)附Demo源码
目录 前言 一.连接&配对方法介绍 二.演示:第一次连接蓝牙设备 & 直接与蓝牙设备建立配对 三.总结 四.补充 五.Demo案例源码地址: 前言 前面两篇文章[Android]蓝 ...
最新文章
- iOS UIModalPresentationFormSheet风格下的键盘隐藏
- Linux shell 常用命令
- Linux 权限管理之基本权限
- 秋色园QBlog技术原理解析:性能优化篇:打印页面SQL,全局的SQL语句优化(十三)...
- java 协议开发_用Java的NIO开发网络协议
- Sqlserver 索引
- linux系统一键安装php运行环境apache,mysql等
- InnoDB 存储引擎(8)——InnoDB 存储引擎文件
- HERO引擎传奇遇到的问题以及解决办法
- 华为数通HCIP笔记
- macbook视频格式转换_Mac视频格式转换器:6款最好的免费工具
- Win10中photoshop打开camera raw 报错
- DARPA到底是什么?一个能轻松将人类变成电子生化人的科技
- 2018-2019-1 20165309 20165312 20165330 实验一 开发环境的熟悉
- c语言自定义标识符do,C语言基础知识习题
- 成功时间管理软件推荐-DesktopCal和GTD
- VGG16各层处理过程
- 网页作业HTML+CSS+JS大作业——汽车租赁(47页) 加特效 web期末作业设计网页_汽车大学生网页设计作业成品
- Codeforce821E Okabe and El Psy Kongroo
- Linux时间子系统之Tick模拟层(Tick Sched)