I'm developing an Android Widget for an app, and the problem is I can't set onClickPendingIntent()
on a button in a RemoteViewsFactory
.
I explain: I created an AppWidgetProvider
, which calls an extending of RemoteViewsService
which calls an extending of RemoteViewsFactory
for complete a ListView
in my widget.
The RemoteViewsFactory
have to return all items for update or create them and display on the widget. But for each items of the list view, I have 2 types of buttons:
- A button which opens gmaps/dialer/sms (It works).
- A button which calls an activity in my app and send it in a parameter the ID of the item.
And the problem is the second button, my solution doesn't work.
Here is the problem:
And so, this is the code which doesn't work:
row.setOnClickPendingIntent(R.id.taskButton, onClickPendingIntent);
// Creating an onclick event for the done button
Intent doneIntent = new Intent(mContext, WidgetProvider.class);
doneIntent.putExtra("DONE_TASK", "DOOOOM");
PendingIntent onDoneIntent = PendingIntent.getActivity(mContext, 0, doneIntent, 0);
row.setOnClickPendingIntent(R.id.doneButton, onDoneIntent);
Here is the complete WidgetFactory
class:
import java.util.Collections;
import java.util.Comparator;
import java.util.GregorianCalendar;
import java.util.Vector;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;
public class WidgetFactory implements RemoteViewsService.RemoteViewsFactory {
private Vector<EventInfo> mAllEvents;
private Context mContext;
public WidgetFactory(Context ctxt, Intent intent) {
// Creating member vars
mContext = ctxt;
updateAllEventsVector();
}
private void updateAllEventsVector() {
SharedInstances sharedInstances = SharedInstances.get();
mAllEvents = new Vector<EventInfo>();
if (sharedInstances != null) {
TaskRequestManager taskManager = sharedInstances
.getTaskRequestManager();
CalendarRequestManager calManager = sharedInstances
.getCalendarRequestManager();
Vector<TaskEvent> tasks = null;
Vector<CalendarEvent> events = null;
if (taskManager != null)
tasks = taskManager.readTasksToday(mContext);
if (calManager != null)
events = calManager.readCalendarEventsToday(mContext);
if (!tasks.isEmpty())
mAllEvents.addAll(tasks);
if (!events.isEmpty())
mAllEvents.addAll(events);
mAllEvents = sortByDate(mAllEvents);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public Vector<EventInfo> sortByDate(Vector<EventInfo> events)
{
Vector<EventInfo> sortedEvents = new Vector<EventInfo>();
for(EventInfo event : events)
{
if ((event.getStartTime()+event.getEventDuration()) > GregorianCalendar.getInstance().getTimeInMillis())
sortedEvents.add(event);
}
Collections.sort(events, new Comparator() {
public int compare(Object arg0, Object arg1)
{
EventInfo event0 = (EventInfo)arg0;
EventInfo event1 = (EventInfo)arg1;
if (event0.getStartTime()+event0.getEventDuration() > event1.getStartTime()+event1.getEventDuration())
return 1;
else if (event0.getStartTime()+event0.getEventDuration() == event1.getStartTime()+event1.getEventDuration())
return 0;
else if (event0.getStartTime()+event0.getEventDuration() < event1.getStartTime()+event1.getEventDuration())
return -1;
return 0;
}
});
return sortedEvents;
}
@Override
public int getCount() {
return mAllEvents.size();
}
@Override
public long getItemId(int arg0) {
return (arg0);
}
@Override
public RemoteViews getLoadingView() {
return null;
}
@Override
public RemoteViews getViewAt(int position) {
// Getting item view
RemoteViews row = new RemoteViews(mContext.getPackageName(),
R.layout.done_task_item);
EventInfo eventInfo = mAllEvents.get(position);
row.setInt(R.id.item_event, "setBackgroundColor", Color.argb(60, Color.red(eventInfo.getColor()), Color.green(eventInfo.getColor()), Color.blue(eventInfo.getColor())));
// Converts startTime and endTime in string
String startTime = TimeCursor.getAdaptativeTime(eventInfo.getStartTime());
String endTime = TimeCursor.getAdaptativeTime((eventInfo
.getEventDuration() + eventInfo.getStartTime()));
//Get title
String title = eventInfo.getTitle();
// Setting data in the view
row.setTextViewText(R.id.titleTask, title);
row.setTextViewText(R.id.periodTask, startTime + " to " + endTime);
//Check type of event
if (eventInfo.isTask()) {
//endDate > GregorianCalendar.getInstance().getTimeInMillis() ) {
//Check if action exists
if (eventInfo.getAction() != null) {
//Get the action title
String action = eventInfo.getAction()
.getTitleText();
//Create a onClickPendingIntent for taskButton
PendingIntent onClickPendingIntent = null;
//Add related button
if (action.equals("Call"))
{
//Set call icon to taskButton
row.setImageViewResource(R.id.taskButton, R.drawable.ic_call_white );
//Get numbers from the contact
Vector<TelOrEmailItem> tel = eventInfo.getContact().getAllPhoneNumbers(mContext.getResources() , mContext, eventInfo.getAction());
// Creating an onclick event for call somebody
Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"+tel.get(0).getMainText()));
onClickPendingIntent = PendingIntent.getActivity(
mContext, 0, callIntent, 0);
}
else if (action.equals("SMS"))
{
//Set sms icon to taskButton
row.setImageViewResource(R.id.taskButton, R.drawable.ic_sms_white);
//Get numbers from the contact
Vector<TelOrEmailItem> tel = eventInfo.getContact().getAllPhoneNumbers(mContext.getResources() , mContext, eventInfo.getAction());
// Creating an onclick event for call somebody
Intent smsIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:"+tel.get(0).getMainText()));
onClickPendingIntent = PendingIntent.getActivity(
mContext, 0, smsIntent, 0);
}
/*else if (action.equals("Chat with"))
row.setImageViewResource(R.id.taskButton, R.drawable.ic_chat_white);*/
else if (action.equals("eMail") || action.equals("Mail") || action.equals("Write to"))
{
//Set email icon to taskButton
row.setImageViewResource(R.id.taskButton, R.drawable.ic_email_white);
//Get numbers from the contact
Vector<TelOrEmailItem> tel = eventInfo.getContact().getAllEMails(mContext, eventInfo.getAction());
//Creating an onclick event for email somebody
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("plain/text");
emailIntent.putExtra(Intent.EXTRA_EMAIL,
new String[]{tel.get(0).getMainText()});
onClickPendingIntent = PendingIntent.getActivity(
mContext, 0, emailIntent, 0);
}
/*else if (action.equals("Skype"))
row.setImageViewResource(R.id.taskButton, R.drawable.ic_skype_white);*/
//Assign the intent to the taskButton
row.setOnClickPendingIntent(R.id.taskButton, onClickPendingIntent);
// Creating an onclick event for the done button
Intent doneIntent = new Intent(mContext, WidgetProvider.class);
doneIntent.putExtra("DONE_TASK", "DOOOOM");
PendingIntent onDoneIntent = PendingIntent.getActivity(mContext, 0, doneIntent, 0);
row.setOnClickPendingIntent(R.id.doneButton, onDoneIntent);
}
else
row.setViewVisibility(R.id.taskButton, View.GONE); //hidde the taskButton
return row;
}
//Check if it's an event
else if(eventInfo.isEvent()) {
//hidde task button (Done)
row.setViewVisibility(R.id.doneButton, View.GONE);
CalendarEvent ev = eventInfo.getCalendarEvent();
String location = ev.getEventLocation();
if (location != null && !location.isEmpty())
{
//Set the locate icon on the taskButton
row.setImageViewResource(R.id.taskButton, R.drawable.ic_locate_white);
//Define the place to open the map
Intent mapIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("geo:0,0?q="+location));
PendingIntent onMapIntent = PendingIntent.getActivity(
mContext, 0, mapIntent, 0);
row.setOnClickPendingIntent(R.id.taskButton, onMapIntent);
}
else
row.setViewVisibility(R.id.taskButton, View.GONE);
return row;
}
return null;
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public boolean hasStableIds() {
return (true);
}
@Override
public void onCreate() {
}
@Override
public void onDataSetChanged() {
// On data changes, update mTasks
updateAllEventsVector();
}
@Override
public void onDestroy() {
mAllEvents = null;
}
}
And thank you :)
Edit: Yeaye ! Problem solved or not...
Method onClickPendingIntent()
is working now, here is the code :
// Creating an onclick event for the done button
Intent onClickDone = new Intent(mContext, DoneTaskActivity.class);
onClickDone.putExtra("TASK_ID", eventInfo.getTaskEvent().getTaskId());
PendingIntent onClickPendingDone = PendingIntent.getActivity(mContext, 0, onClickDone, 0);
row.setOnClickPendingIntent(R.id.doneButton, onClickPendingDone);
But another problem exists: The DoneTaskActivity
doesn't receive the extra declared as TASK_ID
. In the onCreate()
method of the DoneTaskActivity
, the Bundle
var in parameter stays to null
.
Help :(