Android preferences onclick event
Asked Answered
M

5

118

In my preferences.xml I have a preference element like this:

<Preference android:title="About" />

I want to assign onClick event, so if user would click on it, I would be able to do open new Intent or browser. I tried to do it like I do with buttons, but this not seem to work.

Martines answered 16/3, 2011 at 19:27 Comment(0)
S
245

You need to set android:key for the item:

<Preference
    android:key="myKey"
    android:title="About" />

Then you can do the following in your code:

Preference myPref = (Preference) findPreference("myKey");
myPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
    public boolean onPreferenceClick(Preference preference) {
        // open browser or intent here
        return true;
    }
});
Sulcate answered 16/3, 2011 at 19:31 Comment(5)
Where shall i place this? in my SettingsActivity in onPostCreate wont work because it is too early(Nullpointer-Exception). Any help is appreciatedTwoply
findPreference is deprecated.Striction
PreferenceActivity.findPreference is deprecated. However the documentation says "[T]his functionality should now be found in the new PreferenceFragment class. If you are using PreferenceActivity in its old mode, the documentation there applies to the deprecated APIs here.", and PreferenceFragment.findPreference is not deprecated (as of API level 23, current at the time of writing). So, findPreference itself is not deprecated; it is the direct use of PreferenceActivity which is deprecated. Google want us to move to PreferenceFragment instead, not to abandon findPreference.Intravasation
In onPreferenceClick, return true if the click was handled else false.Mecke
This works for me with PreferenceFragmentCompatDividers.Eudemonism
M
60

to launch a website:

<PreferenceScreen android:title="website">
    <intent
        android:action="android.intent.action.VIEW"
        android:data="http://www.example.com"
        />
</PreferenceScreen>

to launch a specific activity:

<PreferenceScreen android:title="something">
    <intent
        android:action="android.intent.action.MAIN"
        android:targetPackage="com.example.foo"
        android:targetClass="com.example.foo.SomeActivity"
        />
</PreferenceScreen>

you can also use "android:mimetype" to set the mimetype.

