weather icon
一些用户问我一些有关如何使用Weatherlib的细节。 在这篇文章中想描述如何使用它。
这是一个Android库,可帮助您快速轻松地开发天气应用。 这篇文章描述了lib背后的主要概念,以便您可以更好地理解它。
如果您对内部库结构不感兴趣,可以跳到介绍如何编写天气客户端代码的部分:
Weatherlib结构
该库由三个不同的层构建:
- 资料模型
-
- 天气提供者
-
- 天气客户
第一层是数据模型,代表不同天气提供者提取的信息。 它对这些信息进行了抽象,以便独立于您选择的天气提供者,您始终可以以相同的方式,以相同的关系呈现相同的信息。
天气提供商是通向天气提供商的连接器。 到目前为止,图书馆支持三种天气提供者:
该层实现从天气提供者提取信息,解析检索到的数据所必需的逻辑,并在过程结束时这些提供者填充数据模型。
最后一层是客户端层。 该层实现了连接天气提供程序(即使用HTTP连接)并处理连接错误等的逻辑。 检索到数据后,客户端将使用天气提供程序来解析数据。
可以轻松地扩展和自定义每一层,以便您可以支持其他天气提供者,或以不同的方式连接到提供者。 我们将在以后看到如何做。
Weatherlib数据模型
这是位于图书馆基础上的模型,当您要获取天气信息时可以与之交互。
CurrentWeather类保存与当前天气数据有关的所有信息。 WeatherHourForecast保留与每小时天气数据有关的信息,而WeatherForecast保留与第二天天气有关的信息。
Weatherlib提供者
该层是库的核心,因为它实现了从天气提供者提取信息的逻辑。 到现在为止,图书馆支持三种不同的天气提供者。 每个提供程序由三个不同的类描述,这些类必须实现三个接口:
-
IProviderType
,用于定义必须实例化以创建提供程序的类名称。 -
IWeatherProvider
所有天气提供者必须实现的主要接口,并拥有解析数据所需的所有方法。 -
IWeatherCodeProvider
一个简单的界面,用于以通用格式转换天气代码,以便天气代码条件与提供程序无关。
例如,如果我们查看openweathermap提供程序,则有:
所有提供程序都是由WeatherProviderFactory
创建的。
天气客户
这是处理与远程天气提供程序的连接并检索数据的最后一层。 您可以使用所有喜欢的协议,但通常使用HTTP协议。 这些类还处理连接错误等。 lib提供了两种不同的实现:
- 一个基于凌空库
- 一种基于Android提供的标准HttpConnection
设置开发环境
使用该库非常简单,因为该库位于中央Maven存储库中,因此您无需在Android Studio中做很多工作。 创建项目后,必须向项目build.gradle
添加新的依赖build.gradle
dependencies {
compile 'com.android.support:appcompat-v7:19.+'
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.survivingwithandroid:WeatherLib:1.3.0'
}
如何使用Weatherlib开发Weather应用
现在您已经知道了主要的库层,是时候开始使用该库了。 当然,当您进行开发时,您不必担心现在解释的内部细节,但是您将仅使用一些内容。 您要做的第一件事是获取WeatherClient
的实例,以便可以在您的应用程序中使用。 此类为单例,因此您只需初始化一次:
WeatherClient client = WeatherClientDefault.getInstance();
在这种情况下,我们要使用基于Volley lib的默认客户端,否则可以使用StandardHttpClient。 现在我们有了客户端,我们必须通过 Context 对其进行初始化 :
client.init(ctx);
现在我们必须配置向客户端传递天气配置:
WeatherConfig config = new WeatherConfig();
config.unitSystem = WeatherConfig.UNIT_SYSTEM.M;
config.lang = "en"; // If you want to use english
config.maxResult = 5; // Max number of cities retrieved
config.numDays = 6; // Max num of days in the forecast
然后:
client.updateWeatherConfig(config);
现在已经配置了客户端,最后一步是选择我们要使用哪种类型的提供程序:
IWeatherProvider provider = null;
try {
//provider = WeatherProviderFactory.createProvider(new YahooProviderType(), config);
provider = WeatherProviderFactory.createProvider(new OpenweathermapProviderType(), config);
//provider = WeatherProviderFactory.createProvider(new WeatherUndergroundProviderType(), config);
client.setProvider(provider);
}
catch (Throwable t) {
// There's a problem
}
OK完成! 我们的客户已准备好使用并准备检索信息。
搜索城市ID
通常,下一步是搜索城市。 几乎所有的天气提供者都想要一个城市ID,您必须在查询天气信息之前先找到它。 现在您可以有两个选择:
- 按名称或名称的一部分进行搜索
- 通过地理坐标搜索
在第一种情况下,您可以使用:
private void search(String pattern) {
client.searchCity(pattern, new WeatherClient.CityEventListener() {
@Override
public void onCityListRetrieved(List<City> cityList) {
// When the data is ready you can implement your logic here
}
@Override
public void onWeatherError(WeatherLibException t) {
// Error
}
@Override
public void onConnectionError(Throwable t) {
// Connection error
}
});
}
模式是您要查找的部分城市名称。 在onCityListRetrived
您有一个作为结果的城市列表,可以将其传递给ArrayAdapter例如向用户显示结果。
在第二个选项中,使用地理坐标,您只需:
client.searchCityByLocation(WeatherClient.createDefaultCriteria(), new WeatherClient.CityEventListener() {
@Override
public void onCityListRetrieved(List<City> cityList) {
// Here your logic when the data is available
}
@Override
public void onWeatherError(WeatherLibException wle) {
}
@Override
public void onConnectionError(Throwable t) {
}
});
}
catch(LocationProviderNotFoundException lpnfe) {
}
请注意,在第1行,我们使用WeatherClient.createDefaultCriteria(),此方法返回一些默认条件 ,这些条件用于选择最佳位置提供程序。 如果要使用您的条件,只需手动设置它们:
Criteria criteria = new Criteria();
criteria.setPowerRequirement(Criteria.POWER_LOW);
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
criteria.setCostAllowed(false);
当前天气状况
获得城市ID后,您可以查询提供商,询问当前的天气状况:
client.getCurrentCondition(cityId, new WeatherClient.WeatherEventListener() {
@Override
public void onWeatherRetrieved(CurrentWeather weather) {
// Here we can use the weather information to upadte the view
}
@Override
public void onWeatherError(WeatherLibException t) {
}
@Override
public void onConnectionError(Throwable t) {
}
});
请注意,客户端使用回调接口,该接口通知调用方数据已准备就绪。 仅当您使用WeatherClientDefault
时,才会发生这种情况。 使用这些回调方法,您不必担心ANR问题,因为HTTP请求发生在单独的线程中,并且这些请求不会阻止应用程序。 当第3行的数据准备就绪时,我们可以使用它来更新UI,如下所示:
@Override
protected void updateView(Object obj) {
CurrentWeather weather = (CurrentWeather) obj;
cityText.setText(weather.location.getCity() + "," + weather.location.getCountry());
condDescr.setText(weather.currentCondition.getCondition() + "(" + weather.currentCondition.getDescr() + ")");
temp.setText("" + ((int) weather.temperature.getTemp()));
unitTemp.setText(weather.getUnit().tempUnit);
....
}
WeatherForecast和每小时天气预报
如果需要,可以使用lib查询预报和每小时预报数据。 以上述相同的方式,我们有:
client.getForecastWeather(cityId, new WeatherClient.ForecastWeatherEventListener() {
@Override
public void onWeatherRetrieved(WeatherForecast forecast) {
updateView(forecast);
}
@Override
public void onWeatherError(WeatherLibException t) {
}
@Override
public void onConnectionError(Throwable t) {
//WeatherDialog.createErrorDialog("Error parsing data. Please try again", MainActivity.this);
}
});
对于每小时的预测,我们有:
client.getHourForecastWeather(cityId, new WeatherClient.HourForecastWeatherEventListener() {
@Override
public void onWeatherRetrieved(WeatherHourForecast forecast) {
updateView(foreacst);
}
@Override
public void onWeatherError(WeatherLibException wle) {
}
@Override
public void onConnectionError(Throwable t) {
}
});
缓存数据
开发天气应用程序时应考虑的一个方面是天气数据不会快速更改,因此缓存数据是个好习惯,这样您就不必一直向远程提供者请求它们。 Weatherlib目前尚未提供缓存机制,因此如果要缓存检索到的结果,则必须由您实施。 这很容易完成,创建一个单例类来保存您检索的数据,例如:
public class AppWeatherClient {
private static AppWeatherClient me;
private Context ctx;
private WeatherClient client;
private WeatherConfig config;
private WeatherForecast forecast;
private CurrentWeather weather;
private AppWeatherClient() {}
public static AppWeatherClient getInstance() {
if (me == null)
me = new AppWeatherClient();
return me;
}
public CurrentWeather getCurrentWeather() {
return this.weather;
}
public void setCurrentWeather(CurrentWeather weather) {
this.weather = weather;
}
public WeatherForecast getForecast() {
return forecast;
}
public void setForecast(WeatherForecast forecast) {
this.forecast = forecast;
}
}
使用API密钥
一些提供程序要求您使用API密钥(即Weatherundergroud)。 此API密钥对于调用远程方法和检索天气信息是必需的。 Weatherlib提供了一种处理此类请求的简便方法,您不必担心如何将密钥发送给远程提供商。 在WeatherConfig类中,您可以添加密钥:
config.ApiKey=your_key
就这样。
有助于
库的源代码是免费的,因此欢迎每个希望为库做出贡献的人。如果您想为库做出贡献,则可以使用github并提出新的请求,以便我可以合并您的代码。 如果您在代码中发现错误,则可以在github上打开问题或与我联系。
如果您使用该库并对它感到满意,我希望您可以发送一些您创建的应用程序的屏幕截图。 您可以加入g +社区并在此处发布屏幕截图,如果您只是想发表意见或提出一些改进,可以加入该社区。
如果有人想为图书馆提供免费的精美徽标,我将非常高兴。
我知道有些用户遇到麻烦,如果有人已经将它导入Eclipse并想解释它,您可以自由贡献。
翻译自: https://www.javacodegeeks.com/2014/05/how-to-develop-an-android-weather-app-using-weatherlib.html
weather icon