Browse » Home » Archive by category 'Resource'

关于layoutopt的介绍和使用方法

介绍
对于一款获得用户青睐的 手机软件,单从实现层面上来分析大体包括两个重要的因素:缜密的逻辑运算和人性化的GUI设计。自由开发者普遍存在身兼数职的情况,除了编写程序以外,还 需兼顾GUI设计。编写程序完全需要依靠过硬的功底,一些简单的优化工具并不能对整体逻辑运算产生较大的帮助,这也决定了自由开发者的背景大部分是程序员 出身。在编写GUI方面由于Android平台的GUI系统采用了XML layout模式,遵循固定的排列规则关联界面元素。对于欠缺GUI编写经验的程序员,依然可以简单的实现比较复杂的操作界面。出于功能上的需求XML Layout会变得越来越臃肿,这使得优化过程变得非常困难,例如:容器类型的转换会影响到所有相关联的子元素、反复调整Views元素而导致某些混乱的问题等,由于以上的问题有时可能不会影响到界面的正常使用,非常容易导致忽略了一些影响执行效率的缺陷。为此Android开发小组在SDK Tools Revision 3中提供了Layout Optimization工具,简称:Layoutopt。由于XML Layout具有严格的定义规则,所以这个工具可以自动帮助开发者发现一些较常规的缺陷。目前还没有将其整合到Eclipse的开发环境中,暂时需要通过Command line来执行(运行->cmd)。
使用方法
layoutopt <list of xml files or directories>
note: 有两种参数形式:第一种,可以将xml文件的full path做为参数,如果有多个xml文件,需要用空格将其分隔开。第二种,直接提供多个xml文件所在folder路径。
例子:
$ layoutopt res/layout-land
$ layoutopt res/layout/main.xml res/layout-land/main.xml

利用Intents实现软件的开放接口

今年九月份的统计数据显示,目前在Android Market中已经有超过10K的Softwares和Games提供给Android手机用户下载。一些曾经在IPhone APP Store创下辉煌战绩的Applications已经开始集体移植到这个拥有巨大潜力的平台。官方第二届Android Development Challenge(简称:ADC2)已经进入到了最后评审阶段,据称这次拥有大量惊奇创新的应用软件,AR会针对排名靠前的一些软件和游戏提供比较详细的技术剖析,希望大家保持关注。今天要说的内容与创新无关,主要是讲解如何将现有功能互补的软件通过Intents无 缝整合,使其最大限度的提高用户体验(不同的软件之间相互协调,不但可以达到优势互补的目的,而且通过相互间的合作可以在某个领域创造出相对完整的应用体 验)。

添加Click Listener的简便方法

