Android之高仿墨迹天气桌面组件(AppWidgetProvider) .
点击:382 发布时间:2012-10-03
更多0

相信墨迹天气,大家都见过,他在时间显示和天气界面上,很吸引人,今天我就来模仿一下墨迹天气的桌面组件,但是由于谷歌在天朝频频被墙的缘故,所以我在今天测试的时候,解析xml文件的网页打不开,所以天气显示出了点问题,希望大家能理解,谢谢。(今天9月24日修改为解析中国天气网获取天气了,而且修改组件在桌面居中显示)。

老规矩,先分享源代码:http://download.csdn.net/detail/weidi1989/4597809

好了,废话不多说,先上效果图:

  

再来看一下整个小项目的主体结构:

首先先声明一个桌面布局的xml文件,即app.xml:

[html] view plaincopyprint?
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!--
  3. 指定该桌面组件的基本配置信息:
  4. initialLayout:初始时显示的布局
  5. minWidth:桌面小控件的最小高度。
  6. minWidth:桌面小控件的最小宽度。
  7. updatePeriodMillis:更新频率
  8. -->
  9. <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
  10. android:initialLayout="@layout/main"
  11. android:minHeight="150dp"
  12. android:minWidth="200dp"
  13. android:updatePeriodMillis="0" >
  14. </appwidget-provider>
<?xml version="1.0" encoding="utf-8"?>
<!--指定该桌面组件的基本配置信息:initialLayout:初始时显示的布局minWidth:桌面小控件的最小高度。minWidth:桌面小控件的最小宽度。updatePeriodMillis:更新频率
-->
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"android:initialLayout="@layout/main"android:minHeight="150dp"android:minWidth="200dp"android:updatePeriodMillis="0" ></appwidget-provider>

然后要在manifest文件中声明:

[html] view plaincopyprint?
  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2. package="com.way.apptest"
  3. android:versionCode="1"
  4. android:versionName="1.0" >
  5. <uses-sdk
  6. android:minSdkVersion="8"
  7. android:targetSdkVersion="15" />
  8. <uses-permission android:name="android.permission.INTERNET" />
  9. <application
  10. android:icon="@drawable/ic_launcher"
  11. android:label="@string/app_name"
  12. android:theme="@style/AppTheme" >
  13. <activity android:name="com.way.apptest.MainActivity" >
  14. </activity>
  15. <receiver android:name="com.way.apptest.App" >
  16. <!-- 指定桌面小控件的meta-data -->
  17. <meta-data
  18. android:name="android.appwidget.provider"
  19. android:resource="@xml/app" />
  20. <!-- 将该BroadcastReceiver当成桌面小控件 -->
  21. <intent-filter>
  22. <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
  23. </intent-filter>
  24. </receiver>
  25. <service android:name=".UpdateService" >
  26. </service>
  27. </application>
  28. </manifest>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.way.apptest"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="8"android:targetSdkVersion="15" /><uses-permission android:name="android.permission.INTERNET" /><applicationandroid:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activity android:name="com.way.apptest.MainActivity" ></activity><receiver android:name="com.way.apptest.App" ><!-- 指定桌面小控件的meta-data --><meta-dataandroid:name="android.appwidget.provider"android:resource="@xml/app" /><!-- 将该BroadcastReceiver当成桌面小控件 --><intent-filter><action android:name="android.appwidget.action.APPWIDGET_UPDATE" /></intent-filter></receiver><service android:name=".UpdateService" ></service></application></manifest>

主要代码:

一:定义一个App类继承AppWidgetProvider,然后再onUpdate方法中启动一个服务去更新时间和天气。

[java] view plaincopyprint?
  1. /**
  2. * @author way
  3. */
  4. public class App extends AppWidgetProvider {
  5. private Intent intent;
  6. @Override
  7. public void onUpdate(Context context, AppWidgetManager appWidgetManager,
  8. int[] appWidgetIds) {
  9. intent = new Intent(context, UpdateService.class);
  10. context.startService(intent);
  11. super.onUpdate(context, appWidgetManager, appWidgetIds);
  12. }
  13. @Override
  14. public void onDeleted(Context context, int[] appWidgetIds) {
  15. context.stopService(intent);
  16. super.onDeleted(context, appWidgetIds);
  17. }
  18. }
/*** @author way*/
public class App extends AppWidgetProvider {private Intent intent;@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {intent = new Intent(context, UpdateService.class);context.startService(intent);super.onUpdate(context, appWidgetManager, appWidgetIds);}@Overridepublic void onDeleted(Context context, int[] appWidgetIds) {context.stopService(intent);super.onDeleted(context, appWidgetIds);}
}

