尝试创建app小部件的多个实例并分别更新每个实例,但无法找到我们无法正常工作的原因。以下是从here收集并稍加修改的代码:
package com.example.widgetagain;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
public class MyWidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
for (int appWidSingle = 0; appWidSingle < appWidgetIds.length; appWidSingle++) {
// initializing widget layout
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.widget_main);
// register for button event
remoteViews.setOnClickPendingIntent(R.id.sync_button,
buildButtonPendingIntent(context, appWidSingle));
// updating view with initial data
remoteViews.setTextViewText(R.id.title, getTitle());
remoteViews.setTextViewText(R.id.desc, getDesc());
// request for widget update
pushWidgetUpdate(context, remoteViews, appWidSingle);
}
}
public static PendingIntent buildButtonPendingIntent(Context context, int appWidgetSingleId) {
++MyWidgetIntentReceiver.clickCount;
Intent clickIntent = new Intent(context, MyWidgetIntentReceiver.class);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetSingleId);
clickIntent.setAction("WidgetUtils.WIDGET_UPDATE_ACTION");
return PendingIntent.getBroadcast(context, appWidgetSingleId, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// initiate widget update request
/*Intent intent = new Intent();
intent.setAction("WidgetUtils.WIDGET_UPDATE_ACTION");
return PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);*/
}
private static CharSequence getDesc() {
return "Sync to see some of our funniest joke collections";
}
private static CharSequence getTitle() {
return "Funny Jokes";
}
public static void pushWidgetUpdate(Context context, RemoteViews remoteViews, int appWidgetSingleId) {
AppWidgetManager manager = AppWidgetManager.getInstance(context);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_main);
Intent clickIntent = new Intent(context, MyWidgetIntentReceiver.class);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetSingleId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, appWidgetSingleId, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.sync_button, pendingIntent);
manager.updateAppWidget(appWidgetSingleId, views);
}
}
package com.example.widgetagain;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.RemoteViews;
public class MyWidgetIntentReceiver extends BroadcastReceiver {
public static int clickCount = 0;
private String msg[] = null;
int widgetId;
@Override
public void onReceive(Context context, Intent intent) {
/* if (intent.getAction()==null) {
Bundle extras = intent.getExtras();
if(extras!=null) {
widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
// do something for the widget that has appWidgetId = widgetId
}
}
else {
//super.onReceive(context, intent);
}*/
if (intent.getAction().equals("WidgetUtils.WIDGET_UPDATE_ACTION")) {
Bundle extras = intent.getExtras();
if(extras!=null) {
widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
// do something for the widget that has appWidgetId = widgetId
}
updateWidgetPictureAndButtonListener(context, widgetId);
}
}
private void updateWidgetPictureAndButtonListener(Context context, int widgetId) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.widget_main);
// updating view
remoteViews.setTextViewText(R.id.title, getTitle());
remoteViews.setTextViewText(R.id.desc, getDesc(context));
// re-registering for click listener
remoteViews.setOnClickPendingIntent(R.id.sync_button,
MyWidgetProvider.buildButtonPendingIntent(context, widgetId));
MyWidgetProvider.pushWidgetUpdate(context.getApplicationContext(),remoteViews, widgetId);
}
private String getDesc(Context context) {
// some static jokes from xml
msg = context.getResources().getStringArray(R.array.string_array_name);
if (clickCount >= msg.length) {
clickCount = 0;
}
return msg[clickCount];
}
private String getTitle() {
return "Funny Jokes";
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.widgetagain"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name=".MyWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_info" />
</receiver>
<receiver
android:name=".MyWidgetIntentReceiver"
android:label="@string/app_name">
<intent-filter>
<action android:name="WidgetUtils.WIDGET_UPDATE_ACTION" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_info" />
</receiver>
</application>
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/widget_main"
android:minHeight="146dp"
android:minWidth="292dp"
android:previewImage="@drawable/ic_launcher"
android:updatePeriodMillis="1000000" >
</appwidget-provider>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5sp"
android:background="@drawable/ic_launcher"
android:orientation="vertical" >
<RelativeLayout
android:id="@+id/buttonContainer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<Button
android:id="@+id/sync_button"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerInParent="true"
android:background="@drawable/ic_launcher"
android:text="" />
</RelativeLayout>
<LinearLayout
android:id="@+id/contentContainer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@id/buttonContainer"
android:layout_alignParentTop="true"
android:orientation="vertical"
android:padding="8dp" >
<TextView
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:paddingBottom="5dp"
android:text=""
android:textColor="#fcfcfc"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/desc"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:maxLines="5"
android:text=""
android:textColor="#fcfcfc"
android:textSize="13sp"
android:textStyle="normal" />
</LinearLayout>
</RelativeLayout>
答案 0 :(得分:3)
根据您发布的内容,似乎是这样:
// request for widget update
pushWidgetUpdate(context, remoteViews, appWidSingle);
应该看起来像这样:
// request for widget update
pushWidgetUpdate(context, remoteViews, appWidgetIds[appWidSingle]);
同样地:
// register for button event
remoteViews.setOnClickPendingIntent(R.id.sync_button,
buildButtonPendingIntent(context, appWidSingle));
应该是:
// register for button event
remoteViews.setOnClickPendingIntent(R.id.sync_button,
buildButtonPendingIntent(context, appWidgetIds[appWidSingle]));
答案 1 :(得分:1)
除了j__m提到的错误之外,这部分代码也不正确:
public static void pushWidgetUpdate(Context context, RemoteViews remoteViews, int appWidgetSingleId) {
AppWidgetManager manager = AppWidgetManager.getInstance(context);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_main);
Intent clickIntent = new Intent(context, MyWidgetIntentReceiver.class);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetSingleId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, appWidgetSingleId, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.sync_button, pendingIntent);
manager.updateAppWidget(appWidgetSingleId, views);
}
即每次创建新的远程视图而不是在pushwidgetupdate方法中使用传递的remoteview。因此上面的代码改为:
public static void pushWidgetUpdate(Context context, RemoteViews remoteViews, int appWidgetSingleId) {
AppWidgetManager manager = AppWidgetManager.getInstance(context);
Intent clickIntent = new Intent(context, MyWidgetIntentReceiver.class);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetSingleId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, appWidgetSingleId, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.sync_button, pendingIntent);
manager.updateAppWidget(appWidgetSingleId, views);
}