2011-01-13 53 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>