Android 小组件完整案例

介绍一下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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龍林1102

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值