|  |  | 
 |  |  | 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.net.ConnectivityManager; | 
 |  |  | import android.net.NetworkCapabilities; | 
 |  |  | import android.net.NetworkInfo; | 
 |  |  | import android.os.Build; | 
 |  |  | import android.content.Intent; | 
 |  |  | import android.text.TextUtils; | 
 |  |  | import android.util.Log; | 
 |  |  |  | 
 |  |  | 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; | 
 |  |  | 
 |  |  |     //文件上传失败重复次数 | 
 |  |  |     int uplodFilerepeatSize = 3; | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     ApiService apiService; | 
 |  |  |     private CompositeDisposable compositeDisposable = new CompositeDisposable(); // 管理订阅事件 | 
 |  |  |     // 管理订阅事件 | 
 |  |  |     private final CompositeDisposable compositeDisposable = new CompositeDisposable(); | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 初始化通信框架 | 
 |  |  | 
 |  |  |     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); | 
 |  |  |     } | 
 |  |  | 
 |  |  |                     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 (!TextUtils.isEmpty(tem.getMsg())) { | 
 |  |  |                                 response.setMsg(tem.getMsg()); | 
 |  |  |                             } else { | 
 |  |  |                                 response.setMsg(""); | 
 |  |  |                             } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |                             if (tClass != null) { | 
 |  |  |                                 if (tem.getContent() instanceof Map) { | 
 |  |  | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 获取天气 | 
 |  |  |      * | 
 |  |  | 
 |  |  |      * @param <T> | 
 |  |  |      */ | 
 |  |  |     public <T> void getCode(Map<String, Object> params, CodeListener listener) { | 
 |  |  |         if (isNetworkAvailable(MyApplication.myApplication)) { | 
 |  |  |         if (NetUtils.isNetworkAvailable(MyApplication.myApplication)) { | 
 |  |  |             Observable observable; | 
 |  |  |             observable = apiService.getCode(params); | 
 |  |  |             observable.subscribeOn(Schedulers.io()) | 
 |  |  | 
 |  |  |      * | 
 |  |  |      * @param urlPath | 
 |  |  |      */ | 
 |  |  |     public void donwLoadTile(String urlPath) { | 
 |  |  |         Observable<ResponseBody> observable; | 
 |  |  |         observable = apiService.downloadTile(urlPath); | 
 |  |  |     @SuppressLint("CheckResult") | 
 |  |  |     public void donwLoadTile(Context context, String 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().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) | 
 |  |  |                 ); | 
 |  |  | //        ); | 
 |  |  |  | 
 |  |  |  | 
 |  |  |                                 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); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     // 停止线程池,释放资源 | 
 |  |  | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 判断当前是否有网络 | 
 |  |  |      * | 
 |  |  |      * @param context | 
 |  |  |      * @return | 
 |  |  |      */ | 
 |  |  |     public boolean isNetworkAvailable(Context context) { | 
 |  |  |         ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); | 
 |  |  |  | 
 |  |  |         if (connectivityManager != null) { | 
 |  |  |             // 对于 Android 版本大于等于 Android Q (API level 29) | 
 |  |  |             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { | 
 |  |  |                 NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork()); | 
 |  |  |                 if (capabilities != null) { | 
 |  |  |                     // 检查网络是否有传输能力(包括 Wi-Fi 和移动数据) | 
 |  |  |                     if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { | 
 |  |  |                         return true; | 
 |  |  |                     } | 
 |  |  |                 } | 
 |  |  |             } else { | 
 |  |  |                 // 对于 Android Q 以下版本 | 
 |  |  |                 NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); | 
 |  |  |                 if (activeNetworkInfo != null && activeNetworkInfo.isConnected()) { | 
 |  |  |                     return true; | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         return false;  // 无网络连接 | 
 |  |  |     } | 
 |  |  | //    public void uploadFile(final Context context, final UplodFileState uplodData, final UploadFileListener listener) { | 
 |  |  | //        uploadFile(context, uplodData, listener, null); | 
 |  |  | //    } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 上传文件 | 
 |  |  |      * 上传图片文件 | 
 |  |  |      * | 
 |  |  |      * @param context | 
 |  |  |      * @param file | 
 |  |  |      * @param uplodData | 
 |  |  |      * @param listener | 
 |  |  |      */ | 
 |  |  |     public void uploadFile(final Context context, final UplodFileState file, final UploadFileListener listener) { | 
 |  |  |     public void uploadFile(final Context context, final UplodFileState uplodData, final UploadFileListener listener, final AddPictureAdapter adapter) { | 
 |  |  |  | 
 |  |  |         // 创建 RequestBody,用于封装构建RequestBody | 
 |  |  |         RequestBody requestFile = | 
 |  |  |                 RequestBody.create(MediaType.parse("multipart/form-data"), file.getFile()); | 
 |  |  |         // MultipartBody.Part  和后端约定好Key,这里的partName是用image | 
 |  |  |         MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getFile().getName(), requestFile); | 
 |  |  |         // 添加描述 | 
 |  |  |         String descriptionString = "hello, 这是文件描述"; | 
 |  |  |         RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), descriptionString); | 
 |  |  |         apiService.uploadFile(description, body).enqueue(new Callback<BaseResponse>() { | 
 |  |  |             @Override | 
 |  |  |             public void onResponse(Call<BaseResponse> call, Response<BaseResponse> response) { | 
 |  |  |                 if (response.body() != null) { | 
 |  |  |                     if (response.body().isSuccess()) { | 
 |  |  |                         file.setState(1); | 
 |  |  |                         file.setUrl(response.body().getMsg()); | 
 |  |  |                         listener.onBack(file); | 
 |  |  |                     } else { | 
 |  |  |                         if (file.getNumber() <= uplodFilerepeatSize) { | 
 |  |  |                             file.setNumber(file.getNumber() + 1); | 
 |  |  |                             file.setState(2); | 
 |  |  |                             uploadFile(context, file, listener); | 
 |  |  |         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 { | 
 |  |  |                             listener.onBack(file); | 
 |  |  |                             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> call, Throwable t) { | 
 |  |  |                 if (file.getNumber() <= uplodFilerepeatSize) { | 
 |  |  |                     file.setNumber(file.getNumber() + 1); | 
 |  |  |                     file.setState(2); | 
 |  |  |                     uploadFile(context, file, listener); | 
 |  |  |                 } else { | 
 |  |  |                     listener.onBack(file); | 
 |  |  |                 @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); | 
 |  |  |     } | 
 |  |  | } |