二:本项目中最重要的部分,在这个服务中,我们注册一个广播接收者去接受系统每分钟时间时间变化的广播,从而来更新桌面时间,这样更省电哦,需要注意的是:这个广播接收者必须在代码中注册,在Manifest文件中注册是没有效果的。更新天气,我是通过定义一个定时器,由用户设置时间间隔来更新天气信息。

[java] view plaincopyprint?
  1. package com.way.apptest;
  2. import java.text.SimpleDateFormat;
  3. import java.util.Date;
  4. import java.util.Timer;
  5. import java.util.TimerTask;
  6. import android.app.AlertDialog;
  7. import android.app.PendingIntent;
  8. import android.app.Service;
  9. import android.appwidget.AppWidgetManager;
  10. import android.content.BroadcastReceiver;
  11. import android.content.ComponentName;
  12. import android.content.Context;
  13. import android.content.DialogInterface;
  14. import android.content.Intent;
  15. import android.content.IntentFilter;
  16. import android.net.ConnectivityManager;
  17. import android.net.NetworkInfo;
  18. import android.os.Handler;
  19. import android.os.IBinder;
  20. import android.os.Message;
  21. import android.widget.RemoteViews;
  22. import com.way.getWeather.MyWeather;
  23. /**
  24. * @author way
  25. */
  26. public class UpdateService extends Service {
  27. private static final int UPDATE = 0x123;
  28. private RemoteViews remoteViews;
  29. // 数字时间图片资源数组
  30. private int[] imgs = { R.drawable.n0, R.drawable.n1, R.drawable.n2,
  31. R.drawable.n3, R.drawable.n4, R.drawable.n5, R.drawable.n6,
  32. R.drawable.n7, R.drawable.n8, R.drawable.n9, };
  33. // 将显示小时、分钟的ImageView定义成数组
  34. private int[] dateViews = { R.id.h1, R.id.h2, R.id.m1, R.id.m2 };
  35. // 按照中国天气网的天气图片顺序排列好本地资源图片,我这里是随意的~嘿嘿
  36. private int[] weatherImg = { R.drawable.sunny, R.drawable.cloudy,
  37. R.drawable.chance_of_rain, R.drawable.chance_of_sleet,
  38. R.drawable.chance_of_snow, R.drawable.chance_of_storm,
  39. R.drawable.clock1, R.drawable.fog, R.drawable.haze,
  40. R.drawable.mist, R.drawable.mostly_sunny, R.drawable.mostly_cloudy,
  41. R.drawable.lower, R.drawable.middle };
  42. private Handler handler = new Handler() {
  43. @Override
  44. public void handleMessage(Message msg) {
  45. switch (msg.what) {
  46. case UPDATE:
  47. // 更新天气
  48. updateTime();
  49. updateWeather();
  50. break;
  51. }
  52. }
  53. };
  54. // 广播接收者去接收系统每分钟的提示广播,来更新时间
  55. private BroadcastReceiver mTimePickerBroadcast = new BroadcastReceiver() {
  56. @Override
  57. public void onReceive(Context context, Intent intent) {
  58. updateTime();
  59. }
  60. };
  61. private void updateWeather() {
  62. // Weather w = new GetWeather().googleWeather();
  63. // if (w != null) {
  64. // System.out.println("当前天气:" + w.getWeather() + ":" + w.getTemp_c()
  65. // + ":" + w.getIcon());
  66. remoteViews.setTextViewText(R.id.condition, MyWeather.weather1);
  67. remoteViews.setTextViewText(R.id.tem, (MyWeather.temp1));
  68. // 根据图片名,获取天气图片资源
  69. // remoteViews.setImageViewResource(
  70. // R.id.weather,
  71. // getApplicationContext().getResources().getIdentifier(
  72. // w.getIcon(), "drawable", "com.way.apptest"));
  73. if (MyWeather.img1 != null || !"".equals(MyWeather.img1))
  74. remoteViews.setImageViewResource(R.id.weather,
  75. weatherImg[Integer.parseInt(MyWeather.img1)]);
  76. // 执行更新
  77. ComponentName componentName = new ComponentName(
  78. getApplicationContext(), App.class);
  79. AppWidgetManager.getInstance(getApplicationContext()).updateAppWidget(
  80. componentName, remoteViews);
  81. }
  82. @Override
  83. public IBinder onBind(Intent intent) {
  84. return null;
  85. }
  86. @Override
  87. public void onCreate() {
  88. super.onCreate();
  89. remoteViews = new RemoteViews(getApplication().getPackageName(),
  90. R.layout.main);// 实例化RemoteViews
  91. if (isNetworkAvailable()) {
  92. MyWeather.getWeather();// json解析中国天气网天气
  93. } else {
  94. toast();
  95. }
  96. updateTime();// 第一次运行时先更新一下时间和天气
  97. updateWeather();
  98. // 点击天气图片,进入MainActivity
  99. Intent intent = new Intent(getApplicationContext(), MainActivity.class);
  100. PendingIntent pi = PendingIntent.getActivity(getApplicationContext(),
  101. 0, intent, 0);
  102. remoteViews.setOnClickPendingIntent(R.id.weather, pi);
  103. // 定义一个定时器去更新天气。实际开发中更新时间间隔可以由用户设置,
  104. new Timer().scheduleAtFixedRate(new TimerTask() {
  105. @Override
  106. public void run() {
  107. Message msg = handler.obtainMessage();
  108. msg.what = UPDATE;
  109. handler.sendMessage(msg);
  110. }
  111. }, 1, 3600 * 1000);// 每小时更新一次天气
  112. }
  113. private void updateTime() {
  114. Date date = new Date();
  115. // 定义SimpleDateFormat对象
  116. SimpleDateFormat df = new SimpleDateFormat("HHmm");
  117. // 将当前时间格式化成HHmm的形式
  118. String timeStr = df.format(date);
  119. for (int i = 0; i < timeStr.length(); i++) {
  120. // 将第i个数字字符转换为对应的数字
  121. int num2 = Integer.parseInt(timeStr.substring(i, i + 1));
  122. // 将第i个图片的设为对应的数字图片
  123. remoteViews.setImageViewResource(dateViews[i], imgs[num2]);
  124. }
  125. remoteViews.setTextViewText(R.id.city, MyWeather.city);
  126. remoteViews.setTextViewText(R.id.date, "0" + (date.getMonth() + 1)
  127. + "-" + date.getDate() + " 周" + date.getDay());
  128. ComponentName componentName = new ComponentName(getApplication(),
  129. App.class);
  130. AppWidgetManager.getInstance(getApplication()).updateAppWidget(
  131. componentName, remoteViews);
  132. }
  133. @Override
  134. public void onStart(Intent intent, int startId) {
  135. // 注册系统每分钟提醒广播(注意:这个广播只能在代码中注册)
  136. IntentFilter updateIntent = new IntentFilter();
  137. updateIntent.addAction("android.intent.action.TIME_TICK");
  138. registerReceiver(mTimePickerBroadcast, updateIntent);
  139. super.onStart(intent, startId);
  140. }
  141. @Override
  142. public void onDestroy() {
  143. // 注销系统的这个广播
  144. unregisterReceiver(mTimePickerBroadcast);
  145. //被系统干掉后,服务重启,做一次流氓软件,哈哈
  146. Intent intent = new Intent(getApplicationContext(), UpdateService.class);
  147. getApplication().startService(intent);
  148. super.onDestroy();
  149. }
  150. /**
  151. * 判断手机网络是否可用
  152. *
  153. * @param context
  154. * @return
  155. */
  156. private boolean isNetworkAvailable() {
  157. ConnectivityManager mgr = (ConnectivityManager) getApplicationContext()
  158. .getSystemService(Context.CONNECTIVITY_SERVICE);
  159. NetworkInfo[] info = mgr.getAllNetworkInfo();
  160. if (info != null) {
  161. for (int i = 0; i < info.length; i++) {
  162. if (info[i].getState() == NetworkInfo.State.CONNECTED) {
  163. return true;
  164. }
  165. }
  166. }
  167. return false;
  168. }
  169. private void toast() {
  170. new AlertDialog.Builder(getApplicationContext())
  171. .setTitle("提示")
  172. .setMessage("网络连接未打开")
  173. .setPositiveButton("前往打开",
  174. new DialogInterface.OnClickListener() {
  175. public void onClick(DialogInterface dialog,
  176. int which) {
  177. Intent intent = new Intent(
  178. android.provider.Settings.ACTION_WIRELESS_SETTINGS);
  179. startActivity(intent);
  180. }
  181. }).setNegativeButton("取消", null).create().show();
  182. }
  183. }
