PhoneGap: Phát hiện xem có chạy trên trình duyệt máy tính để bàn không


118

Tôi đang phát triển một ứng dụng web sử dụng PhoneGap: Build cho phiên bản di động và muốn có một codebase duy nhất cho phiên bản 'máy tính để bàn' và thiết bị di động. Tôi muốn có thể phát hiện xem các cuộc gọi PhoneGap có hoạt động hay không (tức là người dùng trên thiết bị di động sẽ hỗ trợ PhoneGap).

Tôi đã tìm kiếm và không thể tin rằng không có cách nào đơn giản để làm điều này. Nhiều người đã đưa ra lời đề nghị;

Không có cái nào hoạt động, trừ khi bạn xóa tệp PhoneGap Javascript khỏi phiên bản máy tính để bàn của ứng dụng, điều này đã đánh bại mục tiêu của tôi là có một cơ sở mã.

Cho đến nay, giải pháp duy nhất mà tôi đưa ra là đánh hơi trình duyệt / tác nhân người dùng, nhưng điều này không mạnh để nói rằng ít nhất. Bất kỳ giải pháp tốt hơn được chào đón!

CHỈNH SỬA: Một giải pháp tốt hơn một chút là thử gọi hàm PhoneGap sau một khoảng thời gian chờ nhỏ - nếu nó không hoạt động, thì hãy giả sử người dùng đang sử dụng trình duyệt web trên máy tính để bàn.


Vì bạn đang sử dụng Bản dựng, hãy xem câu trả lời của @ bt bên dưới: stackoverflow.com/a/18478002/241244 . Có vẻ như nó có thể tốt hơn những câu trả lời được chấp nhận và được bình chọn nhiều nhất.

Tôi tránh phát hiện thời gian chạy ủng hộ cấu hình thời gian xây dựng rõ ràng vì nó hiệu quả 100%. Tôi chỉ cần chuyển một var cục bộ vào mẫu index.jade của mình như {isPhonegap: true}, sau đó trong mẫu, tôi có thể bao gồm tập lệnh phonegap.js có điều kiện và thực hiện tất cả các đơn vị cụ thể của phonegap mà tôi muốn.
Jesse Hattabaugh

Câu trả lời:


115

Tôi sử dụng mã này:

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

CẬP NHẬT

Có nhiều cách khác để phát hiện xem phonegap có đang chạy trên trình duyệt hay không, đây là một tùy chọn tuyệt vời khác:

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

như đã thấy ở đây: Phát hiện giữa trình duyệt di động hoặc ứng dụng PhoneGap


Cảm ơn vì điều này - sau một thời gian dài chờ đợi để xem những gì người khác đã đề xuất, đây có vẻ là giải pháp tốt nhất. Chúc mừng.
aaronsnoswell,

35
Điều này không chính xác, vì nếu tôi mở cùng một trang trên trình duyệt của Thiết bị, onDeviceReady () sẽ không bao giờ gọi. Thêm vào đó, nếu tôi thay đổi UserAgent trong trình duyệt (cho mục đích gỡ lỗi), onDeviceReady () cũng sẽ không bao giờ gọi.
Slavik Meltser

3
Không chắc bạn đang nói gì - nhưng có vẻ như bạn đang ám chỉ điều này sẽ gây ra sự cố khi sử dụng trình duyệt điện thoại ... Đây là một giải pháp để kiểm tra trên trình duyệt máy tính để bàn không phải điện thoại của bạn.
sirmdawg

7
Điều này không hữu ích khi bạn mở ứng dụng trong trình duyệt thiết bị. Giải pháp tốt hơn: kiểm tra window.cordova. Thử nghiệm trong Trình mô phỏng iPhone (trình duyệt) hoặc trên thiết bị Android (trình duyệt) cũng sẽ phát hiện được Bản đồ điện thoại. Đó là cách tôi phát triển. Nhưng có rất nhiều khả năng để hoàn thành công việc. ;-) Thx để đăng giải pháp của bạn!
Mario

