PhoneGap : 데스크톱 브라우저에서 실행 중인지 감지


118

모바일 버전 용 PhoneGap : Build를 사용하는 웹 애플리케이션을 개발 중이며 '데스크톱'및 모바일 버전 용 단일 코드베이스를 갖고 싶습니다. PhoneGap 통화가 작동하는지 감지하고 싶습니다 (즉, PhoneGap을 지원할 모바일 장치의 사용자).

나는이 일을하는 간단한 방법이 없다는 것을 수색했고 믿을 수 없다. 많은 사람들이 제안을했습니다.

앱의 데스크톱 버전에서 PhoneGap Javascript 파일을 제거하지 않는 한 어느 것도 작동하지 않습니다.

지금까지 내가 생각 해낸 유일한 해결책은 브라우저 / 사용자 에이전트 스니핑이지만, 이것은 아무리 강력하지도 않습니다. 더 나은 솔루션을 환영합니다!

편집 : 조금 더 나은 해결책은 약간의 시간 초과 후에 PhoneGap 함수를 호출하는 것입니다. 작동하지 않으면 사용자가 데스크톱 웹 브라우저에 있다고 가정합니다.


Build를 사용하고 있으므로 아래 @bt의 답변을 참조하십시오. stackoverflow.com/a/18478002/241244 . 수락 및 최고 투표 답변보다 더 나을 것 같습니다.

100 % 효과적이기 때문에 명시적인 빌드 타임 구성을 선호하는 런타임 감지를 피합니다. {isPhonegap : true}와 같은 내 index.jade 템플릿에 로컬 var를 전달한 다음 템플릿에 phonegap.js 스크립트를 조건부로 포함하고 원하는 모든 phonegap 특정 초기화를 수행 할 수 있습니다.
Jesse Hattabaugh

답변:


115

이 코드를 사용합니다.

if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|IEMobile)/)) {
  document.addEventListener("deviceready", onDeviceReady, false);
} else {
  onDeviceReady(); //this is the browser
}

최신 정보

phonegap이 브라우저에서 실행 중인지 여부를 감지하는 다른 많은 방법이 있습니다. 여기에 또 다른 훌륭한 옵션이 있습니다.

var app = document.URL.indexOf( 'http://' ) === -1 && document.URL.indexOf( 'https://' ) === -1;
if ( app ) {
    // PhoneGap application
} else {
    // Web page
}  

여기에 표시된대로 : 모바일 브라우저 또는 PhoneGap 애플리케이션 간 감지


감사합니다. 다른 사람들이 제안한 내용을보기 위해 오랜 시간을 기다린 후 이것이 최선의 해결책 인 것 같습니다. 건배.
aaronsnoswell

35
장치 탐색에서 동일한 페이지를 열면 onDeviceReady ()가 절대 호출되지 않기 때문에 이것은 정확하지 않습니다. 또한 디버그 목적으로 브라우저에서 UserAgent를 변경하면 onDeviceReady ()도 호출하지 않습니다.
Slavik Meltser

3
무슨 말을하는지 잘 모르겠습니다.하지만 이것이 휴대폰 브라우저를 사용하는 데 문제를 일으킬 것이라는 것을 암시하는 것 같습니다. 이것은 휴대폰이 아닌 데스크톱 브라우저에서 테스트하는 솔루션입니다.
sirmdawg 2011

7
이것은 장치 브라우저에서 앱을 열 때 도움이되지 않습니다. 더 나은 솔루션 : window.cordova를 확인하십시오. iPhone Simulator (브라우저) 또는 Android 장치 (브라우저)에서 테스트하면 PhoneGap도 감지됩니다. 그것이 제가 발전하는 방식입니다. 그러나 일을 처리 할 수있는 가능성은 많습니다. ;-) 솔루션 게시를위한 Thx!
Mario

혼란 스럽습니다. Windows Phone과 같은 다른 플랫폼은 어떻습니까? 해당 정규식과 일치하는 userAgent가 있습니까? 빠른 Google 검색은 다음을 의미하지 않습니다. madskristensen.net/post/Windows-Phone-7-user-agents.aspx
mooreds

49

내가 쓴 글을 몇 일 전에 그것에 대해. 이것은 찾을 수있는 최고의 솔루션입니다 (PhoneGap이 무언가를 출시 할 때까지). 짧고 간단하며 완벽합니다 (가능한 모든 방법과 플랫폼에서 확인했습니다).

이 기능은 케이스의 98 %를 처리합니다.

/**
 * Determine whether the file loaded from PhoneGap or not
 */
function isPhoneGap() {
    return (window.cordova || window.PhoneGap || window.phonegap) 
    && /^file:\/{3}[^\/]/i.test(window.location.href) 
    && /ios|iphone|ipod|ipad|android/i.test(navigator.userAgent);
}

if ( isPhoneGap() ) {
    alert("Running on PhoneGap!");
} else {
    alert("Not running on PhoneGap!");
}

다른 2 % 사례를 완료하려면 다음 단계를 따르세요 (네이티브 코드에 약간의 변경이 포함됨).

