通过服务更新 Android 小部件,即执行 http 请求
Posted
技术标签:
【中文标题】通过服务更新 Android 小部件,即执行 http 请求【英文标题】:Android widget update via service, that is doing http requests 【发布时间】:2015-01-25 03:07:14 【问题描述】:以下场景的最佳策略是什么:
我的应用程序将定期向服务器运行 php 脚本发送和接收 http 请求。 我尝试了由 AlarmManager 触发的服务或直接单击其小部件。设备上的直接操作工作正常(如随机数,请参阅http://www.vogella.com/tutorials/androidWidgets/article.html) 当涉及到请求时,这些应该在异步任务中完成。我试图从异步任务的 postexecute 部分更新小部件(remoteView),但它不起作用。
谁能给我一些提示或者sn-ps?
提前谢谢你
更新:
具有异步任务的小部件提供程序类:
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);
具有异步任务的服务类对网站进行 ping 操作(仅用于测试目的,以后的请求将在那里完成) 目的是在小部件中显示 ping:
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);
问题是无法从执行后的异步任务访问小部件。
更新 2:
如何从 postexecute 方法中获取 WidgetID?
@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);
【问题讨论】:
“它不起作用”——请完整准确地解释您的症状是什么。 “不工作”不是对您的症状非常有用的描述。除此之外,如果您不给我们“不工作”的代码来查看您的“不工作”代码,我们将无法帮助您。最后,服务不应该使用AsyncTask
——也许你的服务应该是IntentService
。
谢谢你是对的,我提供了一些关于结构的细节。
【参考方案1】:
问题是无法从执行后的异步任务访问小部件。
不需要。 onPostExecute()
可以get an instance of AppWidgetManager
via getInstance()
并调用updateAppWidget()
就可以了。
【讨论】:
谢谢,但我怎样才能访问小部件 ID?看编辑? int[] allWidgetIds = intent .getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS); @user1616685:将它们放入您的AsyncTask
的数据成员中。
这是一个很好的答案,但我会尝试实现 intentservice 以使其正确完成。以上是关于通过服务更新 Android 小部件,即执行 http 请求的主要内容,如果未能解决你的问题,请参考以下文章