Tôi bối rối, còn các nền tảng khác như windows phone thì sao? Họ có userAgent khớp với biểu thức chính quy đó không? Một tìm kiếm google nhanh chóng ngụ ý không: madskristensen.net/post/Windows-Phone-7-user-agents.aspx
mooreds

49

Tôi đã viết một bài về nó một vài ngày trước. Đây là giải pháp tốt nhất mà bạn có thể tìm thấy (cho đến khi PhoneGap sẽ phát hành thứ gì đó, có thể có hoặc có thể không), nó ngắn gọn, đơn giản và hoàn hảo (tôi đã kiểm tra nó theo mọi cách có thể và nền tảng).

Chức năng này sẽ thực hiện công việc cho 98% trường hợp.

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

Để hoàn thành 2% trường hợp còn lại, hãy làm theo các bước sau (nó liên quan đến một chút thay đổi trên mã gốc):

Tạo một tệp có tên __phonegap_index.html , với nguồn:

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

Bây giờ, trên bản địa chỉ cần thay đổi trang bắt đầu từ index.html thành __phonegap_index.html trên tất cả các nền tảng PhoneGap của bạn. Giả sử tên dự án của tôi là ví dụ , các tệp bạn cần thay đổi là (đối với PhoneGap phiên bản 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(dòng 56)
  • Window Phone 7 - Không biết ở đâu (ai đó vẫn đang phát triển trên nền tảng đó ?!)

Cuối cùng, bạn có thể sử dụng nó ở bất kỳ đâu trên trang web của mình, nếu nó đang chạy trên PhoneGap hay không:

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

Hy vọng nó giúp. :-)


4
Tìm thấy câu trả lời này là tốt nhất!
blong824

3
vâng nó hoạt động nhưng một số lần so với phần tiếp theo của mã là không đúng /^file:\/{3}[^\/]/i.test(window.location.href)nhưng chúng tôi đang sử dụng PhoneGap, ví dụ như khi tải index.html từ một trang khác, trên một cái gì đó như thế này config.xml<content src="http://10.100.1.147/" />
vudduu

3
Biểu thức (cordova || PhoneGap || phonegap) sẽ ném ra một ReferenceError nếu bất kỳ biến nào trong số đó không được xác định. Bạn nên thử nghiệm với typeof cordova !== undefined, phải không?
rojobuffalo

1
@rblakeley bạn nói đúng. Tôi đã chuyển dòng đầu tiên thành:return ( typeof cordova !== undefined || typeof PhoneGap !== undefined || typeof phonegap !== undefined )
ethanpil.

1
@rojobuffalo: Có vẻ như câu trả lời đã được sửa đổi, khiến nó hoạt động trở lại như mong đợi ( tức là nó không ném ra ReferenceErrornữa do windowtiền tố). Tôi chỉ nghĩ rằng tôi sẽ chỉ ra điều này, vì điều này thực sự làm cho chuỗi nhận xét lỗi thời (và do đó, không chính xác).
Priidu Neemre

27

Tôi biết nó đã được trả lời một lúc trước nhưng "PhoneGap.available" không tồn tại nữa. Bạn nên sử dụng:

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

hoặc kể từ ngày 1.7, thích:

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

CHỈNH SỬA 2019: như đã nói trong các nhận xét, điều này chỉ hoạt động nếu bạn không bao gồm wireova lib vào bản dựng trình duyệt máy tính để bàn của mình. Và tất nhiên, một thông lệ tốt là chỉ bao gồm các tệp javascript / html / css tối thiểu nghiêm ngặt cho mỗi thiết bị bạn nhắm mục tiêu


18
Điều này không đúng, vì window.PhoneGap hoặc window.cordova sẽ luôn được xác định nếu bạn bao gồm tập lệnh cordova-xxxjs, ngay cả khi nó được tải trên trình duyệt.
Slavik Meltser

