|  |  | 
 |  |  | package com.dayu.pipirrapp.net; | 
 |  |  |  | 
 |  |  | import static com.dayu.pipirrapp.bean.net.UplodFileState.STATE_DONE; | 
 |  |  | import static com.dayu.pipirrapp.bean.net.UplodFileState.STATE_ERROR; | 
 |  |  | import static com.dayu.pipirrapp.bean.net.UplodFileState.STATE_UPDING; | 
 |  |  | import static com.luck.picture.lib.thread.PictureThreadUtils.runOnUiThread; | 
 |  |  |  | 
 |  |  | import android.annotation.SuppressLint; | 
 |  |  | import android.content.Context; | 
 |  |  | import android.content.Intent; | 
 |  |  | import android.text.TextUtils; | 
 |  |  | import android.util.Log; | 
 |  |  |  | 
 |  |  | import com.dayu.pipirrapp.bean.WeatherResponse; | 
 |  |  | import com.dayu.pipirrapp.MyApplication; | 
 |  |  | import com.dayu.pipirrapp.activity.LoginActivity; | 
 |  |  | import com.dayu.pipirrapp.adapter.AddPictureAdapter; | 
 |  |  | import com.dayu.pipirrapp.bean.net.CodeResult; | 
 |  |  | import com.dayu.pipirrapp.bean.net.UplodFileState; | 
 |  |  | import com.dayu.pipirrapp.bean.net.WeatherResponse; | 
 |  |  | import com.dayu.pipirrapp.bean.net.UploadFileResult; | 
 |  |  | import com.dayu.pipirrapp.net.subscribers.BaseProgressSubscriber; | 
 |  |  | import com.dayu.pipirrapp.net.subscribers.CodeListener; | 
 |  |  | import com.dayu.pipirrapp.net.subscribers.ProgressSubscriber; | 
 |  |  | import com.dayu.pipirrapp.net.subscribers.SubscriberListener; | 
 |  |  | import com.dayu.pipirrapp.net.upload.ProgressRequestBody; | 
 |  |  | import com.dayu.pipirrapp.net.upload.UploadFileListener; | 
 |  |  | import com.dayu.pipirrapp.utils.CleanDataUtils; | 
 |  |  | import com.dayu.pipirrapp.utils.MapJpgUtils; | 
 |  |  | import com.dayu.pipirrapp.utils.MyJsonParser; | 
 |  |  | import com.dayu.pipirrapp.utils.MyLog; | 
 |  |  | import com.dayu.pipirrapp.utils.NetUtils; | 
 |  |  |  | 
 |  |  | import java.io.File; | 
 |  |  | import java.util.HashMap; | 
 |  |  | import java.util.List; | 
 |  |  | import java.util.Map; | 
 |  |  | 
 |  |  | import io.reactivex.rxjava3.disposables.CompositeDisposable; | 
 |  |  | import io.reactivex.rxjava3.functions.Function; | 
 |  |  | import io.reactivex.rxjava3.schedulers.Schedulers; | 
 |  |  | import okhttp3.MediaType; | 
 |  |  | import okhttp3.MultipartBody; | 
 |  |  | import okhttp3.RequestBody; | 
 |  |  | import okhttp3.ResponseBody; | 
 |  |  | import retrofit2.Call; | 
 |  |  | import retrofit2.Callback; | 
 |  |  | import retrofit2.Response; | 
 |  |  |  | 
 |  |  |  | 
 |  |  | /** | 
 |  |  | 
 |  |  |     //文件上传失败重复次数 | 
 |  |  |     int uplodFilerepeatSize = 3; | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     ApiService apiService; | 
 |  |  |     private CompositeDisposable compositeDisposable = new CompositeDisposable(); // 管理订阅事件 | 
 |  |  |     // 管理订阅事件 | 
 |  |  |     private final CompositeDisposable compositeDisposable = new CompositeDisposable(); | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 初始化通信框架 | 
 |  |  | 
 |  |  |         request(context, false, path, false, tClass, params, listener); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public <T> void requestGet(final Context context, final String path, final Class<T> tClass, final Map<String, Object> params, final SubscriberListener listener) { | 
 |  |  |         request(context, false, path, true, tClass, params, listener); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public <T> void requestGetHideLoading(final Context context, final String path, final Class<T> tClass, final Map<String, Object> params, final SubscriberListener listener) { | 
 |  |  |         request(context, true, path, true, tClass, params, listener); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 发送请求 | 
 |  |  |      * | 
 |  |  | 
 |  |  |  | 
 |  |  |         if (isGet) { | 
 |  |  |             if (params == null) { | 
 |  |  |                 observable = apiService.requestGet(path); | 
 |  |  |                 observable = apiService.requestGet(path, MyApplication.myApplication.token); | 
 |  |  |             } else { | 
 |  |  |  | 
 |  |  |                 observable = apiService.requestGet(path, params); | 
 |  |  |                 observable = apiService.requestGet(path, params, MyApplication.myApplication.token); | 
 |  |  |             } | 
 |  |  |         } else { | 
 |  |  |             observable = apiService.requestPost(path, params); | 
 |  |  | 
 |  |  |                     public BaseResponse<T> apply(Object o) { | 
 |  |  |                         if (o instanceof BaseResponse) { | 
 |  |  |                             BaseResponse tem = (BaseResponse) o; | 
 |  |  |                             if (tem.getCode().equals(Constants.TOKEN_INVALID)) { | 
 |  |  |                                 //当code为0000是跳转到登录界面 | 
 |  |  |                                 tem.setMsg("登录失效请重新登录"); | 
 |  |  |                                 redirectToLogin(); | 
 |  |  |                                 return tem; | 
 |  |  |                             } | 
 |  |  |                             BaseResponse<T> response = new BaseResponse<>(); | 
 |  |  |                             response.setCode(tem.getCode()); | 
 |  |  |                             response.setMsg(tem.getMsg()); | 
 |  |  |  | 
 |  |  |                             if (tClass != null && tem.getContent() instanceof Map) { | 
 |  |  |                                 try { | 
 |  |  | //                                    response.setData(MyJsonParser.getBeanFromMap((Map<String, Object>) tem.getData(), tClass)); | 
 |  |  |                                     String jsonData = MyJsonParser.getJsontoMap((Map) tem.getContent()); | 
 |  |  |                                     response.setContent(MyJsonParser.getBeanFromJson(jsonData, tClass)); | 
 |  |  |                                 } catch (Exception e) { | 
 |  |  |                                     e.printStackTrace(); | 
 |  |  |                                 } | 
 |  |  |                             } else if (tClass != null && tem.getContent() instanceof List) { | 
 |  |  |                                 try { | 
 |  |  |                                     response.setContent((T) MyJsonParser.getListByJson(MyJsonParser.getJsonbyList((List) tem.getContent()), tClass)); | 
 |  |  |                                 } catch (Exception e) { | 
 |  |  |                                     e.printStackTrace(); | 
 |  |  |                                 } | 
 |  |  |                             } else if (tClass != null && tem.getContent() instanceof Integer) { | 
 |  |  |                                 response.setContent((T) tem.getContent()); | 
 |  |  |                             if (!TextUtils.isEmpty(tem.getMsg())) { | 
 |  |  |                                 response.setMsg(tem.getMsg()); | 
 |  |  |                             } else { | 
 |  |  |                                 response.setMsg(""); | 
 |  |  |                             } | 
 |  |  |                             if (tClass != null && tClass.getName() instanceof String && tem.getContent() instanceof String) { | 
 |  |  |                                 try { | 
 |  |  |  | 
 |  |  |  | 
 |  |  |                             if (tClass != null) { | 
 |  |  |                                 if (tem.getContent() instanceof Map) { | 
 |  |  |                                     response.setContent(parseMapContent(tem.getContent(), tClass)); | 
 |  |  |                                 } else if (tem.getContent() instanceof List) { | 
 |  |  |                                     response.setContent(parseListContent(tem.getContent(), tClass)); | 
 |  |  |                                 } else if (tem.getContent() instanceof Integer || tem.getContent() instanceof String) { | 
 |  |  |                                     response.setContent((T) tem.getContent()); | 
 |  |  |                                 } catch (Exception e) { | 
 |  |  |                                     e.printStackTrace(); | 
 |  |  |                                 } | 
 |  |  |                             } | 
 |  |  |                             return response; | 
 |  |  |  | 
 |  |  |  | 
 |  |  |                         } | 
 |  |  |  | 
 |  |  |                         return null; | 
 |  |  | 
 |  |  |                 .observeOn(AndroidSchedulers.mainThread()) | 
 |  |  |                 .subscribe(mySubscriber); | 
 |  |  |  | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     // 解析 Map 类型的数据 | 
 |  |  |     private <T> T parseMapContent(Object content, Class<T> tClass) { | 
 |  |  |         try { | 
 |  |  |             String jsonData = MyJsonParser.getJsontoMap((Map<String, Object>) content); | 
 |  |  |             return MyJsonParser.getBeanFromJson(jsonData, tClass); | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             Log.e(TAG, "Error parsing map content", e); | 
 |  |  |             return null; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     // 解析 List 类型的数据 | 
 |  |  |     private <T> T parseListContent(Object content, Class<T> tClass) { | 
 |  |  |         try { | 
 |  |  |             String jsonData = MyJsonParser.getJsonbyList((List<?>) content); | 
 |  |  |             return (T) MyJsonParser.getListByJson(jsonData, tClass); | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             Log.e(TAG, "Error parsing list content", e); | 
 |  |  |             return null; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 获取验证码 | 
 |  |  |      * | 
 |  |  |      * @param params | 
 |  |  |      * @param listener | 
 |  |  |      * @param <T> | 
 |  |  |      */ | 
 |  |  |     public <T> void getCode(Map<String, Object> params, CodeListener listener) { | 
 |  |  |         if (NetUtils.isNetworkAvailable(MyApplication.myApplication)) { | 
 |  |  |             Observable observable; | 
 |  |  |             observable = apiService.getCode(params); | 
 |  |  |             observable.subscribeOn(Schedulers.io()) | 
 |  |  |                     .unsubscribeOn(Schedulers.newThread()) | 
 |  |  |                     .observeOn(AndroidSchedulers.mainThread()) | 
 |  |  |                     .subscribe(responseBody -> { | 
 |  |  |                         listener.onNext((CodeResult) responseBody); | 
 |  |  |                     }, throwable -> { | 
 |  |  |                         listener.error((Throwable) throwable); | 
 |  |  |                     }); | 
 |  |  |         } else { | 
 |  |  |             listener.onNext(null); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 下载地图瓦片 | 
 |  |  |      * | 
 |  |  |      * @param urlPath | 
 |  |  |      */ | 
 |  |  |     @SuppressLint("CheckResult") | 
 |  |  |     public void donwLoadTile(Context context, String urlPath) { | 
 |  |  |         Observable<ResponseBody> observable; | 
 |  |  |         observable = apiService.downloadTile(urlPath); | 
 |  |  |         if (NetUtils.isNetworkAvailable(context)) { | 
 |  |  |             Observable<ResponseBody> observable; | 
 |  |  |             observable = apiService.downloadTile(urlPath); | 
 |  |  |             observable | 
 |  |  |                     // 网络请求在 I/O 线程中进行 | 
 |  |  |                     .subscribeOn(Schedulers.io()) | 
 |  |  |                     // 回调处理也在 I/O 线程 | 
 |  |  |                     .observeOn(Schedulers.io()) | 
 |  |  |                     .subscribe( | 
 |  |  |                             responseBody -> { | 
 |  |  |  | 
 |  |  |  | 
 |  |  |         compositeDisposable.add( | 
 |  |  |                 observable | 
 |  |  |                         .subscribeOn(Schedulers.io())  // 网络请求在 I/O 线程中进行 | 
 |  |  |                         .observeOn(Schedulers.io())    // 回调处理也在 I/O 线程 | 
 |  |  |                         .subscribe( | 
 |  |  |                                 responseBody -> { | 
 |  |  |                                     boolean success = false; | 
 |  |  |                                     if (!MapJpgUtils.getInsatance(context).isHasFiles(urlPath)) { | 
 |  |  |                                         success = MapJpgUtils.getInsatance(context).saveTileToCache(urlPath, responseBody); | 
 |  |  |                                     } | 
 |  |  |                                     if (success) { | 
 |  |  |                                         Log.d(TAG, "Download success for tile: " + urlPath); | 
 |  |  |                                     } else { | 
 |  |  |                                         Log.e(TAG, "Failed to save tile to disk: " + urlPath); | 
 |  |  |                                     } | 
 |  |  |                                 }, | 
 |  |  |                                 throwable -> Log.e(TAG, "Download failed for tile: " + urlPath) | 
 |  |  |                         ) | 
 |  |  |         ); | 
 |  |  |  | 
 |  |  |  | 
 |  |  |                                 boolean success = false; | 
 |  |  |                                 if (!MapJpgUtils.getInsatance().isHasFiles(urlPath)) { | 
 |  |  |                                     success = MapJpgUtils.getInsatance().saveTileToCache(urlPath, responseBody); | 
 |  |  |                                 } | 
 |  |  |                                 if (success) { | 
 |  |  |                                     Log.d(TAG, "Download success for tile: " + urlPath); | 
 |  |  |                                 } else { | 
 |  |  |                                     Log.e(TAG, "Failed to save tile to disk: " + urlPath); | 
 |  |  |                                 } | 
 |  |  |                             }, | 
 |  |  |                             throwable -> Log.e(TAG, "Download failed for tile: " + urlPath) | 
 |  |  |                     ); | 
 |  |  |         } else { | 
 |  |  |             Log.e(TAG, "没有网络不下载: " + urlPath); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     // 停止线程池,释放资源 | 
 |  |  | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  | //    public void uploadFile(final Context context, final UplodFileState uplodData, final UploadFileListener listener) { | 
 |  |  | //        uploadFile(context, uplodData, listener, null); | 
 |  |  | //    } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 上传图片文件 | 
 |  |  |      * | 
 |  |  |      * @param context | 
 |  |  |      * @param uplodData | 
 |  |  |      * @param listener | 
 |  |  |      */ | 
 |  |  |     public void uploadFile(final Context context, final UplodFileState uplodData, final UploadFileListener listener, final AddPictureAdapter adapter) { | 
 |  |  |  | 
 |  |  |         if (!TextUtils.isEmpty(uplodData.getFilePath())) { | 
 |  |  |             MyLog.d("progressRequestBody_uploadFile>>>" + "path:" + uplodData.getFilePath() + ">>>uploadType:" + uplodData.getUploadType()); | 
 |  |  |             uplodData.setState(STATE_UPDING); | 
 |  |  |             File file = new File(uplodData.getFilePath()); | 
 |  |  |             RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file); | 
 |  |  |             ProgressRequestBody progressRequestBody = new ProgressRequestBody(requestBody, (bytesWritten, contentLength, done) -> { | 
 |  |  | //            MyLog.d("progressRequestBody>>>" + "bytesWritten:" + bytesWritten + ">>>contentLength: " + contentLength ); | 
 |  |  |                 // 更新进度条或进行其他操作 | 
 |  |  |                 int progress = (int) (100 * bytesWritten / contentLength); | 
 |  |  |                 // 例如:更新 ProgressBar 或显示进度 | 
 |  |  |                 runOnUiThread(() -> { | 
 |  |  |                     if (progress <5) { | 
 |  |  |                         uplodData.setProgress(0); | 
 |  |  |                     } | 
 |  |  |                     // 进度条更新代码 | 
 |  |  |                     if (adapter != null && uplodData.getAdapterPosition() != -1) { | 
 |  |  |                         //优化不频繁更新进度 | 
 |  |  |                         if (progress - uplodData.getProgress() > 5 || progress == 100) { | 
 |  |  |                             uplodData.setProgress(progress); | 
 |  |  |                             adapter.updateProgress(uplodData); | 
 |  |  |  | 
 |  |  |                         } | 
 |  |  |  | 
 |  |  |                     } | 
 |  |  |                     MyLog.d("progressRequestBodyHolder>>>path" + "adapterPosition:" + uplodData.getAdapterPosition() + ">>>上传进度: " + progress + "%"); | 
 |  |  |                 }); | 
 |  |  |  | 
 |  |  |             }); | 
 |  |  |             MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), progressRequestBody); | 
 |  |  |             RequestBody description = RequestBody.create(MediaType.parse("text/plain"), "file description"); | 
 |  |  |             Call<BaseResponse<UploadFileResult>> uploadFile = null; | 
 |  |  |             switch (uplodData.getUploadType()) { | 
 |  |  |                 case UplodFileState.IMG_TYPE: | 
 |  |  |                     uploadFile = apiService.uploadImgFile(body, description); | 
 |  |  |                     break; | 
 |  |  |                 case UplodFileState.VIDEO_TYPE: | 
 |  |  |                     uploadFile = apiService.uploadVideoFile(body, description); | 
 |  |  |                     break; | 
 |  |  |                 default: | 
 |  |  |                     uploadFile = apiService.uploadImgFile(body, description); | 
 |  |  |                     break; | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             uplodData.setThisCall(uploadFile); | 
 |  |  |             uploadFile.enqueue(new Callback<BaseResponse<UploadFileResult>>() { | 
 |  |  |                 @Override | 
 |  |  |                 public void onResponse(Call<BaseResponse<UploadFileResult>> call, Response<BaseResponse<UploadFileResult>> response) { | 
 |  |  |                     if (response.body() != null) { | 
 |  |  |                         if (response.body().isSuccess()) { | 
 |  |  |                             UploadFileResult uploadFileResult=response.body().getContent(); | 
 |  |  |                             uplodData.setState(STATE_DONE); | 
 |  |  |                             uplodData.setPostId(uploadFileResult.getId()); | 
 |  |  |                             uplodData.setUoloadFilePath(uploadFileResult.getFilePath()); | 
 |  |  |                             uplodData.setHash(uploadFileResult.getHash()); | 
 |  |  |                             uplodData.setWebPathZip(uploadFileResult.getWebPathZip()); | 
 |  |  |                             listener.onBack(uplodData); | 
 |  |  |                         } else { | 
 |  |  |                             MyLog.d("progressRequestBody>>>" + response.body().getMsg()); | 
 |  |  |                             if (uplodData.getNumber() <= uplodFilerepeatSize) { | 
 |  |  |                                 uplodData.setNumber(uplodData.getNumber() + 1); | 
 |  |  |                                 uplodData.setState(STATE_ERROR); | 
 |  |  |                                 uploadFile(context, uplodData, listener, adapter); | 
 |  |  |                             } else { | 
 |  |  |                                 uplodData.setState(STATE_ERROR); | 
 |  |  |                                 uplodData.setNumber(0); | 
 |  |  |                                 listener.onBack(uplodData); | 
 |  |  |                             } | 
 |  |  |                         } | 
 |  |  |                     } | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 @Override | 
 |  |  |                 public void onFailure(Call<BaseResponse<UploadFileResult>> call, Throwable t) { | 
 |  |  |                     MyLog.d("progressRequestBody>>>" + "onFailure:" + t.getMessage()); | 
 |  |  |                     if (!t.getMessage().equals("Canceled")) { | 
 |  |  |                         uplodData.setState(STATE_ERROR); | 
 |  |  |                         if (uplodData.getNumber() <= uplodFilerepeatSize) { | 
 |  |  |                             uplodData.setNumber(uplodData.getNumber() + 1); | 
 |  |  |                             uploadFile(context, uplodData, listener, adapter); | 
 |  |  |                         } else { | 
 |  |  |                             uplodData.setNumber(0); | 
 |  |  |                             listener.onBack(uplodData); | 
 |  |  |                         } | 
 |  |  |                     } | 
 |  |  |  | 
 |  |  |                 } | 
 |  |  |             }); | 
 |  |  |         } else { | 
 |  |  |             uplodData.setState(STATE_ERROR); | 
 |  |  |             listener.onBack(uplodData); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 当code为“0000”时跳转到登录界面 | 
 |  |  |      */ | 
 |  |  |     private void redirectToLogin() { | 
 |  |  |  | 
 |  |  |         Context context = MyApplication.myApplication.getApplicationContext(); | 
 |  |  |         CleanDataUtils.cleanUserData(context); | 
 |  |  |         Intent intent = new Intent(context, LoginActivity.class); // Assuming LoginActivity is your login screen | 
 |  |  |         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); // Clear task stack | 
 |  |  |         context.startActivity(intent); | 
 |  |  |     } | 
 |  |  | } |