PhoneGap: Визначте, якщо він працює в браузері настільних ПК


118

Я розробляю веб-додаток, який використовує PhoneGap: Build для мобільної версії та хочу мати єдину базу коду для «настільних» та мобільних версій. Я хочу мати змогу виявити, чи будуть працювати дзвінки PhoneGap (тобто це користувач на мобільному пристрої, який підтримуватиме PhoneGap).

Я шукав і не можу повірити, що немає простого способу зробити це. Багато людей пропонували пропозиції;

Жоден з яких не працює, якщо ви не видалите файл JavaScript JavaScript з настільної версії програми, що не перешкоджає моєму створенню однієї бази коду.

Поки єдине рішення, яке я придумав, - це нюхати браузер / користувальницький агент, але це не є надійним. Будь-які кращі рішення ласкаво просимо!

EDIT: Насправді кращим рішенням є спробувати викликати функцію PhoneGap після невеликого тайм-ауту - якщо вона не працює, то припустимо, що користувач перебуває у веб-браузері настільних ПК.


Оскільки ви використовуєте Build, дивіться відповідь @ bt нижче: stackoverflow.com/a/18478002/241244 . Здається, це може бути краще, ніж прийняті та голосовані відповіді.

Я уникаю виявлення часу виконання на користь явної конфігурації часу нарощування, оскільки це 100% ефективно. Я просто передаю локальний var моєму шаблону index.jade на зразок {isPhonegap: true}, тоді в шаблон я можу умовно включити скрипт phonegap.js і виконати всі специфічні для fonegap init, які я хочу.
Джессі Хаттабо

Відповіді:


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

35
Це не точно, тому що, якщо я відкрию ту саму сторінку в перегляді пристрою, він буде ніколи не зателефонувати. Плюс, якщо я поміняю UserAgent у веб-переглядачі (для цілей налагодження), onDeviceReady () ніколи не дзвонить.
Славік Мельцер

3
Не впевнений, що ви говорите - але, здається, ви маєте на увазі, що це спричинить проблеми із використанням браузера телефонів ... Це рішення для тестування на настільному браузері, а не на ваших телефонах.
sirmdawg

7
Це не допомагає, коли ви відкриєте додаток у браузері пристрою. Краще рішення: перевірити вікно.cordova. Тестування в iPhone Simulator (браузер) або на пристрої Android (браузер) має також виявляти PhoneGap. Так я розвиваюсь. Але можливостей зробити це дуже багато. ;-) Thx для розміщення вашого рішення!
Маріо

Я розгублений, що з іншими платформами, такими як Windows Phone? Чи є у них userAgent, який відповідає цьому регулярному виразу? Швидкий пошук в Google передбачає не: 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>

Тепер на рідному просто змініть початкову сторінку з index.html на __phonegap_index.html на всіх ваших платформах PhoneGap. Скажімо, назва мого проекту - приклад , файли, які потрібно змінити (як для PhoneGap версії 2.2.0):

  • iOS -CordovaLibApp/AppDelegate.m
  • Android -src/org/apache/cordova/example/cordovaExample.java
  • Windows 8 -example/package.appxmanifest
  • BlackBerry -www/config.xml
  • WebOS -framework/appinfo.json
  • Бада - src/WebForm.cpp(рядок 56)
  • Віконний телефон 7 - Не маю уявлення, де (хтось ще розвивається на цій платформі ?!)

Нарешті, ви можете використовувати його будь-де на вашому сайті, якщо він працює на PhoneGap чи ні:

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

Сподіваюся, це допомагає. :-)


4
Знайшов цю відповідь найкращою!
blong824

3
так, це працює, але інколи наступна частина коду не відповідає дійсності, /^file:\/{3}[^\/]/i.test(window.location.href)але ми використовуємо PhoneGap, наприклад при завантаженні 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 )
етанпіль

1
@rojobuffalo: Схоже, відповідь була змінена, і вона знову працює так, як очікувалося ( тобто вона більше не кидає ReferenceErrorчерез windowпрефікс). Я просто подумав, що я зазначу це, оскільки це насправді робить ланцюжок коментарів застарілою (і, таким чином, неправильною).
Priidu Neemre

27

