package com.dayu.pipirrapp.net;
|
|
import static com.luck.picture.lib.thread.PictureThreadUtils.runOnUiThread;
|
|
import android.content.Context;
|
import android.content.Intent;
|
import android.util.Log;
|
|
import com.dayu.pipirrapp.MyApplication;
|
import com.dayu.pipirrapp.activity.LoginActivity;
|
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.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.ProgressListener;
|
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 com.google.gson.Gson;
|
import com.google.gson.internal.LinkedTreeMap;
|
|
import java.io.File;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
import io.reactivex.rxjava3.core.Observable;
|
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;
|
|
|
/**
|
* Copyright (C), 2023,
|
* Author: zuot
|
* Date: 2023-04-12 9:11
|
* Description:
|
*/
|
public class ApiManager {
|
|
static String TAG = "ApiManager";
|
|
static ApiManager apiManager;
|
//文件上传失败重复次数
|
int uplodFilerepeatSize = 3;
|
|
ApiService apiService;
|
private CompositeDisposable compositeDisposable = new CompositeDisposable(); // 管理订阅事件
|
|
/**
|
* 初始化通信框架
|
*/
|
public static void init() {
|
if (apiManager == null) {
|
apiManager = new ApiManager();
|
}
|
}
|
|
public ApiManager() {
|
apiService = RetrofitClient.getInstance().getApiService();
|
|
}
|
|
public static ApiManager getInstance() {
|
return apiManager;
|
}
|
|
|
public <T> void requestPostLoading(final Context context, final String path, final Class<T> tClass, final Map<String, Object> params, final SubscriberListener listener) {
|
request(context, false, path, false, tClass, params, listener);
|
}
|
|
public <T> void requestPostHideLoading(final Context context, final String path, final Class<T> tClass, final Map<String, Object> params, final SubscriberListener listener) {
|
request(context, true, path, false, tClass, params, listener);
|
}
|
|
public <T> void requestPost(final Context context, final String path, final Class<T> tClass, final Map<String, Object> params, final SubscriberListener listener) {
|
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);
|
}
|
|
/**
|
* 发送请求
|
*
|
* @param context
|
* @param hideLoading 是否显示加载框 false:显示 true:隐藏
|
* @param path 请求路径,在UrlConfig中定义
|
* @param isGet 是否是Get请求 true:get 请求
|
* @param tClass 对应的数据类型
|
* @param params Post请求时,对应的参数
|
* @param listener 回调请求
|
* @param <T>
|
*/
|
public <T> void request(final Context context, final boolean hideLoading, final String path, final boolean isGet, final Class<T> tClass, final Map<String, Object> params, final SubscriberListener listener) {
|
Observable observable;
|
BaseProgressSubscriber<?> mySubscriber;
|
|
|
if (isGet) {
|
if (params == null) {
|
observable = apiService.requestGet(path, MyApplication.myApplication.token);
|
} else {
|
observable = apiService.requestGet(path, params, MyApplication.myApplication.token);
|
}
|
} else {
|
observable = apiService.requestPost(path, params);
|
}
|
|
mySubscriber = new ProgressSubscriber(context, hideLoading, listener);
|
observable.subscribeOn(Schedulers.io()).
|
map(new Function<Object, BaseResponse<T>>() {
|
@Override
|
public BaseResponse<T> apply(Object o) {
|
if (o instanceof BaseResponse) {
|
BaseResponse tem = (BaseResponse) o;
|
if (tem.getCode().equals("0000")) {
|
//当code为0000是跳转到登录界面
|
tem.setMsg("登录失效请重新登录");
|
redirectToLogin();
|
return tem;
|
}
|
BaseResponse<T> response = new BaseResponse<>();
|
response.setCode(tem.getCode());
|
response.setMsg(tem.getMsg());
|
|
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());
|
}
|
}
|
return response;
|
}
|
|
return null;
|
}
|
})
|
.unsubscribeOn(Schedulers.newThread())
|
.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 data 经纬度(格式是 纬度:经度,英文冒号分隔)
|
* @param callback
|
* @param <T>
|
*/
|
public <T> void requestWeather(String data, Callback<WeatherResponse> callback) {
|
Map<String, Object> params = new HashMap<>();
|
params.put("key", "S6Tq4pvOakMuWRrg0");
|
params.put("location", data);
|
params.put("language", "zh-Hans");
|
params.put("unit", "c");
|
params.put("days", "3");
|
Call<WeatherResponse> call = apiService.requestWeather("https://api.seniverse.com/v3/weather/daily.json", params);
|
call.enqueue(callback);
|
}
|
|
|
/**
|
* 获取验证码
|
*
|
* @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
|
*/
|
public void donwLoadTile(Context context, String urlPath) {
|
if (NetUtils.isNetworkAvailable(context)) {
|
Observable<ResponseBody> observable;
|
observable = apiService.downloadTile(urlPath);
|
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)
|
);
|
} else {
|
Log.e(TAG, "没有网络不下载: " + urlPath);
|
}
|
}
|
|
// 停止线程池,释放资源
|
public void clearDisposables() {
|
if (!compositeDisposable.isDisposed()) {
|
compositeDisposable.dispose();
|
}
|
}
|
|
|
/**
|
* 上传文件
|
*
|
* @param context
|
* @param uplodData
|
* @param listener
|
*/
|
public void uploadFile(final Context context, final UplodFileState uplodData, final UploadFileListener listener) {
|
|
File file = new File(uplodData.getFilePath());
|
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
|
ProgressRequestBody progressRequestBody = new ProgressRequestBody(requestBody, new ProgressListener() {
|
@Override
|
public void onProgress(long bytesWritten, long contentLength, boolean done) {
|
// 更新进度条或进行其他操作
|
int progress = (int) (100 * bytesWritten / contentLength);
|
// 例如:更新 ProgressBar 或显示进度
|
runOnUiThread(() -> {
|
// 进度条更新代码
|
// progressBar.setProgress(progress);
|
MyLog.d("progressRequestBody>>>" + "上传进度: " + progress + "%");
|
});
|
}
|
});
|
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), progressRequestBody);
|
RequestBody description = RequestBody.create(MediaType.parse("text/plain"), "file description");
|
apiService.uploadFile(body, description).enqueue(new Callback<BaseResponse>() {
|
@Override
|
public void onResponse(Call<BaseResponse> call, Response<BaseResponse> response) {
|
if (response.body() != null) {
|
if (response.body().isSuccess()) {
|
uplodData.setState(1);
|
uplodData.setId(((LinkedTreeMap) response.body().getContent()).get("id").toString());
|
uplodData.setWebPath(((LinkedTreeMap) response.body().getContent()).get("webPath").toString());
|
listener.onBack(uplodData);
|
} else {
|
if (uplodData.getNumber() <= uplodFilerepeatSize) {
|
uplodData.setNumber(uplodData.getNumber() + 1);
|
uplodData.setState(2);
|
uploadFile(context, uplodData, listener);
|
} else {
|
listener.onBack(uplodData);
|
}
|
}
|
}
|
}
|
|
@Override
|
public void onFailure(Call<BaseResponse> call, Throwable t) {
|
if (uplodData.getNumber() <= uplodFilerepeatSize) {
|
uplodData.setNumber(uplodData.getNumber() + 1);
|
uplodData.setState(2);
|
uploadFile(context, uplodData, listener);
|
} else {
|
listener.onBack(uplodData);
|
}
|
}
|
});
|
}
|
|
/**
|
* 判断当前code是否是未登录状态
|
*
|
* @param responseBody the response body in JSON format
|
* @return true if login is required, false otherwise
|
*/
|
private boolean isLoginRequired(String responseBody) {
|
try {
|
Gson gson = new Gson();
|
Map<String, Object> responseMap = gson.fromJson(responseBody, Map.class);
|
String code = (String) responseMap.get("code");
|
return "0000".equals(code); // Check if the code is not 0000
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return false;
|
}
|
|
/**
|
* 当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);
|
}
|
}
|