When developing Android applications—especially enterprise apps for warehouse devices, handheld barcode scanners (like Zebra or Honeywell), or custom kiosk hardware—you often need an EditText to receive focus immediately on launch to capture scanner input without displaying the soft keyboard.

However, many developers find that calling requestFocus() inside onCreate() triggers the virtual keyboard anyway, and traditional calls to InputMethodManager.hideSoftInputFromWindow() seem to fail due to timing and window initialization issues. Here is a complete guide to cleanly preventing the soft keyboard from opening while keeping focus on your EditText.

Why Does the Keyboard Still Appear?

In Android, the window token is not yet fully bound to the decor view inside onCreate(). When you request focus during initialization, the system queues a request to show the Input Method Editor (IME). Calling imm.hideSoftInputFromWindow() at that exact moment often fails because the window token is null or the show command executes right after your hide command.

Solution 1: Use showSoftInputOnFocus = false (Recommended)

Since API level 21, Android has provided a built-in property designed specifically for this scenario: showSoftInputOnFocus. Setting this property to false allows the view to maintain focus without ever requesting the soft input.

Ensure this is set before requesting focus:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val barcodeEditView = findViewById<EditText>(R.id.editTextText)

    // Prevent the soft keyboard from ever showing when focused
    barcodeEditView.showSoftInputOnFocus = false

    // Safely request focus
    barcodeEditView.requestFocus()
}

Solution 2: Configure windowSoftInputMode in AndroidManifest.xml

To prevent Android from auto-opening the keyboard during Activity creation, declare the soft input mode directly in your AndroidManifest.xml:

<activity
    android:name=".MainActivity"
    android:windowSoftInputMode="stateAlwaysHidden">
</activity>

This guarantees that when the Activity launches, the system will actively suppress the keyboard regardless of initial view focus requests.

Solution 3: Hide the Keyboard via Modern AndroidX APIs

If you still need to dismiss an already active keyboard programmatically, avoid using the deprecated InputMethodManager window token pattern. Use WindowInsetsControllerCompat, which cleanly abstracts window state across all Android versions:

import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat

fun hideSystemKeyboard() {
    val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
    windowInsetsController.hide(WindowInsetsCompat.Type.ime())
}

Solution 4: For Hardware Barcode Scanners (Null Input Type)

If the EditText solely exists as a keystroke receiver for a hardware barcode wedge scanner and human touch typing is never expected, you can disable the soft input connection completely by setting the input type to TYPE_NULL:

barcodeEditView.inputType = android.text.InputType.TYPE_NULL
barcodeEditView.requestFocus()

Complete Clean Implementation

Combining these techniques provides a robust, fail-safe solution that functions reliably across Android versions:

import android.os.Bundle
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat

class MainActivity : AppCompatActivity() {

    private lateinit var barcodeEditView: EditText

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        barcodeEditView = findViewById(R.id.editTextText)

        // 1. Tell EditText never to trigger the IME on focus
        barcodeEditView.showSoftInputOnFocus = false

        // 2. Request view focus
        barcodeEditView.requestFocus()

        // 3. Post a clean fallback dismiss using Modern Insets API
        barcodeEditView.post {
            WindowCompat.getInsetsController(window, window.decorView)
                .hide(WindowInsetsCompat.Type.ime())
        }
    }
}

Summary

  • Always prefer showSoftInputOnFocus = false over manually listening for focus changes and closing the keyboard.
  • Use android:windowSoftInputMode="stateAlwaysHidden" in the manifest to prevent startup popups.
  • Replace legacy InputMethodManager calls with WindowCompat.getInsetsController() for reliable keyboard management.