package com.way.apptest;import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.widget.RemoteViews;import com.way.getWeather.MyWeather;/*** @author way*/
public class UpdateService extends Service {private static final int UPDATE = 0x123;private RemoteViews remoteViews;// 数字时间图片资源数组private int[] imgs = { R.drawable.n0, R.drawable.n1, R.drawable.n2,R.drawable.n3, R.drawable.n4, R.drawable.n5, R.drawable.n6,R.drawable.n7, R.drawable.n8, R.drawable.n9, };// 将显示小时、分钟的ImageView定义成数组private int[] dateViews = { R.id.h1, R.id.h2, R.id.m1, R.id.m2 };// 按照中国天气网的天气图片顺序排列好本地资源图片,我这里是随意的~嘿嘿private int[] weatherImg = { R.drawable.sunny, R.drawable.cloudy,R.drawable.chance_of_rain, R.drawable.chance_of_sleet,R.drawable.chance_of_snow, R.drawable.chance_of_storm,R.drawable.clock1, R.drawable.fog, R.drawable.haze,R.drawable.mist, R.drawable.mostly_sunny, R.drawable.mostly_cloudy,R.drawable.lower, R.drawable.middle };private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case UPDATE:// 更新天气updateTime();updateWeather();break;}}};// 广播接收者去接收系统每分钟的提示广播,来更新时间private BroadcastReceiver mTimePickerBroadcast = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {updateTime();}};private void updateWeather() {// Weather w = new GetWeather().googleWeather();// if (w != null) {// System.out.println("当前天气:" + w.getWeather() + ":" + w.getTemp_c()// + ":" + w.getIcon());remoteViews.setTextViewText(R.id.condition, MyWeather.weather1);remoteViews.setTextViewText(R.id.tem, (MyWeather.temp1));// 根据图片名,获取天气图片资源// remoteViews.setImageViewResource(// R.id.weather,// getApplicationContext().getResources().getIdentifier(// w.getIcon(), "drawable", "com.way.apptest"));if (MyWeather.img1 != null || !"".equals(MyWeather.img1)) remoteViews.setImageViewResource(R.id.weather,weatherImg[Integer.parseInt(MyWeather.img1)]);// 执行更新ComponentName componentName = new ComponentName(getApplicationContext(), App.class);AppWidgetManager.getInstance(getApplicationContext()).updateAppWidget(componentName, remoteViews);}@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();remoteViews = new RemoteViews(getApplication().getPackageName(),R.layout.main);// 实例化RemoteViewsif (isNetworkAvailable()) {MyWeather.getWeather();// json解析中国天气网天气} else {toast();}updateTime();// 第一次运行时先更新一下时间和天气updateWeather();// 点击天气图片,进入MainActivityIntent intent = new Intent(getApplicationContext(), MainActivity.class);PendingIntent pi = PendingIntent.getActivity(getApplicationContext(),0, intent, 0);remoteViews.setOnClickPendingIntent(R.id.weather, pi);// 定义一个定时器去更新天气。实际开发中更新时间间隔可以由用户设置,new Timer().scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {Message msg = handler.obtainMessage();msg.what = UPDATE;handler.sendMessage(msg);}}, 1, 3600 * 1000);// 每小时更新一次天气}private void updateTime() {Date date = new Date();// 定义SimpleDateFormat对象SimpleDateFormat df = new SimpleDateFormat("HHmm");// 将当前时间格式化成HHmm的形式String timeStr = df.format(date);for (int i = 0; i < timeStr.length(); i++) {// 将第i个数字字符转换为对应的数字int num2 = Integer.parseInt(timeStr.substring(i, i + 1));// 将第i个图片的设为对应的数字图片remoteViews.setImageViewResource(dateViews[i], imgs[num2]);}remoteViews.setTextViewText(R.id.city, MyWeather.city);remoteViews.setTextViewText(R.id.date, "0" + (date.getMonth() + 1)+ "-" + date.getDate() + " 周" + date.getDay());ComponentName componentName = new ComponentName(getApplication(),App.class);AppWidgetManager.getInstance(getApplication()).updateAppWidget(componentName, remoteViews);}@Overridepublic void onStart(Intent intent, int startId) {// 注册系统每分钟提醒广播(注意:这个广播只能在代码中注册)IntentFilter updateIntent = new IntentFilter();updateIntent.addAction("android.intent.action.TIME_TICK");registerReceiver(mTimePickerBroadcast, updateIntent);super.onStart(intent, startId);}@Overridepublic void onDestroy() {// 注销系统的这个广播unregisterReceiver(mTimePickerBroadcast);//被系统干掉后,服务重启,做一次流氓软件,哈哈Intent intent = new Intent(getApplicationContext(), UpdateService.class);getApplication().startService(intent); super.onDestroy();}/*** 判断手机网络是否可用* * @param context* @return*/private boolean isNetworkAvailable() {ConnectivityManager mgr = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo[] info = mgr.getAllNetworkInfo();if (info != null) {for (int i = 0; i < info.length; i++) {if (info[i].getState() == NetworkInfo.State.CONNECTED) {return true;}}}return false;}private void toast() {new AlertDialog.Builder(getApplicationContext()).setTitle("提示").setMessage("网络连接未打开").setPositiveButton("前往打开",new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog,int which) {Intent intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS);startActivity(intent);}}).setNegativeButton("取消", null).create().show();}
}

