码迷,mamicode.com
首页 > 其他好文 > 详细

自己实现简单的天气预报应用(8)

时间:2015-03-06 20:32:06      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:

 

8.加入服务来实现自动更新和时钟功能

 

新建一个服务类,通过发送Intent来通知AppWidgetProvider:

  1 import android.app.AlarmManager;
  2 import android.app.IntentService;
  3 import android.app.PendingIntent;
  4 import android.content.Context;
  5 import android.content.Intent;
  6 import android.net.ConnectivityManager;
  7 import android.widget.Toast;
  8 
  9 import com.android.volley.Request;
 10 import com.android.volley.RequestQueue;
 11 import com.android.volley.Response;
 12 import com.android.volley.VolleyError;
 13 import com.android.volley.toolbox.JsonObjectRequest;
 14 import com.android.volley.toolbox.Volley;
 15 
 16 import org.json.JSONException;
 17 import org.json.JSONObject;
 18 
 19 import java.io.File;
 20 import java.io.IOException;
 21 import java.util.ArrayList;
 22 
 23 public class UpdateService extends IntentService {
 24 
 25     //这个是用来后台更新数据的,就是只是检查有无新数据的
 26 
 27     private static final String TAG="UpdateService";
 28     private static final String url="http://api.k780.com:88/?app=weather.future&weaid=101270101&appkey=13217&sign=efb0ccae3443e25fe2238e5bb2f83bba&format=json";
 29     private static final int WEATHER_ALARM_CLOCK=3600000;
 30 
 31     private static File configure;
 32     private static boolean hasNew;
 33     private static ArrayList<WeatherItem> weatherItems=new ArrayList<>();
 34 
 35     public UpdateService() {
 36         super(TAG);
 37         hasNew=false;
 38     }
 39 
 40     public static void setServiceAlarm(Context context,boolean isOn){
 41         Intent intent=new Intent(context,UpdateService.class);
 42         PendingIntent pi=PendingIntent.getService(context,0,intent,0);
 43         AlarmManager alarmManager=(AlarmManager)context.getSystemService(ALARM_SERVICE);
 44         if(isOn){
 45             alarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), WEATHER_ALARM_CLOCK, pi);
 46         }else {
 47             alarmManager.cancel(pi);
 48             pi.cancel();
 49         }
 50     }
 51 
 52     @Override
 53     protected void onHandleIntent(Intent intent) {
 54         ConnectivityManager cm=(ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);
 55         boolean isNetWorkAvailable=cm.getBackgroundDataSetting() && cm.getActiveNetworkInfo()!=null;
 56         if(!isNetWorkAvailable){
 57             return;
 58         }
 59         configure=new File(getFilesDir()+"/"+FileTools.conf);
 60         update();
 61         Intent i=new Intent();
 62         i.setAction(WeatherWidgetProvider.UPDATE_DATA);
 63         sendBroadcast(i);
 64     }
 65 
 66     private void update(){
 67 
 68         if(!configure.exists()){
 69             Toast.makeText(getApplicationContext(), R.string.fetching, Toast.LENGTH_SHORT).show();
 70             fetchData();
 71         }else{
 72             try{
 73                 hasNew = !(DateTools.getDate().equals(FileTools.loadConf(getApplicationContext())));
 74             }catch (IOException e){
 75                 e.printStackTrace();
 76             }
 77             if(hasNew){
 78                 Toast.makeText(getApplicationContext(),R.string.fetching,Toast.LENGTH_SHORT).show();
 79                 fetchData();
 80             }
 81         }
 82     }
 83 
 84     private void fetchData(){
 85         RequestQueue mQueue= Volley.newRequestQueue(getApplicationContext());
 86         mQueue.add(new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
 87             @Override
 88             public void onResponse(JSONObject jsonObject) {
 89                 //服务器有响应的时候才会调用此方法
 90                 try {
 91                     weatherItems = ParseTools.getInstance(jsonObject.toString(),ParseTools.REQUEST_RAW);
 92                     //保存数据到文件
 93                     FileTools.saveData(getApplicationContext(),weatherItems);
 94                     Toast.makeText(getApplicationContext(),"更新完毕",Toast.LENGTH_SHORT).show();
 95                     FileTools.saveWidgetData(getApplicationContext(), weatherItems.get(0));
 96                 } catch (JSONException | IOException e) {
 97                     e.printStackTrace();
 98                 }
 99             }
100         }, new Response.ErrorListener() {
101             @Override
102             public void onErrorResponse(VolleyError volleyError) {
103                 Toast.makeText(getApplicationContext(), "获取失败", Toast.LENGTH_SHORT).show();
104             }
105         }));
106         mQueue.start();
107     }
108 
109     @Override
110     public void onDestroy() {
111         super.onDestroy();
112     }
113 }

 

然后onReceive接受:

 1 import android.appwidget.AppWidgetManager;
 2 import android.appwidget.AppWidgetProvider;
 3 import android.content.ComponentName;
 4 import android.content.Context;
 5 import android.content.Intent;
 6 import android.text.format.DateFormat;
 7 import android.widget.RemoteViews;
 8 
 9 import org.json.JSONException;
