너무 오랜만에 글을 써서 어색하다. 요 며칠 동안 코딩 테스트, 스마트 스토어 준비, 회사 앱 개발, 마블 정주행 등등.. 아무쪼록 빈틈없는 바쁜 날들을 보내고 있다. 오늘은 카카오톡 로그인 기능을 구현하고, 디버그와 릴리즈 해시 키를 등록하였음에도 불구하고, KakaoTalk is installed but not connected to Kakao account. 같은 오류가 뜨는 이유를 알아보자. 위에 영어 뜻은 카카오톡은 설치되엇지만, 카카오 계정이 연결되지 않았다는 뜻이다. 말 뜻 그대로, 카카오톡은 설치했지만, 카카오톡 로그인을 하지 않았다는 뜻이다. 이에 대한 예외 처리를 해주면 된다. 다음 코드를 보자. public void signInKakao(Context context) { this.co..
오늘은 간단히 터미널로 private 되어 있는 깃 레포지터리를 가져오는 방법을 알아보겠다. git clone https://[git userName]:[git password or git token]@github.com/[repositary path] 정말 간단하다 터미널에 다음과 같이 입력한다. git userName은 이 녀석이고, git password or git token에다가는 깃 비밀번호나 토큰 값을 넣어주면 된다. 나 같은 경우는 토큰을 넣었다. 그리고 repositart path에다가는 깃 주소를 넣어준다. 이 드래그 친 부분을 넣어주면 된다. 이런식으로 넣어주면 된다.
안드로이드 레트로핏을 연동 rxJava2를 통해 스트림으로 서버를 호출하였다. 그런데 하루 종일 다음과 같은 오류가 계속 떴다. Unable to create call adapter for io.reactivex.Observable for method LeaveOutApi.postLeaveOutUser 호출하는 어뎁터를 만들 수 없다는 뜻인 것 같은데, 해결법을 찾아보니, .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) 레트로핏 빌더에다가 다음과 같은 AdapterFactory를 추가해주라는 것이었다. 하지만 이미 난 레트로핏에다가 추가를 해주었다. 그렇다면 무엇이 문제일까? 문제는 이것이었다. REST를 호출하는 인터페이스 부분에서 Observa..
요즘 일찍 일찍 자는 중이다. 취미도 잘 즐기고 있고, 코딩도 즐겁게 하고 있다. 12시에 자야 하고, 배운 것도 써야 하니, 오늘 배웠던 것은 크립토 라이브러리이다. https://developer.android.com/guide/topics/security/cryptography?hl=ko 암호화 | Android 개발자 | Android Developers Android의 암호화 기능을 알아보세요. developer.android.com 자세한 정보는 이 곳에서 볼 수 있다. 암호화는 보통 로그인을 할 때 아이디나 비밀번호 등 보안을 위한 값들(키 스토어 라이브러리 사용을 하는 경우이지만 여기서는 암호화)을 보통 암호화를 해주고 서버에 보내주곤 한다. 보통 크게 암호화에는 두 가지가 있다. 대칭 암..
이 글은 간단한 인터페이스에 대한 예제만을 보여드립니다. 깊게는 들어가지 못하는 제 게으름과 실력을 탓합니다. flutter만 하다가 자바로 넘어온 지 어언 2주가 넘어간다. 문득 궁금한 기능이 생겼는데, 바로 A라는 액티비티에 있는 메서드를 내가 B액티비티 혹은 프래그먼트에 있을 때, 실행시키고 싶다면 어떻게 해야 할까? flutter에 경우는 생성자로 Function을 넘겨주어 그 function을 실행하면, 생성자를 넘겨준 쪽에서 이 함수가 실행이 되었다. 그렇다면 자바에서 어떻게 할까? 바로 인터페이스다. 나도 항상 이 인터페이스를 그날그날 이해하면서도, 잘 모르고 넘긴 경우가 있다. 사실은 아직도 잘 모르지만, 이번에 내가 위와 같은 상황에서 인터페이스를 활용하는 법을 기록하기 위해 적어둔다. ..
간혹 이런 일이 있는 듯하다. 나 또한, 회사에서 디바이스별로 대응하기 위해서도 있지만, 일반적인 디바이스와 태블릿 디바이스로 크게 나누었을 때, 일반적인 디바이스에서 크기를 고정해서 앱을 출시하는 쪽으로 가는 경우 말이다. 그런 경우 때문에 회사에 요구대로 기존 텍스트를 sp로 사용했던 것을 dp로 변환하는 작업을 하게 되었다. 하지만, 이미 만들어진 앱은 모든 text가 sp로 되어 있었다. 나는 그래서 답을 찾았다. sp로 되어 있어도, 모든 앱을 sp 자체를 고정시킨 값으로 디바이스에 적용시킬 수 있다. 바로 다음 코드이다. @Override protected void attachBaseContext(Context newBase) { final Configuration override = new ..
현재 회사의 앱에서 영어와 한국어, 이렇게 두 글로벌 언어를 두고, 기기에서 언어에 맞게 대응하고 있다. 그러다가, 자바 코드에서 언어뿐만 아니라, 해당 언어에 따라, ui나 메서드를 달리하고 싶은 일이 생겼다. 그렇게 해서 알아낸 코드가 이것이다. Locale mSysLocale = getResources().getConfiguration().locale; String strLanguage = mSysLocale.getLanguage(); 다음 코드를 사용하면, 현재 디바이스에 설정되어 있는 언어 코드가 String에 담긴다. 메서드를 만들어 예를 들면 public class MainActivity extends AppCompatActivity { @Override protected void onCre..
2021.11.26 - [Programing/Android Studio With Java] - Android Studio/ Java Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0. 오류 해결하기 TIL # 71 Android Studio/ Java Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0. 오류 해결 안드로이드 스튜디오에서 자바로 main를 두고 어느 때와 다름없이 RunTime 버튼을 눌렀는데 다음과 같은 오류가 떴다. Deprecated Gradle features ..
안드로이드 스튜디오에서 자바로 main를 두고 어느 때와 다름없이 RunTime 버튼을 눌렀는데 다음과 같은 오류가 떴다. Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0. 빌드 시에 deprecated 된 기능들이 있어서 현재의 gradle과 호환이 맞지 않다는 이야기이다. 그 아래에 --warning mode all을 사용하라고 명시까지 해주었다. 그렇다면, 이 녀석을 어디서 사용할까? 맥은 preferences로 윈도는 settings로 가게 되면, Build, Execution, Deployment -> Compiler를 들어가면, Command-line Options 입력창에 --w..
최근 sdk 버전 31까지 나와 이러한 오류가 뜬 것 같다. The minCompileSdk (31) specified in a dependency’s AAR metadata is greater than this module’s compileSdkVersion 이 말인즉슨, 현재 사용되는 라이브러리 패키지들의 최소 sdk 버전이 이 앱의 compileSdkVersion 보다 크다고 한다. 그러면 우리는 compileSdkVersion을 31로 바꾸어 주면 된다. android { compileSdkVersion 31 //
로딩 창을 간단히 띄우는 법에 대해 소개하려고 한다. 우선 로딩 창 화면을 만들기 위해 SplashActivity라는 이름으로 EmptyActivity를 하나 만들어 주자. 현재 나는 뷰바인딩을 같이 쓰고 있는 상태이다. public class SplashActivity extends AppCompatActivity { ActivitySplashBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivitySplashBinding.inflate(getLayoutInflater()); setContentView(binding.get..
네이티브로 돌아온 느낌은 꽤나 신선하다. 오늘은 현직에서도 자주 사용되고 있는 Retrofit을 다루려고 한다. 보통 서버 api 통신을 할 때 편리하고 간단하게 사용될 수 있는 라이브러리로써 많은 사람들에게 사랑받고 있는 라이브러리라고 할 수 있다. 그렇다면 한 번 예제를 봐보자. 사용법 dependencies { //retrofit2 implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' } 우선 이 두 종속성을 build.gradle(:app)에 추가를 해주는 것으로 시작합니다. 최신 버전이 있다면 버전을 올려주세요! 여기서 잠깐 알고 갈 것!! g..
코딩을 하다 보면 배우고 싶거나 모르는 라이브러리에 대한 소스코드를 찾아다니게 된다. 나 같은 경우는 githup에서 소스코드를 찾는 경우가 있는데, 깃 헙 홈페이지에서 소스를 참고하면서 라이브러리 예제를 보면서 적용을 할 수가 있다. 혹은 예제 소스를 그대로 다운을 받아 우리가 빌드를 해보려고 시도하는 경우가 있는데, 아주 자주자주 이 오류와 마주치게 된다. could not resolve com.android.tools.build:gradle:x.x.x. could not resolve all files for configuration ':classpath'. No cached version of com.android.tools.build:gradle:4.0.0 available for offline..
앱을 출시하기에 앞서 실수로 광고를 삽입하지 못해, 처음 앱을 출시하느라 복잡한 설명 속에서 헤매던 중, 실수로 스토어 키를 삭제해 버렸다... 그래서 방법을 찾아보니, 우선 새로운 키를 만들고 그 키를 pem 파일로 만들어 구글에 제출을 하면 된다고 한다. 어디 한 번 방법을 보자. 해결법 우선 키를 새로 만들어 보자. 우선 이런식으로 APK나 번들 키를 새로 생성해보자. 그러면 이런식으로 jks파일이나, apk 파일이 생성이 되었을 것이다. 이제 이 파일을 pem파일로 변환해보자. 명령 프롬프트나 안드로이드 내의 터미널을 사용하면 된다. 이런 식으로 써보자. keytool -export -rfc -alias [내가 지정한 alias키 이름] -file [pem키 이름 지정 아무거나 상관X].pem -..
안녕하세요. 이제 금연 설루션 그만 앱 프로젝트에 막바지가 왔습니다. 애드몹 광고를 달고 진작해야 했던, 데이터베이스에 비밀번호를 해시화하는 작업이 필요했다. 어려울 것이라고 고민했다. 서버단은 서로 통신하는 법만 간단히 알고 있지, 비밀번호를 보안성 있게 해시화하는 법은 아마 어렵지 않을까 생각이 들었다. 여러 방법들이 있겠지만, 내가 찾은 방법은 SHA-2이다. SHA-2는 Secure Hash Algorithm의 약자이다. 해시 알고리즘은 값을 입력받아, 고정된 길이의 해시값(64, 128) 등등으로 해시값을 출력하는 알고리즘이다. 암호 알고리즘에는 키가 사용되고, 알고리즘 함수는 키를 사용하지 않습니다. 그래서 같은 입력에 대해 항상 같은 출력이 나오게 된다. 이 알고리즘을 쓰는 이유는 동일한 값..
최근에 이제 프로젝트로 마무리하고 있는 앱에 집중적으로 투자하기 위해 글을 많이 쓰지 못했다. 그래도 배운 것을 기록하는 것도, 매일 코딩하는 것 못지 않게 중요하다고 생각한다. 이제 장장 4달이 되어가는 이 앱 만들기도 끝이 보인다. 오늘 내 앱에 적용한 것은 적응형 광고와 전면 광고 다는 법이다. 순서대로 보겠다. 적응형 광고 띠 배너인 적응형 광고는 기존 스마트 배너(이제 없어진다고 함)에 비해 훨씬 더 앱에 사이즈에 맞게 최적화 되어 알맞게 사이즈가 자동으로 맞춰지는 띠배너이다. 다음은 내가 만든 앱에 일부분이다. 그림과 같이 아래에 내비게이션 뷰에다가 배너를 달아 다른 프래그먼트로 이동해도 계속해서 보이게 해두었다. 우선 구글에 로그인을 하여 애드몹도 가입해서 unit키를 와 id키를 얻어오는 ..
어제부터 리사이클러뷰를 습득하느라 정신이 없었다. 다 습득하고 나서 정리해볼 생각이다. 오늘은 인텐트로 넘어온 데이터가 널이거나, 값에 따라 다르게 처리를 하고 싶을 때 사용하는 인텐트 널처리에 대해서 알아보겠다. /**인텐트 널체크 및 구분*/ private void getIntentValue() { Intent intent = getIntent(); if(!TextUtils.isEmpty(intent.getStringExtra("Rtitle"))){ //인텐트 널체크 만약 Rtitle이라는 글자가 안비어 있다면, title = intent.getStringExtra("Rtitle"); mainText = intent.getStringExtra("RmainText"); saveDateV = intent..
오늘은 집중해서 만들고 있는 프로젝트에 진도를 많이 쭉 뺐다. mysql과 연동을 위해 볼리를 많이 이용했는데, 잘하다가 다음과 같은 문제가 생겼다. 다음과 같이 사진에서 위에 테두리도 밑에 둥글기와 같이 둥글게 나와야 하는데, 직각으로 저런 식으로 표시되는 것이다. 물론 이미지를 넣지 않을 때는 xml 속성으로 설정해놓아서, 이런 식으로 나온다. 아 물론 scaleType을 fitCenter로 하면 다음과 같이 잘 나오지만, 내가 원하는 것은 centerCrop속성이었다. 이상하게 이 속성으로 이미지 뷰에 이미지를 넣으면, 저렇게 둥글기가 사라지는 것이었다. 커뮤니티에 물어보니 원래 이미지 뷰에 이미지를 넣으면 저런 상태가 된다는 것이다. 그래서 비트맵으로 변환해서 크기를 조정해 넣으라는데... 잘 몰..
한 주가 지나갔다. 이제는 초조하고, 마음이 답답해서 하루빨리 이곳을 나가고 싶지만, 침착해야 한다. 거의 앱은 완성되었고, 아직 나는 부족하다. 하지만, 더 배우기 위해서는 현장에 나가보고 사람들도 만나봐야 한다고 생각한다. 오늘은 만들고 있는 앱에 일기 기능을 위해서 한 칼럼에 내용을 모두 가져오는 php구문과 그 값을 안드로이드 스튜디오에서 받는 법을 쓸 생각이다. 해결법 나 같은 경우는 각 회원마다 고유의 번호(num)를 주고, 그 번호가 붙어있는 개인의 Diary테이블을 만들어서 일기 내용을 따로 저장하는 법을 사용했다. 그 과정에서 일기를 쓴 날짜를 모두 가져와야 할 상황이 생겼다. 그래서 sql문을 $query = "SELECT startdate FROM `Diary$num`"; 이런 식으로..
며칠 동안 프로젝트 만드는 데 고전하느라, 빨리빨리 넘어가서 이것저것 쓸 것이 많다. 오늘은 시간이 늦어서 간단하게 배운 사실을 쓰려고 한다. 끝내주는 캘린더뷰 라이브러리를 사용 중인데, 나중에 참고해서 올리려고 한다. 오늘 소개할 내용은 ArrayList 안에 값이 있는지 없는지 확인해야 하고, 만약 있다면, 어떤 동작을 실행할 수 있을지, 결정할 수 있는 메서드입니다. 바로 contain() 메서드입니다. 사용법은 간단합니다. // 어레이 리스트에 {"안녕", "누구", "세요"}가 들어있을때, ArrayList aL = new ArrayList(); aL.contain("안녕"); // 값이 있으면 true// 아니면 false; //if문으로 나타내보자 if(aL.contain("안녕")){ //..
오늘은 아쉬운 점이 있던 부분을 보안하여 새로운 방법을 알아냈기에 글을 써본다. 금연 앱도 거의 마무리했고, 현재 금연일기를 만드는 중이다. 사실 저번 글에서 mysql에 blob을 통해 이미지를 저장하는 법을 올렸는데, 디비에 저장하는 법을 알았지만, 그 저장된 것을 가져오는 부분을 공부하던 중, 커뮤니티에서 그런 방법보다는 서버에 이미지를 올려서 그 url를 연동하는 법이나, 파이어 베이스에 스토리지를 올리는 편이 간단하고, 효율이 좋다는 이야기를 듣게 되었다. 마침 잘 안 풀리기도 했고, 그래도 끝까지 blob으로 이미지를 가져오게 하는 법을 알고, 마무리하고 싶었지만, 뜻대로 된 것 같지는 않다. ㅠㅠ 그래서 이 blob은 이 정도 까지만 알고(언젠가 배울 날이 올 것이다.) 더 효율적이라는 파이..
오랜만에 글을 쓴다. 최근 주말 동안 비트코인이라는 신세계에 빠져서 안드로이드의 신경을 많이 쓰지 못했다. 그래서 그런지 막상 하려니까 머리가 복잡해지고 힘들었지만, 금방 다시 집중이 되어서 무사히 이미지 BLOB이란 기술을 오늘 알게 되었다. 사실 오늘도 삽질을 오래 하게 되었는데, 원래는 저번시간에 phpmyadmin에 디바이스에 사진 경로만 저장해서 보는 법을 올렸다. 2021.03.10 - [Programing/Android Studio With Java] - 안드로이드 phpmyadmin 연동 / 이미지 경로를 phpmyadmin에 올려보자. / 데이터 베이스 이미지 저장하고 불러오기 TIL # 14 안드로이드 phpmyadmin 연동 / 이미지경로를 phpmyadmin에 올려보자. / 데이터 ..
뒤늦게 수정합니다 이미지 경로만 저장하여 하나의 디바이스에서만 불러 올 수 있습니다. 이 부분을 저도 착각하여 다음시간에 이미지 저장 후 불러오기 mysql편으로 올리겠습니다 오늘 프로필 이미지를 만들었지만, 또 하나 고전했던 것이 기존에 쓰던 데이터베이스에 이미지를 저장하고 불러오는 법을 알아내는 것이었다. 이렇게 복잡한 일이었을까? 아직 내가 초보라서 그런지, 정말 복잡한 방법들이 많았다. 나 같은 경우는 우분투 서버를 AWS EC2로 사용하고 있었기에, 구글링을 통해서 얻은 정보는 파이어 베이스를 사용해라.. 리눅스 서버를 사용해라 등등 지금 내 상황에 맞지 않는 답변들 밖에 없었다. 그래서 준비했다. 정말 간단히 이미지를 저장하고 불러오는 방법이다. 우선 phpmyadmin을 구축을 한 상태에서 ..
프로필을 만드는 중에 갤러리에서 이미지만 가져오려고 여러 기능 들을 찾아보았다. 권한도 주고, 복잡한 기능들이 많았는데, 나는 간단히 갤러리에 사진만 가져올려고 했기 때문에, 이 정도로 힘든 작업인가.. 하고 망설여졌다. 그러다가 방법을 알아냈다. 해결책 정말 간단하다. 우선 갤러리에서 이미지를 가져올때, 이미지가 회전되어서 이미지 뷰에 담기는 현상이 있는데, 이러한 현상은 기기마다 다르다고 한다. 해결하는 방법은 글라이드 라이브러리를 통해서 이미지뷰에 이미지를 넣는 방법이 있다. 우선 라이브러리를 설치하자. dependencies { implementation 'com.github.bumptech.glide:glide:3.7.0' } 그리고 난 후 MainActiviy.java public class ..
주말을 보내고 다시 빡세게 코딩 준비중이다. 오늘 잠시 로딩창을 간단하게 구현하기 위해 구글링을 하면서 알게 된 사실들을 적어본다. andro-jinu.tistory.com/entry/androidstudio2 [안드로이드 스튜디오] 로딩창 구현 (ProgressBar) 이번 포스팅에서는 커스텀 프로그레스바를 만들텐데 대기시간이 필요할때 주로 사용되는 로딩창을 프로그레스바로 구현해보도록 하겠습니다. 먼저 새로운 프로젝트를 생성합니다. 템플릿은 andro-jinu.tistory.com 출처를 밝힙니다! 로딩창 만들기 public class ProgressDialog extends Dialog { public ProgressDialog(Context context) { super(context); // 다이..
이번주의 마무리가 되었다. 벌써 금요일이다. 개발을 하면서 하루하루 시간이 정말 빨리 가는 것 같은 느낌이다. 오늘은 만들고 있던 앱이 프래그먼트에서 프래그먼트로 이동할 때, 값이 초기화 되고 있다는 사실을 깨달았다. 값을 주고 프래그먼트 생명주기에 하나씩 값을 주면서 연구해 보았지만, onAttach가 제일 먼저 생성이 됨에도, 초기화를 막을 방법이 없다는 사실을 깨달았다. 그래도 포기하지 않고, 액티비티의 생명주기에도 손을 댔는데, 프래그먼트가 이상하게 먼저 생성이 되어서 액티비티에 값이 전달이 되질 않았다. 물론 번들로 하였다. 하지만, 볼리를 이용한 작업이 내 생각처럼 되질 않았다. 그래서 찾아내고 찾아내니 프래그먼트를 그냥 재생성 하지 않고, 다른 프래그먼트를 왔다갔다 해도 그대로 값이 남아있고..
오늘은 살짝 힘들었다. 만들고 있는 앱이 계속 말썽을 부렸기 때문이다. 기존에 프래그먼트 A 위에 뷰 페이저를 통해 프래그먼트 B를 올렸는데, 프래그먼트 A에서 B에 있던 버튼을 참조해서 버튼을 누를 일이 생겼는데, 누르게 되면 B에서는 버튼이 반응 없는 것이었다. 그렇다고 같은 코드를 두 프래그먼트에 쓰는 건 오류도 나고, 너무 비효율적이라고 판단하여 B프래그먼트에 있는 코드를 모두 B로 옮기고 몇 가지 수정을 했다. 그런데, 갑자기 뜨는 오류 위와 같은 오류가 뜨는 것이었다. did not then call Service.startForeground(): Service에서 startForground() 메서드를 호출하지 않았다는 거 같은데, 웃긴 게 앱은 켜졌지만, 한 10초 지나서 앱이 종료가 되었..
오늘로 세 번째 글이다. 아까 올렸던 ConnectivityManager이다 이것을 이제는 extends로 이용해보자. 우선 Service를 이용해야 하는데, 나는 아직 Service에 대해서 깊게 이해하지는 않았다. 대충 알고 있는 어느 정도 개념은, 눈에 보이지 않은, 디바이스의 백그라운드에서 실행할 수 있다고 들었다. 우선 메인 액티비티에서 Intent로 서비스에게 요청하면, 서비스는 네트워크 콜백 클래스에서 값을 받아서 화면에 값을 출력하는 정도로만 알고 있고, 오늘 예제에도 그 정도만 써보고자 한다. lcw126.tistory.com/278 안드로이드 NetworkCallback(실시간 네트워크 체크) NetworkCallback에 자세한 사항은 아래 안드로이드 개발자 사이트를 참고 바랍니다. ..
오늘로 두 번째 글이다. 오늘 배운 것 중에 유용한 녀석 중 하나였다. 간단하게 설명하면, 네트워크가 켜져있는지 안 켜져 있는지 정보를 얻고, 그에 맞게 실행할 수 있다. ConnectivityManager connManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connManager.getActivityNetworkInfo(); if (networkInfo != null ) { if (networkInfo.geType() == ConnectivityManager.TYPE_WIFI) { // Wi-Fi일때 작업 } else if (networkInfo.getType()..