Filed under Mobile

webOS程序的调试

对于web开发,Firebug之类的工具必不可少。webOS的SDK里面自带了Palm Inspector的调试程序,不过我反复尝试都没有调试成功,一直提示“Disconnected. If you get disconnected as soon as you start Palm Inspector, make sure that the app is ready for inspection.”。可是我已经通过命令”palm-launch -i com.mycompany.palm1″使app运行在inspector的模式了,奇怪的很。

Google一下,发现有种新的调试模式:Emulator Host Mode,可以直接用桌面Chrome来运行app,文档上说的是用PuTTY,我摸索了下,配置如下:

这样,ssh到localhost:5522,帐号:root/[enter],然后在Chrome访问http://localhost:5580/。如下:

可以使用Chrome的Developer Tool来查看dom对象,Cool! 看来webOS系统本身有个web server运行在8080端口上,而UI则是用webkit访问这个server的结果,这个web服务是自给自足啊!不过一些本地功能,比如“打电话”,在Chrome中显然使用不了,所以这个工具只是用来调整UI用的。

新的框架Enyo好像独立出来了,可以直接在本地开发。

Android的“最近应用对话框”

这个对话框会列出应用的图标,当用小球把焦点移到某个图标时,这个图标会有种“光晕”的效果,如下图所示:

刚看到时想要如何画呢:确定图片的边界然后画上一条曲线?把放大后的图片和原来的图片叠加?模糊的边角看上去也很cool…

找一通后发现对话框的代码位置:$Droid_Src/frameworks/base/policy/src/com/android/internal/policy/impl/com/android/internal/policy/impl,图片处理的代码为IconUtilities.java。图简便就地使用ApiDemo里面的代码来做个小例子,主要代码如下。显示结果在上面的图片中。

int[] xy = new int[2];
Paint mBlurPaint = new Paint();
final float density = mDisplayMetrics.density;
final float blurPx = 5 * density;
mBlurPaint.setMaskFilter(new BlurMaskFilter(blurPx, BlurMaskFilter.Blur.NORMAL));
Bitmap mask = mBitmap.extractAlpha(mBlurPaint, xy);

mGlowColorFocusedPaint = new Paint();
mGlowColorFocusedPaint.setColor(0xffff8e00);
mGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));
canvas.drawBitmap(mask, 10, y, mGlowColorFocusedPaint);
canvas.drawBitmap(mBitmap, 10-xy[0], y-xy[1], new Paint());

上面TableMaskFilter在android定义为hidden,所以不能在自己的项目中用。我找个一个方法:在自己的project中重新定义一个同名同package的脚手架类,使上面代码编译通过即可。这个方法跟iPhone上面一样。

package android.graphics;

public class TableMaskFilter2 extends MaskFilter {

public TableMaskFilter2(byte[] table) {

}

public static TableMaskFilter2 CreateClipTable(int min, int max) {
return null;
}

public static TableMaskFilter2 CreateGammaTable(float gamma) {
return null;
}
}

代码很简单,和Photoshop的一些滤镜有点像…… 但是后面的原理现在还不清楚。

Android 2.2终于开放了推送的消息服务

内流满面阿,终于不用自己搞个长连接了。

2.2释放出来了,在其新特性中,有一点:Cloud to Device Messag(C2DM),这个跟gtalk类似,可以让web程序或者app engine向手机发送消息,不同的是gtalk是系统级别的,一般程序访问不了,这个则是标准的API。

在旧版本android上实现这个功能还是蛮麻烦的,我原来写过。主要的思路就是自己起一个gtalk的客户端,用xmpp协议,然后放在service保证长时间运行。缺点很明显:这个service消耗手机资源,功能跟系统本身服务重复。不过在消息服务没有开放时,自己的app是接收不到xmpp消息的。

google开放出来很直接,因为使用的还是老一套。下面是手机受到消息时的log,可以看出使用的还是smack,当然,协议还是xmpp了。

05-22 09:26:13.356: DEBUG/GTalkService(223): [ChatMgr] processPacket: not logged in! drop org.jivesoftware.smack.packet.DataMessage@43e929e8
05-22 09:26:13.576: INFO/JumpNote_SyncAdapter(298): Beginning full sync for account fkpwolf@gmail.com
05-22 09:26:16.316: INFO/JumpNote_SyncAdapter(298): Sync complete, setting last sync time to 1274491573563

那么web端或者云端如何发送消息呢?我看到代码里面是访问https://android.clients.google.com/c2dm/send,大概用的是rest吧。不过现在google要申请帐号才能访问这个服务。mobile收消息则使用标准的receiver模式。

Google给了个例子:JumpNote,可以看作双向同步功能的写字板。技术用android client + app engine + gwt(web client),使用了android新的sync API,还是一个蛮复杂的例子,因为这不单单是一个mobile app,而是一个完整的云服务实例,值得仔细研究研究。

device

Tagged

More about get rid of toolbar at iPhone Safari

When you visit some web site like Google Reader or Delicious at iPhone Safari, maybe you will notice that after have loaded page, the browser will hide tool bar automatically. This feature can save phone’s valuable screen space. To implement it we can just use javascript: window.scrollTo(0,1). See here, and here.

<script type="application/x-javascript">

if (navigator.userAgent.indexOf('iPhone') != -1) {
 addEventListener("load", function() {
 setTimeout(hideURLbar, 0);
 }, false);
}

function hideURLbar() {
 window.scrollTo(0, 1);
}

</script>

In common sense, it works. But if it didn’t, this article will help you.

First if we want toolbar hidden, beside the above JavaScript, below two conditions should be true:

1) web page is long enough. If it is short, the browser will think it is not necessary to hide the bar. You can zoom the page to test this rule.

2) scrollTo after page updated. setTimeout is used for this. We often invoke an AJAX to get HTML text from server and then update some part of page. The updating action will reload page so window.scrollTo must be invoked after AJAX has gotten response and page has been updated. So the timeout of scrollTo should be bigger than timeout of Ajax. Or invoke scrollTo after had gotten response directly. Keep in mind that setTimeout and Ajax both are asynchronousI used jQuery and $(#id).html(“<div>…”); to update page, so for DRY, I override this function:

if (navigator.userAgent.indexOf('iPhone') != -1) {
 (function ($) {
 var originalVal = $.fn.html;
 var hideURLbar = function() {window.scrollTo(0,1);};
 $.fn.html = function(value) {
var ret = originalVal.call(this, value);
 if (typeof value != 'undefined') {
 // setter invoked, do processing
 setTimeout(hideURLbar, 100);
 }
 return ret;
 };
 })(jQuery);
};

I found this cool script from here. Mabye this approach impacts app much, for html method is used everywhere in app. So take care before apply it. There is another option: use $(document).trigger to sent event.
Screenshot 2010.05.08 14.39.26

Tagged