Updating a preference summary in Android when the user sets it

Since you are manually changing the setting outside of the Preference itself, you cannot do this with a SummaryProvider. Instead, you must manually change the summary both (1) when the summary first appears and (2) when you manually change the preference value and commit it. (You could use an OnSharedPreferenceChangeListener to do the second step automatically, but that's more complicated.)

So, create a function that updates its summary and call it in both places: in onCreatePreferences and in onActivityResult where you are setting the value.

By the way you can use preferences.edit { ... } extension function instead of with(preferences.edit) { ... ; apply() } for simpler code.

class SettingsFragment : PreferenceFragmentCompat() {

    private val TARGET_DIR_KEY = "export_dir"
    private val prefs by lazy { preferenceManager.sharedPreferences }
    private val targetDirPreference: Preference by lazy {
        findPreference<Preference>(TARGET_DIR_KEY) ?: error("Missing target directory preference!")
    }

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.root_preferences, rootKey)

        targetDirPreference.setOnPreferenceClickListener {
            val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
            startActivityForResult(intent, REQUEST_TARGET_FOLDER)
            true
        }

        updateTargetDirPreferenceSummary()
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
        super.onActivityResult(requestCode, resultCode, intent)
        // from: https://stackoverflow.com/questions/34331956/trying-to-takepersistableuripermission-fails-for-custom-documentsprovider-via
        if (requestCode == REQUEST_TARGET_FOLDER && resultCode == RESULT_OK && intent != null) {
            val treeUri = intent.data
            if (treeUri != null) {
                // do stuff
            }
            prefs.edit {
                putString(TARGET_DIR_KEY, intent.data.toString())
            }
            updateTargetDirPreferenceSummary()
        }
    }

    private fun updateTargetDirPreferenceSummary() {
        targetDirPreference.summary = prefs.getString("feedback", "")
    }
}

OR, if you want to solve this in a way that provides cleaner code in your Fragment, you can create a subclass of Preference that helps manage the changing of the setting value and internally uses a SummaryProvider mechanism to automatically update itself.

class ManualStringPreference @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null
): Preference(context, attrs) {

    init {
        setSummaryProvider { getPersistedString("") }
    }

    var value: String = ""
        set(inValue) {
            if (inValue != field) {
                field = inValue
                persistString(inValue)
                notifyChanged()
            }
        }

    override fun onSetInitialValue(defaultValue: Any?) {
        value = getPersistedString(defaultValue as? String ?: "")
    }

}

You need to set this as your preference type in your XML.

Then your Fragment looks like this. Notice that you change the SharedPreferences value through the Preference subclass you created.

class SettingsFragment : PreferenceFragmentCompat() {

    private val prefs by lazy { preferenceManager.sharedPreferences }
    private val targetDirPreference: ManualStringPreference by lazy {
        findPreference<ManualStringPreference>("export_dir") ?: error("Missing target directory preference!")
    }

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.root_preferences, rootKey)

        targetDirPreference.setOnPreferenceClickListener {
            val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
            startActivityForResult(intent, REQUEST_TARGET_FOLDER)
            true
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
        super.onActivityResult(requestCode, resultCode, intent)
        // from: https://stackoverflow.com/questions/34331956/trying-to-takepersistableuripermission-fails-for-custom-documentsprovider-via
        if (requestCode == REQUEST_TARGET_FOLDER && resultCode == RESULT_OK && intent != null) {
            val treeUri = intent.data
            if (treeUri != null) {
                // do stuff
            }
            targetDirPreference.value = intent.data.toString()
        }
    }

}