2011-01-13 74 views
3

私は構成アクティビティを持つAndroidウィジェットを持っています。また、ユーザが初期化した後に設定を変更したい場合に備えて、ウィジェットにImageViewの "button"を設定してconfigureアクティビティを起動させることもできます。Android:ウィジェット設定のアクティビティ起動が2回になる?

ので、基本的なライフサイクル:

  1. ユーザーが
  2. 設定アクティビティがポップアップウィジェットを追加し、ユーザーがフィールドに入力し、クリック
  3. ユーザーがタップ
  4. ウィジェットが画面に追加された「送信」 ImageViewで設定アクティビティを開始する
  5. アクティビティの設定、ユーザの編集フィールド
  6. 「送信」またはバックアウトすると、ウィジェットは更新されます
  7. ユーザーは必要に応じてステップ5と6を続行できます。

私の問題は、ステップ5で2つのconfigure活動が起動されているように、ユーザがImageViewのをタップすること非常に最初のみ初めて、それが見えます。つまり、私が最初のものから脱却するとき、もう1つはそれの後ろにあります。その後のconfigureアクティビティの起動時には、1つだけが起動され、すべてがうまくいきます。

何が問題なのですか?以下に関連するコードを掲載します。

の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-プロバイダ

<?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> 

widget.xml 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); 
} 

私は、これらが最も関連性の高い部分であると思います。私がさらに検討しているところは、submitListenerのConfigActivity.javaとWidget.javaのupdateDisplayStateメソッドです。

何か助けが素晴らしいです!ありがとう!

答えて

4

明示的なインテントを呼び出すときは、FLAG_ACTIVITY_CLEAR_TOPのようなインテントフラグの1つを使用してスタックを整理しておくことを検討する必要があります。たとえば:

configIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 

あなたは、ホームボタンの各クリックは、スタック上の家の活動の別のインスタンスを追加しIMDBアプリのようないくつかのアプリでは、このフラグの欠如を見つけることができますので、あなたがクリックする必要があります[戻る]ボタンを何回か押して、スタックをポップしてアプリを終了します。 :)

0

マニフェストファイルのandroidのアクティビティに追加します。noHistory = "true" をとAndroid:excludeFromRecentsは= "true" を

それが問題

<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> 
に解決すると仮定
関連する問題