三:这是桌面组件主要布局文件,如果大家有什么好的建议,欢迎提,本人对布局不是特别擅长。

[html] view plaincopyprint?
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@+id/bg"
  4. android:layout_width="wrap_content"
  5. android:layout_height="wrap_content"
  6. android:layout_gravity="center"
  7. android:background="@drawable/ww_bg"
  8. android:orientation="vertical" >
  9. <LinearLayout
  10. android:id="@+id/time"
  11. android:layout_width="wrap_content"
  12. android:layout_height="wrap_content"
  13. android:layout_gravity="center"
  14. android:orientation="horizontal" >
  15. <LinearLayout
  16. android:id="@+id/linearLayout1"
  17. android:layout_width="wrap_content"
  18. android:layout_height="wrap_content"
  19. android:background="@drawable/wd_bg"
  20. android:orientation="horizontal" >
  21. <ImageView
  22. android:id="@+id/h1"
  23. android:layout_width="wrap_content"
  24. android:layout_height="fill_parent"
  25. android:paddingLeft="10dip"
  26. android:src="@drawable/n0" />
  27. <ImageView
  28. android:id="@+id/h2"
  29. android:layout_width="wrap_content"
  30. android:layout_height="fill_parent"
  31. android:src="@drawable/n0" />
  32. </LinearLayout>
  33. <TextView
  34. android:layout_width="30dip"
  35. android:layout_height="wrap_content" />
  36. <LinearLayout
  37. android:id="@+id/linearLayout2"
  38. android:layout_width="wrap_content"
  39. android:layout_height="wrap_content"
  40. android:background="@drawable/wd_bg"
  41. android:orientation="horizontal" >
  42. <ImageView
  43. android:id="@+id/m1"
  44. android:layout_width="wrap_content"
  45. android:layout_height="match_parent"
  46. android:paddingLeft="10dip"
  47. android:src="@drawable/n0" />
  48. <ImageView
  49. android:id="@+id/m2"
  50. android:layout_width="wrap_content"
  51. android:layout_height="match_parent"
  52. android:src="@drawable/n0" />
  53. </LinearLayout>
  54. </LinearLayout>
  55. <LinearLayout
  56. android:id="@+id/linearLayout3"
  57. android:layout_width="wrap_content"
  58. android:layout_height="wrap_content"
  59. android:layout_gravity="center_horizontal"
  60. android:gravity="center"
  61. android:orientation="horizontal" >
  62. <LinearLayout
  63. android:layout_width="100dip"
  64. android:layout_height="wrap_content"
  65. android:orientation="vertical"
  66. android:paddingLeft="10dip" >
  67. <TextView
  68. android:id="@+id/city"
  69. android:layout_width="wrap_content"
  70. android:layout_height="wrap_content"
  71. android:textColor="#000000"
  72. android:textSize="20sp" />
  73. <TextView
  74. android:id="@+id/condition"
  75. android:layout_width="wrap_content"
  76. android:layout_height="wrap_content"
  77. android:text="@string/neterror"
  78. android:textColor="#000000"
  79. android:textSize="18sp" />
  80. </LinearLayout>
  81. <ImageView
  82. android:id="@+id/weather"
  83. android:layout_width="wrap_content"
  84. android:layout_height="wrap_content"
  85. android:layout_gravity="center_horizontal|top"
  86. android:src="@drawable/sunny" />
  87. <LinearLayout
  88. android:layout_width="100dip"
  89. android:layout_height="wrap_content"
  90. android:gravity="right"
  91. android:orientation="vertical"
  92. android:paddingRight="10dip" >
  93. <TextView
  94. android:id="@+id/date"
  95. android:layout_width="wrap_content"
  96. android:layout_height="wrap_content"
  97. android:textColor="#000000"
  98. android:textSize="18sp" />
  99. <TextView
  100. android:id="@+id/tem"
  101. android:layout_width="wrap_content"
  102. android:layout_height="wrap_content"
  103. android:text="@string/neterror"
  104. android:textColor="#000000"
  105. android:textSize="18sp" />
  106. </LinearLayout>
  107. </LinearLayout>
  108. </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/bg"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:background="@drawable/ww_bg"android:orientation="vertical" ><LinearLayoutandroid:id="@+id/time"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:orientation="horizontal" ><LinearLayoutandroid:id="@+id/linearLayout1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/wd_bg"android:orientation="horizontal" ><ImageViewandroid:id="@+id/h1"android:layout_width="wrap_content"android:layout_height="fill_parent"android:paddingLeft="10dip"android:src="@drawable/n0" /><ImageViewandroid:id="@+id/h2"android:layout_width="wrap_content"android:layout_height="fill_parent"android:src="@drawable/n0" /></LinearLayout><TextViewandroid:layout_width="30dip"android:layout_height="wrap_content" /><LinearLayoutandroid:id="@+id/linearLayout2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/wd_bg"android:orientation="horizontal" ><ImageViewandroid:id="@+id/m1"android:layout_width="wrap_content"android:layout_height="match_parent"android:paddingLeft="10dip"android:src="@drawable/n0" /><ImageViewandroid:id="@+id/m2"android:layout_width="wrap_content"android:layout_height="match_parent"android:src="@drawable/n0" /></LinearLayout></LinearLayout><LinearLayoutandroid:id="@+id/linearLayout3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:gravity="center"android:orientation="horizontal" ><LinearLayoutandroid:layout_width="100dip"android:layout_height="wrap_content"android:orientation="vertical"android:paddingLeft="10dip" ><TextViewandroid:id="@+id/city"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="#000000"android:textSize="20sp" /><TextViewandroid:id="@+id/condition"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/neterror"android:textColor="#000000"android:textSize="18sp" /></LinearLayout><ImageViewandroid:id="@+id/weather"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal|top"android:src="@drawable/sunny" /><LinearLayoutandroid:layout_width="100dip"android:layout_height="wrap_content"android:gravity="right"android:orientation="vertical"android:paddingRight="10dip" ><TextViewandroid:id="@+id/date"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="#000000"android:textSize="18sp" /><TextViewandroid:id="@+id/tem"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/neterror"android:textColor="#000000"android:textSize="18sp" /></LinearLayout></LinearLayout></LinearLayout>