Я знаю, що на нього відповіли деякий час тому, але "PhoneGap.available" вже не існує. Ви повинні використовувати:

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

або з 1,7, віддайте перевагу:

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

EDIT 2019: як сказано в коментарях, це працює лише в тому випадку, якщо ви не включаєте кордову вкладку у свій стільниковий браузер. І звичайно, це хороша практика включати лише суворі мінімальні файли javascript / html / css для кожного пристрою, на який ви орієнтовані


18
Це неправда, тому що window.PhoneGap або window.cordova все одно буде визначено, якщо ви включите скрипт cordova-xxxjs, навіть якщо він завантажений у браузер.
Славік Мельцер

Ви можете допомогти мені зі прикладом. Щоб просто завантажити index.html. Що я роблю, це те, що я завантажив усі файли в папку www на свій локальний сервер, я завантажую index.html. Але пристрій готовий не звільняється.
Насіф

5
Це, здається, зараз правильна відповідь (принаймні, Кордова 3.4). Всі інші методи - це лише марна трата часу, оскільки cordova.js зараз вводиться у додаток простим <script type = "text / javascript" src = "cordova.js"> </script>. Ви фактично не вказуєте на реальний файл, тому він не завантажується під час роботи в браузері. Це лише там, у складі Кордови, який працює на мобільному пристрої.
Майкл Орил

Схоже, це буде особливо добре, якщо використовувати PhoneGap Build.

4
@SlavikMe Не включайте сценарій cordova у збірки, що не входять у модулі.
Джексон

21

Найбільш надійний спосіб, який ми знайшли, щоб сказати, чи ми знаходимось у програмі cordova / phonegap, - це змінити користувацький агент програми cordova за допомогою цього конфігурації AppendUserAgent .

У 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" />це веб-сайт (напр .: <content src="https://www.example.com/index.html" />або з cordova-plugin-remote-injection )
  3. Спроба дозволених агентів користувача догадатись, чи це справжній браузер, дуже складна. Веб-переглядачі Android - це звичайні веб-перегляди.

2
І ми навіть можемо там додати версію програми! (в ідеалі з деякою логікою автоматичної версії) ex; Cordova AppName/v0.0.1<3 Отже, таким чином ви навіть можете якось використовувати це для відстеження (але зауважте, що кожен може змінити його
корисний засіб,

Це, здається, є найбільш нерозумним методом. Здається, другий підбіжник перевіряє відсутність http: // або https: // в URL-адресі документа, але я можу передбачити можливі сценарії, де це не спрацювало б.
JD Smith

14

Я думаю, що це найпростіше: var isPhoneGap = (location.protocol == "file:")

EDIT Для деяких людей, які не працювали. Тоді ви можете спробувати (не тестували)

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

1
Я думав, що PhoneGap запустив внутрішній сервер для всіх файлів на пристрої?
aaronsnoswell

Мені це подобається. Коли ви розвиваєтеся на localhost, це найкраще рішення. (Після багато спроб, сподіваюся, це працює у всіх сценаріях, сподіваємось.) Thx!
Маріо

1
це не працює в емуляторі пульсацій, коли я тестую віддалений файл
Джессі Хаттабо

Також не працює у WP8, протокол "x-wmapp0:". Не можу точно знати, які ще "протоколи" будуть використовуватися в майбутньому.
Адріан

Ну, ви також можете спробуватиvar isPhoneGap = ! /^http/.test(document.location.protocol)
Yuval

8

Це працює для мене (працює 1.7.0)

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

Тестовано на настільних Chrome і Safari.


3
Це майже те саме, що прив’язка до події "пристрій вже". Якщо window.device не визначено, ви не можете сказати, якщо phonegap / cordova завантажується повільно чи подія ніколи не закінчується.
Wytze

8
window.device не визначено до запуску події "пристрій вже".
Славік Мельцер

2
І моліться, щоб жоден інший програміст не мав щасливої ​​ідеї визначити новий глобальний вар, який називається "пристрій".
Містер Сміт

7

Як і в оригінальному плакаті, я використовую послугу побудови фонегапу. Після двох днів і майже 50 складання тестів я придумав елегантне рішення, яке чудово підходить для мене.

Я не міг використовувати нюхання UA, тому що хотів протестувати і працювати в мобільних браузерах. Я спочатку зупинився на досить функціональній техніці коббербоя. Це не спрацювало для мене, оскільки затримка / час очікування "howPatientAreWe: 10000" було занадто великим неприємністю для розробки браузера. А встановлення його нижче буде періодично провалювати тест у режимі програми / пристрою. Треба було бути іншим способом ...

Послуга побудови фонегапу вимагає phonegap.js файл було з вашого сховища коду, перш ніж надсилати файли програми в службу. Тому я маю змогу перевірити його існування, щоб визначити, чи працює він у браузері та програмі.

Ще один застереження, я також використовую jQueryMobile, тому і jQM, і фонегап довелося ініціалізувати, перш ніж я міг розпочати будь-які спеціальні сценарії. Наступний код розміщується на початку мого спеціального файлу 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 в глобальному масштабі. Якщо він є, то ви, швидше за все, працюєте в області Кордова.

var isCordovaApp = !!window.cordova;

2 - Кордова запустить вашу програму так, як ви відкриєте документ 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


5

Я використовую цей метод:

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

debugбуде trueв середовищі браузера, falseна пристрої.



3

Суть проблеми полягає в тому, що, поки cordova.device не визначено, ваш код не може бути впевнений, чи це тому, що cordova встановила, що ваш пристрій не підтримується, або якщо це тому, що 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), тому цей метод має перевагу бути 100% правильним незалежно від протоколів, userAgents або бібліотеки змінні (які можуть змінюватися). Можуть бути й інші речі, які я повинен включати в cordova.js, але я ще не знаю, що вони є.


