将数据从小部件传递到应用程序
Posted
技术标签:
【中文标题】将数据从小部件传递到应用程序【英文标题】:Passing data from widget to app 【发布时间】:2012-07-07 18:52:03 【问题描述】:我正在为我的应用程序开发一个小部件,我想将特定数据从小部件传递到应用程序。用户可以添加多个版本的小部件,我需要检测它来自哪个小部件,以便我可以在应用中显示特定信息。
到目前为止我所做的工作,但前提是我完全退出我的应用程序(反复按下后退按钮),否则它似乎没有检测到正在传递的数据。
这是我必须的代码:
public class WidgetProvider extends AppWidgetProvider
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
final int N = appWidgetIds.length;
for (int i=0; i<N; i++)
UpdateWidget(context, appWidgetManager, appWidgetIds[i]);
public static void UpdateWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId)
Intent intent = new Intent(context, Main.class);
final Bundle bun = new Bundle();
bun.putInt("widgetId", appWidgetId);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtras(bun);
PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
views.setOnClickPendingIntent(R.id.widgetText, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
更新
感谢 Tal Kanel。我的应用程序中有一个ActionBar
,并遵循 Google 的指导方针,我在 onOptionsItemSelected
中有此代码:
if (item.getItemId() == android.R.id.home)
final Intent intent = new Intent(activity, Main.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
return true;
如果我单击ActionBar
中的“返回”按钮,然后最小化我的应用程序并单击小部件,此代码始终为空:
if (getIntent().getExtras() != null)
更新 2
实际上,只是回到我的应用程序中的主要活动会导致getExtras()
为空。我的应用小部件中有此代码,它不会向应用传递任何额外内容:
PendingIntent piMain = PendingIntent.getActivity(context, appWidgetId, new Intent(context, Main.class), PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.widgetTitle, piMain);
如果我在我的小部件中单击该部分,然后返回并单击我的小部件中应该传递额外内容的部分,getExtras()
始终为空。
【问题讨论】:
【参考方案1】:首先 - 当您按下返回直到返回主屏幕时,您的应用程序并没有真正关闭。只是在此阶段不存在您的应用程序中的任何活动。 我认为知道这一点非常重要,以防万一你没有......
关于您的问题: 您正在尝试使用它定义的 FLAG_ACTIVITY_CLEAR_TOP 从小部件启动活动:
如果设置了,并且正在启动的 Activity 已经在当前任务中运行,那么不会启动该 Activity 的新实例,而是关闭它之上的所有其他 Activity,并且此 Intent 将被传递到(现在在顶部)作为新 Intent 的旧活动。
这意味着如果您的 Main 活动已经在前台运行,那么当您从小部件启动活动时 - 此 Main 活动之上的所有其他活动将从堆栈中删除,并且 Main 将恢复并进入 Activity.onNewIntent(intent) 回调。
这就是您看不到数据的原因 - 因为活动不会以新意图重新启动,而只会以您发送的新意图进入 onNewIntent(intent)。
我敢肯定,如果您在 onNewIntent(intent) 方法中设置一个断点 - 您会看到您发送的意图已传递到那里,以及所有额外的数据。
您的代码的另一个问题:检查 Intent.putExtras(boundle) 方法的定义:
向意图添加一组扩展数据。键必须包含包前缀,例如应用程序 com.android.contacts 将使用“com.android.contacts.ShowAll”之类的名称。
您似乎没有按照规则调用您的密钥前缀。这就是它为空的原因。
希望对你有所帮助。
【讨论】:
感谢您的回复。这是我创建的第一个应用小部件,所以我还在搞清楚一切。你是对的,onNewItent
被击中了,所以我添加了我的代码来检查那里的额外内容,它似乎可以工作,但只有在我第二次点击小部件之后。
@KrisB:这正是假设发生的事情 - 如果活动不在堆栈中(第一次),那么以“常规方式”接收的数据 - 通过 onCreate() 和 getIntent( ),而在其他时候(当 Activity 已经在堆栈中时),您将收到 Intent throw the onNewIntent()
你是对的,这正是它的工作方式。我检查了onCreate
和onNewIntent
中的额外内容,问题似乎是当我使用if (getIntent().getExtras() != null)
时,有时getExtras()
是null
。从小部件单击时,我希望 getExtras()
永远不会是 null
。
查看我添加到 OP 的代码。我的小部件的一部分没有传递任何额外内容,而主要部分则传递。如果我单击未传递任何附加信息的部分,然后返回小部件并单击传递任何附加信息的部分,getExtras()
始终为空。
@IgorG.:如果您使用 FLAG_ACTIVITY_SINGLE_TOP 触发意图,并且您之前通过按主页按钮导航离开它(而不是后退按钮)来关闭活动,那么系统尚未销毁您的活动以保留内存,然后它将返回到 onNewIntent() 回调并返回到前台。甚至来自小部件以上是关于将数据从小部件传递到应用程序的主要内容,如果未能解决你的问题,请参考以下文章
将 PendingIntent 中小部件的附加信息传递给 Activity