android 모바일 웹에서 앱 호출 / 앱에서 다른 앱 호출 / javascript 에서 앱 호출 /설치 여부 확인 /

2016.09.27 17:45mobile/android

 


Android 앱에서 이미 설치된 다른 앱을 호출할 경우가 있다.

 

하이브리드앱 (모바일웹)도 다른 앱을 호출할 경우가 있다.

 

위 두 가지 경우를 만족시켜보자.

 

 

 

구글링해보니 모바일 웹에서의 다른 앱 호출은 대부분 frame과 setTimeout를 이용하여 구현하고 있었다.

 

위 방법을 요약하자면 다음과 같다.

 

html body에 frame을 숨겨둠 -> window.href 또는 open 으로 호출 ->

앱 실행 or 특정시간(ex 1초)동안 반응이 없으면 앱이 없다고 판단 -> 마켓으로 이동

 

 

위 방법의 장점은 Andorid, IOS 를 javascript 에서 디바이스를 구분하는 분기문을 통해 한곳에서 구현할 수 있다.

 

또한 하이브리드 앱이 아닌 일반 웹에서 특정 어플리케이션을 호출해야 한다면 이 방법이 최선일지 모른다.

 

하지만 버전에 따른 이슈(리스크)가 있다.

 

android 4 에서 5로 버전업 되면서 frame 문제와 webview 의 대대적인 개편(크롬 적용 등) , IOS 9 버전으로 넘어오면서 여러 이슈들 등등...

 

또한 다들 위 방법을 놓고 꼼수(?) 라는 표현을 많이 사용한다.

 



 

그래서 다른 방법을 설명해 보려 한다.

 

요약하면 다음과 같다.

 

웹에서 네이티브 앱 호출(addJavascriptInterface 연결된 상태) -> 앱이 설치되어있는지 체크 ->

설치되어있다면 앱 호출 or 그렇지 않으면 마켓으로 이동

 

 

생각보다 간단하다.

 

단 전제조건이 addJavascriptInterface 설정이 되어있어야 한다.

* addJavascriptInterface 설정은 따로 설명하지 않습니다. (구글에서 검색 이동)

 



 

javascript

1
2
3
<script>
     window.Android.openApp();
</script>
cs

2# : javascript 에서 네이티브 함수(JavascriptInterface) 호출

 

Android

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 @JavascriptInterface
    public void openApp () {
        boolean isExist = false;
 
        PackageManager packageManager = mContext.getPackageManager();
        List<ResolveInfo> mApps;
        Intent mIntent = new Intent(Intent.ACTION_MAIN, null);
        mIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        mApps = packageManager.queryIntentActivities(mIntent, 0);
 
        try {
            for (int i = 0; i < mApps.size(); i++) {
                if(mApps.get(i).activityInfo.packageName.startsWith("com.app.app.app")){
                    isExist = true;
                    break;
                }
            }
        } catch (Exception e) {
            isExist = false;
        }
 
        // 설치되어 있으면
        if(isExist){
            Intent intent = mContext.getPackageManager().getLaunchIntentForPackage("com.app.app.app");
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mContext.startActivity(intent);
        }else{
            Intent marketLaunch = new Intent(Intent.ACTION_VIEW);
            marketLaunch.setData(Uri.parse("market://details?id=com.app.app.app"));
            mContext.startActivity(marketLaunch);
        }
 
    }
cs

1# : javascript 에서 호출될 JavascriptInterface를 알리는 어노테이션

5# ~ 20# : 디바이스에 "com.app.app.app"패키지를 가진 앱이 설치되어있는지 체크

24# ~ 26# : 설치 되어 있으면 해당 앱을 실행함

28# ~ 30# : 설치되어 있지 않으면 마켓으로 이동함

 

 

 

* 웹이 아닌 앱에서 다른 앱을 호출하는 방법은 Android 에 구현된 함수(opanPP 함수)의 내부 소스만 참고하면 된다.

 

위 상황이 여러번 발생한다면 모듈화 해놓고 사용하면 편할거같다 ㅎㅎ