웹에서 앱 호출 예제 - web-eseo aeb hochul yeje

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

<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 함수)의 내부 소스만 참고하면 된다.

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

모바일웹에서 어플 실행하기
모바일웹에서 네이티브앱 실행하기

아래 예제 소스가있습니다.
자신의 앱 URL스키마로 소스를 변경하시고
구글스토어, 앱스토어 주소를 맞게 변경하신다음 테스트해보시면 될것같습니다.

*** URL스키마 (URL Scheme) 가 뭐냐구요 ?
쉽게 설명하면 웹 브라우저에서 스마트폰에 설치된 APP을 호출하는 닉네임같은것입니다
예를들면 Chrome 앱 하시죠 ? 구글에서 만은 웹브라우저
이놈에 URL스키마는 googlechrome:// 입니다
아래 예제 소스에 googlechrome:// 이걸 도입해서 작성해두었으니
스마트폰에 Chrome 앱 설치하신뒤에 테스트해보시면 Chrome을 실행시키는 모습을 보실 수 있습니다

아이폰의 경우.. 명확하게 앱 설치여부를 판단할만한 방법을 아직 모르겠는데..
혹시 아시는분은 댓글 부탁드립니다.


<!DOCTYPE html>
<html>

    <body>
        <div id="os_name"></div>
        <h2><a href="#" onclick="appStart()" data-role="button">App Start (onclick event)</a></h2>
    </body>

<script>

// OS 확인
var uAgent = navigator.userAgent.toLocaleLowerCase();
if(uAgent.indexOf("android") != -1)  
    OSName = "android";
else if(uAgent.indexOf("iphone") != -1 || uAgent.indexOf("ipad") != -1 || uAgent.indexOf("ipod") != -1) 
    OSName="ios";
else 
    OSName="is not mobile";

// 확인한 OS이름을 HTML에 표시 
document.getElementById("os_name").innerHTML="<h2>Your os : "+OSName+"</h2>";

// 어플 실행
function appStart(){
    if("ios" == OSName || "android" == OSName){
        document.checkframe.location = "googlechrome://";
        setTimeout("checkApplicationInstall_callback()", 1500);
    }else{
        // 어플 실행하지 않고 종료 
        return;
    } 
}

</script>

</html>