さて、私は AppWidget (もちろん AppWidgetProvider を使用)、configure Settings (ユーザーが 5 分から 2 時間の間で更新レートを選択)、およびウィジェットが更新される Service を持っています。
ホーム画面に AppWidget が 1 つしかない場合は、すべて正常に動作します。しかし、ホーム画面に 2 つ目の 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 の他の投稿の回答でコードを見ました。
PendingIntent newPending = PendingIntent.getService(context, (int) System.currentTimeMillis(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
それ以外の:
PendingIntent newPending = PendingIntent.getService(context, widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
問題は、このように作成したら、後でキャンセルするにはどうすればよいかということです。
ありがとう!