I am making one task widget application.
This is a simple widget application which can be used to add new tasks by clicking on "+New Task". So ideally what I have done is, I've added a widget first, then when we click on "+New Task" a new activity opens up from where we can type in a new task and it should get updated in the ListView inside the home screen widget.
Problem: Now whenever I add a new task, the ListView does not get updated. The data gets inside the database a new is created as well. My onUpdate(...) method gets called as well. There is a WidgetService.java which is a RemoteViewService that is being used to call the RemoteViewFactory but WidgetService.java gets called only when we create the widget, never after that.
WidgetService.java never gets called again.
I have the following setup
MyWidgetProvider.java
AppWidgetProvider class for updating the widget and filling its remote views.
public class MyWidgetProvider extends AppWidgetProvider {
public static int randomNumber=132;
static RemoteViews remoteViews = null;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
updateList(context,appWidgetManager,appWidgetIds);
}
public static void updateList(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
final int N = appWidgetIds.length;
Log.d("MyWidgetProvider", "length="+appWidgetIds.length+"");
for (int i = 0; i<N; ++i) {
Log.d("MyWidgetProvider", "value"+ i + "="+appWidgetIds[i]);
// Calling updateWidgetListView(context, appWidgetIds[i]); to load the listview with data
remoteViews = updateWidgetListView(context, appWidgetIds[i]);
// Updating the Widget with the new data filled remoteviews
appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds[i], R.id.lv_tasks);
}
}
private static RemoteViews updateWidgetListView(Context context, int appWidgetId) {
Intent svcIntent = null;
remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget_demo);
//RemoteViews Service needed to provide adapter for ListView
svcIntent = new Intent(context, WidgetService.class);
//passing app widget id to that RemoteViews Service
svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
//setting a unique Uri to the intent
//binding the data from the WidgetService to the svcIntent
svcIntent.setData(Uri.parse(svcIntent.toUri(Intent.URI_INTENT_SCHEME)));
//setting adapter to listview of the widget
remoteViews.setRemoteAdapter(R.id.lv_tasks, svcIntent);
//setting click listner on the "New Task" (TextView) of the widget
remoteViews.setOnClickPendingIntent(R.id.tv_add_task, buildButtonPendingIntent(context));
return remoteViews;
}
// Just to create PendingIntent, this will be broadcasted everytime textview containing "New Task" is clicked and OnReceive method of MyWidgetIntentReceiver.java will run
public static PendingIntent buildButtonPendingIntent(Context context) {
Intent intent = new Intent();
intent.putExtra("TASK_DONE_VALUE_VALID", false);
intent.setAction("com.ommzi.intent.action.CLEARTASK");
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
// This method is defined here so that we can update the remoteviews from other classes as well, like we'll do it in MyWidgetIntentReceiver.java
public static void pushWidgetUpdate(Context context, RemoteViews remoteViews) {
ComponentName myWidget = new ComponentName(context, MyWidgetProvider.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(myWidget, remoteViews);
}
}
WidgetService.java
A RemoteViewsService class for creating a RemoteViewsFactory.
public class WidgetService extends RemoteViewsService {
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,AppWidgetManager.INVALID_APPWIDGET_ID);
return (new ListProvider(this.getApplicationContext(), intent));
}
}
ListProvider.java
A RemoteViewsFactory class for filling the ListView inside the widget.
public class ListProvider implements RemoteViewsFactory {
private List<TemplateTaskData> tasks;
private Context context = null;
private int appWidgetId;
int increment=0;
public ListProvider(Context context, Intent intent) {
this.context = context;
appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,AppWidgetManager.INVALID_APPWIDGET_ID);
//appWidgetId = Integer.valueOf(intent.getData().getSchemeSpecificPart())- MyWidgetProvider.randomNumber;
populateListItem();
}
private void populateListItem() {
tasks = new ArrayList<TemplateTaskData>();
com.ommzi.database.sqliteDataBase letStartDB = new com.ommzi.database.sqliteDataBase(context);
letStartDB.open();
tasks=letStartDB.getData();
letStartDB.close();
}
public int getCount() {
return tasks.size();
}
public long getItemId(int position) {
return position;
}
public RemoteViews getViewAt(int position) {
// We are only showing the text view field here as there is limitation on using Checkbox within the widget
// We prefer to on an activity for the user to make comprehensive changes as changes inside the widget is always limited.
// To view the supported list of views for the widget you can visit http://developer.android.com/guide/topics/appwidgets/index.html
final RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.screen_wcitem);
TemplateTaskData taskDTO = tasks.get(position);
Log.d("My ListProvider", "1");
remoteView.setTextViewText(R.id.wc_add_task, taskDTO.getTaskName());
if(taskDTO.getTaskDone()){
remoteView.setImageViewResource(R.id.imageView1, R.drawable.checked);
}else{
remoteView.setImageViewResource(R.id.imageView1, R.drawable.unchecked);
}
Intent intent = new Intent();
intent.setAction("com.ommzi.intent.action.GETTASK");
intent.putExtra("TASK_DONE_VALUE_VALID", true);
intent.putExtra("ROWID", taskDTO.getRowId());
intent.putExtra("TASK_NAME", taskDTO.getTaskName());
intent.putExtra("TASK_DONE_VALUE", taskDTO.getTaskDone());
remoteView.setOnClickPendingIntent(R.id.imageView1, PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
Log.d("My ListProvider, Inside getView", "Value of Incrementor=" + increment +
"\n ROWID=" + taskDTO.getRowId() +
"\n TASK_NAME=" + taskDTO.getTaskName() +
"\n TASK_DONE_VALUE=" +taskDTO.getTaskDone() +
"\n Total Database Size=" + tasks.size());
return remoteView;
}
public RemoteViews getLoadingView() {
// TODO Auto-generated method stub
return null;
}
public int getViewTypeCount() {
// TODO Auto-generated method stub
return 1;
}
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
public void onCreate() {
// TODO Auto-generated method stub
}
public void onDataSetChanged() {
// TODO Auto-generated method stub
}
public void onDestroy() {
// TODO Auto-generated method stub
}
}
GetTaskActivity.java
This is another activity that is fired from a BroadcastReceiver(MyWidgetIntentReceiver.java). Purpose of this is to get a new task added to the list of task.
MyWidgetIntentReceiver.java
BroadcastReceiver fired using a pending intent that starts an activity GetTaskActivity.java.
Please help me out with this problem. I am seen all the posts here and on other websites no body is having any solution. But I am sure a solution exist to this.
Thanks for your help!