PhoneGap: определить, запущен ли он в браузере рабочего стола


118

Я разрабатываю веб-приложение, использующее PhoneGap: Build для мобильной версии и хочу иметь единую базу кода для «настольной» и мобильной версий. Я хочу иметь возможность определять, будут ли работать вызовы PhoneGap (т. Е. Есть ли у пользователя мобильное устройство, поддерживающее PhoneGap).

Я искал и не могу поверить, что нет простого способа сделать это. Многие люди предлагали свои предложения;

Ничего из этого не сработает, если вы не удалите файл Javascript PhoneGap из настольной версии приложения, что противоречит моей цели иметь единую базу кода.

Пока что единственным решением, которое я придумал, является обнюхивание браузера / пользовательского агента, но это, мягко говоря, не надежно. Приветствуются любые лучшие решения!

РЕДАКТИРОВАТЬ: немного лучшим решением является попытка вызвать функцию PhoneGap после небольшого тайм-аута - если это не сработает, предположим, что пользователь находится в настольном веб-браузере.


Поскольку вы используете Build, см. Ответ @bt ниже: stackoverflow.com/a/18478002/241244 . Похоже, это может быть лучше, чем принятые и получившие наибольшее количество голосов ответы.

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

Ответы:


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
Это неточно, потому что, если я открою ту же страницу в обзоре устройства, onDeviceReady () никогда не вызовет. Кроме того, если я изменю UserAgent в браузере (для целей отладки), onDeviceReady () тоже никогда не будет вызывать.
— Славик Мельцер

3
Не уверен, что вы говорите, но похоже, что вы подразумеваете, что это вызовет проблемы с использованием браузера телефона ... Это решение для тестирования в браузере вашего компьютера, а не на телефоне.
— sirmdawg 07

7
Это не помогает, когда вы открываете приложение в браузере устройства. Лучшее решение: проверьте window.cordova. Тестирование в iPhone Simulator (браузер) или на устройстве Android (браузер) также должно обнаружить PhoneGap. Так я развиваюсь. Но есть много возможностей добиться желаемого. ;-) Спасибо за размещение вашего решения!
— Марио

Я запутался, а как насчет других платформ, таких как Windows Phone? У них есть агент пользователя, соответствующий этому регулярному выражению? Быстрый поиск в 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)
  • Window Phone 7 - Не знаю, где (кто-то все еще разрабатывает эту платформу ?!)

Наконец, вы можете использовать его где угодно на своем сайте, независимо от того, работает он на PhoneGap или нет:

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

Надеюсь, поможет. :-)


4
Считаю этот ответ лучшим!
— blong824 05

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 06

1
@rblakeley, ты прав. Я переключил первую строчку на:return ( typeof cordova !== undefined || typeof PhoneGap !== undefined || typeof phonegap !== undefined )
— ethanpil

1
@rojobuffalo: Похоже, что с тех пор ответ был изменен, поэтому он снова работает так, как ожидалось ( т.е. он больше не выдает a ReferenceErrorиз-за windowпрефикса). Просто подумал, что я укажу на это, поскольку это фактически делает цепочку комментариев устаревшей (и, следовательно, неправильной).
— Priidu Neemre

27

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

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

или с версии 1.7 предпочтительнее:

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

РЕДАКТИРОВАТЬ 2019: как сказано в комментариях, это работает только в том случае, если вы не включите cordova lib в сборку настольного браузера. И, конечно же, рекомендуется включать только строгий минимум файлов javascript / html / css для каждого целевого устройства.


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

Можете ли вы помочь мне на примере. Чтобы просто загрузить index.html. Я загружаю все файлы в папку www на моем локальном сервере, я загружаю index.html. Но устройство готово не уволен.
— Nassif

5
Теперь это кажется правильным ответом (по крайней мере, с Cordova 3.4). Все остальные методы - пустая трата времени, так как cordova.js теперь вводится в приложение с помощью простого <script type = "text / javascript" src = "cordova.js"> </script>. На самом деле вы не указываете на настоящий файл, поэтому он не загружается при запуске в браузере. Он есть только в сборке Cordova, работающей на мобильном устройстве.
— Майкл Орил

Похоже, что это будет особенно хорошо работать при использовании PhoneGap Build.

