Android开发----widget的使用

1.appwidget框架类

  • AppWidgetProvider–本质是一个brocastreciever。在appwidget应用enabled,update,delete,disenabled时接受广播。常用的是onRecieve,和onUpdate;
  • AppWidgetInfo–是widget的配置信息(包括大小,更新频率等),以xml文件等形式存在于res/xml目录下;
  • AppWidgetManager–负责管理 AppWidget ,向 AppwidgetProvider 发送通知;
  • RemoteViews–一个可以在其他应用进程中运行的类,向 AppWidgetProvider 发送通知。

2.AppWidget 框架的主要类介绍

1) AppWidgetManger 类

bindAppWidgetId(int appWidgetId, ComponentName provider)
通过给定的ComponentName 绑定appWidgetId
getAppWidgetIds(ComponentName provider)
通过给定的ComponentName 获取AppWidgetId
getAppWidgetInfo(int appWidgetId)
通过AppWidgetId 获取 AppWidget 信息
getInstalledProviders()
返回一个List的信息
getInstance(Context context)
获取 AppWidgetManger 实例使用的上下文对象
updateAppWidget(int[] appWidgetIds, RemoteViews views)
通过appWidgetId 对传进来的 RemoteView 进行修改,并重新刷新AppWidget 组件
updateAppWidget(ComponentName provider, RemoteViews views)
通过 ComponentName 对传进来的 RemoeteView 进行修改,并重新刷新AppWidget 组件
updateAppWidget(int appWidgetId, RemoteViews views)
通过appWidgetId 对传进来的 RemoteView 进行修改,并重新刷新AppWidget 组件
2) 继承自 AppWidgetProvider 可实现的方法为如下:

  1. onDeleted(Context context, int[] appWidgetIds)
  2. onDisabled(Context context)
  3. onEnabled(Context context)
  4. onReceive(Context context, Intent intent Tip:因为 AppWidgetProvider 是继承自BroadcastReceiver 所以可以重写onRecevie 方法,当然必须在后台注册Receiver
  5. onUpdate(Context context, AppWidgetManager appWidgetManager, int[]
    appWidgetIds)

一般来说都是重写onUpdate就够了

3.创建AppWidget步骤
1.继承AppWidgetProvider,实现自己的provider
在manifest.xml中配置自己的provider

        <receiver android:name=".reciever.MyProvider">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/myappwidget_info" />
        </receiver>

注意,在这里action的name和meta-data的name属性都是固定不变的,分别是android.appwidget.action.APPWIDGET_UPDATE 和 android.appwidget.provider。
android:resource属性是appwidget的配置信息
2.配置myappwidget_info.xml,在res/xml目录下创建新的xml文件

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/activity_main"
    android:minWidth="250dp"
    android:minHeight="40dp"
    android:previewImage="@mipmap/ic_launcher"
    android:updatePeriodMillis="1800000"><!--系统为了省电,默认是30分钟更新一次,如果你设置的值比30分钟小,系统也是30分钟才会更新一次。因为需要频繁更新的Widget,需要自己起一个service进行更新了-->
</appwidget-provider>

在我的例子中实现了自己的serviec用于定时(2秒)更新一次widget
3.remoteviews 的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    tools:context="com.data.www.appwidgetdemo.MainActivity">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_up"
            android:layout_width="match_parent"
            android:layout_height="20dp"
            android:layout_weight="1"
            android:text="当前运行程序:25" />

        <TextView
            android:id="@+id/tv_down"
            android:layout_width="match_parent"
            android:layout_height="20dp"
            android:layout_weight="1"
            android:text="可用内存:2.5G" />
    </LinearLayout>

    <Button
        android:id="@+id/btn_clear"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="一键清理" />
</LinearLayout>

4.实现自己的service用于定时更新

package com.data.www.appwidgetdemo.services;

import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Intent;
import android.os.IBinder;
import android.widget.RemoteViews;

import com.data.www.appwidgetdemo.R;
import com.data.www.appwidgetdemo.reciever.AutoKillReceiver;
import com.data.www.appwidgetdemo.reciever.MyProvider;
import com.data.www.appwidgetdemo.utils.SystemUtils;

import java.util.Timer;
import java.util.TimerTask;

public class UpdateService extends Service {
    private Timer timer;
    private TimerTask task;
    public static final  String ACTION_CLEAR = "self.intent.action.clearprocess";
    RemoteViews remoteViews;

    public UpdateService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (null!=intent&&ACTION_CLEAR.equals(intent.getAction())){
            SystemUtils.clearBackground(new SystemUtils.ClearListener() {
                @Override
                public void onFinish(String result) {
                    changeWidgetStatus("finish");
                }

                @Override
                public void onStart() {
                    changeWidgetStatus("start");
                }

                @Override
                public void onDoingjob() {
                    changeWidgetStatus("doing");
                }
            });
        }
        return super.onStartCommand(intent, flags, startId);
    }

    private void changeWidgetStatus(String status) {
        switch (status) {
            case "start":

                break;
            case "doing":

                break;
            case "finish":

                break;
            default:
                break;
        }
    }

    @Override
    public void onCreate() {

        timer = new Timer();
        task = new TimerTask() {
            @Override
            public void run() {
                int runningTaskCount = SystemUtils.getRunningTaskCount(UpdateService.this);
                double avaliMem = SystemUtils.getAvaliMem(UpdateService.this);
                ComponentName name = new ComponentName(UpdateService.this, MyProvider.class);
                remoteViews = new RemoteViews(getPackageName(), R.layout.activity_main);

                //更新widget中的组件内容
                remoteViews.setTextViewText(R.id.tv_up,"正在运行的程序数:"+runningTaskCount);
                remoteViews.setTextViewText(R.id.tv_down,"可用内存:"+avaliMem+" M");

                //点击按钮事件处理
                Intent intent = new Intent(UpdateService.this, AutoKillReceiver.class);
                intent.setAction("self.intent.brocast.autokillprocess");
                PendingIntent pendingIntent = PendingIntent.getBroadcast(UpdateService.this,0,intent, PendingIntent.FLAG_UPDATE_CURRENT);
                remoteViews.setOnClickPendingIntent(R.id.btn_clear,pendingIntent);

                //注意,一定要使用Appwidgetmanager处理widget
                AppWidgetManager awm = AppWidgetManager.getInstance(getApplicationContext());
                awm.updateAppWidget(name,remoteViews);
            }
        };
        timer.schedule(task,3000,2000);
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        timer.cancel();
        task.cancel();
        timer=null;
        task = null;
    }
}

由于只是模拟,所以并没有真正实现清空运行程序的功能。后续会把该功能完善,然后加入点击widget按钮的动画效果(类似360点击正在清理的转圈功能)。
源码:https://github.com/VenQi/AppWidgetDemo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值