소스를 사용하여 __phonegap_index.html 이라는 파일을 만듭니다 .

<!-- __phonegap_index.html -->
<script type="text/javascript">
    function isPhoneGap() {
        //the function's content is as described above
    }

    //ensure the 98% that this file is called from PhoneGap.
    //in case somebody accessed this file directly from the browser.
    if ( isPhoneGap() )
        localStorage.setItem("isPhoneGap","1");

    //and redirect to the main site file.
    window.location = "index.html";
</script>

이제 네이티브 에서는 모든 PhoneGap 플랫폼 에서 시작 페이지를 index.html 에서 __phonegap_index.html로 변경 하기 만하면 됩니다. 내 프로젝트 이름이 example 이고 변경해야하는 파일은 다음과 같습니다 (PhoneGap 버전 2.2.0의 경우).

  • 아이폰 OS -CordovaLibApp/AppDelegate.m
  • 안드로이드 -src/org/apache/cordova/example/cordovaExample.java
  • 윈도우 8 -example/package.appxmanifest
  • 블랙 베리 -www/config.xml
  • 웹 OS -framework/appinfo.json
  • 바다 - src/WebForm.cpp(56 행)
  • Window Phone 7- 어디에 있는지 모릅니다 (누군가 아직 그 플랫폼에서 개발 중입니까?!)

마지막으로 PhoneGap에서 실행 중인지 여부에 관계없이 사이트의 어느 곳에서나 사용할 수 있습니다.

if ( localStorage.getItem("isPhoneGap") ) {
    alert("Running on PhoneGap!");
} else {
    alert("Not running on PhoneGap!");
}

도움이 되었기를 바랍니다. :-)


4
이 답변이 최고입니다!
blong824 2013

3
예, 작동하지만 코드의 다음 부분이 사실이 아닌 경우도 /^file:\/{3}[^\/]/i.test(window.location.href)있지만 예를 들어 다른 페이지에서 index.html을로드 할 때 다음과 같은 config.xml에서 PhoneGap을 사용합니다<content src="http://10.100.1.147/" />
vudduu

3
(cordova || PhoneGap || phonegap) 해당 변수가 정의되지 않은 경우 표현식 에서 ReferenceError가 발생합니다. 로 테스트해야 typeof cordova !== undefined하죠?
rojobuffalo

1
@rblakeley 당신이 맞습니다. : 나는에 첫 선을 전환return ( typeof cordova !== undefined || typeof PhoneGap !== undefined || typeof phonegap !== undefined )
ethanpil

1
@rojobuffalo : 답변이 수정 된 후 다시 예상대로 작동하는 것 같습니다 ( 예 : 접두사 ReferenceError로 인해 더 이상 던지지 않음 window). 이것은 실제로 주석 체인을 구식으로 만들고 따라서 부정확하게 만들기 때문에 내가 이것을 지적 할 것이라고 생각했습니다.
Priidu Neemre

27

얼마 전에 답변을 받았지만 "PhoneGap.available"은 더 이상 존재하지 않습니다. 다음을 사용해야합니다.

if (window.PhoneGap) {
  //do stuff
}

또는 1.7 이후 선호 :

if (window.cordova) {
  //do stuff
}

EDIT 2019 : 의견에서 말했듯이, 이것은 데스크톱 브라우저 빌드에 cordova lib를 포함하지 않은 경우에만 작동합니다. 물론 대상으로하는 각 장치에 대해 엄격한 최소 javascript / html / css 파일 만 포함하는 것이 좋습니다.


18
window.PhoneGap 또는 window.cordova는 스크립트 cordova-xxxjs를 포함하면 브라우저에로드 되더라도 항상 정의되기 때문에 이것은 사실이 아닙니다.
Slavik Meltser

예를 들어 도와 주시겠습니까? 단순히 index.html을로드하려면 로컬 서버의 www 폴더 아래에 모든 파일을 업로드했습니다 .index.html을로드하고 있습니다.하지만 장치는 준비되어 있습니다. 해고되지 않습니다.
Nassif 2013-06-25

5
이것은 이제 정답 인 것 같습니다 (적어도 Cordova 3.4에서는). 다른 모든 방법은 단순한 <script type = "text / javascript"src = "cordova.js"> </ script>를 사용하여 cordova.js가 응용 프로그램에 주입되므로 시간 낭비 일뿐입니다. 실제로 실제 파일을 가리 키지 않으므로 브라우저에서 실행할 때로드되지 않습니다. 모바일 장치에서 실행되는 Cordova 빌드에만 있습니다.
Michael Oryl 2014 년

이것은 PhoneGap Build를 사용하는 경우 특히 잘 작동하는 것처럼 보입니다.

4
@SlavikMe 비 Cordova 빌드에 cordova 스크립트를 포함하지 마십시오.
Jackson

21

우리가 cordova / phonegap 애플리케이션에 있는지 알 수있는 가장 신뢰할 수있는 방법은이 구성 AppendUserAgent를 사용하여 cordova 애플리케이션의 사용자 에이전트를 수정하는 입니다.

