1

好吧,我有一个 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);

问题是:一旦我像这样创建它,以后如何取消它?

谢谢!

4

0 回答 0