首页 > 解决方案 > 在较新版本的 Android 中,按钮单击在小部件中不起作用

问题描述

我创建了一个 Widget,其中包含一个 ViewFlipper 和可以切换的按钮。找到了解决方案,应用了它,一切正常,但在较新版本的 Android 中却不行。例如,在 API 24 (Android 7) 版本中它可以正常工作,但在新版本中,例如 API 30,小部件不处理点击。请帮我找出问题所在。

package com.example.informationwidget.widgets.actual_info_widget

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.util.Log
import android.widget.RemoteViews
import com.example.informationwidget.R
import com.example.informationwidget.SettingsActivity
import com.example.informationwidget.services.LastCompaniesService


/**
 * Implementation of App Widget functionality.
 */
class ActualInfoWidget : AppWidgetProvider() {
    private val WIDGET_LC_LEFT_BUTTON = "android.appwidget.action.WIDGET_LC_LEFT_BUTTON"
    private val WIDGET_LC_RIGHT_BUTTON = "android.appwidget.action.WIDGET_LC_RIGHT_BUTTON"
    private val WIDGET_LC_SETTINGS_BUTTON = "android.appwidget.action.WIDGET_LC_SETTINGS_BUTTON"
    private val WIDGET_LC_UPDATE_BUTTON = "android.appwidget.action.WIDGET_LC_UPDATE_BUTTON"

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

    override fun onReceive(context: Context?, intent: Intent?) {
        super.onReceive(context, intent)

        val v = intent!!.getIntExtra(
            AppWidgetManager.EXTRA_APPWIDGET_ID,
            AppWidgetManager.INVALID_APPWIDGET_ID
        )

        val views = RemoteViews(context!!.packageName, R.layout.actual_info_widget)
        val appWidgetManager = AppWidgetManager.getInstance(context)

        val widgetName = ComponentName(context, ActualInfoWidget::class.java)
        val widgetId = AppWidgetManager.getInstance(context).getAppWidgetIds(widgetName)

//        Button click
        when {
            WIDGET_LC_LEFT_BUTTON == intent!!.action -> {
                Log.e("This is ViewFlipper:", "This is left button, id = " + v) //widgetId[0]
                views.showPrevious(R.id.vfLastChosenCompanies)
            }
            WIDGET_LC_RIGHT_BUTTON == intent.action -> {
                Log.e("This is ViewFlipper:", "This is right button, id = " + v)
                views.showNext(R.id.vfLastChosenCompanies)
            }
            WIDGET_LC_UPDATE_BUTTON == intent.action -> {
                updateAppWidget(context, appWidgetManager, widgetId[0])
            }
        }

        appWidgetManager.updateAppWidget(widgetId[0], views)
    }

    private fun updateAppWidget(
        context: Context,
        appWidgetManager: AppWidgetManager,
        appWidgetId: Int
    ) {
        val views = RemoteViews(context.packageName, R.layout.actual_info_widget)
        val mainIntent = Intent(context, ActualInfoWidget::class.java)
        mainIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
        mainIntent.data = Uri.parse(mainIntent.toUri(Intent.URI_INTENT_SCHEME))

        // Buttons from widget
        val pendingSettingsBtn = PendingIntent.getActivity(context, 0, clickSettingsBtn(context), 0)

        val viewerIntentLeftClick = Intent(WIDGET_LC_LEFT_BUTTON)
        val viewerPendingLeftClick = PendingIntent.getBroadcast(
            context,
            0,
            viewerIntentLeftClick,
            PendingIntent.FLAG_UPDATE_CURRENT
        )

        val viewerIntentRightClick = Intent(WIDGET_LC_RIGHT_BUTTON)
        val viewerPendingRightClick = PendingIntent.getBroadcast(
            context,
            0,
            viewerIntentRightClick,
            PendingIntent.FLAG_UPDATE_CURRENT
        )

        val intentUpdateClick = Intent(WIDGET_LC_UPDATE_BUTTON)
        val pendingUpdateBtn = PendingIntent.getBroadcast(
            context,
            0,
            intentUpdateClick,
            PendingIntent.FLAG_UPDATE_CURRENT
        )

        showLastCompanies(views, context, appWidgetId)
        Log.e("ID: ", appWidgetId.toString())

        views.setOnClickPendingIntent(R.id.btnLcSettings, pendingSettingsBtn)
        views.setOnClickPendingIntent(R.id.btnLeftScroll, viewerPendingLeftClick)
        views.setOnClickPendingIntent(R.id.btnRightScroll, viewerPendingRightClick)
        views.setOnClickPendingIntent(R.id.btnLcUpdate, pendingUpdateBtn)

        appWidgetManager.updateAppWidget(appWidgetId, views)
        appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.lvLastCompanies)
    }

    private fun clickSettingsBtn(context: Context): Intent {
        val intent = Intent(context, SettingsActivity::class.java)
        intent.data = Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))

        return intent
    }

    private fun showLastCompanies(rv: RemoteViews, context: Context, appWidgetId: Int) {
        val adapter: Intent = Intent(context, LastCompaniesService::class.java)
        rv.setRemoteAdapter(R.id.lvLastCompanies, adapter)
    }
}

标签: androidwidgetandroid-widget

解决方案


问题是您正在使用隐式广播。只需确保将它们全部明确

例如:

val viewerIntentLeftClick = Intent(WIDGET_LC_LEFT_BUTTON)
ComponentName componentName = ComponentName(context, ActualInfoWidget::class.java);
viewerIntentLeftClick.setComponent(componentName);

查看从 Android N 开始的限制


推荐阅读