Android: запуск конфигурации Widget дважды? - PullRequest
3 голосов
/ 13 января 2011

У меня есть виджет Android, который выполняет действия по настройке. У меня также есть «кнопка» ImageView, настроенная на виджете для запуска действия настройки, на случай, если пользователь захочет изменить свои предпочтения после их инициализации.

Итак, основной жизненный цикл:

  1. Пользователь добавляет виджет
  2. Настраивается активность, пользователь заполняет поля и нажимает «Отправить»
  3. Виджет добавлен на экран
  4. Пользователь касается ImageView, чтобы запустить операцию настройки
  5. Настройка всплывающих окон, пользователь редактирует поля
  6. После нажатия кнопки «Отправить» или возврата назад виджет обновляется
  7. Пользователь может продолжить при необходимости выполнять шаги 5 и 6.

Моя проблема на шаге 5. самые первые и только в первый раз, когда пользователь касается ImageView, похоже, что запускаются два действия по настройке. То есть, когда я возвращаюсь к первому, есть еще один "позади" этого. Однако при всех последующих запусках действия по настройке запускается только один, и все прекрасно работает.

В чем может быть проблема? Я выложу соответствующий код ниже.

AndroidManifest.xml

    <activity
        android:name=".ConfigActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
        </intent-filter>
    </activity>
    <receiver
        android:name=".Widget"
        android:label="Widget" >
        <intent-filter>
            <action
                android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <intent-filter>
            <action
                android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <data android:scheme="sample_widget" />
        </intent-filter>
        <intent-filter>
            <action
                android:name="com.this.that.WIDGET_CONTROL" />
            <data
                android:scheme="sample_widget" />
        </intent-filter>
        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/widget" />
    </receiver>

AppWidget-провайдер widget.xml

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:updatePeriodMillis="5000"
    android:minWidth="294dp"
    android:minHeight="220dp"
    android:initialLayout="@layout/widgetlayout"
    android:configure="com.this.that.ConfigActivity" >
</appwidget-provider>

ConfigActivity.java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Get the data we were launched with
    Intent launchIntent = getIntent();
    Bundle extras = launchIntent.getExtras();
    if (extras != null) {
        appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);

        Intent cancelResultValue = new Intent();
        cancelResultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        setResult(RESULT_CANCELED, cancelResultValue);
    } else {
        // Only launch if it's for configuration
        finish();
    }

    setContentView(R.layout.myconfig);

    // Create Buttons/EditTexts
    SubmitBTN = (Button) findViewById(R.id.BTNSubmit);
    SampleET= (EditText) findViewById(R.id.ETSample);
    SubmitBTN.setOnClickListener(submitListener);

    loadPreferences(ConfigActivity.this, appWidgetId);
}

private OnClickListener submitListener = new OnClickListener() {
    public void onClick(View v) {
        final Context context = PriorityViewConfig.this;

        // Save strings in our prefs
        String sample = SampleET.getText().toString();
        SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
        prefs.putString(PREF_PREFIX_KEY + appWidgetId + "sample", sample);
        prefs.commit();

        if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
            // Tell the AppWidgetManager that we're now configured
            Intent resultValue = new Intent();
            //resultValue.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
            resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
            setResult(RESULT_OK, resultValue);

            // Get an instance of the AppWidgetManager
            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);

            // Update the App Widget with the layout
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widgetlayout);
            Widget.updateDisplayState(context, appWidgetId);
        }

        // Activity is now done
        finish();
    }
};

private void loadPreferences(Context context, int appWidgetId) {
    SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
    String sample = prefs.getString(PREF_PREFIX_KEY + appWidgetId + "sample", null);

    if (sample != null) {
        SampleET.setText(sample);
    } else {
        // Nothing stored, don't need to do anything
    }
}

Widget.java

@Override
public void onReceive(Context context, Intent intent) {
    final String action = intent.getAction();
    Log.d(LOG_TAG, "OnReceive:Action: " + action);

    if (ACTION_WIDGET_CONTROL.equals(action)) {
        // Pass this on to the action handler where we'll figure out what to do and update the widget
        final int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
        if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
            this.onHandleAction(context, appWidgetId, intent.getData());
        }           
    }
    super.onReceive(context, intent);
}

public static void updateDisplayState(Context context, int appWidgetId) {
    Intent configIntent = new Intent(context, ConfigActivity.class);
    configIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    // Make this unique for this appWidgetId
    configIntent.setData(Uri.withAppendedPath(Uri.parse(Widget.URI_SCHEME + "://widget/id/"), String.valueOf(appWidgetId)));
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, configIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    views.setOnClickPendingIntent(R.id.IVConfig, pendingIntent);

    AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId, views);
}

private void onHandleAction(Context context, int appWidgetId, Uri data) {
    String controlType = data.getFragment();        
    // Nothing here yet
    updateDisplayState(context, appWidgetId);
}

Я думаю, что это самые важные разделы. Места, которые я собираюсь изучить, находятся в ConfigActivity.java в submitListener и в методе updateDisplayState в Widget.java

Любая помощь будет потрясающей! Спасибо!

Ответы [ 2 ]

4 голосов
/ 28 июня 2011

При вызове явного намерения вы должны рассмотреть возможность использования одного из флагов намерения, таких как FLAG_ACTIVITY_CLEAR_TOP, чтобы сохранить стек организованным. Например:

configIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

Вы можете заметить отсутствие этого флага в некоторых приложениях, таких как приложение IMDB, где каждый щелчок по кнопке «Домой» добавляет еще один экземпляр домашней активности в стек, поэтому вам нужно нажимать кнопку «Назад» столько раз пролистать стек и выйти из приложения. :)

0 голосов
/ 13 июля 2012

добавить к активности в файле манифеста.

...