最近看了有关android widget的资料,感觉widget这东西相对其它控件来说,即简洁又方便,让人耳目一新。按照android官方网的解析,widget实际上是一个放在桌面的应用。它与其它的应用的不同点是,它能够实时地更新内容。只要把它手动添加到桌面,代码就能跑起来。所以用它来更新时间、新闻、地图及电池信息等等很方便,同时也增强用户体验效果。这样用户要想知道这些信息,直接在桌面就能实时查看,而不需要再打开一个应用。widget使生活变得更便捷,不得不说设计这个东西的人很牛!
前段时间设计的widget是与一个项目有关。项目需要设计一个检测USB的应用,于是结合widget的功能,用widget来检测android usb设备(主要是检测外接的usb键盘)。在网上查了很多资料,但很多都是用widget来检测系统电池,检测USB几乎找不到!于是只能一边找资料,一边想象(想象占绝大部分,天马行空是需要的,哈哈),弄了两天终于搞定。少说废话,直接进主题:
一、建一个java文件,继承自AppWidgetProvider
package ideal.usb;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.IBinder;
import android.widget.RemoteViews;
public class UsbWidget extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds){
super.onUpdate(context, appWidgetManager, appWidgetIds);
/** 启动service */
context.startService(new Intent(context, updateService.class));
}
/** 自动更新service */
public static class updateService extends Service {
Bitmap bmp; // 定义机器人图片
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
/** 设置Widget的显示 */
private void setViews() {
/** 定义一个AppWidgetManager */
AppWidgetManager manager = AppWidgetManager.getInstance(this);
/** 定义一个RemoteViews,实现对AppWidget界面控制 */
RemoteViews views = new RemoteViews(getPackageName(),
R.layout.newrelativelayout);
/** 设置AppWidget上显示的图片和文字的内容 */
bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.icharge);
views.setImageViewBitmap(R.id.imageView, bmp);
if (Flag.capCheck) {
views.setTextViewText(R.id.tv, "USB已经连接");
} else
views.setTextViewText(R.id.tv, "USB关闭");
ComponentName thisWidget = new ComponentName(this,
UsbWidget.class);
/** 更新AppWidget */
manager.updateAppWidget(thisWidget, views);
}
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
setViews();
}
//检测usb设备
@Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
if (newConfig.keyboard == Configuration.KEYBOARD_QWERTY) {
Flag.capCheck = true;
Intent startActivityIntent = new Intent(this,ViewFliperFlashActivity.class);//如果检测到外接USB键盘接入,则跳转到指定的Activity
startActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(startActivityIntent);
} else if (newConfig.keyboard == Configuration.KEYBOARD_12KEY) {
} else if (newConfig.keyboard == Configuration.KEYBOARD_NOKEYS) {
Flag.capCheck = false;
}
setViews();
super.onConfigurationChanged(newConfig);
}
}
}
widget启动时,会首先执行onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds)方法,然后在这个方法里启动一个服务context.startService(new Intent(context, updateService.class)); 最后Service里有一个onConfigurationChanged函数里检测USB外设。
二、在工程目录的res目录下建立一个xml文件夹,并在这个文件夹下建立一个new_widget.xml
这个xml文件是widget启动时的设置图片的高度和宽度
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minHeight="72dip"
android:minWidth="72dip"
android:updatePeriodMillis="1000000"
android:initialLayout="@layout/newrelativelayout"
>
</appwidget-provider>
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minHeight="72dip"
android:minWidth="72dip"
android:updatePeriodMillis="1000000"
android:initialLayout="@layout/newrelativelayout"
>
</appwidget-provider>
三、layout目录下建立一个newrelativelayout.xml文件<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="@+id/imageView"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/j"
/>
<TextView
android:id="@+id/tv"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ff0000"
android:textStyle="bold"
android:textSize="14sp"
/>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="@+id/imageView"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/j"
/>
<TextView
android:id="@+id/tv"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ff0000"
android:textStyle="bold"
android:textSize="14sp"
/>
</RelativeLayout>
四、在AndroidManifest.xml里面注册widget
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ideal.usb"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="14" />
<application
android:icon="@drawable/j"
android:label="@string/app_name" >
<receiver
android:name=".UsbWidget"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/new_battery_widget" />
</receiver>
<service android:name=".UsbWidget$updateService" />
<activity
android:name=".ViewFliperFlashActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:windowSoftInputMode="stateHidden"
android:configChanges="keyboard|orientation|keyboardHidden" >
</activity>
<activity
android:name=".FilePlayer"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:configChanges="keyboard|orientation|keyboardHidden"
>
</activity>
</application>
</manifest>