How can I tell if the input method picker is open or closed?
Asked Answered
E

3

13

My app opens the input method picker (the menu where you choose a keyboard) with InputMethodManager.showInputMethodPicker(). My app doesn't actually create the picker (it's created by InputMethodManager) but I know it's a ContextMenu and its id is R.id.switchInputMethod.

enter image description here

The picker is part of a multi-step wizard so I need to know when the picker closes so my app can proceed to the next step. Right now I'm checking in a background thread if the default keyboard changed, but that doesn't help if the user selects the same keyboard or presses back.

So I need a way to tell when the picker closes (or some other clever way to know when to proceed).

Thanks in advance...

Eddins answered 20/12, 2012 at 22:48 Comment(0)
A
0

There is no such mechanism for check InputMethodPicker is open or not.

But you can check it via another way like as using hasWindowFocus() method for check has focus of your root layout.

Below is sample code:

Main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainlayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <Button
        android:id="@+id/btnPicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Picker" />

    <Button
        android:id="@+id/btnCheck"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Stop" />

</LinearLayout>

DemoappActivity.class

public class DemoappActivity extends Activity {
    /** Called when the activity is first created. */


    Button btn1 , btn2;
    InputMethodManager imeManager;

    LinearLayout mLayoutRoot;
    TimerTask timertask;
    Timer timer;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mLayoutRoot = (LinearLayout)findViewById(R.id.mainlayout);
        imeManager = (InputMethodManager) getApplicationContext().getSystemService(INPUT_METHOD_SERVICE);
        btn1 = (Button)findViewById(R.id.btnPicker);
        btn1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                showInputMethodPicker();
            }
        });
        btn2 = (Button)findViewById(R.id.btnCheck);
        btn2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                timer.cancel();
            }
        });
        checkMyWindowHasFocus();
    }
    @Override
    protected void onDestroy() {

        timer.cancel();
        super.onDestroy();
    }

    public void checkMyWindowHasFocus()
    {
        timertask = new TimerTask() {

            @Override
            public void run() {
                System.out.println("has window focus..."+mLayoutRoot.hasWindowFocus());
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(), "Has focus "+mLayoutRoot.hasWindowFocus(), Toast.LENGTH_SHORT).show();
                    }
                });
            }
        };
        timer = new Timer();
        timer.schedule(timertask, 500, 5000);

    }

    private void showInputMethodPicker() {

        if (imeManager != null) {
            imeManager.showInputMethodPicker();

        } else {
            Toast.makeText(this, "Error",Toast.LENGTH_LONG).show();
        }
    }
}
Abisia answered 27/12, 2012 at 5:56 Comment(3)
so you mean to say if your Root Layout isn't having focus then it means InputMethodPicker is opened? then what about other cases which takes root layout focus away?Fiction
This works quite well, except I think Activity.onWindowFocusChanged() is better than a background thread. I'm still testing the code and will reply again soon. Thank you.Eddins
Thanks very much for your answer! I never would have thought to check window focus. Your solution works great (although I prefer using onWindowFocusChanged()).Eddins
B
17

Here is a small trick. Please do test it and let us know if it works.

All you have to do is make your activity extend this InputMethodActivity. When you need the user to pick input method, call pickInput(), and onInputMethodPicked() will be called when the user is done.

package mobi.sherif.inputchangecheck;

import android.os.Bundle;
import android.os.Handler;
import android.content.Context;
import android.support.v4.app.FragmentActivity;
import android.view.inputmethod.InputMethodManager;

public abstract class InputMethodActivity extends FragmentActivity {
    protected abstract void onInputMethodPicked();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mState = NONE;
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if(mState == PICKING) {
            mState = CHOSEN;
        }
        else if(mState == CHOSEN) {
            onInputMethodPicked();

        }
    }

    private static final int NONE = 0;
    private static final int PICKING = 1;
    private static final int CHOSEN = 2;
    private int mState;
    protected final void pickInput() {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showInputMethodPicker();
        mState = PICKING;
    }
}
Brinker answered 28/12, 2012 at 11:48 Comment(5)
Why do you post the call to onInputMethodPicked() instead of calling it directly?Eddins
Thank you for your answer! It is correct and I prefer using onWindowFocusChanged(), but I awarded the bounty to CapDroid since he answered first with essentially the same answer as yours (check window focus).Eddins
For me, this only sort of worked. I'm Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); to determine if my keyboard was selected, however, I don't think the value is set when onInputMethodPicked is called. I ended up adding a Handler to the class, and postDelaying by 300ms the implementation just so the value returned could settle. Its hacky, but it worked.Anagrammatize
Please pardon me, but how/where do I call pickInput()? I tried to assign it to a button's onclick listener by doing pickInput();, but it says that the method cannot be resolved.Whitehot
@ErlendK.H.You must extend this activity or just copy and paste all the methods to your own activity.Gloriagloriana
A
0

There is no such mechanism for check InputMethodPicker is open or not.

But you can check it via another way like as using hasWindowFocus() method for check has focus of your root layout.

Below is sample code:

Main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainlayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <Button
        android:id="@+id/btnPicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Picker" />

    <Button
        android:id="@+id/btnCheck"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Stop" />

</LinearLayout>

DemoappActivity.class

public class DemoappActivity extends Activity {
    /** Called when the activity is first created. */


    Button btn1 , btn2;
    InputMethodManager imeManager;

    LinearLayout mLayoutRoot;
    TimerTask timertask;
    Timer timer;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mLayoutRoot = (LinearLayout)findViewById(R.id.mainlayout);
        imeManager = (InputMethodManager) getApplicationContext().getSystemService(INPUT_METHOD_SERVICE);
        btn1 = (Button)findViewById(R.id.btnPicker);
        btn1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                showInputMethodPicker();
            }
        });
        btn2 = (Button)findViewById(R.id.btnCheck);
        btn2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                timer.cancel();
            }
        });
        checkMyWindowHasFocus();
    }
    @Override
    protected void onDestroy() {

        timer.cancel();
        super.onDestroy();
    }

    public void checkMyWindowHasFocus()
    {
        timertask = new TimerTask() {

            @Override
            public void run() {
                System.out.println("has window focus..."+mLayoutRoot.hasWindowFocus());
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(), "Has focus "+mLayoutRoot.hasWindowFocus(), Toast.LENGTH_SHORT).show();
                    }
                });
            }
        };
        timer = new Timer();
        timer.schedule(timertask, 500, 5000);

    }

    private void showInputMethodPicker() {

        if (imeManager != null) {
            imeManager.showInputMethodPicker();

        } else {
            Toast.makeText(this, "Error",Toast.LENGTH_LONG).show();
        }
    }
}
Abisia answered 27/12, 2012 at 5:56 Comment(3)
so you mean to say if your Root Layout isn't having focus then it means InputMethodPicker is opened? then what about other cases which takes root layout focus away?Fiction
This works quite well, except I think Activity.onWindowFocusChanged() is better than a background thread. I'm still testing the code and will reply again soon. Thank you.Eddins
Thanks very much for your answer! I never would have thought to check window focus. Your solution works great (although I prefer using onWindowFocusChanged()).Eddins
W
0

Simple you can know by using buildin function:

 @Override
        public void onWindowFocusChanged(boolean hasFocus) {
            super.onWindowFocusChanged(hasFocus);
            isMyInputMethodEnabled();// write what ever you want to do after default keyboard selected
        }


  public void isMyInputMethodEnabled() {
        String imId = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
        if (imId.contains(getPackageName())) {
            startActivity(new Intent(this, Main_uk.class));
            finish();
        }
    }
Warthman answered 5/3, 2019 at 11:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.