마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

버튼클릭 시 뷰 (Layout XML) 을 띄우고 싶은데 안되네요...

0 추천
public class MainActivity extends Activity {
    private View mFaceDialogView = null;
    private Context mContext;
    private WindowManager mWindowManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        Button btn = (Button) findViewById(R.id.button);
        final WindowManager.LayoutParams mFaceDialogParams = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY,
                WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING,
                PixelFormat.TRANSLUCENT
        );

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
                mFaceDialogView = layoutInflater.inflate(R.layout.fingerprint_dialog, null);
                mWindowManager.addView(mFaceDialogView, mFaceDialogParams);
            }
        });
    }

}

이런 식인데...

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?

이란 Error 가 발생하네요... 구글링해보면 getApplicationContext() 대신에 액티비티명.this 를 인자로 보내면 해결이라는데 물론 해봤는데 똑같습니다.

 

해결방법이 없을까요??

 

익명사용자 님이 2018년 7월 16일 질문

1개의 답변

0 추천

onClick 호출 되는 Thread가 ui Thread가 아니라. 꼬이는 듯 합니다.

권한이 있다면, 아래와 같이 핸들러로 처리 해 보세요.

public class MainActivity extends Activity {
    private View mFaceDialogView = null;
    private Context mContext;
    private WindowManager mWindowManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        Button btn = (Button) findViewById(R.id.button);
        final WindowManager.LayoutParams mFaceDialogParams = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY,
                WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING,
                PixelFormat.TRANSLUCENT
        );
 
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                uiHandler.sendEmptyMessage(0);
            }
        });
    }
 
  private Handler uiHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
      switch (msg.what){
        case 0:
        addView();
        break;
      }
    }
  }

    private void addView() {
        LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        mFaceDialogView = layoutInflater.inflate(R.layout.fingerprint_dialog, null);
        mWindowManager.addView(mFaceDialogView, mFaceDialogParams);
    }
}

익명사용자 님이 2018년 7월 16일 답변
(쓴이) 해보았습니다만 결과는 역시 똑같고 에러내용도 똑같네요 ㅠㅠ
흠.. 그럼 다음을 한번 체크 해 보세요.
1. AndroidManifest.xml에 권한추가
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />
2. 롤리팝 이상일 경우
      Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
      intent.setData(Uri.parse("package:" + getPackageName()));
      startActivityForResult(intent, REQUSET_PERMISSION_OVERLAY);

로 런타임 권한 획득 후 수행
3.   WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY 값 대신
                            Build.VERSION.SDK_INT < Build.VERSION_CODES.O ?
                                        WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY :
                                       WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY 로 변경
...