Search code examples
javaandroidandroid-keypadinputmethodmanager

In Android, Is there any way to listen Network Changes in the InputMethodService class?


I'm creating a custom keyboard in Android, whenever the keyboard popups, I want to show the popup when the network connection is interrupted, I have tried this in Activity-based classes but this is a different scenario because it's a Service class.

but when it's starting run, keyboard crashes and getting this error message

Error

Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
                    at android.view.ViewRootImpl.setView(ViewRootImpl.java:1159)
                    at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:399)
                    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:133)
                    at android.app.Dialog.show(Dialog.java:345)
                    at com.prasath.openaikeyboard.util.NetworkChangeListener.onReceive(NetworkChangeListener.java:25)
                    at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0$LoadedApk$ReceiverDispatcher$Args(LoadedApk.java:1679)

Thanks in Advance

InputMethodService class

public class MyInputMethodService  extends InputMethodService implements KeyboardView.OnKeyboardActionListener {
    private static final String TAG = "MyInputMethodService";
    private NetworkChangeListener networkChangeListener=new NetworkChangeListener();

    @Override
    public View onCreateInputView() {
        KeyboardView keyboardView=(KeyboardView) getLayoutInflater().inflate(R.layout.keyboard_view,null);
        Keyboard keyboard=new Keyboard(this,R.xml.numberpad);
        keyboardView.setKeyboard(keyboard);
        keyboardView.setOnKeyboardActionListener(this);
        networkChangeListener=new NetworkChangeListener();
        return keyboardView;

    }

NetworkChangeListener class

public class NetworkChangeListener extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(!Common.isConnectedToInternet(context)){
            AlertDialog.Builder builder=new AlertDialog.Builder(context);
            View view= LayoutInflater.from(context).inflate(R.layout.check_internet_dialog,null);
            builder.setView(view);

            Button button=view.findViewById(R.id.btnrefreshid);

            AlertDialog alertDialog=builder.create();
            alertDialog.show();
            alertDialog.setCancelable(false);

            alertDialog.getWindow().setGravity(Gravity.CENTER);

            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    alertDialog.dismiss();
                    onReceive(context,intent);
                }
            });
        }
    }
}

Solution

  • Dialog and its subtypes, like AlertDialog, can only be used from an Activity, not other forms of Context.

    Either:

    • Show your message in your keyboard UI directly, or
    • Start an activity, perhaps one using a dialog theme, to show your message