PhoneGap: Mendeteksi jika dijalankan di browser desktop

118

Saya mengembangkan aplikasi web yang menggunakan PhoneGap: Build untuk versi seluler dan ingin memiliki satu basis kode untuk 'versi desktop' dan seluler. Saya ingin dapat mendeteksi apakah panggilan PhoneGap akan berfungsi (yaitu, apakah pengguna di perangkat seluler yang akan mendukung PhoneGap).

Saya telah mencari dan tidak percaya tidak ada cara sederhana untuk melakukan ini. Banyak orang telah memberikan saran;

Tidak ada yang berfungsi, kecuali Anda menghapus file Javascript PhoneGap dari versi desktop aplikasi, yang mengalahkan tujuan saya untuk memiliki satu basis kode.

Sejauh ini, satu-satunya solusi yang saya temukan adalah mengendus peramban / agen pengguna, tetapi ini tidak kuat untuk sedikitnya. Solusi yang lebih baik diterima!

EDIT: Solusi yang sedikit lebih baik adalah mencoba memanggil fungsi PhoneGap setelah beberapa waktu tunggu sebentar - jika tidak berhasil, anggaplah pengguna menggunakan browser web desktop.

aaronsnoswell
sumber
Karena Anda menggunakan Build, lihat jawaban @ bt di bawah ini: stackoverflow.com/a/18478002/241244 . Sepertinya itu mungkin lebih baik daripada jawaban yang diterima dan paling banyak dipilih.
Saya menghindari deteksi run-time yang mendukung konfigurasi waktu build eksplisit karena 100% efektif. Saya cukup meneruskan var lokal ke template index.jade saya seperti {isPhonegap: true}, lalu di template saya dapat secara bersyarat menyertakan skrip phonegap.js, dan melakukan semua init phonegap spesifik yang saya inginkan.
Jesse Hattabaugh

Jawaban:

115

Saya menggunakan kode ini:

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

MEMPERBARUI

Ada banyak cara lain untuk mendeteksi apakah phonegap berjalan di browser atau tidak, berikut ini pilihan bagus lainnya:

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

seperti yang terlihat di sini: Mendeteksi antara browser seluler atau aplikasi PhoneGap

sirmdawg.dll
sumber
Terima kasih untuk ini - setelah menunggu lama untuk melihat apa yang disarankan orang lain, ini tampaknya menjadi solusi terbaik. Bersulang.
aaronsnoswell
35
Ini tidak akurat, karena jika saya akan membuka halaman yang sama pada penelusuran Perangkat, onDeviceReady () tidak akan pernah memanggil. Ditambah jika saya akan mengubah UserAgent di browser (untuk tujuan debug), onDeviceReady () juga tidak akan pernah memanggil.
Slavik Meltser
3
Tidak yakin apa yang Anda katakan - tetapi tampaknya Anda menyiratkan ini akan menyebabkan masalah dalam menggunakan browser ponsel ... Ini adalah solusi untuk menguji di browser desktop Anda, bukan di ponsel Anda.
sirmdawg
7
Ini tidak membantu saat Anda membuka aplikasi di browser perangkat. Solusi yang lebih baik: periksa window.cordova. Pengujian di iPhone Simulator (browser) atau di perangkat Android (browser) juga harus mendeteksi PhoneGap. Itulah cara saya berkembang. Tetapi ada banyak kemungkinan untuk menyelesaikan sesuatu. ;-) Terima kasih telah memposting solusi Anda!
Mario
Saya bingung, bagaimana dengan platform lain seperti windows phone? Apakah mereka memiliki userAgent yang cocok dengan ekspresi reguler itu? Sebuah pencarian google cepat menyiratkan tidak: madskristensen.net/post/Windows-Phone-7-user-agents.aspx
mooreds
49

Saya menulis posting tentang itu beberapa hari yang lalu. Ini adalah solusi terbaik yang dapat Anda temukan (sampai PhoneGap akan merilis sesuatu, mungkin atau mungkin tidak), ini singkat, sederhana dan sempurna (saya telah memeriksanya dengan segala cara dan platform yang memungkinkan).

