AppWidget with collection - 在点击widget时无法运行Config Activity

时间:2015-04-24 10:30:21

标签: android android-widget android-pendingintent android-appwidget

我遇到了在Stackoverflow上非常流行的问题,并且有很多方法如何修复它。但不幸的是,他们都不适合我。

我使用集合(StackView)创建了 appWidget ,为配置添加了ConfigActivity,并为分配的时间间隔添加了永久更新机制。小部件以适当的方式显示,更新工作正常,但是当我想运行Config Activity并单击小部件时 - 没有任何反应!

也许,我错过了一些重要的细节,希望你能建议我。以下是一些代码段:

清单

<uses-sdk android:minSdkVersion="11"
    android:targetSdkVersion="22"/>

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<application
    android:name=".FinApp"
    android:allowBackup="true"
    android:icon="@mipmap/ic_fin"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

    <receiver android:name=".widget.WidgetProvider" >
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>

        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/fin_app_widget_info" />
    </receiver>

    <activity android:name=".ConfigActivity"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
        </intent-filter>
    </activity>

    <service
        android:name=".widget.WidgetService"
        android:permission="android.permission.BIND_REMOTEVIEWS"/>

</application>

的AppWidgetProvider

public class WidgetProvider extends AppWidgetProvider {
private static final String TAG = WidgetProvider.class.getSimpleName();

@Override
public void onReceive(Context context, Intent intent) {
    Log.i(TAG, "onReceive");
    super.onReceive(context, intent);
}

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    Log.w(TAG, "onUpdate: appWidgetIds - " + Arrays.toString(appWidgetIds));

    for (int id : appWidgetIds) {
        updateAppWidgetInstance(context, appWidgetManager, id);
    }
}

public static void updateWidgetsOnDataSetChanged (Context context) {
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    int[] appWidgetIds = appWidgetManager.getAppWidgetIds(
            new ComponentName(context.getPackageName(), WidgetProvider.class.getName()));

    appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widget_list);
}

private static void addWidgetListener(Context context, int appWidgetId, RemoteViews widget) {
    Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));

    PendingIntent runConfigActivity = PendingIntent.getActivity(context, 0, intent,
            PendingIntent.FLAG_UPDATE_CURRENT);

    widget.setOnClickPendingIntent(R.id.widget_container, runConfigActivity);
}

private static void setupWidgetService(Context context, int appWidgetId, RemoteViews widget) {
    Intent adapterIntent = new Intent(context, WidgetService.class);
    adapterIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    adapterIntent.setData(Uri.fromParts("content", String.valueOf(appWidgetId), null));

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        widget.setRemoteAdapter(R.id.widget_list, adapterIntent);
    } else {
        //noinspection deprecation
        widget.setRemoteAdapter(appWidgetId, R.id.widget_list, adapterIntent);
    }
}

private static void updateAppWidgetInstance(Context context, AppWidgetManager appWidgetManager,
                                           int appWidgetId) {
    Log.e(TAG, "updateAppWidgetInstance");

    RemoteViews widget = new RemoteViews(context.getPackageName(), R.layout.widget_collection_layout);
    setupWidgetService(context, appWidgetId, widget);
    addWidgetListener(context, appWidgetId, widget);

    appWidgetManager.updateAppWidget(appWidgetId, widget);
}

}

widget_collection_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/widget_container"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <StackView
        android:id="@+id/widget_list"
        android:loopViews="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

据我所知,重点在于方法 addWidgetListener

    private static void addWidgetListener(Context context, int appWidgetId, RemoteViews widget) {

    Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));

    PendingIntent runConfigActivity = PendingIntent.getActivity(context, 0, intent,
            PendingIntent.FLAG_UPDATE_CURRENT);

    widget.setOnClickPendingIntent(R.id.widget_container, runConfigActivity);
}

但我不知道出了什么问题......

1 个答案:

答案 0 :(得分:0)

经过一番调查后我得出结论,如果我在appWidget中使用集合并想要打开整个小部件容器上的Config Activity,那么最好的做法就是使用 setPendingIntentTemplate 方法,即使你没有&# 39; t想要处理项目点击而是整个列表(列表容器)。

    private static void addWidgetListener(Context context, int appWidgetId, RemoteViews widget) {
    Intent intent = new Intent(context, ConfigActivity.class);
    intent.setAction(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);

    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);

    intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));

    PendingIntent runConfigActivity = PendingIntent.getActivity(context, 0, intent,
            PendingIntent.FLAG_UPDATE_CURRENT);

    widget.setPendingIntentTemplate(R.id.widget_list, runConfigActivity);
}

并在方法getViewAt(int position)中的 WidgetFactory 中添加2行

    Intent intent = new Intent();
    views.setOnClickFillInIntent(R.id.widget_item_container, intent);