Дуже цікавий підхід.

Хоча початковий сценарій вам дійсно не потрібен. Ви можете просто перевірити, чи він взагалі встановлений: .. if ( typeof __cordovaRunningOnBrowser__ !== 'undefined' ) { stuff(); } правда?

Правильно, тому що невизначеність може означати, що щось інше не так.
BT

3

Ще один спосіб, заснований на рішенні SlavikMe:

Просто використовуйте параметр запиту, переданий index.htmlз вашого джерела PhoneGap. Тобто, в 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" />. Поки це, здається, працює і є на сьогодні найкращим рішенням, запропонованим тут.
Мартін М.

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 ( завантаження тіла (...), $ (документ). Вже (...))

  • 'ontouchstart' у document.documentElement буде присутній на ноутбуках та настільних моніторах, які мають сенсорний екран, щоб він повідомляв про мобільний браузер, навіть якщо це робочий стіл. Існують різні способи зробити більш точну перевірку, але я використовую її, оскільки вона все ще займається 99% випадків, які мені потрібні. Ви завжди можете замінити цю лінію чимось більш надійним.


1
Я пропоную використовувати typeof cordova !== 'undefined'виняток замість риболовлі.
krakatoa

1

Аарони, спробуйте

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

Ні, я цього не робив. Подивіться на вихідний код phonegap-1.1.0.js. PhoneGap.available = DeviceInfo.uuid! == undefined;
GeorgeW

1

Рішення GeorgeW добре, але навіть на реальному пристрої PhoneGap.available є вірним лише після завантаження речей PhoneGap, наприклад, onDeviceReady в document.addEventListener ('пристрій вже', onDeviceReady, помилково).

До цього часу, якщо ви хочете знати, ви можете зробити так:

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

Це рішення передбачає, що більшість розробників розробляють за допомогою Chrome або Firefox.


ОП шукає рішення для виробничого веб-сайту, а не лише розробника.
Джессі Хаттабо

1

У мене те саме питання.

Я схиляюся до того, щоб додати # cordova = true до URL-адреси, завантаженої клієнтом cordova, і перевірити наявність моєї веб-сторінки на адресу location.hash.indexOf ("cordova = true")> -1.


Врешті-решт я пішов маршрутом, запропонованим Аль Рено у своєму 4-му пункті, і нехай вирішує сценарій побудови. Він скасовує прапор у index.html під час копіювання коду веб-сайту у папку активів Android. // UNCOMMENT ON-DEPLOY: window._appInfo.isCordova = true; Коли сценарій збірки копіює index.html у мою папку андроїд активів / www, я запускаю редактор, щоб видалити // UNCOMMENT-ON-DEPLOY: рядок. # Масаж index.html, щоб сказати, що він працює за кордовою редакцією "$ DEST / index.html" << - EOF 1, \ $ s / \ / \ / UNCOMMENT ON-DEPLOY: // wq EOF
Austin France

