brunch

You can make anything
by writing

C.S.Lewis

by 이승현 Jan 27. 2017

안드로이드 앱 강제 업데이트

현재 앱 버전, Play 스토어 앱 버전, 강제 업데이트

필요에 따라 구 버전 앱을 쓰는 사용자를 대상으로 강제로 앱을 업데이트해야 하는 상황이 있습니다.


안드로이드 앱 강제 업데이트에 대해 구글링을 해보고, 구글 플레이 개발자 지원팀에 문의해 봤지만 별도의 API나 구현법이 없네요.

개발자가 직접 개발해야 합니다.


#01 Google Play 개발자 지원팀 문의




1. 현재 앱 버전


Build.VERSION_CODES class를 통해 얻을 수 있습니다.

이 class는 android OS 버전을 얻을 수 있는 class 입니다.

https://developer.android.com/reference/android/os/Build.VERSION.html#SDK_INT


아래 class를 통해 앱의 버전 명을 얻어 올 수 있습니다.

BuildConfig.VERSION_NAME

https://developer.android.com/studio/publish/versioning.html?hl=ko



2. Play 스토어 앱 버전


Play 스토어에 등록된 앱 버전을 얻어오는 공식적인 API는 존재하지 않습니다.                                                 


Google Play의 앱 및 앱 등록정보는 이 약관에 위배되는 기능(예: 정책을 준수하지 않는 스토어 외부의 APK에 연결)을 활성화하거나 액세스하는 수단을 제공해서는 안 됩니다.


앱 버전뿐만 아니라 스토어에 등록된 모든 정보를 제공해주는 서비스가 있지만, 유료네요...

https://42matters.com/docs/app-market-data/android/apps/lookup


비공식적으로는 아래 오픈 소스들이 있는데, 오래되어 제대로 동작하지 않거나 구현이 쉽지 않아 굳이 쓸 이유가 없어 보입니다.

https://code.google.com/archive/p/android-market-api/

https://code.google.com/archive/p/android-query/wikis/Service.wiki

https://github.com/googlesamples/android-play-publisher-api/tree/master/v2/java





간단한 방법은 Play 스토어 [https://play.google.com/store/apps/details?id=packageName]에 등록된 현재 버전 값을 파싱 해서 가져오기입니다.


#02 Play 스토어 추가 정보


#03 Play 스토어 추가 정보 HTML


1. HTML 코드 가져오기


안드로이드에서 기본 제공하는 HttpURLConnection class를 이용하여 가져올 수 있습니다.

URL url = new URL("https://play.google.com/store/apps/details?id=packageName");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();

.....

BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

.....

StringBuilder builder = new StringBuilder();
for (;;) {
    String line = br.readLine();
    if(line == null) break;
    builder.append(line + '\n');
}


다른 방법으로는 HTML Parser 오픈 소스들을 쓸 수 있는데 개인적으로는 jsoup가 사용하기 편하고 성능면에서 좋은 거 같습니다.


https://jsoup.org/

Document document = Jsoup.connect("https://play.google.com/store/apps/details?id=packageName).get();
Elements Version = document.select(".content");


2. 앱 버전 구하기


파싱 한 HTML 코드에서 "softwareVersion" 값을 가져와야 합니다.

여러 방법이 있지만 "softwareVersion" 변수 이름이 변하지 않는다는 가정하에 아래와 같이 구현합니다.

final String startToken = "softwareVersion\">";
final String endToken = "<";
final String lineString = stringBuilder.toString();
final int index = lineString.indexOf(startToken);

if (index == -1) {
   return null;
} else {
   int endCount = 100;
   String temp = lineString.substring(index + startToken.length(), index + startToken.length() + endCount);
   return temp.substring(0, temp.indexOf(endToken)).trim();
}


3. 주의할 점


네트워크 상황이나 구현 방법에 따라 Play 스토어의 앱 버전을 가져오는데 시간이 걸릴 수 있습니다.
따라서 Main Thread에서 구현 시, ANR에 걸릴 수 있으므로 반드시 Background Thread에서 구현하시고 비동기 식으로 처리하시기 바랍니다.

공식적인 API가 존재하지 않기 때문에 구글링을 해보면 이처럼 HTML을 파싱 해서 index 값을 이용해 값을 구하는 이상한? 방법이 많이 있습니다. 하지만 이 방법은 Play 스토어의 상황에 따라 자칫하면 잘못된 값을 얻어 올 수 있으므로 완벽한 코드라고 볼 수 없네요.


다른 분이 작성하신 아래 블로그에 자세히 설명이 되어있습니다.

http://dexx.tistory.com/124




3. 강제 업데이트


앱 강제 업데이트는 아래와 같은 Google의 정책에 위반하기 때문에 공식적인 API는 존재하지 않습니다.


기기 및 네트워크 악용

악의적 행위 정책

개발자 정책 센터

                                                           

결론은 사용자의 사전 동의 없이 기기에 다른 앱을 설치하거나,  Google Play에서 다운로드한 앱은 Google Play의 업데이트 메커니즘이 아닌 다른 방법을 사용하여 자체적으로 수정, 대체 또는 업데이트할 수 없습니다.


따라서 단순히 해당 Play 스토어 앱 화면을 띄워서 사용자가 직접 "업데이트" 버튼을 클릭하여 업데이트를 유도해야 합니다.

Uri uri = Uri.parse("market://details?id=" + packageName);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);


하지만 여기도 맹점이 있습니다.

실제 새로운 앱 버전이 배포되었지만, Play 스토어에서는 곧바로 반영되지 않는 현상이 있습니다.

이 현상에 대한 Google Play 개발자 지원팀의 답변은 아래와 같습니다.

결론은 다 상이하다네요.


먼저 업데이트를 최근에 진행하셨을 경우, 서버와 기기의 통신 주기가 달라 업데이트가 표시되지 않을 수 있습니다.


통신 주기도 정해진 게 있나요? 아니면 모두 상이한가요?
- 기기마다 상이합니다.
OS 버전이 아니라 기기요?
- 네
OS 버전이면 구글의 정책인데, 기기라면 제조사라고 봐도 되겠네요?
- 기기와 저희 스토어 서버와의 통신주기가 기기마다 달라 저희 쪽에서 확인해드리기 어려운 점 양해 부탁드립니다.
MAX 며칠 이런 것도 다 다르다는 거죠?
- 네 맞습니다.


해결 방법은 Play 스토어의 캐시를 삭제 후, 재실행하면 업데이트가 반영됩니다.

하지만 일반 사용자들은 이런 방법도 모르고, 안내를 하더라도 강제성이 없기 때문에 이 같은 방법으로 업데이트하기엔 무리가 있습니다.


#04 Google Play 스토어 캐시 삭제




그래서 특별한 경우가 아니라면 새 버전 배포 당일이 아닌 일정 시간을 두고 진행하는 것 이 좋습니다.

아래 그래프를 보면 새로운 앱 버전 사용률과 기존 앱 버전 사용률이 서로 반비례하여 그려지고 있습니다.

앱이나 사용 환경에 따라 다르겠지만, 보통 1주일 정도면 대부분의 사용자들이 업데이트를 한 상태였습니다.


#05 버전별 사용률 그래프 [Fabric]


결론적으로 시간적 여유가 있다면, 최대한 많은 사용자들이 자동 업데이트를 진행하고 남은 소수의 사람들을 대상으로 강제 업데이트를 진행하는 것이 앱에 대한 불만도를 줄일 수 있는 방법이라 생각합니다.




브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari