Android之高仿墨迹天气桌面组件(AppWidgetProvider) .
2013-11-18 17:31
519 查看
Android之高仿墨迹天气桌面组件(AppWidgetProvider) .
点击:382 发布时间:2012-10-03
更多0
相信墨迹天气,大家都见过,他在时间显示和天气界面上,很吸引人,今天我就来模仿一下墨迹天气的桌面组件,但是由于谷歌在天朝频频被墙的缘故,所以我在今天测试的时候,解析xml文件的网页打不开,所以天气显示出了点问题,希望大家能理解,谢谢。(今天9月24日修改为解析中国天气网获取天气了,而且修改组件在桌面居中显示)。
老规矩,先分享源代码:http://download.csdn.net/detail/weidi1989/4597809
好了,废话不多说,先上效果图:
再来看一下整个小项目的主体结构:
首先先声明一个桌面布局的xml文件,即app.xml:
[html] view
plaincopyprint?
<?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?
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.way.apptest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android: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-data
android: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?
/**
* @author way
*/
public class App extends AppWidgetProvider {
private Intent intent;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
intent = new Intent(context, UpdateService.class);
context.startService(intent);
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
context.stopService(intent);
super.onDeleted(context, appWidgetIds);
}
}
二:本项目中最重要的部分,在这个服务中,我们注册一个广播接收者去接受系统每分钟时间时间变化的广播,从而来更新桌面时间,这样更省电哦,需要注意的是:这个广播接收者必须在代码中注册,在Manifest文件中注册是没有效果的。更新天气,我是通过定义一个定时器,由用户设置时间间隔来更新天气信息。
[java] view
plaincopyprint?
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() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE:
// 更新天气
updateTime();
updateWeather();
break;
}
}
};
// 广播接收者去接收系统每分钟的提示广播,来更新时间
private BroadcastReceiver mTimePickerBroadcast = new BroadcastReceiver() {
@Override
public 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);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
remoteViews = new RemoteViews(getApplication().getPackageName(),
R.layout.main);// 实例化RemoteViews
if (isNetworkAvailable()) {
MyWeather.getWeather();// json解析中国天气网天气
} else {
toast();
}
updateTime();// 第一次运行时先更新一下时间和天气
updateWeather();
// 点击天气图片,进入MainActivity
Intent 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() {
@Override
public 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);
}
@Override
public void onStart(Intent intent, int startId) {
// 注册系统每分钟提醒广播(注意:这个广播只能在代码中注册)
IntentFilter updateIntent = new IntentFilter();
updateIntent.addAction("android.intent.action.TIME_TICK");
registerReceiver(mTimePickerBroadcast, updateIntent);
super.onStart(intent, startId);
}
@Override
public 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?
<?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" >
<LinearLayout
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/wd_bg"
android:orientation="horizontal" >
<ImageView
android:id="@+id/h1"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:paddingLeft="10dip"
android:src="@drawable/n0" />
<ImageView
android:id="@+id/h2"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:src="@drawable/n0" />
</LinearLayout>
<TextView
android:layout_width="30dip"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/wd_bg"
android:orientation="horizontal" >
<ImageView
android:id="@+id/m1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="10dip"
android:src="@drawable/n0" />
<ImageView
android:id="@+id/m2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/n0" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="100dip"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="10dip" >
<TextView
android:id="@+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="20sp" />
<TextView
android:id="@+id/condition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/neterror"
android:textColor="#000000"
android:textSize="18sp" />
</LinearLayout>
<ImageView
android:id="@+id/weather"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top"
android:src="@drawable/sunny" />
<LinearLayout
android:layout_width="100dip"
android:layout_height="wrap_content"
android:gravity="right"
android:orientation="vertical"
android:paddingRight="10dip" >
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="18sp" />
<TextView
android: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?
* @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?
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();
}
}
}
好了,大功告成,这是发表第三遍了,前两次都是悲剧,哎,不知道是网络问题还是我电脑问题,提交没有反应。总之很蛋疼!
点击:382 发布时间:2012-10-03
更多0
相信墨迹天气,大家都见过,他在时间显示和天气界面上,很吸引人,今天我就来模仿一下墨迹天气的桌面组件,但是由于谷歌在天朝频频被墙的缘故,所以我在今天测试的时候,解析xml文件的网页打不开,所以天气显示出了点问题,希望大家能理解,谢谢。(今天9月24日修改为解析中国天气网获取天气了,而且修改组件在桌面居中显示)。
老规矩,先分享源代码:http://download.csdn.net/detail/weidi1989/4597809
好了,废话不多说,先上效果图:
再来看一下整个小项目的主体结构:
首先先声明一个桌面布局的xml文件,即app.xml:
[html] view
plaincopyprint?
<?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>
<?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?
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.way.apptest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android: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-data
android: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>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.way.apptest" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <uses-permission android:name="android.permission.INTERNET" /> <application android: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-data android: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?
/**
* @author way
*/
public class App extends AppWidgetProvider {
private Intent intent;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
intent = new Intent(context, UpdateService.class);
context.startService(intent);
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
context.stopService(intent);
super.onDeleted(context, appWidgetIds);
}
}
/** * @author way */ public class App extends AppWidgetProvider { private Intent intent; @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { intent = new Intent(context, UpdateService.class); context.startService(intent); super.onUpdate(context, appWidgetManager, appWidgetIds); } @Override public void onDeleted(Context context, int[] appWidgetIds) { context.stopService(intent); super.onDeleted(context, appWidgetIds); } }
二:本项目中最重要的部分,在这个服务中,我们注册一个广播接收者去接受系统每分钟时间时间变化的广播,从而来更新桌面时间,这样更省电哦,需要注意的是:这个广播接收者必须在代码中注册,在Manifest文件中注册是没有效果的。更新天气,我是通过定义一个定时器,由用户设置时间间隔来更新天气信息。
[java] view
plaincopyprint?
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() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE:
// 更新天气
updateTime();
updateWeather();
break;
}
}
};
// 广播接收者去接收系统每分钟的提示广播,来更新时间
private BroadcastReceiver mTimePickerBroadcast = new BroadcastReceiver() {
@Override
public 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);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
remoteViews = new RemoteViews(getApplication().getPackageName(),
R.layout.main);// 实例化RemoteViews
if (isNetworkAvailable()) {
MyWeather.getWeather();// json解析中国天气网天气
} else {
toast();
}
updateTime();// 第一次运行时先更新一下时间和天气
updateWeather();
// 点击天气图片,进入MainActivity
Intent 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() {
@Override
public 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);
}
@Override
public void onStart(Intent intent, int startId) {
// 注册系统每分钟提醒广播(注意:这个广播只能在代码中注册)
IntentFilter updateIntent = new IntentFilter();
updateIntent.addAction("android.intent.action.TIME_TICK");
registerReceiver(mTimePickerBroadcast, updateIntent);
super.onStart(intent, startId);
}
@Override
public 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();
}
}
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() { @Override public void handleMessage(Message msg) { switch (msg.what) { case UPDATE: // 更新天气 updateTime(); updateWeather(); break; } } }; // 广播接收者去接收系统每分钟的提示广播,来更新时间 private BroadcastReceiver mTimePickerBroadcast = new BroadcastReceiver() { @Override public 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); } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); remoteViews = new RemoteViews(getApplication().getPackageName(), R.layout.main);// 实例化RemoteViews if (isNetworkAvailable()) { MyWeather.getWeather();// json解析中国天气网天气 } else { toast(); } updateTime();// 第一次运行时先更新一下时间和天气 updateWeather(); // 点击天气图片,进入MainActivity Intent 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() { @Override public 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); } @Override public void onStart(Intent intent, int startId) { // 注册系统每分钟提醒广播(注意:这个广播只能在代码中注册) IntentFilter updateIntent = new IntentFilter(); updateIntent.addAction("android.intent.action.TIME_TICK"); registerReceiver(mTimePickerBroadcast, updateIntent); super.onStart(intent, startId); } @Override public 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?
<?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" >
<LinearLayout
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/wd_bg"
android:orientation="horizontal" >
<ImageView
android:id="@+id/h1"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:paddingLeft="10dip"
android:src="@drawable/n0" />
<ImageView
android:id="@+id/h2"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:src="@drawable/n0" />
</LinearLayout>
<TextView
android:layout_width="30dip"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/wd_bg"
android:orientation="horizontal" >
<ImageView
android:id="@+id/m1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="10dip"
android:src="@drawable/n0" />
<ImageView
android:id="@+id/m2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/n0" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="100dip"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="10dip" >
<TextView
android:id="@+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="20sp" />
<TextView
android:id="@+id/condition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/neterror"
android:textColor="#000000"
android:textSize="18sp" />
</LinearLayout>
<ImageView
android:id="@+id/weather"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top"
android:src="@drawable/sunny" />
<LinearLayout
android:layout_width="100dip"
android:layout_height="wrap_content"
android:gravity="right"
android:orientation="vertical"
android:paddingRight="10dip" >
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="18sp" />
<TextView
android: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>
<?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" > <LinearLayout android:id="@+id/time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:orientation="horizontal" > <LinearLayout android:id="@+id/linearLayout1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/wd_bg" android:orientation="horizontal" > <ImageView android:id="@+id/h1" android:layout_width="wrap_content" android:layout_height="fill_parent" android:paddingLeft="10dip" android:src="@drawable/n0" /> <ImageView android:id="@+id/h2" android:layout_width="wrap_content" android:layout_height="fill_parent" android:src="@drawable/n0" /> </LinearLayout> <TextView android:layout_width="30dip" android:layout_height="wrap_content" /> <LinearLayout android:id="@+id/linearLayout2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/wd_bg" android:orientation="horizontal" > <ImageView android:id="@+id/m1" android:layout_width="wrap_content" android:layout_height="match_parent" android:paddingLeft="10dip" android:src="@drawable/n0" /> <ImageView android:id="@+id/m2" android:layout_width="wrap_content" android:layout_height="match_parent" android:src="@drawable/n0" /> </LinearLayout> </LinearLayout> <LinearLayout android:id="@+id/linearLayout3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:gravity="center" android:orientation="horizontal" > <LinearLayout android:layout_width="100dip" android:layout_height="wrap_content" android:orientation="vertical" android:paddingLeft="10dip" > <TextView android:id="@+id/city" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#000000" android:textSize="20sp" /> <TextView android:id="@+id/condition" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/neterror" android:textColor="#000000" android:textSize="18sp" /> </LinearLayout> <ImageView android:id="@+id/weather" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal|top" android:src="@drawable/sunny" /> <LinearLayout android:layout_width="100dip" android:layout_height="wrap_content" android:gravity="right" android:orientation="vertical" android:paddingRight="10dip" > <TextView android:id="@+id/date" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#000000" android:textSize="18sp" /> <TextView android: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?
* @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;
}
}
* @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?
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();
}
}
}
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)
- Android之高仿墨迹天气桌面组件(AppWidgetProvider)
- (4.1.27.1)Android之桌面组件App Widget案例之高仿墨迹天气桌面组件
- (4.1.27)Android之桌面组件App Widget初探
- Android 桌面组件【app widget】 进阶项目②--心情记录器
- Android桌面组件App Widget开发三步走
- android 桌面组件 App widget的使用
- Android之桌面组件AppWidget
- 初步分析Android——桌面小组件App Widget Host
- (4.1.27.1)Android之桌面组件App Widget案例
- Android 桌面组件【app widget】 进阶项目--心情记录器
- android桌面组件AppWidget
- android桌面组件AppWidget
- Android 桌面组件【app widget】
- Android 桌面小组件AppWidget的使用
- Android--桌面组件AppWidget
- Android 桌面组件【app widget】 进阶项目--心情记录器
- Android之桌面组件App Widget初探
- Android之桌面组件App Widget案例
- Android 桌面组件【app widget】 进阶项目--心情记录器