android appwidget开发

来源:互联网 发布:苹果怎样下载软件 编辑:程序博客网 时间:2024/05/29 23:23

AppWidget就是在桌面上见到的一个个小窗口,利用这个小窗口可以给用户提供一些方便快捷的操作,如通过桌面widget可以开发出桌面媒体播放器,如酷狗widget,本文详细介绍android 中的appwidget的开发。

开发效果图如下所示:

1.首先在res文件夹下新建一个名字为xml的文件夹,然后在xml目录下创建一个xml文件,这个xml是用来描述你所要创建的appWidget的一些描述信息的,比如高度、宽度、刷新间隔、布局文件等等,例如我们创建一个名为appwidget的xml属性文件,如下所示:

<?xml version="1.0" encoding="utf-8"?><appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"    android:minWidth="240dp"     android:minHeight="60dp"     android:updatePeriodMillis="1000"     android:initialLayout="@layout/layout_appwidget"></appwidget-provider>


android:minWidth:定义窗口小部件的最小宽

android:minHeight:定义窗口小部件的最小高

android:updatePeriodMillis:定义窗口小部件自动更新的时间间隔,在后期的android版本,该属性作用不大,google已经设置为1天更新一次

android:initialLayout:定义窗口小部件的布局文件,由此可以看出我们还需要为窗口小部件创建一个布局文件

 

2.窗口小部件的布局layout_appwidget.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="wrap_content"    android:layout_marginLeft="5dp"    android:layout_marginRight="5dp"    android:orientation="vertical" >    <ImageView        android:id="@+id/wigdet_bg1"        android:background="@drawable/bg_image0"        android:layout_width="fill_parent"        android:layout_height="wrap_content"/>    <TextView        android:id="@+id/wigdet_text"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:text="appwidget"        android:autoLink="all"        android:background="#00000000"        android:ellipsize="marquee"        android:focusable="true"        android:gravity="center_horizontal"        android:marqueeRepeatLimit="marquee_forever"        android:paddingTop="5dp"        android:singleLine="true"        android:textAppearance="?android:attr/textAppearanceMedium"        android:textColor="#000000"        android:textSize="18dp" />    <RelativeLayout         android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_below="@id/wigdet_text"        android:layout_marginLeft="5dp"        android:layout_marginRight="10dp">    <ImageButton        android:id="@+id/wigdet_btnLeft"        android:layout_width="50dp"        android:layout_height="50dp"        android:layout_alignParentLeft="true"        android:background="#00000000"        android:scaleType="fitXY"        android:src="@drawable/logo" />    <ImageButton        android:id="@+id/wigdet_btnRight"        android:layout_width="50dp"        android:layout_height="50dp"        android:background="#00000000"        android:scaleType="fitXY"  android:layout_alignParentRight="true"   android:layout_marginRight="3dp"         android:src="@drawable/widget_rightbtn" />   <ImageView        android:id="@+id/wigdet_bg2"        android:background="@drawable/bg_image1"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_toLeftOf="@id/wigdet_btnRight"    android:layout_toRightOf="@id/wigdet_btnLeft"    android:layout_alignBottom="@id/wigdet_btnLeft"    android:layout_marginRight="3dp"/><LinearLayout     android:layout_width="fill_parent"    android:layout_height="47dp"    android:layout_toLeftOf="@id/wigdet_btnRight"    android:layout_toRightOf="@id/wigdet_btnLeft"    android:layout_alignBottom="@id/wigdet_btnLeft"    android:layout_marginRight="3dp">      <ImageButton          android:id="@+id/wigdet_imgbtn1"          android:layout_marginBottom="2dp"          android:layout_marginTop="3dp"          android:layout_weight="1"          android:layout_marginLeft="5dp"          android:scaleType="fitXY"          android:layout_width="40dp"          android:layout_height="40dp"   android:background="#00000000"/>      <ImageButton          android:id="@+id/wigdet_imgbtn2"          android:layout_marginBottom="2dp"          android:layout_weight="1"          android:layout_marginLeft="5dp"          android:scaleType="fitXY"          android:layout_width="40dp"          android:layout_height="40dp"          android:layout_marginTop="3dp"          android:background="#00000000" />      <ImageButton          android:id="@+id/wigdet_imgbtn3"          android:layout_marginBottom="2dp"          android:layout_marginTop="3dp"          android:layout_weight="1"          android:layout_marginLeft="5dp"          android:scaleType="fitXY"          android:layout_width="40dp"          android:layout_height="40dp"          android:background="#00000000" />      <ImageButton          android:id="@+id/wigdet_imgbtn4"          android:layout_marginLeft="5dp"          android:layout_marginRight="5dp"          android:layout_marginBottom="2dp"          android:layout_weight="1"          android:layout_marginTop="3dp"          android:scaleType="fitXY"          android:layout_width="40dp"          android:layout_height="40dp"          android:background="#00000000"/>   </LinearLayout>    </RelativeLayout></RelativeLayout>

该布局文件和android应用开发的其他布局设计一样。

 

3.通过manifest文件注册该窗口小部件

<!-- 桌面插件AppWidget 广播接收器  --><receiver android:name="com.spreadtrum.activity.SprdAppWidget"><meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget"/><intent-filter ><action android:name="android.appwidget.action.APPWIDGET_UPDATE"/><action android:name="com.spreadtrum.action.WIDGET"></action></intent-filter></receiver>

