diff --git a/app/build.gradle b/app/build.gradle index 4fe1f52..b6da6aa 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,4 +1,7 @@ apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-kapt' +apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 30 @@ -83,6 +86,7 @@ dependencies { implementation 'com.lzy.net:okgo:3.0.4' implementation 'com.lzy.net:okrx2:2.0.2' implementation 'com.google.code.gson:gson:2.8.5' + implementation 'com.readystatesoftware.chuck:library:1.0.4' //retrofit+rxJava implementation 'com.squareup.retrofit2:retrofit:2.5.0' @@ -128,7 +132,8 @@ dependencies { def room_version = "2.2.0-alpha01" implementation "androidx.room:room-runtime:$room_version" - annotationProcessor "androidx.room:room-compiler:$room_version" + implementation "androidx.room:room-ktx:$room_version" + kapt "androidx.room:room-compiler:$room_version" implementation "androidx.room:room-rxjava2:$room_version" implementation "androidx.room:room-guava:$room_version" testImplementation "androidx.room:room-testing:$room_version" diff --git a/app/src/main/java/com/navinfo/outdoor/api/Constant.java b/app/src/main/java/com/navinfo/outdoor/api/Constant.java index c70c055..ed0619a 100644 --- a/app/src/main/java/com/navinfo/outdoor/api/Constant.java +++ b/app/src/main/java/com/navinfo/outdoor/api/Constant.java @@ -245,6 +245,8 @@ public class Constant { public static Set submitIdSet = new HashSet<>(); public static final String SUBMIT_TOAST_MSG= "当前POI已经在提交列表中,无需重复提交!"; + public static final long DEFAULT_CUT_SIZE = 5*1024*1024; // 文件切分默认大小为5MB + public static final int DEFAULT_TIME_OUT = 300; // 默认http超时时间设置为300秒 public static void clearLoginInfo() { ACCESS_TOKEN = null; diff --git a/app/src/main/java/com/navinfo/outdoor/bean/CommonRequestSend.java b/app/src/main/java/com/navinfo/outdoor/bean/CommonRequestSend.java new file mode 100644 index 0000000..2efdb7d --- /dev/null +++ b/app/src/main/java/com/navinfo/outdoor/bean/CommonRequestSend.java @@ -0,0 +1,276 @@ +package com.navinfo.outdoor.bean; + +import android.app.Activity; +import android.util.Log; +import android.widget.Toast; + +import com.google.gson.Gson; +import com.google.gson.stream.JsonReader; +import com.lzy.okgo.OkGo; +import com.lzy.okgo.cache.CacheEntity; +import com.lzy.okgo.cache.CacheMode; +import com.lzy.okgo.convert.Converter; +import com.lzy.okgo.convert.StringConvert; +import com.lzy.okgo.model.HttpHeaders; +import com.lzy.okgo.model.HttpParams; +import com.lzy.okgo.model.Response; +import com.lzy.okgo.request.GetRequest; +import com.lzy.okgo.request.PostRequest; +import com.lzy.okgo.request.base.Request; +import com.navinfo.outdoor.api.Constant; +import com.navinfo.outdoor.api.UserApplication; +import com.navinfo.outdoor.http.Callback; +import com.navinfo.outdoor.http.JsonCallback; +import com.navinfo.outdoor.util.FlushTokenUtil; +import com.navinfo.outdoor.util.Md5Util; +import com.navinfo.outdoor.util.NetWorkUtils; +import com.navinfo.outdoor.util.ToastUtils; +import com.umeng.umcrash.UMCrash; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.ResponseBody; + +public class CommonRequestSend { + public void getMethodCommon(Activity mContext, String url, HttpParams params, int timeOut, Callback> callback, Class tClass) { + try { + Response> response = ((GetRequest>) obitainRequest(mContext, url, params, timeOut, 0, tClass)) + .adapt() + .execute(); + if (response.code() == 200) { + if (response.body().getCode() == 200) { + callback.onSuccess(response.body(), 1); + } else if (response.body().getCode() == 230){ + FlushTokenUtil.flushToken(mContext); + Toast.makeText(mContext, "token过期,请重新登录后再试...", Toast.LENGTH_LONG).show(); + Throwable throwable = new Throwable("token过期,请重新登录后再试..."); + callback.onError(throwable, -1); + /* + * 友盟+ + * 使用自定义错误,查看时请在错误列表页面选择【自定义异常】 + */ + UMCrash.generateCustomLog("网络请求报错-位置:OKGOBuilder" + throwable, "UmengException"); + } else { + Toast.makeText(mContext, response.message(), Toast.LENGTH_LONG).show(); + Throwable throwable = new Throwable(response.message()); + callback.onError(throwable, -2); + /* + * 友盟+ + * 使用自定义错误,查看时请在错误列表页面选择【自定义异常】 + */ + UMCrash.generateCustomLog("网络请求报错-位置:OKGOBuilder" + throwable, "UmengException"); + } + + } else { + Toast.makeText(mContext, response.message(), Toast.LENGTH_LONG).show(); + } + } catch (Exception e) { + e.printStackTrace(); + Throwable throwable = e; + if (throwable != null) { + throwable.printStackTrace(); + callback.onError(throwable, -3); + } + /* + * 友盟+ + * 使用自定义错误,查看时请在错误列表页面选择【自定义异常】 + */ + UMCrash.generateCustomLog("网络请求报错-位置:OKGOBuilder" + throwable, "UmengException"); + } + } + + public CommonResponse getMethodCommonSync(Activity mContext, String url, HttpParams params, int timeOut, Class tClass) { + try { + Response> response = ((GetRequest>) obitainRequest(mContext, url, params, timeOut, 0, tClass)) + .adapt() + .execute(); + if (response.code() == 200) { + if (response.body().getCode() == 230){ + FlushTokenUtil.flushToken(mContext); + } + return response.body(); + } else { + return new CommonResponse(response.code(), response.message(), null); + } + } catch (Exception e) { + e.printStackTrace(); + String message = e.getMessage(); + assert message != null; + if (message.equals("timeout") || message.equals("Read time out")) { + ToastUtils.Message(mContext, "请求超时"); + } else { + ToastUtils.Message(mContext, message); + } + Log.d("TAG", "onError: " + e.getMessage()); + return new CommonResponse(e.hashCode(), e.getMessage(), null); + } + } + + public void postMethodCommon(Activity mContext, String url, HttpParams params, int timeOut, Callback> callback, Class tClass) { + try { + Response> response = ((GetRequest>) obitainRequest(mContext, url, params, timeOut, 1, tClass)) + .adapt() + .execute(); + if (response.code() == 200) { + if (response.body().getCode() == 200) { + callback.onSuccess(response.body(), 1); + } else if (response.body().getCode() == 230){ + FlushTokenUtil.flushToken(mContext); + Toast.makeText(mContext, "token过期,请重新登录后再试...", Toast.LENGTH_LONG).show(); + Throwable throwable = new Throwable("token过期,请重新登录后再试..."); + callback.onError(throwable, -1); + /* + * 友盟+ + * 使用自定义错误,查看时请在错误列表页面选择【自定义异常】 + */ + UMCrash.generateCustomLog("网络请求报错-位置:OKGOBuilder" + throwable, "UmengException"); + } else { + Toast.makeText(mContext, response.message(), Toast.LENGTH_LONG).show(); + Throwable throwable = new Throwable(response.message()); + callback.onError(throwable, -2); + /* + * 友盟+ + * 使用自定义错误,查看时请在错误列表页面选择【自定义异常】 + */ + UMCrash.generateCustomLog("网络请求报错-位置:OKGOBuilder" + throwable, "UmengException"); + } + + } else { + Toast.makeText(mContext, response.message(), Toast.LENGTH_LONG).show(); + } + } catch (Exception e) { + e.printStackTrace(); + Throwable throwable = e; + if (throwable != null) { + throwable.printStackTrace(); + callback.onError(throwable, -3); + } + /* + * 友盟+ + * 使用自定义错误,查看时请在错误列表页面选择【自定义异常】 + */ + UMCrash.generateCustomLog("网络请求报错-位置:OKGOBuilder" + throwable, "UmengException"); + } + } + + public CommonResponse postMethodCommonSync(Activity mContext, String url, HttpParams params, int timeOut, List files, Class tClass) { + try { + PostRequest> postRequest = (PostRequest>) obitainRequest(mContext, url, params, timeOut, 1, tClass); + if (files!=null) { + postRequest.addFileParams("file", files); + } + Response> response = postRequest + .adapt() + .execute(); + if (response.code() == 200) { + if (response.body().getCode() == 230){ + FlushTokenUtil.flushToken(mContext); + } + return response.body(); + } else { + return new CommonResponse(response.code(), response.message(), null); + } + } catch (Exception e) { + e.printStackTrace(); + String message = e.getMessage(); + assert message != null; + if (message.equals("timeout") || message.equals("Read time out")) { + ToastUtils.Message(mContext, "请求超时"); + } else { + ToastUtils.Message(mContext, message); + } + Log.d("TAG", "onError: " + e.getMessage()); + return new CommonResponse(e.hashCode(), e.getMessage(), null); + } + } + + /** + * 生成通用请求 + * @param requestType 0-默认为get请求,非0-post请求 + * */ + private Request obitainRequest(Activity mContext, String url, HttpParams params, int timeOut, int requestType, Class clazz) throws Exception{ + if (!NetWorkUtils.iConnected(UserApplication.userApplication)) { // 当前网络不可用 + throw new Exception("网络不可用"); + } + initTimeOut(timeOut); + long time = System.currentTimeMillis(); + params.put("datetime", time); + Request request = null; + if (requestType != 0) { + request= OkGo + // 请求方式和请求url + .>post(url); + } else { + request= OkGo + // 请求方式和请求url + .>get(url); + } + return request + .headers(getHeader(params)) + .params(params) + .retryCount(3) + .converter(new MyJsonCallback(clazz) { + @Override + public void onSuccess(Response response) { + + } + }) + // 请求的 tag, 主要用于取消对应的请求 + .tag(this); + } + + private void initTimeOut(int time) { + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + builder.readTimeout(time, TimeUnit.SECONDS); + //全局的写入超时时间 + builder.writeTimeout(time, TimeUnit.SECONDS); + //全局的连接超时时间 + builder.connectTimeout(time, TimeUnit.SECONDS); + builder.callTimeout(time, TimeUnit.SECONDS); + OkGo.getInstance().init(UserApplication.getUserApplication()).setOkHttpClient(builder.build()) + //全局统一缓存模式,默认不使用缓存,可以不传 + .setCacheMode(CacheMode.NO_CACHE) + //全局统一缓存时间,默认永不过期,可以不传 + .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE) + .setRetryCount(3); + } + + private HttpHeaders getHeader(HttpParams params) { + HttpHeaders headers = new HttpHeaders(); + try { + if (Constant.ACCESS_TOKEN == null) { + headers.put("Authorization", "Basic YXBwOmFwcHNlY3JldA=="); + } else { + headers.put("Authorization", "bearer " + Constant.ACCESS_TOKEN); + } + StringBuilder util = new StringBuilder();//k1=v1&k2=v2&k3=v3 + if (params != null && params.urlParamsMap != null) { + for (Map.Entry> entry : params.urlParamsMap.entrySet()) { + if (!"file".equals(entry.getKey())) { + util.append(entry.getKey()).append("=").append(entry.getValue().get(0).toString()).append("&"); + } + } + if (!util.toString().equals("")) { + util = new StringBuilder(util.substring(0, util.length() - 1)); + } + } + headers.put("key", Md5Util.toMD5("dtxb_2021_navinfo" + util)); + headers.put("Accept-Encoding", "identity"); + return headers; + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/app/src/main/java/com/navinfo/outdoor/bean/CommonResponse.java b/app/src/main/java/com/navinfo/outdoor/bean/CommonResponse.java new file mode 100644 index 0000000..ece4c1e --- /dev/null +++ b/app/src/main/java/com/navinfo/outdoor/bean/CommonResponse.java @@ -0,0 +1,22 @@ +package com.navinfo.outdoor.bean; + +public class CommonResponse extends CommonResponseBase{ + public CommonResponse(int code, String message, T body) { + this.code = code; + this.message = message; + this.body = body; + } + + public CommonResponse() { + } + + protected T body; + + public T getBody() { + return body; + } + + public void setBody(T body) { + this.body = body; + } +} diff --git a/app/src/main/java/com/navinfo/outdoor/bean/CommonResponseBase.java b/app/src/main/java/com/navinfo/outdoor/bean/CommonResponseBase.java new file mode 100644 index 0000000..569f06b --- /dev/null +++ b/app/src/main/java/com/navinfo/outdoor/bean/CommonResponseBase.java @@ -0,0 +1,29 @@ +package com.navinfo.outdoor.bean; + +public class CommonResponseBase { + protected Integer code; + protected String message; + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public CommonResponse toLzyResponse() { + CommonResponse lzyResponse = new CommonResponse(); + lzyResponse.code = code; + lzyResponse.message = message; + return lzyResponse; + } +} diff --git a/app/src/main/java/com/navinfo/outdoor/bean/Convert.java b/app/src/main/java/com/navinfo/outdoor/bean/Convert.java new file mode 100644 index 0000000..fb5d706 --- /dev/null +++ b/app/src/main/java/com/navinfo/outdoor/bean/Convert.java @@ -0,0 +1,72 @@ +package com.navinfo.outdoor.bean; + + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonIOException; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import com.google.gson.stream.JsonReader; +import com.readystatesoftware.chuck.internal.support.JsonConvertor; + +import java.io.Reader; +import java.lang.reflect.Type; + +public class Convert { + + private static Gson create() { + return Convert.GsonHolder.gson; + } + + private static class GsonHolder { + private static Gson gson = new Gson(); + } + + public static T fromJson(String json, Class type) throws JsonIOException, JsonSyntaxException { + return create().fromJson(json, type); + } + + public static T fromJson(String json, Type type) { + return create().fromJson(json, type); + } + + public static T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException { + return create().fromJson(reader, typeOfT); + } + + public static T fromJson(Reader json, Class classOfT) throws JsonSyntaxException, JsonIOException { + return create().fromJson(json, classOfT); + } + + public static T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException { + return create().fromJson(json, typeOfT); + } + + public static String toJson(Object src) { + return create().toJson(src); + } + + public static String toJson(Object src, Type typeOfSrc) { + return create().toJson(src, typeOfSrc); + } + + public static String formatJson(String json) { + try { + JsonParser jp = new JsonParser(); + JsonElement je = jp.parse(json); + return JsonConvertor.getInstance().toJson(je); + } catch (Exception e) { + return json; + } + } + + public static String formatJson(Object src) { + try { + JsonParser jp = new JsonParser(); + JsonElement je = jp.parse(toJson(src)); + return JsonConvertor.getInstance().toJson(je); + } catch (Exception e) { + return e.getMessage(); + } + } +} diff --git a/app/src/main/java/com/navinfo/outdoor/bean/MyJsonCallback.java b/app/src/main/java/com/navinfo/outdoor/bean/MyJsonCallback.java new file mode 100644 index 0000000..5e1fb87 --- /dev/null +++ b/app/src/main/java/com/navinfo/outdoor/bean/MyJsonCallback.java @@ -0,0 +1,128 @@ +package com.navinfo.outdoor.bean; + +import com.google.gson.stream.JsonReader; +import com.lzy.okgo.callback.AbsCallback; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.Serializable; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +import okhttp3.Response; +import okhttp3.ResponseBody; + +public abstract class MyJsonCallback extends AbsCallback { + + private Type type; + private Class clazz; + + public MyJsonCallback() { + } + + public MyJsonCallback(Type type) { + this.type = type; + } + + public MyJsonCallback(Class clazz) { + this.clazz = clazz; + } + + @Override + public T convertResponse(Response response) throws Throwable { + + if (type == null) { + if (clazz == null) { + // 如果没有通过构造函数传进来,就自动解析父类泛型的真实类型(有局限性,继承后就无法解析到) + Type genType = getClass().getGenericSuperclass(); + type = ((ParameterizedType) genType).getActualTypeArguments()[0]; + } else { + return parseClass(response, clazz); + } + } + + if (type instanceof ParameterizedType) { + return parseParameterizedType(response, (ParameterizedType) type); + } else if (type instanceof Class) { + return parseClass(response, (Class) type); + } else { + return parseType(response, type); + } + } + + private T parseClass(Response response, Class rawType) throws Exception { + if (rawType == null) return null; + ResponseBody body = response.body(); + if (body == null) return null; + JsonReader jsonReader = new JsonReader(body.charStream()); + + if (rawType == String.class) { + //noinspection unchecked + return (T) body.string(); + } else if (rawType == JSONObject.class) { + //noinspection unchecked + return (T) new JSONObject(body.string()); + } else if (rawType == JSONArray.class) { + //noinspection unchecked + return (T) new JSONArray(body.string()); + } else { + T t = Convert.fromJson(jsonReader, rawType); + response.close(); + return t; + } + } + + private T parseType(Response response, Type type) throws Exception { + if (type == null) return null; + ResponseBody body = response.body(); + if (body == null) return null; + JsonReader jsonReader = new JsonReader(body.charStream()); + + // 泛型格式如下: new JsonCallback<任意JavaBean>(this) + T t = Convert.fromJson(jsonReader, type); + response.close(); + return t; + } + + private T parseParameterizedType(Response response, ParameterizedType type) throws Exception { + if (type == null) return null; + ResponseBody body = response.body(); + if (body == null) return null; + JsonReader jsonReader = new JsonReader(body.charStream()); + + Type rawType = type.getRawType(); // 泛型的实际类型 + Type typeArgument = type.getActualTypeArguments()[0]; // 泛型的参数 + if (rawType != CommonResponse.class) { + // 泛型格式如下: new JsonCallback<外层BaseBean<内层JavaBean>>(this) + T t = Convert.fromJson(jsonReader, type); + response.close(); + return t; + } else { + if (typeArgument == Void.class) { + // 泛型格式如下: new JsonCallback>(this) + CommonResponseBase simpleResponse = Convert.fromJson(jsonReader, CommonResponseBase.class); + response.close(); + //noinspection unchecked + return (T) simpleResponse.toLzyResponse(); + } else { + // 泛型格式如下: new JsonCallback>(this) + CommonResponse lzyResponse = Convert.fromJson(jsonReader, type); + response.close(); + int code = lzyResponse.code; + // 一般来说服务器会和客户端约定一个数表示成功,如200,其余的表示失败,如400,300等,这里根据实际情况罗列并抛出 + if (code == 0) { + //noinspection unchecked + return (T) lzyResponse; + } else if (code == 230) { + throw new IllegalStateException("Token已过期"); + } /*else if (code == 300) { + throw new IllegalStateException("用户名密码错误"); + } */else { + // 直接将服务端的错误信息抛出,onError中可以获取 + throw new IllegalStateException("错误代码:" + code + ",错误信息:" + lzyResponse.message); + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/outdoor/fragment/PoiVideoFragment.java b/app/src/main/java/com/navinfo/outdoor/fragment/PoiVideoFragment.java index d423124..038be98 100644 --- a/app/src/main/java/com/navinfo/outdoor/fragment/PoiVideoFragment.java +++ b/app/src/main/java/com/navinfo/outdoor/fragment/PoiVideoFragment.java @@ -52,6 +52,7 @@ import com.navinfo.outdoor.room.PoiDao; import com.navinfo.outdoor.room.PoiDatabase; import com.navinfo.outdoor.room.PoiEntity; import com.navinfo.outdoor.util.AWMp4ParserHelper; +import com.navinfo.outdoor.util.DataSaveUtils; import com.navinfo.outdoor.util.FlushTokenUtil; import com.navinfo.outdoor.util.Geohash; import com.navinfo.outdoor.util.GeometryTools; @@ -507,42 +508,62 @@ public class PoiVideoFragment extends BaseDrawerFragment implements View.OnClick ToastUtils.Message(getActivity(), "本地不存在照片文件,无法上传数据,请确认!"); return; } - fileZip = new File(Constant.PICTURE_FOLDER, "files" + ".zip"); - new Thread(new Runnable() { + DataSaveUtils.getInstance().uploadFiles(getActivity(), showPoiEntity, videoFileList, new DataSaveUtils.UploadCallback() { @Override - public void run() { - ZipUtil.zipFiles(videoFileList, fileZip, null); - long zipTrueSize = ZipUtils.getZipTrueSize(fileZip.getAbsolutePath()); - if (zipTrueSize > 0) { - if (getActivity() != null) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - if (showPoiEntity == null) { - showPoiEntity = new PoiEntity(); - } - if (showPoiEntity.getTaskStatus() == 0 || showPoiEntity.getTaskStatus() == 1 || showPoiEntity.getTaskStatus() == 2 || showPoiEntity.getTaskStatus() == 5) { - initPoiSaveLocal(true); - } else { - poiVideoUpload(showPoiEntity.getBodyId(), fileZip); - Constant.isPresent = false; - } - } - }); - } - } else { - if (getActivity() != null) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - fileZip.delete(); - ToastUtils.Message(getActivity(), "压缩文件失败,请重新提交"); - } - }); - } - } + public void onStart() { + dismissLoadingDialog(); + Constant.isPresent = false; + getActivity().getSupportFragmentManager().popBackStack();//回退 + WaitDialog.show((AppCompatActivity) getActivity(), "任务正在后台上传中,请稍候..."); + WaitDialog.dismiss(3000); } - }).start(); + + @Override + public void onFinish() { + Constant.isPresent = true; + } + + @Override + public void onError() { + + } + }); +// fileZip = new File(Constant.PICTURE_FOLDER, "files" + ".zip"); +// new Thread(new Runnable() { +// @Override +// public void run() { +// ZipUtil.zipFiles(videoFileList, fileZip, null); +// long zipTrueSize = ZipUtils.getZipTrueSize(fileZip.getAbsolutePath()); +// if (zipTrueSize > 0) { +// if (getActivity() != null) { +// getActivity().runOnUiThread(new Runnable() { +// @Override +// public void run() { +// if (showPoiEntity == null) { +// showPoiEntity = new PoiEntity(); +// } +// if (showPoiEntity.getTaskStatus() == 0 || showPoiEntity.getTaskStatus() == 1 || showPoiEntity.getTaskStatus() == 2 || showPoiEntity.getTaskStatus() == 5) { +// initPoiSaveLocal(true); +// } else { +// poiVideoUpload(showPoiEntity.getBodyId(), fileZip); +// Constant.isPresent = false; +// } +// } +// }); +// } +// } else { +// if (getActivity() != null) { +// getActivity().runOnUiThread(new Runnable() { +// @Override +// public void run() { +// fileZip.delete(); +// ToastUtils.Message(getActivity(), "压缩文件失败,请重新提交"); +// } +// }); +// } +// } +// } +// }).start(); } else { dismissLoadingDialog(); ToastUtils.Message(getActivity(), "请录像"); diff --git a/app/src/main/java/com/navinfo/outdoor/fragment/RoadFragment.java b/app/src/main/java/com/navinfo/outdoor/fragment/RoadFragment.java index e229f41..f9d1f12 100644 --- a/app/src/main/java/com/navinfo/outdoor/fragment/RoadFragment.java +++ b/app/src/main/java/com/navinfo/outdoor/fragment/RoadFragment.java @@ -44,6 +44,7 @@ import com.navinfo.outdoor.activity.FragmentManagement; import com.navinfo.outdoor.activity.PicturesActivity; import com.navinfo.outdoor.api.Constant; import com.navinfo.outdoor.base.BaseDrawerFragment; +import com.navinfo.outdoor.util.DataSaveUtils; import com.navinfo.outdoor.util.FlushTokenUtil; import com.navinfo.outdoor.util.PoiSaveUtils; import com.navinfo.outdoor.util.PreserveUtils; @@ -584,42 +585,62 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList ToastUtils.Message(getActivity(), "本地不存在照片文件,无法上传数据,请确认!"); return; } - fileZip = new File(Constant.PICTURE_FOLDER, "files" + ".zip"); - new Thread(new Runnable() { + DataSaveUtils.getInstance().uploadFiles(getActivity(), showPoiEntity, videoFileList, new DataSaveUtils.UploadCallback() { @Override - public void run() { - ZipUtil.zipFiles(videoFileList, fileZip, null);//压缩 - long zipTrueSize = ZipUtils.getZipTrueSize(fileZip.getAbsolutePath()); - if (zipTrueSize > 0) { - if (getActivity() != null) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - if (showPoiEntity == null) { - showPoiEntity = new PoiEntity(); - } - if (showPoiEntity.getTaskStatus() == 1 || showPoiEntity.getTaskStatus() == 2 || showPoiEntity.getTaskStatus() == 0 || showPoiEntity.getTaskStatus() == 5) { - initPoiSaveLocal(true); - } else { - poiVideoUpload(showPoiEntity.getBodyId(), fileZip); - Constant.isPresent = false; - } - } - }); - } - } else { - if (getActivity() != null) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - fileZip.delete(); - ToastUtils.Message(getActivity(), "压缩文件失败,请重新提交"); - } - }); - } - } + public void onStart() { + dismissLoadingDialog(); + Constant.isPresent = false; + getActivity().getSupportFragmentManager().popBackStack();//回退 + WaitDialog.show((AppCompatActivity) getActivity(), "任务正在后台上传中,请稍候..."); + WaitDialog.dismiss(3000); } - }).start(); + + @Override + public void onFinish() { + Constant.isPresent = true; + } + + @Override + public void onError() { + + } + }); +// fileZip = new File(Constant.PICTURE_FOLDER, "files" + ".zip"); +// new Thread(new Runnable() { +// @Override +// public void run() { +// ZipUtil.zipFiles(videoFileList, fileZip, null);//压缩 +// long zipTrueSize = ZipUtils.getZipTrueSize(fileZip.getAbsolutePath()); +// if (zipTrueSize > 0) { +// if (getActivity() != null) { +// getActivity().runOnUiThread(new Runnable() { +// @Override +// public void run() { +// if (showPoiEntity == null) { +// showPoiEntity = new PoiEntity(); +// } +// if (showPoiEntity.getTaskStatus() == 1 || showPoiEntity.getTaskStatus() == 2 || showPoiEntity.getTaskStatus() == 0 || showPoiEntity.getTaskStatus() == 5) { +// initPoiSaveLocal(true); +// } else { +// poiVideoUpload(showPoiEntity.getBodyId(), fileZip); +// Constant.isPresent = false; +// } +// } +// }); +// } +// } else { +// if (getActivity() != null) { +// getActivity().runOnUiThread(new Runnable() { +// @Override +// public void run() { +// fileZip.delete(); +// ToastUtils.Message(getActivity(), "压缩文件失败,请重新提交"); +// } +// }); +// } +// } +// } +// }).start(); } else { dismissLoadingDialog(); ToastUtils.Message(getActivity(), "请录像"); diff --git a/app/src/main/java/com/navinfo/outdoor/http/DialogCallback.java b/app/src/main/java/com/navinfo/outdoor/http/DialogCallback.java index fe00ff9..71f0127 100644 --- a/app/src/main/java/com/navinfo/outdoor/http/DialogCallback.java +++ b/app/src/main/java/com/navinfo/outdoor/http/DialogCallback.java @@ -12,6 +12,10 @@ public abstract class DialogCallback extends JsonCallback { @Override public void onSuccess(Response response) { } + public DialogCallback() { + super(); + } + public DialogCallback( Class tClass) { super(tClass); } diff --git a/app/src/main/java/com/navinfo/outdoor/http/HttpInterface.java b/app/src/main/java/com/navinfo/outdoor/http/HttpInterface.java index cd32671..720779c 100644 --- a/app/src/main/java/com/navinfo/outdoor/http/HttpInterface.java +++ b/app/src/main/java/com/navinfo/outdoor/http/HttpInterface.java @@ -1,8 +1,9 @@ package com.navinfo.outdoor.http; public class HttpInterface { - public static final String IP = "http://172.23.138.133:9999/m4";//测试接口 - public static final String IP2 = "http://dtxbmaps.navinfo.com/dtxb/dev/m4";//测试接口-外网 +// public static final String IP = "http://172.23.138.133:9999/m4";//测试接口-IP + public static final String IPm = "http://dtxbmaps.navinfo.com/dtxb/dev/m4";//开发接口-外网 + public static final String IP = "http://dtxbmaps.navinfo.com/dtxb/test/m4";//测试接口-外网 public static final String IP1 = "http://dtxbmaps.navinfo.com/dtxb/m4";//正式接口 public static final String USER_PATH = "/user/";//我的 public static final String MSG_LIST_PATH = "/msgList/";//发现 @@ -136,6 +137,9 @@ public class HttpInterface { //dtxbmaps.navinfo.com/dtxb_test/m4/msgList/InfoPush/28/push?type=0 public static String MESSAGE_INFO_PUSH = null;//消息通知 public static String UPDATE_PHONE_NUM_URL = null;//消息通知 + public static String CREATE_UPLOAD_TASK = null;//创建断点续传任务 + public static String UPLOAD_SPLITE_TASK = null;//执行断点续传 + public static String UPLOAD_TASK_FINISH = null;//断点续传完成 public static String CONTACT_US = "";//联系我们 public static String ABOUT_MAP = "";//关于 -关于地图寻宝 @@ -237,5 +241,8 @@ public class HttpInterface { COMPLETE = IP + TASK_PATH + "polygonTask/" + userId + "/complete";//面状任务结束领取 SUBMIT_POLYGON_TASK = IP + TASK_PATH + "polygonTask/" + userId + "/submitPolygontask";//面状任务开始采集 UPDATE_PHONE_NUM_URL = IP + UPDATE_PHONE_NUM_PATH.replace("{userId}", userId);// 修改手机号 + CREATE_UPLOAD_TASK = IP + TASK_PATH + "task/"+ userId+"/createUploadTask";// 创建断点续传任务 + UPLOAD_SPLITE_TASK = IP + TASK_PATH + "task/"+ userId+"/uploadSplitTask";// 执行断点续传 + UPLOAD_TASK_FINISH = IP + TASK_PATH + "task/"+ userId+"/uploadTaskFinish";// 断点续传完成 } } diff --git a/app/src/main/java/com/navinfo/outdoor/util/DataSaveUtils.java b/app/src/main/java/com/navinfo/outdoor/util/DataSaveUtils.java new file mode 100644 index 0000000..e9139c8 --- /dev/null +++ b/app/src/main/java/com/navinfo/outdoor/util/DataSaveUtils.java @@ -0,0 +1,339 @@ +package com.navinfo.outdoor.util; + +import android.app.Activity; +import android.content.Context; +import android.os.Message; +import android.util.Log; + +import androidx.appcompat.app.AppCompatActivity; + +import com.github.lazylibrary.util.FileUtils; +import com.github.lazylibrary.util.MD5; +import com.github.lazylibrary.util.ZipUtil; +import com.hjq.permissions.OnPermissionCallback; +import com.hjq.permissions.Permission; +import com.hjq.permissions.XXPermissions; +import com.kongzue.dialog.v3.TipDialog; +import com.kongzue.dialog.v3.WaitDialog; +import com.lzy.okgo.OkGo; +import com.lzy.okgo.model.HttpParams; +import com.lzy.okgo.model.Response; +import com.navinfo.outdoor.api.Constant; +import com.navinfo.outdoor.api.UserApplication; +import com.navinfo.outdoor.bean.CommonRequestSend; +import com.navinfo.outdoor.bean.CommonResponse; +import com.navinfo.outdoor.bean.PoiSaveBean; +import com.navinfo.outdoor.http.Callback; +import com.navinfo.outdoor.http.DialogCallback; +import com.navinfo.outdoor.http.HttpInterface; +import com.navinfo.outdoor.http.OkGoBuilder; +import com.navinfo.outdoor.room.InsertAndUpdateUtils; +import com.navinfo.outdoor.room.PoiDatabase; +import com.navinfo.outdoor.room.PoiEntity; +import com.umeng.commonsdk.debug.UMLog; +import com.umeng.umcrash.UMCrash; + +import org.greenrobot.eventbus.EventBus; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import io.reactivex.Observable; +import io.reactivex.ObservableEmitter; +import io.reactivex.ObservableOnSubscribe; +import io.reactivex.ObservableSource; +import io.reactivex.Observer; +import io.reactivex.SingleObserver; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Action; +import io.reactivex.functions.Consumer; +import io.reactivex.functions.Function; +import io.reactivex.schedulers.Schedulers; + +public class DataSaveUtils { + private static DataSaveUtils instance; + + public static DataSaveUtils getInstance() { + if (instance == null) { + instance = new DataSaveUtils(); + } + return instance; + } + + public interface UploadCallback { + public void onStart(); + public void onFinish(); + public void onError(); + } + + // 批量上传文件 + public void uploadFiles(Activity mContext, PoiEntity poiEntity, List poiPicList, UploadCallback callback) { + int auditId = poiEntity.getBodyId(); + File zipFile = new File(poiPicList.get(0).getParentFile(), auditId+".zip"); + Observable.create(new ObservableOnSubscribe() { + @Override + public void subscribe(ObservableEmitter emitter) throws Exception { + if (!zipFile.exists()) { + // 开始压缩文件 + ZipUtil.zipFiles(poiPicList, zipFile, "", null); + } + + emitter.onNext(zipFile); + emitter.onComplete(); + } + }) + .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.computation()) + // 切分数据,发送开始上传请求 + .map(new Function>() { + @Override + public Map apply(File file) throws Exception { + // 每次执行上传都会切分数据,因为都会执行第一步,向服务器请求需要上传的分包数据 + List splitFiles = FileSpliteMergeUtils.splitFile(file, Constant.DEFAULT_CUT_SIZE); + List chunkSizeList = new ArrayList<>(); + for (File f: splitFiles) { + chunkSizeList.add(f.length()); + } + CommonResponse response = createUploadTask(mContext, auditId, file.length(), chunkSizeList); + if (response!=null) { + // 请求成功,获取需要上传的分包index + String body = response.getBody(); + if (response.getCode() == 213) { // 该数据已经上传成功,自动切换该数据为已上传状态 + poiEntity.setTaskStatus(100); + PoiDatabase.getInstance(mContext).getPoiDao().updatePoiEntity(poiEntity); + ToastUtils.Message(mContext, "数据:"+poiEntity.getName()+"已成功上传!"); + } + if (body==null||body.isEmpty()) { + throw new Exception(response.getMessage()); + } + String[] needUploadStrIndex = body.split(","); + // 批量转换String为int + int[] needUploadIndex = new int[needUploadStrIndex.length]; + for (int i = 0; i < needUploadStrIndex.length; i++) { + needUploadIndex[i] = Integer.parseInt(needUploadStrIndex[i]); + } + // 根据返回的index,将需要上传的切分包数据流转到下一个流程 + Map needUploadFileMap = new HashMap<>(); + for (int index: needUploadIndex) { + if (index(); + } + } + }) + .flatMap(new Function, ObservableSource>>() { + @Override + public ObservableSource> apply(Map filesMap) throws Exception { + // 将每个切分的文件file作为发送者重新发送出去 + return Observable.fromIterable(filesMap.entrySet()); + } + }) + .doOnNext(new Consumer>() { + @Override + public void accept(Map.Entry fileEntry) throws Exception { + // 执行上传流程 + CommonResponse response = uploadSplitTask(mContext, auditId, fileEntry.getKey(), fileEntry.getValue()); + if (response.getCode() != 200) { + throw new Exception(response.getMessage()); + } else { + UMLog.mutlInfo(3, "已上传分包"+fileEntry.getKey()); + // 上传成功,则删除该分包数据 + if (fileEntry.getValue().exists()) { + fileEntry.getValue().delete(); + } + } + } + }) + .observeOn(AndroidSchedulers.mainThread()) + .toList() + .observeOn(Schedulers.io()) + // 调用执行成功的接口 + .doOnSuccess(new Consumer>>() { + @Override + public void accept(List> entries) throws Exception { + // 最终成功,调用finish接口 + CommonResponse response = uploadTaskFinish(mContext, auditId); + Message obtain1 = Message.obtain(); + obtain1.what = Constant.NEST_WORD_SUBMIT; + if (response.getCode() == 200) { // 更新成功,再次更新本地数据库 + ToastUtils.Message(mContext, "分包数据上传完成!"); + poiEntity.setTaskStatus(100); + PoiDatabase.getInstance(mContext).getPoiDao().updatePoiEntity(poiEntity); + // 提醒用户数据上传完成 + obtain1.obj = "数据:" + poiEntity.getName() + " 上传成功"; + // 同时删除关联的照片文件和压缩包文件 + if (zipFile.exists()) { + zipFile.delete(); + } + if (poiPicList!=null&&!poiPicList.isEmpty()) { + for (File picFile: poiPicList + ) { + picFile.delete(); + } + } + } else { + obtain1.obj = "数据:" + poiEntity.getName() + " 上传失败"; + } + EventBus.getDefault().post(obtain1); + } + }) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new SingleObserver>>() { + @Override + public void onSubscribe(Disposable d) { + callback.onStart(); + } + + @Override + public void onSuccess(List> entries) { + callback.onFinish(); + } + + @Override + public void onError(Throwable e) { + ToastUtils.Message(mContext, e.getMessage()); + callback.onError(); + callback.onFinish(); + } + }); + } + + /** + * 创建分包上传任务 + * */ + private CommonResponse createUploadTask(Activity mContext, int auditId, long fileSize, List chunkSize) { + HttpParams httpParams = new HttpParams(); + httpParams.put("auditId", auditId); + httpParams.put("fileSize", fileSize); + httpParams.put("chunkSize", list2Str(chunkSize)); + CommonRequestSend commonRequestSend = new CommonRequestSend>(); + CommonResponse response = commonRequestSend.getMethodCommonSync(mContext, HttpInterface.CREATE_UPLOAD_TASK, httpParams, Constant.DEFAULT_TIME_OUT, new CommonResponse().getClass()); + if (response!=null) { + if (response.getCode() == 200) { + return response; + } else { + ToastUtils.Message(mContext, response.getMessage()); + } + return response; + } + return null; + } + + /** + * 上传分包数据 + * */ + private CommonResponse uploadSplitTask(Activity mContext, int auditId, int chunkIndex, File splitFile) { + HttpParams httpParams = new HttpParams(); + httpParams.put("auditId", auditId); + httpParams.put("chunkIndex", chunkIndex); + httpParams.put("md5", MD5.md5sum(splitFile.getAbsolutePath()).toLowerCase()); + httpParams.put("file", splitFile); + +// List fileList = new ArrayList<>(); +// fileList.add(splitFile); + CommonRequestSend commonRequestSend = new CommonRequestSend>(); + CommonResponse response = commonRequestSend.postMethodCommonSync(mContext, HttpInterface.UPLOAD_SPLITE_TASK, httpParams, Constant.DEFAULT_TIME_OUT, null, new CommonResponse().getClass()); + if (response!=null) { + if (response.getCode() == 200) { + return response; + } else { + ToastUtils.Message(mContext, response.getMessage()); + } + return response; + } + return null; + } + /** + * 分包数据上传完成 + * */ + private CommonResponse uploadTaskFinish(Activity mContext, int auditId) { + HttpParams httpParams = new HttpParams(); + httpParams.put("auditId", auditId); + CommonRequestSend commonRequestSend = new CommonRequestSend>(); + CommonResponse response = commonRequestSend.getMethodCommonSync(mContext, HttpInterface.UPLOAD_TASK_FINISH, httpParams, Constant.DEFAULT_TIME_OUT, new CommonResponse().getClass()); + if (response!=null) { + if (response.getCode() == 200) { + return response; + } else { + ToastUtils.Message(mContext, response.getMessage()); + } + return response; + } + return null; + } + + public Observable savePoiEntity(Context mContext, PoiEntity poiEntity) { + return getPermission(mContext) + .subscribeOn(Schedulers.io()) + .map(new Function() { + @Override + public PoiEntity apply(Object o) { + return poiEntity; + } + }) + // 判断当前POI状态,根据状态处理随后的流程 + .map(new Function() { + @Override + public PoiEntity apply(PoiEntity entity) { + return null; + } + }); + } + + public Observable getPermission(Context mContext) { + return Observable.create( + new ObservableOnSubscribe() { + @Override + public void subscribe(ObservableEmitter emitter) throws Exception { + XXPermissions.with(mContext) + //读写权限 + .permission(Permission.MANAGE_EXTERNAL_STORAGE) + .request(new OnPermissionCallback() { + @Override + public void onGranted(List permissions, boolean all) { + if (all) { + emitter.onNext("permission Ok"); + } else { + emitter.onError(new Throwable("未获取文件访问权限,请确认!")); + } + } + + @Override + public void onDenied(List permissions, boolean never) { + if (never) { + emitter.onError(new Throwable("未获取文件访问权限,请确认!")); + } + } + }); + } + } + ); + } + + private String list2Str(List chunkSize) { + StringBuilder result = new StringBuilder(""); + for (Object chunk: chunkSize) { + result.append(chunk).append(","); + } + if (result.length()>0) { + return result.substring(0, result.length()-1); + } + return result.toString(); + } +} diff --git a/app/src/main/java/com/navinfo/outdoor/util/FileSpliteMergeUtils.kt b/app/src/main/java/com/navinfo/outdoor/util/FileSpliteMergeUtils.kt new file mode 100644 index 0000000..c24c0e0 --- /dev/null +++ b/app/src/main/java/com/navinfo/outdoor/util/FileSpliteMergeUtils.kt @@ -0,0 +1,150 @@ +package com.navinfo.outdoor.util + +import android.util.Log +import com.navinfo.outdoor.api.Constant +import java.io.File +import java.io.FileNotFoundException +import java.io.IOException +import java.io.RandomAccessFile +import java.lang.Exception + +/** + * @Author: LiaoZhongKai + * @Date: 2021/7/28 19:42 + * @Description: + */ +object FileSpliteMergeUtils { + const val TAG = "FileUtils" + //默认切割文件的大小 +// private const val DEFAULT_CUT_SIZE: Long = 5*1024*1024//5MB + private const val DEFAULT_CUT_SIZE: Long = Constant.DEFAULT_CUT_SIZE//5MB + + /** + * 分割文件 + * [sourceFile] 需要分割的源文件 + * [cutSize] 每个文件的大小 + * @return 分段文件集合 + */ + @JvmStatic + fun splitFile(sourceFile: File,cutSize: Long = DEFAULT_CUT_SIZE): List{ + //分段片文件集合 + val singleFileList = mutableListOf() + + val totalLength = sourceFile.length() + //分段数量 + val count = if(totalLength % cutSize == 0L) totalLength/cutSize else totalLength/cutSize +1 + Log.d(TAG,"split file count:$count") + val mRandomAccFile = RandomAccessFile(sourceFile,"r") + try { +// val length = mRandomAccFile.length() +// val singleSize = length/count//源文件分割后每个文件的大小 + var offSet = 0L + + for (i in 0 until count){//最后一个文件单独处理,因为它的大小可能不等于singleSize + val begin = offSet + // 如果当前index对应的数据没有超过文件大小,则使用cutSize,否则使用文件实际剩余大小 + var end = begin + cutSize + if (totalLength 0){//最后一个文件 +// val file = createSingleFile(sourceFile,count-1) +// writeFile(mRandomAccFile,file,offSet,length) +// singleFileList.add(file) +// } + + }catch (e: FileNotFoundException){ + e.printStackTrace() + }catch (e: IOException){ + e.printStackTrace() + }finally { + try { + mRandomAccFile.close() + }catch (e: IOException){ + e.printStackTrace() + } + } + return singleFileList + } + + private fun createSingleFile(sourceFile: File,index: Long): File{ + val path = sourceFile.absolutePath.substringBeforeLast(".") +// val suffix = sourceFile.name.substringAfterLast(".") + val suffix = "tmp"; + val file = File("${path}_${index}.${suffix}") + if (file.exists()){ + file.delete() + } + Log.d(TAG,"sourceFilePath:${sourceFile.absolutePath}") + file.createNewFile() + Log.d(TAG,"single file path:${file.absolutePath}") + return file + } + + private fun writeFile(inFile: RandomAccessFile,single: File,begin: Long,end: Long): Long{ + var endPointer = 0L + val out = RandomAccessFile(single,"rw") + try { + val byte = ByteArray(1024) + var index = 0 + inFile.seek(begin) + while (inFile.read(byte).also { index = it } != -1 && inFile.filePointer <= end){ + out.write(byte,0,index) + } + endPointer = inFile.filePointer + }catch (e: Exception){ + e.printStackTrace() + }finally { + out.close() + } + return endPointer - 1024//减1024是为了避免分割文件时丢包 + } + + /** + * 合并文件 + * [files] 需要合并的文件集合 + * [outputFilePath] 输出文件的路径 eg:D:/test + * [outputFileName] 输出文件的名称 eg:crawler.json + */ + @JvmStatic + fun mergeFile(files: List,outputFilePath: String,outputFileName: String){ + + val parentFile = File(outputFilePath) + val targetFile = File(outputFilePath+File.separator+outputFileName) + if (!parentFile.exists()){ + parentFile.mkdirs() + } + if (!targetFile.exists()){ + targetFile.createNewFile() + } + + val outRaf = RandomAccessFile(targetFile,"rw") + try { + files.forEach { file -> + val reader = RandomAccessFile(file,"r") + val byte = ByteArray(1024) + var index = 0 + while (reader.read(byte).also { index = it } != -1){ + outRaf.write(byte,0,index) + } + } + files.forEach { + if (it.exists()){ + it.delete() + } + } + Log.d(TAG,"merge output file path:${targetFile.absolutePath}") + }catch (e: IOException){ + e.printStackTrace() + }catch (e: FileNotFoundException){ + e.printStackTrace() + } + finally { + outRaf.close() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/outdoor/util/PoiSaveUtils.java b/app/src/main/java/com/navinfo/outdoor/util/PoiSaveUtils.java index d9a9a8f..470cf73 100644 --- a/app/src/main/java/com/navinfo/outdoor/util/PoiSaveUtils.java +++ b/app/src/main/java/com/navinfo/outdoor/util/PoiSaveUtils.java @@ -21,6 +21,7 @@ import com.navinfo.outdoor.room.ChargingPileEntity; import com.navinfo.outdoor.room.InsertAndUpdateUtils; import com.navinfo.outdoor.room.PoiDatabase; import com.navinfo.outdoor.room.PoiEntity; +import com.umeng.commonsdk.debug.UMLog; import org.greenrobot.eventbus.EventBus; @@ -256,24 +257,42 @@ public class PoiSaveUtils { bInt++; return; } - File fileZip = new File(Constant.PICTURE_FOLDER, "files" + ".zip"); - ZipUtil.zipFiles(videoFileList, fileZip, null); - photoFile.add(fileZip); + // 需要上传的文件都存在,开始调用分片上传接口上传附件数据 + DataSaveUtils.getInstance().uploadFiles(mContext, poiEntity, videoFileList, new DataSaveUtils.UploadCallback() { + @Override + public void onStart() { + + } + + @Override + public void onFinish() { + anInt++; + } + + @Override + public void onError() { + // 上传失败 + bInt++; + } + }); +// File fileZip = new File(Constant.PICTURE_FOLDER, "files" + ".zip"); +// ZipUtil.zipFiles(videoFileList, fileZip, null); +// photoFile.add(fileZip); } else { bInt++; return; } - if (photoFile.size() > 0) { - long zipTrueSize = ZipUtils.getZipTrueSize(photoFile.get(0).getAbsolutePath()); - if (zipTrueSize > 0) { - initList(HttpInterface.POI_VIDEO_UPLOAD_PIC, photoFile, poiEntity); - } else { - for (int i = 0; i < photoFile.size(); i++) { - photoFile.get(i).delete(); - } - bInt++; - } - } +// if (photoFile.size() > 0) { +// long zipTrueSize = ZipUtils.getZipTrueSize(photoFile.get(0).getAbsolutePath()); +// if (zipTrueSize > 0) { +// initList(HttpInterface.POI_VIDEO_UPLOAD_PIC, photoFile, poiEntity); +// } else { +// for (int i = 0; i < photoFile.size(); i++) { +// photoFile.get(i).delete(); +// } +// bInt++; +// } +// } } else if (poiEntity.getType() == 4) { List videoFileList = AWMp4ParserHelper.getInstance().getFileListByUUID(poiEntity.getId()); if (videoFileList != null && !videoFileList.isEmpty()) { @@ -282,27 +301,48 @@ public class PoiSaveUtils { bInt++; return; } - File fileZip = new File(Constant.PICTURE_FOLDER, "files" + ".zip"); - ZipUtil.zipFiles(videoFileList, fileZip, null); - photoFile.add(fileZip); + // 需要上传的文件都存在,开始调用分片上传接口上传附件数据 + DataSaveUtils.getInstance().uploadFiles(mContext, poiEntity, videoFileList, new DataSaveUtils.UploadCallback() { + @Override + public void onStart() { + + } + + @Override + public void onFinish() { + anInt++; + Log.d("TAGSS", "uploadPoiNet: 成功" + anInt); + } + + @Override + public void onError() { + // 上传失败 + bInt++; + Log.d("TAGSS", poiEntity.getBodyId()+"uploadPoiNet: 失败" + bInt); + UMLog.aq(1, poiEntity.getBodyId()+"uploadPoiNet: 失败", "文件上传失败"); + } + }); +// File fileZip = new File(Constant.PICTURE_FOLDER, "files" + ".zip"); +// ZipUtil.zipFiles(videoFileList, fileZip, null); +// photoFile.add(fileZip); } else { Log.d("TAGSS", "videoFileList: 失败" + bInt); bInt++; return; } - if (photoFile.size() > 0) { - long zipTrueSize = ZipUtils.getZipTrueSize(photoFile.get(0).getAbsolutePath()); - if (zipTrueSize > 0) { - initList(HttpInterface.ROAD_TASK_UPLOAD_PIC, photoFile, poiEntity); - } else { - Log.d("TAGSS", "photoFile: 失败" + bInt); - for (int i = 0; i < photoFile.size(); i++) { - photoFile.get(i).delete(); - } - bInt++; - return; - } - } +// if (photoFile.size() > 0) { +// long zipTrueSize = ZipUtils.getZipTrueSize(photoFile.get(0).getAbsolutePath()); +// if (zipTrueSize > 0) { +// initList(HttpInterface.ROAD_TASK_UPLOAD_PIC, photoFile, poiEntity); +// } else { +// Log.d("TAGSS", "photoFile: 失败" + bInt); +// for (int i = 0; i < photoFile.size(); i++) { +// photoFile.get(i).delete(); +// } +// bInt++; +// return; +// } +// } } else if (poiEntity.getType() == 5) { initList(HttpInterface.OTHER_TASK_UPLOAD_PIC, photoFile, poiEntity); } diff --git a/build.gradle b/build.gradle index f840db7..912a369 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext.anko_version = '0.10.1'//扩展库版本 + ext.kotlin_version = '1.5.10' repositories { google() jcenter() @@ -19,8 +20,8 @@ buildscript { } dependencies { classpath "com.android.tools.build:gradle:4.0.0" - - + //对kotlin支持 + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files