344 lines
14 KiB
Java
344 lines
14 KiB
Java
package com.ttstd.dialer.manager;
|
||
|
||
import android.annotation.SuppressLint;
|
||
import android.content.Context;
|
||
import android.os.Build;
|
||
import android.text.TextUtils;
|
||
|
||
import com.jeremyliao.liveeventbus.LiveEventBus;
|
||
import com.qweather.sdk.Callback;
|
||
import com.qweather.sdk.JWTGenerator;
|
||
import com.qweather.sdk.QWeather;
|
||
import com.qweather.sdk.basic.Lang;
|
||
import com.qweather.sdk.basic.Unit;
|
||
import com.qweather.sdk.parameter.weather.WeatherParameter;
|
||
import com.qweather.sdk.response.error.ErrorResponse;
|
||
import com.qweather.sdk.response.weather.WeatherDailyResponse;
|
||
import com.qweather.sdk.response.weather.WeatherHourlyResponse;
|
||
import com.qweather.sdk.response.weather.WeatherNowResponse;
|
||
import com.tencent.mmkv.MMKV;
|
||
import com.ttstd.dialer.BuildConfig;
|
||
import com.ttstd.dialer.bean.CityInfo;
|
||
import com.ttstd.dialer.config.CommonConfig;
|
||
import com.ttstd.dialer.gson.GsonUtils;
|
||
import com.ttstd.dialer.parser.CsvDeserializer;
|
||
import com.ttstd.dialer.parser.LegacyCsvParser;
|
||
import com.ttstd.dialer.utils.Logger;
|
||
import com.ttstd.dialer.utils.NativeUtils;
|
||
|
||
import java.util.HashMap;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
import java.util.stream.Collectors;
|
||
|
||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||
import io.reactivex.rxjava3.annotations.NonNull;
|
||
import io.reactivex.rxjava3.core.Observable;
|
||
import io.reactivex.rxjava3.core.ObservableEmitter;
|
||
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
|
||
import io.reactivex.rxjava3.core.Observer;
|
||
import io.reactivex.rxjava3.disposables.Disposable;
|
||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||
|
||
public class WeatherManager {
|
||
private static final String TAG = "WeatherManager";
|
||
|
||
private static final String WEATHER_NOW_CACHE = "weather_now_cache_key";
|
||
private static final String WEATHER_24_HOUR_CACHE = "weather_24_hour_cache";
|
||
private static final String WEATHER_10_DAY_CACHE = "weather_10_day_cache";
|
||
|
||
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
|
||
|
||
@SuppressLint("StaticFieldLeak")
|
||
private static volatile WeatherManager INSTANCE;
|
||
private Context mContext;
|
||
private QWeather mQWeather;
|
||
private Map<String, String> LocationIDMap = new HashMap<>();
|
||
private boolean loadCsvFinish = false;
|
||
private String mAdCode;
|
||
private String mLocationId;
|
||
private WeatherUpdateManager mWeatherUpdateManager;
|
||
|
||
private WeatherManager(Context context) {
|
||
this.mContext = context.getApplicationContext();
|
||
mWeatherUpdateManager = WeatherUpdateManager.Companion.getInstance();
|
||
mAdCode = mMMKV.decodeString(CommonConfig.CURRENT_LOCATION_AD_CODE_KEY, "");
|
||
initCsv();
|
||
try {
|
||
// 通过SDK提供的JWTGenerator设置令牌生成器,其实现自TokenGenerator接口
|
||
JWTGenerator jwt = new JWTGenerator(NativeUtils.getQWeatherPrivateKey(), // 私钥
|
||
NativeUtils.getQWeatherProjectId(), // 项目ID
|
||
NativeUtils.getQWeatherCredentialId()); // 凭据ID
|
||
mQWeather = QWeather.getInstance(context, NativeUtils.getQWeatherUrl()) // 初始化服务地址
|
||
.setLogEnable(BuildConfig.DEBUG) // 启用调试日志(生产环境建议设置为 false)
|
||
.setTokenGenerator(jwt);
|
||
} catch (Throwable e) {
|
||
Logger.e(TAG, "QWeatherUtils: " + e.getMessage());
|
||
e.printStackTrace();
|
||
}
|
||
|
||
WeatherNowResponse weatherNowResponse = getWeatherNowCache();
|
||
if (weatherNowResponse != null) {
|
||
mWeatherUpdateManager.publishWeatherNowUpdate(weatherNowResponse);
|
||
} else {
|
||
|
||
}
|
||
WeatherHourlyResponse weatherHourlyResponse = getWeather24hCache();
|
||
if (weatherHourlyResponse != null) {
|
||
mWeatherUpdateManager.publishWeatherHourlyUpdate(weatherHourlyResponse);
|
||
} else {
|
||
|
||
}
|
||
WeatherDailyResponse weatherDailyResponse = getWeather10DCache();
|
||
if (weatherDailyResponse != null) {
|
||
mWeatherUpdateManager.publishWeatherDailyUpdate(weatherDailyResponse);
|
||
} else {
|
||
|
||
}
|
||
}
|
||
|
||
public static void init(Context context) {
|
||
if (INSTANCE == null) {
|
||
synchronized (WeatherManager.class) {
|
||
if (INSTANCE == null) {
|
||
INSTANCE = new WeatherManager(context);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
public static WeatherManager getInstance() {
|
||
if (INSTANCE == null) {
|
||
throw new IllegalStateException("You must first initialize the WeatherManager");
|
||
}
|
||
return INSTANCE;
|
||
}
|
||
|
||
public QWeather getQWeather() {
|
||
return mQWeather;
|
||
}
|
||
|
||
public void setAdCode(String adCode) {
|
||
mAdCode = adCode;
|
||
if (loadCsvFinish) {
|
||
if (!TextUtils.isEmpty(adCode)) {
|
||
String locationId = LocationIDMap.get(adCode);
|
||
Logger.e(this, TAG, "setAdCode: locationId = " + locationId);
|
||
LiveEventBus.get(CommonConfig.LOCATION_ID_CHANGED_KEY)
|
||
.post(locationId);
|
||
}
|
||
}
|
||
}
|
||
|
||
public String getAdCode() {
|
||
return mAdCode;
|
||
}
|
||
|
||
private void initCsv() {
|
||
Observable.create(new ObservableOnSubscribe<List<CityInfo>>() {
|
||
@Override
|
||
public void subscribe(@NonNull ObservableEmitter<List<CityInfo>> emitter) throws Throwable {
|
||
long time = System.currentTimeMillis();
|
||
List<CityInfo> cityInfos;
|
||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
|
||
cityInfos = CsvDeserializer.deserializeFromAssets(mContext, "China-City-List-latest.csv");
|
||
} else {
|
||
cityInfos = LegacyCsvParser.parseFromAssets(mContext, "China-City-List-latest.csv");
|
||
}
|
||
Logger.e(TAG, "subscribe: deserializeFromAssets time = " + (System.currentTimeMillis() - time) + "ms");
|
||
emitter.onNext(cityInfos);
|
||
}
|
||
})
|
||
.subscribeOn(Schedulers.io())
|
||
.observeOn(AndroidSchedulers.mainThread())
|
||
.subscribe(new Observer<List<CityInfo>>() {
|
||
@Override
|
||
public void onSubscribe(@NonNull Disposable d) {
|
||
Logger.e(TAG, "initCsv", "onSubscribe: ");
|
||
}
|
||
|
||
@Override
|
||
public void onNext(@NonNull List<CityInfo> cityInfos) {
|
||
Logger.e(TAG, "initCsv", "onNext: cityInfos size = " + cityInfos.size());
|
||
Logger.e(TAG, "initCsv", "onNext: cityInfos 0 info = " + cityInfos.get(0));
|
||
|
||
LocationIDMap = cityInfos.stream()
|
||
.filter(cityInfo -> cityInfo.getLocation_ID() != null) // 过滤掉 value 为 null 的条目
|
||
.collect(Collectors.toMap(CityInfo::getAD_code, CityInfo::getLocation_ID, (oldVal, newVal) -> oldVal, HashMap::new));
|
||
|
||
Logger.e(TAG, "initCsv", "onNext: LocationIDMap size = " + LocationIDMap.size());
|
||
onComplete();
|
||
}
|
||
|
||
@Override
|
||
public void onError(@NonNull Throwable e) {
|
||
Logger.e(TAG, "initCsv", "onError: " + e.getMessage());
|
||
}
|
||
|
||
@Override
|
||
public void onComplete() {
|
||
Logger.e(TAG, "initCsv", "onComplete: ");
|
||
loadCsvFinish = true;
|
||
if (!TextUtils.isEmpty(mAdCode)) {
|
||
String locationId = LocationIDMap.get(mAdCode);
|
||
Logger.e(TAG, "initCsv", "onComplete: locationId = " + locationId);
|
||
LiveEventBus.get(CommonConfig.LOCATION_ID_CHANGED_KEY)
|
||
.post(locationId);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
private String getLocationID(String adCode) {
|
||
if (LocationIDMap != null) {
|
||
return LocationIDMap.get(adCode);
|
||
}
|
||
return "";
|
||
}
|
||
|
||
public void refreshweather() {
|
||
if (!TextUtils.isEmpty(mAdCode)) {
|
||
|
||
}
|
||
}
|
||
|
||
public void getWeatherNowAdCode(String adCode, Callback<WeatherNowResponse> callback) {
|
||
String locationID = getLocationID(adCode);
|
||
Logger.e(TAG, "getWeatherNowAdCode: locationID = " + locationID);
|
||
getWeatherNow(locationID, callback);
|
||
}
|
||
|
||
public void getWeatherNow(String locationID, Callback<WeatherNowResponse> callback) {
|
||
WeatherParameter parameter = new WeatherParameter(locationID)
|
||
.lang(Lang.ZH_HANS)
|
||
.unit(Unit.METRIC);
|
||
mQWeather.weatherNow(parameter, new Callback<WeatherNowResponse>() {
|
||
@Override
|
||
public void onSuccess(WeatherNowResponse weatherNowResponse) {
|
||
Logger.e(TAG, "getWeatherNow", "onSuccess: " + weatherNowResponse);
|
||
mWeatherUpdateManager.publishWeatherNowUpdate(weatherNowResponse);
|
||
mMMKV.encode(WEATHER_NOW_CACHE, GsonUtils.toJSONString(weatherNowResponse));
|
||
|
||
if (callback != null) {
|
||
callback.onSuccess(weatherNowResponse);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onFailure(ErrorResponse errorResponse) {
|
||
if (callback != null) {
|
||
callback.onFailure(errorResponse);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onException(Throwable throwable) {
|
||
if (callback != null) {
|
||
callback.onException(throwable);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
public void getWeather24HourAdCode(String adCode, Callback<WeatherHourlyResponse> callback) {
|
||
String locationID = getLocationID(adCode);
|
||
Logger.e(TAG, "getWeather24HourAdCode: locationID = " + locationID);
|
||
getWeather24Hour(locationID, callback);
|
||
}
|
||
|
||
public void getWeather24Hour(String locationID, Callback<WeatherHourlyResponse> callback) {
|
||
WeatherParameter parameter = new WeatherParameter(locationID)
|
||
.lang(Lang.ZH_HANS)
|
||
.unit(Unit.METRIC);
|
||
mQWeather.weather24h(parameter, new Callback<WeatherHourlyResponse>() {
|
||
@Override
|
||
public void onSuccess(WeatherHourlyResponse weatherHourlyResponse) {
|
||
Logger.e(TAG, "getWeather24Hour", "onSuccess: " + weatherHourlyResponse);
|
||
mWeatherUpdateManager.publishWeatherHourlyUpdate(weatherHourlyResponse);
|
||
mMMKV.encode(WEATHER_24_HOUR_CACHE, GsonUtils.toJSONString(weatherHourlyResponse));
|
||
|
||
if (callback != null) {
|
||
callback.onSuccess(weatherHourlyResponse);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onFailure(ErrorResponse errorResponse) {
|
||
if (callback != null) {
|
||
callback.onFailure(errorResponse);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onException(Throwable throwable) {
|
||
if (callback != null) {
|
||
callback.onException(throwable);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
public void getWeather10DayAdCode(String adCode, Callback<WeatherDailyResponse> callback) {
|
||
String locationID = getLocationID(adCode);
|
||
Logger.e(TAG, "getWeather10Day: locationID = " + locationID);
|
||
getWeather10Day(locationID, callback);
|
||
}
|
||
|
||
public void getWeather10Day(String locationID, Callback<WeatherDailyResponse> callback) {
|
||
WeatherParameter parameter = new WeatherParameter(locationID)
|
||
.lang(Lang.ZH_HANS)
|
||
.unit(Unit.METRIC);
|
||
mQWeather.weather10d(parameter, new Callback<WeatherDailyResponse>() {
|
||
@Override
|
||
public void onSuccess(WeatherDailyResponse weatherDailyResponse) {
|
||
Logger.e(TAG, "getWeather10Day", "onSuccess: " + weatherDailyResponse);
|
||
mWeatherUpdateManager.publishWeatherDailyUpdate(weatherDailyResponse);
|
||
mMMKV.encode(WEATHER_10_DAY_CACHE, GsonUtils.toJSONString(weatherDailyResponse));
|
||
|
||
if (callback != null) {
|
||
callback.onSuccess(weatherDailyResponse);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onFailure(ErrorResponse errorResponse) {
|
||
if (callback != null) {
|
||
callback.onFailure(errorResponse);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onException(Throwable throwable) {
|
||
if (callback != null) {
|
||
callback.onException(throwable);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
public WeatherNowResponse getWeatherNowCache() {
|
||
String weatherNowCache = mMMKV.decodeString(WEATHER_NOW_CACHE);
|
||
if (!TextUtils.isEmpty(weatherNowCache)) {
|
||
return GsonUtils.toJavaObject(weatherNowCache, WeatherNowResponse.class);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public WeatherHourlyResponse getWeather24hCache() {
|
||
String weather24hCache = mMMKV.decodeString(WEATHER_24_HOUR_CACHE);
|
||
if (!TextUtils.isEmpty(weather24hCache)) {
|
||
return GsonUtils.toJavaObject(weather24hCache, WeatherHourlyResponse.class);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public WeatherDailyResponse getWeather10DCache() {
|
||
String weather10DCache = mMMKV.decodeString(WEATHER_10_DAY_CACHE);
|
||
if (!TextUtils.isEmpty(weather10DCache)) {
|
||
return GsonUtils.toJavaObject(weather10DCache, WeatherDailyResponse.class);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
}
|