4
@SlavikMe Не включайте сценарий Cordova в сборки, отличные от Cordova.
— Джексон

21

Самый надежный способ узнать, находимся ли мы в приложении cordova / phonegap, - это изменить пользовательский агент этого приложения с помощью этой конфигурации 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 Таким образом, вы даже можете каким-то образом использовать это для отслеживания (но учтите, что любой может изменить его пользовательский агент, поэтому не полагайтесь на него для критически важных проверок безопасности)
— GabLeRoux

Это кажется наиболее надежным методом. Второе место, занявшее второе место, похоже, проверяет отсутствие http: // или https: // в URL-адресе документа, но я могу представить себе возможные сценарии, в которых это не сработает.
— Джей Ди Смит,

14

Думаю, это проще всего: var isPhoneGap = (location.protocol == "file:")

ИЗМЕНИТЬ Для некоторых людей это не сработало. Тогда вы можете попробовать (не тестировали)

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

1
Я думал, что PhoneGap запускает внутренний сервер для всех файлов на устройстве?
— aaronsnoswell

Мне это нравится. При разработке на localhost это лучшее решение. (После многих попыток я надеюсь, что это сработает во всех сценариях, надеюсь.) Спасибо!
— Марио

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

Также не работает в WP8, протокол - «x-wmapp0:». Не могу точно знать, какие еще «протоколы» будут использоваться в будущем.
— Адриан

Ну, вы могли бы такжеvar isPhoneGap = ! /^http/.test(document.location.protocol)
— Юваль

8

Это работает для меня (работает 1.7.0)

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

Проверено на настольных компьютерах Chrome и Safari.


3
Это почти то же самое, что и привязка к событию deviceready. Если window.device не определен, вы не можете определить, загружается ли phonegap / cordova медленно или событие никогда не сработает.
— Wytze

8
window.device не определяется до запуска события «deviceready».
— Славик Мельцер

2
И молитесь, чтобы ни у одного другого программиста не возникло счастливой идеи определить новую глобальную переменную под названием «устройство».
— Мистер Смит

7

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

Я не мог использовать сниффинг UA, потому что хотел протестировать и запустить в мобильных браузерах. Изначально я остановился на довольно функциональной технике cobberboy. У меня это не сработало, потому что задержка / тайм-аут "howPatientAreWe: 10000" слишком мешала разработке в браузере. А установка более низкого значения иногда проваливала бы тест в режиме приложения / устройства. Должен был быть другой способ ...

Служба сборки телефонной связи требует, чтобы phonegap.jsфайл был исключен из репозитория кода перед отправкой файлов вашего приложения в службу. Поэтому я могу проверить его существование, чтобы определить, работает ли он в браузере или в приложении.

Еще одно предостережение: я также использую jQueryMobile, поэтому и jQM, и phonegap должны быть инициализированы, прежде чем я смогу начать любой пользовательский скрипт. Следующий код помещен в начало моего настраиваемого файла index.js для приложения (после jQuery, перед jQM). Также в документации по сборке телефонного разговора говорится, что нужно разместить <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 он будет использовать ФАЙЛ. Обнаружение этого даст вам возможность предположить, что ваше приложение было загружено локально.

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на устройстве.


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 сработает позже. (или третий вариант: кордова не загрузилась должным образом).

Единственное решение - определить период ожидания и решить, что после этого периода ваш код должен предполагать, что устройство не поддерживается. Я бы хотел, чтобы кордова установила параметр где-нибудь, чтобы сказать «Мы пытались найти поддерживаемое устройство, но отказались», но похоже, что такого параметра нет.

Как только это будет установлено, вы можете захотеть сделать что-то конкретное именно в тех ситуациях, когда нет поддерживаемого устройства. В моем случае вроде скрытия ссылок на магазин приложений устройства.

Я собрал по кусочкам эту функцию, которая должна охватывать практически любую ситуацию. Он позволяет вам определять обработчик готовности устройства, обработчик готовности устройства и время ожидания.

//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% верен независимо от протоколов, агентов пользователя или библиотеки. переменные (которые могут измениться). Могут быть и другие вещи, которые мне следует включить в cordova.js, но я еще не знаю, что это такое.


Очень интересный подход.

Хотя вам действительно не нужен исходный сценарий. Вы можете просто проверить, установлен ли он вообще: .. if ( typeof __cordovaRunningOnBrowser__ !== 'undefined' ) { stuff(); } правильно?

