앱의 targetSdk 별 대표적인 차이점들

지난 글에서 앱의 targetSdk 버전에 따라 동작이 달라진다는 내용을 살펴보았다. 안드로이드를 이렇게 만든 이유는 이 글에, 차이점은 안드로이드 API 공식 문서인 이 글에 잘 정리되어 있다.

안드로이드에서 호환성 동작(compatibility)라  부르는 이런 차이 점을 여기서는 앱 사용에 영향을 많이 미치는 대표적인 것들만 추려 설명한다.

API 9

메인 스레드에서도 네트워크 통신을 할 수 있었다. API 10 이상부터는 메인 스레드에서 네트워크 통신을 시도하면, 앱이 종료된다. 하지만, TargetSdkVersion을 9로 적는다면 앱이 종료되지 않는다.

안드로이드의 기본 테마가 API 11부터  홀로(Holo) 테마로 바뀌었다. 사용자가 TargetSdkVersion을 10으로 적는다면, 11이상의 단말에서 앱이 실행되더라도 11의 기본 테마인 홀로(Holo)가 아닌 투박한 10 미만에서 지원하던 테마로 앱을 실행한다.

API23

Runtime 퍼미션이 추가되었고, targetSdk가 API22 미만인 앱은 아래와 같은 경고가 뜬다.

API24

정적 브로드캐스트 리시버로는 CONNECTIVITY_ACTION 브로드캐스트를 받을 수 없다. 안드로이드에서는 JobScheduler를 이용해 업데이트와 같은 백그라운드 작업을 처리하도록 강제하고 있다.

시스템 기본 테마의 색상 구성이 밝은 색으로 변경되었다.

API26

투명 액티비티의 orientation 고정을 한 후, API26인 단말에서 실행 시 IllegalStateException이 발생한다. (참고로 API25이하/API27이상 단말에서는 발생하지 않는다.)

참조

삼성 S32D850T의 소리 문제 해결

삼성에서 2014년도 출시한 16:9 비율의 모니터 SD850T 시리즈 32인치 모델이다. 어떤 작업을 하든 FHD(1920×1080) 해상도는 아쉬움을 주는데, 이 모니터는 QHD(2560×1440)로 충분한 해상도를 제공한다. 해상도나 패널 뿐 아니라, 다양한 종류의 포트, USB 확장, PIP 등 다양한  기능도 제공한다.

이 모니터는 3.5파이 sound-out(일명, 이어폰 잭)가 있고, 스피커는 내장되어있지 않다. 대신, 모니터로 입력된 사운드를 sound-out을 통해 출력한다. DVI 포트/DP 포트/HDMI 포트/sound-in(일명, 마이크 잭) 등 이 기능을 지원한다.

모니터의 이어폰 잭에 스피커를 연결해서 사용하려는데 문제가 있다면 다음을 확인해보자.

  • 이어폰 잭에 스피커 대신 이어폰을 꼽아 확인해보자. 스피커가 불량일 수 있다.
  • 케이블을 확인해보자. 케이블이 불량이거나 영상만 전송할 수 있다. 참고로, 모니터 구매 시 제공한 케이블이라면 영상과 소리를 모두 잘 전달한다.
  • 이어폰은 되는데 스피커만 안된다면, 스피커가 충분한 전류를 공급 받는지 확인하자.  특히 USB로부터 전력을 공급받는 경우, 겉보기에는 같은 USB 포트라도 다른 전류량이 나올 수 있으므로 확인이 필요하다.
  • HDMI에서만 소리가 안나온다면, PC/AV 설정을 확인해보자. 우측하단의 ‘메뉴 – 설정 – PC/AV 모드 – HDMI’로 들어가 설정을 변경할 수 있다. 컴퓨터와 연결한 경우 PC, AV와 연결한 경우 AV이다. DVI PC는 컴퓨터에서 DVI-HDMI 변환 케이블로 연결한 경우에만 고른다.

그 밖에

    • SD850의 뒷면 USB 포트 4개는 약 1.0A 정도가 나온다.  하지만, ‘메뉴 – 설정 – USB 고속 충전’ 을 통해 기능을 활성화 하면 위 2개는 고속 충전(1.5A 전류)할 수 있다.

참고

Volley와 Stetho로 네트워크 디버깅

Stetho는 2015년 페이스북에서 공개한 안드로이드 디버깅 도구다. 크롬 브라우저에 내장된 개발자 도구인 DevTools를 활용해 안드로이드 앱의 네트워크, 데이터베이스, 프리퍼런스, 레이아웃 등을 디버깅 할 수 있다. 더 자세한 기능 소개는 공식 페이지를 참조하자.

네트워크 라이브러리와 연계 동작하는 라이브러리들은 보통 Volley를 지원한다. 하지만, Stetho의 네트워크 디버깅 기능은 앱이 OkHttp나 안드로이드의 HttpUrlConnection를 써야 쓸 수 있다. 환경이 맞다면 좋겠지만, 이미 개발된 앱의 네트워크 라이브러리를 Stetho 쓰자고 바꾸기는 어렵다. 같은 고민인지, 아래처럼 Volly의 RequestQueue 객체 생성 시에 OkHttp 라이브러리의 특정 클래스 객체만 활용하는 우회법을 제안하는 글이 많다.

OkHttpClient client = new OkHttpClient();
client.networkInterceptors().add(new StethoInterceptor());
mRequestQueue = Volley.newRequestQueue(getApplicationContext(), new OkHttpStack(client));

