好吧,我有一个AppWidget(当然还有AppWidgetProvider),一个配置设置(用户选择5分钟到2个小时之间的更新速率)和一个服务,其中小部件更新。
正在发生的事情是,如果主屏幕上只有一个AppWidget,一切正常。但是,如果我在主屏幕上放置第二个AppWidget,它们都会同时更新,使用相同的数据(并且它是随机数据)等等。
那么,我该怎么做才能纠正这个问题?
代码,他们在这里:
SettingsActivity,我在哪里开始闹钟:
(...)
Intent intent = new Intent(context, WidgetServiceSmall.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
widgetId);
Uri data = Uri.withAppendedPath(
Uri.parse(WidgetProviderSmall.URI_SCHEME + "://widget/id/service/"),
String.valueOf(widgetId));
intent.setData(data);
PendingIntent newPending = PendingIntent.getService(context,
widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarms.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime(), newTime * 1000,
newPending);
(...)
WidgetServiceSmall的onStartCommand方法(Service类):
public int onStartCommand(Intent intent, int flags, int startId) {
// Atualiza os dados...
Context context = this.getApplicationContext();
int widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
if (widgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
try {
DBAdapter db;
db = new DBAdapter(context);
db.open();
Quote q = db.getRandomQuote();
db.close();
// Guarda o ID da citação...
Editor configEditor = context.getSharedPreferences(
"QuoteWidgetSmall", 0).edit();
configEditor.putInt(String.format("QuoteId-%d", widgetId),
q.getId());
configEditor.commit();
System.out.println("Id: " + widgetId);
System.out.println("Quote Id: " + q.getId());
// Verifica o tamanho e trunca o texto da citação...
String textQuote = "\"" + q.getQuote() + "\"";
if (textQuote.length() > 110 + 10) {
textQuote = textQuote.substring(0, 110) + "...\" [...]";
}
// Cria o RemoteViews
RemoteViews rv = new RemoteViews(context.getPackageName(),
R.layout.widget_layout_small);
// Seta os campos...
// rv.setTextViewText(R.id.txtWdgQuote, "\"" + q.getQuote()
// +
// "\"");
rv.setTextViewText(R.id.txtWdgQuote, textQuote);
rv.setTextViewText(R.id.txtWdgAuthor, "— "
+ q.getAuthor().getName());
// Adiciona o listener do evento do botão Next...
Intent active = new Intent(context, WidgetProviderSmall.class);
active.setAction(StaticHelper.ACTION_WIDGET_REFRESH);
active.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
new int[] { widgetId });
Uri data = Uri.withAppendedPath(
Uri.parse(WidgetProviderSmall.URI_SCHEME
+ "://widget/id/"), String.valueOf(widgetId));
active.setData(data);
PendingIntent actionPendingIntent = PendingIntent.getBroadcast(
context, widgetId, active, 0);
rv.setOnClickPendingIntent(R.id.ibtNext, actionPendingIntent);
// Adiciona o listener do evento do botão Settings... active =
active = new Intent(context, SettingsActivity.class);
active.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
active.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Make the pending intent unique...
active.setData(data);
actionPendingIntent = PendingIntent.getActivity(context,
widgetId, active, PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.ibtSettings,
actionPendingIntent);
// Adiciona o listener do evento do clique no Widget...
active = new Intent(context, WidgetProviderSmall.class);
active.setAction(StaticHelper.ACTION_CLICK);
// onReceive precisa apenas do Id em um int, então passa assim.
active.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
active.setData(data);
actionPendingIntent = PendingIntent.getBroadcast(context,
widgetId, active, 0);
rv.setOnClickPendingIntent(R.id.laySmall, actionPendingIntent);
// Salva tudo
AppWidgetManager manager = AppWidgetManager
.getInstance(context);
ComponentName thiswidget = new ComponentName(context,
WidgetProviderSmall.class);
manager.updateAppWidget(thiswidget, rv);
} catch (SQLException e) {
Log.e(TAG, e.getMessage(), e);
}
} else {
}
return super.onStartCommand(intent, flags, startId);
}
警告停止的WidgetProviderSmall(AppWidgetProvider类)的onDeleted方法:
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
System.out.println("Ih! OnDelete!");
int n = appWidgetIds.length;
for (int i = 0; i < n; i++) {
int widgetId = appWidgetIds[i];
System.out.println("Deletando...");
Intent intent = new Intent(context, WidgetServiceSmall.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
widgetId);
Uri data = Uri.withAppendedPath(
Uri.parse(WidgetProviderSmall.URI_SCHEME
+ "://widget/id/service/"),
String.valueOf(widgetId));
intent.setData(data);
PendingIntent newPending = PendingIntent.getService(context, widgetId,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Para o alarme...
AlarmManager alarms = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
alarms.cancel(newPending);
// Remove o estado armazenado...
SharedPreferences config = context.getSharedPreferences(
"QuoteWidget", 0);
SharedPreferences.Editor edit = config.edit();
edit.remove(String.format("UpdateRate-%d", widgetId));
edit.commit();
System.out.println("Terminou o onDelete");
}
super.onDisabled(context);
}
停止服务的WidgetProviderSmall(AppWidgetProvider类)的onDisabled方法:
@Override
public void onDisabled(Context context) {
/*Intent i = new Intent(context, WidgetProviderSmall.class);
int[] ids = i.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);*/
Intent intent = new Intent(context, WidgetServiceSmall.class);
/*intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
new int[] { widgetId });
Uri data = Uri.withAppendedPath(
Uri.parse(WidgetProviderSmall.URI_SCHEME
+ "://widget/id/service/"), String.valueOf(ids[0]));
intent.setData(data);*/
context.stopService(intent);
super.onDisabled(context);
}
我在StackOverflow上的其他帖子的答案中看到了一个代码,用户表示要像这样创建Pen:
PendingIntent newPending = PendingIntent.getService(context, (int) System.currentTimeMillis(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
而不是:
PendingIntent newPending = PendingIntent.getService(context, widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
问题是:一旦我像这样创建它,我该如何在以后取消它?
谢谢!