Search code examples
androidbuttonandroid-edittextpreference

How to make a DialogPreference that shows a Button next to an EditText?


Here's a problem which is driving me mad.

I have the need to have two slightly different (could pe a parametrized one) and very specific Preference types.

One is an EditText with a Button next to it. The EditText lets you enter (modify) a phone number, while the button opens the Contacts dialog and lets you chooe a contact's number.

The other Preference is really similar, if not identical, but lets you choose an eMail, from another contact (It's not said that the phone and the eMail are from the same contact, they can - and normally should - be from different people).

These custom Preferences should work in PreferenceActivities as well as in PreferenceFragments.

Even better, if the EditText could also have the contact photo on the left - but this is just dreaming, I know...

Do you have any idea how can I accomplish something like that?

I can't even figure out if the best way to do this would be using intents in PreferenceScreen or extending a DialogPreference or ... who knows what.

Now, My English is maybe faulty, I better explain what I need by the help of an image (it's a sequence of actions):

enter image description here

Thank you in advance!


Solution

  • Well, it turn out that DialogPreferences can't override onActivityResult, which is crucial for getting a result aftwer you picked a contact from the contact list.

    So I had to resign and find some other solution.
    A simple EditTextPreference was... too simple for my tastes, I extended a RingTonePreference and bent it to my needs.

    You will need: a Class (the preference itself), a styleable attribute (just an enum to set wether it's used to pick a phone number or an email address) and the preference definition file.

    Here we go:

    CLS_Prefs_Contact.java

    /**
     * CLS_Prefs_Contact class
     *
     * This is the class that allows for a custom Contact Picker Preference
     * (auto refresh summary).
     *
     * @category    Custom Preference
     * @author      Paranoid Eyes
     * @copyright   Paranoid Eyes
     * @version     1.0
     */
    package com.paranoideyes.contactpreference_rt;
    
    /* ---------------------------------- Imports ------------------------------- */
    
    import android.content.Context;
    import android.content.Intent;
    import android.content.SharedPreferences;
    import android.database.Cursor;
    import android.net.Uri;
    import android.preference.PreferenceManager;
    import android.preference.RingtonePreference;
    import android.provider.ContactsContract;
    import android.util.AttributeSet;
    
    /**
    * @attr ref android.R.styleable#ContactPreference_contactInfo
    */
    public class ContactPreference extends RingtonePreference
    {
    
        /* ----------------------------- Constants ------------------------------ */
    
        /*
        private static final String nsContact =
            "http://schemas.android.com/apk/res/com.lucacrisi.contactpreference_rt";
        */
        private static final String nsContact =
            "http://schemas.android.com/apk/res-auto";
    
        /* ----------------------------- Variables ------------------------------ */
    
        //private static Contact_Info contactInfo = null;
        private int contactInfo = 0;
        private final String defaultSummary = "---";
    
        /* ------------------------------ Objects ------------------------------- */
    
        private static Context ctx = null;
    
        private static SharedPreferences prefs = null;
    
        /* ---------------------------- Constructors ---------------------------- */
    
        public ContactPreference(final Context context, final AttributeSet attrs)
        {
            super(context, attrs);
    
            ctx = context;
    
            // Read attributes
            contactInfo = attrs.getAttributeIntValue(nsContact, "contactInfo", 0);
    
            //System.out.println("Constructor - " + contactInfo);
    
            prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
    
            summary_Update();
        }
    
        /* ----------------------------- Overrides ------------------------------ */
    
        @Override
        public final boolean onActivityResult
            (final int requestCode, final int resultCode, final Intent data)
        {
            boolean result = false;
            if (super.onActivityResult(requestCode, resultCode, data))
            {
                if (data != null)
                {
                    //
                    getContactInfo(data);
    
                    //
                    final Uri uri = data.getData();
                    if (callChangeListener(uri != null ? uri.toString() : ""))
                    {
                        result = true;
                    }
                }
            }
            return result;
        }
        @Override
        protected final void onPrepareRingtonePickerIntent(final Intent tnt)
        {
            tnt.setAction(Intent.ACTION_PICK);
            tnt.setData(ContactsContract.Contacts.CONTENT_URI);
        }
    
        /* ------------------------------ Methods ------------------------------- */
    
        private final void getContactInfo(final Intent data)
        {
            //final String noData = getString(R.string.missing_data);
            //String result = noData;
            String result = "";
    
            final Cursor cur =
                ctx.getContentResolver().query(data.getData(), null, null, null, null);
            while (cur.moveToNext())
            {
                final String contactId =
                    cur.getString
                    (
                        cur.getColumnIndex
                        (
                            ContactsContract.Contacts._ID
                        )
                    );
    
                //System.out.println("getContactInfo - " + contactInfo);
    
                switch(contactInfo)
                {
                    case 0: // phone
                    {
                        // Find the phone numbers
                        String hasPhone = cur.getString
                            (
                                cur.getColumnIndex
                                (
                                    ContactsContract.Contacts.HAS_PHONE_NUMBER
                                )
                            );
                        if (hasPhone.equalsIgnoreCase("1"))
                        {
                            hasPhone = "true";
                        }
                        else
                        {
                            hasPhone = "false" ;
                        }
                        if (Boolean.parseBoolean(hasPhone))
                        {
                            final Cursor phones = ctx.getContentResolver().query
                                (
                                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                    null,
                                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID +
                                    " = " + contactId, null, null
                                );
                            String number = ""; //noData;
                            if (phones.getCount() > 0)
                            {
                                phones.moveToFirst();
                                number = phones.getString
                                    (
                                        phones.getColumnIndex
                                        (
                                            ContactsContract.CommonDataKinds.Phone.NUMBER
                                        )
                                    );
                            }
                            phones.close();
                            result = number;
                            //result = ((number == "") ? noData : number);
                        }
                        break;
                    }
                    case 1: // email
                    {
                        // Find the email addresses
                        final Cursor emails = ctx.getContentResolver().query
                            (
                                ContactsContract.CommonDataKinds.Email.CONTENT_URI,
                                null,
                                ContactsContract.CommonDataKinds.Email.CONTACT_ID +
                                " = " + contactId, null, null
                            );
                        String email = ""; //noData;
                        if (emails.getCount() > 0)
                        {
                            emails.moveToFirst();
                            email = emails.getString
                                (
                                    emails.getColumnIndex
                                    (
                                        ContactsContract.CommonDataKinds.Email.DATA
                                    )
                                );
                        }
                        emails.close();
                        result = email;
                        //result = ((email == "") ? noData : email);
                        break;
                    }
                }
            }
            cur.close();
    
            // Here do the magic and put the value into the Preferences
            setting_Write(getKey(), result);
    
            summary_Update();
        }
    
        private final static void setting_Write(final String key, final String value)
        {
            // Write the value
            prefs.edit().putString(key, value).commit();
        }
    
        private final void summary_Update()
        {
            // Read the value and set the summary
            String str = prefs.getString(getKey(), "");
            if ("".equals(str))
            {
                str = defaultSummary;
            }
            setSummary(str);
        }
    }
    

    res/values/attrs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="CLS_Prefs_Contact">
            <attr name="contactInfo">
                <enum name="phone" value="0" />
                <enum name="email" value="1" />
            </attr>
        </declare-styleable>
    </resources>
    

    res/xml/prefs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <PreferenceScreen 
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:contact="http://schemas.android.com/apk/res-auto"
        >
        <com.paranoideyes.contactpreference_rt.CLS_Prefs_Contact
            android:key="phone_nr"
            android:title="@string/phone_nr"
            contact:contactInfo="phone"
        />
        <com.paranoideyes.contactpreference_rt.CLS_Prefs_Contact
            android:key="email_ad"
            android:title="@string/email_ad"
            contact:contactInfo="email"
        />
    </PreferenceScreen>
    

    res/values/strings.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="app_name">ContactPreference Sample</string>
    
        <string name="phone_nr">Choose a phone number</string>
        <string name="summary_pn">Not set</string>
    
        <string name="email_ad">Choose an email</string>
        <string name="summary_ea">Not set</string>
    </resources>
    

    So, this is what I ended up with:

    enter image description here