- 자사 앱 플레이스토어 이동 링크를 웹뷰에서 클릭했는데 다음과 같은 화면이 나왔다.- 웹뷰가 intent:// 스킴을 이해하지 못해서 발생하는 문제다.- 안드로이드 WebView는 http://, https://는 기본 지원하지만, intent:// 같은 커스텀 스킴은 직접 처리해줘야 한다. - 웹뷰 클라이언트를 다음과 같이 수정해 주면 된다. URI_INTENT_SCHEME를 사용해서 대응해 주던지 아니면 외부로 플레이스토어를 열어주던지의 결정이 필요하다.webView.webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Bo..
- 개념적인 것들을 정리하는 것과 별개로 그날 하루 '개발자 활동'에 대해 무지성으로 기록하는 Dev Diary임1. 앱 데이터 복원 문제- 언제부턴가 앱을 재설치하는데, 사용자 prefs 데이터가 자동으로 복원됨 - 그로 인해 자동으로 로그인까지 진행해 버리는데, token 부분은 데이터가 존재하지 않아 계속 유저 인증 오류 발생android:allowBackup="true"- 안드로이드 자동 백업 옵션을 켜두면 구글 드라이브 기반으로 사용자 설정에 따라 앱 데이터를 복원하는데 이것이 영향을 주는 것으로 판단 - 그러나 우리 서비스는 따로 복원하고픈 prefs.xml 파일을 지정하고 있었다. 그런데도 발생.. - 추가로 확인해 보니 앱에서 사용 중인 어떤 라이브러리들이 백업 기능에 영향을 주고 있었고..
- 코틀린에서 코루틴은 CoroutineContext라는 실행 맥락 안에서 동작한다. - Context는 여러 요소(Job, Dispatcher 등)를 포함하고 있으며, 그중에서도 Dispatcher는 코루틴이 어떤 스레드에서 실행될지를 결정하는 중요한 역할을 한다. - 먼저, 코루틴의 Dispatcher에는 다음과 같은 종류가 있다.Dispatchers.Main설명: 안드로이드 메인(UI) 스레드에서 실행.용도: UI 업데이트, Toast, View 조작, LiveData/StateFlow 수집 등.주의: 긴 연산이나 I/O를 여기서 하면 ANR 발생 가능.CoroutineScope(Dispatchers.Main).launch { textView.text = "UI 업데이트" }2️⃣ Dispatche..
- ImageView에 바로 Shadow(elevation)을 적용할 수는 없는 것으로 보이고, CardView에 ImageView를 add 해서 구현해야 했다.val cardLp = FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.CENTER).apply { val m = (8 * resources.displayMetrics.density).toInt() setMargins(m, m, m, m)}val card = CardView(this@AddOnActivity).apply { layoutParams = cardLp ..
- WebView란? 안드로이드 앱 안에 내장된 브라우저라고 생각하면 된다. 즉, 앱 안에서 웹페이지(HTML, CSS, JavaScript)를 렌더링 하고 실행할 수 있는 View - 웹사이트를 보여줄 수도 있고, 앱 내부 기능과 연결된 하이브리드 앱 개발에도 자주 사용된다. - 안드로이드에서 애플 로그인 등. 웹뷰로 url에 접근하여 결과를 받아오는 방식이 필요할 때가 있다. - 이 글에서는 url을 웹뷰로 열고, 어떻게 그 안에서 결과 콜백을 받아오는지 확인해본다. 필자는 다이얼로그로 웹뷰를 보여주고자 한다. - 웹뷰의 데이터 전달 방식은 대략 다음과 같다. - 먼저 WebView 자체를 다이얼로그에 ContentView Set한다.) : Dialog(context) { private late..
- 서버로부터 buttonText라는 문자열을 받아 아래와 같은 안드로이드 기본 Button 컴포넌트에 입력해 주었다. - 그런데 BUTTONTEXT라고 모두 대문자 처리되어 보이고 있다. - 원인은 TextView(Button 상속) 속성 중 textAllCaps 때문이다. - 안드로이드 초창기에는 버튼의 영문을 모두 대문자로 표시하는 것이 디자인 가이드 원칙이었다고 한다. 아마 버튼에 대한 강조성 때문인 듯 - 어쨌든 textAllCaps가 항상 true로 되어있기 때문에 이 값을 false로 바꿔주면 된다.confirmBtn.isAllCaps = falseconfirmBtn.text = data.buttonText
- 안드로이드에서 Signature Hash는 앱의 APK에 포함된 서명(Developer Signing Certificate)을 해시 처리한 값이다.- 주로 외부 서비스(API, SDK)에서 이 앱이 실제로 서명된 진짜 앱인지 검증할 때 사용된다. - 앱은 배포 전에 반드시 개발자 KeyStore로 서명되고, 외부 서비스를 패키지명 + 서명 인증서 Hash 값으로 앱을 식별하는 원리이다. - 서명 Hash에는 다음과 같은 종류가 있다. SHA-1: 예전 API, 구글 로그인, Firebase 등에서 사용SHA-256: 최근 API/보안성 강화된 서비스에서 권장- 안드로이드 스튜디오 터미널에서 아래 명령어를 입력하면 빠르게 확인이 가능하다../gradlew signingReport - 하지만 Base6..
- Coil을 통해 서버로부터 수신받은 url로 webp를 렌더링 하고 있었는데, 원본에 비해 품질이 너무 떨어진다는 보고를 받았다. - 실제 파일을 업로드하는 웹 쪽에서는 품질 조정에 대한 문제는 없었다. 그렇다면 앱에서 조금 깨져보이는건데 대응 방안에는 두 가지 간단한 방법이 있었다. - 먼저 Coil을 통해 리소스를 불러올 때 디코딩 과정에서 품질 손실이 발생할 수 있고, Size 옵션에 따라 품질 손실이 발생할 수도 있다. - 아래가 기존 코일 관련 코드인데, Scale이 지정되지 않았고 ContentScale도 Crop으로 지정해놓았다. 이런 부분에서 변질이 발생하는 것으로 보인다.Image( painter = rememberAsyncImagePainter( ImageReque..
- 위젯에서는 알파 값 적용하는 방식이 제한되어 있다.- 이미지 같은 경우에는 setInt - "setAlpha"를 통해 적용하고, 텍스트의 경우에는 실제 알파 값이 적용된 컬러를 textColor로 지정해주어야 한다. remoteViews.setInt(R.id.widgetRootImg, "setAlpha", alpha)- 참고로 setAlpha에 들어가는 alpha 값의 범위는 0~255이다. - 원하는 투명도 %를 아래 공식을 통해 계산하여 반영해주어야 한다.val alpha = transparency * 255 / 100 - Int형 Color 값에 알파 값을 적용하려면 다음과 같이 처리한다. 예시로 30% 적용할 경우val colorWithAlpha = (textColor and 0x00FFFFF..
- API 호출을 통해 리스트 화면을 갱신하는 구조의 MainActivity가 있는데, 수동 동기화 버튼이 존재하지만 사용자에게 더 편리함을 주기 위해 다른 앱에 있다가 다시 해당 앱으로 복귀하면 자동으로 동기화해주는 기능이 필요했다. - 아래와 같은 Compose 기반의 화면으로 구성되어 있었고, 갱신 시 viewModel에서 새로운 값을 가져온다.@AndroidEntryPointclass MainActivity : ComponentActivity() { private val stationViewModel: StationViewModel by viewModels() private val subwayArrivalViewModel: SubwayArrivalDataViewModel by viewM..