增加天气显示

This commit is contained in:
2026-03-06 09:50:58 +08:00
parent 962a022bf9
commit 0f2adad060
30 changed files with 5567 additions and 64 deletions

View File

@@ -0,0 +1,171 @@
package com.ttstd.dialer.manager;
import android.annotation.SuppressLint;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
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.weather.WeatherDailyResponse;
import com.qweather.sdk.response.weather.WeatherNowResponse;
import com.ttstd.dialer.BuildConfig;
import com.ttstd.dialer.bean.CityInfo;
import com.ttstd.dialer.config.CommonConfig;
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";
@SuppressLint("StaticFieldLeak")
private static WeatherManager INSTANCE;
private Context mContext;
private QWeather mQWeather;
private Map<String, String> LocationIDMap = new HashMap<>();
private boolean loadCsvFinish = false;
private String mAdCode;
private WeatherManager(Context context) {
this.mContext = context.getApplicationContext();
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) {
Log.e(TAG, "QWeatherUtils: " + e.getMessage());
e.printStackTrace();
}
}
public static void init(Context context) {
if (INSTANCE == null) {
INSTANCE = new WeatherManager(context);
}
}
public static WeatherManager getInstance() {
if (INSTANCE == null) {
throw new IllegalStateException("You must be init WeatherManager first");
}
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);
}
}
}
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 = CsvDeserializer.deserializeFromAssets(mContext, "China-City-List-latest.csv");
Log.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 getWeatherNow(String adCode, Callback<WeatherNowResponse> callback) {
String locationID = getLocationID(adCode);
Log.e(TAG, "getWeatherNow: locationID = " + locationID);
WeatherParameter parameter = new WeatherParameter(locationID)
.lang(Lang.ZH_HANS)
.unit(Unit.METRIC);
mQWeather.weatherNow(parameter, callback);
}
public void getWeather10D(String adCode, Callback<WeatherDailyResponse> callback) {
String locationID = getLocationID(adCode);
Log.e(TAG, "getWeather10D: locationID = " + locationID);
WeatherParameter parameter = new WeatherParameter(locationID)
.lang(Lang.ZH_HANS)
.unit(Unit.METRIC);
mQWeather.weather10d(parameter, callback);
}
}