import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.RemoteViews;
import android.widget.Toast;
/**
* Widget中的那些关系
* <p>
* AppWidgetManager:管理整个app中的所有widget的工具(每实例化一个widget都算一个widget), 每个widget通过自己的widgetId来区别
* <p>
* AppWidgetProvider:每一个widget都有一个属于自己的AppWidgetProvider, 但是在一个AppWidgetProvider中可以响应其他的相同种类的widget,
* 比如说可以用appWidgetManager.update()第一个参数传字符串就可以同步更新其他的所有的同类Widget, 并且再onEnabled中可以响应第一次创建的时候,这就是期间有联系。
* <p>
* AppWidgetProviderInfo:所有一类的widget复用一个AppWidgetProviderInfo
* <p>
* widgetId:每一个你生成的widget都有自己的id号码,比如说你再屏幕上放两个一样的控件,但是他们的id是不同的
*
* @date 2022/5/19
*/
public class SimpleWidgetProvider extends AppWidgetProvider {
//定义一个action,这个action要在AndroidMainfest中去定义,不然识别不到,名字是自定义的
private static final String CLICK_ACTION = "com.test.launcher.MainActivity";
//onReceive不存在widget生命周期中,它是用来接收广播,通知全局的
//实时更新widget
//广播接受者方法,用来接受广播消息
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
//当我们点击桌面上的widget按钮(这个按钮我们在onUpdate中已经为它设置了监听),widget就会发送广播
//这个广播我们也在onUpdate中为它设置好了意图,设置了action,在这里我们接收到对应的action并做相应处理
if (intent.getAction().equals(CLICK_ACTION)) {
Toast.makeText(context, "click", Toast.LENGTH_SHORT).show();
//因为点击按钮后要对布局中的文本进行更新,所以需要创建一个远程view
/*
* 获取Widget远程View对象
* 参数1 Widget·的包名
* 参数2 Widget的布局id
*/
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.layout_test);
//为对应的TextView设置文本
// remoteViews.setTextViewText(R.id.tv, "按钮已经点击");
//更新widget
appWidgetManager.updateAppWidget(new ComponentName(context, SimpleWidgetProvider.class), remoteViews);
}
}
//当widget第一次添加到桌面的时候回调,可添加多次widget,但该方法只回调一次
//创建第一个AppWiget实例所调用的方法,
//当第一次创建该类型的AppWidget时,调用此方法
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
Toast.makeText(context, "创建成功", Toast.LENGTH_SHORT).show();
}
//当widget被初次添加或大小被改变时回调
@Override
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
}
/**
* 到达指定的时间,或者用户第一次创建Appwidget所调用的方
* 每次创建该类型的AppWidget都会调用此方法 , 通常来说我们需要在该方法里为该AppWidget指定RemoteViews对象。
*
* 当widget更新时回调
*
* @param context
* @param appWidgetManager 当前app的widgetmanager
* @param appWidgetIds 用当前provider设置的所有widget的id的数组,
* 也就是说同类的widget可以访问生成的其他的widget(这个widget必须也是用这个provider生成的)
* */
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
//因为可能有多个widget,所以要对它们全部更新
for (int appWidgetId : appWidgetIds) {
//创建一个远程view,绑定我们要操控的widget布局文件
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.layout_test);
Intent intentClick = new Intent();
//这个必须要设置,不然点击效果会无效
intentClick.setClass(context, SimpleWidgetProvider.class);
intentClick.setAction(CLICK_ACTION);
//PendingIntent表示的是一种即将发生的意图,区别于Intent它不是立即会发生的
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentClick, PendingIntent.FLAG_UPDATE_CURRENT);
//为布局文件中的按钮设置点击监听
remoteViews.setOnClickPendingIntent(R.id.btn, pendingIntent);
//告诉AppWidgetManager对当前应用程序小部件执行更新
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}
//当 widget 被删除时回调
//删除一个AppWidget所调用的方法,
// 当该类型的AppWidget每次被删除时,调用此方法
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
}
//当最后一个widget实例被删除时回调.
//删除最后一个Appwidget所调用的方法,
// 当该类型的窗口小部件(AppWidget)全被删除时,调用此方法
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
}
}

被折叠的 条评论
为什么被折叠?



