介绍一下android桌面小组件完整的案例,包括:
- 注册一个小组件(系统中能找到并添加小组件)
- 更新小组件数据
- 应用主动添加小组件
- 小组件中的坑
AndroidManifest.xml:? (小组件注册, 其本质是一个BroadcastReceiver)
....
<receiver android:name=".appwidget.HanlonglinWidgetProvider"
android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/app_widget" />
</receiver>
....
xml/app_widget.xml: (小组件配置信息)
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="90dp"
android:minHeight="90dp"
android:updatePeriodMillis="1800000"
android:initialLayout="@layout/moment_widget_moment"
android:widgetCategory="home_screen">
</appwidget-provider>
HanlonglinWidgetProvider.kt: (小组件绑定view的类)
package com.dragon.test.hanlonglindemo.appwidget
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.content.Intent
import android.util.Log
import android.widget.RemoteViews
import com.dragon.test.hanlonglindemo.MainActivity
import com.dragon.test.hanlonglindemo.R
/***
* create by DragonForest on 2022/4/15
*/
class HanlonglinWidgetProvider: AppWidgetProvider() {
private val TAG = this.javaClass.simpleName
override fun onUpdate(
context: Context?,
appWidgetManager: AppWidgetManager?,
appWidgetIds: IntArray?
) {
Log.i(TAG, "HanlonglinWidgetProvider.onUpdate")
appWidgetIds?.forEach { appWidgetId ->
val views: RemoteViews = RemoteViews(
context?.packageName,
R.layout.widget_layout
)
var intent = Intent(context, MainActivity::class.java)
var pendingIntent = PendingIntent.getActivity(
context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
)
views.setOnClickPendingIntent(R.id.iv_widget, pendingIntent)
appWidgetManager?.updateAppWidget(appWidgetId, views)
}
}
companion object{
/**
* 更新组件调用
*/
fun updateAppWidget(
context: Context?,
appWidgetManager: AppWidgetManager?,
appWidgetId: Int,
imgRes: Int
){
val views = RemoteViews(context!!.packageName, R.layout.widget_layout)
views.setImageViewResource(R.id.iv_widget,imgRes)
appWidgetManager?.updateAppWidget(appWidgetId,views)
}
}
}
WidgetController.kt: (小组件操作类)
package com.dragon.test.hanlonglindemo.appwidget
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.widget.Toast
import androidx.annotation.RequiresApi
/***
* 小组件操作类
* create by DragonForest on 2022/4/15
*/
object WidgetController {
private val TAG = this.javaClass.simpleName
/**
* 更新小组件,触发组件的onUpdate
*/
fun update(context: Context){
var intent = Intent(context,HanlonglinWidgetProvider::class.java)
intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
var bundle = Bundle()
bundle.putIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS, getAppWidgetIds(context))
intent.putExtras(bundle)
context.sendBroadcast(intent)
}
/**
* 添加到主屏幕
*/
@RequiresApi(Build.VERSION_CODES.O)
fun addToMainScreen(context: Context){
val appWidgetManager = AppWidgetManager.getInstance(context)
val myProvider = ComponentName(context, HanlonglinWidgetProvider::class.java)
if (getAppWidgetIds(context).isNotEmpty()) {
Toast.makeText(context,"组件已经存在",Toast.LENGTH_SHORT).show()
return
}
if (appWidgetManager.isRequestPinAppWidgetSupported()) {
// Create the PendingIntent object only if your app needs to be notified
// that the user allowed the widget to be pinned. Note that, if the pinning
// operation fails, your app isn't notified. This callback receives the ID
// of the newly-pinned widget (EXTRA_APPWIDGET_ID).
// val successCallback = PendingIntent.getBroadcast(
// /* context = */ context,
// /* requestCode = */ 0,
// /* intent = */ null,
// /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT)
appWidgetManager.requestPinAppWidget(myProvider, null, null)
}
}
private fun getAppWidgetIds(context: Context) :IntArray{
var awm = AppWidgetManager.getInstance(context)
val appWidgetIDs: IntArray = awm.getAppWidgetIds(ComponentName(context,HanlonglinWidgetProvider::class.java))
return appWidgetIDs
}
}
WidgetTestActivity.kt: (测试页面,用来展示操作)
package com.dragon.test.hanlonglindemo.appwidget
import android.app.Activity
import android.os.Build
import android.os.Bundle
import androidx.annotation.RequiresApi
import com.dragon.test.hanlonglindemo.R
import kotlinx.android.synthetic.main.activity_widget_test.*
/***
* create by DragonForest on 2022/4/15
*/
class WidgetTestActivity: Activity() {
@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_widget_test)
btn_add_to_screen.setOnClickListener {
WidgetController.addToMainScreen(this)
}
}
}
注意的地方,
更多信息:?
Enable users to configure app widgets ?|? Android Developers
|