注册方式和广播接收器的注册方式相同,由此可以看出窗口小部件其实就是一个广播接收器,只是它是一个比较特殊的接收器,所有的窗口小部件都接收android.appwidget.action.APPWIDGET_UPDATE 动作的广播,该广播根据android:updatePeriodMillis设定的间隔时间发出广播,用于定时更新桌面上的所有窗口小部件。

上面注册过程中,元数据名称android:name必须为android.appwidget.provider,资源就是第一步中为窗口小部件设置的属性文件。可以通过在该广播接收器中注册自定义的动作以使窗口小部件接收自定义的广播,如上所示,为该widget添加了一个自定义com.spreadtrum.action.WIDGET动作的广播。

 

4.自定义一个继承于AppWidgetProvider 的类

覆写父类的一下方法:

//广播接收public void onReceive(Context context, Intent intent)//当用户向桌面添加AppWidget时被调用,同时接收android.appwidget.action.APPWIDGET_UPDATE广播  public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)//删除一个AppWidget时调用 public void onDeleted(Context context, int[] appWidgetIds)//AppWidget的实例第一次被创建时调用  public void onEnabled(Context context)//最后一个appWidget被删除时调用  public void onDisabled(Context context)


 

具体类实现如下:

public class SprdAppWidget extends AppWidgetProvider{    private final static String TAG = "SprdAppWigdet";    private final static int[] imageBtnIds ={R.id.wigdet_imgbtn1,R.id.wigdet_imgbtn2,R.id.wigdet_imgbtn3,R.id.wigdet_imgbtn4};    private final static int defaultBgId = R.drawable.wos;    /**     * 接受广播事件       */    @Override    public void onReceive(Context context, Intent intent) {        // TODO Auto-generated method stub        if (intent.getAction().equals("com.spreadtrum.action.WIDGET")) {            //因为appwidget运行的进程和我们创建的应用不在一个进程中,所以我们也就不能像平常引用控件那样来获得控件的实例。只能通过RemoteViews远程的视图来引用,//也就是说通过RemoteViews我们能够获得不在同一进程中的对象,这也就为我们编写appwidget的处理事件提供了帮助。             RemoteViews remoteViews  = new RemoteViews(context.getPackageName(),R.layout.layout_appwidget);            ComponentName componentName =new ComponentName(context, SprdAppWidget.class);            //编写该广播下的业务逻辑,如果更换图像控件的图片等等。            AppWidgetManager.getInstance(context).updateAppWidget(componentName, remoteViews);        }        super.onReceive(context, intent);    }    /**     * 到达指定的更新时间或者当用户向桌面添加AppWidget时被调用       */    @Override    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {        // TODO Auto-generated method stub    final Context cxt = context;    Log4debug.i(TAG, "onUpdate", null);              //只能通过远程对象来设置appwidget中的控件状态          RemoteViews remoteViews  = new RemoteViews(context.getPackageName(),R.layout.layout_appwidget); //循环桌面上所有的该窗口小部件,(可以在桌面上同时添加多个相同的窗口小部件)        for (int i = 0; i < appWidgetIds.length; i++) {//为窗口小部件上的按钮设置单击事件            Intent intent1 = new Intent(context, SprdAppMainActivity.class);remoteViews.setOnClickPendingIntent(R.id.wigdet_btnLeft, PendingIntent.getActivity(context, 0, intent1, PendingIntent.FLAG_CANCEL_CURRENT));                        Intent broadIntent = new Intent(context,PopupWindowActivity.class);            remoteViews.setOnClickPendingIntent(R.id.wigdet_btnRight,PendingIntent.getActivity(context, i, broadIntent, PendingIntent.FLAG_UPDATE_CURRENT));            //为窗口小部件上的图像控件设置图像            for (int j = 0; j < imageBtnIds.length; j++) {                remoteViews.setImageViewResource(imageBtnIds[j], defaultBgId);            }            //更新窗口小部件            appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);        }            //网络已连接,启动内容更新线程        if (CommonUtil.checkNetWorkStatus(context)) {                new Thread (new Runnable() {public void run() {// TODO Auto-generated method stubtry {................................    }    } catch (Exception e) {    // TODO Auto-generated catch block    Log4debug.e(TAG, "run", e.getMessage());    }}}).start();        }                super.onUpdate(context, appWidgetManager, appWidgetIds);      }        /**     * 删除一个AppWidget时调用      */    @Override    public void onDeleted(Context context, int[] appWidgetIds) {        // TODO Auto-generated method stub        super.onDeleted(context, appWidgetIds);    }    /**     * AppWidget的实例第一次被创建时调用       */    @Override    public void onEnabled(Context context) {        // TODO Auto-generated method stub        super.onEnabled(context);    }    /**     * 最后一个appWidget被删除时调用       */    @Override    public void onDisabled(Context context) {        // TODO Auto-generated method stub        super.onDisabled(context);    }}

 

PendingIntent 在前文中作了详细介绍,请参看PendingIntent,到此appwidget开发完成,当然可以在注册widget时候添加多个动作。

原创粉丝点击