Revision | 97f614a850a22f8a4f8848ef727cb38a40da0a70 (tree) |
---|---|
Time | 2018-08-02 02:22:42 |
Author | HMML <hmml3939@gmai...> |
Commiter | HMML |
Try to replace ion with HttpURLConnection for workaround of weird semaphore lock error...
@@ -7,8 +7,8 @@ android { | ||
7 | 7 | applicationId "cloud.hmml.mmw" |
8 | 8 | minSdkVersion 17 |
9 | 9 | targetSdkVersion 27 |
10 | - versionCode 7 | |
11 | - versionName '0.4.3' | |
10 | + versionCode 8 | |
11 | + versionName '0.4.4' | |
12 | 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" |
13 | 13 | |
14 | 14 | } |
@@ -645,9 +645,7 @@ public class ConfigManager implements GoogleApiClient.ConnectionCallbacks, Googl | ||
645 | 645 | String ns = loadLocationNS(); |
646 | 646 | |
647 | 647 | if (ns != null && ns.equals(LOCATION_NS_JMA)) { |
648 | - if (!(new ForecastFetcher(this.getContext(), ns, loadLocationId())).save(this)) { | |
649 | - Log.e("cmgr", "Failed to get JMA forecat!"); | |
650 | - } | |
648 | + new ForecastFetcher(this.getContext(), ns, loadLocationId()).save(this); | |
651 | 649 | } |
652 | 650 | } |
653 | 651 |
@@ -1,17 +1,24 @@ | ||
1 | 1 | package cloud.hmml.mmw; |
2 | 2 | |
3 | 3 | import android.content.Context; |
4 | +import android.os.AsyncTask; | |
5 | +import android.os.Build; | |
4 | 6 | import android.util.Log; |
5 | 7 | |
6 | 8 | import com.google.gson.JsonElement; |
7 | 9 | import com.google.gson.JsonObject; |
8 | -import com.koushikdutta.ion.Ion; | |
10 | +import com.google.gson.JsonParser; | |
11 | +import com.google.gson.stream.JsonReader; | |
9 | 12 | |
13 | +import java.io.IOException; | |
14 | +import java.io.InputStreamReader; | |
15 | +import java.net.HttpURLConnection; | |
16 | +import java.net.MalformedURLException; | |
17 | +import java.net.URL; | |
10 | 18 | import java.text.ParseException; |
11 | 19 | import java.text.SimpleDateFormat; |
12 | 20 | import java.util.Calendar; |
13 | 21 | import java.util.Date; |
14 | -import java.util.concurrent.ExecutionException; | |
15 | 22 | |
16 | 23 | |
17 | 24 | public class ForecastFetcher { |
@@ -26,76 +33,137 @@ public class ForecastFetcher { | ||
26 | 33 | this.context = context; |
27 | 34 | } |
28 | 35 | |
29 | - public boolean save(ConfigManager config) { | |
30 | - JsonObject json = getJson(); | |
31 | - if (json == null) { | |
32 | - Log.e("forecast-fetcher", "Failed to fetch forecast JSON."); | |
33 | - return false; | |
34 | - } | |
36 | + public void save(ConfigManager config) { | |
37 | + this.save(config, null); | |
38 | + } | |
35 | 39 | |
36 | - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); | |
37 | - Date reportedAt = null; | |
38 | - Calendar reportedAtCal = null; | |
39 | - try { | |
40 | - reportedAt = df.parse(json.getAsJsonPrimitive("reported_at").getAsString()); | |
41 | - config.saveReportedAt(reportedAt); | |
42 | - } catch (ParseException e) { | |
43 | - Log.e("forecast-fetcher", "Failed to parse reported_at!"); | |
44 | - e.printStackTrace(); | |
45 | - } catch (NullPointerException e) { | |
46 | - // ignore! | |
47 | - } | |
48 | 40 | |
49 | - int index = 1; | |
50 | - for (JsonElement j: json.getAsJsonArray("daily_forecasts")) { | |
51 | - JsonObject day = j.getAsJsonObject(); | |
41 | + public void save(ConfigManager config, Runnable callback) { | |
52 | 42 | |
53 | - String label = day.getAsJsonPrimitive("weather_label").getAsString(); | |
54 | - String ident = day.getAsJsonPrimitive("weather_symbol").getAsString(); | |
55 | - Integer temp_max = null; | |
56 | - Integer temp_min = null; | |
57 | - Integer pop = null; | |
58 | - try { | |
59 | - temp_max = day.getAsJsonPrimitive("temp_max").getAsInt(); | |
60 | - } catch (ClassCastException e) { | |
61 | - // ignroe | |
62 | - } | |
63 | - try { | |
64 | - temp_min = day.getAsJsonPrimitive("temp_min").getAsInt(); | |
65 | - } catch (ClassCastException e) { | |
66 | - // ignroe | |
43 | + class JsonFetcher extends AsyncTask<Void, Void, JsonObject> { | |
44 | + private ConfigManager config; | |
45 | + private Runnable callback; | |
46 | + | |
47 | + public JsonFetcher(ConfigManager config, Runnable callback) { | |
48 | + this.config = config; | |
49 | + this.callback = callback; | |
67 | 50 | } |
68 | - try { | |
69 | - pop = day.getAsJsonPrimitive("pop").getAsInt(); | |
70 | - } catch (ClassCastException e) { | |
71 | - // ignroe | |
51 | + | |
52 | + @Override | |
53 | + protected JsonObject doInBackground(Void... voids) { | |
54 | + return ForecastFetcher.this.getJson(); | |
72 | 55 | } |
73 | 56 | |
74 | - config.saveWeather(index, ident, label, temp_min, temp_max, pop); | |
57 | + @Override | |
58 | + protected void onPostExecute(JsonObject json) { | |
59 | + if (json == null) { | |
60 | + Log.e("forecast-fetcher", "Failed to fetch forecast JSON."); | |
61 | + return; | |
62 | + } | |
63 | + | |
64 | + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); | |
65 | + Date reportedAt = null; | |
66 | + Calendar reportedAtCal = null; | |
67 | + try { | |
68 | + reportedAt = df.parse(json.getAsJsonPrimitive("reported_at").getAsString()); | |
69 | + config.saveReportedAt(reportedAt); | |
70 | + } catch (ParseException e) { | |
71 | + Log.e("forecast-fetcher", "Failed to parse reported_at!"); | |
72 | + e.printStackTrace(); | |
73 | + } catch (NullPointerException e) { | |
74 | + // ignore! | |
75 | + } | |
76 | + | |
77 | + int index = 1; | |
78 | + for (JsonElement j: json.getAsJsonArray("daily_forecasts")) { | |
79 | + JsonObject day = j.getAsJsonObject(); | |
80 | + | |
81 | + String label = day.getAsJsonPrimitive("weather_label").getAsString(); | |
82 | + String ident = day.getAsJsonPrimitive("weather_symbol").getAsString(); | |
83 | + Integer temp_max = null; | |
84 | + Integer temp_min = null; | |
85 | + Integer pop = null; | |
86 | + try { | |
87 | + temp_max = day.getAsJsonPrimitive("temp_max").getAsInt(); | |
88 | + } catch (ClassCastException e) { | |
89 | + // ignroe | |
90 | + } | |
91 | + try { | |
92 | + temp_min = day.getAsJsonPrimitive("temp_min").getAsInt(); | |
93 | + } catch (ClassCastException e) { | |
94 | + // ignroe | |
95 | + } | |
96 | + try { | |
97 | + pop = day.getAsJsonPrimitive("pop").getAsInt(); | |
98 | + } catch (ClassCastException e) { | |
99 | + // ignroe | |
100 | + } | |
101 | + | |
102 | + config.saveWeather(index, ident, label, temp_min, temp_max, pop); | |
103 | + | |
104 | + index++; | |
105 | + if (index > 2) break; | |
106 | + } | |
75 | 107 | |
76 | - index++; | |
77 | - if (index > 2) break; | |
108 | + config.saveUpdatedAt(); | |
109 | + Log.d("forecast-fetcher", "Forecast has been fetched successfully."); | |
110 | + if (callback != null) | |
111 | + callback.run(); | |
112 | + } | |
78 | 113 | } |
79 | 114 | |
80 | - config.saveUpdatedAt(); | |
81 | - Log.d("forecast-fetcher", "Forecast has been fetched successfully."); | |
82 | - return true; | |
115 | + new JsonFetcher(config, callback).execute(); | |
83 | 116 | } |
84 | 117 | |
85 | - private JsonObject getJson() { | |
118 | + protected JsonObject getJson() { | |
119 | + URL url = null; | |
120 | + HttpURLConnection httpconn = null; | |
121 | + try { | |
122 | + url = new URL(BASE_URL + areaNs + "/" + areaId + ".json"); | |
123 | + } catch (MalformedURLException e) { | |
124 | + Log.e("forecast-fetcher", "BAD URL on getting json: " + e.getMessage()); | |
125 | + e.printStackTrace(); | |
126 | + return null; | |
127 | + } | |
86 | 128 | try { |
87 | - return Ion.with(this.context) | |
88 | - .load(BASE_URL + areaNs + "/" + areaId + ".json") | |
89 | - .setHeader("X-Requested-With", "Android cloud.hmml.mmw") | |
90 | - .asJsonObject().get(); | |
91 | - } catch (InterruptedException e) { | |
92 | - Log.e("forecast-fetcher", "Exception in fetching json: " + e.getMessage()); | |
129 | + httpconn = (HttpURLConnection) url.openConnection(); | |
130 | + } catch (IOException e) { | |
131 | + Log.e("forecast-fetcher", "Failed to open connection to get JSON: " + e.getMessage()); | |
93 | 132 | e.printStackTrace(); |
94 | 133 | return null; |
95 | - } catch (ExecutionException e) { | |
96 | - Log.e("forecast-fetcher", "ExecutionException in fetching json: "+e.getMessage()); | |
134 | + } | |
135 | + httpconn.addRequestProperty("X-Requested-With", "Android cloud.hmml.mmw"); | |
136 | + httpconn.addRequestProperty("User-Agent", "cloud.hmml.mmw/" + BuildConfig.VERSION_NAME + " (Android " + Build.VERSION.RELEASE + "; " + Build.DEVICE + ")"); | |
137 | + try { | |
138 | + httpconn.connect(); | |
139 | + } catch (IOException e) { | |
140 | + Log.e("forecast-fetcher", "Failed to request to get JSON: " + e.getMessage()); | |
97 | 141 | e.printStackTrace(); |
98 | 142 | return null; |
99 | 143 | } |
144 | + | |
145 | + try { | |
146 | + try { | |
147 | + int retcode = httpconn.getResponseCode(); | |
148 | + if (retcode != 200) { | |
149 | + Log.e("forecast-fetcher", "Invalid return code " + retcode + " on getting JSON"); | |
150 | + return null; | |
151 | + } | |
152 | + } catch (IOException e) { | |
153 | + Log.e("forecast-fetcher", "Failed to get response code on getting JSON: " + e.getMessage()); | |
154 | + e.printStackTrace(); | |
155 | + return null; | |
156 | + } | |
157 | + | |
158 | + try { | |
159 | + return (new JsonParser()).parse(new JsonReader(new InputStreamReader(httpconn.getInputStream()))).getAsJsonObject(); | |
160 | + } catch (IOException e) { | |
161 | + Log.e("forecast-fetcher", "Failed to read stream data on getting JSON: " + e.getMessage()); | |
162 | + e.printStackTrace(); | |
163 | + return null; | |
164 | + } | |
165 | + } finally { | |
166 | + httpconn.disconnect(); | |
167 | + } | |
100 | 168 | } |
101 | 169 | } |