Madeleinemadelena answered 31/8, 2011 at 21:31 Comment(5)
I agree, this approach is better, especially because it doesn't use the now deprecated findPreference(String key) method and because it's just cleaner overall.Tonguelashing
Very nice, but is it also possible to create a IntentChooser this way?Aramanta
@jasongilbert Is it possible to send a broadcast with ACTION rather than starting activity from preference click?Claybourne
@jasongilbert Should i specify any intent-filter in the manifest for the SomeActivity, cuz am getting ActivityNotFoundException :(Oversize
Can't run an Activity usign this way, always get the following error: Unable to find explicit activity class {de.etc/datnet.app.activities.PinAendernActivity}; have you declared this activity in your AndroidManifest.xml?Lulululuabourg
T
12

You need to use onPreferenceTreeClick event.

For example see http://www.javased.com/index.php?source_dir=platform_packages_apps_phone/src/com/android/phone/MobileNetworkSettings.java

 @Override 
    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { 
        /** TODO: Refactor and get rid of the if's using subclasses */ 
        if (mGsmUmtsOptions != null && 
                mGsmUmtsOptions.preferenceTreeClick(preference) == true) { 
            return true; 
        } else if (mCdmaOptions != null && 
                   mCdmaOptions.preferenceTreeClick(preference) == true) { 
            if (Boolean.parseBoolean( 
                    SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) { 

                mClickedPreference = preference; 

                // In ECM mode launch ECM app dialog 
                startActivityForResult( 
                    new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null), 
                    REQUEST_CODE_EXIT_ECM); 
            } 
            return true; 
        } else if (preference == mButtonPreferredNetworkMode) { 
            //displays the value taken from the Settings.System 
            int settingsNetworkMode = android.provider.Settings.Secure.getInt(mPhone.getContext(). 
                    getContentResolver(), android.provider.Settings.Secure.PREFERRED_NETWORK_MODE, 
                    preferredNetworkMode); 
            mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode)); 
            return true; 
        } else if (preference == mButtonDataRoam) { 
            if (DBG) log("onPreferenceTreeClick: preference == mButtonDataRoam."); 

            //normally called on the toggle click 
            if (mButtonDataRoam.isChecked()) { 
                // First confirm with a warning dialog about charges 
                mOkClicked = false; 
                new AlertDialog.Builder(this).setMessage( 
                        getResources().getString(R.string.roaming_warning)) 
                        .setTitle(android.R.string.dialog_alert_title) 
                        .setIconAttribute(android.R.attr.alertDialogIcon) 
                        .setPositiveButton(android.R.string.yes, this) 
                        .setNegativeButton(android.R.string.no, this) 
                        .show() 
                        .setOnDismissListener(this); 
            } else { 
                mPhone.setDataRoamingEnabled(false); 
            } 
            return true; 
        } else if (preference == mButtonDataEnabled) { 
            if (DBG) log("onPreferenceTreeClick: preference == mButtonDataEnabled."); 
            ConnectivityManager cm = 
                    (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); 

            cm.setMobileDataEnabled(mButtonDataEnabled.isChecked()); 
            return true; 
        } else if (preference == mLteDataServicePref) { 
            String tmpl = android.provider.Settings.Secure.getString(getContentResolver(), 
                        android.provider.Settings.Secure.SETUP_PREPAID_DATA_SERVICE_URL); 
            if (!TextUtils.isEmpty(tmpl)) { 
                TelephonyManager tm = (TelephonyManager) getSystemService( 
                        Context.TELEPHONY_SERVICE); 
                String imsi = tm.getSubscriberId(); 
                if (imsi == null) { 
                    imsi = ""; 
                } 
                final String url = TextUtils.isEmpty(tmpl) ? null 
                        : TextUtils.expandTemplate(tmpl, imsi).toString(); 
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); 
                startActivity(intent); 
            } else { 
                android.util.Log.e(LOG_TAG, "Missing SETUP_PREPAID_DATA_SERVICE_URL"); 
            } 
            return true; 
        } else { 
            // if the button is anything but the simple toggle preference, 
            // we'll need to disable all preferences to reject all click 
            // events until the sub-activity's UI comes up. 
            preferenceScreen.setEnabled(false); 
            // Let the intents be launched by the Preference manager 
            return false; 
        } 
    } 
Tampere answered 16/3, 2011 at 19:31 Comment(1)
The link is 404Volley
F
9

2018+ UPDATE Today, the findPreference method is depricated. So, to achieve this, just override the onPreferenceTreeClick method in your Preference fragment. For example:

public class MySettingsFragment extends PreferenceFragment {

    @Override
    public boolean onPreferenceTreeClick (PreferenceScreen preferenceScreen,
                                          Preference preference)
    {
        String key = preference.getKey();
        if(key.equals("someKey")){
            // do your work
            return true;
        }
        return false;
    }
}

Furthermore, if you need to handle a click inside particular preference element (e.g. ListPreference), you should register the setOnPreferenceChangeListener inside the onCreate method of the MySettingsFragment:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Load the preferences from an XML resource
    addPreferencesFromResource(R.xml.preferences);

    // register listener
    final Preference prefList = findPreference("key");
    prefList.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        public boolean onPreferenceChange(Preference preference, Object value) {
            System.out.println("Selected: " + value);
            return true;
        }
    });
}
Finding answered 22/10, 2018 at 16:44 Comment(1)
What's the difference between onPreferenceClick and onPreferenceTreeClick ?Cadal
D
4

A followup on @jason gilbert's answer

I'm on targetSdkVersion 25, and his answer didn't work, I had to wrap the intent tag with a Preference tag. Example:

<PreferenceScreen android:title="something">
    <Preference title="Title">
       <intent
       android:action="android.intent.action.MAIN"
       android:targetPackage="com.example.foo"
       android:targetClass="com.example.foo.SomeActivity"
       />
    </Preference>
</PreferenceScreen>
Doyle answered 17/5, 2017 at 11:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.