无法将小部件 ID 传递给配置活动
Posted
技术标签:
【中文标题】无法将小部件 ID 传递给配置活动【英文标题】:cant pass widget id to configuration activity 【发布时间】:2011-12-06 13:00:28 【问题描述】:我编写了一个具有配置活动的 AppWidget(我使用了与应用程序本身相同的配置活动) 在调试模式下将小部件添加到主屏幕时,我将小部件 ID(使用 put extra)传递给意图。单击小部件本身时(加载首选项的活动,我在 onCreate 方法处中断,在我调用 intent.getExtras 或 intent.getIntExtra 的部分 - 我得到空值。 我想使用以下代码,但无法理解: passing-widget-id-to-activity:
问题在于 android 使用 PendingIntents 进行缓存。解决方案是添加 FLAG_UPDATE_CURRENT 标志,使其更新缓存的 PendingIntent。
PendingIntent configPendingIntent = PendingIntent.getActivity(context, REQUEST_CODE_ONE, configIntent, PendingIntent.FLAG_UPDATE_CURRENT);
这是我的代码:
Manifest.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();
【问题讨论】:
我把我的课程缩写了,以免你不相关的东西。 【参考方案1】:我需要改变下一件事:
//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);
现在可以了
【讨论】:
以上是关于无法将小部件 ID 传递给配置活动的主要内容,如果未能解决你的问题,请参考以下文章