728x90

 

//EditText 객체에서 onKeyPreIme 메소드를 재정의

    public boolean onKeyPreIme( int keyCode, KeyEvent event ) {
     
   
     Log.d("AutoCallService", "keyCode : "+keyCode+"");
     Log.d("AutoCallService", "event.getKeyCode() : "+event.getKeyCode()+"");
     switch (event.getAction()) {
     
     case KeyEvent.ACTION_DOWN :
     
     if( event.getAction() == KeyEvent.ACTION_DOWN ) {
     if( keyCode == KeyEvent.KEYCODE_BACK ) {
     this.clearFocus();
     

     Log.d("AutoCallService", "onBackPressed()2");
     }
     }
     break;
     
     
     }
   
return super.onKeyPreIme( keyCode, event );
}

Activity 에서 implements OnEditorActionListener 후


/*@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

if(event.getAction() == KeyEvent.ACTION_DOWN)
{
Log.i("AutoCallService", event.getKeyCode()+"");

}
// TODO Auto-generated method stub
return false;
}*/

 

Reference

http://nerobong2.blogspot.com/2015/12/androidedittext.html

728x90
728x90

 

해당 에러 로그

 

Fatal Exception: android.view.WindowManager$BadTokenException

 

 

Fatal Exception: android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@66e8c4 is not valid; is your activity running?
       at android.view.ViewRootImpl.setView(ViewRootImpl.java:1056)
       at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:381)
       at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
       at android.app.Dialog.show(Dialog.java:470)
       at 에러난 액티비티.onRequestComplete(ProductionManagementActivityRe.java:406)
       at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:715)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:214)
       at android.app.ActivityThread.main(ActivityThread.java:7063)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)

 

 

원인1:

BadTokenException이 발생한 원인을 파악하기 위해 오류를 재현하던 중, 같은 코드라도 쓰레드 위치나 라이프 사이클 상의 시점에 따라 간헐적으로 발생하는 것을 발견했다. 쓰레드 위치는 Main Thread가 아닌 Background Thread에서, 주로 AsyncTask의 onPostExecute() 메소드에서 다이얼로그 창을 통해 사용자에게  무엇인가를 알려주려고 시도하는 경우 간헐적으로 발생한다. 발생하는 시점은 Background Thread의 작업이 모두 종료되기 전에 뒤로가기 버튼을 누르거나 명시적으로 finish()메소드를 호출할 때이다. BadTokenException의 이유를 한문장으로 정리하면 , 예외 메시지에 ”is your activity running?” 이라고 명시되어 있듯 종료된 Activity의 context를 인자로 다이얼로그 창을 표시하려고 할 때 발생한다. 다이얼로그 창을 표시할 Activity가 없기 때문에 안드로이드 런타임이 나쁜 토큰(Bad Token1))이라는 예외를 던진다.

 

해결방법1:

해당 UI들을 사용할 때, Activity가 종료되었는 지를 확인하면된다. 만약 종료되었다면 다이얼로그 창을 열지 않으면 그만이다. 다음과 같이 isFinishing() 메소드를 사용하면 Activity의 종료 여부를 확인할 수 있다.

if (! ThisActivity.this.isFinishing()) {
    AlertDialog.builder dialog  = new AlertDialog.builder(ThisActivity.this);
    dialog.setTitle(status);
    dialog.setMessage(message);
    dialog.show();
}

 

원인2: 아래와 같이 activity 하위에 fragment가 있고, 그 중 한 곳에서 dialog를 사용할 때,

AlertDialog.Builder alertDialog = new AlertDialog.Builder(activity);

getActvitiy()가 아니라, activity로 했을 경우

 

 

해결방법2:

activity 일때와 fragment 일때 구분 해서 parameter 값을 넣어주는게 좋은거 같음

activity 대신에 getActivity() 로 하기

final AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());

 

 

원인3: (그런데 위의 2가지 케이스와 달리) 액티비티가 아닌 곳에서 발생한다면? 위 방법을 사용 할 수 없다. 참으로 희한하게도 context는 분명 들어 있는데 다이얼로그를 띄우면 죽는다. 액티비티를 종료 한 것도 아닌데... 보통 해당 프리퍼런스에서 다이얼로그를 띄운뒤 앱을 back키로 디스트로(destroy)이 한 뒤 다시 들어와서 해당 프리퍼런스의 다이얼로그를 띄우면 100% 죽는다. 이 경우에는 context를 static으로 만들어 주면 해결 된다. 


 

 

Reference

https://blog.sangyoung.me/2016/12/28/BadTokenException/

https://cishome.tistory.com/71

https://comoi.io/164

 

728x90
728x90

1. 구글 계정 로그인 Api?

- OAuth 방식

2019/10/07 - [Dev/Etc] - [생활코딩] OAuth 2.0

 

- OAuth를 통해 사용자User(Resource Owner)로부터 허가를 받고 얻어낸 Access Token을 이용하여, Resource Server에서 얻어온 사용자 ID를 통해 사용자를 인증한다.

