android設定桌面小部件

yuqingsen發表於2020-12-17

1、簡單的建立完成後:
在AppWidgetProvider內

 override fun onUpdate(
        context: Context,
        appWidgetManager: AppWidgetManager,
        appWidgetIds: IntArray
    ) {
        // There may be multiple widgets active, so update all of them
        for (appWidgetId in appWidgetIds) {
            onAppWidgetOptionsChanged(
                context,
                appWidgetManager,
                appWidgetId,
                appWidgetManager.getAppWidgetOptions(appWidgetId)
            )
        }
    }

這個方法系統會根據你的配置檔案進行週期性呼叫,雖然說最少是15分鐘,但是經常性是30分鐘呼叫一次。

  /**
     * 桌面小部件新增時呼叫
     * @param context receiver is running
     */
    override fun onEnabled(context: Context) {
        startNotifyServiceOne()
        val componentName = ComponentName(context, WeatherOneWidget::class.java)
        val packageManager = context.packageManager
        val componentEnabledSetting = packageManager.getComponentEnabledSetting(componentName)
        if (componentEnabledSetting != PackageManager.COMPONENT_ENABLED_STATE_ENABLED && componentEnabledSetting != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
            packageManager.setComponentEnabledSetting(
                componentName,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP
            )
        }
        MobclickAgent.onEvent(context, WIDGET_ADD,"主要顯示天氣---4x1")
    }

這個方法會在新增桌面小部件時呼叫,我們在這裡做一些基礎設定以及開啟相應的服務

 /**
     * 控制元件大小發生改變時呼叫
     * @param context receiver is running
     * @param appWidgetManager AppWidgetManager的物件,可以用這個呼叫updateAppWidget
     * @param appWidgetId 桌面小部件id,哪個桌面小部件大小發生了變化,這個就是哪個的id
     * @param newOptions 不知道
     */
    override fun onAppWidgetOptionsChanged(
        context: Context?,
        appWidgetManager: AppWidgetManager?,
        appWidgetId: Int,
        newOptions: Bundle?
    ) {
        startNotifyServiceOne()
    }

這個方法是在控制元件大小發生變化時呼叫,而且我們剛才也手動呼叫了,我們在這裡開啟相應的服務
服務通過以下方式開啟就可以了

val intent = Intent(context, WeatherOneService::class.java)
intent.setPackage(context.packageName)
ContextCompat.startForegroundService(context, intent)

底下這個方法在service中onCreate中呼叫

   private fun initForeground() {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                startForeground(1003, getNotification(this))
            }
        } catch (e: Throwable) {
            e.printStackTrace()
        }
    }

getNotification方法主要是做以下設定

private fun getNotification(context: Context): Notification {
        return NotificationCompat.Builder(context, "weather")
            .setSmallIcon(R.mipmap.app_launcher)
            .setContentTitle(context.getString(R.string.app_name))
            .setContentText(context.getString(R.string.slogan))
            .setContentIntent(getMainPendingIntent(context)).build()
    }
    
    private fun getMainPendingIntent(context: Context): PendingIntent {
        val intent = Intent()
        intent.setPackage(context.packageName)
        intent.component = ComponentName(context, ReMainActivity::class.java)
        intent.action = context.packageName + ".action.notify"
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        intent.putExtra("isNeedCheckNotify", false)
        intent.putExtra("where", "notify")
        return PendingIntent.getActivity(context, 0, intent, 0)
    }

最後我們在onStartCommand(intent: Intent?, flags: Int, startId: Int)中做一些需要的耗時操作。

 clickCode = intent?.getIntExtra(REQUEST_CODE, 0) ?: 0
        timer?.cancel()
        timer = Timer()
        val handler = MyHandler(this)
        timer?.schedule(object : TimerTask() {
            override fun run() {
                handler.removeMessages(TIME_UPDATE)
                handler.sendEmptyMessageAtTime(TIME_UPDATE, 1000)
            }
        }, 0, 1000 * 60 * 10)//10分鐘更新一次

最後,設定remoteviews
1、建立自己的remoteviews繼承remoteviews
在init中設定基礎的點選事件
如果涉及到通過點選事件開啟service的話,可以這麼設定

  private fun getSupportPending(context: Context, intent: Intent): PendingIntent {
        Intrinsics.checkParameterIsNotNull(context, com.umeng.analytics.pro.b.Q)
        Intrinsics.checkParameterIsNotNull(intent, "Intent")
        intent.setPackage(context.packageName)
        intent.putExtra(REQUEST_CODE,41)
        return when {
            SDK_INT >= Build.VERSION_CODES.P -> {
                intent.setClass(context, WidgetHotSpotActivity::class.java)
                PendingIntent.getActivity(context, 41, intent, PendingIntent.FLAG_UPDATE_CURRENT)
            }
            SDK_INT >= Build.VERSION_CODES.O -> {
                PendingIntent.getForegroundService(
                    context,
                    41,
                    intent,
                    PendingIntent.FLAG_UPDATE_CURRENT
                )
            }
            else -> {
                PendingIntent.getService(context, 41, intent, PendingIntent.FLAG_UPDATE_CURRENT)
            }
        }
    }

根據不同的版本使用不同的方法
WidgetHotSpotActivity內是這樣設定的

class WidgetHotSpotActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val intExtra = intent.getIntExtra(REQUEST_CODE, 0)
        startNotifyServiceOne(intExtra)
        finish()
    }
}

requestcode是為了區分點選事件設定的,不需要可以不設定。

相關文章