由于受到安全的限制,WEB应用跨域调用实现起来是比较麻烦的。传统的做法有服务器代理、jsonp接口等,但在firefox os中并不需要如此大费周折。在firefox os中已经提供了跨应用交互的机制,虽然目前来看并不是特别的方便,但已经可以实现基本的跨应用交互的App了。本文将以一个实际的DEMO来讲解B2G的跨应用调用。
概要介绍
本文将开发两个应用,应用一:Caller,应用二:Receiver
Caller中有一个Show Images的按钮,点击该按钮将启动Receiver,Receiver中提供了一些图片浏览的功能,在Receiver中选择图片后,点击Select按钮,将把图片传送到Caller中,并在Caller中展现该选择的图片
整体效果如下
Caller应用
Receiver应用
细节说明
Receiver
在Firefox OS中,要让应用可被其他应用调用,需要在该应用的manifest.webapp中进行声明。我们看一下Receiver的manifest.webapp文件
复制
{ "name": "Receiver", "launch_path": "/index.html", "developer": { "name": "chyblog", "url": "http://www.chyblog.com" }, "icons": { "120": "/style/icons/Receiver.png" }, "permissions": [ "background", "backgroundservice", "attention", "contacts", "settings", "desktop-notification" ], "activities": { "pick": { "filters": { "type": ["image/png", "image/gif"] }, "returnValue": true, "disposition": "inline" } } }
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
其中activities属性声明了一个web activity,取名为pick,其中filters属性告诉system对哪些类型的请求响应,Receiver应用,可以响应名称为pick,type为image/png或者image/gif类型的响应。
returnValue是一个布尔类型的属性,为true时,声明该web activity需要返回数据给调用它的应用,false则不需要返回数据给调用者
disposition属性有两种可选值,window和inline,如果为window,则会以启动一个新应用的方式打开,如果为inline,则会临时启动一个画面显示该应用的界面。
在Receiver应用中,还需要用js编写响应调用的处理代码
复制
navigator.mozSetMessageHandler('activity', webActivityHandler); var activityRequest; var webActivityHandler = function(request) { activityRequest = request; document.getElementById('button').disabled = ''; document.getElementById('cancelButton').disabled = ''; };
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
以上代码注册了一个事件响应句柄,并将请求者的信息保存在全局变量activityRequest中
当用户点击Select按钮后,将把图片信息传送给Caller。代码如下
复制
function select() { if (!activityRequest) { alert('There are no any pending activity request.'); return; } // Return the request activityRequest.postResult({ type : 'image/png', text : getBase64Image(selectedImg) }); activityRequest = null; // close app, currently useless, // see https://bugzilla.mozilla.org/show_bug.cgi?id=789392 window.close(); };
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
由于两个应用的数据交互只能使用文本信息传递,这里将Receiver中的图片以base64文字编码的方式传给Caller,在Caller中,将该文本设置到backgroundImage中,即可显示,获取图片的base64编码的代码如下
复制
function getBase64Image(imgSrc) { var img = new Image(); img.src = imgSrc; var canvas = document.createElement("canvas"); canvas.width = img.width; canvas.height = img.height; var ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0); var dataURL = canvas.toDataURL("image/png", 0.2); return dataURL; }
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Caller
Call应用中,主要是触发Receiver调用的响应和接受返回数据的处理
Call首先创建一个activity请求,需要告诉system,请求的名称和类型。并注册请求成功返回和请求失败时的处理逻辑。而请求如何去调用,完全由system控制。创建请求的代码如下
复制
var a = new MozActivity({ name : 'pick', data : { type : 'image/png' } }); a.onsuccess = function() { reopenApp(); document.getElementById('showImg').style.backgroundImage = "url(" + this.result.text + ")"; document.getElementById('result').textContent = 'well done'; }; a.onerror = function() { reopenApp(); document.getElementById('showImg').style.backgroundImage = ""; document.getElementById('result').textContent = '(canceled)'; };
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
需要强调的是,Caller和Receiver是两个独立的应用,两者之间的交互都是system app负责的。我们需要做的,就是声明web activity,触发请求和响应请求。
源码下载:http://chyblog-chyblog.stor.sinaapp.com/wp-content/uploads/2012/10/webActivity.zip