好吧,我有一个 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(Service类)的onStartCommand方法:
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);
问题是:一旦我像这样创建它,以后如何取消它?
谢谢!