web-dev-qa-db-ja.com

モバイルブラウザーまたはPhoneGapアプリケーション間の検出

ユーザーがJavaScriptを使用してブラウザまたはアプリケーションからアクセスしているかどうかを検出することは可能ですか?

私は、WebページとPhoneGapアプリケーションを介して複数のモバイルOSへのハイブリッドアプリケーションを開発していますが、目標は次のとおりです。

  1. 展開ターゲットに関係なく同じコードを使用する
  2. ユーザーエージェントがアプリケーションの場合のみ、PhoneGap.jsファイルを追加します
61
Diogo Cardoso

現在のURLにhttpプロトコルが含まれているかどうかを確認できます。

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

頭に浮かぶ解決策は、

onDeviceReady

あなたを助けるでしょう。このJS呼び出しはネイティブブリッジ(objCまたはJava)によってのみ呼び出されるため、safariモバイルブラウザーはこれを検出できません。したがって、デバイス上のアプリ(電話ギャップ)のソースベースはonDeviceReadyから開始されます。

また、Device.platformやDevice.nameのようなPhonegapのJS呼び出しのいずれかがNaNまたはnullの場合、明らかにモバイルWeb呼び出しです。

結果を確認してお知らせください。

15
Futur

私はこれを行う方法を考え出し、devicereadyイベントに依存せず、ウェブコードベースをそのまま維持しました...

組み込みのdevicereadyイベントを使用する際の現在の問題は、ページが読み込まれたときに、アプリに伝える方法がないことです。「これはモバイルデバイスで実行されていないので、始めること"。

1.-たとえばiOSのMainViewController.mのコードのネイティブ部分には、viewDidLoadメソッドがあり、後でWebコードで確認するjavascript変数を送信しています。その変数が存在する場合は待機しますすべての準備が整うまで(たとえば、ナビゲーターの位置情報)ページのコードを開始する

MainViewController.mの下:

- (void) viewDidLoad
{
    [super viewDidLoad];
    NSString* jsString = [NSString stringWithFormat:@"isAppNative = true;"];
    [self.webView stringByEvaluatingJavaScriptFromString:jsString];
}

2.- index.htmlコードは次のようになります。

function onBodyLoad()
{
    document.addEventListener("deviceready", onDeviceReady, false);
}

function onDeviceReady(){;
    myApp.run();
}

try{
    if(isAppNative!=undefined);
}catch(err){
    $(document).ready(function(){
        myApp.run();
    });
}
11

PhoneGapにはwindow.PhoneGap(またはCordovaでは、window.cordovaまたはwindow.Cordova)オブジェクトが設定されています。そのオブジェクトが存在するかどうかを確認し、魔法をかけます。

7
zvona

PhonegapアプリとWebクライアントの両方に同じコードを使用しています。 phonegapが使用可能かどうかを検出するために使用するコードは次のとおりです。

window.phonegap = false;
$.getScript("cordova-1.7.0.js", function(){
    window.phonegap = true;
});

Phonegap jsファイルは非同期でロードされることに注意してください。気の利いたjquery $ .getScript関数の正しいオプションを設定することで、同期的にロードできます。

このアプローチでは、Webクライアントでもphonegap jsファイルを取得するための追加のGETリクエストが行われることに注意してください。私の場合、ウェブクライアントのパフォーマンスには影響しませんでした。少なくとも他の誰かが簡単な1行の解決策を見つけるまではそうです:)

4
Aki

PhonegapアプリでWebビューが開始されたら、別のWebページを読み込んでいるようですが、正しいですか?その場合は、構成に基づいてリクエストURLにパラメーターを追加できます。

たとえば、PHPを想定して、

App.Config = {
  target: "phonegap"
};

<body onload="onbodyload()">

var onbodyload = function () {
  var target = App.Config.target;
  document.location = "/home?target=" + target;
};

次に、サーバー側で、ターゲットがphonegapの場合、phonegap jsを含めます。

ユーザーエージェントを使用して違いを検出する方法はありません。

4
sciritai

私もこれに苦労していて、これが古いスレッドであることを知っていますが、どこからでも私のアプローチを見たことがないので、id shareは誰かを助けると思います。

実際のuseragentの後にカスタムuseragentを設定します:

String useragent = settings.getUserAgentString();
settings.setUserAgentString(useragent + ";phonegap");

phonegap文字列を追加するだけで、モバイルユーザーエージェントの検出に依存している他のサイトは引き続き機能します。

次に、次のようにしてphonegapをロードできます。

if( /phonegap/i.test(navigator.userAgent) ) 
{
//you are on a phonegap app, $getScript etc
} else {
alert("not phonegap");
}
4
Havihavi

あなたがフォローしようとするとどうなりますか:

if(window._cordovaNative) {
  alert("loading cordova");
  requirejs(["...path/to/cordova.js"], function () { 
         alert("Finished loading cordova");
  });
}
4
user3415370

