Android Q 上基于 OkHttp 上传(大)文件的实现

Android Q 上基于 OkHttp 上传(大)文件的实现,第1张

如图,RequestBody 有好几个 create 方法,可以满足不同场景下的内容上传,比如字符串、字节数组和文件

显然,字符串和字节数组是不能上传大文件的,均可能 OOM。

那么,就只能使用 RequestBody create(MediaType contentType, File file) 方法了。正常情况下也是没什么问题的,但是在 Android Q 上,由于存储权限的变更,将导致无法直接访问从内容库所选择的文件。

得到如下日志:

可见,即使通过 uri 得到了文件的真实路径,也是无法直接访问的。

通过上面的实验可以看到,我们是无法直接通过 File 相关的 API 访问原始文件的,但是我们却可以通过 ContentResolver 得到原始文件的流。

类似地,可以基于流或者 FileDescriptor 对图片解码成 Bitmap,参考:

/**

* 上传文件

* @param actionUrl 连接地址

* @param paramsMap 参数

* @param callback 回调

* @param <T>

*/

public static <T>void upLoadFile(String actionUrl, HashMap<String, Object>paramsMap, Callback callback) {

//RequestBody requestBody = new MultipartBuilder() //建立请求的内容

//.type(MultipartBuilder.FORM)//表单形式

//.addFormDataPart("token", token)//携带的参数

//.addFormDataPart("file", file.getName(), RequestBody.create(null, file))//第一个参数是服务器接收的名称,第二个是上传文件的名字,第三个是上传的文件

//.build()

//Request request = new Request.Builder()//建立请求

//.url(url)//请求的地址

//.post(requestBody)//请求的内容(上面建立的requestBody)

//.build()

try {

OkHttpClient okHttpClient = new OkHttpClient()

MultipartBuilder builder = new MultipartBuilder()

builder.type(MultipartBuilder.FORM)

//追加参数

for (String key : paramsMap.keySet()) {

Object object = paramsMap.get(key)

if (!(object instanceof File)) {

builder.addFormDataPart(key, object.toString())

} else {

File file = (File) object

builder.addFormDataPart(key, file.getName(), RequestBody.create(null, file))

}

}

//创建RequestBody

RequestBody body = builder.build()

//创建Request

final Request request = new Request.Builder().url(actionUrl).post(body).build()

HLog.v("upLoadFile","upLoadFile",request.urlString())

Call call=okHttpClient.newCall(request)

call.enqueue(callback)

} catch (Exception e) {

Log.e(TAG, e.toString())

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/8109980.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-13
下一篇 2023-04-13

发表评论

登录后才能评论

评论列表(0条)

保存