Bạn có thể giúp tôi một ví dụ. Để chỉ cần tải index.html. Điều tôi đang làm là tôi đã tải lên tất cả các tệp trong thư mục www trong máy chủ cục bộ của mình, tôi đang tải index.html. Nhưng thiết bị đã sẵn sàng không bị sa thải.
Nassif

5
Đây dường như là câu trả lời chính xác hiện tại (ít nhất là với Cordova 3.4). Tất cả các phương pháp khác chỉ là lãng phí thời gian kể từ khi cordova.js được đưa vào ứng dụng với <script type = "text / javascript" src = "cordova.js"> </script> bây giờ. Bạn không thực sự trỏ đến tệp thực, vì vậy tệp không được tải khi chạy trong trình duyệt. Nó chỉ có trong một bản dựng Cordova chạy trên thiết bị di động.
Michael Oryl

Điều này có vẻ như nó sẽ hoạt động đặc biệt tốt nếu sử dụng PhoneGap Build.

4
@SlavikMe Không bao gồm tập lệnh cordova trong các bản dựng không phải cordova.
Jackson

21

Cách đáng tin cậy nhất mà chúng tôi tìm thấy để biết liệu chúng tôi có đang ở trong ứng dụng cordova / phonegap hay không là sửa đổi tác nhân người dùng của ứng dụng cordova bằng cách sử dụng cấu hình này AppendUserAgent này .

Trong config.xmladd:

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

Sau đó gọi:

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

Tại sao?

  1. window.cordovadocument.addEventListener('deviceready', function(){}); tùy thuộc vào các điều kiện đua
  2. navigator.standalonekhông hoạt động khi <content src="index.html" />là một trang web (Ví dụ: <content src="https://www.example.com/index.html" />hoặc với cordova-plugin-remote-injection )
  3. Việc cố gắng đưa các tác nhân người dùng vào danh sách trắng để đoán xem đó có phải là một trình duyệt thực hay không là rất phức tạp. Các trình duyệt Android thường là các chế độ xem web tùy chỉnh.

2
Và chúng tôi thậm chí có thể thêm phiên bản ứng dụng vào đó! (lý tưởng nhất là với một số logic va chạm phiên bản tự động) ex; Cordova AppName/v0.0.1<3 Vì vậy, theo cách này, bạn thậm chí có thể bằng cách nào đó sử dụng này để theo dõi (nhưng lưu ý rằng bất cứ ai có thể sửa đổi useragent của nó do đó, không dựa vào điều này đối với an ninh xác minh quan trọng)
GabLeRoux

Đây có vẻ là phương pháp dễ đánh lừa nhất. Người về nhì dường như đang kiểm tra sự vắng mặt của http: // hoặc https: // trong URL tài liệu, nhưng tôi có thể hình dung ra các trường hợp có thể xảy ra mà điều đó sẽ không hoạt động.
JD Smith

14

Tôi nghĩ điều này là đơn giản nhất: var isPhoneGap = (location.protocol == "file:")

CHỈNH SỬA Đối với một số người không hoạt động. Sau đó, bạn có thể thử (chưa thử nghiệm)

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

1
Tôi nghĩ rằng PhoneGap đã chạy một máy chủ nội bộ cho tất cả các tệp trên thiết bị của nó?
aaronsnoswell

Tôi thích nó. Khi phát triển trên localhost, đây là giải pháp tốt nhất. (Sau khi cố gắng rất nhiều, tôi hy vọng điều này sẽ hiệu quả trong mọi tình huống.) Thx!
Mario

1
điều này không làm việc trong giả lập gợn khi tôi đang thử nghiệm một tập tin từ xa
Jesse Hattabaugh

Cũng không hoạt động trong WP8, giao thức là "x-wmapp0:". Không thể biết chắc chắn những "giao thức" khác sẽ được sử dụng trong tương lai.
Adrian,

