리소스 오버레이 프로젝트 폴더 준비: AndroidManifest.xml 파일, res 폴더

안드로이드 스튜디오 프로젝트로 만드는 분들도 있던데, 저는 잘 몰라서 손수 해 보겠습니다.
잘 찾아보면 괜찮은 템플릿 많이 있는 것 같아요. 요런 것도 있고요

프로젝트 폴더로 삼을 폴더 하나를 만들고, 그 안에 아래와 같은 파일 및 폴더를 만드세요.

(1) AndroidManifest.xml

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="28" android:compileSdkVersionCodename="9" package="<오버레이 패키지명>">
    <overlay android:priority="<우선순위>" android:targetPackage="<대상 패키지명>"/>
    <application android:allowBackup="false" android:hasCode="false"/>
</manifest>
  • <오버레이 패키지명>
    리소스 오버레이 패키지의 이름을 적당히 지어주시면 됩니다.
  • <대상 패키지명>
    리소스를 수정하려는 대상 앱의 패키지 이름을 적으세요.
  • <우선순위>
    양수 자연수 숫자 값이고요, 같은 대상 패키지에 대해 오버레이가 여러 개 있을 때... 낮은 우선순위 값을 지닌 오버레이가 나중에 적용됩니다. 최후의 승자가 되는 셈이죠.
    예를 들어, 쓰고 있는 오버레이의 우선순위가 9인데, 같은 앱을 대상으로 하는 내 오버레이가 꼭 적용되어야 한다면 우선순위를 9보다 작은 8 또는 그 이하 값으로 주면 되겠죠.

(2) res 폴더
요기다 수정하려는 리소스를 넣어두게 됩니다. 하위 폴더 구조는 일반적인 안드로이드 앱 리소스와 같으니 안드로이드 문서, 또는 수정 대상과 똑같이 해 두세요. 아래에서 이어집니다.

수정할 리소스 만들어 넣기

💡 리소스 폴더명 뒤에 옵션이 붙을 수 있습니다:

  • 화면 밀도 (xhdpi, xxhdpi, ...), 회전 여부 (land), API 버전 (v21), 야간 모드 (dark), 언어 (ko) 등등

✔ 각각 다 고쳐주셔야 합니다!

  • 덮어쓰려는 리소스 파일과 같은 경로, 같은 파일 이름으로 만드세요.

해본 것 위주로 예시를 적어보겠습니다.

숫자, 문자열 값 /res/values/...

원본과 같은 이름의 폴더에 같은 이름의 파일을 만들고 (e.g. dimens.xml), 파일 내용으로는 덮어쓰려는 키-값 쌍만 나열해 주세요. 원래 파일의 키-값 전체를 반복해서 쓸 필요 없습니다. 파일 내용으로 예를 들면 이렇습니다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="operator_text_font_size">0.0dip</dimen>
    <dimen name="operator_text_kt_image_width">0.0dip</dimen>
    <!-- 몇 개 더 덮어썼지만 생략합니다. -->
</resources>

위험도: 낮음 ✅
다른 곳에서 정의된 ID를 참조하는 형태가 아니므로 _없는 ID 참조 예외_가 발생할 일 없으며, 어지간히 잘못된 값을 주지 않는 한 앱 오류를 발생시킬 가능성도 낮으므로 그럭저럭 실수해도 안전하다 하겠습니다.

그림 리소스: /res/drawable/... 또는 /res/mipmap/...

drawable 폴더에 바로 그림이 있을수도 있고, drawable 폴더에는 상황별 리소스를 참조하는 XML 파일이 있고 mipmap에 실제 그림 리소스가 있을 수 있습니다. XML 파일을 고치는 것은 위험하다고 생각되니, 대신 이미지 파일을 수정해보세요.

e.g. /res/drawables-xxxhdpi-v4/stat_sys_operator_kt.png 파일을 투명 파일로 교체, xxxhdpi 대신 xxhdpi, xhdpi 폴더의 그림도 마찬가지.

💡 화면 밀도, 회전 여부 등 폴더명 베리에이션을 잊지 마세요.

위험도: (그림 자체) 낮음 ✅
다른 곳에서 정의된 ID를 참조하는 형태가 아니므로 _없는 ID 참조 예외_가 발생할 일 없으며, 그림이 비정상이 아닌 한 역시 안전하다 하겠습니다.
위험도: (XML 파일) ..? ❔
(안 해봤습니다. 다른 리소스명을 참조하게 되기 때문에 혹시나 새 버전에서 사라지면.. 오류를 일으킬 것 같습니다.)

스타일 /res/values/styles.xml

TODO 스타일 상속 받는 법을 잘 모르겠더라구요.. 그걸 제외하고는 앞과 비슷하게 (1) 같은 이름의 스타일을 적고, (2) 그 안에 덮어쓸 item 을 나열하세요.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="TextAppearance.Material.Notification.Emphasis" parent="@*android:style/TextAppearance.Material.Notification.Emphasis">
        <item name="android:textColor">#66ffffff</item>
    </style>
</resources>

💡 정의된 다른 ID를 참조할 때는 아래와 같이 적으세요.
@*<패키지명>:<리소스 분류>/<리소스 ID>
오버레이 대상 패키지에 속한 ID를 참조할 때, 안드로이드 프레임워크 (위의 android) 안의 내장 ID를 참조할 때 모두 위와 같이 @* 기호와 함께 패키지명을 적어 주세요.
(왜 그래야 할까요... :()

위험도: 잘 모름
음... 참조 잘못하면 위험하겠죠.

레이아웃

한 발 나아가서 레이아웃도 굳이 고치려면 고칠 수 있습니다. 그런데 XML 파일에 다른 곳에서 정의된 ID를 참조하거나, 새 ID를 정의하는 내용이 들어갑니다. 앱 업데이트 후 있던 ID가 없어지거나 ID 이름이 바뀌었을 때, 레이아웃에서 또는 소스코드에서 엉뚱한 ID를 참조하려 하면 오류가 발생하겠습니다. 시스템 리소스를 수정한다면 오류 때문에 더 위험하겠죠?

  • 원본 레이아웃 파일을 오버레이 프로젝트 폴더로 복사해 오세요.

  • 파일을 열고, ID 참조 부분을 모두 수정해주세요.

    💡 오버레이 프로젝트에는 원래 앱 패키지에 정의된 ID가 없습니다. 그러니 ID 참조가 원래 패키지를 가리키도록 수정해 주어야 정상적으로 리소스 오버레이 프로젝트의 컴파일이 가능합니다.
    <리소스 분류>/<리소스 ID> => @*<패키지명>:<리소스 분류>/<리소스 ID>
    e.g. integers/awesome => com.lvlz8.lovelinus:integers/awesome

  • 이제 레이아웃 파일에 원하는 수정 사항을 적용하세요 e.g. 뷰 요소 자리 바꾸기, (TextView 등 안드로이드 기본) 뷰 추가하기, ...

위험도: 높음 ❗
잘못된, 없는 ID 참조 시 예외로 앱이 강제종료됩니다. 시스템UI라면 상황은 더 심각합니다. 삼성 기기는 안전 모드로 재부팅하면 리소스 오버레이가 해제되는 듯 한데, LG 기기는 그렇지도 않아서 어려움이 있습니다.

aapt 툴 통해 프로젝트를 APK 파일로 생성, 서명 후 기기에 잘 설치

수정할 리소스 준비를 모두 마쳤다면, 프로젝트 폴더에서 명령줄 창을 띄우고 aapt 도구로 APK 컴파일이 가능합니다. aapt는 안드로이드 SDK에 들어있는 패키징 도구입니다.

아래 명령은 Pie OS 기기를 (API 28) 목표로 하고, 시스템 요소 중 SystemUI.apk 파일을 대상으로 준비해 본 명령입니다.

aapt package -f -M AndroidManifest.xml --min-sdk-version 26 -S res -I <android-28.jar> -I <SystemUI.apk> -I <framework-res.apk> -I <제조사 리소스 경로> -F <APK 출력 경로>
  • 최소 SDK 버전을 26으로 두었는데요, 최소 버전이 낮으면 예전 권한 시스템이 필요한 것으로 잘못 인식해 불필요한 권한이 부여됩니다.
  • -M, -S 플래그로 각각 매니페스트 파일, 리소스 폴더를 지정했습니다.
  • -I 플래그를 연속으로 나열하여 안드로이드 API 파일 (SDK에서 떼어왔습니다), 수정 대상 앱 (SystemUI.apk), 그리고 안드로이드·제조사 프레임워크 리소스 파일을 지정했습니다. 이렇게 하면 컴파일 중 필요한 리소스를 모두 정상적으로 참조할 수 있습니다.
  • -F 플래그로 APK 출력 경로를 적었습니다.
  • 뭔가 덜 한 것 같기는 하지만 여러분이 완성시켜주세요.

컴파일된 APK 파일을 테스트 인증서 또는 여러분의 인증서로 서명하면 준비 끝.

준비된 리소스 오버레이 파일을 모아... 아래와 같이 설치해볼 수 있겠네요.

  • 오레오 OS라면 그냥 설치?
  • Substratum 같은 리소스 오버레이 매니저를 쓰시거나
  • 루팅해서 설치하거나...
  • LG, 삼성 기기면 직접 테마로 만들든 툴을 쓰든 해서

...여기까지 해서 비록 Pie 버전에서는 설치가 막혔지만, 시스템 리소스 또는 사용자 앱 리소스를 수정해볼 수 있는 안드로이드 OS 내장 도구인 리소스 오버레이를 알아봤습니다.
읽으시느라 고생하셨습니다!

분석 결과 예시

LG 휴대폰 오레오/파이 OS에서 상태바 통신사 문구 및 VoLTE 로고 숨기기를 위해 찾아본 리소스 목록을 예시로 들어 보겠습니다.

굿락으로 챙겨주는 갤럭시 부럽다..

무슨 파일을 덮어써야 할까...

상태바 리소스이니 다음 파일을 찾아봅시다.

  • SystemUI.apk를 먼저 찾아보고,
  • 공통 리소스를 담는 framework-res.apk
  • 그리고 제조사 공통 리소소를 담는 lge-res.apk (삼성 폰도 비슷한 거 있음) 파일을 열심히 뒤져봐야겠습니다.

SystemUI.apk에 있는 상태바 관련 레이아웃 파일이나 소스코드를 참고해서 관련 리소스 이름을 알아내는 것도 좋습니다.

문구 표출 형태, 그리고 관련 리소스 찾기

리소스 디렉토리 구조 및 이름 짓는 법을 알고 계시면 편합니다. 이 부분은 공식 문서 포함해서 좋은 글 많으니 직접 찾아보시고요, 여기서는 실제 예시를 들어보겠습니다.

❌ 레이아웃(layout) 등 다른 ID를 참조하는 코드가 포함된 리소스는 수정하기 어렵습니다. 자세한 내용은 나중에..

  • 🧀 아이콘: KT, LGU+, 그리고 VoLTE 로고
    그림 형태이니까, 1px * 1px 크기 투명한 PNG 파일로 바꿔치기하면 되겠습니다.

수정 대상은 drawable 리소스 자체일 수 있고, drawable 리소스는 여러 mipmap 요소를 상황에 따라 사용하도록 하는 XML 파일이며 실제 이미지는 mipmap일 수 있습니다. 후자의 경우는 실제 그림 리소스인 mipmap을 고치는 게 좋겠습니다.

SystemUI.apk에만 있으면 좋았을텐데, lge-res.apk에도 VoLTE 로고를 포함해서 몇 개 있었습니다. 싹다 바꿔주면 되겠고요.
DPI 별로 베리에이션이 있으니 (xhdpi, xxhdpi, xxxhdpi 등) 모든 베리에이션에 대해 역시 싹다 바꿔줍니다.

  • 🅰 문구: SKT
    그냥 T로고가 예쁜데..

이 경우는 문구에 해당하는 폰트 크기를 0으로 만드는 방법이 먹혔습니다. 아래와 같은 방법으로 수정 대상 값을 찾을 수 있는데요.

  • res/values/dimens.xml 파일의 dimen(sion) 값 중 적절해보이는 이름을 찾을 수 있고, (머리가 귀찮으면 몸이 고생)
  • 상태바 관련 레이아웃에서 통신사 문구를 나타내는 요소를 찾아 확인할 수 있습니다.
    • 폰트 크기 속성이 직접 지정되어 있으면 그 값을 봅니다.
      res/layout/status_bar.xml:
      <TextView ... android:textSize="@dimen/operator_text_font_size" />
      <TextView ... android:textSize="12sp" /> <!-- 단, 이렇게 값이 직접 씌어있다면 수정하기 난감합니다. -->
    • (폰트 크기 속성을 포함하는) 스타일을 지정한 경우, res/values/styles.xml을 확인해야 합니다.
      <!-- res/layout/status_bar.xml: -->
      <TextView ... android:textAppearance="@style/TextAppearance.StatusBar.Clock" />
      <!-- res/values/styles.xml: -->
      <style android:name="TextAppearance.StatusBar.Clock">
      ...
      <item name="android:textSize">10sp</item>  <!-- 값으로 직접 지정되어 있으면 styles.xml을 고치면 되고 -->
      <item name="android:textSize">@dimen/clock_text_font_size</item> <!-- 또다른 값을 참조하면 해당 값을 고쳐줍니다 -->
      ...
      </style>
      • 레이아웃 대신 소스코드에서 뷰 요소의 폰트 크기를 지정할 수도 있겠죠. 이 경우는 잘... 확인하시면 되겠습니다.

다행히 폰트 크기가 레이아웃에 하드코딩되어있지 않으며 dimen 값을 참조하게 되어 있었고, 해당하는 값은 다른 상태바 요소와 공유되지 않는 별도 값이었습니다. (통신사 문구 폰트 크기를 0으로 만들었더니 시계 문구도 안 보이면 난감하니까요.)

 

샤오미(산하 브랜드?)에서 만든 블랙박스 70mai Pro는 저렴한 가격에 고화질 영상을 자랑하는 가성비 블랙박스입니다. 국내 제품에서는 고가 제품에만 들어가는 고급 이미지 센서를 7만원짜리 저가형 제품에서 누릴 수 있는 것이 큰 장점입니다.

70mai pro


(이미지 출처: 다나와)

제가 쓸 건 아니고 아버지 가끔 운행하시는 차량에 들어갈 거지만 대충 본 소감을 말씀드려 봅니다.
국내 쇼핑몰에서 본체 구입, 알리익스프레스..에서 GPS 모듈 및 퓨즈박스 연결용 시거잭 소켓 케이블을 구입해서 전면에 장착했습니다.

장점

  • QHD + H.265 녹화
    주간에 촬영되는 영상 선예도는 참 좋습니다. 쓱 보기에 중심부 뿐 아니라 주변부 선명도도 괜찮아 보입니다. 게다가 H.265 코덱을 지원하니 미지원 기기 대비 비디오 파일 용량이 줄어들겠다는 기대도 듭니다 (확인 안 해봄..). 영상을 PC에서 확인하지 않고 폰에서만 확인했기 때문에 화질이 어떠한지 자세한 평가를 내리지는 못하겠네요.

  • 까리한 디자인
    다들 인정하시리라 봅니다. 하지만 다른 회사 디자인 카피..

    예시: 아이나비 FXD900 (2013) 존똑

    아이나비 FXD900 (2013)
  • 전원 넣으면 2초만에 켜짐
    빠른 부팅은 사랑입니다. 내장 배터리의 위엄인지 모르겠네요.

  • 없는 것보다는 나은 ADAS 기능: 앞차 출발 알림, 차선 변경 알림
    GPS 모듈을 연결하고, ADAS 기능을 켜고 나서 차량을 운행하면 몇 분간 보정 작업을 진행한 후 사용할 수 있습니다.
    - 차선 변경 알림은 일정 속도 이상 (수정: 80km/h 이상) 고속 주행 시에 동작하도록 되어 있다더군요. 그래서 동작하는 모습을 못 봤습니다.
    - 앞차 출발 알림은 나름 잘 되는 것 같습니다. 음성으로 알려주는데, 음성 대신 적절한 알림음이면 좋겠네요.
      (오토바이는 차량으로 인식하지 못했습니다.)
    - 앞차 거리 경고 알림도 가끔 됩니다. 이걸 들을 일이 없는 게 제일 좋죠.

아쉬운 점

  • 중국 제품임..
    사드 보복이라던지 대북 외교에 도움 안 주는 점(후자는 아무튼 중국이 북한 편이니 어쩔 수 없기는 하겠는데)을 생각하면.., 중국 제품 구매를 주저하게 되는 면이 있습니다. 하지만 샀죠... 유구무언이네요.

  • 2채널 맞추려면 국내 제품 대비 가성비 이득 하락
    앞뒤로 2개 달려면 배선, 전력 소모 문제도 있지만, 2개면 7만원*2에 액세서리 하면 국내 제품 대비 그렇게 값싸지 않게 됩니다.

  • 야간 모드 엉망, 반사광 방지가 잘 안 되어 있음
    야간 화질은 별로라서 외국 포럼을 보시면 이를 해결하기 위해 여러 노력들을 하고 계시더군요. 또한 국내 제품에는 되어있는 렌즈 반사광 방지 처리가 안 되어 있어서 주간 화질이 저하되는 문제가 있습니다.
    주간 화질 이야기를 한 김에 적어보면, "WDR" 모드는 중국어 펌웨어에서만 적용된다고 합니다.

  • 기기 언어 한국어 미지원, 앱은 한국어 지원
    앱은 한국어가 되니 괜찮지만, 기기 화면 언어는 국제 펌웨어는 영어, 중국 펌웨어는 중국어로 고정이라 불편한 점이 있습니다. 음성 언어도 그렇고요. (이거 말고 신기종에는 어설픈 한국어 음성 안내가 들어간대요.)

  • 충격 감지 기준이 뭔가 이상
    1.0.5 때는 "낮음"이 민감, "높음"이 둔감으로 잘못되어 있었다더군요. 1.0.6부터 수정이 되었다던데... 테스트할 때는 괜찮았는데, 장착한 후로는 충격 감지가 잘 안 되는 것 같아 이상합니다. TODO

  • GPS 모듈로 ADAS밖에 못 함, 시간 자동 설정은 휴대폰 연결 통해서만 가능, 영상에 위치 정보 기록은 되는 듯 함
    ADAS 외에는 GPS 모듈이 별 쓸모가 없습니다. 그나마 국제판 펌웨어에서는 위치 기록이 되기는 된다더군요.
    - 다른 블로거님들 글을 보시면 펌웨어에 따라 화면에 GPS 좌표·속도를 띄워주더군요. 단, 영상 자체에 기록되는 것은 아닙니다.
    - 러시아제 커스텀 펌웨어를 쓰시면, 위치 정보를 SRT 자막 파일로 (동영상 플레이어에서 함께 볼 수 있게), 그리고 지도 프로그램에서 읽는 KML,GPX 포맷으로도 저장해준대요.

  • 주차 모드
    기본적으로는 기기 내장 배터리를 이용해서 전원 차단 후 일정 시간 (20분 등) 녹화가 가능합니다.
    별도 상시 케이블 (2만원 내외..) 장착시 사용할 수 있는 "타임 랩스" 모드는 중국어 펌웨에서만 동작한다더라구요. 응, 포기. 상시 케이블 따로 구입한다면 가성비가 없어지는 또다른 문제도 있습니다. 그럴거면 국내 제품 샀죠.

  • 로고 못 지움
    v1.0.6 버전부터 녹화 영상에서 로고를 숨길 수 있게 되었습니다. 휴대폰 앱에서 설정하면 돼요.
  • 30프레임만 지원, 60프레임 녹화까지 되면 좋을텐데...
    60프레임은 사랑인데 아쉽습니다. 7만원짜리니까 그러려니 해야겠죠. 다음 세대 제품에서는 개선될 것 같습니다.

참고사항

  • "event_s" 처럼 "_s" 달린 폴더가 생기고 안 달린 폴더와 용량은 작되 같은 내용의 파일이 생긴다는데요.
    휴대폰 앱에서 미리보기할 때 작은 용량으로 빨리빨리 다운받아서 미리보기하라고 만들어두는 거라고 합니다. 다만 이러한 미리보기 파일 만들기 기능을 끌 순 없는 것 같네요.
  • 다른 블로거님에 의하면, 주차모드 시 차단 전압이 좀 낮게 설정되어 있다고 합니다. 잘못하면 차량 배터리 방전 각이죠.
    ( 4pda.ru 포럼 유저에 의하면 차단 전압은 11.7V )

총평

번호판 식별 성능은 모르겠지만 아무튼 가격 대비 뛰어난 화질로 승부하는 블랙박스입니다. 관리에 손이 가고(새 펌웨어 찾으러 다녀야 함, 액세서리 구입이 쉽지 않음) 부가기능이 중요하다면 국내 제품 사는 것이 나으나, 가격과 좋은 화질이 모든 것을 용서합니다.

+ Recent posts