android - 无法将小部件 ID 传递给配置 Activity

标签 android android-intent android-widget android-appwidget

我编写了一个具有配置 Activity 的 AppWidget(我使用了与应用程序本身相同的配置 Activity ) 在 Debug模式下将小部件添加到主屏幕时,我将小部件 ID(使用 put extra)传递给 Intent 。当单击小部件本身时(加载我在 onCreate 方法中中断的 prefs Activity ,在我调用 intent.getExtras 或 intent.getIntExtra 的部分 - 我得到空值。 我想使用以下代码,但无法理解如何使用: passing-widget-id-to-activity :

The issue was that android does caching with PendingIntents. The solution was to add the FLAG_UPDATE_CURRENT flag which causes it to update the cached PendingIntent.

PendingIntent configPendingIntent = PendingIntent.getActivity(context, REQUEST_CODE_ONE, configIntent, PendingIntent.FLAG_UPDATE_CURRENT);

这是我的代码:

list .xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test.dryrun" android:versionCode="3"
    android:versionName="1.1" android:installLocation="auto">
    <uses-sdk android:minSdkVersion="8" />

    <application android:icon="@drawable/ic_launcher_test"
        android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
        android:debuggable="true"><!-- different< android:theme="@style/Theme.NoBackground" -->

        <!-- Main Activity -->
        <activity android:name=".MyActivity"
            android:configChanges="orientation"> <!--android:screenOrientation="portrait" -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Preferences -->

        <activity android:name=".Preferences.EditPreferences"
            android:configChanges="orientation">
             <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
        </activity>

        <!-- Widgets -->

        <!--  Widget-->
        <receiver android:name=".Widget.testWidget" android:label="@string/app_widget_">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <!--action
                    android:name="com.test.dryrun.Widget.testWidget.PREFENCES_WIDGET_CONFIGURE" /-->
            </intent-filter>
            <meta-data android:name="android.appwidget.provider"
                android:resource="@xml/test_widget__provider" />
        </receiver>
        <service android:name=".Widget.testWidget$WidgetService" />

        <uses-permission android:name="android.permission.BIND_REMOTEVIEWS"></uses-permission>
    </application>
</manifest>

appwidget_provider xml

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
 android:minWidth="146dip"
 android:minHeight="146dip"
 android:updatePeriodMillis="0"
 android:initialLayout="@layout/test_widget_"
/>

小部件类

public class testWidget extends AppWidgetProvider {
  public static String PREFENCES_WIDGET_CONFIGURE = "ActionConfigureWidget";
  @Override
  public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
  {
    Intent svcIntent = new Intent(context, WidgetService.class);        
    context.startService(svcIntent);
  }


  @Override
  public void onReceive(Context context, Intent intent) 
  {
    RemoteViews remoteViews = new RemoteViews(
           context.getPackageName(), R.layout.test_widget); 

        // v1.5 fix that doesn't call onDelete Action
        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
        {
            super.onReceive(context, intent);           
        }
    }

    //public void updateWidget()
    /**
    * @param context
    * @param remoteViews
    */
    public static void updateWidget(Context context, RemoteViews remoteViews)
    {
        String Prefix = context.getString(R.string._prefix);

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        String ToShow = prefs.getString(context.getString(
                     R.string.Widget_string),
                     context.getString(R.string.default_string));

        String pkgName = context.getPackageName();
        int resID = context.getResources().getIdentifier(Prefix + ToShow, "drawable", pkgName);

        WidgetController widgetController = WidgetController.getInstance();
        widgetController.setRemoteViewImageViewSource(remoteViews, R.id.WidgetImage, resID);
    }

    public static class WidgetService extends Service
    {
        @Override
        public void onStart(Intent intent, int startId)
        {
            super.onStart(intent, startId);
            // Update the widget
            RemoteViews remoteView = buildRemoteView(this);

            // Push update to homescreen
            WidgetController.getInstance().pushUpdate(
                    remoteView, 
                    getApplicationContext(),
                    testWidget.class);

            // No more updates so stop the service and free resources
            stopSelf();
        }

        public RemoteViews buildRemoteView(Context context)
        {
            RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.test_widget_);

            Intent runConfigtest = new Intent(context, EditPreferences.class);
            runConfigtest.setAction(testWidget.PREFENCES_WIDGET_CONFIGURE);
            //old code-what you get in all the widget examples
            PendingIntent runtestPendingIntent = PendingIntent.getActivity(context, 0, runConfigtest, 0);
            //new code - this is how you should write it
            PendingIntent runtestPendingIntent = PendingIntent.getActivity(context, 0, runConfigtest, PendingIntent.FLAG_UPDATE_CURRENT);
            remoteViews.setOnClickPendingIntent(R.id.WidgetImage, runtestPendingIntent);

            updateWidget(context, remoteViews);

            return remoteViews;
        }



        @Override
        public void onConfigurationChanged(Configuration newConfig)
        {
            int oldOrientation = this.getResources().getConfiguration().orientation;

            if(newConfig.orientation != oldOrientation)
            {
                // Update the widget
                RemoteViews remoteView = buildRemoteView(this);

                // Push update to homescreen
                WidgetController.getInstance().pushUpdate(
                        remoteView, 
                        getApplicationContext(),
                        testWidget.class);
            }
        }

        @Override
        public IBinder onBind(Intent arg0)
        {
            // TODO Auto-generated method stub
            return null;
        }
    }
}

