what is the best strategy for the following scenario:
my app will periodically send and receive http requests to a server run PHP script. I tried a service fired by AlarmManager or clicking directly on its widget. Direct operations on the device are working fine (like random numbers, see http://www.vogella.com/tutorials/AndroidWidgets/article.html ) when it comes to the request, these should be done in async tasks. I tried to update the widget (remoteView) from the postexecute section of the async task, but it is not working.
Somebody could give me some hints or maybe snippets?
thank you in advance
Update:
widget provider class with async task:
public class MyWidgetProvider extends AppWidgetProvider {
private static final String ACTION_CLICK = "ACTION_CLICK";
long ddd;
String dddd;
RemoteViews remoteViews;
TextView tvUpdate;
private static final String LOG = "de.vogella.android.widget.example";
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Log.w(LOG, "onUpdate method called");
// Get all ids
ComponentName thisWidget = new ComponentName(context,
MyWidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
// Build the intent to call the service
Intent intent = new Intent(context.getApplicationContext(),
UpdateWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
// Update the widgets via the service
context.startService(intent);
}
}
the service class with async task making pings to website (only for test purpose, later requests will be done there) the aim is to show the ping in the widget:
public class UpdateWidgetService extends Service {
private static final String LOG = "de.vogella.android.widget.example";
long ddd;
String dddd;
RemoteViews remoteViews;
TextView tvUpdate;
@Override
public void onStart(Intent intent, int startId) {
Log.i(LOG, "Called");
// create some random data
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this
.getApplicationContext());
int[] allWidgetIds = intent
.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
ComponentName thisWidget = new ComponentName(getApplicationContext(),
MyWidgetProvider.class);
int[] allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);
Log.w(LOG, "From Intent" + String.valueOf(allWidgetIds.length));
Log.w(LOG, "Direct" + String.valueOf(allWidgetIds2.length));
for (int widgetId : allWidgetIds) {
// create some random data
int number = (new Random().nextInt(100));
remoteViews = new RemoteViews(this
.getApplicationContext().getPackageName(),
R.layout.widget_layout);
Log.w("WidgetExample", String.valueOf(number));
if (dddd!=null)Log.w("dddd -", dddd);
new LongOperation().execute("");
if (dddd!=null)Log.w("dddd +", dddd);
// Set the text
remoteViews.setTextViewText(R.id.update,
"Random: " + String.valueOf(number));
// Register an onClickListener
Intent clickIntent = new Intent(this.getApplicationContext(),
MyWidgetProvider.class);
clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
allWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(), 0, clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.add(Calendar.SECOND, 5);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), 5 * 1000, pendingIntent);
}
stopSelf();
super.onStart(intent, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private class LongOperation extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
ddd = MainActivity.isURLReachable();
Log.e("ddd", ddd + "");
dddd = ddd + " ms";
Log.e("dddd", dddd);
return null;
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Log.e("POST dddd", dddd);
remoteViews.setTextViewText(R.id.update, dddd);
}
}
}
problem is that widget is not reachable from the post execute async task.
UPDATE 2:
How can I get the WidgetIDs from the postexecute method?
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(UpdateWidgetService.this
.getApplicationContext());
int[] allWidgetIds = intent
.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
ComponentName thisWidget = new ComponentName(getApplicationContext(),
MyWidgetProvider.class);
int[] allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);
Log.w(LOG, "From Intent" + String.valueOf(allWidgetIds.length));
Log.w(LOG, "Direct" + String.valueOf(allWidgetIds2.length));
for (int widgetId : allWidgetIds) {
// create some random data
int number = (new Random().nextInt(100));
remoteViews = new RemoteViews(UpdateWidgetService.this
.getApplicationContext().getPackageName(),
R.layout.widget_layout);
Log.w("WidgetExample", String.valueOf(number));
if (dddd!=null)Log.w("dddd -", dddd);
new LongOperation().execute("");
if (dddd!=null)Log.w("dddd +", dddd);
// Set the text
remoteViews.setTextViewText(R.id.update,
"Random: " + dddd);
// Register an onClickListener
Intent clickIntent = new Intent(UpdateWidgetService.this.getApplicationContext(),
MyWidgetProvider.class);
clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
allWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(), 0, clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
It does not need to be.
onPostExecute()
can get an instance ofAppWidgetManager
viagetInstance()
and callupdateAppWidget()
on it.