web-dev-qa-db-fra.com

Détecter entre un navigateur mobile ou une application PhoneGap

Est-il possible de détecter si l'utilisateur accède via le navigateur ou l'application en utilisant JavaScript? 

Je développe une application hybride pour plusieurs systèmes d’exploitation mobiles via une page Web et une application PhoneGap. L’objectif serait de:

  1. Utiliser le même code indépendamment de la cible de déploiement
  2. Ajouter le fichier PhoneGap.js uniquement lorsque l'agent utilisateur est une application
61
Diogo Cardoso

Vous pouvez vérifier si l'URL actuelle contient le protocole http.

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

Une solution rapide me vient à l’esprit:

onDeviceReady

doit vous aider. Cet appel JS n'étant appelé que par le pont natif (objC ou Java), le navigateur mobile Safari ne parviendra pas à le détecter. Ainsi, votre base source d'application sur appareil (interruption de téléphone) sera lancée à partir de onDeviceReady.

Et si l'un des appels JS de Phonegap, comme Device.platform ou Device.name, est NaN ou null, il s'agit évidemment d'un appel Web mobile.

S'il vous plaît vérifier et laissez-moi savoir les résultats. 

15
Futur

J'ai trouvé un moyen de faire cela et de ne pas compter sur des événements complexes, en maintenant la base de code Web intacte ...

Le problème actuel lié à l’utilisation de l’événement intégré intégré est que, lorsque la page est chargée, vous n’avez aucun moyen de dire à l’application: "Hé, cela ne fonctionne PAS sur un appareil mobile, il n’est pas nécessaire d’attendre que l’appareil soit prêt. commencer".

1.- Dans la partie native du code, par exemple pour iOS, dans MainViewController.m, il existe une méthode viewDidLoad, j'envoie une variable javascript que je vérifie plus tard dans le code Web. Si cette variable est disponible, j'attendrai pour démarrer le code de ma page jusqu'à ce que tout soit prêt (par exemple, géolocalisation du navigateur)

Sous MainViewController.m:

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

2.- index.html le code va comme ceci:

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

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

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

PhoneGap a le jeu d'objets window.PhoneGap (ou dans Cordova, c'est window.cordova ou window.Cordova). Vérifiez si cet objet existe et faites la magie.

7
zvona

J'utilise le même code pour l'application phonegap et pour notre client Web. Voici le code que j'utilise pour détecter si phonegap est disponible:

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

N'oubliez pas que le fichier phonegap js est chargé de manière asynchrone. Vous pouvez le charger de manière synchrone en définissant l'option correcte d'une fonction astucieuse jquery $ .getScript. 

Notez que cette approche fait une requête GET supplémentaire pour récupérer le fichier jj phonegap même dans votre client Web. Dans mon cas, cela n’a pas affecté les performances de mon client Web; Donc, au moins, jusqu'à ce que quelqu'un d'autre trouve une solution rapide en une ligne :)

4
Aki

On dirait que vous chargez une autre page Web une fois que la vue Web a démarré dans l'application Phonegap, est-ce exact? Si cela est vrai, vous pouvez ajouter un paramètre à l'URL de la demande en fonction de la configuration.

Par exemple, en supposant que PHP,

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

<body onload="onbodyload()">

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

Ensuite, côté serveur, incluez phonegap js si la cible est phonegap.

Il n'y a aucun moyen de détecter la différence en utilisant l'agent d'utilisateur. 

4
sciritai

J'ai aussi des difficultés avec cela, et je sais que c'est un vieux fil, mais je n'ai jamais vu mon approche nulle part.

j'ai défini un useragent personnalisé après le useragent réel: 

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

cela ajoute simplement la chaîne phonegap afin que les autres sites utilisant la détection de votre agent utilisateur mobile fonctionnent toujours.

Ensuite, vous pouvez charger une différence de téléphone comme ceci: 

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