Fungsi ini akan berfungsi untuk 98% kasus.

/**
 * 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!");
}

Untuk menyelesaikan 2% kasus lainnya, ikuti langkah-langkah berikut (ini melibatkan sedikit perubahan pada kode native):

Buat file bernama __phonegap_index.html , dengan sumber:

<!-- __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>

Sekarang, di native cukup ubah halaman awal dari index.html ke __phonegap_index.html di semua platform PhoneGap Anda. Katakanlah nama proyek saya adalah contoh , file yang perlu Anda ubah adalah (seperti untuk PhoneGap versi 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
  • Bada - src/WebForm.cpp(baris 56)
  • Window Phone 7 - Tidak tahu di mana (seseorang masih mengembangkan di platform itu ?!)

Terakhir, Anda dapat menggunakannya di mana saja di situs Anda, apakah itu berjalan di PhoneGap atau tidak:

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

Semoga membantu. :-)

Slavik Meltser
sumber
4
Menemukan jawaban ini sebagai yang terbaik!
blong824
3
ya berfungsi tetapi beberapa kali bagian kode berikutnya tidak benar /^file:\/{3}[^\/]/i.test(window.location.href)tetapi kami menggunakan PhoneGap, misalnya saat memuat index.html dari halaman lain, di config.xml sesuatu seperti ini<content src="http://10.100.1.147/" />
vudduu
3
Ekspresi tersebut (cordova || PhoneGap || phonegap) akan memunculkan ReferenceError jika salah satu variabel tersebut tidak ditentukan. Anda harus mengujinya typeof cordova !== undefined, bukan?
rojobuffalo
1
@rblakeley Anda benar. Saya mengganti baris pertama ke:return ( typeof cordova !== undefined || typeof PhoneGap !== undefined || typeof phonegap !== undefined )
ethanpil
1
@rojobuffalo: Sepertinya jawabannya telah diubah, membuatnya berfungsi seperti yang diharapkan lagi ( yaitu tidak membuang ReferenceErrorlagi karena windowawalan). Hanya berpikir saya akan menunjukkan ini, karena ini sebenarnya membuat rantai komentar ketinggalan jaman (dan karenanya, tidak benar).
Priidu Neemre
27

Saya tahu ini telah dijawab beberapa waktu yang lalu tetapi "PhoneGap.available" tidak ada lagi. Kamu harus menggunakan:

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

atau sejak 1.7, lebih suka:

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

EDIT 2019: seperti yang dikatakan di komentar, ini hanya berfungsi jika Anda tidak menyertakan cordova lib ke dalam build browser desktop Anda. Dan tentu saja merupakan praktik yang baik untuk hanya menyertakan file javascript / html / css minimum yang ketat untuk setiap perangkat yang Anda targetkan

fredericrous
sumber
18
Ini tidak benar, karena window.PhoneGap atau window.cordova akan selalu ditentukan jika Anda menyertakan skrip cordova-xxxjs, bahkan jika itu dimuat di browser.
Slavik Meltser
Bisakah Anda membantu saya dengan sebuah contoh.Untuk memuat index.html. Apa yang saya lakukan adalah bahwa saya telah mengunggah semua file di bawah folder www di server lokal saya, saya memuat index.html. Tapi perangkat sudah siap tidak dipecat.
Nassif
5
Ini tampaknya menjadi jawaban yang benar sekarang (setidaknya dengan Cordova 3.4). Semua metode lainnya hanya membuang-buang waktu karena cordova.js dimasukkan ke dalam aplikasi dengan <script type = "text / javascript" src = "cordova.js"> </script> sederhana sekarang. Anda tidak benar-benar menunjuk ke file yang sebenarnya, jadi file tidak dimuat saat dijalankan di browser. Itu hanya ada di build Cordova yang berjalan di perangkat seluler.
Michael Oryl
Sepertinya ini akan bekerja dengan baik jika menggunakan PhoneGap Build.
4
@SlavikMe Jangan menyertakan skrip cordova di build non-cordova.
Jackson
21

Cara paling tepercaya yang kami temukan untuk mengetahui apakah kita berada dalam aplikasi cordova / phonegap adalah dengan memodifikasi agen pengguna aplikasi cordova menggunakan konfigurasi AppendUserAgent ini .

Di config.xmltambahkan:

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

Kemudian hubungi:

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

Mengapa?

  1. window.cordovadan document.addEventListener('deviceready', function(){});tunduk pada ketentuan balapan
  2. navigator.standalonetidak berfungsi ketika <content src="index.html" />sebuah situs web (Mis: <content src="https://www.example.com/index.html" />atau dengan cordova-plugin-remote-injection )
  3. Mencoba memasukkan agen pengguna ke daftar putih untuk menebak apakah ini adalah browser yang sebenarnya sangat rumit. Browser Android sering kali berupa tampilan web khusus.
jrobichaud.dll
sumber
2
Dan kami bahkan dapat menambahkan versi aplikasi di sana! (idealnya dengan beberapa logika benjolan versi otomatis) ex; Cordova AppName/v0.0.1<3 Jadi dengan cara ini, Anda bahkan dapat menggunakan ini untuk pelacakan (tetapi perhatikan bahwa siapa pun dapat mengubah agen penggunanya jadi jangan mengandalkan ini untuk verifikasi penting keamanan)
GabLeRoux
Ini sepertinya metode yang paling mudah dilakukan. Runner up kedua tampaknya menguji ketiadaan http: // atau https: // di URL dokumen, tetapi saya dapat membayangkan kemungkinan skenario di mana hal itu tidak akan berhasil.
JD Smith
14

Saya pikir ini paling sederhana: var isPhoneGap = (location.protocol == "file:")

EDIT Untuk beberapa orang yang tidak berhasil. Maka Anda mungkin mencoba (belum diuji)

var isPhoneGap = ! /^http/.test(location.protocol);
Yuval
sumber
1
Saya pikir PhoneGap menjalankan server internal untuk semua file di perangkat itu?
aaronsnoswell
Saya suka itu. Saat mengembangkan di localhost, ini adalah solusi terbaik. (Setelah mencoba banyak, saya harap ini berfungsi di semua skenario, semoga.) Terima kasih!
Mario
1
ini tidak berfungsi di emulator riak ketika saya menguji file jarak jauh
Jesse Hattabaugh
Juga tidak berfungsi di WP8, protokolnya adalah "x-wmapp0:". Tidak tahu pasti "protokol" lain apa yang akan digunakan di masa mendatang.
Adrian
Nah, Anda juga bisa --mencobavar isPhoneGap = ! /^http/.test(document.location.protocol)
Yuval
8

Ini berfungsi untuk saya (menjalankan 1.7.0)

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

Diuji di Chrome desktop dan Safari.

rampok
sumber
3
Ini hampir sama dengan mengikat acara 'deviceready'. Jika window.device tidak ditentukan, Anda tidak dapat mengetahui apakah phonegap / cordova lambat dalam memuat atau jika acara tidak akan pernah aktif.
Wytze
8
window.device tidak ditentukan sebelum peristiwa "deviceready" dipicu.
Slavik Meltser
2
Dan berdoa agar tidak ada programmer lain yang memiliki ide bagus untuk mendefinisikan var global baru yang disebut "perangkat".
Mister Smith
7

Seperti poster asli, saya menggunakan layanan pembuatan peta telepon. Setelah dua hari dan hampir 50 uji coba, saya telah menemukan solusi elegan yang cocok untuk saya.

Saya tidak dapat menggunakan pengendusan UA karena saya ingin menguji dan menjalankannya di browser seluler. Saya awalnya memilih teknik yang cukup fungsional cobberboy. Ini tidak berhasil untuk saya karena penundaan / waktu tunggu "howPatientAreWe: 10000" terlalu mengganggu pengembangan dalam browser. Dan menyetelnya lebih rendah terkadang akan gagal dalam pengujian dalam mode aplikasi / perangkat. Pasti ada cara lain ...

Layanan build phonegap mengharuskan phonegap.jsfile dihilangkan dari repositori kode Anda sebelum mengirimkan file aplikasi Anda ke layanan. Oleh karena itu saya dapat menguji keberadaannya untuk menentukan apakah berjalan di browser vs. aplikasi.

Satu peringatan lain, saya juga menggunakan jQueryMobile, jadi baik jQM dan phonegap harus diinisialisasi sebelum saya dapat memulai pembuatan skrip khusus. Kode berikut ditempatkan di awal file index.js kustom saya untuk aplikasi (setelah jQuery, sebelum jQM). Juga dokumen phonegap build mengatakan untuk ditempatkan <script src="phonegap.js"></script>di suatu tempat di HTML. Saya meninggalkannya sepenuhnya dan memuatnya menggunakan $ .getScript () untuk menguji fasilitas keberadaannya.

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!
    }
}
Jim H.
sumber
6

Menariknya, ada banyak jawaban, tetapi tidak menyertakan tiga opsi ini:

1 - Cordova.js akan mengatur objek cordova dalam lingkup global. Jika ada maka kemungkinan besar Anda menjalankan dalam lingkup Cordova.

var isCordovaApp = !!window.cordova;

2 - Cordova akan menjalankan aplikasi Anda seperti Anda membuka dokumen HTML dari Desktop Anda. Alih-alih protokol HTTP, ia akan menggunakan FILE. Mendeteksi ini akan memberi Anda kesempatan untuk berasumsi bahwa aplikasi Anda dimuat secara lokal.

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

3 - Gunakan peristiwa pemuatan skrip cordova untuk mendeteksi konteksnya. Termasuk skrip dapat dengan mudah dihapus dalam proses pembangunan atau pemuatan skrip hanya akan gagal di browser. Sehingga variabel global ini tidak akan disetel.

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

Kredit diberikan kepada Damien Antipa dari Adobe

Frodik
sumber
5

Saya menggunakan metode ini:

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

debugakan ada truedi lingkungan browser, falsedi perangkat.

andreszs
sumber
4

Ini tampaknya layak dan saya telah menggunakannya dalam produksi:

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

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

Deminetix
sumber
3

Inti dari masalahnya adalah selama cordova.device tidak ditentukan, kode Anda tidak dapat memastikan apakah itu karena cordova telah menetapkan bahwa perangkat Anda tidak didukung, atau jika itu karena cordova masih mempersiapkan dirinya sendiri dan perangkat akan menyala nanti (atau opsi ketiga: cordova tidak dimuat dengan benar).

Satu-satunya solusi adalah menentukan masa tunggu, dan memutuskan bahwa setelah jangka waktu ini kode Anda harus menganggap perangkat tidak didukung. Saya berharap cordova akan menetapkan parameter di suatu tempat untuk mengatakan "Kami telah mencoba menemukan perangkat yang didukung dan menyerah" tetapi sepertinya tidak ada parameter seperti itu.

Setelah ini dibuat, Anda mungkin ingin melakukan sesuatu yang spesifik dengan tepat dalam situasi di mana tidak ada perangkat yang didukung. Seperti menyembunyikan tautan ke pasar aplikasi perangkat, dalam kasus saya.

Saya telah menggabungkan fungsi ini yang seharusnya mencakup hampir semua situasi. Ini memungkinkan Anda menentukan penangan perangkat, penangan yang tidak pernah siap perangkat, dan waktu tunggu.

//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
                    }
                }
            }
    }

}
Wytze
sumber
3

Cara saya melakukannya adalah menggunakan variabel global yang ditimpa oleh cordova.js versi khusus browser. Di file html utama Anda (biasanya index.html), saya memiliki skrip berikut yang bergantung pada pesanan:

    <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 -->

Dan di dalamnya cordova.jssaya hanya memiliki:

__cordovaRunningOnBrowser__ = true

Saat membuat untuk perangkat seluler, cordova.js tidak akan digunakan (dan sebagai gantinya file cordova.js khusus platform akan digunakan), jadi metode ini memiliki keuntungan 100% benar terlepas dari protokol, agen pengguna, atau pustaka variabel (yang dapat berubah). Mungkin ada hal lain yang harus saya sertakan di cordova.js, tapi saya belum tahu apa itu.

BT
sumber
Pendekatan yang sangat menarik.
Padahal, Anda tidak terlalu membutuhkan skrip awal. Anda hanya dapat mengujinya untuk disetel sama sekali: .. benar if ( typeof __cordovaRunningOnBrowser__ !== 'undefined' ) { stuff(); } ?
Benar, jika tidak ditentukan mungkin menunjukkan ada sesuatu yang salah.
BT
3

Cara lain, berdasarkan solusi SlavikMe:

Cukup gunakan parameter kueri yang diteruskan ke index.htmldari sumber PhoneGap Anda. Yaitu, di Android, bukan

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

menggunakan

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

SlavikMe memiliki daftar bagus tentang tempat melakukan ini di platform lain.

Maka Anda index.htmlcukup melakukan ini:

if (window.location.href.match(/phonegap=1/)) {
  alert("phonegap");
}
else {
  alert("not phonegap");
}
Andrew Magee
sumber
1
Saya menggunakan Cordova 3.4.1 dan bahkan lebih sederhana: Anda hanya perlu mengubah <content src="index.html" />opsi di file config.xml menjadi <content src="index.html?cordova=1" />. Sejauh ini tampaknya berfungsi dan sejauh ini merupakan solusi terbaik yang disarankan di sini.
Martin M.
2

Untuk mempertahankan satu basis kode, yang menarik adalah "platform" tempat kode dijalankan. Bagi saya, "platform" ini bisa terdiri dari tiga hal yang berbeda:

  • 0: browser-komputer
  • 1: peramban seluler
  • 2: phonegap / cordova

Cara untuk memeriksa platform:

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

catatan:

  • Ini harus dijalankan hanya setelah cordova.js dimuat (body onload (...), $ (document) .ready (...))

  • 'ontouchstart' di document.documentElement akan hadir di laptop dan monitor desktop yang memiliki layar sentuh aktif sehingga akan melaporkan browser seluler meskipun itu adalah desktop. Ada berbagai cara untuk melakukan pemeriksaan yang lebih tepat tetapi saya menggunakannya karena masih menangani 99% kasus yang saya butuhkan. Anda selalu dapat mengganti baris itu dengan sesuatu yang lebih kuat.

Nik
sumber
1
Saya sarankan menggunakan typeof cordova !== 'undefined'alih-alih memancing untuk pengecualian.
krakatoa
1

Aarons, coba

if (PhoneGap.available){
    do PhoneGap stuff;
}
GeorgeW
sumber
Tidak, aku tidak melakukannya. Lihat kode sumber phonegap-1.1.0.js. PhoneGap.available = DeviceInfo.uuid! == tidak ditentukan;
GeorgeW
1

Solusi GeorgeW tidak apa-apa, tetapi bahkan pada perangkat nyata, PhoneGap.available hanya berlaku setelah hal-hal PhoneGap dimuat, misalnya onDeviceReady di document.addEventListener ('deviceready', onDeviceReady, false) telah dipanggil.

Sebelum itu, jika Anda ingin tahu, Anda bisa melakukan seperti ini:

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

Solusi ini mengasumsikan bahwa sebagian besar pengembang mengembangkan menggunakan Chrome atau Firefox.

Ngoc Dao
sumber
OP sedang mencari solusi untuk situs produksi, bukan hanya pengembang.
Jesse Hattabaugh
1

Saya memiliki masalah yang sama.

Saya cenderung menambahkan # cordova = true ke URL yang dimuat oleh klien cordova dan menguji location.hash.indexOf ("cordova = true")> -1 di halaman web saya.

Austin Prancis
sumber
Pada akhirnya, saya mengikuti rute yang disarankan oleh Al Renaud di poin ke-4, dan membiarkan skrip build memutuskan. Ini menghapus tanda komentar pada tanda di index.html saat menyalin kode situs web ke dalam folder aset android. // UNCOMMENT-ON-DEPLOY: window._appInfo.isCordova = true; Ketika skrip build menyalin index.html ke folder android assets / www saya, saya menjalankannya untuk menghapus // UNCOMMENT-ON-DEPLOY: string. # Massage index.html untuk memberitahukan bahwa sedang berjalan cordova ed "$ DEST / index.html" << - EOF 1, \ $ s / \ / \ / UNCOMMENT-ON-DEPLOY: // wq EOF
Austin Prancis
1

Berikut ini bekerja untuk saya dengan PhoneGap / Cordova (2.1.0) terbaru.

Bagaimana itu bekerja:

  • Sangat sederhana dalam konsepnya
  • Saya membalik logika dari beberapa solusi batas waktu di atas.
  • Mendaftar ke acara device_ready (seperti yang direkomendasikan oleh dokumen PhoneGap )
    • Jika peristiwa masih BELUM diaktifkan setelah waktu tunggu, kembali ke asumsi browser.
    • Sebaliknya, solusi lain di atas bergantung pada pengujian beberapa fitur PhoneGap atau lainnya, dan memperhatikan pengujian mereka berhenti.

Keuntungan:

  • Menggunakan acara device_ready yang direkomendasikan PhoneGap.
  • Aplikasi seluler tidak memiliki penundaan. Segera setelah peristiwa device_ready diaktifkan, kami melanjutkan.
  • Tidak ada agen pengguna yang mengendus (Saya suka menguji aplikasi saya sebagai situs web seluler sehingga mengendus peramban bukanlah pilihan bagi saya).
  • Tidak ada ketergantungan pada fitur / properti PhoneGap yang tidak berdokumen (dan karenanya rapuh).
  • Simpan cordova.js Anda dalam basis kode Anda bahkan saat menggunakan desktop atau browser seluler. Dengan demikian, ini menjawab pertanyaan OP.
  • Wytze menyatakan di atas: 'Saya berharap cordova akan menetapkan parameter di suatu tempat untuk mengatakan "Kami telah mencoba menemukan perangkat yang didukung dan menyerah" tetapi sepertinya tidak ada parameter seperti itu.' Jadi saya menyediakan satu di sini.

Kekurangan:

  • Batas waktu itu menjijikkan. Namun logika aplikasi seluler kami tidak bergantung pada penundaan; sebaliknya, ini digunakan sebagai cadangan saat kita berada dalam mode browser web.

==

Buat proyek PhoneGap kosong baru. Dalam contoh index.js yang diberikan, ganti variabel "app" di bagian bawah dengan ini:

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"));
}
cobberboy
sumber
1

Saya tersandung pada masalah ini beberapa bulan yang lalu ketika memulai aplikasi kami, karena kami ingin aplikasi juga " browser-compatible" (dengan pemahaman bahwa beberapa fungsi akan diblokir dalam skenario itu: rekaman audio, kompas, dll.).

Satu-satunya 100%(dan saya bersikeras pada kondisi 100-ratus persen) untuk PRA-menentukan konteks eksekusi aplikasi adalah ini:

  • menginisialisasi variabel "flag" JS menjadi true, dan mengubahnya menjadi false ketika dalam konteks semua web;

  • oleh karena itu Anda dapat menggunakan panggilan seperti " willIBeInPhoneGapSometimesInTheNearFuture()" (itu PRE-PG, tentu saja Anda masih memerlukan metode POST-PG untuk memeriksa apakah Anda dapat memanggil PG API, tetapi yang itu sepele).

  • Kemudian Anda berkata: " but how do you determine the execution context?"; jawabannya adalah: "Anda tidak" (karena menurut saya Anda tidak dapat diandalkan, kecuali orang-orang brilian di PG akan melakukannya dalam kode API mereka);

  • Anda menulis skrip build yang melakukannya untuk Anda: satu basis kode dengan dua varian.

Al Renaud
sumber
1

Tidak benar - benar jawaban atas pertanyaan tersebut, tetapi ketika saya mengujinya di browser desktop, saya baru saja menetapkan nilai penyimpanan lokal untuk membuat browser memuat aplikasi meskipun perangkat tidak menyala.

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();
    }
});
geon
sumber
1

Tidak ada yang berfungsi, kecuali Anda menghapus file Javascript PhoneGap dari versi desktop aplikasi, yang mengalahkan tujuan saya untuk memiliki satu basis kode.

Pilihan lain adalah menggunakan folder gabungan , lihat gambar di bawah.

Anda dapat menambahkan file khusus platform / mengganti file default.

(itu harus melakukan trik dalam beberapa skenario)

masukkan deskripsi gambar di sini


Dengan kata lain: Daripada mendeteksi browser, Anda hanya tidak menyertakan file tertentu untuk desktop membangun / melampirkan file tertentu untuk iOS saja.

Mars Robertson
sumber
1

Deteksi browser desktop meskipun perangkat emulasi aktif

Bekerja di mesin Windows dan Mac. Perlu menemukan solusi untuk linux Lihat detailnya

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
}
Anulal S
sumber
0

Saya sebenarnya telah menemukan kombinasi dari dua teknik yang tercantum di sini telah bekerja paling baik, pertama periksa apakah cordova / phonegap dapat diakses juga periksa apakah perangkat tersedia. Seperti:

function _initialize() {
    //do stuff
}

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

Coba pendekatan ini:

/**
 * 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);
        }
    });
}
Zorayr
sumber
0

Saya menggunakan kombinasi dari apa yang disarankan oleh GeorgeW dan 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.')
   }
skybondsor
sumber
0

Saya kira dalam beberapa hal mereka tidak begitu berbeda, bukan? Ha Ha ... tidak lucu. Siapa yang tidak mengira ini tidak akan menjadi masalah? Inilah solusi paling sederhana untuk pertimbangan Anda. Dorong file yang berbeda ke server Anda lalu lakukan ke PhoneGap. Saya juga akan menggunakan http: cek yang disarankan di atas untuk sementara.

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

Ketertarikan saya adalah mendorong navbar browser ke atas, jadi saya benar-benar dapat menghapus tag skrip yang terisolasi dan menekan rekondisi [dalam DW] (toh akan tetap ada pembersihan untuk penerapan sehingga ini bisa menjadi salah satu tugas tersebut.) Pokoknya saya rasa ini adalah pilihan yang baik (mengingat tidak banyak lagi yang tersedia) untuk secara efisien mengomentari hal-hal secara manual dengan isMobileBrowserAndNotPhoneGap saat mendorong ke PG). Sekali lagi untuk saya dalam situasi saya, saya hanya akan menghapus tag untuk file (kode terisolasi) yang mendorong bilah navigasi saat itu adalah browser seluler (itu akan jauh lebih cepat dan lebih kecil). [Jadi ya, jika Anda dapat mengisolasi kode untuk solusi manual yang dioptimalkan itu.]

MistereeDevlord
sumber
0

Sedikit dimodifikasi, tetapi berfungsi dengan sempurna untuk saya tanpa masalah apa pun.

Maksudnya adalah memuat Cordova hanya saat di perangkat yang disematkan, bukan di desktop, jadi saya sepenuhnya menghindari cordova di browser desktop. Pengujian dan pengembangan UI dan MVVM dan karenanya sangat nyaman.

Letakkan kode ini misalnya. dalam file 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);
}

Kemudian alih-alih menyertakan javascript cordova itu sendiri, sertakan 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> 

Kemudahan pekerjaan Anda! :)

OSP
sumber
0
if ( "device" in window ) {
    // phonegap
} else {
    // browser
}
Petar Vasilev
sumber
0

Sekadar info caranya di PhoneGap 3.x Mobile Application Development 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();
} );

dan dalam kerangka YASMF

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

Whisher
sumber
0

Saya mencoba dengan objek jendela tetapi tidak berhasil karena saya membuka url jarak jauh di InAppBrowser. Tidak bisa menyelesaikannya. Jadi cara terbaik dan termudah untuk mencapainya adalah dengan menambahkan string ke url yang perlu Anda buka dari aplikasi phonegap. Kemudian periksa apakah lokasi dokumen memiliki string yang ditambahkan padanya.

Di bawah ini adalah kode sederhana untuk itu

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

Anda akan melihat string ditambahkan ke url "#phonegap". Jadi di url domain tambahkan script berikut

if(window.location.indexOf("#phonegap") > -1){
     alert("Url Loaded in the phonegap App");
}
Ashish
sumber