四:谷歌天气不给力,所以我就简单的给出获取天气的核心代码。这里简单的做了一下乱码处理。

[java] view plaincopyprint?
  1. * @author way
  2. *
  3. */
  4. public class GetWeather {
  5. /**
  6. *
  7. * @return 天气对象
  8. */
  9. public Weather googleWeather() {
  10. String str = "http://www.google.com/ig/api?hl=zh_cn&weather=shenzhen";
  11. try {
  12. URL url = new URL(str);
  13. InputStream in = url.openStream();
  14. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  15. int len = -1;
  16. while ((len = in.read()) != -1) {
  17. bos.write(len);
  18. }
  19. InputStream is = new ByteArrayInputStream(bos.toString("GBK")
  20. .getBytes("utf-8"));
  21. // 从流中获取文档到本地内存
  22. Document doc = DocumentBuilderFactory.newInstance()
  23. .newDocumentBuilder().parse(is);
  24. // 从文档中得到名字为current_conditions的第一个节点下的所有子节点(一个集合)
  25. NodeList nodeList = doc.getElementsByTagName("current_conditions")
  26. .item(0).getChildNodes();
  27. // 得到nodeList下第一个节点的第一个元素内容(即当前天气)
  28. String condition = nodeList.item(0).getAttributes().item(0)
  29. .getNodeValue();
  30. // 当前温度
  31. String temp_c = nodeList.item(2).getAttributes().item(0)
  32. .getNodeValue();
  33. // 当前湿度
  34. //          String humidity = nodeList.item(3).getAttributes().item(0)
  35. //                  .getNodeValue();
  36. // 当前图片路径
  37. String iconPath = nodeList.item(4).getAttributes().item(0)
  38. .getNodeValue();
  39. // 当前风向
  40. //          String wind_condition = nodeList.item(5).getAttributes().item(0)
  41. //                  .getNodeValue();
  42. Weather w = new Weather();
  43. w.setWeather(condition);
  44. w.setTemp_c(temp_c);
  45. // 从图片路径中获取图片的名字
  46. String icon = iconPath.substring(iconPath.lastIndexOf("/") + 1,
  47. iconPath.indexOf("."));
  48. w.setIcon(icon);
  49. return w;
  50. } catch (MalformedURLException e) {
  51. e.printStackTrace();
  52. } catch (IOException e) {
  53. e.printStackTrace();
  54. } catch (SAXException e) {
  55. e.printStackTrace();
  56. } catch (ParserConfigurationException e) {
  57. e.printStackTrace();
  58. }
  59. return null;
  60. }
  61. }
 * @author way* */
