2011-01-13 4 views
3

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

Таким образом, основной жизненный цикл:

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

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

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

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

Любая помощь была бы потрясающей! Благодаря!

ответ

4

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

configIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 

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

0

добавить к деятельности в файле манифеста Android: noHistory = "истинный" и андроид: excludeFromRecents = "истинный"

это предполагают, чтобы решить проблему

<activity 
    android:name=".ConfigActivity" 
    android:label="@string/app_name" 
    android:noHistory="true" 
    android:excludeFromRecents="true"> 
    <intent-filter> 
     <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /> 
    </intent-filter> 
</activity> 
Смежные вопросы