需要获取数据的 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 实例仅更新最后一个小部件

Flex 小部件从 JSON 加载图像,而不是显示所有图像

带有 ListView 的小部件为找到的每个项目显示“正在加载”

如何刷新 Widget 数据?

Android桌面小部件AppWidget开发

带有 AlarmManager 和配置的 Android 小部件