1

Наступне працює для мене з найсвіжішими PhoneGap / Cordova (2.1.0).

Як це працює:

  • Дуже простий в концепції
  • Я перевернув логіку деяких із вищезазначених рішень таймауту.
  • Зареєструйтесь на подію пристрою (як рекомендують документи PhoneGap )
    • Якщо подія все ще НЕ завершилася після тайм-ауту, відмовтеся від припущення браузера.
    • На відміну від цього, інші рішення, розроблені вище, покладаються на тестування певної функції PhoneGap чи іншого, а також на перегляд їх тестового перерви.

Переваги:

  • Використовує рекомендовану для пристрою подію PhoneGap.
  • Мобільний додаток не затримується. Як тільки запускається подія device_ready, ми продовжуємо роботу.
  • Ніякого нюхаючого агента користувача (мені подобається тестувати свою програму як мобільний веб-сайт, щоб нюхати браузер не було для мене варіантом).
  • Немає покладатися на незадокументовані (і, отже, крихкі) функції / властивості PhoneGap.
  • Зберігайте cordova.js у своїй кодовій базі навіть під час використання настільного або мобільного браузера. Таким чином, це відповідає на питання ОП.
  • 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-відсотковій умові) рішенням PRE-визначення контексту виконання програми було таке:

  • ініціалізувати змінну "прапор" JS на true та змінити її на false, якщо вона знаходиться в контексті загальної мережі;

  • тому ви можете використовувати виклик типу " willIBeInPhoneGapSometimesInTheNearFuture()" (це PRE-PG; звичайно, вам все одно потрібен метод POST-PG для перевірки, чи можете ви викликати PG API, але це тривіально).

  • Тоді ви кажете: " but how do you determine the execution context?"; відповідь: "ви цього не робите" (тому що я не думаю, що ви можете надійно, якщо тільки ті блискучі люди в PG не зробили б це у своєму API-коді);

  • Ви пишете сценарій збірки, який робить це для вас: одна база коду з двома варіантами.


1

Чи не на самому ділі відповідь на це питання, butwhen тест я в браузері настільного комп'ютера, просто встановіть значення LocalStorage , щоб зробити завантаження браузера додатки dispite 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

Жоден з яких не працює, якщо ви не видалите файл JavaScript 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

Я фактично знайшов комбінацію двох перерахованих тут методів, які працювали найкраще, по-перше, перевірте, чи можна отримати доступ до кордова / фонегапу, і перевірити, чи доступний пристрій. Так:

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

Я використовую комбінацію запропонованих GeorgeW та mkprogramming :

   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] (вони все одно будуть чистими для розгортання, так що це може бути однією з цих задач.) У будь-якому випадку я відчуваю це хороший варіант (враховуючи, що не багато іншого доступно), щоб ефективно просто вручну коментувати речі з isMobileBrowserAndNotPhoneGap при натисканні на PG). Знову для мене в моїй ситуації я просто видалю тег для файлу (ізольований код), який підштовхує вниз на панель навігації, коли це мобільний браузер (він буде набагато швидшим і меншим). [Отже, якщо ви можете виділити код для оптимізованого, але ручного рішення.]


0

Трохи модифікований, але працює для мене ідеально без проблем.

Намічається завантажувати Кордову лише тоді, коли на вбудованому пристрої, а не на робочому столі, тож я повністю уникаю кордова в настільному браузері. Тестування та розробка 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);
}

Тоді замість того, щоб сам JavaScript 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 Точка розробки мобільних додатків

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

Я намагався з об’єктами вікна, але це не спрацювало, коли я відкривав віддалений URL в InAppBrowser. Не вдалося це зробити. Таким чином, найкращим і найпростішим способом досягти цього було додавання рядка до URL-адреси, який потрібно відкрити через додаток phonegap. Потім перевірте, чи до документа документа додано рядок.

Нижче наведено простий код для нього

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");
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.