我一直试图找出这个问题多年,并尝试了至少10个堆栈溢出的解决方案,但没有成功。
我创建了一个Widget类,在主屏幕上显示一些每5分钟更新一次的数字。 Widget是一个按钮,当用户点击它时,会加载配置活动,以便更新小部件。
第一次创建窗口小部件时,会打开配置活动,用户可以在文本框中键入内容。配置完成后,窗口小部件会更新 - 全部按预期工作。但是,按下该按钮时,配置活动不会再次启动。奇怪的是,当我通过android studio运行应用程序或重新启动手机时,可以启动活动。我认为它与它有关,因为某些原因没有更新按钮按下,但我找不到在哪里修复它。
我已经看到了几个与我的问题有关的类似问题并尝试了他们的解决方案,但它根本不起作用。我是android编程的新手,所以我可能忽略了一些东西。我已经硬编码了一些非常糟糕的变量需要改变,但我认为这不会影响活动的启动。
这是我的WidgetProvider,配置活动类和清单。
LPWidget.java
public class LPWidget extends AppWidgetProvider {
private static final String LOG_TAG = "ExampleWidget";
static int nowLP = LPWidgetConfigureActivity.currentLP ;
static int maxNowLP = LPWidgetConfigureActivity.maxLP;
static boolean notfirstTime = false;
/**
* Custom Intent name that is used by the AlarmManager to tell us to update the clock once per second.
*/
public static String CLOCK_WIDGET_UPDATE = "doingitnow.simplelptracker.CLOCK_WIDGET_UPDATE";
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (CLOCK_WIDGET_UPDATE.equals(intent.getAction())) {
Log.d(LOG_TAG, "Clock update");
// Get the widget manager and ids for this widget provider, then call the shared
// clock update method.
ComponentName thisAppWidget = new ComponentName(context.getPackageName(), getClass().getName());
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int ids[] = appWidgetManager.getAppWidgetIds(thisAppWidget);
for (int appWidgetID: ids) {
updateAppWidget(context, appWidgetManager, appWidgetID);
}
}
}
private PendingIntent createClockTickIntent(Context context) {
Intent intent = new Intent(CLOCK_WIDGET_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
Log.d(LOG_TAG, "Widget Provider disabled. Turning off timer");
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(createClockTickIntent(context));
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
Log.d(LOG_TAG, "Widget Provider enabled. Starting timer to update widget every second");
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), 10000, createClockTickIntent(context));
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
Log.d(LOG_TAG, "Updating Example Widgets.");
// Perform this loop procedure for each App Widget that belongs to this
// provider
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.lpwidget);
Intent configIntent = new Intent(context, LPWidgetConfigureActivity.class);
configIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
configIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
configIntent.setData(Uri.parse(configIntent.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, configIntent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.button, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
// Update The clock label using a shared method
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
if (notfirstTime) { //if it is not the first time, update
if (nowLP < maxNowLP) { //if the nowLP less than the max, add one.
nowLP = nowLP + 1;
}
}
notfirstTime = true;
String StringNowLP = "LP: " + Integer.toString(nowLP) + "/" + Integer.toString(maxNowLP);
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.lpwidget);
updateViews.setTextViewText(R.id.button, StringNowLP);
appWidgetManager.updateAppWidget(appWidgetId, updateViews);
}
LPWidgetConfigureActivity.java
public class LPWidgetConfigureActivity extends Activity {
static int currentLP = 20;
static int maxLP = 50;
int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
public LPWidgetConfigureActivity() {
super();
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Set the result to CANCELED. This will cause the widget host to cancel
// out of the widget placement if the user presses the back button.
setResult(RESULT_CANCELED);
setContentView(R.layout.lpwidget_configure);
// 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 this activity was started with an intent without an app widget ID, finish with an error.
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
}
final EditText currentLPText = (EditText) findViewById(R.id.currentLPText);
final EditText MaxLPText = (EditText) findViewById(R.id.MaxLPText);
Button applyButton = (Button) findViewById(R.id.add_button);
applyButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = LPWidgetConfigureActivity.this;
try { //No empty text - update all
String intcurrentLP = currentLPText.getText().toString();
String intMaxLP = MaxLPText.getText().toString();
currentLP = Integer.parseInt(intcurrentLP);
maxLP = Integer.parseInt(intMaxLP);
LPWidget.nowLP = currentLP;
LPWidget.maxNowLP = maxLP;
} catch (NumberFormatException e) {
try { //Empty currentLP text - update MaxLP
String intMaxLP = MaxLPText.getText().toString();
maxLP = Integer.parseInt(intMaxLP);
LPWidget.maxNowLP = maxLP;
Context toastcontext = getApplicationContext();
CharSequence text = "Max LP is updated only";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(toastcontext, text, duration);
toast.show();
} catch (NumberFormatException e1) {
try { //empty MaxLP text - update currentLP
String intcurrentLP = currentLPText.getText().toString();
currentLP = Integer.parseInt(intcurrentLP);
LPWidget.nowLP = currentLP;
Context toastcontext = getApplicationContext();
CharSequence text = "Current LP is updated only";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(toastcontext, text, duration);
toast.show();
} catch (NumberFormatException e2) { //All empty text - No changes
Context toastcontext = getApplicationContext();
CharSequence text = "No Text Inputted - No Changes done";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(toastcontext, text, duration);
toast.show();
}
}
}
LPWidget.notfirstTime = false;
// It is the responsibility of the configuration activity to update the app widget
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
LPWidget.updateAppWidget(context, appWidgetManager, mAppWidgetId);
// Make sure we pass back the original appWidgetId
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
});
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="doingitnow.simplelptracker" >
<application
android:allowBackup="true"
android:label="@string/app_name"
android:theme="@android:style/Theme.WallpaperSettings" >
<activity
android:name=".LPMainPage"
android:label="@string/title_activity_lpmain_page"
android:theme="@android:style/Theme.WallpaperSettings" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".LPWidgetConfigureActivity"
android:theme="@android:style/Theme.WallpaperSettings" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<receiver android:name=".LPWidget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="doingitnow.simplelptracker.CLOCK_WIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/lpwidget_info" />
</receiver>
<activity
android:name=".LPUpdateActivity"
android:label="@string/title_activity_lpupdate"
android:theme="@android:style/Theme.WallpaperSettings">
<intent-filter>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
答案 0 :(得分:0)
经过多次痛苦之后,我设法弄清楚为什么配置活动从未运行过。
首先,calendar.add(Calendar.SECOND, 10);
表示一旦设置了警报,它会等待10秒钟,直到警报被触发。这意味着如果我在10秒之前完成配置活动,它将不会触发警报和更新,直到10秒钟结束。如果活动在警报后10秒完成,则活动将正常工作。
然而,当配置活动更新时,窗口小部件LPWidget.updateAppWidget(context, appWidgetManager, mAppWidgetId);
只会更新屏幕上的内容,而不会创建按钮的远程视图,因为它位于onUpdate()
功能中。由于我将信息提供程序中的updateperiodmillis
设置为0,因此该函数永远不会更新,因此远程视图将在警报更新后启动。此外,制作了两个远程视图,这会导致更多的混淆,因此合并我拥有的两个远程视图并将其放在updateAppWidget(context, appWidgetManager, mAppWidgetId);
中意味着可以按下按钮并在屏幕上更新小部件。