물론 네트워크 라이브러리를 바꾸는 것에 비해 수정은 적지만, 쓰지 않아도 되는 라이브러리를 추가하는건 여전하다. 이 같은 고민을 한다면 포기하기 전에 여기를 살펴보자. Stetho의 UrlConnectionManager를 활용하는 기능이 포함된 StethoVolleyHurlStack 클래스를 제공하여, OkHttp를 사용하지 않고도 Stetho의 네트워크 디버깅을 사용하도록 도와준다.

RequestQueue queue = Volley.newRequestQueue(this, new StethoVolleyHurlStack());

2020년 1월 테스트로는 잘 되지만, 1년 넘게 commit이 없고 pull-request도 처리 안하는 것으로 미루어 보아 유지보수가 중단된 것 같다.

그 밖에

  • 데이터베이스, 프리퍼런스, 레이아웃 디버깅과 같은 다른 기능들은 위와 같은 수정 없이 Stetho 라이브러리 적용만으로 쓸 수 있다.

참고

워드프레스에 저작권 표시하기

블로깅을 하다보면, 저작권을 달고 싶어지기도 한다. ‘복잡한 저작권 문제를 내가 어떻게 정리할까?’ 싶다면 Creative Commons 를 이용한 저작권 표시를 고려해 보자.

얼마 전까지 워드프레스에 Creative Commons를 이용해 저작권 표시를 하려면 푸터(footer) 파일을 커스터마이징해야 했다. 19년 7월 1일부터 공식 Creative Commons 워드프레스 플러그인이 출시되어, 이를 이용하면 저작권 뱃지도 쉽게 표시할 수 있다.

아래를 따라, 플러그인을 설치하고 적용해 보자.

  1. 내 블로그의 ‘관리자 – 플러그인 – 새로 추가’ 에서 ‘Creative Commons’ 키워드로 검색
  2. 플러그인 설치
  3. 활성화
  4. 내 블로그의 ‘관리자 – 설정 – Creative Commons’를 통해 저작권 설정 화면으로 이동
  5. 저작권 옵션 선택
  6. 적용

어떤 뱃지를 선택해야할 지 고민하는 사람을 위해, Creative Commons는 간단한 문답으로 찾아보는 저작권 선택하기도구도 제공하니 이용해보자.

그 밖에

  • Creative Commons 플러그인은 저작권 표시를 글의 끝에 표시하는 것보다 블로그에 위젯으로 다는 것을 권장한다.
  • Creative Commons 뱃지를 단 결과는 이 블로그에서도 볼 수 있다.

참고

The user 12345 does not meet the requirements to access device identifiers

안드로이드는 휴대폰을 구분할 수 있는 변경 불가능한 식별자(이하 편의상 UID, Unique identifier)를 제공해 왔다. 공식 문서에 언급된 API들은 아래와 같다.

Build나 TelephonyManager 클래스를 통해 제공되는 이 기능이 안드로이드 10(API29 혹은 Q OS)부터 개인정보 보호 강화 정책에 따라 추가 제약을 받는다고 한다. targetSdkVersion 기준 28까지는 READ_PHONE_STATE 권한을 가진 앱은 UID를 읽을 수 있으나, 29부터 READ_PRIVILEGED_PHONE_STATE 권한이 있어야 한다. 그러므로, TelephonyManager.getDeviceId() API를 각각 O OS와 Q OS에서 호출한다면 아래와 같이 동작할 것이다.

O OS + READ_PHONE_STATE 권한이 없을 때

Caused by: java.lang.SecurityException: getDeviceId: uid 10237 does not have android.permission.READ_PHONE_STATE.

O OS + READ_PHONE_STATE 권한이 있을 때

2019-12-31 14:59:56.528 32231-32231/me.sunphiz.android.myapplication2 D/sunphiz: deviceId= 230064929080355

Q OS + READ_PHONE_STATE 권한이 없을 때

Caused by: java.lang.SecurityException: getDeviceId: The user 10265 does not meet the requirements to access device identifiers.

Q OS + READ_PHONE_STATE 권한이 있을 때

2019-12-31 14:54:39.741 5812-5812/me.sunphiz.android.myapplication2 D/sunphiz: deviceId= null

Q OS + READ_PRIVILEGED_PHONE_STATE 권한이 있을 때

2019-12-31 14:59:56.528 32231-32231/me.sunphiz.android.myapplication2 D/sunphiz: deviceId= 230064929080355

그럼 READ_PRIVILEGED_PHONE_STATE 권한은 어떻게 얻을 수 있을까? 결론만 이야기하면, 다운로드 앱(구글 플레이 스토어 등에서 다운받아 설치한 앱)은 저 권한을 얻을 방법이 없다. 저 퍼미션이 선언된 시스템의 AndroidManifest.xml을 보면, protectionLevel이 signatureOrSystem이기 때문이다. 이 조건은 단말 제조사만 충족할 수 있으므로, 다운로드 앱은 targetSdkVersion 29부터 UID에 접근할 수 없다는 결론이 된다.

그럼 어떻게하란 말인가? UID를 이용하던 기능이 있다면, 아래 방법 중 하나를 적용해보자.

  1. targetSdkVersion을 28이하로 유지
  2. 광고 및 사용자 분석을 위한 고유 식별자‘로 대체 고려
  3. Android 식별자 사용 권장사항‘을 보고 기능 변경

그 밖에

UID는 변경이 불가능한 값이라 편리하다. 동시에, 내 서비스를 통해 값이 유출된다면 의도치 않은 사용자 피해가 생긴다. 조금 번거롭더라도 더 안전한 방향으로 개선하자.

참조