Запустите Activity from preferences.xml и получите результат в onActivityResult - программирование
Подтвердить что ты не робот

Запустите Activity from preferences.xml и получите результат в onActivityResult

Это дополнение к этому вопросу.

Я могу запустить Activity, но мне также нужно получить результат. Как это сделать?

Я попробовал переопределить onActivityResult на моем PreferencesActivity безрезультатно.

Мне не хватает некоторых дополнительных свойств в файле preferences.xml?

4b9b3361

Ответ 1

Самое чистое решение, о котором я знаю, - это прослушать щелчок по предпочтению и явно запустить намерение. Этот способ onActivityResult будет вызываться как обычно.

Предполагая, что ваше намерение-предпочтение определено в XML, вы можете прикрепить к нему слушателя (здесь 1234 - код запроса для onActivityResult):

Preference pref = (Preference) findPreference("prefKey");
pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
  @Override
  public boolean onPreferenceClick(Preference preference) {
    startActivityForResult(preference.getIntent(), 1234);
    return true;
  }
});

Ответ 2

Попробуйте переопределить startActivity() в вашем классе PreferencesActivity и заставить его вызывать startActivityForResult() вместо этого после проверки того, что намерение - это то, что нас интересует, похожее на следующее (с кодом 1234 в качестве кода запроса):

public class PreferencesActivity {
    // ...

    @Override
    public void startActivity(Intent intent) {
        if (thisIsTheExpected(intent)) {
            super.startActivityForResult(intent, 1234);
        } else {
            super.startActivity(intent);
        }
    }

    @Override
    protected void onActivityResult(int reqCode, int resCode, Intent data) {
        if (reqCode == 1234) {
            // should be getting called now
        }
    }

    // ...
}

В зависимости от ваших потребностей это может быть проще по сравнению с добавлением нескольких OnPreferenceClickListener в ваш код:)

Ответ 3

Если вы хотите передать данные из активности предпочтений в свою основную деятельность, используйте этот код:

В вашем основном классе активности (запуск):

startActivityForResult(new Intent(main.this, preferences.class), 0);

В вашем классе активности предпочтений (установите результат):

Intent i;
i.putStringExtra("name", "tom");
setResult(RESULT_OK, i);
finish();

В вашем основном классе активности (получите результат):

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 0) {
        if (resultCode == RESULT_OK){
            Log.d("test", data.getExtraString("name");
        }
    }
}

Вы можете разместить столько дополнительных функций, сколько хотите, и не только строки, но и все стандартные типы данных.

Надеюсь, я все сделал правильно;)

ИЗМЕНИТЬ

Как сказал мне Каарель, я, вероятно, пропустил этот вопрос. Вот как вы можете получать данные из основной активности в активности предпочтений:

В вашем основном действии: запустите действие настроек и прикрепите данные

String foo = "hello";
Intent i = new Intent();
i.putExtra("testString", foo);//You can also add other types of variables here, see [1] for reference
i.setClass(main.this, preferences.class);
startActivity(i);

В вашей настройке: получите данные, привязанные к намерению

Bundle b = this.getIntent().getExtras();//[2]
if (b!=null){
    String recievedString = b.getString("testString");
    //The recievedString variable contains the String "hello" now, see [3]
}

[1] https://developer.android.com/reference/android/content/Intent.html

[2] https://developer.android.com/reference/android/content/Intent.html#getExtras%28%29

[3] https://developer.android.com/reference/android/os/Bundle.html

Ответ 4

Если вы посмотрите на PreferenceActivity.java в исходном коде платформы здесь в строке 1000 вы увидите, что ваше намерение вызывается через startActivity startActivity(header.intent); а не через startActivityForResult, поэтому я не думаю, что это возможно.

Однако вы можете попытаться переопределить функцию onHeaderClick вместе с onActivityResult функции PreferenceActivity и посмотреть, что произойдет. Я сам не пробовал, поэтому не знаю, и есть хорошие шансы, что этот подход будет нарушен в будущих версиях.

Но может быть, есть и другой подход, который мог бы сработать для вас. Как я вижу из вашего справочного вопроса, вы запускаете деятельность с помощью намерения. Если это действие предназначено для редактирования настроек, это НЕ правильный подход, так как андроид использует это намерение только для запуска активности и не более того. На мой взгляд, лучше создать свою специфическую активность предпочтений, расширив любой из доступных, чтобы настроить его. Вот мой настраиваемый ListPreference, который я использую, чтобы пользователь мог выбрать приложение:

public class CustomSelectAppPreference extends ListPreference {

//----- Constructor -----
public CustomSelectAppPreference(Context context, AttributeSet attrs) {
    super(context, attrs);
}
//----- Constructor END -----



//----- Public Code -----
public void SetResult(String packageName) {
    if(this.callChangeListener(packageName)) {
        Editor edit = this.getSharedPreferences().edit();
        edit.putString(this.getKey(), packageName);
        edit.commit();
    }

    this.getDialog().dismiss();
}
//----- Public Code END -----



//----- ListPreference Overrides -----
@Override
protected void onPrepareDialogBuilder(Builder builder) {
    Log.d("CustomSelectAppPreference", "onPrepareDialogBuilder");

    super.onPrepareDialogBuilder(builder);

    String selectedPackage = this.getSharedPreferences().getString(this.getKey(), "");

    ListAdapter listAdapter = (ListAdapter) new ApplicationsArrayAdapter(this.getContext(), Utilities.getInstalledApplications(this.getContext(), selectedPackage), this);

    builder.setAdapter(listAdapter, this);
}   
//----- ListPreference Overrides END -----
} 

И я использую его в моих предпочтениях .xml вот так:

<PreferenceScreen android:key="connection_screen"
        android:title="@string/wpref_Connection_Screen_title"
        android:summary="@string/wpref_Connection_Screen_summary"
        android:shouldDisableView="true">

    <com.test.app.CustomSelectAppPreference android:key="userSelectedApplication"
            android:title="@string/wpref_userSelectedApplication_title"
            android:summary="@string/wpref_userSelectedApplication_summary"
            android:dialogTitle="@string/userselectedApplication_dialogTitle"
            android:entries="@array/selectedapps_dummy_actions"
            android:entryValues="@array/selectedapps_dummy_actionsvalues"           
            android:defaultValue=""
            android:shouldDisableView="true"/>
</PreferenceScreen>

Используя этот подход, я могу контролировать все, что делает мой пользователь в этой деятельности, не нарушая правила Android о настройках.

Надеюсь, что это поможет.