2009年4月29日

Android SDK1.5 R1发布

http://developer.android.com/sdk/RELEASENOTES.html

主要变化为:

1.SDK中包含了Android平台的多个版本(1.1,1.5),工具也升级了,这样可以发布应用到SDK支持的任何一个版本上。
2.引入了Android Virtual Devices(AVD),使之在模拟器上运行更接近于真机。每个AVD有自己的存储卡空间,使得更容易并发运行多个模拟器。
3.SDK支持add-on。这可以扩充SDK,使得可以访问多个外部Android库,能够在模拟器内运行定制的系统映像。(?)
4.新的ADT版本--0.9。增强了JUnit等有关功能
5.更容易的性能分析。
6.本地化资源管理更容易
7.新的"android"工具代替了activitycreator脚本

就API方面:

1.增加了AppWidget框架,这下widget也有了
2.增加了输入法框架
3.增加了语音识别框架
4.增强了多媒体框架:Audio的录/放API,Video的录像API,视频/照片的shareing intent等
5.增强了UI框架:
6.其他增强:重新设计的传感器API、WebView的增强等


从版本号也可看出,1.1-->1.5比起1.0-->1.1,功能增强还是较大的。但1.0-->1.1用了四个半月,1.1-->1.5只用了不到三个月。可看出Android逐步稳定,google要发力了!

WebView再探

WebView初探 了解到WebView的强大,。听说WebView对Javascript的支持也很强,想从网上找些例子,还很难找,最终从google老家找了一个Java和Javascript互调的例子 ,当时看了,下巴“咣当”就掉在地上了,太强了!这样也行?
整个Eclipse ADT工程例子中都有,这里重点分析一下代码:

public class WebViewDemo extends Activity {
private WebView mWebView;
private Handler mHandler = new Handler();

public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.webviewdemo);
mWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new Object() {
public void clickOnAndroid() {
mHandler.post(new Runnable() {
public void run() {
mWebView.loadUrl("javascript:wave()");
}
});
}
}, "demo");
mWebView.loadUrl("file:///android_asset/demo.html");
}
}

这里的重点是addJavascriptInterface(Object obj,String interfaceName)方法,该方法将一个java对象绑定到一个javascript对象中,javascript对象名就是 interfaceName,作用域是Global。这样初始化webview后,在webview加载的页面中就可以直接通过 javascript:window.demo访问到绑定的java对象了。来看看在html中是怎样调用的:

<html>
<script language="javascript">
function wave() {
document.getElementById("droid").src="android_waving.png";
}
</script>
<body>
<a onClick="window.demo.clickOnAndroid()">
<img id="droid" src="android_normal.png"/><br>
Click me!
</a>
</body>
</html>

这样在javascript中就可以调用java对象的clickOnAndroid()方法了,wave()方法是java中调用javascript的例子。

这里还有几个知识点:

1)为了让WebView从apk文件中加载assets,Android SDK提供了一个schema,前缀为"file:///android_asset/"。WebView遇到这样的schema,就去当前包中的 assets目录中找内容。如上面的"file:///android_asset/demo.html"

2)addJavascriptInterface方法中要绑定的Java对象及方法要运行另外的线程中,不能运行在构造他的线程中,这也是使用Handler的目的。

2009年4月28日

Blogspot中贴代码

原来一直对blogsport不了解哈。通过修改HTML模板也是可以贴代码地~~
方法参见Antlite的方法:用google prettify code给blogspot代码着色

如果是贴HTML,那就只好先通过http://www.elliotswan.com/postable/将特殊标签转义后再放在pre标签中了。

WebView初探

环境:Android SDK 1.1

Android手机中内置了一款高性能webkit内核浏览器,在SDK中封装成了WebView组件。
SDK的Dev Guide中有一个WebView的简单例子 ,寥寥几行代码就可以做一个自己的浏览器。
在实验时,有如下几个注意事项:
1.AndroidManifest.xml中必须使用许可"android.permission.INTERNET",否则会出Web page not available错误:

2.如果访问的页面中有Javascript,则webview必须设置支持Javascript:
webview.getSettings().setJavaScriptEnabled(true);
否则显示空白页面。
3.如果页面中链接,如果希望点击链接继续在当前browser中响应,而不是新开Android的系统browser中响应该链接,必须覆盖webview的WebViewClient对象:

mWebView.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});

上述方法告诉系统由我这个WebViewClient处理这个Intent,我来加载URL。点击一个链接的Intent是向上冒泡的,shouldOverrideUrlLoading方法return true表示我加载后这个Intent就消费了,不再向上冒泡了。
4.如果不做任何处理,在显示你的Brower UI时,点击系统“Back”键,整个Browser会作为一个整体“Back"到其他Activity中,而不是希望的在Browser的历史页面中 Back。如果希望实现在历史页面中Back,需要在当前Activity中处理并消费掉该Back事件:

public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}

Android以后会胜出其他Linux的手机平台

“伐木丁丁鸟鸣嘤嘤”写的几篇文章写的不错:

谈谈智能手机软件(1):概述

谈谈智能手机软件(2):Linux手机软件
Android能用Linux打败Linux手机吗?

介绍了几种手机上的Linux平台,增长了见识。

就我的感觉而言,毫无疑问Android以后会胜出其他Linux的手机平台,Google的江湖地位是其一,最重要的一点要看到,从iPhone起,智能手机OS/平台取胜的关键是应用!大量的应用!只有有了应用,才能够获得用户。你做的Linux平台可以模仿Window Mobile的UI,但应用呢?Office呢?这些是这些Linux平台的致命伤。

