Jetpack Compose Glance 小部件未更新

问题描述 投票:0回答:1

我有一个 jetpack 撰写概览小部件,它在启动时显示一条短信。

如果用户为应用程序启用了辅助功能服务,则扫视小部件应更改为按钮。但这并没有按预期工作。

下面是我的代码。

MyAccessibilityService.kt

class MyAccessibilityService : AccessibilityService() {

    companion object {
        private const val TAG = "MY_ACCESSIBILITY_SERVICE_TAG"
    }

    override fun onAccessibilityEvent(event: AccessibilityEvent) {
        // some code
    }

    override fun onServiceConnected() {
        super.onServiceConnected()
        Log.i(TAG, "Service connected")

        CoroutineScope(Dispatchers.IO).launch {
            Log.i(TAG, "Updating widget")
            MyAppWidget().updateAll(this@MyAccessibilityService)
        }
    }

    override fun onInterrupt() {
        Log.i(TAG, "Service interrupted")
    }

}

MyAppWidget.kt

class MyAppWidget : GlanceAppWidget() {

    override val sizeMode = SizeMode.Exact

    override suspend fun provideGlance(context: Context, id: GlanceId) {

        // In this method, load data needed to render the AppWidget.
        // Use `withContext` to switch to another thread for long running
        // operations.
        val manager =
            context.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager

        val isServicesEnabled = context.isManagerAndServicesEnabled(manager)

        provideContent {
            MyContent(
                isAccessibilityServicesEnabled = isServicesEnabled
            )
        }
    }
}

MyAppWidgetUi.kt

@Composable
internal fun MyContent(
    isAccessibilityServicesEnabled: Boolean = false
) {

    // Get the smallest dimension to ensure square shape
    val width = LocalSize.current.width
    val height = LocalSize.current.height
    val size = minOf(width, height)
    val coroutine = rememberCoroutineScope()

    if(isAccessibilityServicesEnabled){
        Box(
            modifier = GlanceModifier
                .size(size)
                .background(GlanceTheme.colors.background)
                .cornerRadius(100.dp)
                .clickable {
                    sendAccessibilityEvent()
                },
            contentAlignment = Alignment.Center
        ) {
            Image(
                provider = ImageProvider(R.drawable.ic_launcher_foreground),
                contentDescription = "",
                colorFilter = ColorFilter.tint(GlanceTheme.colors.primary),
                contentScale = ContentScale.Fit,
                modifier = GlanceModifier.size(48.dp)
            )
        }
    }else{
        Box(
            modifier = GlanceModifier
                .fillMaxSize()
                .background(GlanceTheme.colors.background)
                .clickable(actionStartActivity<MainActivity>()),
            contentAlignment = Alignment.Center
        ) {
            Text(
                "Open app to setup"
            )
        }
    }
}

在启用辅助功能服务之前,如果我将小部件放在主屏幕上,它会按预期显示文本。当我为我的应用程序启用辅助功能服务时,小部件不会更改。我需要删除该小部件并再次添加它才能看到该按钮重新出现。

有人可以帮我吗?

android-jetpack-compose accessibilityservice android-jetpack-compose-material3 glance-appwidget glance
1个回答
0
投票

出现此问题的原因是 GlanceAppWidget 框架不会自动更新小部件以响应辅助功能设置等外部条件的变化。当无障碍服务状态发生变化时,您需要显式触发小部件更新。

解决问题的方法如下:

解决步骤: 广播小部件更新:当无障碍服务状态发生变化时,您应该发送广播以触发小部件更新。

实现

BroadcastReceiver
:创建一个自定义
BroadcastReceiver
,用于侦听更新广播并调用
GlanceAppWidget's
updateAll()
方法。

修改

AccessibilityService
:从无障碍服务的
onServiceConnected
方法发送广播。

更新代码


----------
BroadcastReceiver for Widget Updates
Create a `BroadcastReceiver` to handle widget updates:
----------
class MyWidgetUpdateReceiver : BroadcastReceiver() {
      override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == "com.example.MY_WIDGET_UPDATE") {
             MyAppWidget().updateAll(context)
         }
      }
   }



----------
Declare the receiver in the AndroidManifest.xml:
----------
<receiver android:name=".MyWidgetUpdateReceiver">
    <intent-filter>
        <action android:name="com.example.MY_WIDGET_UPDATE" />
    </intent-filter>
</receiver>
 


----------
Trigger the Broadcast in the Accessibility Service
Modify your AccessibilityService to send the broadcast:
----------
override fun onServiceConnected() {
    super.onServiceConnected()
    Log.i(TAG, "Service connected")

    CoroutineScope(Dispatchers.IO).launch {
        Log.i(TAG, "Sending widget update broadcast")
        val intent = Intent("com.example.MY_WIDGET_UPDATE")
        sendBroadcast(intent)
    }
}


----------
Update the GlanceAppWidget Logic
Your existing MyAppWidget logic remains unchanged. The provideGlance method will now get called whenever the broadcast triggers an update.
----------


© www.soinside.com 2019 - 2024. All rights reserved.