最近在写一个云备份功能,参考了一下市面上的软件,发现有一种采用WebDav协议的云备份成本比较低,故特地研究一下使用。

服务器提供商是使用国内的坚果云,还是非常良心的。

坚果云官网:https://www.jianguoyun.com

注册账号后,点击账户信息,安全选项中即可看到 第三方应用管理

这里需要三个东西,服务器地址、账户、密码(这个密码是你为应用单独开辟的,不是用户密码),具体参考:http://help.jianguoyun.com/?tag=webdav

拿到数据后,我们就可以开始进行安卓开发了。

依赖以及权限设置

因为涉及到网络,所以需要在Manifests中设置联网权限:

 <uses-permission android:name="android.permission.INTERNET" /> 

同时注意安卓9.0以上的网络安全策略,需要单独配置一下:

在res新建一个 network_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>

接着在Manifests的application中配置:

android:networkSecurityConfig="@xml/network__config"

webDav网上的教程不是特别多,一开始找到的是 lookfirst/sardine

该项目是使用的HttpClient且和安卓部分依赖有些冲突,所以不推荐直接使用

后来在github中找到一个移植到安卓的sardine,项目地址

经过测试可以直接使用。

implementation 'com.thegrizzlylabs.sardine-android:sardine-android:0.5'

当然你也可以直接翻到文末查看我提供的对sardine的二次封装库,使用起来更方便。

基础使用方法

请注意:以下所有方法都必须在新线程中进行,且对UI的直接操作要放回主线程进行,可以考虑使用Handler

初始化

 Sardine sardine= new OkHttpSardine();
sardine.setCredentials(userName,password);

这里的userName,password即你的用户账号+分配的应用的所属密码

获取目录下所有文件

List<DavResource> resources = null;
try {
resources = sardine.list("https://dav.jianguoyun.com/dav/");//如果是目录一定别忘记在后面加上一个斜杠
for (DavResource res : resources)
{
listNames=listNames+res+"\n";
}
} catch (IOException e) {
e.printStackTrace();
}

判断路径(或文件)是否存在

//判断文件是否存在
if (sardine.exists("https://dav.jianguoyun.com/dav/file1.jpg"))
System.out.println("got here!");
//判断路径是否存在
if (sardine.exists("https://dav.jianguoyun.com/dav/file/"))
System.out.println("got here!");

若目录不存在,可以自己创建:

sardine.createDirectory("https://dav.jianguoyun.com/dav/
目录名称/");

下载文件

InputStream is = sardine.get("https://dav.jianguoyun.com/dav/"+"文件目录"+"afile.jpg");

上传文件

byte[] data = FileUtils.readFileToByteArray(new File("/file/on/disk"));
sardine.put("http://yourdavserver.com/adirectory/nameOfFile.jpg", data);

或者使用

InputStream fis = new FileInputStream(new File("/some/file/on/disk.txt"));
sardine.put("http://yourdavserver.com/adirectory/nameOfFile.jpg", fis);

节省内存空间

删除文件

sardine.delete("http://yourdavserver.com/adirectory/nameOfFile.jpg");

综合例子

这里给出一个简单的例子,可以把这些代码统一封装成一个类

/**
* 同步管理器
* SyncManager(Context context)
* getCloudFiles(final Handler handler) 获取文件
* public void upDate(final Handler handler) 更新文件
* */
public class SyncManager {
private String serverHostUrl;//WebDav服务器地址,坚果云为:https://dav.jianguoyun.com/dav/
private String userName;//用户名
private String password;//密码
private Sardine sardine;
private Context context;
private SettingManager settingManager; public SyncManager(Context context){
this.context=context;
//初始化设置,主要是获取用户设定的服务器地址、用户名和密码
settingManager=new SettingManager(context);
serverHostUrl=settingManager.getUserServer();
userName=settingManager.getUsername();
password=settingManager.getPassword();
//初始化sardine,使用OkHttpSardine进行实例化
sardine=new OkHttpSardine();
}
/**
* 更新数据(即上传数据)
* @param counterEvents 数据源
* @param handler 线程回调
* */
private void updateFiles(List<CounterEvent> counterEvents,Handler handler){
sardine.setCredentials(userName,password);//设置登录账号,登录
//自己规定一种数据格式,这里面我采用的是json
Gson gson=new Gson();
String jsons=gson.toJson(counterEvents);
//把要上传的数据转成byte数组
byte[] data=jsons.getBytes();
try {
//首先判断目标存储路径文件夹存不存在
if(!sardine.exists(serverHostUrl+"pickTime/")){
//若不存在需要创建目录
sardine.createDirectory(serverHostUrl+"pickTime/");
}
//存入数据
sardine.put(serverHostUrl+"pickTime/backup.txt",data);
//通知主线程进行下一步操作
Message message=new Message();
message.what=1;
handler.sendMessage(message);
} catch (IOException e) {
Message message=new Message();
message.what=-1;
message.obj=e;
handler.sendMessage(message);
Log.d("啥情况",e.toString());
e.printStackTrace();
}
}
/**
* 封装的更新方法
* @param handler 回调
* */
public void upDate(final Handler handler){
if(userName.equals("")||password.equals("")){
Toasty.info(context,"请设置账号",Toasty.LENGTH_SHORT).show();
Intent intent=new Intent(context, SettingActivity.class);
context.startActivity(intent);
}else {
//开启线程进行执行操作
new Thread(new Runnable() {
@Override
public void run() {
updateFiles(Manager.getAllCounterEvents(context),handler);
}
}).start();
}
}
/**
* 封装的获取文件方法
* @param handler 回调
* */
public void getCloudFiles(final Handler handler){
if(userName.equals("")||password.equals("")){
Toasty.info(context,"请设置账号",Toasty.LENGTH_SHORT).show();
Intent intent=new Intent(context, SettingActivity.class);
context.startActivity(intent);
}else {
Toasty.info(context,"恢复中",Toasty.LENGTH_SHORT).show();
new Thread(new Runnable() {
@Override
public void run() {
getFiles(handler);
}
}).start();
}
}
/**
* 获取文件
* @param handler 回调
* */
private void getFiles(Handler handler){
sardine.setCredentials(userName,password);//登录。设置账号
try {
//拿到输入流
InputStream inputStream=sardine.get(serverHostUrl+"pickTime/backup.txt");
//设置输入缓冲区
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); // 实例化输入流,并获取网页代
String s; // 依次循环,至到读的值为空
StringBuilder sb = new StringBuilder();
while ((s = reader.readLine()) != null) {
sb.append(s);
}
reader.close(); String str = sb.toString();
//TODO 这里放你的处理逻辑,或者由handler传送给相应处理
Message message=new Message();
message.what=2;
handler.sendMessage(message);
} catch (IOException e) {
Message message=new Message();
message.what=-2;
message.obj=e;
handler.sendMessage(message);
e.printStackTrace();
} } }

封装库

我已经把该代码封装成了一个库,可以直接使用:https://github.com/paul623/WebDavSyncerDemo

implementation 'com.paul623.wdsyncer:wdsyncer:0.0.1'

具体功能及实现请查看github