public class GetWeather {/*** * @return 天气对象*/public Weather googleWeather() {String str = "http://www.google.com/ig/api?hl=zh_cn&weather=shenzhen";try {URL url = new URL(str);InputStream in = url.openStream();ByteArrayOutputStream bos = new ByteArrayOutputStream();int len = -1;while ((len = in.read()) != -1) {bos.write(len);}InputStream is = new ByteArrayInputStream(bos.toString("GBK").getBytes("utf-8"));// 从流中获取文档到本地内存Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);// 从文档中得到名字为current_conditions的第一个节点下的所有子节点(一个集合)NodeList nodeList = doc.getElementsByTagName("current_conditions").item(0).getChildNodes();// 得到nodeList下第一个节点的第一个元素内容(即当前天气)String condition = nodeList.item(0).getAttributes().item(0).getNodeValue();// 当前温度String temp_c = nodeList.item(2).getAttributes().item(0).getNodeValue();// 当前湿度
//          String humidity = nodeList.item(3).getAttributes().item(0)
//                  .getNodeValue();// 当前图片路径String iconPath = nodeList.item(4).getAttributes().item(0).getNodeValue();// 当前风向
//          String wind_condition = nodeList.item(5).getAttributes().item(0)
//                  .getNodeValue();Weather w = new Weather();w.setWeather(condition);w.setTemp_c(temp_c);// 从图片路径中获取图片的名字String icon = iconPath.substring(iconPath.lastIndexOf("/") + 1,iconPath.indexOf("."));w.setIcon(icon);return w;} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (SAXException e) {e.printStackTrace();} catch (ParserConfigurationException e) {e.printStackTrace();}return null;}
}

今天再修改解析中国天气网的json代码:

[html] view plaincopyprint?
  1. public class MyWeather {
  2. public static String city;
  3. public static String temp1;
  4. public static String weather1;
  5. public static String img1;
  6. public static void getWeather() {
  7. try {
  8. URL url = new URL("http://m.weather.com.cn/data/101250101.html");
  9. InputStream is = url.openStream();
  10. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  11. int len = -1;
  12. byte[] buffer = new byte[1024];
  13. while ((len = is.read(buffer)) != -1) {
  14. bos.write(buffer, 0, len);
  15. }
  16. String info = bos.toString("utf-8");
  17. JSONObject dataJson = new JSONObject(info);
  18. JSONObject json = dataJson.getJSONObject("weatherinfo");
  19. city = json.getString("city");
  20. temp1 = json.getString("temp1");
  21. weather1 = json.getString("weather1");
  22. img1 = json.getString("img1");
  23. System.out.println(city);is.close();bos.close();
  24. } catch (MalformedURLException e) {
  25. e.printStackTrace();
  26. } catch (IOException e) {
  27. e.printStackTrace();
  28. } catch (JSONException e) {
  29. e.printStackTrace();
  30. }
  31. }
  32. }
public class MyWeather {public static String city;public static String temp1;public static String weather1;public static String img1;public static void getWeather() {try {URL url = new URL("http://m.weather.com.cn/data/101250101.html");InputStream is = url.openStream();ByteArrayOutputStream bos = new ByteArrayOutputStream();int len = -1;byte[] buffer = new byte[1024];while ((len = is.read(buffer)) != -1) {bos.write(buffer, 0, len);}String info = bos.toString("utf-8");JSONObject dataJson = new JSONObject(info);JSONObject json = dataJson.getJSONObject("weatherinfo");city = json.getString("city");temp1 = json.getString("temp1");weather1 = json.getString("weather1");img1 = json.getString("img1");System.out.println(city);is.close();bos.close();} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (JSONException e) {e.printStackTrace();}}}

好了,大功告成,这是发表第三遍了,前两次都是悲剧,哎,不知道是网络问题还是我电脑问题,提交没有反应。总之很蛋疼!

Android之高仿墨迹天气桌面组件(AppWidgetProvider) .相关推荐