config.xml추가 :

<preference name="AppendUserAgent" value="Cordova" />

그런 다음 전화 :

var isCordova = navigator.userAgent.match(/Cordova/i))

왜?

  1. window.cordovadocument.addEventListener('deviceready', function(){});경주 조건이 적용됩니다
  2. navigator.standalone<content src="index.html" />웹 사이트 일 때 작동하지 않음 (예 : <content src="https://www.example.com/index.html" />또는 cordova-plugin-remote-injection 사용 )
  3. 사용자 에이전트를 허용 목록에 추가하여 실제 브라우저인지 추측하는 것은 매우 복잡합니다. Android 브라우저는 종종 사용자 지정 웹보기입니다.

2
그리고 거기에 애플리케이션 버전을 추가 할 수도 있습니다! (이상적으로는 일부 자동화 된 버전 범프 로직에서) ex; Cordova AppName/v0.0.1<3 이런 식으로 그래서, (그래서 보안을 위해이에 중요한 검증을 의존하지 않지만 참고 사람의 사용자 에이전트를 수정할 수 있습니다) 당신도 어떻게 든 추적이 사용할 수 있습니다
GabLeRoux

이것은 가장 확실한 방법 인 것 같습니다. 두 번째 준우승자는 문서 URL에 http : // 또는 https : //가 없는지 테스트하는 것 같지만 작동하지 않는 가능한 시나리오를 상상할 수 있습니다.
JD Smith

14

나는 이것이 가장 간단하다고 생각합니다. var isPhoneGap = (location.protocol == "file:")

작동하지 않은 일부 사람들을 위해 편집하십시오 . 그런 다음 시도 할 수 있습니다 (테스트하지 않음)

var isPhoneGap = ! /^http/.test(location.protocol);

1
PhoneGap이 모든 기기 내 파일에 대해 내부 서버를 실행했다고 생각 했나요?
aaronsnoswell 2012 년

나는 그것을 좋아한다. localhost에서 개발할 때 이것이 최상의 솔루션입니다. (많은 시도 끝에 모든 시나리오에서 작동하기를 바랍니다.) Thx!
Mario

1
나는 원격 파일을 테스트있을 때이 리플 에뮬레이터에서 작동하지 않습니다
제시 Hattabaugh에게

또한 WP8에서 작동하지 않으며 프로토콜은 "x-wmapp0 :"입니다. 앞으로 어떤 다른 "프로토콜"이 사용 될지 확실히 알 수 없습니다.
Adrian

글쎄, 당신은 또한 --try 수var isPhoneGap = ! /^http/.test(document.location.protocol)
Yuval 교수

8

이것은 나를 위해 작동합니다 (1.7.0 실행).

if (window.device) {
  // Running on PhoneGap
}

데스크톱 Chrome 및 Safari에서 테스트되었습니다.


3
이것은 'deviceready'이벤트에 바인딩하는 것과 거의 같습니다. window.device가 정의되어 있지 않으면 phonegap / cordova가 로딩 속도가 느리거나 이벤트가 절대로 발생하지 않는지 알 수 없습니다.
Wytze

8
window.device가 "deviceready"이벤트가 트리거되기 전에 정의되지 않았습니다.
Slavik Meltser

2
그리고 다른 프로그래머가 "장치"라는 새로운 전역 변수를 정의하는 기쁜 생각을 갖고 있지 않도록기도하십시오.
Mister Smith

7

오리지널 포스터처럼 폰갭 빌드 서비스를 사용하고 있습니다. 이틀 동안 거의 50 개의 테스트 빌드를 마친 후 저에게 잘 맞는 우아한 솔루션을 찾았습니다.

모바일 브라우저에서 테스트하고 실행하고 싶었 기 때문에 UA 스니핑을 사용할 수 없었습니다. 나는 원래 cobberboy의 상당히 기능적인 기술에 정착했습니다. "howPatientAreWe : 10000"지연 / 시간 초과가 브라우저 내 개발에 너무 많은 성가신 문제 였기 때문에 이것은 저에게 효과적이지 않았습니다. 더 낮게 설정하면 앱 / 기기 모드에서 테스트가 실패하는 경우가 있습니다. 다른 방법이 있어야 했어 ...

phonegap 빌드 서비스를 사용하려면 phonegap.js앱 파일을 서비스에 제출하기 전에 코드 저장소에서 파일을 생략 해야합니다 . 따라서 브라우저에서 실행 중인지 앱에서 실행 중인지 확인하기 위해 그 존재를 테스트 할 수 있습니다.

또 다른주의 사항은 jQueryMobile도 사용하고 있으므로 사용자 지정 스크립팅을 시작하기 전에 jQM과 phonegap을 모두 초기화해야한다는 것입니다. 다음 코드는 앱의 사용자 지정 index.js 파일 시작 부분에 배치됩니다 (jQuery 이후, jQM 이전). 또한 phonegap 빌드 문서 <script src="phonegap.js"></script>는 HTML 어딘가에 배치하도록 말합니다 . 나는 그것을 완전히 버리고 $ .getScript ()를 사용하여 그 존재를 테스트하는 시설로로드합니다.

