android天气预报----google开源天气API,SAX解析
2011-12-15 09:41
399 查看
最近项目不太忙,就抽空看了看天气预报,做个玩玩,上图:
转载请注明出处:
http://blog.csdn.net/dany1202/archive/2011/05/17/6426064.aspx
1.知识基础:小部件、数据库、SAX解析XML文件
2.实现说明:
google提供了天气预报的开放XML文件
http://www.google.com/ig/api?hl=zh-cn&weather=Beijing
查看如上网址,会看到界面显示一个XML文件,用SAX解析的方式获取XML文件节点内容,并将其存储到一个实体当中。
存储数据到数据库。
显示内容到小部件。
3.窗口小部件时间的实时刷新
Intent.ACTION_TIME_CHANGED 为系统时间每次发生改变的时候,发送的广播,其只能动态注册
所以在小部件的WeatherWidgetProvider.java中的onUpdate()方法中开启service,并在service中进行注册接收的广播
view
plain
public class UpdateTimeService extends Service {
BroadcastReceiver mIntentReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
if(Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())
|| Intent.ACTION_TIME_TICK.equals(intent.getAction())
|| Intent.ACTION_TIME_CHANGED.equals(intent.getAction()))
WeatherWidgetProvider.UpdateTime(context);
}
};
@Override
public void onDestroy() {
unregisterReceiver(mIntentReceiver);
super.onDestroy();
}
@Override
public void onCreate() {
IntentFilter commandFilter = new IntentFilter();
commandFilter.addAction(Intent.ACTION_TIME_TICK);
commandFilter.addAction(Intent.ACTION_TIME_CHANGED);
commandFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
getBaseContext().registerReceiver(mIntentReceiver, commandFilter);
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
在WeatherWidgetProvider.java中提供静态方法public static void UpdateTime(Context context){。。。}刷新时间。
4.SAX解析,获取current_conditions节点内容
view
plain
public class XMLHandler extends DefaultHandler {
private static final String TAG = "XMLHandler";
private CurrentEntity currentWeather;
private boolean currentFlag;
public void setCurrentWeather(CurrentEntity currentWeather){
this.currentWeather = currentWeather;
}
public CurrentEntity getCurrentWeather(){
return currentWeather;
}
public XMLHandler() {
currentFlag = false;
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
String tagName = localName.length() != 0 ? localName : qName;
tagName = tagName.toLowerCase();
Log.d(TAG,"tagName = "+tagName);
if(tagName.equals("current_conditions")){
currentFlag = true;
currentWeather = new CurrentEntity();
}
if(currentFlag){
if(tagName.equals("condition")){
Log.d(TAG,"condition = "+attributes.getValue("data"));
currentWeather.setCondition(attributes.getValue("data"));
}else if(tagName.equals("temp_c")){
Log.d(TAG,"temp_c--------");
currentWeather.setTempc(attributes.getValue("data"));
}else if(tagName.equals("humidity")){
currentWeather.setHumidity(attributes.getValue("data"));
}else if(tagName.equals("icon")){
currentWeather.setIcon(attributes.getValue("data"));
}else if(tagName.equals("wind_condition")){
currentWeather.setWindcondition(attributes.getValue("data"));
}
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
String tagName = localName.length() != 0 ? localName : qName;
tagName = tagName.toLowerCase();
if(tagName.equals("current_conditions")) {
currentFlag = false;
}
}
}
将节点对应的内容存放到CurrentEntity实体类中。
5.在天气的service中,开启线程,刷新小部件中的天气内容
view
plain
public class UpdateForecastService extends Service implements Runnable {
private static final String TAG = "UpdateForecastService";
private Uri currentUri = null;
private String city = "Beijing";
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
currentUri = intent.getData();
Cursor cur = getContentResolver().query(currentUri, null, Weathers._ID +"="+ currentUri.getPathSegments().get(1), null, null);
if(cur!=null && cur.getCount()>0){
cur.moveToFirst();
city = cur.getString(2);
}
Log.d(TAG,"-----------city = "+city);
new Thread(this).start();
}
public void run(){
Log.d(TAG,"----------------run --------------");
SAXParserFactory spf = SAXParserFactory.newInstance();
try {
SAXParser sp = spf.newSAXParser();
XMLReader reader = sp.getXMLReader();
XMLHandler handler = new XMLHandler();
reader.setContentHandler(handler);
URL url = new URL(Weathers.WEB_URI + URLEncoder.encode(city));
InputStream is = url.openStream();
InputStreamReader isr = new InputStreamReader(is,"GBK");
InputSource source = new InputSource(isr);
reader.parse(source);
CurrentEntity currentWeather = handler.getCurrentWeather();
Log.d(TAG,"------tempc = "+currentWeather.getTempc()+" condition = "+currentWeather.getCondition());
ContentValues values = new ContentValues();
values.put(Weathers.CONDITION, currentWeather.getCondition());
values.put(Weathers.TEMPC,currentWeather.getTempc());
values.put(Weathers.HUMIDITY,currentWeather.getHumidity());
values.put(Weathers.ICON,currentWeather.getIcon());
values.put(Weathers.WINDCONDITION,currentWeather.getWindcondition());
getContentResolver().update(currentUri, values, null, null);
WeatherWidgetProvider.UpdateWeather(this,currentUri);
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG,"not complete the parser");
}
stopSelf();
}
}
6小部件对应appwidgetprovider
view
plain
public class WeatherWidgetProvider extends AppWidgetProvider{
private static final String TAG = "WeatherWidgetProvider";
private static int flagsDate = DateUtils.FORMAT_SHOW_DATE;
private static int flagsWeek = DateUtils.FORMAT_SHOW_WEEKDAY;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
UpdateTime(context);
Intent intent=new Intent(context ,UpdateTimeService.class);
context.startService(intent);
for(int i=0;i<appWidgetIds.length;i++){
Cursor cur = context.getContentResolver().query(Weathers.CONTENT_URI,null,Weathers.WIDGETID+"="+appWidgetIds[i],null,null);
if(cur!=null&& cur.getCount()>0){
cur.moveToFirst();
String uri = Weathers.CONTENT_URI+"/"+String.valueOf(cur.getString(0));
Intent intentForcast = new Intent(context,UpdateForecastService.class);
intentForcast.setData(Uri.parse(uri));
context.startService(intentForcast);
}
cur.close();
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
if(0 == appWidgetIds.length){
Intent intent = new Intent(context ,UpdateTimeService.class);
context.stopService(intent);
}
super.onDeleted(context, appWidgetIds);
}
private final static String M12 = "h:mm";
private final static String M24 = "kk:mm";
public static void UpdateTime(Context context){
RemoteViews views=new RemoteViews(context.getPackageName(),R.layout.weather_appwidget);
String dateStr = (String)DateUtils.formatDateTime(context, System.currentTimeMillis(), flagsDate);
String smPmStr = DateUtils.getAMPMString(Calendar.getInstance().get(Calendar.AM_PM));
String formatTime;
if(android.text.format.DateFormat.is24HourFormat(context)){
formatTime = M24;
views.setViewVisibility(R.id.widget_am_pm,View.GONE);
}else{
formatTime = M12;
views.setViewVisibility(R.id.widget_am_pm,View.VISIBLE);
views.setTextViewText(R.id.widget_am_pm, smPmStr);
}
String timeStr = (String) DateFormat.format(formatTime,System.currentTimeMillis());
String weekStr = (String)DateUtils.formatDateTime(context, System.currentTimeMillis(), flagsWeek);
views.setTextViewText(R.id.widget_date,dateStr+" "+weekStr);
views.setTextViewText(R.id.widget_time,timeStr);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds=appWidgetManager.getAppWidgetIds(new ComponentName(context, WeatherWidgetProvider.class));
appWidgetManager.updateAppWidget(appWidgetIds, views);
}
public static void UpdateWeather(Context context, Uri currentUri) {
Cursor curCurrent = context.getContentResolver().query(currentUri, null, Weathers._ID +"="+ currentUri.getPathSegments().get(1), null, null);
if(curCurrent!=null && curCurrent.getCount()>0){
curCurrent.moveToFirst();
Log.d(TAG,"curCurrent.getInt(1) = "+curCurrent.getInt(1));
Intent configIntent = new Intent(context, WeatherWidgetProvider.class);
configIntent.setAction(currentUri.toString());
configIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,curCurrent.getInt(1));
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,configIntent, 0);
RemoteViews views=new RemoteViews(context.getPackageName(),R.layout.weather_appwidget);
views.setTextViewText(R.id.city,curCurrent.getString(2));
views.setTextViewText(R.id.condition,curCurrent.getString(3));
views.setTextViewText(R.id.tempc, curCurrent.getString(4)+"°");
views.setTextViewText(R.id.humidity,curCurrent.getString(5));
views.setImageViewResource(R.id.icon, WeatherUtil
.getForecastImage(curCurrent.getString(6)));
views.setOnClickPendingIntent(R.id.icon, pendingIntent);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
appWidgetManager.updateAppWidget(curCurrent.getInt(1), views);
}
curCurrent.close();
}
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"intent.getAction() = "+intent.getAction());
if(intent.getAction().startsWith(Weathers.CONTENT_URI.toString())){
int mAppWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
Uri uri = Uri.parse(intent.getAction());
Log.d(TAG,"mAppWidgetId = "+mAppWidgetId+" uri = "+uri);
Intent i = new Intent(context,UpdateForecastService.class);
i.setData(uri);
context.startService(i);
}
super.onReceive(context, intent);
}
}
在onUpdate中开启两个service,一个刷新时间,一个刷新天气。定义了一个Icon的点击事件,继续起到刷新天气的功能。
onReceive中接收点击事件,找到是哪一个小部件被点击了,根据小部件的Id进行区分。
当然此小部件是需要一个配置活动的,获取用户输入的城市名,不再多帖代码了,网上例子还是蛮多的
备注:搜狐天气api接口
http://sms.sohu.com/weatherfore/getformobile.php?city=北京
转载请注明出处:
http://blog.csdn.net/dany1202/archive/2011/05/17/6426064.aspx
1.知识基础:小部件、数据库、SAX解析XML文件
2.实现说明:
google提供了天气预报的开放XML文件
http://www.google.com/ig/api?hl=zh-cn&weather=Beijing
查看如上网址,会看到界面显示一个XML文件,用SAX解析的方式获取XML文件节点内容,并将其存储到一个实体当中。
存储数据到数据库。
显示内容到小部件。
3.窗口小部件时间的实时刷新
Intent.ACTION_TIME_CHANGED 为系统时间每次发生改变的时候,发送的广播,其只能动态注册
所以在小部件的WeatherWidgetProvider.java中的onUpdate()方法中开启service,并在service中进行注册接收的广播
view
plain
public class UpdateTimeService extends Service {
BroadcastReceiver mIntentReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
if(Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())
|| Intent.ACTION_TIME_TICK.equals(intent.getAction())
|| Intent.ACTION_TIME_CHANGED.equals(intent.getAction()))
WeatherWidgetProvider.UpdateTime(context);
}
};
@Override
public void onDestroy() {
unregisterReceiver(mIntentReceiver);
super.onDestroy();
}
@Override
public void onCreate() {
IntentFilter commandFilter = new IntentFilter();
commandFilter.addAction(Intent.ACTION_TIME_TICK);
commandFilter.addAction(Intent.ACTION_TIME_CHANGED);
commandFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
getBaseContext().registerReceiver(mIntentReceiver, commandFilter);
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
在WeatherWidgetProvider.java中提供静态方法public static void UpdateTime(Context context){。。。}刷新时间。
4.SAX解析,获取current_conditions节点内容
view
plain
public class XMLHandler extends DefaultHandler {
private static final String TAG = "XMLHandler";
private CurrentEntity currentWeather;
private boolean currentFlag;
public void setCurrentWeather(CurrentEntity currentWeather){
this.currentWeather = currentWeather;
}
public CurrentEntity getCurrentWeather(){
return currentWeather;
}
public XMLHandler() {
currentFlag = false;
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
String tagName = localName.length() != 0 ? localName : qName;
tagName = tagName.toLowerCase();
Log.d(TAG,"tagName = "+tagName);
if(tagName.equals("current_conditions")){
currentFlag = true;
currentWeather = new CurrentEntity();
}
if(currentFlag){
if(tagName.equals("condition")){
Log.d(TAG,"condition = "+attributes.getValue("data"));
currentWeather.setCondition(attributes.getValue("data"));
}else if(tagName.equals("temp_c")){
Log.d(TAG,"temp_c--------");
currentWeather.setTempc(attributes.getValue("data"));
}else if(tagName.equals("humidity")){
currentWeather.setHumidity(attributes.getValue("data"));
}else if(tagName.equals("icon")){
currentWeather.setIcon(attributes.getValue("data"));
}else if(tagName.equals("wind_condition")){
currentWeather.setWindcondition(attributes.getValue("data"));
}
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
String tagName = localName.length() != 0 ? localName : qName;
tagName = tagName.toLowerCase();
if(tagName.equals("current_conditions")) {
currentFlag = false;
}
}
}
将节点对应的内容存放到CurrentEntity实体类中。
5.在天气的service中,开启线程,刷新小部件中的天气内容
view
plain
public class UpdateForecastService extends Service implements Runnable {
private static final String TAG = "UpdateForecastService";
private Uri currentUri = null;
private String city = "Beijing";
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
currentUri = intent.getData();
Cursor cur = getContentResolver().query(currentUri, null, Weathers._ID +"="+ currentUri.getPathSegments().get(1), null, null);
if(cur!=null && cur.getCount()>0){
cur.moveToFirst();
city = cur.getString(2);
}
Log.d(TAG,"-----------city = "+city);
new Thread(this).start();
}
public void run(){
Log.d(TAG,"----------------run --------------");
SAXParserFactory spf = SAXParserFactory.newInstance();
try {
SAXParser sp = spf.newSAXParser();
XMLReader reader = sp.getXMLReader();
XMLHandler handler = new XMLHandler();
reader.setContentHandler(handler);
URL url = new URL(Weathers.WEB_URI + URLEncoder.encode(city));
InputStream is = url.openStream();
InputStreamReader isr = new InputStreamReader(is,"GBK");
InputSource source = new InputSource(isr);
reader.parse(source);
CurrentEntity currentWeather = handler.getCurrentWeather();
Log.d(TAG,"------tempc = "+currentWeather.getTempc()+" condition = "+currentWeather.getCondition());
ContentValues values = new ContentValues();
values.put(Weathers.CONDITION, currentWeather.getCondition());
values.put(Weathers.TEMPC,currentWeather.getTempc());
values.put(Weathers.HUMIDITY,currentWeather.getHumidity());
values.put(Weathers.ICON,currentWeather.getIcon());
values.put(Weathers.WINDCONDITION,currentWeather.getWindcondition());
getContentResolver().update(currentUri, values, null, null);
WeatherWidgetProvider.UpdateWeather(this,currentUri);
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG,"not complete the parser");
}
stopSelf();
}
}
6小部件对应appwidgetprovider
view
plain
public class WeatherWidgetProvider extends AppWidgetProvider{
private static final String TAG = "WeatherWidgetProvider";
private static int flagsDate = DateUtils.FORMAT_SHOW_DATE;
private static int flagsWeek = DateUtils.FORMAT_SHOW_WEEKDAY;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
UpdateTime(context);
Intent intent=new Intent(context ,UpdateTimeService.class);
context.startService(intent);
for(int i=0;i<appWidgetIds.length;i++){
Cursor cur = context.getContentResolver().query(Weathers.CONTENT_URI,null,Weathers.WIDGETID+"="+appWidgetIds[i],null,null);
if(cur!=null&& cur.getCount()>0){
cur.moveToFirst();
String uri = Weathers.CONTENT_URI+"/"+String.valueOf(cur.getString(0));
Intent intentForcast = new Intent(context,UpdateForecastService.class);
intentForcast.setData(Uri.parse(uri));
context.startService(intentForcast);
}
cur.close();
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
if(0 == appWidgetIds.length){
Intent intent = new Intent(context ,UpdateTimeService.class);
context.stopService(intent);
}
super.onDeleted(context, appWidgetIds);
}
private final static String M12 = "h:mm";
private final static String M24 = "kk:mm";
public static void UpdateTime(Context context){
RemoteViews views=new RemoteViews(context.getPackageName(),R.layout.weather_appwidget);
String dateStr = (String)DateUtils.formatDateTime(context, System.currentTimeMillis(), flagsDate);
String smPmStr = DateUtils.getAMPMString(Calendar.getInstance().get(Calendar.AM_PM));
String formatTime;
if(android.text.format.DateFormat.is24HourFormat(context)){
formatTime = M24;
views.setViewVisibility(R.id.widget_am_pm,View.GONE);
}else{
formatTime = M12;
views.setViewVisibility(R.id.widget_am_pm,View.VISIBLE);
views.setTextViewText(R.id.widget_am_pm, smPmStr);
}
String timeStr = (String) DateFormat.format(formatTime,System.currentTimeMillis());
String weekStr = (String)DateUtils.formatDateTime(context, System.currentTimeMillis(), flagsWeek);
views.setTextViewText(R.id.widget_date,dateStr+" "+weekStr);
views.setTextViewText(R.id.widget_time,timeStr);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds=appWidgetManager.getAppWidgetIds(new ComponentName(context, WeatherWidgetProvider.class));
appWidgetManager.updateAppWidget(appWidgetIds, views);
}
public static void UpdateWeather(Context context, Uri currentUri) {
Cursor curCurrent = context.getContentResolver().query(currentUri, null, Weathers._ID +"="+ currentUri.getPathSegments().get(1), null, null);
if(curCurrent!=null && curCurrent.getCount()>0){
curCurrent.moveToFirst();
Log.d(TAG,"curCurrent.getInt(1) = "+curCurrent.getInt(1));
Intent configIntent = new Intent(context, WeatherWidgetProvider.class);
configIntent.setAction(currentUri.toString());
configIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,curCurrent.getInt(1));
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,configIntent, 0);
RemoteViews views=new RemoteViews(context.getPackageName(),R.layout.weather_appwidget);
views.setTextViewText(R.id.city,curCurrent.getString(2));
views.setTextViewText(R.id.condition,curCurrent.getString(3));
views.setTextViewText(R.id.tempc, curCurrent.getString(4)+"°");
views.setTextViewText(R.id.humidity,curCurrent.getString(5));
views.setImageViewResource(R.id.icon, WeatherUtil
.getForecastImage(curCurrent.getString(6)));
views.setOnClickPendingIntent(R.id.icon, pendingIntent);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
appWidgetManager.updateAppWidget(curCurrent.getInt(1), views);
}
curCurrent.close();
}
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"intent.getAction() = "+intent.getAction());
if(intent.getAction().startsWith(Weathers.CONTENT_URI.toString())){
int mAppWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
Uri uri = Uri.parse(intent.getAction());
Log.d(TAG,"mAppWidgetId = "+mAppWidgetId+" uri = "+uri);
Intent i = new Intent(context,UpdateForecastService.class);
i.setData(uri);
context.startService(i);
}
super.onReceive(context, intent);
}
}
在onUpdate中开启两个service,一个刷新时间,一个刷新天气。定义了一个Icon的点击事件,继续起到刷新天气的功能。
onReceive中接收点击事件,找到是哪一个小部件被点击了,根据小部件的Id进行区分。
当然此小部件是需要一个配置活动的,获取用户输入的城市名,不再多帖代码了,网上例子还是蛮多的
备注:搜狐天气api接口
http://sms.sohu.com/weatherfore/getformobile.php?city=北京
相关文章推荐
- android天气预报----google开源天气API,SAX解析
- android天气预报widget----google开源天气API,SAX解析
- python for android : 天气预报 API
- 开源免费天气预报接口API以及全国所有地区代码!!(国家气象局提供)
- Android实战--天气预报(API+JSON解析)
- 开源免费天气预报接口API(国家气象局提供)
- 一款基于网易云音乐 UI,使用 Gank.Io 及豆瓣 api 开发的符合 Google Material Design 的 Android 开源项目.
- 使用Google Weather API查询天气预报
- 开源免费天气预报接口API以及全国所有地区代码!
- 开源免费天气预报接口API以及全国所有地区代码
- 开源免费天气预报接口API以及全国所在地所有地区代码(国家气象局提供)
- 开源免费天气预报接口API以及全国所有地区代码!!(国家气象局提供)
- 开源免费的天气预报接口API以及全国所有地区代码(国家气象局提供)
- 开源免费天气预报接口API以及全国…
- 使用Google Weather API查询天气预报
- 开源免费天气预报接口API以及全国所有地区代码!!(国家气象局提供)
- 开源免费天气预报接口API以及全国所有地区代码!!(国家气象局提供)
- 开源免费天气预报接口API以及全国所有地区代码!!(国家气象局提供)
- 开源免费的天气预报接口API以及全国所有地区代码(国家气象局提供)
- 开源免费天气预报接口API以及全国所有地区代码!!(国家气象局提供)