Android AppWidget未接收AppWidget\u启用意图

Android AppWidget未接收AppWidget\u启用意图,android,android-intent,android-appwidget,Android,Android Intent,Android Appwidget,我正在尝试使用AlarmManager类创建我的第一个AppWidget,这样我可以比每30分钟更新一次更频繁。我将此作为设置小部件的基础,但由于某些原因,我无法正确开始更新。似乎我从未收到任何APPWIDGET_启用的意图,这会在我的AppWidgetProvider中触发OneEnabled事件回调 以下是我的AppWidgetProvider的清单定义: <receiver android:name="com.myapp.android.appwidget.M

我正在尝试使用AlarmManager类创建我的第一个AppWidget,这样我可以比每30分钟更新一次更频繁。我将此作为设置小部件的基础,但由于某些原因,我无法正确开始更新。似乎我从未收到任何APPWIDGET_启用的意图,这会在我的AppWidgetProvider中触发OneEnabled事件回调

以下是我的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>
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;
}

以下是我的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>
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;
}
公共类MarketTimeingAppWidgetProvider扩展了AppWidgetProvider{
公共void onUpdate(上下文上下文,AppWidgetManager AppWidgetManager,int[]AppWidgetId){
final int N=appWidgetIds.length;
Log.d(“myLogger”、“onUpdate”);
//对属于此提供商的每个应用程序小部件执行此循环过程

对于(int i=0;i您的清单中有错误。此元素中的操作名称:

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

应替换为实际字符串,而不是引用。因此应如下所示:

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

或者
元素中的values/something.xml中的任何内容

问题是BroadcastReceiver没有从AlarmManager接收广播。我用您的代码创建了一个项目,在清单中只替换了这个字符串(当然,还向values/strings.xml添加了适当的值),所有这些都可以正常工作


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

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

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