isPhoneGap = false;
isPhoneGapReady = false;
isjQMReady = false;

$.getScript("phonegap.js")
.done(function () {
    isPhoneGap = true;
    document.addEventListener("deviceready", function () {
        console.log("phonegap ready - device/app mode");
        isPhoneGapReady = true;
        Application.checkReadyState();
    }, false);
})
.fail(function () {
    console.log("phonegap load failed - browser only");
    isPhoneGapReady = true;
    Application.checkReadyState();
});

$(document).bind("mobileinit", function () {
    Application.mobileInit();
    $(document).one("pageinit", "#Your_First_jQM_Page", function () {
        isjQMReady = true;
        Application.checkReadyState();
    });
});

Application = {
    checkReadyState: function () {
        if (isjQMReady && isPhoneGapReady) {
            Application.ready();
        }
    },
    mobileInit: function () {
        // jQM initialization settings go here
        // i.e. $.mobile.defaultPageTransition = 'slide';
    },
    ready: function () {
        // Both phonegap (if available) and jQM are fired up and ready
        // let the custom scripting begin!
    }
}

6

흥미롭게도 많은 답변이 있지만 다음 세 가지 옵션이 포함되어 있지 않습니다.

1 – cordova.js는 전역 범위에서 cordova 개체를 설정합니다. 이것이 있으면 Cordova 범위에서 실행 중일 가능성이 큽니다.

var isCordovaApp = !!window.cordova;

2 – Cordova는 데스크탑에서 HTML 문서를 여는 것처럼 애플리케이션을 실행합니다. HTTP 프로토콜 대신 FILE을 사용합니다. 이를 감지하면 앱이 로컬로로드되었다고 가정 할 수 있습니다.

var isCordovaApp = document.URL.indexOf('http://') === -1
  && document.URL.indexOf('https://') === -1;

3 – cordova 스크립트의로드 이벤트를 사용하여 컨텍스트를 감지하십시오. 스크립트 포함은 빌드 프로세스에서 쉽게 제거 할 수 있습니다. 그렇지 않으면 스크립트로드가 브라우저에서 실패합니다. 이 전역 변수가 설정되지 않도록합니다.

<script src="../cordova.js" onload="javascript:window.isCordovaApp = true;"></script>

크레딧은 Adobe의 Damien Antipa에게 전달됩니다.


5

이 방법을 사용합니다.

debug = (window.cordova === undefined);

debug될 것입니다 true, 브라우저 환경에 false장치에.


4

이것은 실행 가능한 것처럼 보이며 프로덕션에서 사용했습니다.

if (document.location.protocol == "file:") {
    // file protocol indicates phonegap
    document.addEventListener("deviceready", function() { $(initInternal);} , false);
}
else {
    // no phonegap, start initialisation immediately
    $(initInternal);
}

출처 : http://tqcblog.com/2012/05/09/detecting-phonegap-cordova-on-startup/


3

문제의 핵심은 cordova.device가 정의되지 않은 한, Cordova가 장치가 지원되지 않는다고 설정했기 때문인지 아니면 Cordova가 아직 자체 준비 중이고 deviceready가 나중에 실행될 것인지를 코드에서 확신 할 수 없다는 것입니다. (또는 세 번째 옵션 : Cordova가 제대로로드되지 않았습니다).

유일한 해결책은 대기 기간을 정의하고이 기간이 지나면 코드에서 장치가 지원되지 않는다고 가정해야한다는 것을 결정하는 것입니다. Cordova가 "지원되는 장치를 찾고 포기했습니다"라는 매개 변수를 설정하고 싶지만 그런 매개 변수가없는 것 같습니다.

이것이 설정되면 지원되는 장치가없는 상황에서 정확하게 특정 작업을 수행 할 수 있습니다. 제 경우에는 장치의 앱 시장에 대한 링크를 숨기는 것과 같습니다.

나는 거의 모든 상황을 다루어야하는이 기능을 모았습니다. 이를 통해 장치 준비 처리기, 준비되지 않은 장치 처리기 및 대기 시간을 정의 할 수 있습니다.

//Deals with the possibility that the code will run on a non-phoneGap supported
//device such as desktop browsers. Gives several options including waiting a while
//for cordova to load after all.
//In:
//onceReady (function) - performed as soon as deviceready fires
//patience 
//  (int) - time to wait before establishing that cordova will never load
//  (boolean false) - don't wait: assume that deviceready will never fire
//neverReady 
//  (function) - performed once it's established deviceready will never fire
//  (boolean true) - if deviceready will never fire, run onceReady anyhow
//  (boolean false or undefined) - if deviceready will never fire, do nothing
function deviceReadyOrNot(onceReady,patience,neverReady){

    if (!window.cordova){
            console.log('Cordova was not loaded when it should have been')
            if (typeof neverReady == "function"){neverReady();}
        //If phoneGap script loaded...
        } else {
            //And device is ready by now...
            if  (cordova.device){
                callback();
            //...or it's loaded but device is not ready
            } else {
                //...we might run the callback after
                if (typeof patience == "number"){
                    //Run the callback as soon as deviceready fires
                    document.addEventListener('deviceready.patience',function(){
                        if (typeof onceReady == "function"){onceReady();}
                    })
                    //Set a timeout to disable the listener
                    window.setTimeout(function(){
                        //If patience has run out, unbind the handler
                        $(document).unbind('deviceready.patience');
                        //If desired, manually run the callback right now
                        if (typeof neverReady == 'function'){neverReady();}
                    },patience);
                //...or we might just do nothing
                } else {
                    //Don't bind a deviceready handler: assume it will never happen
                    if (typeof neverReady == 'function'){neverReady();} 
                    else if (neverReady === true){onceReady();} 
                    else {
                       //Do nothing
                    }
                }
            }
    }

}

