구글 플레이 서비스가 설치되어 있지 않은 안드로이드 디바이스에서 구글 API (구글 플러스, GCM, 구글 맵, 구글 드라이브등) 를 사용하려고 하면 아래와 비슷한 Exception 을 발생시키며 죽는다.
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=http://play.google.com/store/apps/details?id=com.google.android.gms flg=0x80000 pkg=com.android.vending }
우선 이 문제가 발생하는 이유 첫 번째로 기기에 설치되어 있는 플레이 서비스가 너무 구 버전이거나 또는 아예 설치가 되어있지 않을때 발생한다.
또 두 번째 이유로 위에서 언급한 Exception 메세지를 보면
http://play.google.com/store/apps/details?id=com.google.android.gms flg=0x80000 pkg=com.android.vending
라고 표시되는데, 이 것은 진저 브레드 이하의 디바이스에서 스토어의 플레이 서비스 설치 페이지로 이동하는데 있어서 data 의 uri 값이 http:// 로 시작하기 때문이다. 보통 진저브레드 이하에서 스토어 앱을 통하여 특정 앱 설치 페이지로 이동할 때는 http:// 가 아닌 market:// 을 사용해야한다. 예를 들어
market://play.google.com/store/apps/details?id=com.google.android.gms이렇게 말이다.
이런 문제 때문에 안드로이드에서 플레이 서비스를 이용하는 구글 API 를 사용할시에는 다음과 같은 코드를 구글 API 호출하기 전에 사용하여 사용자에게 구글 스토어의 플레이 서비스 설치 페이지로 유도하도록 하여 문제를 해결해야 한다.
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //... 생략
// 플레이 서비스가 설치되어 있는지 확인하고 설치되어 있지 않다면 플레이 스토어로 이동
if(!isInstalledGooglePlayService()) {
installPlayService(this);
}
//... 생략
}
/**
* 구글 플레이 서비스가 설치 되어있는지를 확인한다.
* @return
*/
private boolean isInstalledGooglePlayService() {
boolean services = false;
try {
getPackageManager().getApplicationInfo("com.google.android.gms", 0);
services = true;
} catch(PackageManager.NameNotFoundException e) {
services = false;
}
return services;
}
/**
* 구글 플레이 서비스를 설치한다.
* @param context Activity
*/
private void installPlayService(Context context) {
new AlertDialog.Builder(context)
.setTitle("Google Play Services")
.setMessage("Required Google Play Services.")
.setCancelable(false)
.setPositiveButton("Install", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
dialog.dismiss();
try {
// 허니콤 이상에서 스토어를 통하여 플레이 서비스를 설치하도록 유도.
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=com.google.android.gms"));
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
intent.setPackage("com.android.vending");
startActivity(intent);
}
catch (ActivityNotFoundException e) {
try {
// 허니콤 미만에서 스토어를 통하여 플레이 서비스를 설치하도록 유도.
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.gms"));
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
intent.setPackage("com.android.vending");
startActivity(intent);
}
// 마켓 앱이 없다면 마켓 웹 페이지로 이동시켜주도록한다.
// (이 상태에서는 설치하기 힘들겠지만은....)
catch (ActivityNotFoundException f) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=com.google.android.gms"));
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
startActivity(intent);
}
}
}
}).setNegativeButton("Cancel",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
dialog.cancel();
}
}).create().show();
}
위 코드에서는 구글 플레이 스토어 앱이 없을 경우에는 구글 스토어의 웹 페이지로(플레이 서비스 설치 페이지) 연결을 직접 시도하고 있다.
그리고, 당연한 이야기지만 플레이 스토어나 플레이 서비스를 설치할 수 없는 안드로이드 기기에서는(구글 앱스 – gapps – 가 설치되어있지 않은 기기.) 구글 맵이나 GCM 과 같은 구글 서비스를 정상적인 방법으로 이용할 수 없다.
참고 페이지 : https://code.google.com/p/android/issues/detail?id=42543