Запустите Activity из файлаferences.xml и получите результат в onActivityResult. - PullRequest
17 голосов
/ 03 марта 2012

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

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

Я попытался переопределить onActivityResult для моих настроек PreferencesActivity, но безрезультатно.

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

Ответы [ 4 ]

17 голосов
/ 31 декабря 2012

Самое чистое решение, которое я знаю, - это прослушать щелчок по предпочтению и запустить намерение явно.Таким образом, 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;
  }
});
14 голосов
/ 01 января 2013

Попробуйте переопределить 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 голосов
/ 31 марта 2012

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

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

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

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

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

EDIT

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

В вашей основной деятельности: запустите действие предпочтений и приложите данные

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

1 голос
/ 06 января 2013

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

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

Но, возможно, есть другой подход, который может работать для вас.Как я вижу из вашего справочного вопроса, вы запускаете действие через намерение.Если это действие предназначено для редактирования настроек, то это НЕ правильный подход, так как Android использует это намерение только для запуска действия и ничего более.На мой взгляд, лучше создать свою конкретную активность предпочтений, расширив любую из доступных, чтобы настроить ее.Вот моя настраиваемая 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>

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

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

...