Question

I'm making a homescreen widget which has to do different things depending on the widget part the user has clicked in. To achieve this I make the call setOnClickPendingIntent 5 times but only the last call works. How can I set 5 different intents for click events in my widget?

package bembibre.coolstar.windowsmobilewidget;

import java.util.Calendar;

import bembibre.coolstar.windowsmobilewidget.backend.CalendarProvider;
import bembibre.coolstar.windowsmobilewidget.backend.CallsProvider;
import bembibre.coolstar.windowsmobilewidget.backend.DateProvider;
import bembibre.coolstar.windowsmobilewidget.backend.MissedCallsContentObserver;
import bembibre.coolstar.windowsmobilewidget.backend.Provider;
import bembibre.coolstar.windowsmobilewidget.backend.SmssContentObserver;
import bembibre.coolstar.windowsmobilewidget.backend.SmssProvider;
import bembibre.coolstar.windowsmobilewidget.backend.WhatsappProvider;
import bembibre.coolstar.windowsmobilewidget.backend.alarms.AlarmSetter;

import android.app.IntentService;
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.net.Uri;
import android.os.Bundle;
import android.provider.CallLog.Calls;
import android.widget.RemoteViews;
import android.widget.Toast;

public class ExtendedAppWidgetProvider extends AppWidgetProvider{
private MissedCallsContentObserver mcco;
private SmssContentObserver smsco;
private static final String WIDGET_CLICK = "element";

/**
 * Llama a la clase AlarmManager de Android para indicarle que esta aplicación
 * debe ser ejecutada automáticamente en la próxima medianoche. Como este
 * widget contiene la fecha (día, mes y año), cada vez que sea medianoche
 * debe ser ejecutado para que se actualice y cambie de día.
 */
public static void setDayChangeAlarm(Context context){
    AlarmSetter alarmSetter = new AlarmSetter(context);
    Calendar when = Calendar.getInstance();
    when.roll(Calendar.DAY_OF_MONTH, 1);
    when.set(Calendar.HOUR, 0);
    when.set(Calendar.HOUR_OF_DAY, 0);
    when.set(Calendar.MINUTE, 0);
    when.set(Calendar.SECOND, 0);
    when.set(Calendar.MILLISECOND, 0);
    alarmSetter.setAlarm(when);
}

@Override
public void onEnabled(Context context){
    super.onEnabled(context);
    setDayChangeAlarm(context);

    WhatsappProvider provider = new WhatsappProvider(context);
    provider.mDbHelper.open();
    provider.resetNoMessagesField();
    provider.mDbHelper.close();

    this.mcco = new MissedCallsContentObserver(context);
    context.getContentResolver().registerContentObserver(Calls.CONTENT_URI, true, this.mcco);

    this.smsco = new SmssContentObserver(context);
    context.getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, this.smsco);

    Toast.makeText(context, "Widget iniciado", Toast.LENGTH_SHORT).show();
}

@Override
public void onDisabled(Context context){
    if(this.mcco != null){
        context.getContentResolver().unregisterContentObserver(this.mcco);
    }
    if(this.smsco != null){
        context.getContentResolver().unregisterContentObserver(this.smsco);
    }
}

@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction() == null) {
        new SmssProvider(context).setData();

        Bundle extras = intent.getExtras();
        if(extras != null){
            int element = extras.getInt(WIDGET_CLICK);
            switch(element){
                case R.id.widget_date:
                    Toast.makeText(context, "DATE", Toast.LENGTH_SHORT).show();
                    break;

                case R.id.widget_whatsapp:
                    Toast.makeText(context, "WHATSAPP", Toast.LENGTH_SHORT).show();
                    break;

                case R.id.widget_calendar:
                    Toast.makeText(context, "CALENDAR", Toast.LENGTH_SHORT).show();
                    break;

                case R.id.widget_calls:
                    Toast.makeText(context, "CALLS", Toast.LENGTH_SHORT).show();
                    break;

                case R.id.widget_messages:
                    Toast.makeText(context, "MESSAGES", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    } else {
        super.onReceive(context, intent);
    }
}

@Override
public void onUpdate(Context context, AppWidgetManager
appWidgetManager, int[] appWidgetIds) {
    context.startService(new Intent(context,
    ListItemClickService.class));

    setDayChangeAlarm(context);

    /*
     * Para evitar que se muestren eventos del calendario que
     * comienzan en una fecha ya pasada, los actualizamos cada vez
     * que pase un cierto periodo de tiempo y se llame a este
     * método, onUpdate.
     */
    new CalendarProvider(context).setData();

    /*
     * Para evitar que en la parte de mensajes SMS se muestren mensajes ya
     * leídos, la actualizamos periódicamente.
     */
    new SmssProvider(context).setData();
}

// TODO Hacer que no pueda haber más de una instancia de este IntentService
// ejecutándose a la vez.
public static class ListItemClickService extends IntentService {
    public ListItemClickService() {
        super("ExtendedAppWidgetProvider$ListItemClickService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        ComponentName me = new ComponentName(this, ExtendedAppWidgetProvider.class);
        AppWidgetManager mgr = AppWidgetManager.getInstance(this);
        mgr.updateAppWidget(me, buildUpdate(this));
    }

    private void setOnClickPendingIntent(RemoteViews updateViews, int element,
        Context context){

        Intent i = new Intent(this, ExtendedAppWidgetProvider.class);
        i.putExtra(WIDGET_CLICK, element);

        PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
        updateViews.setOnClickPendingIntent(element, pi);
    }

    private RemoteViews buildUpdate(Context context) {
        RemoteViews updateViews = new
        RemoteViews(context.getPackageName(), R.layout.widget_list);

        Provider dateProvider = new DateProvider(context);
        WhatsappProvider whatsappProvider = new WhatsappProvider(context);
        Provider calendarProvider = new CalendarProvider(context);
        Provider callsProvider = new CallsProvider(context);
        Provider smssProvider = new SmssProvider(context);

        updateViews.setTextViewText(R.id.date, dateProvider.getText());
        updateViews.setTextViewText(R.id.whatsapp, whatsappProvider.getSpannedText());
        updateViews.setTextViewText(R.id.calendar, calendarProvider.getText());
        updateViews.setTextViewText(R.id.calls, callsProvider.getText());
        updateViews.setTextViewText(R.id.messages, smssProvider.getText());

        this.setOnClickPendingIntent(updateViews, R.id.widget_date, context);
        this.setOnClickPendingIntent(updateViews, R.id.widget_whatsapp, context);
        this.setOnClickPendingIntent(updateViews, R.id.widget_calendar, context);
        this.setOnClickPendingIntent(updateViews, R.id.widget_calls, context);
        this.setOnClickPendingIntent(updateViews, R.id.widget_messages, context);

        return updateViews;
    }
}
}
Was it helpful?

Solution

How can I set 5 different intents for click events in my widget?

The simplest solution is to provide different values to the second parameter of your getBroadcast() call, so that you have five different PendingIntents. getBroadcast() (and getActivity() and getService()) only create a new PendingIntent if there isn't already one, and in your case, your first getBroadcast() call creates it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top