ユーザーがJavaScriptを使用してブラウザーまたはアプリケーションからアクセスしているかどうかを検出することは可能ですか?
WebページとPhoneGapアプリケーションを介して複数のモバイルOSへのハイブリッドアプリケーションを開発しています。目標は次のとおりです。
- デプロイメントターゲットとは関係なく同じコードを使用する
- ユーザーエージェントがアプリケーションの場合にのみPhoneGap.jsファイルを追加します
ユーザーがJavaScriptを使用してブラウザーまたはアプリケーションからアクセスしているかどうかを検出することは可能ですか?
WebページとPhoneGapアプリケーションを介して複数のモバイルOSへのハイブリッドアプリケーションを開発しています。目標は次のとおりです。
現在のURLにhttp
プロトコルが含まれているかどうかを確認できます。
var app = document.URL.indexOf( 'http://' ) === -1 && document.URL.indexOf( 'https://' ) === -1;
if ( app ) {
// PhoneGap application
} else {
// Web page
}
すぐに頭に浮かぶ解決策は、
onDeviceReady
あなたを助けます。このJS呼び出しはネイティブブリッジ(objCまたはJava)によってのみ呼び出されるため、Safariモバイルブラウザーはこれを検出できません。したがって、デバイス上のアプリ(電話ギャップ)のソースベースはから開始されonDeviceReady
ます。
また、Device.platformやDevice.nameなどのPhonegapのJS呼び出しのいずれかがNaNまたはnullの場合、明らかにモバイルWeb呼び出しです。
確認して結果を教えてください。
私はこれを行う方法を考え出し、デバイスレディイベントに依存せず、Webコードベースをそのまま維持します...
組み込みの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();
});
}
PhoneGapにはwindow.PhoneGap(またはCordovaではwindow.cordovaまたはwindow.Cordova)オブジェクトが設定されています。そのオブジェクトが存在するかどうかを確認し、魔法を実行します。
phonegapアプリのURLがロードされるネイティブコール内で、値phonegapを使用してパラメーターターゲットを追加します。したがって、Androidの呼び出しは次のようになります。
super.loadUrl("file:///android_asset/www/index.html?target=phonegap");
このコードを使用しているWebサイトは追加のパラメーターを使用して呼び出されないため、2つのデプロイプラットフォーム間で何かが異なります。var urlVars = window.location.href.split('?'); if(urlVars.length> 1 && urlVars [1] .search('target = phonegap')!= -1){ //phonegapが通話に使用されました $('head')。append('<script src = "cordova.js"> </ script>'); }小さな注意点:このメソッドでは、対象となるさまざまなモバイルプラットフォームごとにphonegapのindex.htmlへの呼び出しを変更する必要があります。私はほとんどのプラットフォームでこれをどこで行うのかよくわかりません。
phonegapアプリとWebクライアントの両方に同じコードを使用しています。phonegapが利用可能かどうかを検出するために使用するコードは次のとおりです。
window.phonegap = false;
$.getScript("cordova-1.7.0.js", function(){
window.phonegap = true;
});
phonegapjsファイルは非同期でロードされることに注意してください。気の利いたjquery$.getScript関数の正しいオプションを設定することで、同期的にロードできます。
このアプローチでは、Webクライアントでもphonegapjsファイルを取得するための追加のGETリクエストが作成されることに注意してください。私の場合、Webクライアントのパフォーマンスには影響しませんでした。だから、これを行うための素晴らしい/クリーンな方法になりました。少なくとも誰かが簡単な1行の解決策を見つけるまでは:)
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の場合はphonegapjsを含めます。
ユーザーエージェントを使用して違いを検出する方法はありません。
私がそれをしている方法は、ブラウザのみのバージョンの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に含めるべき他のものがあるかもしれませんが、それらがまだ何であるかはわかりません。
私もこれに苦労していて、これが古いスレッドであることは知っていますが、私のアプローチはどこにも見たことがないので、誰かを助ける場合に備えてidshareを考えました。
私は実際のユーザーエージェントの後にカスタムユーザーエージェントを設定しました:
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");
}
次のようにしようとするとどうなりますか:
if(window._cordovaNative) {
alert("loading cordova");
requirejs(["...path/to/cordova.js"], function () {
alert("Finished loading cordova");
});
}
私の考えでは、あなたは自分自身のために問題を作ろうとします。開発プラットフォームについては言及していませんが、それらのほとんどは異なるデプロイメント構成を持っています。2つの構成を定義できます。そして、コードがどのようにデプロイされたかを示す変数を設定します。この場合、アプリをデプロイしたデバイスを気にする必要はありません。
短くて効果的:
if (document.location.protocol == 'file:') { //Phonegap is present }
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()
}
新しいソリューション:
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は現在ブラウザをプラットフォームとして追加することをサポートしているようです。
cordova platforms add browser
これにより、実行時にcordova.jsが自動的に追加され、onDeviceReady
イベントが特徴となるため、偽造する必要はありません。また、多くのプラグインはブラウザをサポートしているため、コードでブラウザをハッキングする必要はありません。
ブラウザでアプリを使用するには、を使用する必要がありますcordova run browser
。デプロイする場合は、他のプラットフォームと同じコマンドを使用してデプロイできます。
編集:私のソースに言及するのを忘れました。
解決策:Cordovaでindex.htmlにパッチを適用し、タグに追加cordova-platform="android"
して<html>
、cordova-platform属性がCordovaビルドにのみ存在し、Cordova外のWebに使用される元のindex.htmlから欠落するようにします。
長所:ユーザーエージェント、URLスキーマ、またはcordovaAPIに依存しません。devicereadyイベントを待つ必要はありません。Cordovaの外部のWebアプリとCordovaのブラウザープラットフォームビルドを区別するために、さまざまな方法で拡張できます。たとえば、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
}