  1. (4.0.24.2)Android之桌面组件App Widget案例之高仿墨迹天气桌面组件

    相信墨迹天气,大家都见过,他在时间显示和天气界面上,很吸引人,今天我就来模仿一下墨迹天气的桌面组件,但是由于谷歌在天朝频频被墙的缘故,所以我在今天测试的时候,解析xml文件的网页打不开,所以天气显示出 ...

  2. 高仿墨迹天气 白天晴天

    简介 一直对墨迹天气的绚丽的场景蛮感兴趣的,趁有时间,自己就高仿了其中的一个场景,其他场景呢,也是类似的,主要是写对象的AI也就是逻辑了. 先看看效果吧,动态效果比较坑,太模糊 高清图 代码分析 来看 ...

  3. android 自定义皮肤,仿墨迹天气在Android App中实现自定义zip皮肤更换

    在这里谈一下墨迹天气的换肤实现方式,不过首先声明我只是通过反编译以及参考了一些网上其他资料的方式推测出的换肤原理, 在这里只供参考. 若大家有更好的方式, 欢迎交流. 墨迹天气下载的皮肤就是一个zip ...

  4. 高仿墨迹天气“我”页面

    看到墨迹天气的"我"页面比较炫酷,处于好奇,就写了一个demo模仿一下. 1,实现效果 实现的效果分三个部分来说明,首先是下拉到最大高度,个人信息界面会产生一个回弹的效果,然后是滚 ...