对于任何一个开发者而言,常常需要为Views元素添加各种 “Listener”,响应用户的各种交互信息。下面的代码对于一般的开发者而言再熟悉不过了,是一种最原始的添加Click listener的方法:
findViewById(R.id.myButton).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Do stuff
}
});
下面这个方法较前一种稍微简单了一些,允许多个Buttons共享一个Listener。通过Switch控制对不同Button Click事件的响应方法:
View.OnClickListener handler = View.OnClickListener() {
public void onClick(View v) {
switch (v.getId()) {
[...]

RelativeLayout的缺陷得到修复

Android UI toolkit提供了多个Layout类,其中RelativeLayout的强大功能可以满足大多数情况下的需求,同时可以有效的组织和管理程序中包含 的Views。然而,由于存在一些缺陷限制,导致初学者经常会遇到某些奇怪的问题而影响正常的应用。基于这样的问题,Android开发小组重构了 RelativeLayout类。不仅仅除掉了一些零零散散的Bugs,最主要的是修复了一个比较严重的缺陷:Views必须以特定的顺序声明,否则无法 依据属性设置正确显示。下面根据一个具体的例子来了解实际情况:

代码中的RelateiveLayout包含有两个TextView和一个ImageView。从参 数设置来分析ImageView处在TextViews的左边,而两个TextViews则应该是靠左垂直排列。然而,以上的配置却无法在Android 1.5中得到正确的解析,结果如下所示:

问题最主要的原因是由于RelativeLayout处理Views关联是从当前向前查找已经解析的Views,而忽略后边的Views。例如,上个例子 中“band”的位置与“track”相关联,然而“track”是在“band”之后声明。在Android 1.5中,由于RelativeLayout存在缺陷,使得它无法处理这样的问题。值得庆幸的是目前已经修复了这个问题,依然是上边的代码,在 Android 1.6中完全按照正确的逻辑显示Views的位置:

为了帮助Android小组开发更加健壮的程序,提交你发现的缺陷或者Bugs。

给程序添加一个控制WIFI的Switcher

什么是WIFI?
Wi-Fi(发音为 /’waɪfaɪ/)是一個無線網路通信技術的品牌,由Wi-Fi聯盟(Wi-Fi Alliance)所持有,使用在经验证的基于IEEE 802.11标准的产品上,目的是改善基於IEEE 802.11標準的無線網路產品之間的互通性(查看完整内容:维基百科)。
現時一般人會把Wi-Fi及IEEE 802.11混為一談。甚至把Wi-Fi等同于無線互聯網。
Wi-Fi聯盟成立于1999年,當時的名稱叫做Wireless Ethernet Compatibility Alliance (WECA)。在2002年10月,正式改名為Wi-Fi Alliance
作为手机平台应用最广泛的一种无限网络协议(中国受限),其在地球上的覆盖面积达到了惊人的程度(结论凭主观判断,目前还没有确切的数据来源)。此前有文章讨论“如何检测当前区域内可用的网络资源?” ,下面将围绕网络应用的话题介绍与WIFI应用开发的一些方法。
首先,需要在Manifest中添加如下permissions:

其次,在调用的函数中声明一个WIFIManager实体:
private WifiManager wifiManager;

@Override
public void onCreate…
wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
然后通过WIFIManager所提供的方法处理各种与WIFI相关的应用:

检测当前网络信号质量:static int calculateSignalLevel(int rssi, int [...]

关于Zipalign的介绍和使用方法

Android 1.6 SDK中包含了一个用于优化APK的新工具zipalign。 它提高了优化后的Applications与Android系统的交互效率(俗话:“要致富先修路”,Android小组重新为Applications 与Android系统之间搭建了一条高速公路),从而可以使整个系统的运行速度有了较大的提升。Android小组强烈建议开发者在发布新Apps之前使 用zipalign优化工具,而且对于已经发布但不受限于系统版本的Apps,建议用优化后的APK替换现有的版本。在下面的内容中将从三个方面介绍 zipalign:

zipalign如何优化
如何使用zipalign
使用zipalign的理由

根据官方文档的描述,Android系统中Application的数据都保存在它的APK文件中,同时可以被多个进程访问,安装的过程包括如下几个步骤:

Installer通过每个apk的manifest文件获取与当前应用程序相关联的permissions信息
Home application读取当前APK的Name和Icon等信息。
System server将读取一些与Application运行相关信息,例如:获取和处理Application的notifications请求等。
最后,APK所包含的内容不仅限于当前Application所使用,而且可以被其它的Application调用,提高系统资源的可复用性。

zipalign优化的最根本目的是帮助操作系统更高效率的根据请求索引资源,将resource-handling code统一将Data structure alignment(数 据结构对齐标准:DSA)限定为4-byte boundaries。如果第一次接触有关Data structure alignment的内容,强烈建议搜索更多与其相关的内容来充分理解这样做的最终目的,这也是理解zipalign工作原理的关键。如果不采取对齐的标 准,处理器无法准确和快速的在内存地址中定位相关资源。
目前的系统中使用fallback mechanism机制处理那些没有应用DSA标准的应用程序,这的确大大的方便了普通开发者无需关注繁琐的内存操作问题。但是相反,对于这样的应用程序 将给普通用户带来一定的麻烦,不但影响程序的运行的效率,而且使系统的整体执行效率下降和占用大量不必要的内存资源,甚至消耗一定的电池资源 (battery life)。
在Android 1.6 SDK中提供了三种应用Align操作的方法:

使用ADT:

从 ADT 0.9.3版本开始,可以通过export wizard自动对发布的application packages执行align操作。设置方法:鼠标右键点击Project,然后选择”Android Tools” > “Export Signed Application Package…”。或者可以直接在AndroidManifest.xml中设置。

使用 Ant:

对于API Level 大于等于4的Application Packages可以直接通过Ant build script来Align优化。但对于API Level小于4的情况,只能采取手动Align优化。
默认下应用Ant build script运行Debug packages(API Level >= 4)时,将自动执行Align优化。
针对Release packages。当使用Ant build script执行Align优化时,首先需要拥有足够的信息来Sign packages。当完成Signing之后, 才能执行Align优化。通过官方文档了解如何Sign Packages。

手动执行Align优化:

利用tools文件夹下的zipalign工具。首先调出cmd命令行,然后执行:zipalign -v [...]

介绍Android Gestures的使用方法

开始讨论Gestures技术之前,首先回顾与触摸屏技术相关的历史。在1971年,Elographics公司(已经更名为:Elo TouchSystems)的创始人Sam Hurst博士作为肯塔基州立大学导师期间发明了第一块触摸传感器,取名为“Elograph”。与当今的技术相比,其并不算是真正意义上的Touch Screen,但却是触摸屏技术发展史上最重要的里程碑。直到1974年,一款真正意义上的触摸屏问世,实现了透明和显示图像的特性。在1977年,又创造出了five-wire resistive,这就是今天广泛被应用于许多领域的触摸屏核心技术,具有更加精确和稳定的特点。
目前Touch Screens技术在不同的应用领域发挥着重要的作用。尤其各种智能移动设备向着更薄、更轻、更强大的方向发展,这对于人机交互提出了更高的要求。凭借触摸屏技术,使用者将从繁琐的按键操作逐渐过渡为利用各种手势快速和准确的实现人机交互,比如轻轻触摸、拖拽、甩或者滑动等一系列的简单手势快速的实现一些常规的命令操作。在Android 1.6之前的版本中,需要开发者编写大量的代码才能实现某些更为复杂的Gestures功能。为了让Gestures技术可以被方便的嵌入到第三方软件中,Android 1.6 SDk中嵌入标准的Gestures API库(Package: android.gesture),包括了所有与Gesture技术相关的操作:存储、加载、创建新Gestures和识别等。接下来将通过具体的例子全面的介绍如何将Gestures技术加入到Application中。开始前请先下载实例的源码。
创建一个Gestures Library
Gestures Builder 在Android 1.6 SDK 中作为系统工具经Emulator启动时被默认加载。开发者可以直接通过Gestures Builder工具创建一批Gestures库,并添加到自己的程序中为用户提供可直接使用的Gestures行为。如果希望用户可以在程序中自定义 Gestures信息,也可以将Gestures Builder作为一个单独的模块整合到程序中,使用的方式与单独操作Gestures Builder工具完全一致。Gestures Builder工具的源码存放在Samples中,建议大家亲自尝试。使用Gestures Builder生成的gestures集合将自动存放在SD Card中。如果使用Emulator调试程序,需要在使用Gestures Builder之前确保当前有可用的虚拟SD Card映射。下边的截图表示当前已经添加三个gestures。

上边的图示中可以看到每个条目包含两个基本元素,gesture 2D信息和标签,标签在Application中起到索引的作用。在同一个Application中允许包含一个以上带有相同标签的集合,这样可以提高某 些指令被准确识别的几率。利用Gestures Builder添加或者编辑gestures,生成的最终文件存放在SD card中的 gestures目录。可以直接将这个目录下的gestures拷贝到Application的/res/raw中作为默认的gestures资源。
加载Gestures Library
根据前一节的了解,完全可以掌握利用Gestures Builder创建gestures的方法,并将生成的文件捆绑在自己的应用程序中,作为默认的gestures库。接下来了解如何在 Applicationg程序中加载库中的gestures资源(利用GestureLibraries类可以非常容易处理这个请求):

mLibrary = GestureLibraries.fromRawResource(this, R.raw.spells);
if (!mLibrary.load()) {
finish();
}

上边的代码实现了调用gestures前的准备工作。另外除了从本地raw中获取资源以外,也可以直接从SD Card中加载资源,特别针对允许用户自行创建gestures的应用程序,需要在程序中实现基于SD Card的读取和存储方法。由raw中读取的gestures仅具有可读属性,用户无法编辑默认捆绑在Application中的gestures资源。
下边的图标展示了Gesture Library的层级结构。

Gestures的识别方法

在应用程序中识别gestures包括绘制和识别两个部分。为了让用户可以直接在Applications表面绘制gestures,需要将下边的标签加入到当前窗口的XML Layout中。

由于GestureOverlayView类并不属于android.widget资源范畴,因此调用时必须提供完整名称(Botton或者其它的 Views只需要提供Short Name就可以直接被系统识别)。Gesture overlay相当于一块简单的绘画板,允许用户绘制各种gestures。Gesture overlay的显示属性可以根据应用程序的整体样式而制定合适的色彩和笔触宽度。利用Listener跟踪Gestures的不同行为,从而相应用户的 细微操作。其中OnGesturePerformedListener是最常用的方法,当用户完成一次Gesture绘制后,系统将自动运行这个 Listener中的代码。至此,完成了Gestures识别功能中的第一个步骤。

GestureOverlayView gestures [...]

介绍Text-To-Speech在Android中的用法

TextToSpeech简称 TTS,是Android 1.6版本中比较重要的新功能。将所指定的文本转成不同语言音频输出。它可以方便的嵌入到游戏或者应用程序中,增强用户体验。
在讲解TTS API和将这项功能应用到你的实际项目中的方法之前,先对这套TTS引擎有个初步的了解。

Dialog工具箱 – ProgressDialog

在此前的几个教程中引出过一些Dialog的使用方法,可从来没有系统全面的介绍Android平台上所有Dialog家族成员的情况(其实官方文档有相当明确的说明:参考1、参考2)。对于大部分人可以直接根据官方文档获得有关Dialog的使用方法,AR给出的有关Dialog参考教程可以作为额外的补充。
在这里为大家介绍ProgressDialog的使用方法:

1) 创建一个普通ProgressDialog(不带有ProgressBar)所必须的几个参数

Context: 指定当前Dialog的Container
Title:对话框标题
Message:对话框主体所显示的信息
Indeterminate:不确定性属性,这个属性对于ProgressDailog默认的转轮模式没有实际意义,默认下设置为true,它仅仅对带有ProgressBar的Dialog有作用。

2)以下两个为可选参数

Cancelable:增加一个可以Cancel当前Dialog的按钮,强制退出。
CancelListner:当前Dialog强制取消之后将会被执行,通常用来清理未完成的任务。

快速创建一个ProgressDialog的方法(代码片段):
private ProgressDialog dialog;
private Handler handler = new Handler() {
public void handleMessage(Message msg)
{
dialog.dismiss();
}
[...]

设置电脑共享Android网络服务

Android系统提供了共享网络资源的开关,就好像设置普通手机的蓝牙功能那样简单。只不过需要额外提供一根USB线,使手机与电脑相连接。本次测试的电脑操作系统为Ubuntu 9.04(其它版本的Linux也应该可以正常使用),手机是HTC Hero。

检测当前网络环境的方法

通过下列代码可以检测当前手机所在区域是否存在可用网络,在操作代码之前首先在Manifest中声明使用用户的 android.permission.ACCESS_NETWORK_STATE许可。

在Eclipse中Override基类行为的便捷方式

在Android开发过程中将会引用大量的标准库,同时也需要通过Override基类函数实现特定的应用需求,每一次都需要手动输入标准的函数调用,而这不但降低了编写效率,还容易发生拼写错误(让更多的脑资源去摩擦灵感,而不是去记住海量的函数名)。

应用Intent启动Map的几种可选参数

在Android中普遍通过URI传递信息,尤其是启动某个Activity时,需要提供Intent和URI参数。
在这个启动Map的例子中,可以通过参数的设定,实现根据需要显示地图信息。下边是一个显示默认地图信息的方法:参数为:["geo:"+latitude+","+longitude]
注:省略了对latitude 和 longtitude声明,并且要赋予相应的数值才能起作用。
String uri = “geo:”+ latitude + “,” + longitude;
startActivity(new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(uri)));
下边添加了Zoom参数:
String uri = “geo:”+ latitude + “,” + longitude + “q=my+street+address”;
startActivity(new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(uri)));
根据实际的需求选择合适的参数,下边是根据官方文档所提供的全部可选参数:

geo:latitude,longitude
geo:latitude,longitude?z=zoom
geo:0,0?q=my+street+address
geo:0,0?q=business+near+city

Zoom 代表地图的显示范围,其有多个不同的显示等级。例如: zoom = 1 显示整个地球,为2时显示差不多地图的四分之一范围(相当于国家级范围),并以此类推。Zoom Level设置的最大上限是23,其精度可以满足一般性民用需要了。
参考文档:

Invoking Google Application
URI: Current under development (External)

引用来源:androidsnippets.org

获取系统内Applications的基本信息

在这个例子中将展示如何获取Application的几个基本属性信息:名字、Package标签、版本信息和图标信息。
创建一个用于存储基本信息的Class:

class PInfo {
private String appname = “”;
private String pname = “”;
private String versionName = “”;
private int versionCode = 0;
private Drawable icon;
private void prettyPrint() {
[...]

介绍Android中与JSON相关的应用

JOSN的定义:
一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换。JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为。 – Json.org

应用TabHost优化Activity的GUI

智能移动设备的操作会受限于屏幕的尺寸。一些有关GUI优化技巧不提倡在单独的Activity中显示过多的元素,比较简单的解决办法是将其拆分成多个Activities,每个部分都单独调用。尽管这样解决了表面问题,但是却出现了额外的麻烦,尤其是针对某些内聚属性较高的操作,这样会降低操作的流畅性。
这里介绍一种比较“温馨”的解决方法,应用Widget.TabHost将多个Activities合并成一个Activity,这样就可以同时解决两个问题:

获取本地Music资源列表

这个例子包含了取得本地资源的方法,并且具有一定的代表性。其中包含了两个部分:
1)通过managedQuery()获取Cursor资源。
2)通过一个循环将Cursor中的资源添加到一个空的List中。

通过People provider以及URI获取本地通讯录资

当程序有必要调用本地通讯录时,可以通过Contacts.People方便的获取指定的资源。在Android平台中获取任何资源都需要借助相应的Content provider,而Content provider可能会同时具备多个Data sets(multiple tables),而每个set都有各自独立的对外公开的URI。

Notifications人性化的设计技巧 (一)

如何在结束Notifications时返回原来状态?
智能手机作为新时代的时间“吸血鬼”,时刻利用其“婀娜”的身段吸引我们的注意,而启到关键作用是接下来将要介绍的Notifications。无论这样的比喻是否恰当,首先需要明确一点,Notifications是人机之间非常重要的沟通渠道。例如:实时的提醒主人查看最新的Message、提醒电量不足、提示朋友或者家人的最新来电和股票又上了一个涨停板等。

浅谈Activity几种不同的启动方式

开发者在设计之初可以决定用户与应用程序的交互方式,其中包括如何选着程序启动入口以及Package中所包含的Activities。众所周知,应用程序是一系列有着特定功能的Activities组成,它们有自己的属性和行为。用户可以在Home中通过启动快捷方式将当前进程引入特定的Activites,或者可以在其它程序进程中启动外部的Activities。有的人会问,了解程序的启动方式有用吗?当然,了解不同的启动方式才能更好的根据需要设计Activities。

通过Resoruce的Name得到其标识符(Identifier)

利用几句简单的语句可以根据Resource的displayName获得系统中唯一的标识符,程序可以通过标识符获得Resource。
源代码:

1. int drawable_id = context.getResources().getIdentifier(“ball_red”, “drawable”, context.getPackageName());

文章来源 Androidsnippets.org

滑条自动跳转,显示控件的新条目(:listView)

经常需要用ListView或者其它显示大量Items的控件实时跟踪或者查看信息,并且希望最新的条目可以自动滚动到可视范围内。通过设置的控件transcriptMode属性可以将Android平台的控件(支持ScrollBar)自动滑动到最底部。
源代码:

文章来源 Androidsnippets.org

查看当前系统的存储资源

下边的源代码可以查看Internal和External的存储资源:

Internal总存储空间
Internal已用存储空间
External总存储空间
External已用存储空间
根据不同单位表示存储空间

源代码:

import java.io.File;

import android.os.Environment;
import android.os.StatFs;

public class MemoryStatus {

static final int ERROR = -1;

static public boolean externalMemoryAvailable() {
return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
}

static public long getAvailableInternalMemorySize() {
[...]

一些有关Intent异常的处理方法(no activity matches)

通常系统中的应用程序会借助于抛出Intent的方法,调用程序以外的资源来处理当前需求。这种方式可以提高系统资源利用率,而且当存在多个解决方法时,可以供用户作出最优化选择。然而,有一种特殊的情况却不容忽视,当前Intent无法在系统中获得任何可利用资源。这是一个必须要面对的客观情况,这里给出两种针对这种情况的解决方法。
第一种方法是提前预判,预判特定的Intent在当前系统的运行条件下是否可用,这样可以根据不同的系统配置提前屏蔽某些无法正常执行的功能或者引导用户通过某种方式提前为系统增加必要的运行条件,具体的可执行方法参照下面的代码:
/**
* Indicates whether the specified action can be used as an intent. This
* method queries the package manager for installed packages that can
* respond to an intent with the specified action. If no suitable package is
* found, this method returns false.
*
* @param context The application’s environment.
* @param action [...]

为Activity添加Intent Filter所要考虑的条件

新创建的Activities都具有某种目的性,那么是否需要为其明确定义Intent Filter呢?这要根据实际情况而定,如果其将来不会被其它App复用(re-using),无需为其定义任何Intent Filter。这样的Activity常常通过Android Launcher或者被同在一个Application域中的其它Activities启动。

关于Activity和Task的设计思路和方法

Activity和Task是Android Application Framework架构中最基础的应用,开发者必须清楚它们的用法和一些开发技巧。本文用大量的篇幅并通过引用实例的方式一步步深入全面讲解它们的基础原理(underlying principles)和架构(mechanisms),例如:Navigation、Multitasking、activity re-use、intents和activity stack等…大部分与其相关的应用模块。重点讲解开发过程中如何更准确的体现用户交互性的便捷和高效,同时也帮助分析Designers和Developers在开发期间所要面对的问题。

GestureDetector

探测当前用户各种不同的操作手势,通过 GestureDetector.OnGestureListener callback来获取当前被触发的操作手势(Single Tap Up、Show Press、Long Press、Scroll、Down、Fling)。
使用方法:
private GestureDetector mGestureDetector;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGestureDetector = new GestureDetector(this, new LearnGestureListener());
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mGestureDetector.onTouchEvent(event))
return true;
else
return false;
}
class [...]

限制URLConnection抓取本地Caches数据

当通过URL获取网络资源或者其它操作时,系统会寻找本地与其匹配的Caches记录,其结果可能造成程序无法直接获得最新数据,针对这样的问题可以设置URLConnection实例不读取本地Caches,以下是具体操作过程:

URL myURL = new URL(“http://www.yourURL.com/”);

/* Open a connection to that URL. */
URLConnection ucon = myURL.openConnection();
ucon.setUseCaches(false);
ucon.setRequestProperty(“Cache-Control”, “no-cache”);

XmlPullParser

XmlPullParser是Android平台标准的XML解析器,它的正确名字应该是“XML PULL PARSER”,这项技术来自一个开源的XML解析API项目XMLPULL。
它有两个比较重要的方法next()和nextToken(),官方文档的解释将next()作为处理高等级解析事件方法,而nextToken()则相反,专门处理 low level tokens。getEventType()可以返回当前时间处理的模式。
使用方法:
具体的 用法请参照官方文档,下边引用Almond Mendoza的一个例子作为比对:
public static void getAllXML(String url) throws
XmlPullParserException, IOException, URISyntaxException{
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser parser = factory.newPullParser();
parser.setInput(new InputStreamReader(getUrlData(url)));
XmlUtils.beginDocument(parser,”results”);
int eventType = parser.getEventType();
do{
XmlUtils.nextElement(parser);
parser.next();
eventType = parser.getEventType();
[...]

为程序添加自启动设置

在Windows平台下安装一些软件时,经常会遇到一些软件带有自启动设置。通常我会关掉这些功能,除非对于某些重要的程序有必要开启这项功能。在Android平台也可以方便的给程序添加自启动设置,下边给出了具体的实现方法:

线程间相互传递信息的方法

最重要的是理解实现线程间相互传递信息的目的,例如:有专门的线程来实时跟踪某些状态信息,当需要在某些Activity的线程(例如:Rendering Thread)中调用实时状态信息时,经常采用线程间相互共享数据方法。

关于Menu的两种设置方法

大部分的应用程序都包括两种人机互动方式,一种是直接通过GUI的Views,其可以满足大部分的交互操作。另外一种是应用Menu,当按下Menu按钮后,会弹出与当前活动状态下的应用程序相匹配的菜单。

应用AES技术加密/解密字符串

什么是AES?
引用中文维基百科的定义(浏览全文):
密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。

ACCESS_COARSE_LOCATION

ACCESS_COARSE_LOCATION访问CellID或WiFi,只要当前设备可以接收到基站的服务信号,便可获得位置信息。(COARSE英文原意为:粗略的,可以理解为这种方式获得的位置信息是相对粗略的数据)。
使用方法:
Manifest.xml中需要添加Permission:

在程序主体中调用方法:

LocationManager m_location_manager = (LocationManager) getSystemService(LOCATION_SERVICE);
Location lm = m_location_manager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Log.d(“log”,lm.toString());

说明:
getSystemService():通过这个方法来获取当前系统的服务信息,请参照这个列表了解有哪些服务信息可通过这个方法来获取。
LocationManager:用于管理当前空间位置信息类,可通过它的函数做有关位置信息的操作。
Location:是Android平台用于存储位置信息的载体。
特别提示:当前例子中通过GetLastKnowLocation方法获取最后一次通过基站定位的信息,如果需要获得最新信息,需要通过 requestLocationUpdates方法来强制获取。
其它帮助文档:
Developer Group中相关讨论:

COARSE_LOCATION相比FINE_LOCATION,如何权衡在什么情况下应用最合适的服务?
获取当前服务区国家代码。

实际项目可参照代码:

项目1
项目2

查看官方文档

通过Intent启动程序来查看文件

操作系统都有一套”血缘关系“列表,它用于标识所有可识别的类型文件的查看方式,例如:Mp3 ->Windows Media Player、Txt -> Notepad、JPG -> Picasa等等。相同的,在Android中也提供了这样一种机制,当用户想查看存储器中的某些文件时,将通过Intent找到启动这种类型文件的程序。
这里提供两个用于查看MP4和MP3的例子作为参考:

Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
File file = new File(“/sdcard/test.mp4″);
intent.setDataAndType(Uri.fromFile(file), “video/*”);
startActivity(intent);

Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
File file = new File(“/sdcard/test.mp3″);
intent.setDataAndType(Uri.fromFile(file), “audio/*”);
startActivity(intent);

文章来源 androidsnippets.org

如何读取程序的Log信息

如果需要程序实现这个功能,需要在Manifest中添加Permission:
android.permission.READ_LOGS
应用Runtime.getRuntime().exec(  parameters )启动Logcat,并返回一个Process对象,然后通过BufferedReader捕捉进程的数据流。
源代码:

Process mLogcatProc = null;
BufferedReader reader = null;
try
{
mLogcatProc = Runtime.getRuntime().exec(new String[]
{“logcat”, “-d”, “AndroidRuntime:E [Your Log Tag Here]:V *:S” });

reader = [...]

针对Debug/Relese两种模式合理设置Log的方法

为了发现程序的漏洞和将来可能会出现的隐患,或者跟踪程序中数据流的动态变化,开发者常常需要在Debug模式下通过设置断点或者向程序中添加Log输出语句来掌握整个程序或者某一个类的行为是否正确。然而添加“生成Log记录”的方法会在原有的基础上增加一些对最终用户毫无意义的代码,而这些仅供开发者有作用的代码有必要通过条件的限定来限制其针对不同模式下表现为不同的状态。下边列举在Android开发过程中,便于针对Debug/Relese两种模式合理设置Log的方法:

Debug version of Config.java:

package com.test;
public class Config {
public static final boolean D = true;
public static final boolean V = true;
}

Release version of Config.java:

package com.test;
public class Config {
public static final boolean D = false;
public static final boolean V = false;
}

The [...]

通过Socket实现文件传输(Java)

这个简单的例子将演示应用Java实现客户端与服务器端传输文件的方法。

应用Svn下载Code/Google开源项目源代码

一直以来都是在code.google.com中以网页形式查看某些Android开源项目的源代码,接受大家的取笑!经过本人对Source标签下内容的扫描,发现了一个巧妙的方法:通过SVN将开源代码完整的Export到本地(幸福感就像第一次品尝西瓜的味道)。
以Shelves开源项目为例:
可以在command-Line中直接输入以下命令
svn checkout http://shelves.googlecode.com/svn/trunk/ shelves-read-only
会出现以下内容

当看到Checked out revision **,就可以在相应的路径下找到完整的源代码

C:\Documents and Settings\esun\shelves-read-only\Shelves

下载Subversion Client

借助免费的Android Apps来赚钱

相信不少人有过啃着方便面埋头写代码的经历,特别针对当今这个经济不景气的大背景下,存在许许多多依然执着追求梦想的人。梦想指引了前进的方向,而现实中的前进步伐过于缓慢,前方那个若隐若现的目标渐渐变得模糊不清。停!今天先不讨论如何“料理后事”,身处洪水中的我们如何才能选择一块带来希望的浮木。开篇的废话是一些糟料,目的是感受极端恶劣的环境后,才更容易得到满足感,这样接下来所说的内容才可能有意义。

Android通过Socket(TCP/IP)与PC通讯

Android作为完全开源的手机平台,已经被非常多的开发者视作未来最有潜力的智能手机操作系统。而且短时间内已经有大量的第三方应用程序出现在Android Market供用户下载和使用,其中有一些程序增强了手机的应用功能,而另外一些会充分的发挥手机与其它电子设备的互动。今天将主要通过两个例子讲解如何实现Android与PC通讯。

应用HttpURLConnection读取InputStream信息

基于Android平台的应用开发大部分都会涉及到应用网络资源,然而通过指定的URL来读取数据可以算得上是最基本的应用。下面通过一个小例子演示如何实现这个方法。
注意:在调试代码之前,请首先确认AndroidManifest中已经添加了Internet permission标签。
源代码:

private void getConnStream(){

String result = null;
URL url = null;
try {
url = new URL(“http://www.androidres.com”);
} catch (MalformedURLException e) {
Log.e(“TestConnStream_URL”,e.getMessage());
}

if (url != null) {
try {
HttpURLConnection urlConn = (HttpURLConnection) url
.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
urlConn.getInputStream()));
String inputLine;

int lineCount = 0; // limit the lines for the example

[...]

Live Folder

Folder给我们的直观感觉是用来标识某一类文件的Category,且具备一些简单的属性,习惯了使用桌面操作系统会容易产生这样的条件反射。今天要介绍给大家的“Live Folder”,它是Android 1.5版本中一个新功能。根据官方的解释,Live Folder是一个可以实时显示信息的载体,而且可以从Home Screen直接快速启动。

API Level

应用1.5 “Cupcake” 最新版本的SDK创建第一个Package时会发现一个新属性 “minSdkVersion”,它的作用是存储一个Integer类型的标识。

Android中5个需要引起注意的Anti-Patterns

什么是Anti-Patterns?
业内有一本圣经级别的参考书《Design Pattern》,由四个“勤劳”的人共同完成,目前已经成为软件开发标准,称之为设计模式。与其相反,那些需要严禁避免的模式称之为Anti-Patterns。这篇文章将详细的介绍在Android开发过程中极易遇到的五个Anti-Patterns。

为程序增加Download activity模块

仅从标题还不足以概括本教程的核心内容,因为创建一个新的Activity,并整合到现有package中再简单不过了。说正题,Download Activity究竟是发挥什么作用?带着这个疑问先让我们来对比类似的应用,例如:某些桌面软件在运行初期需要配置程序的初始化配置,这包括从本地读取一些*.config的文件或者从网络服务器读取最新的数据。当我们运行一款游戏的时候,需要核实游戏用户身份,并通过存储在网络服务器中的数据对当前登录的用户完成必要的属性配置,同时游戏客户端也需要下载一些必要的文件来更新当前运行版本等等。返回到今天我们要介绍的主题,为软件增加一个Download Activity来使程序根据需要获取外部的必要资源。

了解 HS Widgets和AppWidget framework

前边有几篇针对Android 1.5 SDK “cupcake” 的讨论 (提前品尝 Android 1.5 SDK的滋味(CupCake), 第二代Android的“Cupcake计划”)。 Android开发小组前些天发布了”early-look” android 1.5 SDK,其目的是让大家预先了解即将在新版本中出现的新功能。而且前边也提到过,在今后会陆续针对这个版本的新功能做一些介绍,帮助大家能更好的利用Android小组成员智慧的“结晶”。
这次将与大家一同了解 AppWidget framework,这个令人期待的新平台内嵌架构可以允许开发者编写”widgets”。用户可以将它直接拖放到主窗口作为互动的接口,或者可以通过主窗口的Widget辅助某些APPs和后台服务程序的应用,例如:显示calendar中即将开始任务、查看后台正在播放的音乐信息等。

应用WebView加载html和本地图片资源

将Html代码通过String的形式被加载到WebView中,而且在Html中可以引用存储在设备中的图片资源等。这个方式可以非常方便的实现RichTextField的效果,尤其是对某些程序提供一些本地的简单文档时,非常方便。

获得当前Screen尺寸和Orientation mode

通过什么方式才能简单的得到当前Screen的尺寸和Orientation方向模式呢?
应用Android.view.display和WindowManager两个方法来完成题目中所提到的目的,以下是具体的代码:

Toast

OverView: 
这个类用来向用户显示一些简单的提醒信息。其效果类似于桌面软件中,当鼠标指针停留在某些Controls的时候弹出的 “ToolTip”。其特点浮动在当前Activity之上,但无法获得Fouce(当toast弹出的时候,用户依然可以在原来的Activity中输入某些信息)。查看官方文档
Usage Example:

当调节某些Controls的属性或者通过硬件按键操作设备的设置。
完成某些操作后,提醒用户当前操作的返回结果。
在游戏中设置一些简单操作的提示。

Coding Example:
仅仅显示文本:
 
Toast.makeText(this,”AndroidRes.com :Toast overview”, Toast.LENGTH_LONG).show();
显示Icon:
Toast toast = new Toast(this);
ImageView view = new ImageView(this);
view.setImageResource(R.drawable.icon);
toast.setView(view);
toast.show();
显示文本和Icon:
Toast toast = Toast.makeText(this, “lalalal”, Toast.LENGTH_LONG);
View textView = toast.getView();
LinearLayout lay = new LinearLayout(this);
lay.setOrientation(LinearLayout.HORIZONTAL);
ImageView view = new ImageView(this);
view.setImageResource(R.drawable.icon);
lay.addView(view);
lay.addView(textView);
toast.setView(lay);
toast.show();
 
ScreenShot:

 

较深入的分析Content Providers用法

之前的教程(Android平台上四种保存数据的方法)中有讨论过Android平台上四种存储数据的方法以及需要着重注意的特性。Android严格控制了数据的安全使用规范,为此建立在各种存储模块中的数据依然是私有于其相对应的程序。有简单提及应用Content Providers来实现多个Applications共享数据,并没有深入讲解具体的执行过程。这个教程的目的就是对这个话题的延展,一步一步了解使用Content Providers的方法和规范。

ManagedQuery()

用途:
根据指定的URI路径信息返回包含特定数据的Cursor对象,应用这个方法可以使Activity接管返回数据对象的生命周期。
参数:

URI:  Content Provider 需要返回的资源索引
Projection: 用于标识有哪些columns需要包含在返回数据中。
Selection: 作为查询符合条件的过滤参数,类似于SQL语句中Where之后的条件判断。
SelectionArgs: 同上。
SortOrder: 用于对返回信息进行排序。

下面是有关ContentResolver.query()和Activity.managedQuery()两个方法的区别:
To query a content provider, you can use either the ContentResolver.query() method or the Activity.managedQuery() method. Both methods take the same set of arguments, and both return a Cursor object. However, managedQuery() causes the activity to manage the life cycle of the Cursor. [...]

如何应用DDMS准确分析GC

GC是Garbage Collection的缩写,从名字可以直观的看出来是有关垃圾回收。不论程序规模的大小,伴随着程序的运行或多或少需要面对垃圾回收的问题。那么针对Android平台开发时,该如何高效准确的通过分析Garbage Collection信息来评估程序的表现力(性能)。
向大家介绍一个非常实用和有效的方法。DDMS大家应该不会陌生了,在使用Eclipse作为IDE来开发Android程序的时候会看到这个小东西,但这次给大家介绍的是另外一种途径来使用DDMS (Standalone version) – 独立的DDMS 工具。我们可以在SDK的Tools文件夹中看到DDMS.bat的可执行文件,运行后可以看到如下界面 – Dalvik Debug Monitor(它是伴随开发的最亲密战友)。

查看Garbage Collection信息的方法:
点击右侧Tabs Bar [Allocation Tracker] -> 运行 [Start Tracking] -> 保持程序运行一段时间后 ->执行[Get Allocations] 
凭借得到的Allocations信息可以通过Line Number准确找到哪里的代码出现了问题。
官方关于 Designing for Performance 的文档

应用MediaRecorder实现录制音频功能

首先了解MediaRecorder的基本情况,它的完整路径是 android.media.MediaRecorder。这个方法是用来录制音频和视频,通过下边这个比较“凌乱”的图标了解工作机制。

弹出预置信息的Email窗口

在Emulator中无法正常使用这个功能,将会弹出系统无法识别的信息“No application can perform this action”。请在Dev device 中运行。

final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);

/* Fill it with Data */
emailIntent.setType(“plain/text”);
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{“to@email.com”});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, “Subject”);
[...]

Android平台上四种保存数据的方法

对于我们所熟悉的大部分软件都有一个比较典型的特点,应用现有的数据根据不同的需求来得到相应的结果。例如,我们最常用的Office word、Excel、PowerPoint等办公软件,它们都是帮助我们完成某种特定的需求,同时由其所产生的数据或者文档又可以被其它软件所读取和做进一步的优化等等,在这个层面上可以看成是这些软件通过相同的文件标准来共享数据。但是对于Android最大的不同点在于,其平台上的应用软件所存储的数据或者文件是私有,仅仅可以通过它自身才可以访问其所包含的数据资源。

为程序添加版本自动更新功能

OverView:
程序通过后台每天检查是否有最新版本,如果需要更新当前版本,将弹出对话框让用户选择是否在当前通过Market来更新软件。
Knowledge Points:

SharedPreferences: 一个轻量级的存储方法,类似于经常使用的.ini文件,它也是通过检索关键字来取得相应的数值。之所以是成为轻量级,是因为它所能应用的数值类型有限,对于存储较大数值,效率相对较低。官方参考
System.currentTimeMillis:将当前时间以毫秒作为单位来表示,用于比较两个时间的先后顺序。(其数值表示从1970-01-01 00:00:00直到当前时间的总毫秒数)官方参考
通过网络来读取信息:在checkUpdate()方法中包含了通过制定的URL来读取网络资源。具体操作步骤,请参考源代码。
Runnable: 在其内部的Run()方法中实现所要执行的任何代码,当这个runnable interface被调用后可以视作为新的线程。

Source Code:

public class Test extends Activity {
private Handler mHandler;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.front);
mHandler = [...]

在Activity中通过URL来查看网页

这是一个非常简单的应用,仅仅是通过新的Intent调用Browser通过指定的地址来查看网页。

彻底关闭程序进程

最近有很多人反应在触发Back按钮后,程序没有完全退出,依然可以通过DDMS看到程序的进程。或者再次启动程序后跳出 “ The application stopped unexpectedly, try again ”。
解决以上问题的方法:
在onDestroy()方法中加入 Process.killProcess 彻底终止当前程序进程。
源代码 (Java):

protected void onDestroy()
{
super.onDestroy();

// After this is called, your app process is no longer available in DDMS
android.os.Process.killProcess(android.os.Process.myPid());
}

在Camera preview上叠加drawable元素

例子中将演示android.graphics.Canvas 和 android.hardware.Camera 的用法。
源代码 (Java):
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.ViewGroup.LayoutParams;
public class TestCameraOverlay extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
[...]