Android: Widget Config activity running twice?

I have an Android widget with configuration activity. I also have an ImageView "button" installed in widgets to start configuration activity, in case the user wants to change their settings after they are initialized.

So, the basic life cycle:

  • User Adds Widget
  • Configure activity pops up, user fills in the fields and clicks "Submit"
  • Widget added to screen
  • A user picks up an ImageView to start configuration activity.
  • Configure activity pops up, user edits fields
  • After clicking "Submit" or return, the widget is updated
  • The user can continue to perform steps 5 and 6 as necessary.

My problem is at step 5. The very first and only the first click on the ImageView looks like it starts two configuration actions. That is, when I return from the first, there is another “behind”. However, in all subsequent runs of configure activity, only one runs, and everything works fine.

What could be the problem? I will post the appropriate code below.

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-Provider 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 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);
}

I think these are the most relevant sections. The places that I will look at next are in ConfigActivity.java in submitListener and in the updateDisplayState method in Widget.java

Any help would be awesome! Thank!

+3
source share
2 answers

, FLAG_ACTIVITY_CLEAR_TOP, . :

configIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

, IMDB-, "" , "" , .:)

+4

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

Source: https://habr.com/ru/post/1785217/


All Articles