1:创建基类小组件接收者 BaseAppWidgetProvider
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.net.Uri
import android.widget.RemoteViews
abstract class BaseAppWidgetProvider : AppWidgetProvider() {
val widgets = HashSet<Any>()
/**
* 部件布局
* @return Int
*/
abstract fun getLayout(): Int
/**
* 点击可以打开app的控件id
* @return Int
*/
abstract fun click2AppViewId(): Int
/**
* 设置views
* @param views RemoteViews
*/
abstract fun setViews(views: RemoteViews)
/**
* 指定子provider
* @return String
*/
abstract fun _this(): String
override fun onReceive(context: Context?, intent: Intent?) {
super.onReceive(context, intent)
var action = intent?.action
var isClick = intent?.getBooleanExtra("isClick", false)
// 接收到日期改变,或者手动改变app widget更新状态的时候触发刷新
if ("android.intent.action.DATE_CHANGED".equals(action) ||
("android.appwidget.action.APPWIDGET_UPDATE".equals(action) && isClick == true)) {
context?.let {
var appWidgetManager: AppWidgetManager = AppWidgetManager.getInstance(it);
var componentName = ComponentName(it, _this())
var appWidgetIds = appWidgetManager.getAppWidgetIds(componentName)
onUpdate(it, appWidgetManager, appWidgetIds)
}
}
}
override fun onUpdate(
context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray,
) {
for (appWidgetId in appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId)
widgets.add(appWidgetId)
}
}
override fun onDeleted(context: Context?, appWidgetIds: IntArray?) {
super.onDeleted(context, appWidgetIds)
}
private fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int) {
val views = buildRemoteViews(context)
setViews(views)
appWidgetManager.updateAppWidget(appWidgetId, views)
}
private fun buildRemoteViews(context: Context): RemoteViews {
val views = RemoteViews(context.packageName, getLayout())
val homeIntent = Intent(context, WelcomeAct::class.java)
homeIntent.data = Uri.parse(homeIntent.toUri(Intent.URI_INTENT_SCHEME))
homeIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
val homePendingIntent = PendingIntent.getActivity(context, 0, homeIntent, PendingIntent.FLAG_UPDATE_CURRENT)
views.setOnClickPendingIntent(click2AppViewId(), homePendingIntent)
return views
}
}
2:创建桌面组件SimpleWidget,继承基类组件BaseAppWidgetProvider
import android.graphics.Color
import android.text.TextUtils
import android.util.Log
import android.widget.RemoteViews
class SimpleWidget : BaseAppWidgetProvider() {
override fun getLayout(): Int = R.layout.test_widget
override fun click2AppViewId(): Int = R.id.layout_body
override fun _this(): String = SimpleWidget::class.java.name
override fun setViews(views: RemoteViews) {
// sp获取颜色
var color = spGetString("color")
if (!TextUtils.isEmpty(color)) {
var parseColor = Color.parseColor(color)
views.setInt(R.id.tv, "setTextColor", parseColor)
}
}
}
3:创建桌面组件布局test_widget.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/Widget.Desktopflipclockandroid.AppWidget.Container"
android:id="@+id/layout_body"
android:layout_width="match_parent"
android:layout_height="170dp"
android:gravity="center"
android:orientation="vertical"
android:theme="@style/Theme.Desktopflipclockandroid.AppWidgetContainer"
android:background="@drawable/widget_bg">
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="2222"
android:textColor="@color/white"/>
</LinearLayout>
4:Manifast文件注册广播
<receiver
android:name=".widget.SimpleWidget"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.intent.action.TIME_SET"/>
<action android:name="android.intent.action.TIME_TICK"/>
<action android:name="android.intent.action.DATE_CHANGED"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/test_widget_info" />
</receiver>
5:创建xml test_widget_info.xml resource文件
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/app_widget_description"
android:initialKeyguardLayout="@layout/test_widget"
android:initialLayout="@layout/test_widget"
android:minWidth="200dp"
android:minHeight="100dp"
android:previewImage="@mipmap/img_fg_widget"
android:previewLayout="@layout/test_widget"
android:resizeMode="horizontal|vertical"
android:targetCellWidth="4"
android:targetCellHeight="2"
android:updatePeriodMillis="86400000"
android:widgetCategory="home_screen|keyguard" />
关于BaseAppWidgetProvider基类中的onReceive方法:
android.intent.action.DATE_CHANGED".equals(action)是判断接收的广播是否为系统的日期改变广播,就是每天凌晨0点接收到,然后去刷新widget桌面部件,日期及时更新可以用到。
("android.appwidget.action.APPWIDGET_UPDATE".equals(action) && isClick == true)是判断用户是在app中去更新桌面部件,只需要在事件中发送APPWIDGET_UPDATE广播和putExtra isClick为true就可以了。如下:
val intent = Intent()
intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
intent.`package` = packageName
intent.putExtra("isClick",true)
sendBroadcast(intent);