What android:inputType should I use for entering an IP Address and hostname?
Asked Answered
A

13

60

I am building a small Android app where the user will enter an IP address or a hostname into an EditText widget. 90% of the time they will be entering an IP address, the rest of the time - a hostname.

So naturally, I want to make it easy for them to enter an IP address, but the ability to switch to alpha numerics for hostname entry is important.

I can't seem to find a good inputType. The numberDecimal initially seemed like a good shot, but it only allows one dot.

Ideally, I'd like to start with a standard keyboard that had the ?123 button pressed.

How do I get there?

Automata answered 28/12, 2011 at 22:15 Comment(2)
I think only option is EditText type Text. You may need to add validation for IP.Galla
don't forget, IP addresses are going to start using a-f and : in 1995…Apomixis
S
69

Try using android:inputType="number", but also set android:digits="0123456789.". Works for me.

Shelton answered 3/2, 2014 at 22:6 Comment(4)
Just read the question again and noticed that the you wanted to be able to enter a hostname as well. My answer won't work for that, but it will bring up the standard "number" keyboard and allow for multiple dots.Shelton
You can add lower and upper case letters and a hyphen to digits, but it is a bit messy. It will work, though.Shelton
Using Android 6.0, number didn't show me the dot while numberDecimal did.Euripides
For typing "192.168.1.111", either number or numberDecimal with digits didn't work on my Samsung Note 9 (Android 9.0). It just doesn't allow me to type the second dot. I use Patterns.IP_ADDRESS.matcher("192.168.1.111").matches() to validate the input in my code.Soviet
B
47

If you use inputType="phone" you gain access to a cut down keyboard containing Numbers and a Period character - this doesn't restrict the input with regards to the amount of Periods you can enter.

Please see this answer for validation while being entered.

Bastardize answered 18/7, 2012 at 14:29 Comment(4)
Thanks I think this is a good answer. It's so annoying to be brought up with a keyboard for a field that only requires numbers such as an IP Address. Validation is key obviously but you've even provided a link for that! Kudos.Heideheidegger
On Android Marshmallow 23 the period button on the keyboard has been replaced by * and #. Therefore inputType="phone" should not be used for IP address input fields. Use android:inputType="numberDecimal" and android:digits="0123456789." instead as suggested in other questionsLindley
Use Patterns work for me, number and numberDecimal with digits didn't work.Soviet
This still allows the user to input *#(/), unfortunately.Tempo
A
31

This works perfectly keyboard with numbers and decimal by adding android:inputType="number|numberDecimal" and android:digits="0123456789."

Example

 <EditText
    android:id="@+id/ip_address"
    android:inputType="number|numberDecimal"
    android:digits="0123456789."
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>
Acceptant answered 10/10, 2014 at 2:6 Comment(4)
perfect solutionCarom
This is the perfect solution. Thank you!Pygidium
This doesn't work for me on API Level 27 unfortunately. It only allows one decimalTempo
works on Pixel 3a XL, android 11 API 30 and Samsung android 7.0 API 24. Thanks!Typewrite
C
17

You can use your own input filter for that

final EditText text = new EditText(ServerSettings.this);
InputFilter[] filters = new InputFilter[1];
filters[0] = new InputFilter() {
    @Override
    public CharSequence filter(CharSequence source, int start,
            int end, Spanned dest, int dstart, int dend) {
        if (end > start) {
            String destTxt = dest.toString();
            String resultingTxt = destTxt.substring(0, dstart) +
            source.subSequence(start, end) +
            destTxt.substring(dend);
            if (!resultingTxt.matches ("^\\d{1,3}(\\." +
                    "(\\d{1,3}(\\.(\\d{1,3}(\\.(\\d{1,3})?)?)?)?)?)?")) { 
                return "";
            } else {
                String[] splits = resultingTxt.split("\\.");
                for (int i=0; i<splits.length; i++) {
                    if (Integer.valueOf(splits[i]) > 255) {
                        return "";
                    }
                }
            }
        }
    return null;
    }
};
text.setFilters(filters);
Contraposition answered 5/4, 2012 at 10:0 Comment(2)
Thanks for this. This answer was exactly what I needed.Viehmann
Not working with spannables, since the whole input gets replaced with an empty string in some cases. See Łukasz Sromeks answer at #3349621Richardo
S
6

use this :

<EditText
    android:id="@+id/txtIP"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:digits="0123456789."
 />
