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?

Intenté sobreescribir onActivityResult en mi PreferencesActivity sin éxito.

¿Me faltan algunas propiedades adicionales en preferences.xml?

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.

  • Preferencias independientes para cada vista en una aplicación para Android
  • Obtener posición del artículo desde el adaptador personalizado
  • ¿Cómo escuchar los cambios de preferencia dentro de un archivo PreferenceFragment?
  • Activar y desactivar una preferencia
  • ¿Cómo puedo cambiar el tamaño de un título CheckBox o hacer que envuelva en un xml PreferenceScreen?
  • Aplicar tema personalizado a PreferenceFragment
  • ¿Cómo usar el Porcentaje para el diseño de Android?
  • ActionBar en PreferenceActivity
  • ¿Cuál es la diferencia entre TypedArray.getInteger () y TypedArray.getInt ()?
  • Cómo abrir un cuadro de diálogo de una entrada de texto en una pantalla de preferencia?
  • ¿Por qué la inspección de código en SharedPreferences.getString () con el informe de valor predeterminado "puede producir NPE"?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.