Jospehus Chou
Jospehus Chou

Reputation: 117

How to use the back press to remove the view added by WindowManager?

guys, I am developing an android AppLock Application, and I use WindowManager to add a gesture lock view. but I have a problem. back key press doesn't remove the view. And I can't rewrite the View to override the dispatchKeyEvent() function, as I use LayoutInflater to inflate my view. Just like that:

LayoutInflater layoutInflater = 
            (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
enterPassView = layoutInflater.inflate(R.layout.activity_enterpass, null);

Please help me to slove this problem! Thank you.


Add in UTC+8 2014/12/31 18:20

hello, I am so happy as I use a simple way to solve my problem. I use two flag variable, one is viewFlag(when I call addView( ), viewFlag = true; and when I call removeView( ), viewFlag = false), the other one is lockedFlag(when the top App is locked by user add in database, lockedFlag = true, and when it's not locked, lockedFlag = false) So, if(lockedFlag == false && viewFlag == true && view != null) { //I send message to a handler to call removeView( ) }


class EnterPassView extends View {

    public EnterPassView(Context context) {
        super(context);
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if(event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            Message message = viewHandler.obtainMessage(0);
            viewHandler.sendMessage(message);
            return super.dispatchKeyEvent(event);
        } else if(event.getKeyCode() == KeyEvent.KEYCODE_HOME) {
            Message message = viewHandler.obtainMessage(0);
            viewHandler.sendMessage(message);
            return super.dispatchKeyEvent(event);
        } else if(event.getKeyCode() == KeyEvent.KEYCODE_MENU) {
            Message message = viewHandler.obtainMessage(0);
            viewHandler.sendMessage(message);
            return super.dispatchKeyEvent(event);
        }
        return super.dispatchKeyEvent(event);
    }

}

private void showGestureLockView() {
    params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT, 
            WindowManager.LayoutParams.MATCH_PARENT, 
            WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, 
            WindowManager.LayoutParams.FLAG_FULLSCREEN | 
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, 
            PixelFormat.RGBA_8888);
    params.gravity = (Gravity.CENTER);

    LayoutInflater layoutInflater = 
            (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    enterPassView = layoutInflater.inflate(R.layout.activity_enterpass, null);

    iv_icon = (ImageView) enterPassView.findViewById(R.id.enterpass_iv_icon);
    tv_text = (TextView) enterPassView.findViewById(R.id.enterpass_tv_text);

    animation = new TranslateAnimation(-20, 20, 0, 0);
    animation.setDuration(50);
    animation.setRepeatCount(2);
    animation.setRepeatMode(Animation.REVERSE);

    SharedPreferences sp = getSharedPreferences(AppConfig.APP_SP_NAME, MODE_PRIVATE);
    String savePass = sp.getString(AppConfig.GESTURE_PASS, "");
    gesturePassView = (GesturePassView) enterPassView.findViewById(R.id.enterpass_view_gpv);
    gesturePassView.setSavedPass(savePass);
    gesturePassView.setScene(0);
    gesturePassView.setOnGestureCompleteListener(new OnGestureCompleteListener() {

        @Override
        public void onGestureComplete(int result, String enterPassword) {
            if(result == 0) {
                iv_icon.setAnimation(animation);
                tv_text.setText(R.string.enterpass_lesspass);
            } else if(result == 1){
                Message message = viewHandler.obtainMessage(0);
                viewHandler.sendMessage(message);
                Log.e("sendMessage", "pass is true want to remove view");
            } else if(result == -1){
                iv_icon.setAnimation(animation);
                tv_text.setText(R.string.enterpass_wrongpass);
            }
        }
    });

    if(windowsManager == null) {
        windowsManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
    }
    if(windowsManager != null && enterPassView != null) {
        Message message = viewHandler.obtainMessage(1);
        viewHandler.sendMessage(message);
        Log.e("sendMessage", "want to addView");
    }

}

Handler viewHandler = new Handler() {

    @Override
    public void handleMessage(Message message) {
        int flag = message.what;
        if(flag == 1) {
            windowsManager.addView(enterPassView, params);
            Log.e("sendMessage", "addView");
        } else if(flag == 0) {
            windowsManager.removeView(enterPassView);
            enterPassView = null;
            Log.e("sendMessage", "removeView");
        }

    }

};

Upvotes: 1

Views: 2666

Answers (2)

Mikelis Kaneps
Mikelis Kaneps

Reputation: 4584

Here is a pseudo code that could help.

  1. Create a public method in your view that calls this:

    windowsManager.removeView(enterPassView);

  2. And then in your activity override onBackPressed. http://developer.android.com/reference/android/app/Activity.html#onBackPressed()

  3. In the overriden onBackPressed call the method that you created in your custom View class. Make a try catch statement:

    try{ YourView.removeWindowView() }catch(IllegalArgumentException e){ //if it comes here that means that the there is no view to remove from windowsManager - in this case call super.onBackPressed(); }

Edit. Here is the code that solves the problem:

public class MainActivity extends Activity {
    private MyService mServer;
    ServiceConnection mConnection = new ServiceConnection() {

        public void onServiceDisconnected(ComponentName name) {

        }

        public void onServiceConnected(ComponentName name, IBinder service) {

            LocalBinder mLocalBinder = (LocalBinder) service;
            mServer = mLocalBinder.getServerInstance();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(MainActivity.this, MyService.class);
        bindService(intent, mConnection, BIND_AUTO_CREATE);

    }
    @Override
    public void onBackPressed() {
        try{
            mServer.removeWindow();
        }
        catch(IllegalArgumentException e){
            super.onBackPressed();
        }


    }

}

public class MyService extends Service {

    Thread thread;
    WindowManager windowsManager = null;
    WindowManager.LayoutParams params;
    View view;

    IBinder mBinder = new LocalBinder();


    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    public class LocalBinder extends Binder {
        public MyService getServerInstance() {
            return MyService.this;
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                showView();
            }

        }, 5000);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    private void showView() {
        params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT, 
                WindowManager.LayoutParams.MATCH_PARENT, 
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 
                WindowManager.LayoutParams.FLAG_FULLSCREEN | 
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, 
                PixelFormat.RGBA_8888);
        params.gravity = (Gravity.CENTER);
        LayoutInflater layoutInflater = 
                (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = layoutInflater.inflate(R.layout.view_service, null);
        if(windowsManager == null) {
            windowsManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        }
        if(windowsManager != null && view != null) {
            Message message = addViewHandler.obtainMessage(1);
            addViewHandler.sendMessage(message);
        }

    }

    Handler addViewHandler = new Handler() {

        @Override
        public void handleMessage(Message message) {
            int flag = message.what;
            if(flag == 1) {
                windowsManager.addView(view, params);
            } else if(flag == 0) {
                windowsManager.removeView(view);
            }
        }
    };
    public void removeWindow(){
        windowsManager.removeView(view);
    }

}

Upvotes: 1

binaryKarmic
binaryKarmic

Reputation: 988

The code snippets are not enough to understand and answer the best one. What comes to mind is attach a keylistener to your view and in handle the event saying ((ViewGroup)enterPassView.getParent()).removeView(enterPassView );

Upvotes: 0

Related Questions