哎呀,关于Android应用程序小部件的教程似乎有成千上万种,甚至在这里还有更多问题,但我就是无法弄清楚为什么我的小部件不起作用。叹气!反问:为什么代码不能和其他对象一样,使用setOnClickListener(new Button.OnClickListener() { // do stuff }... 就可以了呢?
总之,我的小部件出现在屏幕上,标签也正确,但当我点击小部件时,没有任何反应。我在所有认为会执行某些操作的地方设置了断点,但仍然没有执行任何操作。
问题1:小部件被点击后执行哪些代码?
我的小部件在被点击时实际上并不会更新,只会在我的程序的其他部分中执行一些代码。它只是执行一些网络HTTP和/或套接字服务器命令。此外,在将它放置在桌面之前,我的小部件被配置了一个活动。
以下是清单文件:
这里是小部件配置器活动。
这是我的小部件提供程序。
当我添加并移除小部件时,不同的意图会传递到onReceive中,所以这是有效的,但是当点击事件发生时没有任何反应。
问题2:有人能否友好地指出我做错了什么?我基本上按照这里的教程进行操作:http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/appwidget/ExampleAppWidgetProvider.html 问题3:看起来我可以在小部件的布局xml中放置一个android:onclick="WidgetClicked",但我无法弄清楚在哪里放置WidgetClicked方法。 WidgetProvider似乎是合乎逻辑的,但对我也没有用。是否有一种方法在xml中实现这个功能?
免责声明:以上代码是经过一天半的疑难解答后的当前状态。这只是许多不同尝试的一个迭代。
总之,我的小部件出现在屏幕上,标签也正确,但当我点击小部件时,没有任何反应。我在所有认为会执行某些操作的地方设置了断点,但仍然没有执行任何操作。
问题1:小部件被点击后执行哪些代码?
我的小部件在被点击时实际上并不会更新,只会在我的程序的其他部分中执行一些代码。它只是执行一些网络HTTP和/或套接字服务器命令。此外,在将它放置在桌面之前,我的小部件被配置了一个活动。
以下是清单文件:
<receiver android:name="PhcaAppWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.skipmorrow.phca.PhcaAppWidgetProvider.WIDGET_CLICKED" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/phca_widget_info" />
</receiver>
这里是小部件配置器活动。
private Activity act;
private static ListView listView;
private static ArrayAdapter<String> adapter;
private ArrayList<String> actionList;
private final String widgetPageName = "_widget";
int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
private static final String PREFS_NAME = "PHCA";
private static final String PREF_PREFIX_KEY = "prefix_";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("Choose an action for this widget");
actionList = GetActionList();
if (!actionList.isEmpty()) {
listView = getListView();
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, actionList);
setListAdapter(adapter);
}
else {
// no objects on the widget page
}
// Find the widget id from the intent.
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
// If they gave us an intent without the widget id, just bail.
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
}
}
private ArrayList<String> GetActionList() {
ArrayList<String> l = new ArrayList<String>();
Page p = CommonActivity.GetPageNamed(getApplicationContext(), widgetPageName);
if (p!=null) {
if (p.pageObjects.size()==0) DisplayEmptyPageHelpDialog();
for (int i = 0; i < p.pageObjects.size(); i++) {
l.add(p.pageObjects.get(i).GetParsedMajorLabel(getApplicationContext()).toString());
}
}
else {
CreateWidgetPage();
DisplayEmptyPageHelpDialog();
}
return l;
}
private void CreateWidgetPage() {
Page widgetPage = new Page(getApplicationContext());
widgetPage.setPageName(widgetPageName);
widgetPage.SetPageType("list");
widgetPage.setNote("Widget Page");
widgetPage.setPageTitle("Widget Page");
widgetPage.setImageFilename("");
widgetPage.setTransparentImageOverlayFilename("");
widgetPage.InsertInstanceIntoDatabase(getApplicationContext());
}
private void DisplayEmptyPageHelpDialog() {
Dialog helpDialog = new Dialog(this);
helpDialog.setContentView(R.layout.phca_help_dialog);
helpDialog.setTitle("PHCA Widget");
TextView helpText = (TextView) helpDialog.findViewById(R.id.tvHelpText);
helpText.setText("Your _widget page is empty. Please add an action to the _widget page so it can be used in a widget.");
TextView subTitle = (TextView) helpDialog.findViewById(R.id.tvSubject);
subTitle.setText("PHCA Widget configurator");
helpDialog.show();
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
SharedPreferences.Editor prefs = getSharedPreferences(PREFS_NAME, 0).edit();
prefs.putInt(PREF_PREFIX_KEY + mAppWidgetId, position);
prefs.commit();
// Push widget update to surface with newly set prefix
String majorLabel = CommonActivity.GetPageObjectAtIndex(getApplicationContext(), widgetPageName, position).GetParsedMajorLabel(getApplicationContext()).toString();
String minorLabel = CommonActivity.GetPageObjectAtIndex(getApplicationContext(), widgetPageName, position).GetParsedMinorLabel(getApplicationContext()).toString();
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
PhcaAppWidgetProvider.updateAppWidget(getApplicationContext(), appWidgetManager,
mAppWidgetId, majorLabel, minorLabel);
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
这是我的小部件提供程序。
public class PhcaAppWidgetProvider extends AppWidgetProvider {
private static final String ACTION_CLICK = "WIDGET_CLICKED";
private final String widgetPageName = "_widget";
private static final String PREFS_NAME = "PHCA";
private static final String PREF_PREFIX_KEY = "prefix_";
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// Get all ids
ComponentName thisWidget = new ComponentName(context,
PhcaAppWidgetProvider.class);
//int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
final int N = appWidgetIds.length;
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
SharedPreferences myPrefs = context.getSharedPreferences(PREFS_NAME, context.MODE_WORLD_WRITEABLE);
Integer objNum = myPrefs.getInt(PREF_PREFIX_KEY + appWidgetId, -1);
if (objNum > -1) {
PageAction pa = (PageAction) CommonActivity.GetPageObjectAtIndex(context, widgetPageName, objNum);
String majorLabel = pa.GetUnparsedMajorLabel(context).toString();
String minorLabel = pa.GetUnparsedMinorLabel(context).toString();
updateAppWidget(context, appWidgetManager, appWidgetId, majorLabel, minorLabel);
}
}
}
@Override
public void onEnabled(Context context) {
Log.d("Widget", "onEnabled");
}
@Override
public void onReceive(Context context, Intent intent) {
String intentAction = intent.getAction();
updateWidgetState(context, intentAction);
if (intentAction.equals(ACTION_CLICK)) {
Bundle extras = intent.getExtras();
Integer appWidgetId = extras.getInt("appwidgetid");
SharedPreferences myPrefs = context.getSharedPreferences(PREFS_NAME, context.MODE_WORLD_WRITEABLE);
Integer objNum = myPrefs.getInt(PREF_PREFIX_KEY + appWidgetId, -1);
if (objNum > -1) {
PageAction pa = (PageAction) CommonActivity.GetPageObjectAtIndex(context, widgetPageName, objNum);
pa.ExecuteActionFromWidgetClick(context);
}
} else {
super.onReceive(context, intent);
}
}
public static void updateWidgetState(Context paramContext, String paramString)
{
RemoteViews localRemoteViews = buildUpdate(paramContext, paramString);
ComponentName localComponentName = new ComponentName(paramContext, PhcaAppWidgetProvider.class);
AppWidgetManager.getInstance(paramContext).updateAppWidget(localComponentName, localRemoteViews);
}
private static RemoteViews buildUpdate(Context ctx, String paramString)
{
RemoteViews views = new RemoteViews(ctx.getPackageName(), R.layout.phca_appwidget);
views.setTextViewText(R.id.majorlabel, "majorLabel");
views.setTextViewText(R.id.minorlabel, "minorLabel");
Intent intent = new Intent(ctx, PhcaAppWidgetProvider.class);
intent.setAction(ACTION_CLICK);
intent.putExtra("appwidgetid", 0);
PendingIntent pendingIntent = PendingIntent.getBroadcast(ctx, 0, intent , 0);
views.setOnClickPendingIntent(R.layout.phca_appwidget, pendingIntent);
if(paramString.equals(ACTION_CLICK))
{
Toast.makeText(ctx, "ACTION_CLICK", Toast.LENGTH_LONG).show();
}
return views;
}
}
当我添加并移除小部件时,不同的意图会传递到onReceive中,所以这是有效的,但是当点击事件发生时没有任何反应。
问题2:有人能否友好地指出我做错了什么?我基本上按照这里的教程进行操作:http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/appwidget/ExampleAppWidgetProvider.html 问题3:看起来我可以在小部件的布局xml中放置一个android:onclick="WidgetClicked",但我无法弄清楚在哪里放置WidgetClicked方法。 WidgetProvider似乎是合乎逻辑的,但对我也没有用。是否有一种方法在xml中实现这个功能?
免责声明:以上代码是经过一天半的疑难解答后的当前状态。这只是许多不同尝试的一个迭代。