Chà, bạn cũng có thểvar isPhoneGap = ! /^http/.test(document.location.protocol)
Yuval,

8

Điều này phù hợp với tôi (chạy 1.7.0)

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

Đã thử nghiệm trên Chrome và Safari dành cho máy tính để bàn.


3
Điều này gần giống như ràng buộc với sự kiện 'deviceready'. Nếu window.device không được xác định, bạn không thể biết liệu phonegap / cordova tải chậm hay sự kiện sẽ không bao giờ xảy ra.
Wytze

8
window.device không được xác định trước khi sự kiện "deviceready" được kích hoạt.
Slavik Meltser

2
Và cầu nguyện rằng không có lập trình viên nào khác có ý tưởng vui vẻ khi định nghĩa một var toàn cầu mới có tên là "thiết bị".
Mister Smith

7

Giống như người đăng ban đầu, tôi đang sử dụng dịch vụ tạo bản đồ điện thoại. Sau hai ngày và gần 50 lần xây dựng thử nghiệm, tôi đã đưa ra một giải pháp thanh lịch phù hợp với tôi.

Tôi không thể sử dụng tính năng dò tìm UA vì tôi muốn thử nghiệm và chạy trong trình duyệt trên thiết bị di động. Ban đầu tôi đã định hướng về kỹ thuật khá chức năng của cobberboy. Điều này không hiệu quả với tôi vì độ trễ / thời gian chờ "howPworthyAreWe: 10000" gây quá nhiều phiền toái cho việc phát triển trong trình duyệt. Và việc đặt nó thấp hơn bất kỳ lúc nào sẽ không thành công trong thử nghiệm ở chế độ ứng dụng / thiết bị. Phải có một cách khác ...

Dịch vụ xây dựng bản đồ điện thoại yêu cầu phonegap.jstệp được bỏ qua khỏi kho mã của bạn trước khi gửi tệp ứng dụng của bạn tới dịch vụ. Do đó, tôi có thể kiểm tra sự tồn tại của nó để xác định xem đang chạy trong ứng dụng trình duyệt hay ứng dụng.

Một lưu ý khác, tôi cũng đang sử dụng jQueryMobile, vì vậy cả jQM và phonegap đều phải khởi chạy trước khi tôi có thể bắt đầu bất kỳ tập lệnh tùy chỉnh nào. Đoạn mã sau được đặt ở đầu tệp index.js tùy chỉnh của tôi cho ứng dụng (sau jQuery, trước jQM). Ngoài ra, các tài liệu xây dựng bản đồ điện thoại cũng nói để đặt <script src="phonegap.js"></script>ở đâu đó trong HTML. Tôi bỏ nó ra ngoài hoàn toàn và tải nó bằng cách sử dụng $ .getScript () để kiểm tra sự tồn tại của nó.

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

Thật thú vị, nhiều câu trả lời, nhưng chúng không bao gồm ba tùy chọn sau:

1 - cordova.js sẽ đặt đối tượng cordova trong phạm vi toàn cầu. Nếu nó ở đó thì rất có thể bạn đang chạy trong phạm vi Cordova.

var isCordovaApp = !!window.cordova;

2 - Cordova sẽ chạy ứng dụng của bạn như khi bạn mở tài liệu HTML từ Máy tính để bàn. Thay vì giao thức HTTP, nó sẽ sử dụng FILE. Việc phát hiện điều này sẽ cho bạn cơ hội giả định rằng ứng dụng của bạn đã được tải cục bộ.

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

3 - Sử dụng sự kiện tải của tập lệnh cordova để phát hiện ngữ cảnh. Tập lệnh bao gồm có thể dễ dàng bị xóa trong quá trình xây dựng hoặc quá trình tải tập lệnh sẽ không thành công trong trình duyệt. Vì vậy, biến toàn cục này sẽ không được đặt.

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