3

내가하는 방식은 cordova.js의 브라우저 전용 버전으로 덮어 쓰는 전역 변수를 사용하는 것입니다. 기본 html 파일 (일반적으로 index.html)에는 순서에 따라 달라지는 다음 스크립트가 있습니다.

    <script>
        var __cordovaRunningOnBrowser__ = false
    </script>
    <script src="cordova.js"></script> <!-- must be included after __cordovaRunningOnBrowser__ is initialized -->
    <script src="index.js"></script> <!-- must be included after cordova.js so that __cordovaRunningOnBrowser__ is set correctly -->

그리고 내부 cordova.js에는 다음이 있습니다.

__cordovaRunningOnBrowser__ = true

모바일 장치 용으로 빌드 할 때 cordova.js가 사용되지 않고 대신 플랫폼 별 cordova.js 파일이 사용되므로이 방법은 프로토콜, userAgent 또는 라이브러리에 관계없이 100 % 정확하다는 이점이 있습니다. 변수 (변경 될 수 있음). cordova.js에 포함시켜야 할 다른 것들이있을 수 있지만 아직 무엇인지 모르겠습니다.


매우 흥미로운 접근 방식입니다.

하지만 실제로 초기 스크립트가 필요하지는 않습니다. 당신은 그것이 설정되고 있는지 테스트 할 수 있습니다 : if ( typeof __cordovaRunningOnBrowser__ !== 'undefined' ) { stuff(); } .. 맞습니까?

맞습니다. 정의되지 않은 것은 다른 것이 잘못되었음을 나타낼 수 있습니다.
BT

3

SlavikMe의 솔루션을 기반으로 한 또 다른 방법 :

index.htmlPhoneGap 소스에서 전달 된 쿼리 매개 변수를 사용 하십시오. 즉, Android에서는

super.loadUrl("file:///android_asset/www/index.html");

사용하다

super.loadUrl("file:///android_asset/www/index.html?phonegap=1");

SlavikMe에는 다른 플랫폼에서이 작업을 수행 할 수있는 훌륭한 목록이 있습니다.

그런 다음 index.html간단히 다음을 수행 할 수 있습니다.

if (window.location.href.match(/phonegap=1/)) {
  alert("phonegap");
}
else {
  alert("not phonegap");
}

1
Cordova 3.4.1을 사용하고 있으며 훨씬 더 간단 <content src="index.html" />합니다 <content src="index.html?cordova=1" />. config.xml 파일 의 옵션을 . 지금까지 작동하는 것처럼 보이며 여기에서 제안 된 최상의 솔루션입니다.
Martin M.

2

하나의 코드베이스를 유지하기 위해 관심있는 것은 코드가 실행되는 "플랫폼"입니다. 저에게이 "플랫폼"은 세 가지 다른 요소가 될 수 있습니다.

  • 0 : 컴퓨터 브라우저
  • 1 : 모바일 브라우저
  • 2 : 폰갭 / 코르도바

플랫폼을 확인하는 방법 :

var platform;
try {
 cordova.exec(function (param) {
   platform = 2;
  }, function (err) {}, "Echo", "echo", ["test"]);
} catch (e) {
  platform = 'ontouchstart' in document.documentElement ? 1 : 0;
}

노트 :

  • 이것은 cordova.js가로드 된 후에 만 ​​실행 되어야 합니다 (body onload (...), $ (document) .ready (...)).

  • document.documentElement의 'ontouchstart' 는 터치가 가능한 화면이있는 랩톱 및 데스크톱 모니터에 표시되므로 데스크톱이더라도 모바일 브라우저를보고합니다. 더 정확한 검사를하는 방법은 여러 가지가 있지만 필요한 케이스의 99 %를 여전히 처리하기 때문에 사용합니다. 항상 더 강력한 것으로 대체 할 수 있습니다.


1
typeof cordova !== 'undefined'예외를 위해 낚시 대신 사용 하는 것이 좋습니다 .
krakatoa

1

Aarons, 시도

if (PhoneGap.available){
    do PhoneGap stuff;
}

아니요 나는 안 그랬어요. phonegap-1.1.0.js 소스 코드를보십시오. PhoneGap.available = DeviceInfo.uuid! == 정의되지 않음;
GeorgeW

1