et si vous essayez de suivre: 

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

Pour ce faire, j'utilise une variable globale qui est écrasée par une version de cordova.js réservée aux navigateurs. Dans votre fichier html principal (généralement index.html), j'ai les scripts suivants qui dépendent de l'ordre:

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

Et à l'intérieur de cordova.js j'ai simplement:

__cordovaRunningOnBrowser__ = true

Cordova.js ne sera pas utilisé lors de la compilation pour un appareil mobile (mais à la place, le fichier cordova.js spécifique à la plate-forme sera utilisé). Cette méthode présente l'avantage d'être correcte à 100%, quels que soient les protocoles, les agents d'utilisateur ou la bibliothèque. variables (qui peuvent changer). Il y a peut-être d'autres choses que je devrais inclure dans cordova.js, mais je ne sais pas encore ce qu'elles sont. 

4
B T

À mon avis, vous essayez de créer un problème pour vous-même. Vous n'avez pas mentionné votre plate-forme de développement, mais la plupart d'entre eux ont une configuration de déploiement différente. Vous pouvez définir deux configurations. Et définissez la variable qui indique comment le code a été déployé . Dans ce cas, vous n'avez pas à vous soucier des périphériques sur lesquels vous avez déployé votre application.

1
RredCat

Similaire à la solution de B T , mais plus simple:

J'ai un fichier cordova.js vide dans mon dossier www, qui est écrasé par Cordova lors de la construction. N'oubliez pas d'inclure cordova.js avant votre fichier de script d'application (cela m'a pris une heure pour découvrir que je les avais dans le mauvais ordre ...).

Vous pouvez ensuite rechercher l'objet Cordova:

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

function bootstrap() {
   do_something()
}
1
user5924996

Court et efficace:

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

Nouvelle solution:

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

Ancienne solution:
Utilisez jQuery, lancez comme ça

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

Prenez iPhone comme exemple pour votre application mobile,

Lorsque vous utilisez PhoneGap ou Cordova, vous obtenez 460 pixels de WebView, mais en safari, vous perdez de la hauteur à cause de l'en-tête et du pied de page par défaut du navigateur.

Si window.innerHeight est égal à 460, vous pouvez charger le fichier phonegap.js et appeler la fonction onDeviceReady <. S>

0

Solution: corrigez index.html dans Cordova et ajoutez cordova-platform="Android" à la balise <html> afin que l'attribut cordova-platform soit uniquement présent dans la version de Cordova et manquant dans le fichier index.html d'origine utilisé pour le Web en dehors de Cordova.

Avantages: ne comptez pas sur l'agent utilisateur, le schéma d'URL ou l'API cordova. N'a pas besoin d'attendre l'événement deviceready. Peut être étendu de différentes manières, par exemple cordova-platform = "browser" peut être inclus ou non, afin de distinguer les applications Web extérieures à Cordova avec la plateforme de navigation de Cordova.

Fusionner avec config.xml

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

Ajouter un fichier 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');
}

Remarques: Pour les applications autres qu'Android, les chemins platforms/Android et /app/src/main/assets/www/index.html doivent être ajustés.

App peut vérifier pour Cordova-plate-forme avec

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

ou

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

Personne n'en a encore parlé, mais il semblerait que Cordova prenne désormais en charge l'ajout du navigateur en tant que plateforme:

cordova platforms add browser

Ceci ajoutera automatiquement cordova.js pendant l'exécution, qui comporte l'événement onDeviceReady, de sorte que vous n'avez pas besoin de le simuler. En outre, de nombreux plug-ins prennent en charge les navigateurs, évitez les hacks des navigateurs dans votre code.

Pour utiliser votre application dans le navigateur, vous devez utiliser cordova run browser. Si vous souhaitez le déployer, vous pouvez le faire en utilisant les mêmes commandes que les autres plates-formes.

EDIT: oublié de mentionner ma source .

0
Ricardo Cruz