Tín dụng được chuyển đến Damien Antipa từ Adobe


5

Tôi sử dụng phương pháp này:

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

debugsẽ có truetrên môi trường trình duyệt, falsetrên thiết bị.



3

Bản chất của vấn đề là miễn là cordova.device chưa được xác định, mã của bạn không thể chắc chắn liệu đó có phải là do cordova đã thiết lập rằng thiết bị của bạn không được hỗ trợ hay không, hay là do cordova vẫn đang tự chuẩn bị và thiết bị sẽ hoạt động sau đó (hoặc tùy chọn thứ ba: cordova không tải đúng cách).

Giải pháp duy nhất là xác định khoảng thời gian chờ và quyết định rằng sau khoảng thời gian này, mã của bạn phải giả định rằng thiết bị không được hỗ trợ. Tôi ước cordova sẽ đặt một thông số ở đâu đó để nói rằng "Chúng tôi đã thử tìm một thiết bị được hỗ trợ và từ bỏ" nhưng có vẻ như không có thông số như vậy.

Khi điều này được thiết lập, bạn có thể muốn thực hiện một việc cụ thể chính xác trong những trường hợp không có thiết bị được hỗ trợ. Giống như ẩn các liên kết đến chợ ứng dụng của thiết bị, trong trường hợp của tôi.

Tôi đã kết hợp chức năng này với nhau để bao gồm khá nhiều tình huống. Nó cho phép bạn xác định một trình xử lý thiết bị đã sẵn sàng, một trình xử lý thiết bị không bao giờ sẵn sàng và thời gian chờ.

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

Cách tôi đang làm là sử dụng biến toàn cục được ghi đè bởi phiên bản cordova.js chỉ dành cho trình duyệt. Trong tệp html chính của bạn (thường là index.html), tôi có các tập lệnh sau phụ thuộc vào thứ tự:

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

Và bên trong cordova.jstôi chỉ có:

__cordovaRunningOnBrowser__ = true

Khi xây dựng cho thiết bị di động, cordova.js sẽ không được sử dụng (và thay vào đó, tệp cordova.js dành riêng cho nền tảng sẽ được sử dụng), vì vậy phương pháp này có lợi ích là đúng 100% bất kể giao thức, userAgents hay thư viện các biến (có thể thay đổi). Có thể có những thứ khác tôi nên đưa vào cordova.js, nhưng tôi chưa biết chúng là gì.


Cách tiếp cận rất thú vị.

Tuy nhiên, bạn không thực sự cần script ban đầu. Bạn chỉ có thể kiểm tra xem nó có được thiết lập không: if ( typeof __cordovaRunningOnBrowser__ !== 'undefined' ) { stuff(); } ..right?

Đúng vậy, vì nó không được xác định có thể chỉ ra điều gì đó không ổn.
BT

3

Một cách khác, dựa trên giải pháp của SlavikMe:

Chỉ cần sử dụng một tham số truy vấn được chuyển đến index.htmltừ nguồn PhoneGap của bạn. Tức là trong Android, thay vì

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

sử dụng

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

SlavikMe có một danh sách tuyệt vời về nơi để thực hiện việc này trên các nền tảng khác.

Sau đó, bạn index.htmlcó thể chỉ cần làm điều này:

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

1
Tôi đang sử dụng Cordova 3.4.1 và nó thậm chí còn đơn giản hơn: Bạn chỉ cần thay đổi <content src="index.html" />tùy chọn trong tệp config.xml thành <content src="index.html?cordova=1" />. Cho đến nay nó dường như hoạt động và cho đến nay là giải pháp tốt nhất được đề xuất ở đây.
Martin M.

2

Để giữ một cơ sở mã, điều quan tâm là "nền tảng" mà mã đang chạy. Đối với tôi "nền tảng" này có thể là ba thứ khác nhau:

  • 0: máy tính-trình duyệt
  • 1: trình duyệt di động
  • 2: phonegap / cordova