私がそれをやっている方法は、ブラウザ専用バージョンのcordova.jsによって上書きされるグローバル変数を使用することです。メインhtmlファイル(通常はindex.html)順序に依存する次のスクリプトがあります。

    <script>
        var __cordovaRunningOnBrowser__ = false
    </script>
    <script src="cordova.js"></script> <!-- must be included after __cordovaRunningOnBrowser__ is initialized -->
    <script src="index.js"></script> <!-- must be included after cordova.js so that __cordovaRunningOnBrowser__ is set correctly -->

そしてcordova.js私は単純に:

__cordovaRunningOnBrowser__ = true

モバイルデバイス用にビルドする場合、cordova.jsは使用されず(代わりにプラットフォーム固有のcordova.jsファイルが使用されます)、この方法には、プロトコル、userAgent、またはライブラリに関係なく100%正しいという利点があります変数(変更される場合があります)。 cordova.jsに含める必要のあるものは他にもあるかもしれませんが、それらが何であるかはまだわかりません。

4
B T

私の考えでは、あなたは自分のために問題を作ろうとします。開発プラットフォームについては言及しませんでしたが、それらのほとんどには異なるデプロイメント構成があります。 2つの構成を定義できます。そして、コードがデプロイされた方法を示す変数を設定します。この場合、アプリを展開したデバイスを気にする必要はありません。

1
RredCat

B Tの解 に似ていますが、より簡単です:

wwwフォルダーに空のcordova.jsがあり、ビルド時にCordovaによって上書きされます。アプリのスクリプトファイルの前にcordova.jsを含めることを忘れないでください(順序が間違っていることを知るのに1時間かかりました)。

その後、Cordovaオブジェクトを確認できます。

document.addEventListener('DOMContentLoaded', function(){
    if (window.Cordova) {
        document.addEventListener('DeviceReady', bootstrap);
    } else {
        bootstrap();
    }
});

function bootstrap() {
   do_something()
}
1
user5924996

短くて効果的:

if (document.location.protocol == 'file:') { //Phonegap is present }
1
AmpT

新しいソリューション:

var isPhoneGapWebView = location.href.match(/^file:/); // returns true for PhoneGap app

古いソリューション:
JQueryを使用して、このように実行します

$(document).ready(function(){
   alert(window.innerHeight);
});

モバイルアプリケーションの例としてiPhoneを取り上げ、

PhoneGapまたはCordovaを使用すると、460pxのWebViewを取得できますが、サファリでは、ブラウザーのデフォルトのヘッダーとフッターのために高さがいくらか失われます。

Window.innerHeightが460に等しい場合、phonegap.jsをロードし、onDeviceReady関数を呼び出すことができます

解決策:Cordovaのindex.htmlにパッチを適用し、cordova-platform="Android"から<html>タグ。これにより、cordova-platform属性はCordovaビルドにのみ存在し、Cordovaの外部のWebに使用される元のindex.htmlから欠落します。

長所:ユーザーエージェント、URLスキーマ、またはCordova APIに依存しません。 devicereadyイベントを待つ必要はありません。 CordovaのブラウザープラットフォームビルドとCordovaの外部のWebアプリを区別するために、さまざまな方法で拡張できます。たとえば、cordova-platform = "browser"を含めるかどうかは異なります。

Config.xmlとのマージ

    <platform name="Android">
        <hook src="scripts/patch-Android-index.js" type="after_prepare" />
    </platform>

ファイルscripts/patch-Android-index.jsを追加します

module.exports = function(ctx) {
    var fs = ctx.requireCordovaModule('fs');
    var path = ctx.requireCordovaModule('path');

    var platformRoot = path.join(ctx.opts.projectRoot, 'platforms/Android');
    var indexPath = platformRoot + '/app/src/main/assets/www/index.html';

    var indexSource = fs.readFileSync(indexPath, 'utf-8');

    indexSource = indexSource.replace('<html', '<html cordova-platform="Android"');

    fs.writeFileSync(indexPath, indexSource, 'utf-8');
}

注:Android以外の場合、パスplatforms/Androidおよび/app/src/main/assets/www/index.htmlを調整する必要があります。

アプリは次の方法でcordova-platformを確認できます

if (! document.documentElement.getAttribute('cordova-platform')) {
  // Not in Cordova
}

または

if (document.documentElement.getAttribute('cordova-platform') === 'Android') {
  // Cordova, Android
}
0
Ventzy Kunev

これについてはまだ誰も言及していませんが、Cordovaは現在、ブラウザをプラットフォームとして追加することをサポートしているようです:

cordova platforms add browser

これにより、onDeviceReadyイベントを備えた実行時にcordova.jsが自動的に追加されるので、偽造する必要はありません。また、多くのプラグインはブラウザをサポートしているため、コード内でブラウザがハッキングすることはありません。

ブラウザでアプリを使用するには、cordova run browser。デプロイする場合は、他のプラットフォームと同じコマンドを使用してデプロイできます。

編集: 私のソース を言及するのを忘れた.

0
Ricardo Cruz