PhoneGap:デスクトップブラウザで実行されているかどうかを検出します


118

モバイルバージョンでPhoneGap:Buildを使用するWebアプリケーションを開発していて、「デスクトップ」バージョンとモバイルバージョンで1つのコードベースを使用したいと考えています。PhoneGap呼び出しが機能するかどうか(つまり、PhoneGapをサポートするモバイルデバイスのユーザーかどうか)を検出できるようにしたい。

私は検索しましたが、これを行う簡単な方法はありません。多くの人々が提案を提供しています。

デスクトップバージョンのアプリからPhoneGap JavaScriptファイルを削除しない限り、どれも機能しません。これは、コードベースを1つにするという私の目標に反します。

これまでのところ、私が思いついた唯一の解決策はブラウザ/ユーザーエージェントのスニッフィングですが、これは控えめに言っても堅牢ではありません。より良いソリューションを歓迎します!

編集:少し良い解決策は、小さなタイムアウトの後にPhoneGap関数を呼び出すことです。それが機能しない場合は、ユーザーがデスクトップWebブラウザーを使用していると想定します。


Buildを使用しているため、以下の@btの回答を参照してください:stackoverflow.com/a/18478002/241244。受け入れられた投票数の多い回答よりも優れているようです。

実行時の検出は100%効果的であるため、明示的なビルド時の構成を優先して実行時の検出を回避します。{isPhonegap:true}のようにローカル変数をindex.jadeテンプレートに渡すだけで、テンプレートに条件付きでphonegap.jsスクリプトを含め、必要なすべてのphonegap固有のinitを実行できます。
Jesse Hattabaugh、2015

回答:


115

私はこのコードを使用します:

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

更新

ブラウザーで電話ギャップが実行されているかどうかを検出するには、他にも多くの方法があります。別の優れたオプションを次に示します。

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

ここに見られるように:モバイルブラウザーまたはPhoneGapアプリケーション間の検出


これをありがとう-他の人々が提案したものを見るのに長い間待った後、これは最良の解決策のようです。乾杯。
aaronsnoswell 2012

35
デバイスのブラウズで同じページを開くと、onDeviceReady()が呼び出されないため、これは正確ではありません。さらに、(デバッグ目的で)ブラウザーでUserAgentを変更する場合、onDeviceReady()は決して呼び出しません。
Slavik Meltser

3
何を言っているのかわからない-しかし、これが電話ブラウザの使用で問題を引き起こすことを示唆しているようです...これは、電話ではなくデスクトップブラウザでテストするためのソリューションです。
sirmdawg

7
これは、デバイスブラウザーでアプリを開いたときには役に立ちません。より良い解決策:window.cordovaを確認してください。iPhoneシミュレーター(ブラウザー)またはAndroidデバイス(ブラウザー)でテストすると、PhoneGapも検出されます。それが私が開発する方法です。しかし、物事を成し遂げる可能性はたくさんあります。;-)ソリューションを投稿するためのThx!
マリオ

私は混乱しています、Windows Phoneのような他のプラットフォームはどうですか?その正規表現に一致するuserAgentがありますか?簡単なグーグル検索は意味しません:madskristensen.net/post/Windows-Phone-7-user-agents.aspx
係留された

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の場合):

  • iOS版 -CordovaLibApp/AppDelegate.m
  • アンドロイド -src/org/apache/cordova/example/cordovaExample.java
  • Windowsの8 -example/package.appxmanifest
  • ブラックベリー -www/config.xml
  • WebOSと -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で次のようなものを使用しています<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:回答が変更されて、期待どおりに機能するようになっているように見えます(つまりReferenceErrorwindow接頭辞が原因でもうスローされません)。これは実際にコメントチェーンを古くする(したがって正しくない)ため、これを指摘したいと思いました。
Priidu Neemre 2017年

27

少し前に回答されたのは知っていますが、「PhoneGap.available」はもう存在しません。あなたは使うべきです:

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

または1.7以降、以下を優先します。

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

EDIT 2019:コメントで述べたように、これは、デスクトップブラウザービルドにCordova libを含めない場合にのみ機能します。そしてもちろん、ターゲットとする各デバイスの厳密な最小javascript / html / cssファイルのみを含めることをお勧めします


18
ブラウザにロードされている場合でも、スクリプトCordova-xxxjsを含めると、window.PhoneGapまたはwindow.cordovaが常に定義されるため、これは当てはまりません。
Slavik Meltser

例を教えてください。単純にindex.htmlをロードします。ローカルサーバーのwwwフォルダーの下にあるすべてのファイルをアップロードしたので、index.htmlをロードしています。解雇されていません。
Nassif 2013年

5
これが正しい答えのようです(少なくともCordova 3.4では)。単純な<script type = "text / javascript" src = "cordova.js"> </ script>を使用してcordova.jsがアプリケーションに注入されるため、他のすべてのメソッドは時間の無駄です。実際のファイルをポイントしていないため、ブラウザで実行してもロードされません。モバイルデバイスで実行されているCordovaビルドにのみ存在します。
Michael Oryl、2014年