GeorgeW의 솔루션은 괜찮지 만 실제 장치에서도 PhoneGap.available은 PhoneGap의 항목이로드 된 후에 만 ​​true입니다 (예 : document.addEventListener ( 'deviceready', onDeviceReady, false)의 onDeviceReady).

그 전에 알고 싶다면 다음과 같이 할 수 있습니다.

runningInPcBrowser =
    navigator.userAgent.indexOf('Chrome')  >= 0 ||
    navigator.userAgent.indexOf('Firefox') >= 0

이 솔루션은 대부분의 개발자가 Chrome 또는 Firefox를 사용하여 개발한다고 가정합니다.


OP는 개발자뿐만 아니라 프로덕션 웹 사이트를위한 솔루션을 찾고 있습니다.
Jesse Hattabaugh 2010 년

1

나는 같은 문제가 있습니다.

Cordova 클라이언트가로드 한 URL에 # cordova = true를 추가하고 내 웹 페이지에서 location.hash.indexOf ( "cordova = true")> -1을 테스트하는쪽으로 기울고 있습니다.


결국 저는 Al Renaud가 4 번째 지점에서 제안한 경로를 따라 가고 빌드 스크립트가 결정하도록했습니다. 웹 사이트 코드를 android assets 폴더에 복사 할 때 index.html의 플래그를 주석 해제합니다. // 배포시 주석 해제 : window._appInfo.isCordova = true; 빌드 스크립트가 index.html을 내 android assets / www 폴더에 복사 할 때 ed를 실행하여 // UNCOMMENT-ON-DEPLOY : 문자열을 제거합니다. # index.html을 마사지하여 cordova ed "$ DEST / index.html"<<-EOF 1, \ $ s / \ / \ / UNCOMMENT-ON-DEPLOY : // wq EOF
Austin France

1

다음은 가장 최근의 PhoneGap / Cordova (2.1.0)에서 저에게 적합합니다.

작동 원리 :

  • 개념이 매우 간단합니다.
  • 위의 시간 초과 솔루션 중 일부의 논리를 뒤집 었습니다.
  • device_ready 이벤트 등록 ( PhoneGap 문서에서 권장 )
    • 시간 초과 후에도 이벤트가 여전히 발생하지 않으면 브라우저 가정으로 대체합니다.
    • 반대로, 위의 다른 솔루션은 일부 PhoneGap 기능 또는 기타 기능을 테스트하고 테스트 중단을 관찰하는 데 의존합니다.

장점 :

  • PhoneGap 권장 device_ready 이벤트를 사용합니다.
  • 모바일 앱은 지연이 없습니다. device_ready 이벤트가 발생하자마자 진행합니다.
  • 사용자 에이전트 스니핑 없음 (나는 내 ​​앱을 모바일 웹 사이트로 테스트하는 것을 좋아하므로 브라우저 스니핑은 옵션이 아니 었습니다).
  • 문서화되지 않은 (따라서 깨지기 쉬운) PhoneGap 기능 / 속성에 의존하지 않습니다.
  • 데스크톱 또는 모바일 브라우저를 사용하는 경우에도 코드베이스에 cordova.js를 유지하십시오. 따라서 이것은 OP의 질문에 답합니다.
  • Wytze는 위에서 다음과 같이 말했습니다. '나는 Cordova가 "지원되는 장치를 찾고 포기했습니다"라는 매개 변수를 어딘가에 설정하고 싶지만 그러한 매개 변수가없는 것 같습니다. " 그래서 여기에 하나를 제공합니다.

단점 :

  • 시간 초과가 엉망입니다. 그러나 우리의 모바일 앱 로직은 지연에 의존하지 않습니다. 오히려 웹 브라우저 모드 일 때 대체 수단으로 사용됩니다.

==

완전히 새로운 빈 PhoneGap 프로젝트를 만듭니다. 제공된 샘플 index.js에서 하단의 "app"변수를 다음으로 바꿉니다.

var app = {
    // denotes whether we are within a mobile device (otherwise we're in a browser)
    iAmPhoneGap: false,
    // how long should we wait for PhoneGap to say the device is ready.
    howPatientAreWe: 10000,
    // id of the 'too_impatient' timeout
    timeoutID: null,
    // id of the 'impatience_remaining' interval reporting.
    impatienceProgressIntervalID: null,

    // Application Constructor
    initialize: function() {
        this.bindEvents();
    },
    // Bind Event Listeners
    //
    // Bind any events that are required on startup. Common events are:
    // `load`, `deviceready`, `offline`, and `online`.
    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
        // after 10 seconds, if we still think we're NOT phonegap, give up.
        app.timeoutID = window.setTimeout(function(appReference) {
            if (!app.iAmPhoneGap) // jeepers, this has taken too long.
                // manually trigger (fudge) the receivedEvent() method.   
                appReference.receivedEvent('too_impatient');
        }, howPatientAreWe, this);
        // keep us updated on the console about how much longer to wait.
        app.impatienceProgressIntervalID = window.setInterval(function areWeThereYet() {
                if (typeof areWeThereYet.howLongLeft == "undefined") { 
                    areWeThereYet.howLongLeft = app.howPatientAreWe; // create a static variable
                } 
                areWeThereYet.howLongLeft -= 1000; // not so much longer to wait.

                console.log("areWeThereYet: Will give PhoneGap another " + areWeThereYet.howLongLeft + "ms");
            }, 1000);
    },
    // deviceready Event Handler
    //
    // The scope of `this` is the event. In order to call the `receivedEvent`
    // function, we must explicity call `app.receivedEvent(...);`
    onDeviceReady: function() {
        app.iAmPhoneGap = true; // We have a device.
        app.receivedEvent('deviceready');

        // clear the 'too_impatient' timeout .
        window.clearTimeout(app.timeoutID); 
    },
    // Update DOM on a Received Event
    receivedEvent: function(id) {
        // clear the "areWeThereYet" reporting.
        window.clearInterval(app.impatienceProgressIntervalID);
        console.log('Received Event: ' + id);
        myCustomJS(app.iAmPhoneGap); // run my application.
    }
};

