UFO ET IT

모바일 브라우저 또는 PhoneGap 애플리케이션 간 감지

ufoet 2020. 11. 30. 20:24
반응형

모바일 브라우저 또는 PhoneGap 애플리케이션 간 감지


사용자가 JavaScript를 사용하여 브라우저 또는 응용 프로그램을 통해 액세스하고 있는지 감지 할 수 있습니까?

웹 페이지와 PhoneGap 애플리케이션을 통해 여러 모바일 OS에 하이브리드 애플리케이션을 개발 중이며 목표는 다음과 같습니다.

  1. 배포 대상과 독립적으로 동일한 코드 사용
  2. 사용자 에이전트가 애플리케이션 인 경우에만 PhoneGap.js 파일 추가

현재 URL에 http프로토콜이 포함되어 있는지 확인할 수 있습니다 .

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

떠오르는 빠른 해결책은

onDeviceReady

당신을 도울 것입니다. 이 JS 호출은 Native 브리지 (objC 또는 Java)에 의해서만 호출되므로 safari 모바일 브라우저는이를 감지하지 못합니다. 따라서 장치 앱 (전화 간격) 소스 기반은 onDeviceReady.

그리고 Device.platform 또는 Device.name과 같은 Phonegap의 JS 호출이 NaN 또는 null이면 분명히 모바일 웹 호출입니다.

결과를 확인하고 알려주세요.


이 작업을 수행하고 deviceready 이벤트에 의존하지 않고 웹 코드베이스를 그대로 유지하는 방법을 알아 냈습니다.

내장 된 deviceready 이벤트를 사용할 때의 현재 문제는 페이지가로드 될 때 앱에 다음과 같이 알릴 방법이 없다는 것입니다. "이건 휴대 기기에서 실행되지 않습니다. 기기가 준비 될 때까지 기다릴 필요가 없습니다. 시작한다".

1.- 코드의 네이티브 부분 (예 : iOS 용)에 MainViewController.m 메서드가 viewDidLoad에 있습니다. 나중에 웹 코드에서 확인할 자바 스크립트 변수를 보내고 있습니다. 해당 변수가 주변에 있으면 기다릴 것입니다. 모든 것이 준비 될 때까지 내 페이지의 코드를 시작하려면 (예 : 내비게이터 위치 정보)

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 값이있는 매개 변수 대상을 추가합니다. 그래서 안드로이드에 대한 호출은 다음과 같이됩니다.

super.loadUrl("file:///android_asset/www/index.html?target=phonegap");
이 코드를 사용하는 웹 사이트는 추가 매개 변수로 호출되지 않으므로 이제 두 배포 플랫폼간에 다른 점이 있습니다.
자바 스크립트 내에서 매개 변수가 있는지 확인하고 있다면 phonegap / cordova에 대한 스크립트 태그를 추가합니다.
    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 앱과 웹 클라이언트 모두에 동일한 코드를 사용하고 있습니다. 다음은 phonegap을 사용할 수 있는지 감지하는 데 사용하는 코드입니다.

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

phonegap js 파일은 비동기 적으로로드됩니다. 멋진 jquery $ .getScript 함수의 올바른 옵션을 설정하여 동기식으로로드 할 수 있습니다.

접근 방식은 웹 클라이언트에서도 phonegap js 파일을 가져 오기 위해 추가 GET 요청을 수행합니다. 제 경우에는 웹 클라이언트의 성능에 영향을 미치지 않았습니다. 그래서이 작업을 수행하는 좋은 / 깨끗한 방법이되었습니다. 적어도 다른 사람이 빠른 한 줄 솔루션을 찾을 때까지 :)


Phonegap 앱에서 웹뷰가 시작되면 다른 웹 페이지를로드하는 것 같습니다. 맞습니까? 이것이 사실이라면 구성을 기반으로 요청 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를 포함합니다.

사용자 에이전트를 사용하여 차이를 감지하는 방법은 없습니다.


내가하는 방식은 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에 포함시켜야 할 다른 것들이있을 수 있지만, 그것들이 무엇인지 아직 모릅니다.


Ive Ben은 이것으로도 어려움을 겪고 있으며 이것이 오래된 스레드라는 것을 알고 있지만 어디에서나 내 접근 방식을 보지 못했기 때문에 누군가를 도울 것이라고 생각했습니다.

실제 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");
}

다음을 시도하면 어떨까요?

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

내 마음에 당신은 스스로 문제를 일으키려고 노력합니다. 개발 플랫폼에 대해서는 언급하지 않았지만 대부분의 배포 구성이 다릅니다. 두 가지 구성을 정의 할 수 있습니다. 그리고 코드가 배포 된 방식을 나타내는 변수를 설정합니다. 이 경우 앱을 배포 한 장치에 대해 신경 쓸 필요가 없습니다.


짧고 효과적 :

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

BT의 솔루션유사 하지만 더 간단합니다.

I have an empty cordova.js in my www folder, which gets overwritten by Cordova when building. Don't forget to include cordova.js before your app script file (it took my one hour to find out that I had them in wrong order...).

You can then check for the Cordova object:

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

function bootstrap() {
   do_something()
}

New solution:

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

Old solution:
Use jQuery, run like this

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

Take iPhone as example for your mobile application,

When using PhoneGap or Cordova, you'll get 460px of WebView, but in safari, you'll lose some height because of browser's default header and footer.

If window.innerHeight is equal to 460, you can load phonegap.js, and call onDeviceReady function


Nobody mentioned this yet, but it seems Cordova now supports adding the browser as a platform:

cordova platforms add browser

This will automatically add cordova.js during run-time, which features the onDeviceReady event, so that you do not need to fake it. Also, many plugins have browser support, so no more browser hacks in your code.

To use your app in the browser, you should use cordova run browser. If you want to deploy it, you can do so using the same commands as the other platforms.

EDIT: forgot to mention my source.


Solution: Patch index.html in Cordova and add cordova-platform="android" to <html> tag, so that cordova-platform attribute will be only present in Cordova build and missing from original index.html used for web outside of Cordova.

Pros: Not rely on user agent, url schema or cordova API. Does not need to wait for deviceready event. Can be extended in various ways, for example cordova-platform="browser" may be included or not, in order to distinguish between web app outside of Cordova with Cordova's browser platform build.

Merge with config.xml

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

Add file 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');
}

Notes: For other than android, the paths platforms/android and /app/src/main/assets/www/index.html should be adjusted.

App can check for cordova-platform with

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

or

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

참고URL : https://stackoverflow.com/questions/10347539/detect-between-a-mobile-browser-or-a-phonegap-application

반응형