从小部件传递给活动的错误项目

时间:2013-10-16 00:07:29

标签: android android-widget

我有一个使用集合的小部件。我需要的是在选中小部件ListView的其中一行时,将小部件中的ID传递给我的应用中的活动。

出于某种原因,当我调试活动时,正在发送错误的id。我把它缩小到与位置有关的东西。如果我在调试时将位置传递给我的活动,那么这是错误的位置可能只是我对一个带有集合的小部件如何工作的误解,因为它是我的第一个。

小工具服务

public class WidgetService extends RemoteViewsService {
    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        return new StackRemoteViewsFactory(this.getApplicationContext(), intent);
    }
}

class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory  {

        private List<Integer> mIds = new ArrayList<Integer>();
        private Context mContext;
        private int mAppWidgetId;

        public StackRemoteViewsFactory(Context context, Intent intent) {
            mContext = context;
            mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
        }

        public void onCreate() {
        }

        public int getCount() {
            // TODO Auto-generated method stub
            return mIds.size();
        }

        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }

        public RemoteViews getLoadingView() {
            // TODO Auto-generated method stub
            return null;
        }

        public RemoteViews getViewAt(int position) {
            RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item);
            final Intent mi = new Intent(mContext, MyActivity.class);
            final Bundle bun = new Bundle();
            bun.putInt("id", mIds.get(position));
            mi.putExtras(bun);

            final PendingIntent piMain = PendingIntent.getActivity(mContext, mAppWidgetId, mi, PendingIntent.FLAG_UPDATE_CURRENT);

            rv.setOnClickPendingIntent(R.id.widget_text, piMain);
            rv.setTextViewText(R.id.widget_text, mIds.get(position));

            return rv;
        }

        public int getViewTypeCount() {
            // TODO Auto-generated method stub
            return 1;
        }

        public boolean hasStableIds() {
            // TODO Auto-generated method stub
            return true;
        }

        public void onDataSetChanged() {
            mIds = Utilities.GetIds();
        }

        public void onDestroy() {
            // TODO Auto-generated method stub

        }
}

我的活动

public class Activity extends SherlockFragmentActivity {

    @Override
    public void onCreate(final Bundle icicle)
    {    
        super.onCreate(icicle);

        setContentView(R.layout.browser_pager);

        if (getIntent().getExtras() != null)
        {
            final Bundle extras = getIntent().getExtras();

            int id = extras.getInt("id"); //this id is wrong
        }
    }
}

1 个答案:

答案 0 :(得分:3)

final PendingIntent piMain = PendingIntent.getActivity(mContext, mAppWidgetId, mi, PendingIntent.FLAG_UPDATE_CURRENT);

getActivity()处不要使用mAppWidgetId作为请求代码:窗口小部件ID对于窗口小部件的实例是常量。因此,该平台无法将新Intent识别为“new”,并且会始终提供相同的PendingIntent。引自docs

  

...为了检索PendingIntent,知道两个Intent何时被认为是相同的是很重要的。人们常犯的一个错误是使用Intents创建多个PendingIntent对象,这些对象只在其“额外”内容中有所不同,期望每次都获得不同的PendingIntent。这不会发生。用于匹配的Intent部分与Intent.filterEquals定义的部分相同。如果你使用两个与Intent.filterEquals相同的Intent对象,那么你将获得两个相同的PendingIntent。

     

有两种典型的方法可以解决这个问题。

     

如果您确实需要多个不同的PendingIntent对象同时处于活动状态(例如用作同时显示的两个通知),那么您需要确保关联它们的某些内容有所不同他们有不同的PendingIntents。这可能是Intent.filterEquals考虑的任何Intent属性,或者提供给getActivity(Context, int, Intent, int)getActivities(Context, int, Intent[], int)getBroadcast(Context, int, Intent, int)或{{3的不同的请求代码整数 }}

相反,请使用每行唯一的ID:position是一个很好的候选者。