10 
11 import java.io.IOException;
12 import java.util.Date;
13 
14 //管理所有Widget的类
15 @SuppressWarnings("NullableProblems")
16 public class WeatherWidgetProvider extends AppWidgetProvider {
17 
18     public static final String UPDATE_DATA="action.appwidget.SEND_DATA";
19     public static final String UPDATE_TIME="action.appwidget.UPDATE_TIME";
20     private static WeatherItem mItem;//这里必须使用静态成员
21 
22     @Override
23     public void onReceive(Context context, Intent intent) {
24         RemoteViews rv=new RemoteViews(context.getPackageName(),R.layout.widget_layout);
25         AppWidgetManager appWidgetManager=AppWidgetManager.getInstance(context);
26         ComponentName componentName=new ComponentName(context,WeatherWidgetProvider.class);
27         int[] appWidgetIds=appWidgetManager.getAppWidgetIds(componentName);
28         switch (intent.getAction()){
29             case UPDATE_DATA:
30                 for(int appWidgetId : appWidgetIds){
31                     rv.setTextViewText(R.id.date, mItem.getDate());
32                     rv.setTextViewText(R.id.week,mItem.getWeek());
33                     rv.setTextViewText(R.id.weather,mItem.getWeather());
34                     rv.setTextViewText(R.id.temp,mItem.getTemp_low() + "~" + mItem.getTemp_high() + "℃");
35                     rv.setTextViewText(R.id.wind,mItem.getWind());
36                     appWidgetManager.updateAppWidget(appWidgetId,rv);
37                 }
38                 break;
39             case UPDATE_TIME:
40                 for(int appWidgetId : appWidgetIds){
41                     rv.setTextViewText(R.id.time, DateFormat.format("kk:mm",new Date()));
42                     appWidgetManager.updateAppWidget(appWidgetId,rv);
43                 }
44                 break;
45         }
46         super.onReceive(context, intent);
47     }
48 
49     @Override
50     public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
51         RemoteViews rv;
52         try{
53             mItem = FileTools.loadWidgetData(context);
54         }catch (IOException | JSONException e){
55             e.printStackTrace();
56         }
57         if(mItem != null){
58             rv = new RemoteViews(context.getPackageName(),R.layout.widget_layout);
59             rv.setTextViewText(R.id.date,mItem.getDate());
60         }else{
61             rv = new RemoteViews(context.getPackageName(),R.layout.widget_void_layout);
62         }
63 
64         for(int appWidgetId : appWidgetIds){
65             appWidgetManager.updateAppWidget(appWidgetId,rv);
66         }
67         super.onUpdate(context, appWidgetManager, appWidgetIds);
68     }
69 
70     @Override
71     public void onEnabled(Context context) {
72         super.onEnabled(context);
73         TimeService.setTimeAlarm(context,true);
74         UpdateService.setServiceAlarm(context,true);
75     }
76 
77     @Override
78     public void onDisabled(Context context) {
79         super.onDisabled(context);
80         TimeService.setTimeAlarm(context,false);
81         UpdateService.setServiceAlarm(context,false);
82     }
83 }

 

这里面有一个实现时钟功能的Service:

 1 import android.app.AlarmManager;
 2 import android.app.IntentService;
 3 import android.app.PendingIntent;
 4 import android.content.Context;
 5 import android.content.Intent;
 6 
 7 public class TimeService extends IntentService {
 8     private static final String TAG="TimeService";
 9     private static final int TIME_ALARM_CLOCK=1000;
10 
11     public TimeService() {
12         super(TAG);
13     }
14 
15     public static void setTimeAlarm(Context context, boolean isOn){
16         Intent intent=new Intent(context,TimeService.class);
17         PendingIntent pi=PendingIntent.getService(context,0,intent,0);
18         AlarmManager alarmManager=(AlarmManager)context.getSystemService(ALARM_SERVICE);
19         if(isOn){
20             alarmManager.setRepeating(AlarmManager.RTC,System.currentTimeMillis(),TIME_ALARM_CLOCK,pi);
21         }else{
22             alarmManager.cancel(pi);
23             pi.cancel();
24         }
25     }
26 
27     @Override
28     protected void onHandleIntent(Intent intent) {
29         Intent i = new Intent();
30         i.setAction(WeatherWidgetProvider.UPDATE_TIME);
31         sendBroadcast(i);
32     }
33 }

 

当然这些数据必须要在manifest中定义节点:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="                                " >
 4 
 5     <uses-permission android:name="android.permission.INTERNET"/>
 6     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
 7 
 8     <application
 9         android:allowBackup="true"
10         android:icon="@drawable/ic_launcher"
11         android:label="@string/app_name"
12         android:theme="@style/AppTheme" >
13         <activity
14             android:name=".MainActivity"
15             android:label="@string/app_name" >
16             <intent-filter>
17                 <action android:name="android.intent.action.MAIN" />
18 
19                 <category android:name="android.intent.category.LAUNCHER" />
20             </intent-filter>
21         </activity>
22 
23         <receiver android:name=".WeatherWidgetProvider" android:label="@string/weather">
24             <intent-filter>
25                 <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
26                 <action android:name="action.appwidget.SEND_DATA"/>
27                 <action android:name="action.appwidget.UPDATE_TIME"/>
28             </intent-filter>
29             <meta-data android:name="android.appwidget.provider"
30                 android:resource="@xml/widget_info"/>
31         </receiver>
32         <service android:name=".UpdateService"/>
33         <service android:name=".TimeService"/>
34     </application>
35 </manifest>

 

所有这些东西完成之后Widget效果如下,测试的过程中还是有些Bug:

技术分享

 

所有的东西就是这样的,github地址:https://github.com/wylhyz/TimeAndWeather

自己实现简单的天气预报应用(8)

标签:

原文地址:http://www.cnblogs.com/lhyz/p/4319098.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!