【Android】WebDav For Android的更多相关文章

  1. 【转】第一次使用Android Studio时你应该知道的一切配置(三):gradle项目构建

    原文网址:http://www.cnblogs.com/smyhvae/p/4456420.html [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.c ...

  2. 【转】第一次使用Android Studio时你应该知道的一切配置

    原文网址:http://www.cnblogs.com/smyhvae/p/4390905.html [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.c ...

  3. 【转】unity开发android游戏(一)搭建Unity安卓开发环境

    http://blog.csdn.net/chenggong2dm/article/details/20654075 1,下载安装Java的JDK: http://www.oracle.com/tec ...

  4. 【转】深入理解Android的startservice和bindservice--不错

    原文网址:http://www.cnblogs.com/yejiurui/p/3429451.html 一.首先,让我们确认下什么是service?         service就是android系 ...

  5. 【Android】4.0 Android项目的基本结构

    分类:C#.Android.VS2015: 创建日期:2016-02-06: 修改日期:2016-02-27 一.简介 第3章虽然通过百度地图应用展示了你可能感兴趣的内容,但是,如果你是一个初学者,一 ...

  6. 【Android】神奇的android:clipChildren属性

    前言 前几天有在微博上推荐过一个博客,看他文章时发现了这个属性.有些属性不常用,但需要的时候非常有用,于是做了个例子,正好项目用到,与大家分享一下. 声明 欢迎转载,请注明出处! 博客园:http:/ ...

  7. 【Android】日常开发android.jar文件中十五个重要的包概述

    简述Android项目中android.jar文件里包含较为重要的15个系统编译后的class文件 android.app:提供高层的程序模型,提供基本的运行环境android.content:包含各 ...

  8. 【转载】总结一下Android中主题(Theme)的正确玩法

    http://www.cnblogs.com/zhouyou96/p/5323138.html 总结一下Android中主题(Theme)的正确玩法 在AndroidManifest.xml文件中有& ...

  9. 【转】Jollen 的 Android 教學,#12: 如何建立選單 Menu

    原文网址:http://www.jollen.org/blog/2009/06/jollen-android-programming-12.html Android應用程式的UI可以使用XML來定義, ...

随机推荐

  1. 宝塔面板管理阿里云服务器FTP不能用

    # 宝塔面板管理阿里云,ftp不能用 解决方法 搜ftp点击设置 然后Ctrl+F搜索ForcePassiveIP 注意2在默认情况下是带#号的,去掉#号,后面的ip地址是阿里云的公网ip 重启,再次 ...

  2. php7 mongodb 扩展windows 安装

    1. 打开phpinfo 查看 nts(非线程) 还是 ts (线程),然后查看操作位数 注: 86 等于 32 位  2. 下载对应的版本的php_mongodb.dll 文件 下载链接: pecl ...

  3. Mybatis基础(二)

    Mybatis连接池 Mybatis连接池提供了三种配置方式,配置的位置在SqlMapConfig.xml的dataSource标签中,其type属性就是配置连接池的种类.type的可取值 1.POO ...

  4. Exception:Request processing failed; nested exception is org.apache.ibatis.binding.BindingException

    异常 在测试Spring MVC+Mybatis整合时,运行 Maven build -> tomcat7:Run 遇到如下异常 从异常信息上看,是找不到mapper对应的xml文件,于是我到t ...

  5. JDK 原生动态代理是怎么实现的 + 面试题

    JDK 原生动态代理是怎么实现的 + 面试题 反射 反射机制是 Java 语言提供的一种基础功能,赋予程序在运行时自省(introspect)的能力.简单来说就是通过反射,可以在运行期间获取.检测和调 ...

  6. Hexo Next 接入 google AdSense 广告

    前言 个人网站 www.yanlongwang.net 已经运营近一年,每日的浏览量不断上升,现在维持在两位数,打算承接一点广告赚睡后收入,用来维持网站的日常运营,希望能覆盖网站的服务器和域名开销. ...

  7. sql serverDB运维实用sql大全

    运维sql server的sql总结,包含阻塞语句.等待语句.某个时间段的sql性能查询等等常用sql语句 ##断开库的连接,记得修改库名 USE masterGOALTER DATABASE [DB ...

  8. 11、ACL

    IP访问控制列表 标准ACL 1)检查源地址 2)不能对协议簇作限定 扩展ACL 1)检查源和目标地址 2)能容许或拒绝特定的协议和应用(端口号) 区别列表类型: 1)ACL号 : 1-99,1300 ...

  9. qt连接mysql数据库实例

    qt5.2版本已经封装进去了mysql驱动,所以省去了我们现编译的麻烦!!! #include <QCoreApplication> #include <QDebug> #in ...

  10. python3 控制结构知识及范例

    (一)三种基本控制结构 1.顺序结构:按照程序语句编写的顺序依次逐条执行 2.选择结构:根据特定的条件选择某一个分支 3.循环结构:反复执行某个或者某些操作,关注点:在什么情况下,反复执行哪一部分的操 ...