I\'ve tried to create a widget that, on click calls a routine on Configuration activity, on update calls another routine on Configuration activity, update must be under 30 m
For Timing under 30 mins and multiple instances i've decided to use only one timer for all instances.
Below the code onCreate of Configuration Class:
private static long millis = 20000;
SharedPreferences read = context.getSharedPreferences(PREFS_NAME, 0);
String firstinstance = read.getString("FirstInstance", "KO");
if (firstinstance.equals("KO")) {
SharedPreferences.Editor write = context.getSharedPreferences(
PREFS_NAME, 0).edit();
write.putString("FirstInstance", "OK");
write.commit();
Intent intent = new Intent(ControlloWidget.MY_WIDGET_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
Configurazione.this, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), millis, pendingIntent);
ControlloWidget.SaveAlarmManager(alarmManager, pendingIntent);
}
revert that process onDisabled of WidgetClass:
@Override
public void onDisabled(Context context) {
// TODO Auto-generated method stub
//super.onDisabled(context);
SharedPreferences.Editor write = context.getSharedPreferences(PREFS_NAME, 0).edit();
write.putString("FirstInstance", "KO" );
write.commit();
myAlarmManager.cancel(myPendingIntent);
}
static void SaveAlarmManager(AlarmManager tAlarmManager, PendingIntent tPendingIntent){
myAlarmManager = tAlarmManager;
myPendingIntent = tPendingIntent;
}
Now, setting up button Action and My Own Update: Class declaration:
public static String ACTION_WIDGET_CLICKED = "your.packagename.ACTION_WIDGET_CLICKED";
public static String MY_WIDGET_UPDATE = "your.packagename.MY_WIDGET_UPDATE";
onReceive method:
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
super.onReceive(context, intent);
choice = false;
// ////Toast.makeText(context, intent.getAction(),
// ////Toast.LENGTH_LONG).show();
// choice=false;
Bundle extras = intent.getExtras();
if (MY_WIDGET_UPDATE.equals(intent.getAction())) {
choice = false;
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
ComponentName thisAppWidget = new ComponentName(
context.getPackageName(), ControlloWidget.class.getName());
int[] appWidgetIds = appWidgetManager
.getAppWidgetIds(thisAppWidget);
onUpdate(context, appWidgetManager, appWidgetIds);
// ////Toast.makeText(context, "AUTOUPDATE",
// ////Toast.LENGTH_LONG).show();
} else
if (ACTION_WIDGET_CLICKED.equals(intent.getAction())) {
// choice =true;
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
ComponentName thisAppWidget = new ComponentName(
context.getPackageName(), ControlloWidget.class.getName());
int[] appWidgetIds = appWidgetManager
.getAppWidgetIds(thisAppWidget);
int appWidgetId = intent.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
// ////////
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.widget);
remoteViews.setTextViewText(R.id.btnEsegui,
Configurazione.getName(context, "nome", appWidgetId));
// ACTION CODE HERE
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
Log.d("LOG_Esecuzione",
"Log Esecuzione, Widget n." + String.valueOf(appWidgetId));
}
}
Then onUpdate and updateAppWidget Method:
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
// super.onUpdate(context, appWidgetManager, appWidgetIds);
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,int appWidgetId){
//TestOnClick
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget);
Intent myIntent = new Intent(context, ControlloWidget.class);
myIntent.setAction(ACTION_WIDGET_CLICKED);
myIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,appWidgetId,
myIntent, 0);
remoteViews.setOnClickPendingIntent(R.id.btnEsegui, pendingIntent);
remoteViews.setTextViewText(R.id.btnEsegui,Configurazione.getName(context, "nome", appWidgetId));
//On Update Code, Requested Action when onUpdate is called (for all widget), it also refresh pending intent
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
Log.d("LOG_UPDATE", "Log Update, Widget n."+String.valueOf(appWidgetId));
}
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
For separate instances is necessary:
On intentcreation:(on updateAppWidget)
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget);
Intent myIntent = new Intent(context, ControlloWidget.class);
myIntent.setAction(ACTION_WIDGET_CLICKED);
//The line below is the appWidgetId Specification
myIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,appWidgetId,
myIntent, 0);
remoteViews.setOnClickPendingIntent(R.id.btnEsegui, pendingIntent);
On receiving broadcast: (on onReceive)
if (ACTION_WIDGET_CLICKED.equals(intent.getAction())){
//Commented are not used on that example
//AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
//ComponentName thisAppWidget = new ComponentName(context.getPackageName(), ControlloWidget.class.getName());
//int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
now we could call any routine everywhere passing appWidgetId and Context to function... Example:
Action.SomeAction(context,appWidgetId);
For UPDATE TIMER, is also possible (without using preferences):
Like the other intent
could use putExtra
then on broadcast:
retrieve the int on broadcast receive
int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
BUT now we don't call onUpdate
method but directly updateAppWidget
with that alternative solution every widget has his own time refresh (maybe configurable)
I've preferred to have only one timer process active at same time and get all the widget updated at first instance widget update time