これは、PhoneGap Buildを使用する場合に特にうまくいくようです。

4
@SlavikMe非コードビルドにコードバスクリプトを含めないでください。
ジャクソン

21

Cordova / phonegapアプリケーションを使用しているかどうかを確認する最も信頼できる方法は、このAppendUserAgent構成を使用してCordovaアプリケーションのユーザーエージェントを変更することです。

さらにconfig.xml

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

次に電話してください:

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

どうして?

  1. window.cordovaそしてdocument.addEventListener('deviceready', function(){});レースの条件が適用され
  2. navigator.standalone<content src="index.html" />Webサイトの場合は機能しません(例:<content src="https://www.example.com/index.html" />またはcordova-plugin-remote-injectionを使用
  3. ユーザーエージェントをホワイトリストに登録して、それが実際のブラウザであるかどうかを推測するのは非常に複雑です。多くの場合、AndroidブラウザーはカスタムWebビューです。

2
アプリケーションのバージョンを追加することもできます!(理想的には、いくつかの自動化されたバージョンバンプロジックを使用)ex; Cordova AppName/v0.0.1<3このようにして、追跡にこれを何らかの方法で使用することもできます(ただし、誰でもそのユーザーエージェントを変更できるため、セキュリティクリティカルな検証のためにこれに依存しないでください)
GabLeRoux

これは最も簡単な方法のようです。2番目の次点は、ドキュメントURLにhttp://またはhttps://がないことをテストしているようですが、それが機能しない可能性のあるシナリオを想定できます。
JDスミス

14

私はこれが最も簡単だと思います: var isPhoneGap = (location.protocol == "file:")

編集 うまくいかなかった人のために。次に、試してみるかもしれません(テストされていません)

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

1
PhoneGapはデバイス上のすべてのファイルに対して内部サーバーを実行していると思いましたか?
aaronsnoswell 2012年

私はそれが好きです。localhostで開発する場合、これが最良のソリューションです。(たくさん試した後、これがすべてのシナリオでうまくいけば幸いです。)Thx!
マリオ

1
リモートファイルをテストしているとき、リップルエミュレータではこれは機能しません
Jesse Hattabaugh

また、WP8では機能しません。プロトコルは「x-wmapp0:」です。将来、他にどの「プロトコル」が使用されるかを確実に知ることはできません。
エイドリアン

まあ、あなたもできます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、2012年

8
「deviceready」イベントがトリガーされる前にwindow.deviceが定義されていません。
Slavik Meltser

2
そして、他のプログラマーが「デバイス」と呼ばれる新しいグローバル変数を定義する幸せな考えを持っていないことを祈る。
ミスタースミス

7

元のポスターと同様に、私はPhoneGapビルドサービスを使用しています。2日後、ほぼ50回のテストビルドを行った後、私にとってはうまく機能するエレガントなソリューションを思いつきました。

モバイルブラウザーでテストして実行したかったため、UAスニッフィングを使用できませんでした。私はもともとコバーボーイのかなり機能的なテクニックに落ち着いていました。「howPatientAreWe:10000」の遅延/タイムアウトは、ブラウザー内での開発にはあまりにも面倒なので、これは私にはうまくいきませんでした。そして、それより低い値に設定すると、アプリ/デバイスモードでのテストが失敗することがあります。別の方法が必要でした...

phonegapビルドサービスでは、phonegap.jsアプリのファイルをサービスに送信する前に、コードリポジトリからファイルを削除する必要があります。したがって、その存在をテストして、ブラウザーとアプリのどちらで実行しているかを判別できます。

もう1つの注意点は、私も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

興味深いことに、多くの答えがありますが、これらには次の3つのオプションが含まれていません。

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 –コルドバスクリプトのロードイベントを使用して、コンテキストを検出します。スクリプトインクルードはビルドプロセスで簡単に削除できます。そうしないと、ブラウザでスクリプトのロードが失敗します。そのため、このグローバル変数は設定されません。

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

クレジットはアドビからダミアンアンティパに行く


5

私はこの方法を使用します:

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

debugなりtrue、ブラウザ環境でfalseデバイス上で。



3

この問題の本質は、cordova.deviceが未定義である限り、cordovaがデバイスがサポートされていないことを確立したためか、cordovaがまだ準備中であり、devicereadyが後で起動するためであるかどうか、コードが確信できないことです(または3番目のオプション:コルドバが正しく読み込まれませんでした)。

唯一の解決策は、待機期間を定義し、この期間の後、コードがデバイスがサポートされていないと想定する必要があることを決定することです。コルドバがどこかにパラメータを設定して「サポートされているデバイスを見つけてあきらめた」と言ってもらいたいのですが、そのようなパラメータはないようです。

これが確立されたら、サポートされているデバイスがない状況で正確に何かを実行したい場合があります。私の場合、デバイスのアプリ市場へのリンクを隠すように。

ほぼすべての状況をカバーするこの機能を組み合わせました。devicereadyハンドラー、device-never-readyハンドラー、および待機時間を定義できます。

//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" />ますが、さらに簡単です。config.xmlファイルのオプションをに変更するだけです<content src="index.html?cordova=1" />。これまでのところ機能しているようで、ここで提案されている最善の解決策です。
マーティンM.

2

1つのコードベースを維持するために重要なのは、コードが実行されている「プラットフォーム」です。私にとって、この「プラットフォーム」は3つの異なるものになる可能性があります。

  • 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'例外として、釣りの代わりに使用することをお勧めします。
クラカトア2014年

1

アーロン、やってみて

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

いいえ、しませんでした。phonegap-1.1.0.jsのソースコードを見てください。PhoneGap.available = DeviceInfo.uuid!== undefined;
GeorgeW 2012年

1

GeorgeWのソリューションは問題ありませんが、実際のデバイスでさえ、PhoneGap.availableは、PhoneGapのものがロードされた後にのみtrueになります。

その前に、知りたい場合は、次のようにすることができます。

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

このソリューションは、ほとんどの開発者がChromeまたはFirefoxを使用して開発することを前提としています。


OPは、開発だけでなく、プロダクションWebサイトのソリューションを探しています。
Jesse Hattabaugh、2013年

1

同じ問題があります。

CordovaクライアントによってロードされたURLに#cordova = trueを追加し、私のWebページでlocation.hash.indexOf( "cordova = true")> -1をテストすることに傾いています。


結局、私は4番目のポイントでアルルノーが提案したルートをたどり、ビルドスクリプトに決定を任せました。ウェブサイトのコードをAndroidアセットフォルダーにコピーするときに、index.htmlのフラグのコメントを解除します。// UNCOMMENT-ON-DEPLOY: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イベントが発生するとすぐに処理を進めます。
  • ユーザーエージェントのスニッフィングはありません(私のアプリをモバイルWebサイトとしてテストするのが好きなので、ブラウザーのスニッフィングは選択肢にありませんでした)。
  • 文書化されていない(したがって、もろい)PhoneGap機能/プロパティに依存しない。
  • デスクトップまたはモバイルブラウザーを使用している場合でも、cordova.jsをコードベースに保持します。したがって、これはOPの質問に答えます。
  • Wytzeは上記のように述べています。「コルドバがどこかでパラメータを設定して、「サポートされているデバイスを見つけてあきらめた」と言ってほしいのですが、そのようなパラメータはないようです。」ここに1つ提供します。

短所:

  • タイムアウトは厄介です。しかし、モバイルアプリのロジックは遅延に依存していません。むしろ、それはウェブブラウザモードにいるときのフォールバックとして使用されます。

==

新しい空の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の「フラグ」変数をtrueに初期化し、すべてのWebコンテキストの場合はfalseに変更します。

  • したがって、 " willIBeInPhoneGapSometimesInTheNearFuture()"のような呼び出しを使用できます(これはPRE-PGですが、PG APIを呼び出すことができるかどうかを確認するPOST-PGメソッドが必要ですが、それは簡単です)。

  • 次に、「but how do you determine the execution context?」と言います。答えは次のとおりです。「しないでください」(PGの優秀な人がAPIコードでそれを実行しない限り、確実にできるとは思わないため)。

  • それを行うビルドスクリプトを作成します。1つのコードベースに2つのバリアントがあります。


1

実際には質問に対する答えでありません、デスクトップブラウザーでテストするときは、localstorage値を設定して、ブラウザーがアプリをロードし、デバイスが起動していないことに気付かないようにします。

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ファイルを削除しない限り、どれも機能しません。これは、コードベースを1つにするという私の目標に反します。

別のオプションは、マージフォルダを使用することです。以下のスクリーンショットを参照してください。

プラットフォーム固有のファイルを追加したり、デフォルトのファイルを上書きしたりできます。

(それはいくつかのシナリオでトリックを行う必要があります)

ここに画像の説明を入力してください


言い換えると、ブラウザを検出するのではなく、デスクトップビルド用の特定のファイルを含めず、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

ここに記載されている2つの手法の組み合わせが最も効果的であることが実際にわかりました。まず、コルドバ/電話ギャップにアクセスできることを確認し、デバイスが利用可能かどうかも確認します。そのようです:

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で]再構築を押すだけです(いずれにしても、展開のクリーンアップが行われるため、これはこれらのタスクの1つになる可能性があります)。 PGにプッシュするときにisMobileBrowserAndNotPhoneGapを使用して手動でコメントアウトすることは、他に利用できることはほとんどないことを考慮して)良いオプションです。繰り返しになりますが、私の状況では、モバイルブラウザーの場合、ナビゲーションバーを押し上げる(分離されたコード)ファイルのタグを単純に削除します(非常に高速で小さくなります)。[だから、その最適化された手動のソリューションのコードを分離できるとしたら。


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

参考までに、 PhoneGap 3.xモバイルアプリケーション開発Hotshotの方法

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');

「#phonegap」というURLに文字列が追加されていることがわかります。ドメインのURLに次のスクリプトを追加します。

if(window.location.indexOf("#phonegap") > -1){
     alert("Url Loaded in the phonegap App");
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.