Secure Text Entry is a text input mode in Android where entered characters are displayed in a hidden form (dots or asterisks) instead of actual characters. This mode is used for password fields, PIN codes, CVV codes and other confidential information. Secure Text Entry not only protects data from visual interception but also prevents leakage through screenshots, screen recordings and autocorrect features. According to Android Security Best Practices (2026), hidden input is a mandatory requirement for applications handling user authentication data.
Key Takeaways
Secure Text Entry (protected text input) is an Android feature that replaces the display of each entered character with a masking character, usually a dot (•) or asterisk (*). This prevents password reading over the shoulder (shoulder surfing) and hides entered data from prying eyes. This feature is also known as password masking and is a standard practice in mobile applications.
Unlike iOS, where Secure Text Entry is a separate UITextField setting, in Android this feature is activated via the inputType attribute with the PASSWORD variation. When an EditText receives inputType="textPassword", it automatically applies PasswordTransformationMethod — a class responsible for character replacement. As each new character is entered, EditText instantly replaces it with a masking character through the TransformationMethod interface mechanism.
According to Android Source Code (AOSP, 2026), the PasswordTransformationMethod implementation uses the TextPaint class to render masking characters. The size of the masking character matches the field's font size, which prevents information leakage through word length — all characters look identical in width. This is important for protection against attacks based on analyzing the length of entered data.
<!-- Basic Secure Text Entry example -->
@+id/etPassword
android:layout_width="match_parent"
android:hint="Enter password"
android:inputType="textPassword"
android:maxLength="64"
android:importantForAutofill="yes" />
The Secure Text Entry mechanism in Android is based on the TransformationMethod interface, defined in the android.text.method package. PasswordTransformationMethod is a built-in implementation that overrides the getTransformation() method, returning a replaced character sequence for display. The original text in Editable remains unchanged — only its visual representation is altered.
When a user enters a character, EditText calls dispatchEvent and passes the character to InputConnection, which adds it to Editable. Then EditText calls the getTransformation() method of the current TransformationMethod, which takes the original CharSequence and returns a SpannableString with masking characters. This SpannableString is rendered on screen instead of the original text. The key feature is that the transformation itself does not change the Editable content, so calling getText().toString() returns the actual entered text.
According to Android Developers Reference (2026), PasswordTransformationMethod adds a MetricAffectingSpan to each character, which replaces the glyph with a dot. These spans do not affect text length, so the cursor and input position are preserved correctly even with hidden display. There is also VisiblePasswordTransformationMethod, which displays the last entered character for a short time (similar to iOS).
// PasswordTransformationMethod - built-in masking
editText.transformationMethod = PasswordTransformationMethod.getInstance()
// VisiblePasswordTransformationMethod - shows last char
editText.transformationMethod = VisiblePasswordTransformationMethod.getInstance()
Visibility toggle (password visibility toggle) is a feature that allows the user to temporarily show the entered password to verify it before submitting the form. In Android, this feature is implemented via TextInputLayout with the app:endIconMode="password_toggle" attribute. When the eye icon is tapped, the field switches between textPassword and textVisiblePassword.
The password_toggle implementation in TextInputLayout automatically changes the inputType of the internal EditText and animates the icon (eye open/closed). It is important to remember that during such switching the cursor position may reset, so TextInputLayout saves and restores the position after mode change. Also, when switching to visible password, autocorrect and suggestions are not enabled — TYPE_TEXT_VARIATION_VISIBLE_PASSWORD is used, not regular text.
According to Material Design Guidelines (2025), the password show icon should always be visible, not only when the field is in focus. The user should be able to verify the password at any moment. The icon should not automatically hide the password after a certain time — only upon user action.
<!-- TextInputLayout with password toggle -->
@+id/tilPassword
android:layout_width="match_parent"
app:endIconMode="password_toggle"
app:passwordToggleTint="@color/primary">
@+id/etPassword
android:inputType="textPassword"
android:hint="Password" />
</com.google.android.material.textfield.TextInputLayout>
Programmatic setting of Secure Text Entry in Kotlin is done by setting inputType or via setTransformationMethod(). Both approaches lead to the same result but differ in details. Setting inputType additionally configures autocorrect and suggestions, while setTransformationMethod only affects character display.
// Programmatic password visibility toggle
fun togglePasswordVisibility(til: TextInputLayout) {
val editText = til.editText ?: return
val currentType = editText.inputType
val isPassword = (currentType and
InputType.TYPE_TEXT_VARIATION_PASSWORD) != 0
if (isPassword) {
editText.inputType = InputType.TYPE_CLASS_TEXT or
InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
} else {
editText.inputType = InputType.TYPE_CLASS_TEXT or
InputType.TYPE_TEXT_VARIATION_PASSWORD
}
// Restore cursor position
val cursorPos = editText.selectionStart
editText.setSelection(maxOf(0, cursorPos))
}
// Custom masking — shows only last 4 chars
class PartialPasswordTransformation : TransformationMethod {
override fun getTransformation(source: CharSequence?,
view: View?): CharSequence {
val text = source?.toString() ?: ""
if (text.length <= 4) return text
val dots = "\u2022".repeat(text.length - 4)
return dots + text.substring(text.length - 4)
}
override fun onFocusChanged(view: View?,
sourceText: CharSequence?,
focused: Boolean,
direction: Int,
previouslyFocusedRect: android.graphics.Rect?) {}
}
Secure Text Entry provides protection at multiple levels. Visual masking prevents password reading over the shoulder (shoulder surfing) — the most common method of password theft in public places. Disabling autocorrect prevents the password from being saved in the user's dictionary, eliminating leakage through predictive input. Protection against screenshots (if FLAG_SECURE is enabled) prevents other applications from capturing the field's content.
However, Secure Text Entry is not complete protection. Attacks through input interception (keylogging) at the system level can obtain actual characters from InputConnection. Malicious applications with accessibility services can read EditText content even if characters are hidden on screen. Also, SSL sniffing during data transmission to the server can expose the password if HTTPS with proper certificate validation is not used.
According to OWASP Mobile Security Testing Guide (2025), for maximum password protection in Android it is recommended to: use inputType="textPassword" + disable autofill for critical fields; not cache the password in memory longer than necessary; clear the password field when the application is minimized (onPause/onStop); use masking even during brief password display.
| Protection level | Secure Text Entry | Additional measures |
|---|---|---|
| Visual interception | Character masking | Biometric auth, avoid shoulder surfing |
| Screenshots | Partial (depends on implementation) | FLAG_SECURE on Window |
| Keylogging | Does not protect | Use IME with secure input |
| Autocorrect/dictionary | Disabled | disabled by default for password |
| Network interception | Does not protect | HTTPS with certificate pinning |
Android developers should follow several key practices when working with hidden input. First, always use TextInputLayout with endIconMode="password_toggle" for password fields — this is the modern Material Design standard. Second, do not disable the ability to show the password — the user should be able to verify what they entered, especially on mobile devices with small keyboards.
Secure Text Entry also requires proper autofill configuration. For password fields, always specify autofillHints="password" or autofillHints="newPassword" so that password managers can correctly fill and save data. For the new password confirmation field, use autofillHints="newPassword" so the system does not suggest filling it with the current saved password.
// Full password field with autofill and cleanup
class SecurePasswordField {
private fun setupPasswordField(til: TextInputLayout) {
val editText = til.editText ?: return
editText.inputType = InputType.TYPE_CLASS_TEXT or
InputType.TYPE_TEXT_VARIATION_PASSWORD
editText.setAutofillHints(View.AUTOFILL_HINT_PASSWORD>)
editText.importantForAutofill = View.IMPORTANT_FOR_AUTOFILL_YES
}
fun clearOnPause(editText: EditText) {
editText.text?.clear()
}
}
Frequently Asked Questions
textPassword hides all entered characters and disables autocorrect. textVisiblePassword also disables autocorrect but displays characters in plain view. textVisiblePassword is used when toggling password visibility — it is not regular text, as autocorrect and suggestions remain disabled for security.
Yes, create a custom class implementing the TransformationMethod interface. Override the getTransformation() method returning a CharSequence with the desired replacement character. Set it via editText.transformationMethod = CustomPasswordTransformation(). Remember that the character must be monospaced for security.
On mobile devices with small screens and touch keyboards, the probability of error when entering a password is significantly higher than on desktop. The ability to verify the entered password reduces input errors and decreases the number of password reset requests, which improves user experience and reduces support load.
Set the FLAG_SECURE flag on the Activity or Dialog window: window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE). This prevents screenshots and screen recording for the entire window. However, note that this will also disable screenshots for regular content, which may be undesirable.
Starting from Android 8.0 (API 26), the Autofill Framework automatically detects password fields by inputType. For correct operation, set importantForAutofill="yes" and specify autofillHints ("password", "newPassword", "emailAddress"). Gboard and password managers use these attributes to suggest saved passwords.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also