Android App Widget 中按钮单击无法启动服务
我在启动服务来更新我作为练习创建的 AppWidget 时遇到问题。我正在尝试从 DDMS 获取欺骗位置数据的纬度和经度以显示在小部件中。该小部件使用一项服务来更新 TextView,这可能有点过大,但我想遵循在完成更多工作的 AppWidget 中常见的模板(例如 Forecast 小部件或 Wiktionary 小部件)。
现在,我没有收到任何错误消息或奇怪的行为;按下按钮时什么也不会发生。我对可能出了什么问题感到有点困惑。有人能指出我正确的方向吗?
此外,如果我的位置逻辑有错误,我也希望得到相关建议。我看过几个博客、Google 示例和文档,但我对它的工作原理感到有点模糊。
这是小部件的当前状态:
public class Widget extends AppWidgetProvider
{
static final String TAG = "Widget";
/**
* {@inheritDoc}
*/
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds)
{
// Create an intent to launch the service
Intent serviceIntent = new Intent(context, UpdateService.class);
// PendingIntent is required for the onClickPendingIntent that actually
// starts the service from a button click
PendingIntent pendingServiceIntent =
PendingIntent.getService(context, 0, serviceIntent, 0);
// Get the layout for the App Widget and attach a click listener to the
// button
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);
views.setOnClickPendingIntent(R.id.address_button, pendingServiceIntent);
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
// To prevent any ANR timeouts, we perform the update in a service;
// really should have its own thread too
public static class UpdateService extends Service
{
static final String TAG = "UpdateService";
private LocationManager locationManager;
private Location currentLocation;
private double latitude;
private double longitude;
public void onStart(Intent intent, int startId)
{
// Get a LocationManager from the system services
locationManager =
(LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Register for updates from spoofed GPS
locationManager.requestLocationUpdates("gps", 30000L, 0.0f, new LocationListener()
{
@Override
public void onLocationChanged(Location location)
{
currentLocation = location;
}
@Override
public void onProviderDisabled(String provider) {}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onStatusChanged(String provider, int status,
Bundle extras) {}
});
// Get the last known location from GPS
currentLocation =
locationManager.getLastKnownLocation("gps");
// Build the widget update
RemoteViews updateViews = buildUpdate(this);
// Push update for this widget to the home screen
ComponentName thisWidget = new ComponentName(this, Widget.class);
// AppWidgetManager updates AppWidget state; gets information about
// installed AppWidget providers and other AppWidget related state
AppWidgetManager manager = AppWidgetManager.getInstance(this);
// Updates the views based on the RemoteView returned from the
// buildUpdate method (stored in updateViews)
manager.updateAppWidget(thisWidget, updateViews);
}
public RemoteViews buildUpdate(Context context)
{
latitude = currentLocation.getLatitude();
longitude = currentLocation.getLongitude();
RemoteViews updateViews =
new RemoteViews(context.getPackageName(), R.layout.main);
updateViews.setTextViewText(R.id.latitude_text, "" + latitude);
updateViews.setTextViewText(R.id.longitude_text, "" + longitude);
return updateViews;
}
@Override
public IBinder onBind(Intent intent) {
// We don't need to bind to this service
return null;
}
}
}
I'm having trouble starting a Service to update an AppWidget that I'm creating as an exercise. I'm trying to get the latitude and longitude of spoofed location data from DDMS to display in the widget. The widget uses a service to update the TextView, which may be slightly overkill, but I wanted to follow the template that seems to be common in AppWidgets that do more work (like the Forecast widget or the Wiktionary widget).
Right now, I'm not getting any error messages or strange behavior; nothing at all happens when the button is pressed. I'm a bit mystified as to what might be wrong. Could anyone out there point me in the right direction?
Additionally, if my logic for location is faulty, I'd love recommendations on that too. I've looked at several blogs, the Google examples, and the documentation, but I feel a little fuzzy on how it works.
Here is the current state of the widget:
public class Widget extends AppWidgetProvider
{
static final String TAG = "Widget";
/**
* {@inheritDoc}
*/
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds)
{
// Create an intent to launch the service
Intent serviceIntent = new Intent(context, UpdateService.class);
// PendingIntent is required for the onClickPendingIntent that actually
// starts the service from a button click
PendingIntent pendingServiceIntent =
PendingIntent.getService(context, 0, serviceIntent, 0);
// Get the layout for the App Widget and attach a click listener to the
// button
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);
views.setOnClickPendingIntent(R.id.address_button, pendingServiceIntent);
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
// To prevent any ANR timeouts, we perform the update in a service;
// really should have its own thread too
public static class UpdateService extends Service
{
static final String TAG = "UpdateService";
private LocationManager locationManager;
private Location currentLocation;
private double latitude;
private double longitude;
public void onStart(Intent intent, int startId)
{
// Get a LocationManager from the system services
locationManager =
(LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Register for updates from spoofed GPS
locationManager.requestLocationUpdates("gps", 30000L, 0.0f, new LocationListener()
{
@Override
public void onLocationChanged(Location location)
{
currentLocation = location;
}
@Override
public void onProviderDisabled(String provider) {}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onStatusChanged(String provider, int status,
Bundle extras) {}
});
// Get the last known location from GPS
currentLocation =
locationManager.getLastKnownLocation("gps");
// Build the widget update
RemoteViews updateViews = buildUpdate(this);
// Push update for this widget to the home screen
ComponentName thisWidget = new ComponentName(this, Widget.class);
// AppWidgetManager updates AppWidget state; gets information about
// installed AppWidget providers and other AppWidget related state
AppWidgetManager manager = AppWidgetManager.getInstance(this);
// Updates the views based on the RemoteView returned from the
// buildUpdate method (stored in updateViews)
manager.updateAppWidget(thisWidget, updateViews);
}
public RemoteViews buildUpdate(Context context)
{
latitude = currentLocation.getLatitude();
longitude = currentLocation.getLongitude();
RemoteViews updateViews =
new RemoteViews(context.getPackageName(), R.layout.main);
updateViews.setTextViewText(R.id.latitude_text, "" + latitude);
updateViews.setTextViewText(R.id.longitude_text, "" + longitude);
return updateViews;
}
@Override
public IBinder onBind(Intent intent) {
// We don't need to bind to this service
return null;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试将最后一个参数设置为
:
另外,有时您需要将 addData 添加到您的 Android 意图中,以将其区分为新内容,这有点 hacky,但似乎可行,因此添加:
Try setting the last parameter of
to:
Also sometimes you need to addData to your intent for Android to distinguish it as something new, this is a bit hacky but seems to work so add:
appWidgetManager.updateAppWidget
必须调用,否则点击事件不会响应appWidgetManager.updateAppWidget
must be call , or click event won't response