【问题标题】:How can I target a specific AppWidgetProvider with an intent?如何以意图为目标定位特定的 AppWidgetProvider?
【发布时间】:2013-11-02 02:31:00
【问题描述】:

我为我的任务应用程序实现了一个小部件,我希望它的AppWidgetProvider 接收自定义数据更改通知广播。因为我想将这些广播定位到我的应用程序中的注册组件,WidgetProvider 实例就是其中之一,所以我正在使用Intent 的 setComponent() API。 widgetProvider 仅在我删除对setComponent() 的调用并且将意图过滤器添加到AndroidManifest.xml 中的WidgetProvider 组件时才接收到意图。我怎样才能让setComponent() 工作?下面是我正在使用的代码的表示。

package com.mypackage.widgets;

public class WidgetProvider extends AppWidgetProvider {

    static {
        MyActivity.registerChangeListener( new ComponentName( 
            WidgetProvider.class.getPackage().getName(), WidgetProvider.class.getName() ) );
    }

    ...

    @Override
    public void onReceive( Context ctx, Intent intent ) {
        final String action = intent.getAction();

        if( MyActivity.FETCH_DATA_ACTION.equals( action ) ) {
            // This only runs when I *don't* call setComponent() on the intent
            ...
            // fetch data
            ...
        }
    }

    ...
}

...

package com.mypackage;

public class MyActivity extends Activity {

    public static final String FETCH_DATA_ACTION = "com.mypackage.MyActivity.FETCH_DATA";

    private static ArrayList<ComponentName> sChangeListeners = new ArrayList<ComponentName>();

    public static void registerChangeListener( ComponentName cn ) {
        sChangeListeners.add( cn );
    }

    private static void notifyChangeListeners() {
        for( ComponentName cn: sChangeListeners ) {
            Intent intent = new Intent();
            intent.setAction( FETCH_DATA_ACTION );
            intent.setComponent( cn );
            sendBroadcast( intent );
        }
    }

    ...
        changeData();
        notifyChangeListeners();
    ...
}

WidgetProvider 在我的 AndroidManifest 中注册如下:

<receiver android:name=".widgets.WidgetProvider"
    android:exported="false">

    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        <action android:name="android.appwidget.action.APPWIDGET_DELETED" />
        <action android:name="android.appwidget.action.APPWIDGET_ENABLED" />
        <action android:name="android.appwidget.action.APPWIDGET_DISABLED" />
    </intent-filter>

    <meta-data android:name="android.appwidget.provider"
        android:resource="@xml/widget_info" />
</receiver>

【问题讨论】:

    标签: android android-intent android-widget


    【解决方案1】:

    ComponentName 实例是使用 Android 包名而不是 java 包名构建的。如果WidgetProvider.class.getPackage().getName() 不等于AndroidManifest.xml 中指定的包名称,则调用setComponent(cn) 将指向无效组件。

    【讨论】:

    • 相对于 Java 包名,Android 包名是什么意思?
    • Android 包名称 = package 属性在您的 &lt;manifest&gt; 中。 java包名是你WidgetProviderjava类的包名,可能是一个子包。构造 ComponentNames 时不应使用 java 包名。
    • 我尝试过,但它也不起作用:new ComponentName("com.mypackage", "WidgetProvider")
    • 类名是完全限定的java类名。对于组件名称的类名部分,您之前拥有的内容应该没问题。
    • 尤里卡,这行得通。谢谢@jspurlock。文档(developer.android.com/reference/android/content/…,java.lang.String))需要更清楚,因为它应该指定应用程序包名称而不是 java 包名称。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-17
    • 2017-03-11
    相关资源
    最近更新 更多