Android AppWidget SetFillinContent无法处理setData或componentName中的数据集?

Android AppWidget SetFillinContent无法处理setData或componentName中的数据集?,android,android-intent,android-appwidget,android-pendingintent,appwidgetprovider,Android,Android Intent,Android Appwidget,Android Pendingintent,Appwidgetprovider,我想从我的应用程序小部件启动不同的应用程序。这个小部件是一个项目列表,点击一个项目应该会打开一个像Google Plus这样的应用程序。按下列表中的某个项目时,不会发生任何事情。当我删除setData和setComponentName时,它会弹出一个对话框,询问要使用哪个应用程序。是否无法将数据和componentname与appWidget集合上的PendingEvent合并 我的AppWidgetProvider如下所示: public class StreamsWidgetProvider

我想从我的应用程序小部件启动不同的应用程序。这个小部件是一个项目列表,点击一个项目应该会打开一个像Google Plus这样的应用程序。按下列表中的某个项目时,不会发生任何事情。当我删除setData和setComponentName时,它会弹出一个对话框,询问要使用哪个应用程序。是否无法将数据和componentname与appWidget集合上的PendingEvent合并

我的AppWidgetProvider如下所示:

public class StreamsWidgetProvider extends AppWidgetProvider {

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {

    final int N = appWidgetIds.length;

        for (int i=0; i<N; i++) {
            int appWidgetId = appWidgetIds[i];

            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);

            ...

            //set service for list view
            Intent listIntent = new Intent(context, StreamsWidgetService.class);
            listIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
            listIntent.setData(Uri.parse(listIntent.toUri(Intent.URI_INTENT_SCHEME)));
            views.setRemoteAdapter(R.id.streamItemsList, listIntent);

            ...

            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
            views.setPendingIntentTemplate(R.id.streamItemsList, pendingIntent);
            appWidgetManager.updateAppWidget(appWidgetId, views);
        }

        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }
}
public class StreamsWidgetService extends RemoteViewsService {
    private static final String TAG = "StreamsWidgetService";

    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        return new StreamItemWidgetFactory(intent);
    }

    private class StreamItemWidgetFactory implements RemoteViewsService.RemoteViewsFactory {
        @Override
        public RemoteViews getViewAt(int position) {
            StreamItem item = mItems.get(position);

            RemoteViews rv = new RemoteViews(getPackageName(), R.layout.widget_item);
            ...

            Intent intent = new Intent();
            intent.setData(ContentUris.withAppendedId(StreamItems.CONTENT_URI, item.getId()));

            AccountType at = item.getAccountType();
            intent.setComponent(new ComponentName(at.getPackageName(), at.getViewStreamItemActivity()));
            rv.setOnClickFillInIntent(R.id.streamItemRowId, intent);
            Log.d(TAG, "FillIntent set for " + item.getId() + " at position " + position + " with data " + intent.getDataString() + " and component " + intent.getComponent().toString());

            return rv;
        }

        ...
    }
}
当使用正常活动而不使用fillIntent时,此操作有效:

final AccountType at = item.getAccountType();
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(ContentUris.withAppendedId(StreamItems.CONTENT_URI, item.getId()));
intent.setClassName(at.getPackageName(), at.getViewStreamItemActivity());
startActivity(intent);

我如何解决这个问题?我做错了什么?

我通过对自己的AppWidgetProvider使用广播意图解决了这个问题。我有我自己的行为,我在接收时检查。然后,我使用包名、类名和数据id的参数设置FillinContent。在onReceive方法中使用此参数,我可以创建一个与ListActivity中的意图完全相同的新意图

在职期间:

Intent intent = new Intent();
intent.putExtra(StreamsWidgetProvider.BROADCAST_PARAM_ITEM_ID, item.getId());
AccountType at = item.getAccountType();
intent.putExtra(StreamsWidgetProvider.BROADCAST_PARAM_CLASS_NAME, at.getViewStreamItemActivity());
intent.putExtra(StreamsWidgetProvider.BROADCAST_PARAM_PACKAGE_NAME, at.getPackageName());

rv.setOnClickFillInIntent(R.id.streamItemRowId, intent);
在AppWidgetProvider中:

public static final String ACTION_START_ACTIVITY = "startActivity";
public static final String BROADCAST_PARAM_ITEM_ID = "intentId";
public static final String BROADCAST_PARAM_PACKAGE_NAME = "intentPackage";
public static final String BROADCAST_PARAM_CLASS_NAME = "intentClassName";

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {

    final int N = appWidgetIds.length;

    for (int i=0; i<N; i++) {
        int appWidgetId = appWidgetIds[i];

        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);

        ...

        Intent intent = new Intent(context, StreamsWidgetProvider.class);
        intent.setAction(ACTION_START_ACTIVITY);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
        views.setPendingIntentTemplate(R.id.streamItemsList, pendingIntent);

        appWidgetManager.updateAppWidget(appWidgetId, views);
    }

    super.onUpdate(context, appWidgetManager, appWidgetIds);
}