Selfeffacement answered 3/11, 2014 at 21:24 Comment(0)
L
5
<EditText
    android:id="@+id/ip_address"
    android:inputType="number|numberDecimal"
    android:digits="0123456789."
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

worked for me

Lorenalorene answered 9/8, 2017 at 12:3 Comment(3)
Using number|numberDecimal only allows one dot.Burress
add android:digits="0123456789." tooLorenalorene
My mistake. Using inputType + digits works fine on Android, but not on FireOS (Amazon Android fork) which has a custom dialog implementation.Burress
O
1

I think your only option is..

EditText android:inputType="text" ... />

You could possible check the Text for 3 dots a IP address contains

Overstreet answered 28/12, 2011 at 22:18 Comment(3)
User wants same text box need to handle host name and IP, number may constrian it to only number. Even IP he can't enter because of DOTS.Galla
"number" won't let you switch to letters and won't let u enter a dot.Automata
I think your only option is Text. You can then check the IP address for consistency to make sure the decimals are in place.Overstreet
M
1

I think you need to use TextWatcher for validation, register it with TextView.addTextChangedListener() method and use Pattern.DOMAIN_NAME and Pattern.IP_ADDRESS (Android 2.2+).

See:
Android: How can I validate EditText input?
Validating IP in android

Molecule answered 28/12, 2011 at 22:26 Comment(1)
This is validation - I got that part. I am only concerned right now with making it easy on the user and not having the user tap extra keys.Automata
S
1

You can extend the DigitsKeyListener (source) and change the filter() function (validation that will check either ip pattern or a string hostname) and getInputType() to return InputType.TYPE_CLASS_PHONE;

Squarely answered 28/12, 2011 at 22:46 Comment(0)
F
1

Maybe if you use 2 radiobutton, one shows an edittext for host, the other one shows 4 numeric edittext for IP, then, once the user submit data you concat all 4 edittext values with dots between them, something like this, edittext1.getText() + "." + edittext2.getText() + "." edittext3.getText() + "." edittext4.getText() so you can obtain a validated IP address like that but obviously it will imply more work.

Fabricant answered 16/1, 2015 at 15:10 Comment(3)
Good golly I hate when apps try to make entering an IP address "easier". Guess what, if I know what an IP address is, I can probably find the "." button.Yingyingkow
@Yingyingkow Well, the idea was in order to facilitate IP validation and make user input easierFabricant
You can easily validate a string against Patterns.IP_ADDRESS. For the user, tapping back and forth between different fields in an IP address is never easier. Have you ever seen a phone dialer with separate area-code/3-digit-prefix/4-digit-suffix fields? Or an email widget with different fields for name/domain? Please just don't.Yingyingkow
N
1

Here is the code that allows you to display a soft keyboard with only numbers and a dot (but allows you to enter multiple dots).

etIpAddress.setInputType(InputType.TYPE_CLASS_NUMBER);
etIpAddress.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
etIpAddress.setKeyListener(DigitsKeyListener.getInstance(false,false));
etIpAddress.setKeyListener(DigitsKeyListener.getInstance("0123456789."));
Norinenorita answered 9/3, 2021 at 9:1 Comment(0)
R
0

SKTs answer is working pretty well until the InputFilter passes Spannables. Spannables are tricky to handle which is described for example ins answers of this question. In this case, returning "" for invalid input will replace the whole text by an empty string. I've adapted the solution also to handle this case. Here is the code, differing the types, in Kotlin:

val ipAddressFilters = arrayOf(InputFilter { source, start, end, dest, dstart, dend ->
    if (end > start) {
        val toCheck = if (source is Spannable) {
            source.toString()
        } else {
            val destString = dest.toString()
            destString.substring(0, dstart) + source.subSequence(start, end) + destString.substring(dend)
        }
        if (!toCheck.matches("^\\d{1,3}(\\.(\\d{1,3}(\\.(\\d{1,3}(\\.(\\d{1,3})?)?)?)?)?)?".toRegex())) {
            return@InputFilter if (source is Spannable) { dest } else { "" }
        } else {
            val splits = toCheck.split("\\.".toRegex()).toTypedArray()
            for (i in splits.indices) {
                if (splits[i] != "" && Integer.valueOf(splits[i]) > 255) {
                    return@InputFilter if (source is Spannable) { dest } else { "" }
                }
            }
        }
    }
    null
})
Richardo answered 15/10, 2020 at 18:13 Comment(0)
T
-1

Try using android:inputType="textUri". It works especially well when you want hostname or IP address.

Tergal answered 24/3, 2018 at 20:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.