Inicie Actividad desde preferences.xml y obtenga el resultado en onActivityResult
Es un complemento a esta pregunta .
Puedo lanzar la Actividad pero también necesito ser capaz de obtener el resultado. ¿Cómo lo hago?
- PreferenceScreen personalizado con botones pulsables
- TimePicker en PreferenceScreen
- Android: Fragmento de preferencia con un fragmento de cajón de navegación
- Android - ¿Cómo cambiar los textos en la actividad de preferencias dinámicamente?
- Single page PreferenceActivity w / sin encabezados / fragmentos?
Intenté sobreescribir onActivityResult en mi PreferencesActivity sin éxito.
¿Me faltan algunas propiedades adicionales en preferences.xml?
- Cómo crear una preferencia que acepte sólo valores enteros
- Qué es diferente entre OnPreferenceChangeListener y OnSharedPreferenceChangeListener
- Extraño error utilizando onCreateView en PreferenceFragment al llamar addPreferencesFromResource de onCreate
- Android switchpreference ¿cómo puedo configurar el valor predeterminado de la preferencia de conmutador?
- No hay campo estático list_container de tipo I en la clase Landroid / support / v7 / preference / R $ id
- FindViewById devuelve nulo para el diseño de preferencias
- Mi var pública es invisible a su primo
- Preferencia y comprobación de la casilla de verificación si está activada o desactivada
La solución más limpia que conozco es escuchar el clic en la preferencia y lanzar la intención explícitamente. De esta manera onActivityResult
se llamará como de costumbre.
Suponiendo que su preferencia de intención está definida en XML, puede adjuntarle un oyente de este modo (donde 1234
es un código de solicitud para onActivityResult
):
Preference pref = (Preference) findPreference("prefKey"); pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { startActivityForResult(preference.getIntent(), 1234); return true; } });
Trate de reemplazar startActivity()
en su clase PreferencesActivity y haga que llame a startActivityForResult()
después de comprobar que la intención es la que nos interesa, similar a la siguiente (con 1234 como código de solicitud):
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 } } // ... }
Dependiendo de sus necesidades, esto podría ser más simple en comparación con la adición de varios OnPreferenceClickListener
en su código 🙂
Si desea pasar datos de la actividad de preferencia a su actividad principal, utilice este código:
En su clase de actividad principal (lanzamiento):
startActivityForResult(new Intent(main.this, preferences.class), 0);
En su clase de actividad preferida (defina el resultado):
Intent i; i.putStringExtra("name", "tom"); setResult(RESULT_OK, i); finish();
En su clase de actividad principal (obtenga el resultado):
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 0) { if (resultCode == RESULT_OK){ Log.d("test", data.getExtraString("name"); } } }
Puede poner tantos extras como desee y no sólo cadenas, sino todos los tipos de datos estándar.
Espero que lo hice todo bien;)
EDITAR
Como Kaarel me dijo, probablemente no comprendí la pregunta. Así es como puede recibir datos de la actividad principal en la actividad de preferencias:
En su actividad principal: inicie la actividad de preferencias y adjunte los datos
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);
En su actividad de preferencias: reciba los datos adjuntos a la intención
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
Si echa un vistazo a PreferenceActivity.java en el código fuente de la plataforma aquí en la línea 1000 puede ver que su intención se llama a través startActivity startActivity(header.intent);
y no a través de startActivityForResult, así que no creo que esto sea posible.
Sin embargo, puede intentar anular la función onHeaderClick
junto con el onActivityResult
de PreferenceActivity y ver qué sucede. No lo intenté yo mismo, así que no lo sé y hay una buena probabilidad de que este enfoque se rompa en versiones futuras.
Pero tal vez hay otro enfoque que podría funcionar para usted. Como puedo ver de su pregunta de referencia que está lanzando una actividad a través de una intención. Si esta actividad es para la edición de ajustes, entonces este NO es el enfoque correcto ya que android utiliza esta intención sólo para iniciar una actividad y nada más. En mi opinión, es mejor crear su actividad de preferencia específica mediante la ampliación de cualquiera de las disponibles para personalizarlo. Aquí está mi ListPreference personalizado que utilizo para permitir al usuario seleccionar una aplicación:
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 ----- }
Y lo estoy usando en mis preferences.xml como esto:
<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>
Al usar este enfoque, puedo controlar todo lo que mi usuario hace en esta actividad sin romper las reglas de android sobre las preferencias.
Espero que esto ayude.
- Android IAB: "Error al actualizar el inventario (consultar precios de los elementos)" Error del desarrollador
- com.android.sdklib.build.ApkCreationException: Error de certificado de depuración caducado