Запустите Activity from preferences.xml и получите результат в onActivityResult
Это дополнение к этому вопросу.
Я могу запустить Activity, но мне также нужно получить результат. Как это сделать?
Я попробовал переопределить onActivityResult на моем PreferencesActivity безрезультатно.
Мне не хватает некоторых дополнительных свойств в файле preferences.xml?
Ответы
Ответ 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 о настройках.
Надеюсь, что это поможет.