2

I am trying to add a widget in view by an android widget picker. A simple analog clock widget is displayed correctly but widget, where data have to fetch, is only showing loading without showing data as in the screenshot below.

Screenshot

My widget creation code is done from Hosting Android Widget.

My code is :

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
}
}

Here, remove_widget and add_widget are button and widgetLayout is linearlayout to add widget.

edit: The following error is shown in log after adding gmail widget.

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)

note: from another launcher, widget is rendering as expected, not from my code though. Also, I changed my context with applicationContext. But, it produces same result.

Xuzan
  • 335
  • 1
  • 11
  • Do either the createWidget or configureWidget functions ever get called? Could you do printlns and see if they are being called as/when expected? – Scott Evans Nov 28 '19 at 08:05
  • Yes, both create and configure is being called properly, but there was an exception in log after adding gmail widget. I have updated the question, please look into it. – Xuzan Nov 28 '19 at 08:37

2 Answers2

1

If you are using androidX AppCompactActivity, then try to use normal activity and see if that works.

import android.app.Activity;


//other codes....

public class MainActivity extends Activity {

    // other codes...

}
umuieme
  • 729
  • 6
  • 20
  • Yes, it works with activity. Probably as Remoteviews is using appcompat views rather than android app views. – Xuzan Nov 28 '19 at 11:11
0

** RemoteViews is limited to support for the following layouts:

  • AdapterViewFlipper
  • FrameLayout
  • GridLayout
  • GridView
  • LinearLayout
  • ListView
  • RelativeLayout
  • StackView
  • ViewFlipper

** And the following widgets:

  • AnalogClock
  • Button
  • Chronometer
  • ImageButton
  • ImageView
  • ProgressBar
  • TextClock
  • TextView

** Descendants of these classes are not supported.

You should review your layout!

Louis Nguyen
  • 347
  • 6
  • 18
  • I am not implementing remote views myself. I am loading a widget from the widget picker and adding it in a linear layout view, so I think there is no problem in my layout. – Xuzan Dec 02 '19 at 07:36