- 사용자의 허가를 받은 Access Token을 이용한 ID이므로, PW가 없어도 해당 사용자임이 증명되며 로그인 가능하다.

 

2. Android Studio 환경설정

(참고: https://developers.google.com/identity/sign-in/android/start-integrating)

 

1) Project단 build.gradle에 google()추가

allprojects {
    repositories {
        google()

        // If you're using a version of Gradle lower than 4.1, you must instead use:
        // maven {
        //     url 'https://maven.google.com'
        // }
    }
}

 

2) Module단 build.gradle에 

    'com.google.android.gms:play-services-auth:17.0.0' 추가

    (version 참고: https://developers.google.com/android/guides/setup )

 

apply plugin: 'com.android.application'
    ...

    dependencies {
        implementation 'com.google.android.gms:play-services-auth:17.0.0'
    }

 

3) Configure a Google API Console project

To configure a Google API Console project, click the button below, and specify your app's package name when prompted. You will also need to provide the SHA-1 hash of your signing certificate. See Authenticating Your Client for information.

 

 

4) Activity 코드

Configure a Google API Console project and set up your Android Studio project.

 (※코드 추가 전에 구글 Api 콘솔 프로젝트를 설정하고, 안드로이드 프로젝트를 셋업할 것)

// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestEmail()
        .build();

 

sign-in activity의 onCreate에 본인이 원하는 옵션을 정의한 GoogleSignInClient 객체를 생성. 

// Build a GoogleSignInClient with the options specified by gso.
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

sign-in activity의 onStart에 사용자가 구글로부터 당신의 앱에 이미 sign in했는지를 체크하도록 추가.

// Check for existing Google Sign In account, if the user is already signed in
// the GoogleSignInAccount will be non-null.
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
updateUI(account);

추가 참고

https://github.com/googlesamples/google-services

 

 

Reference

https://github.com/googlesamples/google-services

https://developers.google.com/identity/sign-in/android

https://developers.google.com/android/guides/setup

https://galid1.tistory.com/109

 

 

 

728x90
728x90

1. 현상

- Migrate to AndroidX로 변경을 하는데...

  정식 서비스 앱에서는 제대로 잘 변경되었는데, 문제가 터진건 토이프로젝트였음.

  Migration을 잘못한건지 xml에서 이전 그대로 따라가고 잘못 꼬여있었다.

 

2. 수정 경로

 

* AppBarLayout

수정전: android.support.design.widget.AppBarLayout

수정후: com.google.android.material.appbar.AppBarLayout

 

* Toolbar

수정전: android.support.v7.widget.Toolbar

수정후: androidx.appcompat.widget.Toolbar

 

* CoordinatorLayout

수정전: androidx.constraintlayout.ConstraintLayout 

수정후: androidx.coordinatorlayout.widget.CoordinatorLayout

 

android.view.InflateException: Binary XML file line #2: Binary XML file line #2: Error inflating class androidx.constraintlayout.ConstraintLayout

 

 

* ConstraintLayout

수정전: androidx.constraintlayout.ConstraintLayout

수정후: androidx.constraintlayout.widget.ConstraintLayout

 

* FloatingActionButton

수정전: android.support.design.widget.FloatingActionButton
수정후: com.google.android.material.floatingactionbutton.FloatingActionButton

   Caused by: android.view.InflateException: Binary XML file line #12: Binary XML file line #26: Error inflating class android.support.design.widget.FloatingActionButton
     Caused by: android.view.InflateException: Binary XML file line #26: Error inflating class android.support.design.widget.FloatingActionButton
     Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.design.widget.FloatingActionButton" on path: DexPathList[[zip file ~~

 

* CardView

수정전: android.support.v7.widget.CardView
수정후: androidx.cardview.widget.CardView

 

* TabLayout

수정전: android.support.design.widget.TabLayout

수정후: com.google.android.material.tabs.TabLayout

 

* TabItem

수정전: android.support.design.widget.TabItem

수정후: com.google.android.material.tabs.TabItem

 

* TextInputLayout

수정전: android.support.design.widget.TextInputLayout

수정후: com.google.android.material.textfield.TextInputLayout

 

* TextInputEditText

수정전: android.support.design.widget.TextInputEditTextt

수정후: com.google.android.material.textfield.TextInputEditText

 

 

* ViewPager

수정전: androidx.core.view.ViewPager

수정후: androidx.viewpager.widget.ViewPager

     Caused by: android.view.InflateException: Binary XML file line #11: Binary XML file line #11: Error inflating class androidx.core.view.ViewPager
     Caused by: android.view.InflateException: Binary XML file line #11: Error inflating class androidx.core.view.ViewPager

 

Reference:

https://stackoverflow.com/questions/55298742/android-error-inflating-class-android-support-design-widget-appbarlayout

https://stackoverflow.com/questions/42221530/error-inflating-class-android-support-design-widget-floatingactionbutton

728x90

+ Recent posts