@Override
public void onReceive(Context context, Intent intent) {
    if(ACTION_START_ACTIVITY.equals(intent.getAction())) {
        long itemId = intent.getLongExtra(BROADCAST_PARAM_ITEM_ID, 0);
        String packageName = intent.getStringExtra(BROADCAST_PARAM_PACKAGE_NAME);
        String className = intent.getStringExtra(BROADCAST_PARAM_CLASS_NAME);

        Intent i = new Intent(Intent.ACTION_VIEW);
        i.setData(ContentUris.withAppendedId(StreamItems.CONTENT_URI, itemId));
        i.setComponent(new ComponentName(packageName, className));
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        context.startActivity(i);
    }

    super.onReceive(context, intent);
}

我通过对自己的AppWidgetProvider使用广播意图解决了这个问题。我有我自己的行为,我在接收时检查。然后,我使用包名、类名和数据id的参数设置FillinContent。在onReceive方法中使用此参数,我可以创建一个与ListActivity中的意图完全相同的新意图

在职期间:

Intent intent = new Intent();
intent.putExtra(StreamsWidgetProvider.BROADCAST_PARAM_ITEM_ID, item.getId());
AccountType at = item.getAccountType();
intent.putExtra(StreamsWidgetProvider.BROADCAST_PARAM_CLASS_NAME, at.getViewStreamItemActivity());
intent.putExtra(StreamsWidgetProvider.BROADCAST_PARAM_PACKAGE_NAME, at.getPackageName());

rv.setOnClickFillInIntent(R.id.streamItemRowId, intent);
在AppWidgetProvider中:

public static final String ACTION_START_ACTIVITY = "startActivity";
public static final String BROADCAST_PARAM_ITEM_ID = "intentId";
public static final String BROADCAST_PARAM_PACKAGE_NAME = "intentPackage";
public static final String BROADCAST_PARAM_CLASS_NAME = "intentClassName";

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {

    final int N = appWidgetIds.length;

    for (int i=0; i<N; i++) {
        int appWidgetId = appWidgetIds[i];

        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);

        ...

        Intent intent = new Intent(context, StreamsWidgetProvider.class);
        intent.setAction(ACTION_START_ACTIVITY);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
        views.setPendingIntentTemplate(R.id.streamItemsList, pendingIntent);

        appWidgetManager.updateAppWidget(appWidgetId, views);
    }

    super.onUpdate(context, appWidgetManager, appWidgetIds);
}

@Override
public void onReceive(Context context, Intent intent) {
    if(ACTION_START_ACTIVITY.equals(intent.getAction())) {
        long itemId = intent.getLongExtra(BROADCAST_PARAM_ITEM_ID, 0);
        String packageName = intent.getStringExtra(BROADCAST_PARAM_PACKAGE_NAME);
        String className = intent.getStringExtra(BROADCAST_PARAM_CLASS_NAME);

        Intent i = new Intent(Intent.ACTION_VIEW);
        i.setData(ContentUris.withAppendedId(StreamItems.CONTENT_URI, itemId));
        i.setComponent(new ComponentName(packageName, className));
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        context.startActivity(i);
    }

    super.onReceive(context, intent);
}
除非您特别要求,否则Pending帐篷不允许填充组件

PendingIntent pendingIntent = PendingIntent.getActivity(context,
    0, intent, Intent.FILL_IN_COMPONENT);
请注意,这与其他填充标记的工作方式不同。

除非您特别要求,否则PendingEvent不允许填充组件

PendingIntent pendingIntent = PendingIntent.getActivity(context,
    0, intent, Intent.FILL_IN_COMPONENT);

请注意,这与其他填充标志的工作方式不同。

所有这些都不是必需的;请看下面我的答案。所有这些都不是必需的;请参阅下面我的答案。我将尝试此选项,并将您的答案设置为已接受的答案(如果有效):我使用的是来自的方法,但它看起来相当慢。所以我试着直接从点击开始活动,并用你的答案实现了它,但看起来没有更快。这是‘正常’吗?我能期待更好的吗?如果你的应用程序已从内存中删除,Daverix的答案将要求它重新加载到内存中,而这个答案将允许点击直接启动目标应用程序,而不必加载你的应用程序,这可能会快得多。然而,如果设备有足够的内存,这种差异就无关紧要了。影响响应时间的主要因素是启动器正在执行的操作和其他应用程序正在执行的操作,这两个操作您都无法控制。我将尝试此操作,并将您的答案设置为可接受的答案(如果有效):我使用的是来自的方法,但它看起来相当慢。所以我试着直接从点击开始活动,并用你的答案实现了它,但看起来没有更快。这是‘正常’吗?我能期待更好的吗?如果你的应用程序已从内存中删除,Daverix的答案将要求它重新加载到内存中,而这个答案将允许点击直接启动目标应用程序,而不必加载你的应用程序,这可能会快得多。然而,如果设备有足够的内存,这种差异就无关紧要了。影响响应时间的主要因素将是启动器正在做什么和其他应用程序正在做什么,这两个方面你都无法控制。