我有一个 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"
)
}
}
}
在启用辅助功能服务之前,如果我将小部件放在主屏幕上,它会按预期显示文本。当我为我的应用程序启用辅助功能服务时,小部件不会更改。我需要删除该小部件并再次添加它才能看到该按钮重新出现。
有人可以帮我吗?
出现此问题的原因是 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.
----------