[Théorie] Créer des applications mobiles françaises avec l’Api du WebRtc , utiliser la cam, le micro, le gps etc … Et piloter des robots

IntroductionFDS_371236.jpg


De nos jours, il n’est pas rare de devoir créer des applications françaises mixtes tournant sur des ordis de bureau et sur des machines mobiles (Tablettes, Téléphones tournant sous Android ou AppleIOS).

On peut désormais se servir des APIS HTML 5.0 du WebRtc  pour accéder directement aux mécanismes (DEVICES) des téléphones et tablettes mobiles ! (Voir les exemples)

Sur cette bonne page, on peut voir d’autres exemples utilisant le sensor par exemple.

Du coup, il n’y a plus besoin d’installer la librairie PhoneGap ou Cordova, couteuse en temps de chargement et en taille.

Il est donc possible d’élaborer des applications complexes avec par exemple un codeBar Scanner(Ce que je vais faire ces jours ci), un microphone et de la capture vidéo, sans se farcir la complexité de Java  ( Que je pratique aussi, par gout pour la prog objet et par goût pour UML2.0), c’est  vraiment la fête.

Une autre chose à savoir est que les derniers CSS bootstrap 3.0 ont vraiment de superbes aptitudes à s’auto-adapter sur desktop et mobile(Ils ont poussé le responsive design à fond) .

Note : Il est également possible d’utiliser la librairie ngCordova avec Ionic afin d’accéder à toutes les fonctionnalités des appareils mobile ( Photographie, Microphone, Code Bar scanner, envoi de Sms, Position GPS) avec une syntaxe plus facile en AngularJs… Par contre, une fois que l’application est finalisée, il faut la compiler, et ça, on ne veut pas le faire dans le cas présent, ce n’est pas le sujet du post, nous ce qu’on veut, c’est accéder aux fonctionnalités du mobile directement en HTML5.0 et en Javascript, sans avoir à compiler et faire des trucs qui vont nous faire perdre un peu de temps  .

I9300-Smartphone-telephone-portable-3G-Dual-core-1.0-GHz-MTK6575-Android-4.0-mobile-ecran-tactile-capacitif-4.7-pouces-Dual-sim-et-Dual-camera-007

