首先说一下我的项目需求,Widget中实现一个gridView并且点击对应item跳转到相应的webActivity,但是发现build.gradle在 targetSdkVersion版本较高情况下会没有点击效果,话不多说上代码
RemoteViewsFactory类
override fun getViewAt(position: Int): RemoteViews {
//widget item click
val fillInIntent = Intent(mContext,PanasonicWidgetProvider::class.java)
fillInIntent.putExtra("position", position)
rv.setOnClickFillInIntent(R.id.device_widget_item, fillInIntent)
}
WidgetService类
你也可以看作是AppWidgetProvider类里面的onUpdate方法(我这边需要五分钟刷新一次所以用开服务取请求数据)
我看网上大多博主这一步骤都是用的空Intent模板,导致在版本相对高的情况下AppWidgetProvider那边会响应不到消息,所以重点就是在这个Intent中去显式的取指定AppWidgetProvider类传递消息,现在都2023年了,Android高版本适配可太难了,
简单来说:Intent模板需要显式执行
private fun addPendingIntentTemplate(ids: IntArray, remoteViews: RemoteViews) {
val gridIntent = Intent(applicationContext,
PanasonicWidgetProvider::class.java).apply {
action = COLLECTION_VIEW_ACTION
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, ids[0])
data = Uri.parse(toUri(Intent.URI_INTENT_SCHEME))
}
val pendingIntent = PendingIntent.getBroadcast(
applicationContext,
0,
gridIntent,
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_MUTABLE
)
// intent 型板の設置
remoteViews.setPendingIntentTemplate(
R.id.grid_widget,
pendingIntent
)
}
AppWidgetProvider类
然后就是我们的最后一步,在它的onReceive方法中去接收消息
我第一遍改完报了一个这样的错:android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
Context中有一个startActivity方法,Activity继承自Context,重载了startActivity方法。如果使用Activity的startActivity方法,不会有任何限制,而如果使用Context的startActivity方法的話,就需要开启一个新的的task,遇到这个异常,是因为使用了Context的startActivity方法(通常发生在你想在一个service或者广播接收器里面调用startActivity方法)。解决办法是,加一个flag。
简单来说:这一步的重点在于intent的addFlags,需要添加flag,否则会抛出异常闪退,别问我是怎么知道的。
override fun onReceive(context: Context?, intent: Intent?) {
super.onReceive(context, intent)
val action = intent?.action
if (action.equals(COLLECTION_VIEW_ACTION)) {
val position = intent?.getIntExtra("position",0)
if (position != null) {
val intent = Intent(context, HomeWebActivity::class.java)
intent.putExtras(bundle)
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P){
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
context?.startActivity(intent)
}
}
}
问题解决,本人表达能力较差,有哪块看不懂的可以提问,以上代码有过删减(因为项目逻辑复杂),就把重点放出来了
总结:intent模板需要显式执行,最后跳转时候需要添加一个flag