2011-01-13 96 views
3

我有一個具有配置活動的Android小部件。我還在窗口小部件上設置了一個ImageView「按鈕」來啓動配置活動,以防用戶想要在初始化後更改其偏好設置。Android:Widget配置活動兩次啓動?

所以,基本的生命週期:

  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和在Widget.java中的updateDisplayState方法

任何幫助都會很棒!謝謝!

回答

4

當調用顯式意圖時,應該考慮使用FLAG_ACTIVITY_CLEAR_TOP之類的意圖標誌之一來保持堆棧的組織。例如:

configIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 

可以發現缺少這個標誌像IMDB應用,在那裏的Home按鍵每次點擊增加了棧上的家庭活動的另一個實例,一些應用程序,所以你需要點擊返回按鈕多次彈出堆棧並退出應用程序。 :)

0

添加到清單文件中的android活動:noHistory = 「真」 和android: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>