Cách để kiểm tra nền tảng:

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

Ghi chú:

  • Điều này chỉ được chạy sau khi đã tải xong cordova.js (body onload (...), $ (document) .ready (...))

  • 'ontouchstart' trong document.documentElement sẽ hiện diện trong máy tính xách tay và màn hình máy tính để bàn có màn hình hỗ trợ cảm ứng, do đó nó sẽ báo cáo trình duyệt di động mặc dù đó là máy tính để bàn. Có nhiều cách khác nhau để kiểm tra chính xác hơn nhưng tôi sử dụng nó vì nó vẫn xử lý 99% các trường hợp tôi cần. Bạn luôn có thể thay thế dòng đó bằng một thứ gì đó mạnh mẽ hơn.


1
Tôi đề nghị sử dụng typeof cordova !== 'undefined'thay vì câu cá cho một ngoại lệ.
krakatoa

1

Aarons, hãy thử

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

Không tôi không làm. Nhìn vào mã nguồn phonegap-1.1.0.js. PhoneGap.available = DeviceInfo.uuid! == không xác định;
GeorgeW

1

Giải pháp của GeorgeW là OK, nhưng ngay cả trên thiết bị thực, PhoneGap.available chỉ đúng sau khi những thứ của PhoneGap đã được tải, ví dụ: onDeviceReady trong document.addEventListener ('deviceready', onDeviceReady, false) đã được gọi.

Trước thời điểm đó, nếu bạn muốn biết, bạn có thể làm như sau:

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

Giải pháp này giả định rằng hầu hết các nhà phát triển đều sử dụng Chrome hoặc Firefox.


OP đang tìm kiếm giải pháp cho một trang web sản xuất, không chỉ dành cho nhà phát triển.
Jesse Hattabaugh

1

Tôi có cùng một vấn đề.

Tôi đang hướng tới việc thêm # cordova = true vào URL được tải bởi ứng dụng khách cordova và kiểm tra location.hash.indexOf ("cordova = true")> -1 trong trang web của tôi.


Cuối cùng, tôi đã đi theo lộ trình do Al Renaud gợi ý ở điểm thứ 4 của anh ấy, và để kịch bản xây dựng quyết định. Nó bỏ ghi chú một cờ trong index.html khi sao chép mã trang web vào thư mục nội dung android. // UNCOMMENT-ON-DEPLOY: window._appInfo.isCordova = true; Khi tập lệnh xây dựng sao chép index.html vào thư mục tài sản android / www của tôi, tôi chạy chỉnh sửa trên đó để xóa chuỗi // UNCOMMENT-ON-DEPLOY:. # Massage index.html cho biết nó đang chạy cordova ed "$ DEST / index.html" << - EOF 1, \ $ s / \ / \ / UNCOMMENT-ON-DEPLOY: // wq EOF
Austin France

1

Phần sau phù hợp với tôi với PhoneGap / Cordova (2.1.0) mới nhất.

Làm thế nào nó hoạt động:

  • Rất đơn giản trong khái niệm
  • Tôi đã đảo ngược logic của một số giải pháp hết thời gian ở trên.
  • Đăng ký sự kiện device_ready (theo khuyến nghị của tài liệu PhoneGap )
    • Nếu sự kiện vẫn KHÔNG kích hoạt sau khi hết thời gian chờ, hãy dự phòng để giả định có trình duyệt.
    • Ngược lại, các giải pháp khác ở trên dựa vào việc thử nghiệm một số tính năng PhoneGap hoặc tính năng khác và xem thử nghiệm của chúng có bị phá vỡ hay không.