偏好类

public class EditPreferences extends PreferenceActivity implements OnSharedPreferenceChangeListener
{
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
        Intent intent = getIntent();
        m_extras = intent.getExtras();
        mAppWidgetId = intent.getIntExtra("widget_id", defaultVal);
    }
    private Bundle m_extras;

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) 
    {

        if(key.equals(getString(R.string.rlvntString)))
        {
                        Context ctx = getApplicationContext();
            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(ctx);
            setResult(RESULT_CANCELED);
            if (m_extras != null) 
            {
                mAppWidgetId = m_extras.getInt(
                        AppWidgetManager.EXTRA_APPWIDGET_ID, 
                        AppWidgetManager.INVALID_APPWIDGET_ID);
                RemoteViews views = new RemoteViews(ctx.getPackageName(),
                        R.layout.test_widget);
                appWidgetManager.updateAppWidget(mAppWidgetId, views);
                Intent resultValue = new Intent();
                resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
                setResult(RESULT_OK, resultValue);
                finish();
            }
            else
            {
                RemoteViews views = new RemoteViews(ctx.getPackageName(),
                        R.layout.test_widget);
                appWidgetManager.updateAppWidget(mAppWidgetId, views);
                Intent resultValue = new Intent();
                resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
                setResult(RESULT_OK, resultValue);
                finish();
            }
        }
    }

最佳答案

接下来我需要改变:

//old code-what you get in all the widget examples
PendingIntent runtestPendingIntent = PendingIntent.getActivity(context, 0, runConfigtest, 0);
//new code - this is how you should write it
PendingIntent runtestPendingIntent = PendingIntent.getActivity(context, 0, runConfigtest, PendingIntent.FLAG_UPDATE_CURRENT);

现在可以了

关于android - 无法将小部件 ID 传递给配置 Activity ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7747455/

相关文章:

android - 如何更改 Android Switch 小部件的拇指(开/关)的文本颜色?

android - 自定义 Android ListView 颜色?

android - 从另一个 Activity 中打开一个 Activity 的 fragment

java - .dex 文件中引用的方法数量不能超过 64K 和 java.lang.UnsupportedOperationException

Android从不同的资源文件夹中挑选图像和样式

java - 禁止在 map 长按时多次重新打开 Activity

android - 在 Android 中的按钮上编写多行文本

android - 在android中使用外部字体

java - 需要一种更简单的方法来为 Android 计算器程序中的多个变量设置 onClickListener

javascript - Android:有没有办法在渐进式应用程序架构中启用 WI-FI