firefox os - a (mobile) web developers dream - dwx14
DESCRIPTION
My slides from Developer Week 2014 in Nuremberg. Original Slides: http://casarock.github.io/dwx14 (Quality of uploaded slides is not good as slideshare has problem converting the used backgorund)TRANSCRIPT
FIREFOX OSA (MOBILE) WEB DEVELOPERS DREAM
Carsten Sandtner ( ) 2014 - DWX 2014@casarock
WHO AM I?Carsten Sandtner
Head of Development at //mediaman GmbHMozilla representative
Javascript enthusiast and web developer since 1998.
HTML5 BASED OPERATING SYSTEMS
The full Safari engine is inside of iPhone.And so, you can write amazing Web 2.0 and
Ajax apps that look exactly and behaveexactly like apps on the iPhone. And theseapps can integrate perfectly with iPhoneservices. They can make a call, they can
send an email, they can look up a locationon Google Maps. And guess what? There’s
no SDK that you need!
WEBOS
CHROME OS
IN DETAIL
ARCHITECTURE
GONKLow level OS of Firefox OS. Linux - based on Android Open
Source Project
GECKO
GAIAUI level of Firefox OS
Only interface to the underlying operating system and hardware
WEB APIS AND WEB ACTIVITIES
APPS AND 3RD PARTY APPSEvery HTML5, Javascript, CSS based Apps for Firefox OS
Using WebAPIs and Web Activities
APP DEVELOPMENTOpen Web Apps
3 DIFFERENT APP TYPES
HOSTED APPS
PRIVILEGED APPS
CERTIFIED APPS
THE WEB APP MANIFEST
EXAMPLE (MINIMAL){ "name": "My Awesome App", "description": "My elevator pitch goes here", "launch_path": "/somedir/index.html", "icons": { "128": "/img/icon-128.png" }, "developer": { "name": "Your Name", "url": "http://your-homepage-here.tld" }, "default_locale": "en"}
EXAMPLE PRIVILEGED APP{ "name": "My Awesome Privileged App", .... "type": "privileged", "fullscreen": "true", "permissions": { "contacts": { "description": "Required for autocompletion in the share screen", "access": "readcreate" } }, "default_locale": "en", ...}
WEB APISOpen API specifications to access the hardware of devicesCreated with and submitted to standards bodies and other
browser makers
WEB APIS: HOSTED APPSVibration API, Screen Orientation, Geolocation API, MouseLock API, Open WebApps, Network Information API,Battery Status API, Alarm API, Push Notifications API,WebFM API / FMRadio, WebPayment, IndexedDB,Ambient light sensor, Proximity sensor, Notification.
WEB APIS: PRIVILEGED APPSDevice Storage API, Browser API, TCP Socket API,Contacts API, systemXHR.
WEB APIS: CERTIFIED APPSWebTelephony, WebSMS, Idle API, Settings API, PowerManagement API, Mobile Connection API, WiFi InformationAPI, WebBluetooth, Permissions API, Network Stats API,Camera API, Time/Clock API, Attention screen, Voicemail.
Example: Battery APIvar battery = navigator.battery || navigator.mozBattery || navigator.webkitBattery, info = { charging: battery.charging, chargingTime: parseInt(battery.chargingTime / 60, 10), dischargingTime: parseInt(battery.dischargingTime / 60, 10), level: Math.round(battery.level * 100) };
EXAMPLE: BATTERY API - CONT.APIs are event driven!
var battery = navigator.battery || navigator.mozBattery || navigator.webkitBattery;
function updateBatteryStatus() { console.log("Battery status: " + battery.level * 100 + " %");
if (battery.charging) { console.log("Battery is charging"); }}
battery.addEventListener("chargingchange", updateBatteryStatus);battery.addEventListener("levelchange", updateBatteryStatus);updateBatteryStatus();
EXAMPLE: GEOLOCATION API*navigator.geolocation.getCurrentPosition(handleLocation);
function handleLocation(position) { var latitude = position.coords.latitude; var longitude = position.coords.longitude;}
// Or watch the current position...var watchID = navigator.geolocation.watchPosition(function(position) { handlePostion(position.coords.latitude, position.coords.longitude);});
*Ok, ok, not really a new one!
EXAMPLE: VIBRATION APIvar pattern = [200, 100, 200, 200, 100], goodVibration = navigator.vibrate(pattern);
EXAMPLE: NOTIFICATION APINeeds permissions granted by users! (e.g. webapp.manifest)"permissions": { "desktop-notification": { "description": "Allows to display notifications on the user's desktop." }}
// At first, let's check if we have permission for notification// If not, let's ask for itif (Notification && Notification.permission !== "granted") { Notification.requestPermission(function (status) { if (Notification.permission !== status) { Notification.permission = status; }});}
if (Notification && Notification.permission === "granted") { var n = new Notification("Hi!");}
EXAMPLE: CONNECTION APIGet information about current connection
var connection = navigator.connection || navigator.webkitConnection || navigator.mozConnection;
function updateConnectionStatus() { console.log("Connection changed"); console.log("Bandwidth: " + connection.bandwidth); console.log("Metered: " + connection.metered);}
connection.onchange = updateConnectionStatus;
EXAMPLE: AMBIENTLIGHTGet current Lux of ambient light
window.ondevicelight = function (event) { // Read out the lux value var lux = event.value;};
EXAMPLE: CONTACTS APIRead/Write/Delete Contacts - Permission required!
"permissions": { "contacts":{ "description": "Contacts permissions is required to write contact from Google to your Firefox OS phone", "access": "readwrite" } }}
var contactData = { givenName: ["John"], familyName: ["Doe"]};
var person = new mozContact(contactData);// save the new contactvar saving = navigator.mozContacts.save(person);
saving.onsuccess = function() { console.log('new contact saved');};
saving.onerror = function(err) { console.error(err);};
EXAMPLE: DEVICE STORAGE APISave/Read from sdcard, photo, music, video ...
"permissions": { "device-storage:pictures":{ "access": "readwrite" }, "device-storage:sdcard":{ "access": "readwrite" }}
var sdcard = navigator.getDeviceStorage("sdcard"), file = new Blob(["This is a text file."], {type: "text/plain"}), request = sdcard.addNamed(file, "my-file.txt");
request.onsuccess = function () {...}request.onerror = function () {...}
var pics = navigator.getDeviceStorage('pictures');// browse all the images availablevar cursor = pics.enumerate();cursor.onsuccess = function () { var file = this.result; console.log("File found: " + file.name);
// check if there is other results if (!this.done) { // Then we move to the next result, which call the cursor // success with the next file as result. this.continue(); }}
WEB ACTIVITIES
WEB ACTIVITIESconfigure, costcontrol, dial, open, pick, record, save-bookmark, share, view, update.
new: f.e type: “websms/sms” or “webcontacts/contact”
EXAMPLE: DIAL A NUMBERvar call = new MozActivity({ name: "dial", data: { number: "+49123456789" }});
Invokes "native" Dialer app
EXAMPLE: OPEN AN URLvar openURL = new MozActivity({ name: "view", data: { type: "url", // Possibly text/html in future versions url: "http://www.developer-week.de/" }});
Invokes "native" browser
EXAMPLE: SEND A SMSvar sms = new MozActivity({ name: "new", data: { type: "websms/sms", number: "+49987654321" }});
Invokes "native" messaging app
EXAMPLE: PICK AN IMAGEvar getphoto = new MozActivity({ name: "pick", data: { type: ["image/png", "image/jpg", "image/jpeg"] }});
RESULT
EXAMPLE: PICK AN IMAGE - CONT.getphoto.onsuccess = function() { var img = document.createElement("img"); if (this.result.blob.type.indexOf("image") != -1) { img.src = window.URL.createObjectURL(this.result.blob); }};getphoto.onerror = function() { // error};
REGISTER AN APP AS ACTIVITY HANDLER{ // Other App Manifest related stuff
// Activity registration "activities": { "pick": { "href": "./pick.html", "disposition": "inline", "filters": { "type": ["image/*", "image/jpeg", "image/png"] }, "returnValue": true } }}
HANDLE AN ACTIVITYnavigator.mozSetMessageHandler('activity', function(activityRequest) { var option = activityRequest.source;
if (option.name === "pick") {
// Do something to handle the activity
// Send back the result if(picture) { activityRequest.postResult(picture); } else { activityRequest.postError("Unable to provide a picture"); } }});
TOOLS&UTILS
TESTINGSimulatorBrowser - It's a Web App!
DEVELOPMENTNo SDK!Use your favorite IDE/EditorIt's HTML5!WebIDE!
WEBIDE
https://apps.webmaker.org/
RAPID APPLICATION DEVELOPMENTuse Mozillas Appmaker
DEBUGGING
DEBUGGING - SIMULATOR
Developer tools in Firefox! (NOT! Firebug)Remote Debugger!
DEBUGGING - REMOTEConnect your deviceDebug!That's all
FIREFOX OS BOILERPLATE
https://github.com/robnyman/Firefox-OS-Boilerplate-App
PHONEGAP AND CORDOVA
http://build.phonegap.com/http://cordova.apache.org/
HOW TO DISTRIBUTE YOUR APP
HOSTED APPHost the App on your web spaceProvide installation using WebAPI
HOSTED APP DISTRIBUTIONCheck if app is already installed
var request = navigator.mozApps.checkInstalled(manifestPath);
request.onerror = function() { console.log('Error checking for installed app: ', request.error.name);};
request.onsuccess = function() { // If the app is installed, you'll get a mozApp object in ̀request.result̀, // else ̀request.result̀ is null console.log("Could be installed: ", request.result !== null ? "is installed" : "is not installed"};
HOSTED APP DISTRIBUTIONInstall your app
var installRequest = navigator.mozApps.install(manifestPath);
installRequest.onsuccess = function() { // No error console.log("App installed");};
installRequest.onerror = function() { console.log('Error installing the app: ', installRequest.error.name);};
Done. Cool, eh?Works on Firefox Android, too.
Distribute via Firefox OS MarketplacePRIVILEGED APP
Validate using App-ManagerPRIVILEGED APP DISTRIBUTION
Upload ZIP of your app to marketplace.Wait for approval. Done.
THANK YOU!Carsten Sandtner
@casarock
Slides: http://casarock.github.io/dwx14