  5. Android 高仿墨迹天气“我”页面

    1,实现效果  转自:http://blog.csdn.net/huweigoodboy/article/details/47301197 实现的效果分三个部分来说明,首先是下拉到最大高度,个人信息界 ...

  6. 高仿墨迹天气-天鹰气象

            本项目主要设计了一个Android天气气象软件,从网络上获取相关天气信息后展示给用户,主要进行解析json.界面设计.动画优化等工作.所开发软件能够达到如下预期效果: (1)能够根据用 ...

  7. Android之高仿雅虎天气(一)

    引言: 记得去年下半年有上传一份代码(超逼真仿雅虎天气界面):http://download.csdn.net/detail/weidi1989/6312271 但那仅仅只是一个界面,而且还有一些比较 ...

  8. Android之高仿雅虎天气

    首先感谢作者:weidi1989 的无私分享 转来自:http://blog.csdn.net/way_ping_li/article/details/38963807点击打开链接 引言: 记得去年下 ...

  9. Android之高仿雅虎天气(二)---代码结构解析

    版本已升级至1.0.1 源码地址: GitHub:https://github.com/way1989/WayHoo OsChina:http://git.oschina.net/way/WayHoo ...

最新文章

  1. Android是否会因低价打败iPhone
  2. kotlin学习之类(三)
  3. java xwork_java-与休眠的Struts2 xwork类型转换
  4. fstab各项参数及ls-l 长格式各项信息
  5. python自动化常见面试题_Python基础面试题80问 Python自动化开发
  6. edius裁剪快捷键_EDIUS 快捷键大全 edius常用快捷键大全
  7. java实现excel转图片功能
  8. CNN--MINIST
  9. 扫雷(简易版) 10*10
  10. 兜兜转转,华为与李一男终于在汽车行业重逢,两者将展开决战?
  11. msvcp100.dll 丢失的解决方法-msvcp100.dll 丢失怎么修复
  12. 程序猿麒麟臂打造之路(健身一)
  13. 写点什么好呢2? 钱、事业、婚姻、人生意义
  14. python合并视频(mp4+mp3)
  15. 腾讯发布 2017 年度代码报告
  16. Java开发入门学习线路图+配套Java基础视频教程分享
  17. 802.11 WLAN/CCKM/11R Roaming
  18. 使用excel进行数据挖掘(4)---- 突出显示异常值
  19. Java 字体颜色转换工具类 ColorUtil
  20. ubuntu18 usb耳机,ubuntu18.04 调试USB声卡

热门文章

  1. 多边形彩色教育教学述职报告PPT模板
  2. matlab图形绘制经典案例,Matlab图形绘制经典案例(转载)
  3. 计算机软件应用知识,计算机软件及应用c_数据库应用知识ppt讲解学习课件
  4. springboot使用p6spy打印完整SQL
  5. 2020淘宝双十二脚本分享(UI版)
  6. 计算机程序数据随机变化,计算机程序编程课程设计报告(马尔可夫链算法生成随机可读文本)...
  7. java程序运行图形_java编程 要用到继承的方法图形计算器项目: 实现一个图形计算器,程序运行后显示界面:请选择图形: 1 圆 2 矩形...
  8. C语言以菜单方式进入属于,2009“高职升本科”计算机试卷及参考答案
  9. variables are collinear 的原因
  10. 【微课制作软件】Focusky教程 | 怎样改变图片形状?