我正在开发一个没有任何错误的小部件,但我的小部件的ImageView
没有更新,也没有给出任何错误。因此让我对我正在做的错误感到困惑。这是代码: -
BroadcastReceiver _broadcastReceiver;
GetDrawableResources getDrawableResources = new GetDrawableResources();
private final SimpleDateFormat _sdfWatchTime = new SimpleDateFormat("HH:mm");
@Override
public void onEnabled(final Context context) {
super.onEnabled(context);
// TODO Auto-generated method stub
System.out.println("Entering onstart");
_broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context ctx, Intent intent) {
System.out.println("Registering BroadCast");
if (intent.getAction().compareTo(Intent.ACTION_TIME_TICK) == 0) {
System.out.println(_sdfWatchTime.format(new Date()));
Bundle extras = intent.getExtras();
if (extras != null) {
AppWidgetManager awm = AppWidgetManager
.getInstance(context);
ComponentName thisWidget = new ComponentName(
context.getPackageName(),
MainActivity.class.getName());
int[] appWidgetIds = awm.getAppWidgetIds(thisWidget);
onUpdate(context, awm, appWidgetIds);
}
}
}
};
context.getApplicationContext().registerReceiver(_broadcastReceiver,
new IntentFilter(Intent.ACTION_TIME_TICK));
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
super.onUpdate(context, appWidgetManager, appWidgetIds);
for (int awID : appWidgetIds) {
updateAppWidget(context, appWidgetManager, awID);
}
}
private void updateAppWidget(Context context,
AppWidgetManager appWidgetManager, int awID2) {
// TODO Auto-generated method stub
// class to get drawable images that will be used to denote hours and
// minutes
int time[] = new int[new GetTime().getTime(context
.getApplicationContext()).length];
// class to get each digit of time separately eg 10:10, separating 1 0 1
// 0 working correctly
time = new GetTime().getTime(context.getApplicationContext());
// changing views
System.out.println("awID for " + awID2);
RemoteViews views = new RemoteViews(context
.getPackageName(), R.layout.activity_main);
views.setImageViewResource(R.id.ivHour0,
getDrawableResources.setTimeDrawable(time[0]));
views.setImageViewResource(R.id.ivHour1,
getDrawableResources.setTimeDrawable(time[1]));
views.setImageViewResource(R.id.ivMinute0,
getDrawableResources.setTimeDrawable(time[2]));
views.setImageViewResource(R.id.ivMinute1,
getDrawableResources.setTimeDrawable(time[3]));
System.out.println("updating the views");
appWidgetManager.updateAppWidget(awID2, views);
}
我的LogCat中的输出
06-28 19:46:00.076: I/System.out(680): Registering BroadCast
06-28 19:46:00.086: I/System.out(680): 19:46
06-28 19:46:00.096: I/System.out(680): awID for 14
06-28 19:46:00.096: I/System.out(680): updating the views
06-28 19:47:00.086: I/System.out(680): Registering BroadCast
06-28 19:47:00.086: I/System.out(680): 19:47
06-28 19:47:00.096: I/System.out(680): awID for 14
06-28 19:47:00.096: I/System.out(680): updating the views
因此appWidgetID是正确的,函数正在执行,但是视图没有更新。它们和以前一样。
答案 0 :(得分:1)
您的方法有一个有效的基础,但是您正在onEnabled方法中创建并注册broadcastReceiver,而onEnabled方法又属于WidgetProvider类。
当WidgetProvider(onEnabled,onUpdate)的方法完成执行时,系统会破坏WidgetProvider类,因此你的broadcastReceiver也是如此。正如你在这里看到没有错误但没有收到错误。
为了做你想做的事情,你需要一个更“稳定”的应用程序组件来保存你的broadcastReceiver,像这样的组件是一种服务。即使您的应用程序已停止运行,服务也会继续运行,因此它是这类作业的一个很好的组件。
因此,为了回答您的问题,我建议您创建一个服务,创建并注册您的broadcastReceiver,然后从您的widgetprovider类的onEnabled方法启动服务,并且当用户从您的widget移除您的小部件时,您可以停止该服务主屏幕。
从我的建议开始的一个好地方是here...
修改强> Here是来自谷歌的App Widgets的文档(约中间):
注意:由于AppWidgetProvider是BroadcastReceiver的扩展,因此在回调方法返回后,您的进程无法保证继续运行(有关广播生命周期的信息,请参阅BroadcastReceiver)。如果您的App Widget设置过程可能需要几秒钟(可能在执行Web请求时),并且您需要继续进程,请考虑在onUpdate()方法中启动Service。在服务中,您可以对App Widget执行自己的更新,而无需担心由于应用程序无响应(ANR)错误导致AppWidgetProvider关闭。有关运行服务的App Widget的示例,请参阅Wiktionary示例的AppWidgetProvider。
我在我的appwidget中遇到了类似的问题,原来这是由我的appwidgetprovider的生命周期引起的,所以我基于此回答了你。但是在你的观察中你是对的,你的小部件应该至少更新自己第一次更新的当前时间,所以看看它更多我看到你正在使用自定义的getDrawableResources类来获取你的资源(你能用它编辑你的问题吗?代码?),你正在使用getDrawableResources.setTimeDrawable(time [0]));为了得到drawable,也许你应该把它改成getDrawableResources.getTimeDrawable(time [0]))?
编辑2
以下是说明我的建议的代码。首先是我们注册BatteryReceiver的服务。
class FullWidgetBatteryChangedReceiver extends BroadcastReceiver {
//----- BroadcastReceiver Overrides -----
@Override
public void onReceive(Context cx, Intent intent) {
Log.d("BatteryChangedReceiver", "onReceive");
Commands.FullWidgetUpdate(cx, -1, 0); //<-- Update all widgets
}
//----- BroadcastReceiver Overrides END -----
}
public class myWidgetService extends Service {
//----- Private Members -----
private FullWidgetBatteryChangedReceiver bcRCV;
//----- Private Members END -----
//----- Private Code -----
private void RegisterBatteryChangedReceiver() {
Log.d(TAG, "RegisterBatteryChangedReceiver");
if (bcRCV == null) {
Log.d(TAG, "BatteryChangedReceiver needs Registration and I am doing it...");
bcRCV = new FullWidgetBatteryChangedReceiver();
IntentFilter actions = new IntentFilter();
actions.addAction(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(bcRCV, actions);
} else {
Log.d(TAG, "BatteryChangedReceiver does not needs Registration");
}
}
private void UnRegisterBatteryChangedReceiver() {
Log.d(TAG, "UnRegisterBatteryChangedReceiver");
if (bcRCV != null) {
Log.d(TAG, "Assuming that BatteryChangedReceiver is registered and I am unregister it...");
unregisterReceiver(bcRCV);
bcRCV = null;
} else {
Log.d(TAG, "Assuming that BatteryChangedReceiver is NOT registered");
}
}
//----- Private Code END -----
//----- Service Overrides -----
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
RegisterBatteryChangedReceiver();
return Service.START_STICKY; //<-- This is important!!!
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
UnRegisterBatteryChangedReceiver();
super.onDestroy();
}
//----- Service Overrides END -----
}
然后是myWidgetProvider,其中完成了服务操作:
public class myWidgetProvider extends AppWidgetProvider {
//----- AppWidgetProvider Overrides -----
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
// If no specific widgets requested, collect list of all
if (appWidgetIds == null) {
appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, FullWidgetProvider.class));
}
// Εδώ κάνουμε update to Widget για κάθε id ξεχωριστά
for (int widgetId : appWidgetIds) {
Commands.FullWidgetUpdate(context, widgetId, 0); //<-- Update το widgetId
}
context.startService(new Intent(context, myWidgetService.class));
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
context.stopService(new Intent(context, FullWidgetService.class));
int[] appWidgetIds = AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, FullWidgetProvider.class));
if (appWidgetIds.length != 0) {
AppWidgetHost host = new AppWidgetHost(context, 0);
for (int widgetId : appWidgetIds) {
host.deleteAppWidgetId(widgetId);
}
}
}
//----- AppWidgetProvider Overrides END -----
}
希望这会有所帮助......