반응형

며칠 전 Play 스토어에 배포된 앱의 버그 리포트를 검토 및 수정하면서 정리한 내용의 기록입니다.

 

[문제가 된 경로 및 현상]

앱에서 구글 플레이스토어의 해당 앱으로 이동하는 기능 실행 시 FC(Force Close)

 

[문제가 된 코드]

appInfoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("market://details?id=" + getPackageName()));
startActivity(intent);
}
});

[발생한 오류 및 콜 스택]

Fatal Exception: android.content.ActivityNotFoundException

No Activity found to handle Intent { act=android.intent.action.VIEW dat=market://details?id=packageName }

 

 

[분석]

문제가 된 모델은 GI-I9500_TMMARS인데, 메이커가 TrendMicro라고 나옵니다.

TrendMicro라면 보안업체인데 느낌상 apk 검증을 위한 가상 디바이스일 것 같다는 생각이 들었고, TMMARS로 검색해보니 TrendMicro Mobile App Reputation Service인데 글자 그대로 번역하면 TrendMicro 모바일 앱 평가 서비스입니다.

 

이 서비스를 통하여 apk를 검사하면 가상 디바이스에 apk를 설치한 후에 가상 디바이스 상에서 여러 가지 검증을 하는 것으로 생각됩니다. 그 검증하는 중에 문제가 된 경로로 진입하게 되고 FC 발생한 후 버그 리포팅 된 것으로 판단됩니다.

 

다행히 실사용 기기에서 발생한 문제는 아니었지만 생각해보니 실사용 기기에서도 오류가 발생할 가능성은 있어 보였습니다.

 

발생 원인

 - 앱에서 Play 스토어로 이동하기 위해서 인텐트를 전달하지만, 단말에서 마켓(Play 스토어)이 존재하지 않는 경우에 ActivityNotFoundException의 원인이 됩니다.

 

"Play 스토어"의 경우 시스템 앱인데 존재하지 않는 것이 가능한가?

먼저 "Play 스토어"의 경우 모든 안드로이드 단말에 다 들어가는 것은 아닙니다.

"Play 스토어" 및 구글의 모바일 서비스(GMS: Google Mobile Service)를 이용하려고 하면 구글 승인을 받아야 합니다.

즉, 구글의 승인(CDD[각주:1], CTS[각주:2])을 받지 못하거나 GMS를 제거하고 출시하고자 하는 단말의 경우는 "Play 스토어"가 존재하지 않습니다.

보통 AOSP(Android Open Source Project) 단말인 경우인데, 아마존의 파이어 테블릿과 샤오미 등의 중국 단말들이 많이 존재합니다. 이런 단말에서 앱을 실행하게 되면 ActivityNotFoundException이 발생합니다.

 

[해결책]

일단 AOSP 단말과 같이 "Play 스토어"가 존재하지 않아서 발생하는 ActivityNotFoundException에 대한 try~catch 처리로 오류 회피를 해주면서 인터넷 브라우저로 Play 스토어의 해당 앱으로 연결되도록 처리해줍니다.

 

[개선 코드]

appInfoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("market://details?id=" + getPackageName()));
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Intent webIntent = new Intent(Intent.ACTION_VIEW);
webIntent.setData(Uri.parse("https://play.google.com/store/apps/details?id=" + getPackageName()));
if (webIntent.resolveActivity(getPackageManager()) != null) {
startActivity(webIntent);
}
}
}
});
여기까지입니다. 읽어주셔서 감사합니다.
  1. Compatibility Definition Document [본문으로]
  2. Compatiblity Test Suite [본문으로]

+ Recent posts