글쓴이 보관물: 낭창

안드로이드 사용자 조작 없이 백그라운드에서 패키지 설치하기

개발 중인 앱에 자동업데이트 기능이 필요하다.
수십에서 수백대가 설치되는데다 사용자가 일일이 조작할 수는 없는 상황이기 때문에
프로그램이 알아서 파일을 다운로드 받고 패키지 설치까지 하는 기능이 필요한 상황.

하지만, 알아본 바로는 마켓의 자동 업데이트를 통하지 않는 다음에야 사용자 확인 없이
패키지를 설치하는 것은 불가능하다. OTL
보안상 문제 때문인거 같은데…

아무튼 그대로 좌절할 수는 없어서 좀더 알아보니 일반 사용자 앱은 불가능하지만
제조사의 key로 싸인된 패키지는 방법이 있는 듯하다.. 하지만 이것도 기기 제조사에서
key를 받기가 어렵기 때문에 불가능 OTL

그러나, 이 방법이 가능한 또다른 경우는 해당 앱이 system app 인 경우이다.
이건 좀 희망이 있다. 비록 루팅을 한다거나, 커스텀 펌웨어를 만든다던가 해야 하지만.=_=

세상에 간단한 일은 없다고 조건이 다 충족되더라도 걍 되는건 아닌데…
자세한건 다음 글을 참조.

간단히 요약하면, 안드로이드에서 패키지를 관리하는 PackageManager 에서 사용자 확인 따위의 과정은
건너띄어 버리고, 실제 설치를 하는 함수를 바로 불러 버리는 거다.

하지만, 이 함수와 관련 인터페이스가 외부에 공개가 되지 않는 관계로, reflection 이라는 좀 고급 기술을 써야한다.
머.. spring 이라던지 이런 류의 프레임워크에서 다 reflection을 사용하여 구현되어 있다지만,
일반 자바 개발자가 흔히 쓸만한 기술은 아니지=_=;

암튼, 다음과 같이 해서 작동하는 건 확인완료.

==

1. Android.Manifest.xml 파일을 열고, android.permission.INSTALL_PACKAGES 퍼미션을 추가한다.
해당 권한은 제조사 key로 싸인된 앱이나 시스템 앱 처럼 시스템 권한을 가진 경우 사용 가능하다.

2. Activity 에 버튼을 하나 추가 하고, 클릭 시에 패키지 설치 코드가 실행되게한다.
직접 코드를 작성해도 되고, 위 글에 있는 소스를 사용해도 된다.

ApplicationManager am = new ApplicationManager(MyActivity.this);
am.installPackage(“/mnt/sdcard/myapp_new.apk”);

3. 버전을 다르게 하여 패키지를 2개 생성한다.

4. 루팅이된 디바이스에 두 개의 패키지 파일을 복사하고, 루트 기능을 사용할 수 있는
파일 관리자 앱을 이용하여 낮은 버전의 패키지를 /system/app 으로 복사한다.

5. 파일 권한 설정 메뉴로 해당 패키지 파일의 권한을 rw-r–r– , 즉 644 로 변경 하고,
user와 group ID는 0으로 설정한다.

6. 디바이스를 재부팅하고, 해당 앱이 어플서랍에 표시되면 시스템 앱 만들기 성공.

7. 아까 만들었던 높은 버전의 패키지 파일은 설치코드에서 지정한 것과 동일한 경로에 동일한
파일명으로 바꾼다.

8. 앱을 실행하고, 버튼을 클릭하면, 잠시 후 앱이 종료된다.

9. 어플리케이션 정보 화면에 들어가서 해당 앱의 버전이 변경되었는지 확인하면 끝!

==

이걸로 한 가지 문제는 해결이 됐는데… 업데이트 후 다시 실행하게 하는게 또 문제군=_=