Last year, I made a simple desktop weather plug-in: appwidgetprovider, the android-like moji weather Desktop component, was easy to use and cannot be used by now, as a matter of fact, I always wanted to make some changes. Since I have been relatively lazy, I have been busy with work, and it will be almost a year in the twinkling of an eye. It's very easy to make improvements in recent days, but I think it is enough for weather applications. We don't need so many fancy functions. We can simply tell us the weather information. Well, let's take a look at the effect:
Download Baidu application APK:Http://as.baidu.com/a/item? Docid = 4064176 & Pre = web_am_se
Source Code address v1.0.0: http://download.csdn.net/detail/weidi1989/5768855
New Version v1.2.0 uploaded: http://download.csdn.net/detail/weidi1989/5951563
Changelog:
①. Add splashactivity to reduce the time required to access the application for a black screen and a better user experience.
②. Rewrite bladeview and fix the bug that popwindow is not closed yet, which will cause the program to be shut down abnormally.
③. Fixed the bug that retrieval failed due to changes to the Air Quality API.
④. Other minor details are optimized.
1. A simple desktop plug-in. The above is mine, and the following is moji weather. Of course, image resources are all from moji weather. The font is somewhat different, and the color is changed to white.
2. on the main interface, the image resources come from Netease news. Does it feel like the pictures are small and fresh? Haha, the title bar is similar to the moji weather function. The left side is city management, the right side is two buttons, one is automatic positioning, and the other is refreshing the weather. The top-right corner of the main interface below shows the Air Quality PM2.5 value, the middle is the weather conditions of the day, the following is the weather conditions in the next three days.
3. There are more than 2500 cities across the country.
4. automatic search is only available in three search modes: full search, city initials, and Chinese.
Okay! Today is Saturday, and I will not post the full code. It is estimated that no one will read it. Let's talk about the main ideas!
①. The weather information on the main interface is obtained by parsing three addresses.
Brief weather: http://www.weather.com.cn/data/sk/101280601.html.
Detailed weather: http://m.weather.com.cn/data/101280601.html
Air Quality: http://www.pm25.in/api/querys/pm2_5.json? City = Shenzhen & token = 5j1znbvasnsf5xqynqyq & Stations = No
Note that the token here for air quality is a public key, which can be requested 500 times per hour. Please do not request it frequently and leave some opportunity for other development engineers ~ Thank you.
②. I will not talk about the desktop plug-in here. The basic usage is quite detailed in the previous blog. I just optimized it here, optimized the service for maintaining plug-in updates so that it will not be easily recycled by the system. It seems that I still have to post code. I have done the following in the androidmanifest. xml file:
<receiver android:name="com.way.weather.WeatherWidget" android:label="@string/app_name" > <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.intent.action.USER_PRESENT" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/weather_widget_4x2" /> </receiver>
An additional android. intent. action. user_present event monitoring is actually a broadcast that listens to the system wake up. When the system is sleeping, our services are most likely to be recycled. Therefore, we listen to this broadcast. When the system wakes up, restart the service. This service will become more tenacious. I tested it for about three days, and no service was killed.
③. Let's focus on matching and searching the city list. First, for more than 2500 cities, it is impossible to read the database temporarily for quick matching. Therefore, when the application is started, you can read these 2000 cities from the database into the memory. Then, sort the first letter of the pinyin alphabet so that we can set the adapter of the listview. Let's take a look at the searchcityadapter of the search City: it implements the filterable interface, covering the getfilter function. This function is the most important part, the anonymous internal filter class matches the dynamically passed strings (such as the descrimfiltering function), and dynamically updates the adapter to implement dynamic search.
Public class searchcityadapter extends baseadapter implements filterable {private list <city> mallcities; private list <city> mresultcities; private layoutinflater minflater; private context mcontext; Public searchcityadapter (context, list <city> allcities) {mcontext = context; mallcities = allcities; mresultcities = new arraylist <city> (); minflater = layoutinflater. from (mcontext) ;}@ overridepublic in T getcount () {return mresultcities. size () ;}@ overridepublic city getitem (INT position) {return mresultcities. get (position) ;}@ overridepublic long getitemid (INT position) {return position ;}@ overridepublic view getview (INT position, view convertview, viewgroup parent) {If (convertview = NULL) {convertview = minflater. inflate (R. layout. search_city_item, null);} textview provincetv = (textview) convertvi Ew. findviewbyid (R. id. search_province); provincetv. settext (mresultcities. get (position ). getprovince (); textview citytv = (textview) convertview. findviewbyid (R. id. column_title); citytv. settext (mresultcities. get (position ). getcity (); Return convertview;} // the following code is crucial @ overridepublic filter getfilter () {filter = new filter () {protected void publishresults (charsequence constraint, filterresults resu Lts) {mresultcities = (arraylist <city>) results. values; If (results. count> 0) {policydatasetchanged ();} else {policydatasetinvalidated () ;}} protected filterresults specify mfiltering (charsequence s) {string STR = S. tostring (). touppercase (); // mfilterstr = STR; filterresults Results = new filterresults (); arraylist <city> citylist = new arraylist <city> (); If (mallcities! = NULL & mallcities. Size ()! = 0) {for (city CB: mallcities) {// match the full screen, first letter, and city name (if (CB. getallfristpy (). indexof (STR)>-1 | CB. getallpy (). indexof (STR)>-1 | CB. getcity (). indexof (STR)>-1) {citylist. add (CB) ;}} results. values = citylist; results. count = citylist. size (); return results ;}}; return filter ;}}
Next, let's take a look at how the data is passed to searchcityadapter for processing. I will post the function that listens for the dynamic change of edittext, msearchcityadapter. getfilter (). filter (s); in this way, you can. In fact, it is not very difficult!
@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {mSearchCityAdapter = new SearchCityAdapter(SelectCtiyActivity.this,mCities);mSearchListView.setAdapter(mSearchCityAdapter);mSearchListView.setTextFilterEnabled(true);if (mCities.size() < 1 || TextUtils.isEmpty(s)) {mCityContainer.setVisibility(View.VISIBLE);mSearchContainer.setVisibility(View.INVISIBLE);mClearSearchBtn.setVisibility(View.GONE);} else {mClearSearchBtn.setVisibility(View.VISIBLE);mCityContainer.setVisibility(View.INVISIBLE);mSearchContainer.setVisibility(View.VISIBLE);mSearchCityAdapter.getFilter().filter(s);}}
Now, I will introduce it here. If you want to know more, you can download the source code. Congratulations, you have seen the end of the article. I also went to bed and would like to have a good time tomorrow!