Android10文件存儲機(jī)制修改成了沙盒模式,應(yīng)用不能直接訪問除了沙盒文件和公共文件以外的文件,直接使用圖片絕對地址上傳圖片會出錯,可以通過圖片的Uri來上傳圖片
private fun copyFromUri(uri:Uri,fileName:String,subscribe:Observer<String>){
var cacheFile = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES)?.absolutePath+File.separator+"cache")
if(!cacheFile.exists())
cacheFile.exists()
cacheFile = File(cacheFile.absolutePath + File.separator + fileName)
Observable.create<String>{
val inStream:InputStream = contentResolver.openInputStream(uri)!!
val outStream:OutputStream = FileOutputStream(cacheFile)
val bytes = ByteArray(1024)
var len = -1
try {
while ({len = inStream.read(bytes);len}()!=-1)
outStream.write(bytes,0,len)
} catch (e: Exception) {
it.onError(e)
} finally {
inStream.close()
outStream.close()
}
it.onNext(cacheFile.path)
it.onComplete()
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscribe)
}
上傳圖片
private fun onUpload(path: String){
if ( "" != path.trim() ){
val file = File(path)
val body = file.asRequestBody("application/octet-stream".toMediaTypeOrNull())
val progressBody = ProgressRequestBody(body){
progress.progress = it.toInt()
}
val part = MultipartBody.Part.createFormData("file",file.name,progressBody)
getRetrofit().create(Api::class.java).onUpload(part)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<ResponseBody> {
override fun onSubscribe(d: Disposable) {
}
override fun onNext(t: ResponseBody) {
Toast.makeText(this@MainActivity,"Success",Toast.LENGTH_SHORT).show()
}
override fun onError(e: Throwable) {
Toast.makeText(this@MainActivity,"Error!"+e.message,Toast.LENGTH_SHORT).show()
}
override fun onComplete() {
if(file.exists())
file.delete()
}
})
}
}
網(wǎng)絡(luò)接口定義
@Multipart
@POST("downloadApp/upload")
fun onUpload(@Part part:MultipartBody.Part):Observable<ResponseBody>
實(shí)現(xiàn)進(jìn)度更新
class ProgressRequestBody(private val requestBody: RequestBody,private val listener:((Long)->Unit) ):RequestBody() {
private var byteBufferSink:BufferedSink ?= null
override fun contentType(): MediaType? {
return requestBody.contentType()
}
override fun contentLength(): Long {
return requestBody.contentLength()
}
override fun writeTo(sink: BufferedSink) {
if (byteBufferSink == null)
byteBufferSink = sink(sink).buffer()
requestBody.writeTo(byteBufferSink!!)
byteBufferSink?.flush()
}
private fun sink(sink:Sink) = object : ForwardingSink(sink) {
private var count = 0L
private var total = -1L
@SuppressLint("CheckResult")
override fun write(source: Buffer, byteCount: Long) {
if (total ==-1L) total = contentLength()
super.write(source, byteCount)
count += byteCount
val progress = count/total.toDouble() * 100
Observable.just(count).observeOn(AndroidSchedulers.mainThread()).subscribe {
listener.invoke(progress.toLong())
}
}
}
}
web端的圖片上傳代碼
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String realPath = userPath + "/upload/test";
String cachePath = userPath + "/upload/cache";
File realFile = new File(realPath);
File cacheFile = new File(cachePath);
System.out.println("上傳路徑是:"+realPath);
if (!realFile.exists())
realFile.mkdirs();
if (!cacheFile.exists())
cacheFile.mkdirs();
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(cacheFile);
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("UTF-8");
if (!ServletFileUpload.isMultipartContent(request))
return;
InputStream in = null;
OutputStream out = null;
List<String> files = new ArrayList<>();
try {
List<FileItem> items = upload.parseRequest(request);
for (FileItem item:items){
if (item.isFormField()){
System.out.println(item.getFieldName()+": "+item.getString("UTF-8"));
}else {
String fileName = item.getName();
if (fileName.isEmpty()||"".equals(fileName.trim()))
continue;
fileName = fileName.substring(fileName.lastIndexOf("/")+1);
String downloadPath = realPath+"/"+fileName;
files.add(fileName);
in = item.getInputStream();
out = new FileOutputStream(downloadPath);
byte bt[] = new byte[1024];
int len = -1;
while ((len = in.read(bt))!=-1)
out.write(bt,0,len);
}
item.delete();
}
} catch (FileUploadException | IOException e) {
System.out.println(e.getMessage());
response.getWriter().write("ERROR");
} finally {
if (in!=null)
in.close();
if (out!=null)
out.close();
}
response.getWriter().write("SUCCESS");
}