Ưu điểm:

  • Sử dụng sự kiện device_ready do PhoneGap đề xuất.
  • Ứng dụng di động không có độ trễ. Ngay sau khi sự kiện device_ready kích hoạt, chúng tôi sẽ tiếp tục.
  • Không có tác nhân người dùng (Tôi thích thử nghiệm ứng dụng của mình như một trang web dành cho thiết bị di động nên tính năng dò tìm trình duyệt không phải là một lựa chọn cho tôi).
  • Không phụ thuộc vào các tính năng / thuộc tính của PhoneGap không có tài liệu (và do đó dễ vỡ).
  • Giữ cordova.js trong codebase của bạn ngay cả khi sử dụng trình duyệt trên máy tính để bàn hoặc thiết bị di động. Do đó, điều này trả lời câu hỏi của OP.
  • Wytze đã nói ở trên: 'Tôi ước cordova sẽ đặt một thông số ở đâu đó để nói rằng "Chúng tôi đã thử tìm một thiết bị được hỗ trợ và từ bỏ" nhưng có vẻ như không có thông số nào như vậy.' Vì vậy, tôi cung cấp một ở đây.

Nhược điểm:

  • Hết giờ thật là khó. Nhưng logic ứng dụng dành cho thiết bị di động của chúng tôi không dựa trên độ trễ; đúng hơn, nó được sử dụng như một dự phòng khi chúng ta đang ở chế độ trình duyệt web.

==

Tạo một dự án PhoneGap trống hoàn toàn mới. Trong index.js mẫu đã cung cấp, hãy thay thế biến "ứng dụng" ở dưới cùng bằng biến này:

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

Tôi đã vấp phải sự cố này vài tháng trước khi bắt đầu ứng dụng của mình, bởi vì chúng tôi muốn ứng dụng trở thành "browser-compatible cũng "" (hiểu rằng một số chức năng sẽ bị chặn trong trường hợp đó: ghi âm, la bàn, v.v.).

Giải pháp duy nhất 100%(và tôi nhấn mạnh vào điều kiện 100 trăm phần trăm) để xác định TRƯỚC bối cảnh thực thi ứng dụng là:

  • khởi tạo biến "cờ" JS thành true và thay đổi nó thành false khi ở trong ngữ cảnh toàn web;

  • do đó bạn có thể sử dụng một lệnh gọi như " willIBeInPhoneGapSometimesInTheNearFuture()" (đó là PRE-PG, tất nhiên bạn vẫn cần một phương pháp POST-PG để kiểm tra xem bạn có thể gọi PG API hay không, nhưng phương thức đó là nhỏ).

  • Sau đó bạn nói: " but how do you determine the execution context?"; câu trả lời là: "you don`t" (bởi vì tôi không nghĩ rằng bạn có thể tin cậy được, trừ khi những người giỏi ở PG sẽ làm điều đó trong mã API của họ);

  • bạn viết một tập lệnh xây dựng thực hiện điều đó cho bạn: một cơ sở mã với hai biến thể.


1

Không thực sự là câu trả lời cho câu hỏi, nhưng khi tôi kiểm tra trong trình duyệt trên máy tính để bàn, tôi chỉ đặt giá trị lưu trữ cục bộ để làm cho trình duyệt tải ứng dụng mà thiết bị không kích hoạt.

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

Không có cái nào hoạt động, trừ khi bạn xóa tệp PhoneGap Javascript khỏi phiên bản máy tính để bàn của ứng dụng, điều này đã đánh bại mục tiêu của tôi là có một cơ sở mã.

Một tùy chọn khác sẽ là sử dụng hợp nhất thư mục , xem ảnh chụp màn hình bên dưới.

Bạn có thể thêm các tệp dành riêng cho nền tảng / ghi đè các tệp mặc định.

(nó sẽ thực hiện thủ thuật trong một số trường hợp)

nhập mô tả hình ảnh ở đây


Nói cách khác: Thay vì phát hiện trình duyệt, bạn chỉ không đưa vào một số tệp nhất định để tạo / đính kèm các tệp nhất định chỉ dành cho iOS.


1