Sommaire :


  • Les normes du W3c « Media Capture and Streams ».
  • Le WebRTC.
  • Le Mozilla Developper Network .
  • La nouvelle tendance à n’autoriser que le HTTPS .
  • Problèmes de version de MediaDevices.getUserMedia()
    1.  Exemple de code de Géolocalisation mixte Desktop Mobile
    2.  Exemple de prise de photo sur Firefox dans un mobile Samsung 5 pouces Galaxy
    3. Exemple de scan de Code bars en Html 5.0 avec quaggaJS (https://serratus.github.io/quaggaJS/).
    4. Exemple de détection de visage et de mouvements
    5. Piloter un bras robotisé avec Javascript : les pistes.
    6. Que faire avec un lecteur de cartes au format bancaire et js?

 

 

télécharger

Les normes du W3c « Media Capture and Streams ».


Les normes webRtc sont définies et mises à jour sur le site suivant : https://www.w3.org/TR/mediacapture-streams/

 

webrtc-logo-vert-retro-255x305.png

Le WebRtc


Il existe déjà depuis un certains temps … et permet aussi de faire du peer to peer(échange de fichiers d’ordi à ordi) plus facilement avec des libs comme http://peerjs.com.

https://reep.io permet également le transfert d’ordi à ordi.

 

Mozilla_Developer_Network

Le Mozilla Developper Network .


Lié au navigateur Firefox, il décrit l’api et la manière d’accéder aux mécanismes(devices) des mobiles. Il récapitule les instructions dépréciées, c’est pour ça que certains codes ne fonctionnent plus parfois, parce que l’instruction de l’api est dépréciée, il ne faut pas s’affoler pour cela, parce que webRtc est encore en cours d’élaboration, et consulter ce site.

 

La nouvelle tendance à n’autoriser que le HTTPS .

Attention Chrome n’autorise plus que la connexion HTTPS pour bénéficier de la caméra sur les mobiles.

Problèmes de version de MediaDevices.getUserMedia()


C’est le nouveau format de l’instruction d’accès aux mécanismes des mobiles.

Avant, la syntaxe était la suivante: Navigator.getUserMedia()

Firefox est rétro-compatible, mais pas Chrome. On peut voir que l’ancienne syntaxe est dépréciée à cette adresse : https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getUserMedia

De ce fait, il ne faut pas s’étonner que certaines anciennes briques de codes de passent plus dans Chrome, mais dans Firefox.

 

 

 

comment-ne-pas-se-faire-geolocaliser-via-les-applications_5194315

Exemple de code de Géolocalisation mixte Desktop Mobile (Cliquer pour tester)


Ce code a été testé avec succès sur un mobile Samsung Galaxy Grand Plus, sur l’émulateur opéra et sur un ordi de bureau Windows 7.  Cependant attention, dans le samsung galaxy, le code fonctionne encore dans Firefox, mais pas dans Google Chrome, qui est passé sur le nouveau format d’instructions webRtc(ou sur HTTPS forcé).

Index.html : Il va afficher la carte Google Map :

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Géolocalisation</title>
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">

	   <!-- JQUERY ET BOOTSRAP -->
        <script src="bower_components/jquery/dist/jquery.min.js"></script>
        <script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
        	<link rel="stylesheet" type="text/css" href="bower_components/bootstrap/dist/css/bootstrap.min.css">

        <!-- ANGULAR -->
        <script src='bower_components/angular/angular.min.js'></script>
		<script src="js/app.js"></script>

  </head>

	<body ng-app="geo" ng-controller="GeoCtrl">
<div id="map"></div>
</body>
</html>

Le fichier app.js, qui est le controleur de la vue index.html :

angular.module('geo', [])
.controller('GeoCtrl', function($scope) {
	/* GEOLOCALISATION */
	// Detect l'api avant de l'utiliser 
	 
	if (navigator.geolocation) {
	 // Insère la carte dans la div "map"
		var mapElem = document.getElementById("map"),
	 
		// cette fonction en cas de succès dacces à la position récupère la long et la lat puis affiche google map
	 
			successCallback = function(position) {
				var lat = position.coords.latitude,
					long = position.coords.longitude;
	 
				mapElem.innerHTML = '<img src="http://maps.googleapis.com/maps/api/staticmap?markers=' + lat + ',' + long + '&zoom=15&size=300x300&sensor=false" />';
			},
		
		// Cette fonction se lance si l'endroit ne peut pas être localisé
		errorCallback = function() {
				  alert("Désolé, je ne peux pas trouvé vos coordonées GPS.");
			};
	 
		// Start watching the user’s location, updating once per second (1s = 1000ms)
		// and execute the appropriate callback function based on whether the user
		// was successfully located or not
	 
		navigator.geolocation.watchPosition(successCallback, errorCallback, {
			maximumAge: 1000
		});
	}
});

 

 

10893962-Prendre-des-photos-avec-un-t-l-phone-mobile-smartphone-en-mode-appareil-photo-en-ext-rieur-Banque-d'images

Exemple de prise de photo sur Firefox dans un mobile Samsung 5 pouces Galaxy


une fois de plus, ce code marche très bien dans Firefox mobile, mais pas dans Chrome Mobile, on se demande vraiment ce qu’il leur a pris de suprimer la rétro compatibilité chez Chrome(ou de forcer l’accès https).

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Acquérir le média d'un utilisateur - Photo</title>
</head>
<body>
<button id="take">Prends une photo, jojo</button>

<video id="v"></video>
<canvas id="canvas" style="display:none;"></canvas>
<img src="http://placehold.it/300&text=Your%20image%20here%20..." id="photo" alt="photo">
<script>
    ;(function(){
	<!-- la fonction générique qui est censée s adapter a tous les navigateurs -->
        function userMedia(){
            return navigator.getUserMedia = navigator.getUserMedia ||
            navigator.webkitGetUserMedia ||
            navigator.mozGetUserMedia ||
            navigator.msGetUserMedia || null;

        }

        // Maintenant, on peut l utiliser
        if( userMedia() ){
            var videoPlaying = false;
            var constraints = {
                video: true,
                audio:false
            };
            var video = document.getElementById('v');

            var media = navigator.getUserMedia(constraints, function(stream){

                // L url de l objet est different dans webkit
                var url = window.URL || window.webkitURL;

                // creer l url et set la source de la video
                video.src = url ? url.createObjectURL(stream) : stream;

                // lance la video
                video.play();
                videoPlaying  = true;
            }, function(error){
                console.log("ERROR");
                console.log(error);
            });

            // ecoute l action utilisateur sur le bouton prendre une photo jojo
            document.getElementById('take').addEventListener('click', function(){
                if (videoPlaying){
                    var canvas = document.getElementById('canvas');
                    canvas.width = video.videoWidth;
                    canvas.height = video.videoHeight;
                    canvas.getContext('2d').drawImage(video, 0, 0);
                    var data = canvas.toDataURL('image/webp');
                    document.getElementById('photo').setAttribute('src', data);
                }
            }, false);

        } else {
            console.log("KO");
        }
    })();
</script>
</body>
</html>

Mais… On s’en fout complétement de pouvoir prendre une photo, notre mobile le fait déjà bien!

L’intérêt est que l’on peut penser par exemple à une application commerciale qui permettrait de stocker des photos, ainsi que la localisation GPS à un instant T, qui seraient prises par des commerciaux. De cette façon, on pourrait ensuite réaliser des statistiques basées sur ces photos, leur fréquence etc … De même on peut lier la photo a un système de notation par étoile, le commercial peut par exemple attribuer une note à la devanture d’un magasin. Un autre exemple est le flash photographique lors du passage sous un portique, ne serait-ce que pour la sécurité.

 

 

46769-code-barre-codes-barres

Exemple de scan de Code bars en Html 5.0 avec quaggaJS (https://serratus.github.io/quaggaJS/).


 

Lorsque l’on pense à scanner un code barre, on pense généralement à utiliser une machine comme ceci :

155033_176018255756655_106589586032856_527658_3535967_n

avec une technique Js comme cela, par exemple . De suite, on est frappé par le fait que l’on puisse développer des applications AngularJs en utilisant ce système, AngularJs étant spécialement flexible et structuré, cela est très excitant et peut même sembler facile!

J’ai de ce pas acheté un petit lecteur de codes Barres sur Ebay pour commencer  à m’entrainer à créer des apps.

code128

Cependant, un développeur(génie?) a également développé QuaggaJs qui permet de scanner un code Barre avec l’appareil photo d’un téléphone mobile, ou à partir d’une photo. Reste à savoir le pourcentage de réussite de scans et à s’assurer que cela soit réellement utilisable en condition professionelle.

Je dois avouer que mes premiers tests avec une webcam de base et un téléphone Samsung Galaxy ne sont pas vraiment concluants, j’ai essayé de scanner une bouteille de coca cola, mais visiblement, sur le site Web, cela ne passe pas.

Par contre suite à une prise de photo, l’api semble avoir retrouvé le code barre. Il faut donc que je teste avec du code pour savoir si je récupère un code, avec un console.log();

Je termine l’article ces jours ci….
 

Publicités

[Théorie] Utiliser des Apis Web pour concevoir plus rapidement des Application Web. ( + »Piquer » des données avec le Web Scrapping, hi hi hi)

Introductionbfs-module-icon-api-letter


Lorsque l’on débute un projet, notre base de données est vide, on a alors souvent besoin de données .

Pour obtenir ses futures données plus rapidement, on peut se connecter à l’aide d’une api à des bases de données WEB reconnues, afin d’alimenter notre application plus rapidement.

Un exemple: J’ai une application de vente et de gestion de poissons d’aquariums, je ne vais pas me taper à la main l’enregistrement de 1000 poissons et la prise de photo des 1000 poissons si les photos nommées existent déjà, triées , dans une base de données accessible sur WEB.
Un autre exemple : Si je veux créer un AutoComplete sur un Champs Input Html répertoriant des noms de villes, je ne vais pas, bien sur, coder à la main chaque nom de ville ! Je vais d’abord chercher si une API ne pourrait pas me fournir ces données automatiquement sans le moindre effort( De plus l’api pourra même me fournir énormément d’informations à propos de telle ou telle ville ).

Pour voir du web scrapping dans une de mes apps c’est ici : http://nicolash.org/truc53/#/dashboard/crud

Cependant attention, il pourrait arriver que certaines API soient supprimées ou discontinuées ou même mises à jour, en ce cas, si notre application reposant dessus ne fonctionne plus, on aura beaucoup de problèmes avec nos clients ! Il faut donc soit plutôt prévoir un système d’import des données ou soit prévoir une solution de secours dans notre application, dans l’idéal, l’intégration de l’api doit être transparente dans notre app, que l’api soit accessible ou pas.

Sommaire :


  1. Mais comment cela fonctionne-t-il sur le web ?
  2. Peux-tu nous faire un schéma ?
  3. A quoi ressemble la réponse du serveur distant ?
  4. Quelles  sont ces merveilleuses apis, alors  ?
  5. Mais …Il n’y a pas d’API et pourtant je voudrais acquérir les données d’un autre site web super bien dans mon application ! Le Web Scrapping.
  6. Et on peut scrapper avec Jquery ou Angular directement ?
  7. Des entreprises sont elles spécialisées dans le Web scrapping ?
  8. Les outils de Web scrapping

Lire la suite

[Théorie] Schéma d’une application AngularJs + Php-Mysql

file-page1

[Théorie] Les générateurs de CRUD pour PHP, pour JAVA et pour MongoDb.

Introduction php_crud_with_mysql

Après avoir créé mes propres systèmes Crud pour firebase et pour PHP-Mysql et pour MongoLab ,

Je m’intéresse maintenant aux générateurs automatiques de CRUD.

CRUD veut dire créer, lire, mettre à jour , supprimer.

Lorsque l’on a plusieurs tables SQL, il devient fastidieux, parfois de devoir réecrire tous les codes et les vues.

Il existe donc des générateurs CRUD. qui vont tout générer le code à notre place, au pire on pourra le modifier après.En anglais, ça s’appelle souvent scaffolding.

LEQUELS ?


Pour Php:

  • http://www.phpscaffold.com : Celui ci est totalement en ligne et créé les fichiers après copié collé de nos exports de table SQL, par contre ne gère pas les jointures. Testé avec succès, c’est assez sympa.
  • http://www.grocerycrud.com mais faut vérifier qu’il n’a pas besoin de codeIgniter.
  • https://www.creativejuiz.fr/blog/veille-technologique/generer-back-end-complet-depuis-base-mysql-crud-admin-generator le look a l’air sympa.
  • http://xcrud.com/demos/index.php?page=join&theme=default Fais les jointures et pas mal de trucs.

Pour Java : 

  • https://sites.google.com/site/telosystutorial/angularjs/step0 : A l’air bien et est bien expliqué.

Pour noSql : 

  • je crois que c’est ça : https://jhipster.github.io ou ça https://github.com/jlmonteagudo/generator-meanjs-table

#scfc

[Css] Utiliser un templates Css d’Administration moderne et responsive pour créer une application(Partie 2 AngularJs).

IntroductionWB0P6NR1N


Finalement, suite au premier article, j’ai trouvé le meilleur template pour mon cas, je pense, avec sb admin 2.

C’est un pure template open source fait en ANGULARJS, avec du routing de vues, du lazy loading, des directives, mais très bien fait et structuré.

Pleins d’atouts : Le lazy loading de librairies Angular qui fait qu’on charge une grosse librairie annexe, seulement lors du click sur une vue qui impose cela dans le router. Si je clique sur le menu »Graphiques », alors la librairie Charts.JS est chargée. De ,ce fait, tout le site est plus rapide.

Les css sont hyper bien fait, et décris. Ca passe hyper bien sur mobile( Revérifié aujourd’hui, oui c’est le top sur un 5 pouces !).

Dorénavant, je créerais tous mes exercices la dessus,le look est trop bon.

 Description sommaire


Faut l’installer carrément avec NPM, qui installe ensuite les libs via BOWER, au final le tout pèse 8MO librairies annexes comprises.

Ensuite, on a un index.html classique, des vues, des directives et des controllers. Pour les css, il ne faut jamais créer les siens, mais toujours utiliser au maximum les css du template, il faut donc repérer leurs noms dans class= »laClasseDuCss » dans une vue HTML.

Dans le fichier scripts/app.js, on retrouve le routing avec le lazy loading des libriaires et chaque controleur dédié par vue, c’est simple une fois qu’on a compris.

La partie légèrement plus compliquée est les directives, mais une fois qu’on a compris, on peut y injecter des variables et aussi des fonctions personnalisées, qui peuvent se répéter à l’infini. Les directives sont comme un mini-template HTML que l’on peut répéter à loisir dans le HTML, entre des balises personnalisées.

Le testing :


Pour tester le template déja modifié sur mon serveur, cliquer sur ce lien.

Une autre version plus simple :

Quelqu’un a réalisé une version plus à tester :
https://github.com/rcaferraz/startbootstrap-sb-admin-2/tree/angularmod

[Exercice 52] Déplacement des points sur click dans le graphique avec HighCharts

Introductionhighcharts21


Dans cet exercice, on peut bouger les points d’un graphique en cliquant dessus, puis le modèle de données JSON est enregistré quand on clique sur Sauvegarder.

Note : je commence à éviter à fond les $scope maintenant, je ne les utiliserais qu’en cas d’absolue nécessité (Par exemple pour les menus déroulants)

Je vais créer une micro App de gestion de ressources humaines utilisant ce système.

Le Code :


Je l’ai stocké sur JsFiddle ici :

http://jsfiddle.net/nicolas1000/efv0vvbp/

Le voici au cas ou :

Index.html


<!-- REF http://jsfiddle.net/highcharts/AyUbx/ draggable REF http://jsfiddle.net/pablojim/Cp73s/ highcharts-ng -->
<html >
	<head>
		<meta charset="utf-8" />
		<title>Statistiques .</title>

		<!-- LIbs -->
		<script src="librairies/angular.min.js"></script>
		<script src="librairies/highcharts.js"></script>
		<script src="librairies/highcharts-ng.js"></script>
		<script src="librairies/draggable-points.js"></script>

		<link rel="stylesheet" type="text/css" href="librairies/bootstrap.min.css">

		<script src="app.js"></script>

	</head>

<body>

<div ng-app="myapp">
    <div ng-controller="myctrl">
        <highchart id="container" config="highchartsNG" style="height: 300px"></highchart>
        <div class="well row">
            <div class="col-xs-3">
                <button ng-click="randomize()" class="btn">Randomizer la série</button>
                <button ng-click="randomize(true)" class="btn">Randomizer l'historique</button>
				<button ng-click="save()" class="btn">Sauvegarder</button>
            </div>
            <div ng-bind="drag" class="col-xs-3"></div>
            <div ng-bind="drop" class="col-xs-3"></div>
			<div id="text"></div>
        </div>
    </div>
</div>

</body>

Le fichier JS app.js :

var myapp = angular.module('myapp', ["highcharts-ng"]);

myapp.controller('myctrl', function ($scope) {
    $scope.drag = 'drag feedback';
    $scope.drop = 'drop feedback';

    $scope.randomize = function (onlyHistory) {
        var seriesArray = $scope.highchartsNG.series
        for (i in seriesArray[0].data) {
            var random = Math.floor(Math.random() * 250);
            seriesArray[0].data[i] = random;
            if (!onlyHistory) seriesArray[1].data[i] = random;
        }
    };

	$scope.save= function(){
		 console.log(test);
		document.getElementById('text').innerHTML = "<br>MODELE DE DONNEE APRES SAUVEGARDE: "+test;
	}

	test  = [45, 200, 150];

    $scope.highchartsNG = {
        options: {
            chart: {
                type: 'spline'
            },
            plotOptions: {
                series: {
                    cursor: 'ns-resize',
                    point: {
                        events: {
                            drag: function (e) {
                                $scope.drag = this.series.name + ' = ' + Highcharts.numberFormat(e.newY, 2);
                                $scope.$apply($scope.test);

                            },
                            drop: function () {
                                $scope.drop = this.series.name + ' = ' + Highcharts.numberFormat(this.y, 2);
                                $scope.$apply();
								var point = Highcharts.numberFormat(this.y, 2);
								test[this.index] = parseInt(point); 

                            }
                        }
                    },
                    stickyTracking: false
                },
                column: {
                    stacking: 'normal'
                }
            },

            tooltip: {
                yDecimals: 2
            },

        },

        xAxis: {
            categories: ['Puissance', 'Diplomes', 'Flexibilité']
        },

        series: [{
            data: [0, 71.5, 106.4],
            name: 'Historique',
            draggableY: false,
            dashStyle: 'dash'
        }, {
            data: test,
            name: 'Draggable',
            draggableY: true
        }],
        title: {
            text: 'Cliquez sur les points pour modifier les valeurs.'
        },
        loading: false
    }

});