I have a list view present in the home screen widget of my android app. I am using a flutter plugin called home widget to enable communication between kotlin and dart code. There are two elements in every item of the listview: a checkbox and text. When the checkbox is clicked, I want to execute HomeWidgetBackgroundIntent.getBroadcast method to trigger a background callback in my dart code(this makes some changes in the database) and when the text is clicked I want to use HomeWidgetLaunchIntent.getActivity method to open my app with a specific URI. Both these methods are pending intents. The problem is that android doesn't allow you to add different pending intents for one single list item. They want developers to use fillInIntent for individual items and then set common pending intent template. How I am supposed to detect which element is clicked(checkbox or text) and set a different pending intent template for both cases? I have also thought of letting the pending intent template to trigger the receiver of the widget and then call the home_widget plugin methods here(based on data set in fillInIntent). But since the methods are pending intents, how can I trigger pending intents here(usually pending intents are triggered on click event but its not possible to trigger them in onReceive method right)?
Code pertaining to my widget:
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray, widgetData: SharedPreferences) {
Log.d("debugging", "widget loaded")
val sharedPref: SharedPreferences = context.getSharedPreferences(
"ApplicationListener", Context.MODE_PRIVATE)
appWidgetIds.forEach { widgetId ->
val views = RemoteViews(context.packageName, R.layout.widget_layout).apply {
val todosStr = widgetData.getString("todos", "null")
val todos = ArrayList<HashMap<String, Any>>()
val todosRemoteView = RemoteViews.RemoteCollectionItems.Builder()
if(todosStr != "null"){
val jObj = JSONObject(todosStr)
val jsonArry = jObj.getJSONArray("todos")
for (i in 0 until jsonArry.length()) {
val todo = HashMap<String, Any>()
val obj = jsonArry.getJSONObject(i)
todo["id"] = obj.getInt("id")
todo["taskName"] = obj.getString("taskName")
todos.add(todo)
val view = RemoteViews(context.packageName, R.layout.each_todo).apply {
setTextViewText(R.id.each_todo_container_text, todo["taskName"].toString())
setCompoundButtonChecked(R.id.each_todo_container_checkbox, todo["finished"].toString().toBoolean())
//i want to have a separate pending intent for the text view and the check box
val backgroundIntent = HomeWidgetBackgroundIntent.getBroadcast(context,
Uri.parse("myAppWidget://todo_checked/${todo["id"].toString()}"))
setOnCheckedChangeResponse(
R.id.each_todo_container_checkbox,
RemoteViews.RemoteResponse.fromPendingIntent(backgroundIntent)
)
//this pending intent doesn't get triggered
val fillInIntent = Intent().apply {
Bundle().also { extras ->
extras.putInt(EXTRA_ITEM, todo["id"].toString().toInt())
putExtras(extras)
}
}
setOnClickFillInIntent(R.id.each_todo_container_text, fillInIntent)
}
todosRemoteView.addItem(todo["id"].toString().toInt().toLong(), view)
}
}
setRemoteAdapter(
R.id.todos_list,
todosRemoteView
.build()
)
val editTodoIntent = HomeWidgetLaunchIntent.getActivity(
context,
MainActivity::class.java,
Uri.parse("http://edit_todo/$timeType"))
setPendingIntentTemplate(R.id.todos_list, editTodoIntent)
//how to set two different pending intent templates here for the text view and checkbox?
}
appWidgetManager.updateAppWidget(widgetId, views)
}
}
override fun onReceive(context: Context?, intent: Intent?) {
val viewIndex: Int = intent!!.getIntExtra(EXTRA_ITEM, 0)
Log.d("debugging", "an item is clicked $viewIndex")
//i can make the pending intent template of the list view trigger this onReceive function and I can use the data inside intent(set by fillInIntent) to find out which element of the two was clicked
//but how can I trigger the pending intent here?
super.onReceive(context, intent)
}
}