Phát hiện trình duyệt máy tính để bàn ngay cả khi thiết bị giả lập đang hoạt động

Hoạt động trên máy tính Windows và Mac. Cần tìm giải pháp cho linux Xem chi tiết

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

Tôi thực sự thấy rằng sự kết hợp của hai trong số các kỹ thuật được liệt kê ở đây đã hoạt động tốt nhất, trước tiên hãy kiểm tra xem có thể truy cập vào wireova / phonegap hay không, đồng thời kiểm tra xem thiết bị có khả dụng không. Như vậy:

function _initialize() {
    //do stuff
}

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

0

Hãy thử cách tiếp cận này:

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

Tôi sử dụng kết hợp những gì GeorgeWmkprogramming đã đề xuất:

   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

Tôi đoán bằng cách nào đó chúng không khác nhau như vậy phải không? Ha Ha ... không vui đâu. Ai đã không nghĩ rằng điều này sẽ không có vấn đề? Đây là giải pháp đơn giản nhất để bạn cân nhắc. Đẩy các tệp khác nhau đến máy chủ của bạn sau đó bạn thực hiện với PhoneGap. Tôi cũng tạm thời sử dụng http: séc được đề xuất ở trên.

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

Mối quan tâm của tôi là đẩy thanh điều hướng của trình duyệt lên, vì vậy thực sự tôi có thể xóa thẻ của tập lệnh bị cô lập và nhấn xây dựng lại [trong DW] (dù sao thì chúng cũng sẽ được dọn dẹp để triển khai nên đây có thể là một trong những nhiệm vụ đó.) Dù sao thì tôi cảm thấy đó là một lựa chọn tốt (xem xét không có sẵn nhiều thứ khác) để chỉ nhận xét mọi thứ theo cách thủ công với isMobileBrowserAndNotPhoneGap khi đẩy sang PG). Một lần nữa đối với tôi trong tình huống của tôi, tôi sẽ đơn giản xóa thẻ cho tệp (mã riêng biệt) đẩy thanh điều hướng lên khi đó là trình duyệt dành cho thiết bị di động (nó sẽ nhanh hơn và nhỏ hơn nhiều). [Vì vậy, nếu bạn có thể tách mã cho giải pháp thủ công nhưng được tối ưu hóa đó.]


0

Một chút sửa đổi, nhưng hoạt động cho tôi một cách hoàn hảo mà không có bất kỳ vấn đề nào.

Mục đích là chỉ tải Cordova khi trên thiết bị nhúng, không phải trên máy tính để bàn, vì vậy tôi hoàn toàn tránh sử dụng Cordova trên trình duyệt máy tính để bàn. Việc thử nghiệm và phát triển giao diện người dùng và MVVM, sau đó rất thoải mái.

Đặt mã này, ví dụ. trong tệp 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);
}

Sau đó, thay vì bao gồm bản thân javascript của cordova, hãy bao gồm 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> 

Dễ dàng làm việc của bạn! :)



0

Chỉ để biết thông tin theo cách trong PhoneGap 3.x Hotshot Phát triển Ứng dụng Di động

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

và trong khuôn khổ YASMF

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


0

Tôi đã thử với các đối tượng cửa sổ nhưng nó không hoạt động khi tôi đang mở url từ xa trong InAppBrowser. Không thể hoàn thành. Vì vậy, cách tốt nhất và dễ nhất để đạt được điều đó là thêm một chuỗi vào url mà bạn cần mở từ ứng dụng phonegap. Sau đó, kiểm tra xem vị trí tài liệu có chuỗi được nối với nó hay không.

Dưới đây là mã đơn giản cho nó

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

Bạn sẽ thấy một chuỗi được thêm vào url "#phonegap". Vì vậy, trong url tên miền, hãy thêm tập lệnh sau

if(window.location.indexOf("#phonegap") > -1){
     alert("Url Loaded in the phonegap App");
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.