diff --git a/res/layout/preference_list_content.xml b/res/layout/preference_list_content.xml new file mode 100644 index 000000000..9d0ed3ece --- /dev/null +++ b/res/layout/preference_list_content.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/res/xml-v14/preferences.xml b/res/xml-v14/preferences.xml index 162af496d..a365f88e5 100644 --- a/res/xml-v14/preferences.xml +++ b/res/xml-v14/preferences.xml @@ -1,9 +1,6 @@ - - diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 1d10eb8ba..cc9cbcf7e 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -1,9 +1,7 @@ - - - + diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java index 25efffaf1..b438f053e 100644 --- a/src/org/linphone/LinphoneActivity.java +++ b/src/org/linphone/LinphoneActivity.java @@ -42,6 +42,7 @@ import org.linphone.core.Log; import org.linphone.mediastream.Version; import org.linphone.setup.SetupActivity; import org.linphone.ui.AddressText; +import org.linphone.ui.PreferencesListFragment; import android.app.Activity; import android.content.Context; @@ -225,6 +226,7 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene dialerFragment = newFragment; break; case SETTINGS: + newFragment = new PreferencesFragment(); break; case ABOUT_INSTEAD_OF_CHAT: case ABOUT_INSTEAD_OF_SETTINGS: @@ -439,14 +441,16 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene dialer.setSelected(true); } else if (id == R.id.settings) { - Intent intent = new Intent(ACTION_MAIN); - intent.setClass(this, PreferencesActivity.class); - startActivityForResult(intent, SETTINGS_ACTIVITY); - if (FragmentsAvailable.SETTINGS.isRightOf(currentFragment)) { - Compatibility.overridePendingTransition(this, R.anim.slide_in_right_to_left, R.anim.slide_out_right_to_left); - } else { - Compatibility.overridePendingTransition(this, R.anim.slide_in_left_to_right, R.anim.slide_out_left_to_right); - } +// Intent intent = new Intent(ACTION_MAIN); +// intent.setClass(this, PreferencesActivity.class); +// startActivityForResult(intent, SETTINGS_ACTIVITY); +// if (FragmentsAvailable.SETTINGS.isRightOf(currentFragment)) { +// Compatibility.overridePendingTransition(this, R.anim.slide_in_right_to_left, R.anim.slide_out_right_to_left); +// } else { +// Compatibility.overridePendingTransition(this, R.anim.slide_in_left_to_right, R.anim.slide_out_left_to_right); +// } + changeCurrentFragment(FragmentsAvailable.SETTINGS, null); + settings.setSelected(true); } else if (id == R.id.about_chat) { Bundle b = new Bundle(); diff --git a/src/org/linphone/PreferencesFragment.java b/src/org/linphone/PreferencesFragment.java new file mode 100644 index 000000000..fac6a9cb4 --- /dev/null +++ b/src/org/linphone/PreferencesFragment.java @@ -0,0 +1,72 @@ +package org.linphone; + +import static org.linphone.R.string.pref_media_encryption_key; + +import java.util.ArrayList; +import java.util.List; + +import org.linphone.core.LinphoneCore; +import org.linphone.core.LinphoneCore.MediaEncryption; +import org.linphone.ui.PreferencesListFragment; + +import android.os.Bundle; +import android.preference.ListPreference; +import android.preference.Preference; + +public class PreferencesFragment extends PreferencesListFragment { + private ListPreference mencPref; + + public PreferencesFragment() { + super(R.xml.preferences); + } + + @Override + public void onCreate(Bundle bundle) { + super.onCreate(bundle); + mencPref = (ListPreference) findPreference(pref_media_encryption_key); + initializeMediaEncryptionPreferences(); + } + + private void initializeMediaEncryptionPreferences() { + LinphoneCore lc=LinphoneManager.getLc(); + boolean hasZrtp=lc.mediaEncryptionSupported(MediaEncryption.ZRTP); + boolean hasSrtp=lc.mediaEncryptionSupported(MediaEncryption.SRTP); + if (!hasSrtp && !hasZrtp){ + mencPref.setEnabled(false); + }else{ + List mencEntries=new ArrayList(); + List mencEntryValues=new ArrayList(); + mencEntries.add(getString(R.string.media_encryption_none)); + mencEntryValues.add(getString(R.string.pref_media_encryption_key_none)); + if (hasSrtp){ + mencEntries.add(getString(R.string.media_encryption_srtp)); + mencEntryValues.add(getString(R.string.pref_media_encryption_key_srtp)); + } + if (hasZrtp){ + mencEntries.add(getString(R.string.media_encryption_zrtp)); + mencEntryValues.add(getString(R.string.pref_media_encryption_key_zrtp)); + } + CharSequence[] contents=new CharSequence[mencEntries.size()]; + mencEntries.toArray(contents); + mencPref.setEntries(contents); + contents=new CharSequence[mencEntryValues.size()]; + mencEntryValues.toArray(contents); + mencPref.setEntryValues(contents); + mencPref.setDefaultValue(getString(R.string.media_encryption_none)); + //mencPref.setValueIndex(mencPref.findIndexOfValue(getString(R.string.media_encryption_none))); + } + } + + private Preference findPreference(int key) { + return getPreferenceManager().findPreference(getString(key)); + } + + @Override + public void onResume() { + super.onResume(); + + if (LinphoneActivity.isInstanciated()) { + LinphoneActivity.instance().selectMenu(FragmentsAvailable.SETTINGS); + } + } +} diff --git a/src/org/linphone/ui/PreferencesListFragment.java b/src/org/linphone/ui/PreferencesListFragment.java new file mode 100644 index 000000000..4ea5163fa --- /dev/null +++ b/src/org/linphone/ui/PreferencesListFragment.java @@ -0,0 +1,242 @@ +package org.linphone.ui; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +import org.linphone.R; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.preference.Preference; +import android.preference.PreferenceGroup; +import android.preference.PreferenceManager; +import android.preference.PreferenceScreen; +import android.support.v4.app.ListFragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewParent; +import android.widget.ListView; + +@SuppressLint("ValidFragment") +public class PreferencesListFragment extends ListFragment { + private PreferenceManager mPreferenceManager; + + /** + * The starting request code given out to preference framework. + */ + private static final int FIRST_REQUEST_CODE = 100; + private static final int MSG_BIND_PREFERENCES = 0; + + private Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_BIND_PREFERENCES: + bindPreferences(); + break; + } + } + }; + private ListView preferencesList; + private int xmlResID; + + public PreferencesListFragment(int xmlId) { + this.xmlResID = xmlId; + } + + // Must be provided + public PreferencesListFragment(){ + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle b) { + postBindPreferences(); + return preferencesList; + } + + @Override + public void onDestroyView(){ + super.onDestroyView(); + ViewParent p = preferencesList.getParent(); + if (p != null) { + ((ViewGroup)p).removeView(preferencesList); + } + } + + @Override + public void onCreate(Bundle bundle) { + super.onCreate(bundle); + if (bundle != null) { + xmlResID = bundle.getInt("xml"); + } + mPreferenceManager = onCreatePreferenceManager(); + preferencesList = (ListView) LayoutInflater.from(getActivity()).inflate(R.layout.preference_list_content, null); + preferencesList.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); + addPreferencesFromResource(xmlResID); + postBindPreferences(); + } + + @Override + public void onStop(){ + super.onStop(); + try { + Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityStop"); + m.setAccessible(true); + m.invoke(mPreferenceManager); + } catch(Exception e) { + e.printStackTrace(); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + preferencesList = null; + try { + Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityDestroy"); + m.setAccessible(true); + m.invoke(mPreferenceManager); + } catch(Exception e) { + e.printStackTrace(); + } + } + + @Override + public void onSaveInstanceState(Bundle outState) { + outState.putInt("xml", xmlResID); + super.onSaveInstanceState(outState); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + try { + Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityResult", int.class, int.class, Intent.class); + m.setAccessible(true); + m.invoke(mPreferenceManager, requestCode, resultCode, data); + } catch(Exception e) { + e.printStackTrace(); + } + } + + /** + * Posts a message to bind the preferences to the list view. + *

+ * Binding late is preferred as any custom preference types created in + * {@link #onCreate(Bundle)} are able to have their views recycled. + */ + private void postBindPreferences() { + if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return; + mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget(); + } + + private void bindPreferences() { + final PreferenceScreen preferenceScreen = getPreferenceScreen(); + if (preferenceScreen != null) { + preferenceScreen.bind(preferencesList); + } + } + + /** + * Creates the {@link PreferenceManager}. + * + * @return The {@link PreferenceManager} used by this activity. + */ + private PreferenceManager onCreatePreferenceManager() { + try { + Constructor c = PreferenceManager.class.getDeclaredConstructor(Activity.class, int.class); + c.setAccessible(true); + PreferenceManager preferenceManager = c.newInstance(this.getActivity(), FIRST_REQUEST_CODE); + return preferenceManager; + } catch(Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * Returns the {@link PreferenceManager} used by this activity. + * @return The {@link PreferenceManager}. + */ + public PreferenceManager getPreferenceManager() { + return mPreferenceManager; + } + + /** + * Sets the root of the preference hierarchy that this activity is showing. + * + * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy. + */ + public void setPreferenceScreen(PreferenceScreen preferenceScreen) { + try { + Method m = PreferenceManager.class.getDeclaredMethod("setPreferences", PreferenceScreen.class); + m.setAccessible(true); + boolean result = (Boolean) m.invoke(mPreferenceManager, preferenceScreen); + if (result && preferenceScreen != null) { + postBindPreferences(); + } + }catch(Exception e){ + e.printStackTrace(); + } + } + + /** + * Gets the root of the preference hierarchy that this activity is showing. + * + * @return The {@link PreferenceScreen} that is the root of the preference + * hierarchy. + */ + public PreferenceScreen getPreferenceScreen() { + try { + Method m = PreferenceManager.class.getDeclaredMethod("getPreferenceScreen"); + m.setAccessible(true); + return (PreferenceScreen) m.invoke(mPreferenceManager); + } catch(Exception e) { + e.printStackTrace(); + } + + return null; + } + + /** + * Inflates the given XML resource and adds the preference hierarchy to the current + * preference hierarchy. + * + * @param preferencesResId The XML resource ID to inflate. + */ + public void addPreferencesFromResource(int preferencesResId) { + try { + Method m = PreferenceManager.class.getDeclaredMethod("inflateFromResource", Context.class, int.class, PreferenceScreen.class); + m.setAccessible(true); + PreferenceScreen prefScreen = (PreferenceScreen) m.invoke(mPreferenceManager, getActivity(), preferencesResId, getPreferenceScreen()); + setPreferenceScreen(prefScreen); + } catch(Exception e) { + e.printStackTrace(); + } + } + + /** + * Finds a {@link Preference} based on its key. + * + * @param key The key of the preference to retrieve. + * @return The {@link Preference} with the key, or null. + * @see PreferenceGroup#findPreference(CharSequence) + */ + public Preference findPreference(CharSequence key) { + if (mPreferenceManager == null) { + return null; + } + return mPreferenceManager.findPreference(key); + } + + public interface OnPreferenceAttachedListener { + public void onPreferenceAttached(PreferenceScreen root, int xmlId); + } +} \ No newline at end of file