我有一个带有小部件的Android应用程序,它有按钮。 此代码有效。
当发生某些事情时,小部件上的按钮停止工作,例如更改手机的语言。我使用共享首选项,所以如果用户重新安装应用程序(不卸载),按钮再次运行,设置仍然是设置的。
AppWidgetProvider
类中的Intents(此分析下的代码)没有被适当地触发。 Toast
实例化的Call1
类中添加了AppWidgetProvider
消息,但未显示。UpdateService.java
只是获取设置首选项并自定义窗口小部件的外观,因此我认为它可能与我的问题无关。Main.java
文件只包含微调器并保存共享首选项,这意味着我在微调器中选择“计算机”,以便小部件上显示“计算机”文本。当我改变手机的语言时,它也不会消失,图像也不会消失。因此,我认为UpdateService.java
必须没问题。这是AppWidgetProvider类:
public class HelloWidget extends AppWidgetProvider {
public static String ACTION_WIDGET_CONFIGURE = "ConfigureWidget";
public static String ACTION_WIDGET_CONFIGURE2 = "ConfigureWidget";
public static String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget";
public static String ACTION_WIDGET_RECEIVER2 = "ActionReceiverWidget";
private static final int REQUEST_CODE_FOUR = 40;
private static final int REQUEST_CODE_FIVE = 50;
private static final int REQUEST_CODE_SIX = 60;
private static final int REQUEST_CODE_SEVEN = 70;
private static final int REQUEST_CODE_EIGHT = 80;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
context.startService(new Intent(context, UpdateService.class));
//Intent widgetUpdateIntent = new Intent(context, UpdateService.class);
//context.startService(widgetUpdateIntent );
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetmain2);
//P1 starts Call1.class
Intent configIntent4 = new Intent(context, Call1.class);
configIntent4.setAction(ACTION_WIDGET_CONFIGURE);
PendingIntent configPendingIntent4 = PendingIntent.getActivity(context, REQUEST_CODE_FOUR, configIntent4, 0);
remoteViews.setOnClickPendingIntent(R.id.ImageView01, configPendingIntent4);
//P2 starts Call2.class
Intent configIntent5 = new Intent(context, Call2.class);
configIntent5.setAction(ACTION_WIDGET_CONFIGURE);
PendingIntent configPendingIntent5 = PendingIntent.getActivity(context, REQUEST_CODE_FIVE, configIntent5, 0);
remoteViews.setOnClickPendingIntent(R.id.ImageView02, configPendingIntent5);
//P3 starts Call3.class
Intent configIntent6 = new Intent(context, Call3.class);
configIntent6.setAction(ACTION_WIDGET_CONFIGURE);
PendingIntent configPendingIntent6 = PendingIntent.getActivity(context, REQUEST_CODE_SIX, configIntent6, 0);
remoteViews.setOnClickPendingIntent(R.id.ImageView03, configPendingIntent6);
//P4 starts Call4.class
Intent configIntent7 = new Intent(context, Call4.class);
configIntent7.setAction(ACTION_WIDGET_CONFIGURE);
PendingIntent configPendingIntent7 = PendingIntent.getActivity(context, REQUEST_CODE_SEVEN, configIntent7, 0);
remoteViews.setOnClickPendingIntent(R.id.ImageView04, configPendingIntent7);
//P5 starts Call5.class
Intent configIntent8 = new Intent(context, Call5.class);
configIntent8.setAction(ACTION_WIDGET_CONFIGURE);
PendingIntent configPendingIntent8 = PendingIntent.getActivity(context, REQUEST_CODE_EIGHT, configIntent8, 0);
remoteViews.setOnClickPendingIntent(R.id.ImageView05, configPendingIntent8);
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
}
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action))
{
final int appWidgetId = intent.getExtras().getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,AppWidgetManager.INVALID_APPWIDGET_ID);
if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID)
{
this.onDeleted(context, new int[] { appWidgetId });
}
}
else
{
if (intent.getAction().equals(ACTION_WIDGET_RECEIVER))
{
String msg = "null";
try {
msg = intent.getStringExtra("msg");
} catch (NullPointerException e) {
//Log.e("Error", "msg = null");
}
}
super.onReceive(context, intent);
}
}
}
我还有一个EditPreferences.java
,GlobalVars.java
和其他一些现在没有意义的课程。这些课程的名称不言自明。
另一件事。我还有Widgetmain.java
:
public class WidgetMain extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.widgetmain2);
}
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId)
{
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetmain2);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}
编辑:这个怎么样:
当我在同事的ZTE Blade上安装此应用程序时,窗口小部件上的文本视图未加载相应的文本,只是使用在strings.xml中确定的文本。
当我重新安装应用程序(不卸载)时,会加载textview,一切都很好。 我的HTC Desire HD没有出现此问题。
textview在前面提到的UpdateService.java中加载(代码的一部分):
RemoteViews updateViews = new RemoteViews(this.getPackageName(), R.layout.main);
updateViews.setTextViewText(R.id.widget_textview, name);
ComponentName thisWidget = new ComponentName(this, HelloWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
manager.updateAppWidget(thisWidget, updateViews);
即使“name”是静态的(例如String name =“Something”),在第一次安装时仍未加载该textview。
答案 0 :(得分:6)
每当您通过“new RemoteViews”创建新实例时,尝试使用单击侦听器更新RemoteView。在某些情况下,可能会从XML中新加载RemoteView,因此需要重新分配点击侦听器。
答案 1 :(得分:5)
我的UpdateService.java只是获取设置首选项并自定义窗口小部件的外观,所以我认为它可能与我的问题无关。
它可能是相关的,因为你可以使用它来“刷新”未决的意图。我的appwidget中有类似的问题,图像按钮在一些随机运行时间(小时)后停止响应点击。
我找到了这个帖子: AppWidget Button onClick stops working
这句话:
每次使用后,待处理的意图都会被“烧毁”。你需要再次设置它。或者等待窗口小部件刷新,然后它也会发生,但这可能不是理想的方式。
鉴于小部件更新时间通常设置为多个小时或几天(我的是86400000毫秒),以防止手机每隔这么多分钟停止暂停,您的小部件将不会经常在更新上运行。在更新服务中设置待处理的意图ALSO可能会阻止您描述的问题。每次更新服务运行时,都会重新创建待处理的意图。
我今天已经为我的appwidget添加了这个可能的修复程序,我必须等待,看看修复程序是否真的有效,但到目前为止还是那么好。
我在更新服务'循环中添加了以下代码,其中刷新了每个小部件:
for (int i=0; i<appWidgetIds.length; i++)
{
appWidgetId=appWidgetIds[i];
/* other stuff to do */
RemoteViews views=new RemoteViews(context.getPackageName(), R.layout.example_appwidget);
/* here you "refresh" the pending intent for the button */
Intent clickintent=new Intent("net.example.appwidget.ACTION_WIDGET_CLICK");
PendingIntent pendingIntentClick=PendingIntent.getBroadcast(context, 0, clickintent, 0);
views.setOnClickPendingIntent(R.id.example_appwidget_button, pendingIntentClick);
appWidgetManager.updateAppWidget(appWidgetId, views);
/* then tell the widget manager to update */
appWidgetManager.updateAppWidget(appWidgetId, views);
}
答案 2 :(得分:2)
问题是您无法对窗口小部件进行部分更新,您必须设置所有窗口小部件功能,例如每次推送新的远程视图时的PendingIntent集。 (Partiall更新仅适用于API14及更高版本......)。
你的小部件丢失pendingIntents的原因是android系统保存了remoteView,并用它重建你的小部件,以防它重置小部件(memmory短缺,TaskManager / taskKiller正在使用等等),因此,您必须在updateService中的remoteView中设置窗口小部件的所有更新代码。否则,它只是不会再次设置pendingIntents。
因此,只需将pendingIntents的代码设置添加到服务中,您的问题就会得到解决=]
答案 3 :(得分:0)
我认为PendingIntents可能需要传递一个标志,可能会尝试更改:
PendingIntent.getActivity(context, REQUEST_CODE, configIntent, 0);
为:
PendingIntent.getActivity(context, REQUEST_CODE, configIntent, PendingIntent.FLAG_UPDATE_CURRENT);
从PendingIntent documentation,我认为代码'0'未定义。在这种情况下,FLAG_UPDATE_CURRENT最有效,因为您可能希望每次单击按钮时都更新Intent。
答案 4 :(得分:0)
根据您提供的所有信息,我会说更改首选项时未正确触发更新方法。
我希望经过这么多测试后,您已经验证了您的清单文件包含:
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
你确认onUpdate
曾经跑过吗?在我看来,如果重新安装应用程序而不卸载可以解决您的问题,可能是因为它强制进行更新调用。
仔细检查后,发现ScanPlayGames有一个点:official documentation's example使用super.onUpdate()。请注意,它在方法结束时使用它,但Internet上的多个examples表示您最好在方法开始时使用它。
答案 5 :(得分:0)
我已经有很长一段时间了。我的小部件有按钮@(onUpdate)。小部件具有更新服务。小部件上的按钮在发生某些事情时停止工作,例如:更改字体等。
当我重新安装应用程序时,按钮再次运行。最后,我意识到我从未在我的Service类中调用onUpdate。
从服务类调用onUpdate解决了问题。
答案 6 :(得分:0)
如果仍有问题,请尝试在AppWidgetProviderInfo中设置属性android:updatePeriodMillis; 操作系统可以出于各种原因终止待定意图,并且您的按钮可以停止工作。设置此属性后,您将告诉Android何时应调用AppWidgetProvider中的onUpdate方法,因此将重新创建所有待处理的意图。
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
...
android:updatePeriodMillis="3600000">
</appwidget-provider>