首页 > 解决方案 > 更新小部件的频率超过 30 分钟

问题描述

很多答案,没有一个有效。

您应该使用服务、警报还是计时器?所有的答案似乎只是一个随机的猜测。

在这个例子中onDisable,创建一个新实例AppWidgetAlarm然后调用stopAlarm()- 警报不是仍在运行在onEnabled.

onEnabled只有在创建新小部件时才会调用警报。因此,在重新启动后,警报将不会启动——用户必须删除并重新创建小部件。

package com.example.thisisnotawidget

import android.app.AlarmManager
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.widget.RemoteViews
import java.util.*

val ACTION_AUTO_UPDATE = "doodah"

// https://stackoverflow.com/questions/5476867/updating-app-widget-using-alarmmanager/14319020#14319020
class AppWidgetAlarm(private val context: Context) {
    private val ALARM_ID = 0
    private val INTERVAL_MILLIS = 500

    fun startAlarm() {
        val calendar = Calendar.getInstance()
        calendar.add(Calendar.MILLISECOND, INTERVAL_MILLIS)
        val alarmIntent = Intent(context, ThisIsTheWidget::class.java)
        alarmIntent.action = ACTION_AUTO_UPDATE
        val pendingIntent = PendingIntent.getBroadcast(
            context,
            ALARM_ID,
            alarmIntent,
            PendingIntent.FLAG_CANCEL_CURRENT
        )
        val alarmManager =
            context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        // RTC does not wake the device up
        alarmManager.setRepeating(
            AlarmManager.RTC,
            calendar.timeInMillis,
            INTERVAL_MILLIS.toLong(),
            pendingIntent
        )
    }

    fun stopAlarm() {
        val alarmIntent = Intent(ACTION_AUTO_UPDATE)
        val pendingIntent = PendingIntent.getBroadcast(
            context,
            ALARM_ID,
            alarmIntent,
            PendingIntent.FLAG_CANCEL_CURRENT
        )
        val alarmManager =
            context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        alarmManager.cancel(pendingIntent)
    }
}

/**
 * Implementation of App Widget functionality.
 */
class ThisIsTheWidget : AppWidgetProvider() {

    override fun onUpdate(
        context: Context,
        appWidgetManager: AppWidgetManager,
        appWidgetIds: IntArray
    ) {
        // Do the updating.
        val thisWidget = ComponentName(context, ThisIsTheWidget::class.java)
        val allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget)
        for (widgetId in allWidgetIds) {
            updateAppWidget(context, appWidgetManager, widgetId)
        }
    }

    override fun onEnabled(context: Context) {
        // Enter relevant functionality for when the first widget is created
        // start alarm
        val appWidgetAlarm = AppWidgetAlarm(context.applicationContext)
        appWidgetAlarm.startAlarm()
    }

    override fun onDisabled(context: Context) {
        // Enter relevant functionality for when the last widget is disabled
        // stop alarm only if all widgets have been disabled
        val appWidgetManager = AppWidgetManager.getInstance(context);
        val thisWidget = ComponentName(context, ThisIsTheWidget::class.java)
        val allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget)
        if (allWidgetIds.count() == 0) {
            // stop alarm
            val appWidgetAlarm = AppWidgetAlarm(context.getApplicationContext());
            appWidgetAlarm.stopAlarm();
        }
    }
}

internal fun updateAppWidget(
    context: Context,
    appWidgetManager: AppWidgetManager,
    appWidgetId: Int
) {
    val prefs = context.getSharedPreferences("W", 0)
    val n:Int = prefs.getInt("W_" + appWidgetId.toString(), 0) + 1
    val e = prefs.edit()
    e.putInt("W_" + appWidgetId.toString(), n)
    e.apply()
    e.commit()

    // Construct the RemoteViews object
    val views = RemoteViews(context.packageName, R.layout.this_is_the_widget)
    views.setTextViewText(R.id.appwidget_text, n.toString())

    // Instruct the widget manager to update the widget
    appWidgetManager.updateAppWidget(appWidgetId, views)
}

标签: android-widgetandroid-alarms

解决方案


推荐阅读