如何在Jetpack Compose应用中托管并绘制已安装应用Widget
开发Android Launcher:Jetpack Compose中集成已安装App Widget的问题与求助
我正在使用Jetpack Compose开发一款Android Launcher,目标是实现在主屏幕加载并展示所有已安装应用Widget的功能,但始终找不到完整、可靠的参考资料。曾参考过Medium文章和一篇早期博客内容,但讲解不完整,按其方法操作时出现大量错误。尝试让ChatGPT生成相关代码,但代码无法正常运行,以下是生成的代码:
MainActivity代码
class MainActivity : ComponentActivity() { private lateinit var appWidgetHost: AppWidgetHost private lateinit var appWidgetManager: AppWidgetManager private lateinit var requestPermissionLauncher: ActivityResultLauncher<String> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) appWidgetHost = AppWidgetHost(this, APP_WIDGET_HOST_ID) appWidgetManager = AppWidgetManager.getInstance(this) requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean -> if (isGranted) { // Permission granted, continue with widget setup println("permission") setupWidgets() } else { setContent{ WidgetsScreenExampleTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { println("no permission") Text( text = "permission not found", style = TextStyle(color = Color.Black, fontSize = TextUnit(10f, TextUnitType.Sp)) ) } } } } } checkAndRequestWidgetPermission() } private fun checkAndRequestWidgetPermission() { val permission = "android.permission.BIND_APPWIDGET" when { ContextCompat.checkSelfPermission( this, permission ) == PackageManager.PERMISSION_GRANTED -> { // Permission already granted, continue with widget setup setupWidgets() } Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> { // Permission not granted, request it from the user requestPermissionLauncher.launch(permission) } else -> { // For versions below Android M, permission is granted at installation time // Continue with widget setup setupWidgets() } } } private fun setupWidgets() { // Continue with widget setup here setContent { WidgetsScreenExampleTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { WidgetsView( Modifier .fillMaxSize(), appWidgetHost, appWidgetManager, APP_WIDGET_HOST_ID ) } } } } companion object { const val APP_WIDGET_HOST_ID = 1 } }
AppWidgetHostView Composable代码
@Composable fun AppWidgetHostView( appWidgetManager: AppWidgetManager, appWidgetHost: AppWidgetHost, appWidgetId: Int, modifier: Modifier = Modifier ) { val appWidgetHostView = appWidgetHost.createView( LocalContext.current, appWidgetId, appWidgetManager.getAppWidgetInfo(appWidgetId) ) DisposableEffect(appWidgetHostView) { onDispose { appWidgetHost.deleteAppWidgetId(appWidgetId) } } // Measure the app widget size appWidgetHostView.measure( View.MeasureSpec.makeMeasureSpec(100.dp.value.toInt(), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(100.dp.value.toInt(), View.MeasureSpec.EXACTLY) ) // Layout the app widget appWidgetHostView.layout( 0, 0, appWidgetHostView.measuredWidth, appWidgetHostView.measuredHeight ) // Draw the app widget AndroidView( factory = { appWidgetHostView }, modifier = modifier ) }
AppWidgetListItem Composable代码
@Composable fun AppWidgetListItem(appWidget: AppWidget, appWidgetHostId: Int) { val context = LocalContext.current val appWidgetHost = AppWidgetHost(context, appWidgetHostId) val appWidgetManager = AppWidgetManager.getInstance(context) val (isExpanded, setExpanded) = remember { mutableStateOf(false) } // val remoteViews = appWidgetManager.getAppWidgetViews(appWidget.appWidgetId) Column( modifier = Modifier .fillMaxWidth() .padding(16.dp) .background(MaterialTheme.colorScheme.background) .clickable { setExpanded(!isExpanded) } ) { Text(text = appWidget.appWidgetInfo.label) if (isExpanded) { Box( modifier = Modifier .fillMaxWidth() .padding(top = 8.dp) ) { AppWidgetHostView( appWidgetManager = appWidgetManager, appWidgetHost = appWidgetHost, appWidgetId = appWidget.appWidgetId, modifier = Modifier.fillMaxWidth() ) } } } }
WidgetsView Composable代码
@OptIn(ExperimentalMaterial3Api::class) @Composable fun WidgetsView( modifier: Modifier = Modifier, appWidgetHost: AppWidgetHost, appWidgetManager: AppWidgetManager, appWidgetHostId: Int ) { val context = LocalContext.current val appWidgetIds = appWidgetHost.appWidgetIds val appWidgets = appWidgetIds.map { appWidgetId -> val appWidgetInfo = appWidgetManager.getAppWidgetInfo(appWidgetId) if (appWidgetInfo != null) { AppWidget(appWidgetId, appWidgetInfo) } else { null } }.mapNotNull { it } Column { TopAppBar( title = { Text(text = "Installed Widgets") }, actions = { IconButton(onClick = { /* Handle settings action */ }) { Icon(imageVector = Icons.Default.Star, contentDescription = null) } } ) LazyColumn { items(appWidgets.size) { i -> AppWidgetListItem(appWidgets[i], appWidgetHostId) } } } }
希望能得到针对这段代码的问题反馈,以及实现该功能的优质参考资源指引。
内容的提问来源于stack exchange,提问作者Dhruv Bansal
相关产品推荐
相关产品推荐