app.initialize();

function myCustomJS(trueIfIAmPhoneGap) {
    // put your custom javascript here.
    alert("I am "+ (trueIfIAmPhoneGap?"PhoneGap":"a Browser"));
}

1

몇 달 전에 앱을 시작할 때이 문제를 우연히 발견했습니다. 앱도 " browser-compatible" 이길 원했기 때문입니다 (이 시나리오에서는 오디오 녹음, 나침반 등 일부 기능이 차단된다는 점을 이해하고 있음).

100%앱 실행 컨텍스트를 미리 결정하는 유일한 솔루션은 다음과 같습니다 (100 % 조건을 주장합니다).

  • JS "flag"변수를 true로 초기화하고 모든 웹 컨텍스트에서 false로 변경합니다.

  • 따라서 " willIBeInPhoneGapSometimesInTheNearFuture()" 와 같은 호출을 사용할 수 있습니다 (PG API를 호출 할 수 있는지 확인하는 POST-PG 메소드가 필요하지만 이는 사소합니다).

  • 그런 다음 " but how do you determine the execution context?"; 대답은 다음과 같습니다. "당신은하지 않습니다"(PG의 훌륭한 사람들이 API 코드에서 그렇게하지 않는 한 당신이 안정적으로 할 수 있다고 생각하기 때문입니다);

  • 당신을위한 빌드 스크립트를 작성합니다 : 하나의 코드베이스에 두 가지 변종이 있습니다.


1

아니 정말 데스크톱 브라우저에서 I 시험 butwhen 질문에 대한 답변은, 그냥 응용 프로그램에 견디는는 deviceready fireing하지 브라우저 부하를 만들 수있는 로컬 스토리지의 값을 설정합니다.

function main() {

    // Initiating the app here.
};

/* Listen for ready events from pheongap */
document.addEventListener("deviceready", main, false);

// When testing outside ipad app, use jquerys ready event instead. 
$(function() {

    if (localStorage["notPhonegap"]) {

        main();
    }
});

1

앱의 데스크톱 버전에서 PhoneGap Javascript 파일을 제거하지 않는 한 어느 것도 작동하지 않습니다.

또 다른 옵션은 병합 폴더 를 사용하는 것 입니다. 아래 스크린 샷을 참조하십시오.

플랫폼 별 파일을 추가하거나 기본 파일을 재정의 할 수 있습니다.

(일부 시나리오에서는 트릭을 수행해야 함)

여기에 이미지 설명 입력


즉, 브라우저를 감지하는 대신 데스크톱 빌드를위한 특정 파일을 포함하지 않고 iOS 전용 특정 파일을 첨부합니다.


1

에뮬레이션 장치가 활성화 된 경우에도 데스크탑 브라우저 감지

Windows 및 Mac 컴퓨터에서 작동합니다. Linux 용 솔루션을 찾아야합니다. 자세히보기

var mobileDevice = false;
if(navigator.userAgent.match(/iPhone|iPad|iPod|Android|BlackBerry|IEMobile/))
    mobileDevice = true; 

if(mobileDevice && navigator.platform.match(/Win|Mac/i))
    mobileDevice = false; // This is desktop browser emulator

if(mobileDevice) {
    // include cordova files
}

0

실제로 여기에 나열된 두 가지 기술의 조합이 가장 효과적이라는 것을 발견했습니다. 먼저 cordova / phonegap에 액세스 할 수 있는지 확인하고 장치를 사용할 수 있는지 확인합니다. 이렇게 :

function _initialize() {
    //do stuff
}

if (window.cordova && window.device) {
    document.addEventListener('deviceready', function () {
      _initialize();
    }, false);
} else {
   _initialize();
}

0

이 접근 방식을 시도하십시오.

/**
 * Returns true if the application is running on an actual mobile device.
 */
function isOnDevice(){
    return navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/);
}

function isDeviceiOS(){
    return navigator.userAgent.match(/(iPhone)/);
}