Верно, хотя значение undefined может означать, что что-то еще не так.
— 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 (body onload (...), $ (document) .ready (...))

  • '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 ('deviceready', onDeviceReady, false).

До этого времени, если вы хотите знать, вы можете сделать так:

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

Это решение предполагает, что большинство разработчиков разрабатывают с использованием Chrome или Firefox.


OP ищет решение для производственного веб-сайта, а не только для разработчиков.
— Джесси Хаттабо

1

У меня такая же проблема.

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


В конце концов, я пошел по пути, предложенному Аль Рено в его 4-м пункте, и предоставил решение сценарию сборки. Он раскомментирует флаг в index.html при копировании кода веб-сайта в папку ресурсов Android. // ОТКРЫТИЕ ПРИ РАЗВЕРТЫВАНИИ: window._appInfo.isCordova = true; Когда сценарий сборки копирует index.html в мою папку с ресурсами / www android, я запускаю на нем 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 и наблюдение за их тестовым перерывом.

Преимущества:

  • Использует событие device_ready, рекомендованное PhoneGap.
  • Мобильное приложение без задержек. Как только сработает событие device_ready, мы продолжаем.
  • Никакого обнюхивания пользовательского агента (мне нравится тестировать свое приложение как мобильный веб-сайт, поэтому анализ браузера не был для меня вариантом).
  • Не полагайтесь на недокументированные (и, следовательно, хрупкие) функции / свойства PhoneGap.
  • Сохраняйте ваш cordova.js в своей кодовой базе даже при использовании настольного или мобильного браузера. Таким образом, это отвечает на вопрос ОП.
  • Wytze заявил выше: «Я бы хотел, чтобы кордова установила параметр где-нибудь, чтобы сказать:« Мы пытались найти поддерживаемое устройство, но отказались », но похоже, что такого параметра нет». Так что я привожу его здесь.

Недостатки:

  • Тайм-ауты неприятны. Но логика нашего мобильного приложения не зависит от задержки; скорее, он используется как запасной вариант, когда мы находимся в режиме веб-браузера.

==

Создайте новый пустой проект 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()" (это PRE-PG, конечно, вам все еще нужен метод POST-PG для проверки того, можете ли вы вызывать API PG, но это тривиально).

  • Затем вы говорите: « but how do you determine the execution context?»; ответ: «нет» (потому что я не думаю, что вы можете надежно, если только эти блестящие ребята из PG не сделают это в своем коде API);

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


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

Ничего из этого не сработает, если вы не удалите файл Javascript PhoneGap из настольной версии приложения, что противоречит моей цели иметь единую базу кода.

Другой вариант - использовать слияния папку , см. Снимок экрана ниже.

Вы можете добавлять файлы для конкретной платформы / отменять файлы по умолчанию.

(он должен помочь в некоторых сценариях)

введите описание изображения здесь


Другими словами: вместо того, чтобы определять браузер, вы просто не включаете определенные файлы для сборки на рабочем столе / не прикрепляете определенные файлы только для 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: check, предложенный выше.

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

Я заинтересован в том, чтобы поднять панель навигации браузеров вверх, так что на самом деле я могу просто удалить тег изолированного скрипта и нажать rebuild [в DW] (они все равно будут очищать для развертывания, так что это может быть одной из этих задач). В любом случае, я чувствую это хороший вариант (учитывая, что больше ничего не доступно), чтобы просто вручную комментировать вещи с помощью isMobileBrowserAndNotPhoneGap при нажатии на PG). Опять же, в моей ситуации я просто удалю тег для файла (изолированного кода), который поднимает панель навигации, когда это мобильный браузер (он будет намного быстрее и меньше). [Так что, если вы можете выделить код для этого оптимизированного, но ручного решения.]


0

Немного изменен, но у меня работает отлично, без проблем.

Намерение состоит в том, чтобы загружать Cordova только на встроенном устройстве, а не на рабочем столе, поэтому я полностью избегаю Cordova в браузере для настольных компьютеров. Тестирование и разработка пользовательского интерфейса и 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 включите 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-адресу, который вам нужно открыть из приложения телефонной связи. Затем проверьте, не добавлена ​​ли к месту расположения документа строка.

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

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.