怎样才能有大量的应用?只有吸引大量的开发者进入这个平台/市场,才能繁荣这个平台上应用。现在那个平台上的开发人员多,开发应用的门槛低?Java!

2009年4月27日

apk的文件结构

apk实际是就是一个rar/zip,重命名rar后可以用winrar直接打开

apk文件一般包括如下内容:

META-INF -----没有签名的apk没有这个目录,该目录下包括签名信息
res -----资源文件目录,和工程中的一样
AndroidManifest.xml -----主描述文件,和工程中的一样
classes.dex -----所有的java类编译后的文件,是Dalvik VM需要的字节码
resources.arsc -----res目录的结构,重新组织过的二进制文件,格式未知

其中dex的格式参见:http://www.retrodev.com/android/dexformat.html
把这个搞清楚了,就可以反编译dex文件了:)

2009年4月26日

如何在Android开机时启动你的应用?

和监听SMS类似。在Android系统在启动完成后,会发出一个android.intent.action.BOOT_COMPLETED的Intent。配置你的Activity/Service接收他就行了

详细参见http://iame.javaeye.com/admin/blogs/375515

Android系统所有的Permission参见Reference中的android.Manifest.permission类的定义,看看他声明的所有primission,发现可以做不少事情,才会体会到Intent的强大。

Android上监听收到的SMS

Android SDK1.1 验证可行。

1.实现一个Receiver【收到的是PDU,需要从PDU中还原出SMSMessage】

public class SMSReceiver extends BroadcastReceiver {
public void onReceive(Context ctx, Intent intent) {
Log.d("SMSReceiver", "a message received");
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
for (SmsMessage message : messages) {
String strFrom = message.getDisplayOriginatingAddress();
String strMsg = message.getDisplayMessageBody();
Log.d("SMSReceiver","From:"+strFrom);
Log.d("SMSReceiver","Msg:"+strMsg);
}
}
}
}

2.配置应用permission,允许接收SMS。在AndroidManifest.xml中

<uses-permission android:name="android.permission.RECEIVE_SMS" />

3.配置Receiver的Intent-Filter,可以接收SMS。在AndroidManifest.xml中

<receiver android:name=".app.SMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>

关于监听发出的SMS参考:
http://blog.chinaunix.net/u/9577/showart_1850111.html

2009年4月23日

Google的核心技术

听了一遍李开复对云计算的演讲,提到Google的核心技术并非搜索,搜索只是在这个核心技术之上的一个应用。那他的核心技术是什么呢?

---基于普通pc的海量存储、海量计算能力,以及管理这些海量存储、计算能力的Cluster软件,所有这些构成的遍布世界的Google数据中心,这才是Google的核心技术,也是云计算的基础。具体的技术就是:MapReduceGFSBigTale

演讲中也提到的Google的海量服务器对电力的巨量消耗,导致了其他数据中心的倒闭(数据中心对托管的服务器是免收电费的)。从这个角度出发,不难理解Google的数据中心要建造水库旁边---水力发电成本更低,可以降低数据中心的运营成本。一篇文章中提到Google的一个数据中心的耗电量相当于一个8.2万人的城市的耗电量,看看他的照片吧。

这些数据中心之间的互联互通至关重要,为了保证数据中心的通讯畅通,Google甚至在美国建立了自己光纤骨干网。

APK的安装/卸载

制作好apk后(必须签名),通过adb install xx.apk后,
1)apk文件放在了/data/app/目录下
2)/data/system/packages.xml中增加了条记录
3)如果使用到了数据库,首次运行后/data/data下增加了个apk使用到的数据目录


卸载方式有如下几种:
1)优雅式:通过界面 settings-->applications-->manage applications-->找到应用-->application Info-->uninstall 就可以正常卸载应用了。
2)粗暴式 直接到/data/app目录下删除apk
adb shell
cd /data/app
rm xxx.apk

不推荐这种方式,只删除了apk,如果应用还有其他的目录,如数据库目录/data/data/xxx/databases/并没有清理干净,留有隐患。
3)隐藏式:
adb uninstall package-name (这个在adb的帮助文档中没有说明,但可以用)
什么,不知道package-name?看看你的AndroidManifest.xml中有个必须的属性就是package,它所指定的就是package-name。

PS. android中package和application不是一个东西,但也没有看到清楚的解释。能否这样理解:
package是物理概念,application是运行期的逻辑概念?

2009年4月22日

首个app engine应用发布成功

昨天看了doc/java/get start。试着例子写了一个app,今天发布成功:
http://hello2iame.appspot.com

其中共遇到如下问题:
1)Eclispse创建工程时,将整个工程的文本文件的编码设为UTF-8。xp下默认的GBK造成jsp和编译后的文件出错
2)Eclipse需要的JRE指向JDK,不能指向单纯的JRE。因为编译、发布需要javac
3)昨天通过Eclipse发布时,会提示Http 400错误:是由于Google App Engine for Java目前是early look,申请需要审核确认,今天收到帐号激活的邮件,就可以正常发布了。

gmail过滤器设置多个发件人

通过gmail订阅了很多newsletter,收到这些邮件想统一添加一个标签。可以使用gmail的过滤器设置,将多个发件人以||隔开,这样凡是位于from中的发件人的邮件收到后就可以自动打标签了

开张大吉

内容以技术、生活为主