需要获取数据的 Android 小部件仅显示加载
Posted
技术标签:
【中文标题】需要获取数据的 Android 小部件仅显示加载【英文标题】:Android widget that requires data fetching only shows loading 【发布时间】:2020-03-16 23:22:33 【问题描述】:我正在尝试通过 android 小部件选择器在视图中添加一个小部件。一个简单的模拟时钟小部件正确显示,但必须获取数据的小部件仅显示加载而不显示数据,如下面的屏幕截图所示。
我的小部件创建代码是从Hosting Android Widget 完成的。
我的代码是:
class MainActivity : AppCompatActivity()
private lateinit var mAppWidgetManager: AppWidgetManager
lateinit var mAppWidgetHost: AppWidgetHost
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mAppWidgetManager = AppWidgetManager.getInstance(this)
mAppWidgetHost = AppWidgetHost(this, APPWIDGET_HOST_ID)
add_widget.setOnClickListener
selectWidget()
fun selectWidget()
val appWidgetId = mAppWidgetHost.allocateAppWidgetId()
val pickIntent = Intent(AppWidgetManager.ACTION_APPWIDGET_PICK)
pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
addEmptyData(pickIntent)
startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET)
private fun addEmptyData(pickIntent: Intent)
val customInfo = arrayListOf<Parcelable>()
pickIntent.putParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_INFO, customInfo)
val customExtras = arrayListOf<Parcelable>()
pickIntent.putParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_EXTRAS, customExtras)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK)
if (requestCode == REQUEST_PICK_APPWIDGET)
configureWidget(data)
else if (requestCode == REQUEST_CREATE_APPWIDGET)
createWidget(data)
else if (resultCode == RESULT_CANCELED && data != null)
val appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
if (appWidgetId != -1)
mAppWidgetHost.deleteAppWidgetId(appWidgetId)
private fun configureWidget(data: Intent?)
val extras = data?.extras ?: return
val appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
val appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId)
if (appWidgetInfo.configure != null)
val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE)
intent.component = appWidgetInfo.configure
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
startActivityForResult(intent, REQUEST_CREATE_APPWIDGET)
else
createWidget(data)
private fun createWidget(data: Intent?)
val extras = data?.extras ?: return;
val appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
val appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
val hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
remove_widget.setOnClickListener
removeWidget(hostView)
hostView.setAppWidget(appWidgetId, appWidgetInfo);
widgetLayout.addView(hostView);
override fun onStart()
super.onStart()
mAppWidgetHost.startListening()
override fun onStop()
super.onStop()
mAppWidgetHost.stopListening()
private fun removeWidget(hostView: AppWidgetHostView)
mAppWidgetHost.deleteAppWidgetId(hostView.appWidgetId)
widgetLayout.removeView(hostView);
companion object
const val REQUEST_PICK_APPWIDGET = 9
const val REQUEST_REFRESH_APPWIDGET = 10
const val APPWIDGET_HOST_ID = 442
const val REQUEST_CREATE_APPWIDGET = 5
这里,remove_widget 和 add_widget 是按钮,widgetLayout 是添加小部件的线性布局。
编辑: 添加 gmail 小部件后,日志中会显示以下错误。
2019-11-28 14:18:33.652 15363-15363/com.example.testapplication W/AppWidgetHostView: Error inflating RemoteViews : android.widget.RemoteViews$ActionException: android.widget.RemoteViews$ActionException: view: androidx.appcompat.widget.AppCompatImageView can't use method with RemoteViews: setImageResource(int)
注意:从另一个启动器,小部件按预期呈现,但不是来自我的代码。另外,我用 applicationContext 改变了我的上下文。但是,它会产生相同的结果。
【问题讨论】:
是否曾经调用过 createWidget 或 configureWidget 函数?您能否进行 printlns 并查看它们是否按预期/何时被调用? 是的,create 和 configure 都被正确调用了,但是添加 gmail 小部件后日志中出现异常。我已经更新了问题,请查看。 【参考方案1】:如果您使用的是 androidX AppCompactActivity,请尝试使用普通活动,看看是否有效。
import android.app.Activity;
//other codes....
public class MainActivity extends Activity
// other codes...
【讨论】:
是的,它适用于活动。可能是因为 Remoteviews 使用的是 appcompat 视图而不是 android 应用视图。【参考方案2】:** RemoteViews 仅限于支持以下布局:
AdapterViewFlipper 框架布局 网格布局 网格视图 线性布局 列表视图 相对布局 堆栈视图 ViewFlipper** 以及以下小部件:
模拟时钟 按钮 天文钟 图像按钮 图像视图 进度条 文本时钟 文本视图** 不支持这些类的后代。
你应该检查你的布局!
【讨论】:
我自己没有实现远程视图。我正在从小部件选择器加载小部件并将其添加到线性布局视图中,所以我认为我的布局没有问题。以上是关于需要获取数据的 Android 小部件仅显示加载的主要内容,如果未能解决你的问题,请参考以下文章
多个 Android Widget 实例仅更新最后一个小部件