android天气预报widget----google开源天气API,SAX解析
来源:互联网 发布:移动硬盘排名知乎 编辑:程序博客网 时间:2024/04/30 18:58
转载请注明出处:
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中进行注册接收的广播
- 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节点内容
- 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中,开启线程,刷新小部件中的天气内容
- 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
- 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天气预报widget----google开源天气API,SAX解析
- android天气预报----google开源天气API,SAX解析
- android天气预报----google开源天气API,SAX解析
- google天气预报SAX解析版(只有当天的天气)
- sax解析雅虎天气api
- Android天气预报各种天气API
- Android天气预报,Json解析,百度天气接口
- Android开源天气预报app - 清新小天气
- 天气API-----开源免费天气预报接口API以及全国所有地区代码!!(国家气象局提供)
- 天气API-----开源免费天气预报接口API以及全国所有地区代码!!(国家气象局提供)
- Android访问中央气象台的天气预报API得到天气数据
- Android访问中央气象台的天气预报API得到天气数据
- Android访问中央气象台的天气预报API得到天气数据 .
- Android访问中央气象台的天气预报API得到天气数据 .
- Android访问中央气象台的天气预报API得到天气数据 .
- Android访问中央气象台的天气预报API得到天气数据
- Android访问中央气象台的天气预报API得到天气数据
- Android访问中央气象台的天气预报API得到天气数据
- Real-Time Transport Protocol (RTP) Parameters
- C++内存分配及变长数组的动态分配
- C++ fill() fill_n() back_inserter 简析
- 1
- Python 的 Socket 编程教程
- android天气预报widget----google开源天气API,SAX解析
- cnblogs文章记录
- C语言文件读写
- 《疯狂的程序员》五
- C++ equal_range() 函数
- java数组遍历——iterator和for方法
- 端口和协议
- 扩大 vm虚拟机linux磁盘空间
- SyntaxError: Non-ASCII character Python中文处理