【问题标题】:Android AppWidget not receiving APPWIDGET_ENABLED intentAndroid AppWidget 未收到 APPWIDGET_ENABLED 意图
【发布时间】:2011-11-21 05:26:52
【问题描述】:

我正在尝试使用 AlarmManager 类创建我的第一个 AppWidget,以便我可以比每 30 分钟更频繁地更新。我遵循this tutorial 作为设置小部件的基础,但由于某种原因,我无法正常开始更新。似乎我从未收到任何 APPWIDGET_ENABLED 意图,这将触发我的 AppWidgetProvider 中的 onEnabled 事件回调。

这是我的 AppWidgetProvider 的清单定义:

    <receiver 
       android:name="com.myapp.android.appwidget.MarketTimingAppWidgetProvider"
       android:label="@string/appwidget_markettiming_label">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
            <action android:name="@string/appwidget_markettiming_updateintent" />           
        </intent-filter>
        <meta-data android:name="android.appwidget.provider"
                   android:resource="@xml/appwidget_markettiming_info" />
    </receiver>

这是我的 AppWidgetProvider 的代码:

public class MarketTimingAppWidgetProvider extends AppWidgetProvider {

public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

    final int N = appWidgetIds.length;

    Log.d("myLogger", "onUpdate");
    // Perform this loop procedure for each App Widget that belongs to this provider
    for (int i=0; i<N; i++) {

        int appWidgetId = appWidgetIds[i];
        Log.d("myLogger", "Updating Widget: " + appWidgetId);
        updateWidget(context, appWidgetManager, appWidgetId);

    }

}

@Override
public void onEnabled(Context context) {
    super.onEnabled(context);

    Log.d("myLogger", "onEnabled running");
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.add(Calendar.SECOND, 1);
    alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), 
                              1000, createClockIntent(context));   
}

public void onDisabled(Context context) {
    super.onDisabled(context);
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    alarmManager.cancel(createClockIntent(context));
}

public void onReceive(Context context, Intent intent) {
    super.onReceive(context, intent);

    Log.d("myLogger", "Intent Received " + intent.getAction());
    String widgetIntent = context.getResources().getString(R.string.appwidget_markettiming_updateintent);

    // This code fires when my custom intent is received
    if(widgetIntent.equals(intent.getAction())) {
        ComponentName thisAppWidget = new ComponentName(context.getPackageName(), getClass().getName());
        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
        int ids[] = appWidgetManager.getAppWidgetIds(thisAppWidget);
        for(int appWidgetId: ids) {
            updateWidget(context, appWidgetManager, appWidgetId);
        }
    }

}

private void updateWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {

    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_markettiming);
    views.setTextViewText(R.id.widget_text, "Update: " +  
            DateFormat.getDateTimeInstance(
                    DateFormat.LONG, DateFormat.LONG).format(new Date()));

    // Tell the AppWidgetManager to perform an update on the current app widget
    appWidgetManager.updateAppWidget(appWidgetId, views);

}

private PendingIntent createClockIntent(Context context) {
    String updateIntent = context.getResources().getString(R.string.appwidget_markettiming_updateintent);
    Log.d("myLogger", "my intent: " + updateIntent);
    Intent intent = new Intent(updateIntent);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    return pendingIntent;
}

}

当我查看 LogCat 时,我的 onReceive 方法收到的唯一意图是初始 APPWIDGET_UPDATE 意图,并且唯一执行的回调是 onUpdate 回调。我尝试在我的 appwidget 意图过滤器中包含 APPWIDGET_ENABLED 意图(尽管文档告诉我这应该由我的小部件自动接收)。它没有用。我在这里缺少什么吗?

【问题讨论】:

    标签: android android-intent android-appwidget


    【解决方案1】:

    您的清单中有错误。此元素中的操作名称:

    <action android:name="@string/appwidget_markettiming_updateintent" />
    

    应该替换为实际的字符串,而不是引用。所以应该是这样的:

    <action android:name="com.myapp.android.appwidget.action.MARKETTIMING_UPDATE" />
    

    或您在 &lt;string name="appwidget_markettiming_updateintent"&gt; 元素内的 values/something.xml 中的任何内容。

    问题是BroadcastReceiver 没有接收到来自AlarmManager 的广播。我已经用你的代码创建了一个项目,只替换了清单中的这个字符串(当然还向 values/strings.xml 添加了适当的值)并且一切正常。

    此外,您可能希望仅将 alarmManager.setRepeating() 的第二个参数替换为 System.currentTimeMillis() + 1000 并删除所有与日历相关的额外内容。

    【讨论】:

    • 嗯,出于某种原因,我没有得到那个意图,但至少很高兴知道代码的结构就像我认为的那样。小部件上的 TextView 是否每秒更新一次?
    • 不,只有一次。现在我去睡觉了,但明天会尝试找时间更详细地查看代码。我目前也在学习使用 App Widgets,所以会一起寻找错误。 :)
    • 所以我发现当我从模拟器中完全卸载应用程序然后重新安装它时,启用的事件就会触发。我想这意味着我真的不明白这个 Intent 什么时候会被解雇。我认为任何时候都会将小部件的第一个实例添加到主屏幕。如果我删除它并再次添加它,我想应该再次触发启用的意图。
    • 你说得对,我发现这是我第二个问题的根源。我想我只是想在我的配置中变得太花哨:)。虽然,我不完全确定为什么它不像我期望的那样工作,因为我可以像在清单中的其他任何地方一样使用字符串资源。
    • 我也不知道为什么这与清单的其他部分或 xml 资源的工作方式不同。另一方面,String 常量在代码中的使用更加简单明了。所以一切都好。 :)
    【解决方案2】:

    显然从模拟器中卸载它然后重新安装它就可以了。现在,当我添加一个小部件时,会收到 APPWIDGET_ENABLE 意图,当我删除它时,会像我预期的那样触发 APPWIDGET_DISABLED 意图。我仍然遇到一个问题,即警报管理器实际上并没有像我预期的那样触发我的自定义 Intent,但这是我需要研究的另一个问题。

    【讨论】:

      猜你喜欢
      • 2018-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多