Android 小部件没有更新视图,也没有显示错误
我正在开发一个运行中没有任何错误的小部件,但是我的小部件的Android 小部件没有更新视图,也没有显示错误,android,android-widget,broadcastreceiver,android-view,android-appwidget,Android,Android Widget,Broadcastreceiver,Android View,Android Appwidget,我正在开发一个运行中没有任何错误的小部件,但是我的小部件的ImageView没有更新,也没有给出任何错误。这让我对自己做错了什么感到困惑。代码如下:- BroadcastReceiver _broadcastReceiver; GetDrawableResources getDrawableResources = new GetDrawableResources(); private final SimpleDateFormat _sdfWatchTime = new SimpleDateFor
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是正确的,函数正在按其应该的方式执行,但视图没有更新。它们与以前相同。您的方法有一个有效的基础,但是您正在使用OneEnabled方法创建并注册broadcastReceiver,而OneEnabled方法又属于WidgetProvider类 当WidgetProvider(oneEnabled,onUpdate)的方法完成执行时,系统将销毁WidgetProvider类,您的broadcastReceiver也是如此。正如你所看到的,这里没有错误,也没有接收错误 为了实现您想要的功能,您需要一个更“稳定”的应用程序组件来容纳您的broadcastReceiver,这样的组件就是服务。即使应用程序停止运行,服务也会继续运行,因此它是此类作业的良好组件 因此,为了回答您的问题,我建议您创建一个服务,创建并注册您的broadcastReceiver,然后从widgetprovider类的OneEnabled方法启动该服务,当用户从主屏幕上删除您的小部件时,您可以停止该服务 从我的建议开始的一个好地方是 编辑 是来自谷歌的应用程序小部件文档(大约在中间)说明: 注意:由于AppWidgetProvider是BroadcastReceiver的一个扩展,因此不能保证在回调方法返回后进程继续运行(有关广播生命周期的信息,请参阅BroadcastReceiver)。如果应用程序小部件安装过程可能需要几秒钟(也许在执行Web请求时),并且要求进程继续进行,请考虑在OnUpDeDeO()方法中启动服务。在服务中,您可以对应用程序小部件执行自己的更新,而无需担心AppWidgetProvider因应用程序无响应(ANR)错误而关闭。有关运行服务的应用程序小部件的示例,请参见Wiktionary示例的AppWidgetProvider 在我的appwidget中,我和你有过类似的问题,结果是由我的appwidgetprovider的生命周期造成的,所以我基于此回答了你。然而,根据您的观察,您是对的,您的小部件应该至少在第一次更新时使用当前时间进行自我更新,因此仔细查看它,我发现您正在使用一个自定义的getDrawableResources类来获取资源(您能用它的代码编辑您的问题吗?),并且您正在使用getDrawableResources.setTimeDrawable(时间[0]);为了获得可绘制的,也许您应该将其更改为getDrawableResources.getTimeDrawable(时间[0]) 编辑2 下面是说明我的建议的代码。首先是我们注册电池接收器的服务
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 -----
}
类FullWidgetBatteryChangedReceiver扩展了BroadcastReceiver{
//-----广播接收机覆盖-----
@凌驾
公共void onReceive(上下文cx、意图){
Log.d(“电池更换接收器”、“接收”);
命令。FullWidgetUpdate(cx,-1,0);//我不知道这些WidgetProvider类和broadcastReceiver在执行后被销毁。我正在阅读有关该服务的信息,如果它解决了我的问题,请将答案标记为正确。谢谢。我想澄清一些事情。您说过,在执行后,onEnabled、onUpdate和broadcastReceiver被销毁,但每分钟我的broadcastReceiver都会被销毁nUpdate,然后最后调用updateAppWidget。因此,如果updateAppWidget每分钟都被调用,那么视图必须更新,因为更新是在这个方法中完成的。我说的有什么不对吗?getDrawableResources
是我创建的一个自定义类,它没有扩展或实现任何内容。它是一个简单的类。它返回t基于发送时间[0]的图像id。例如-if time[0]是8那么运行在getDrawableResources
中的代码是案例8:time=R.drawable.time_8;break;@RohanKandwal是这样的,但是看看我的第二次编辑,我在其中添加了一些说明这种方法的代码。谢谢。@RohanKandwal命令是一个自定义的静态类,我创建它是为了保持事情的有序性。哟你可以用你的updatewidget函数替换这一行。对于给你带来的不便,我深表歉意,但我的代码只是为了说明,不是一个完整的工作代码。顺便说一句,我很高兴你解决了你的问题。谢谢。
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 -----
}