/**
 * Method for invoking functions once the DOM and the device are ready. This is
 * a replacement function for the JQuery provided method i.e.
 * $(document).ready(...).
 */
function invokeOnReady(callback){
    $(document).ready(function(){
        if (isOnDevice()) {
            document.addEventListener("deviceready", callback, false);
        } else {
            invoke(callback);
        }
    });
}

0

GeorgeWmkprogramming이 제안한 조합을 사용합니다 .

   if (!navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) {
      onDeviceReady();
   } else if (Phonegap.available){
      onDeviceReady();
   } else {
      console.log('There was an error loading Phonegap.')
   }

0

어쩐지 그들은 그렇게 다르지 않습니까? 하하 ... 재미 없어. 이것이 문제가되지 않을 것이라고 누가 생각 했습니까? 고려 사항에 대한 가장 간단한 해결책은 다음과 같습니다. 다른 파일을 서버에 푸시 한 다음 PhoneGap으로 이동합니다. 또한 위에 제안 된 http : 확인을 임시로 사용합니다.

var isMobileBrowserAndNotPhoneGap = (document.location.protocol == "http:");

내 관심은 브라우저 탐색 모음을 위로 올리는 것이므로 격리 된 스크립트의 태그를 삭제하고 [DW에서] 다시 빌드를 누르면됩니다 (어쨌든 배포를 위해 정리할 수 있으므로이 작업 중 하나가 될 수 있습니다.) 어쨌든 저는 느낍니다. PG로 푸시 할 때 isMobileBrowserAndNotPhoneGap을 사용하여 수동으로 주석 처리 만하는 것은 좋은 옵션입니다 (사용 가능한 것이 많지 않다는 점을 고려). 다시 제 상황에서 모바일 브라우저 일 때 navbar를 밀어 올리는 (격리 된 코드) 파일에 대한 태그를 간단히 삭제하겠습니다 (훨씬 빠르고 작아 질 것입니다). [최적화되었지만 수동 솔루션에 대한 코드를 분리 할 수 ​​있다면 나중에.]


0

약간 수정되었지만 문제없이 완벽하게 작동합니다.

의도는 데스크탑이 아닌 임베디드 장치에서만 Cordova를로드하는 것이므로 데스크탑 브라우저에서 Cordova를 완전히 피합니다. UI 및 MVVM 등의 테스트 및 개발은 매우 편안합니다.

예를 들어이 코드를 넣으십시오. cordovaLoader.js 파일

function isEmbedded() {
    return  
    // maybe you can test for better conditions
    //&& /^file:\/{3}[^\/]/i.test(window.location.href) && 
     /ios|iphone|ipod|ipad|android/i.test(navigator.userAgent);
}

if ( isEmbedded() )
{
   var head= document.getElementsByTagName('head')[0];
   var script= document.createElement('script');
   script.type= 'text/javascript';
   script.src= 'cordova-2.7.0.js';
   head.appendChild(script);
}

그런 다음 cordova javascript 자체를 포함하는 대신 cordovaLoader.js를 포함하십시오.

<head>
  <script src="js/cordovaLoader.js"></script>
  <script src="js/jquery.js"></script>
  <script src="js/iscroll.js"></script>
  <script src="js/knockout-2.3.0.js"></script>
</head> 

작업을 쉽게하세요! :)



0

그냥 정보를 원하시면의 방법 폰갭은 모바일 응용 프로그램 개발 핫샷을 3.X

var userLocale = "en-US";
function startApp()
{
// do translations, format numbers, etc.
}
function getLocaleAndStartApp()
{
    navigator.globalization.getLocaleName (
        function (locale) {
            userLocale = locale.value;
            startApp();
        },
        function () {
            // error; start app anyway
            startApp();
        });
}
function executeWhenReady ( callback ) {
    var executed = false;
    document.addEventListener ( "deviceready", function () {
        if (!executed) {
            executed = true;
            if (typeof callback === "function") {
                callback();
            }
        }
    }, false);
    setTimeout ( function () {
        if (!executed) {
            executed = true;
            if (typeof callback === "function") {
                callback();
            }
        }
    }, 1000 );
};
executeWhenReady ( function() {
    getLocaleAndStartApp();
} );

그리고 YASMF 프레임 워크에서

https://github.com/photokandyStudios/YASMF-Next/blob/master/lib/yasmf/util/core.js#L152


0

창 개체로 시도했지만 InAppBrowser에서 원격 URL을 열 때 작동하지 않았습니다. 할 수 없습니다. 따라서이를 달성하는 가장 쉽고 쉬운 방법은 phonegap 앱에서 열어야하는 URL에 문자열을 추가하는 것입니다. 그런 다음 문서 위치에 문자열이 추가되었는지 확인합니다.

아래는 간단한 코드입니다.

var ref = window.open('http://yourdomain.org#phonegap', '_blank', 'location=yes');

url "#phonegap"에 문자열이 추가 된 것을 볼 수 있습니다. 따라서 도메인 url에 다음 스크립트를 추가합니다.

if(window.location.indexOf("#phonegap") > -1){
     alert("Url Loaded in the phonegap App");
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.