andbook!
release.002
title_skateboard.png
Android Programming
with Tutorials from the anddev.org-Community.
written by Nicolas Gramlich
Check for the latest version on
http://andbook.anddev.org
Content
Foreword / How to read this doc ................................................. 5
Introduction................................................................................ 6
What is Android – a GPhone? ...................................................... 7
Android from above ........................................................................ 8
Openness ....................................................................................................... 8
All applications are created equal ................................................................. 9
Breaking down application boundaries ......................................................... 9
Fast & easy application development ........................................................... 9
The first weeks .............................................................................. 12
Dalvik.equals(Java) == false ........................................................... 13
Differences to a normal JavaVM ................................................................. 13
The Android Code Challenge ..................................................... 14
Creating Android Applications .................................................. 15
Anatomy of an Android Application ............................................... 15
Activity ......................................................................................................... 15
Intent Receiver ............................................................................................ 17
Service ......................................................................................................... 17
Content Provider ......................................................................................... 18
Android User Interfaces ................................................................. 19
Hierarchy of Screen Elements ..................................................................... 19
Comparing Android UI Elements to Swing UI Elements .............................. 22
The AndroidManifest.xml ......................................................... 23
General ......................................................................................... 24
<manifest> ................................................................................................... 25
<uses-permission> ....................................................................................... 25
<permission> ............................................................................................... 25
<instrumentation> ....................................................................................... 25
<application> ............................................................................................... 25
<meta-data> ................................................................................................ 27
<receiver> .................................................................................................... 27
<service> ...................................................................................................... 27
<provider> ................................................................................................... 28
Resources and the magic R.java ................................................ 29
Resources ..................................................................................... 29
List of resources ........................................................................................... 29
Using resources in code ............................................................................... 30
Referencing Resources ................................................................................ 31
Alternate Resources & Localization ................................................ 32
The magic R.java ........................................................................... 33
Hello World – The Android way. ................................................ 34
Installing the Android SDK ............................................................. 35
The Android Development Tools (ADT) ....................................................... 35
Installation done, let’s do some code ............................................. 37
Creating a new Android Project .................................................................. 37
Running your first application ..................................................................... 43
UIs the Java way ........................................................................... 45
System.out.println(…) ? ................................................................. 46
The LogCat ................................................................................................... 46
Using Intents ............................................................................ 49
Starting (Sub)Activities .................................................................. 49
Finding XML-defined Views in Java-Code .................................................... 52
Handling Clicks to Views .............................................................................. 53
Returning values from SubActivities ........................................................... 56
Passing Data to (Sub)Activities ...................................................... 58
Important Layouts and ViewGroups .......................................... 60
The RelativeLayout ........................................................................ 60
Bibliography ............................................................................. 61
Lost chapters ............................................................................ 62
The communities .......................................................................... 62
wink.gif
nuts.gif
explicit_code.png
Foreword / How to read this doc
前言/如何阅读本文档
This document was written for developers who have worked with Java.
before and want to start developing for the Android Platform. I tried to
make this as much “hands on” as possible, placing example codes
everywhere it fit. Also I tried to insert as many picture as possible,
because they liven up the learning process and relax the reader’s eyes.
这个文档是为那些做过java开发并且向继续在Android平台开发的开发者而写的。我把示例代码放在每一个适合的地方,便于让开发更加容易上手。此外,我也试着插入尽可能多的图片,因为图片能够使学习过程更加生动并且让读者能轻松的阅读。
But unfortunately coding is not everything; one has to learn about
some basic facts of the Android Platform to fully understand. That is
what is described on the first ~XXX pages. It is not necessary to read all
those describing pages, but it is preferable. You could decide to treat it as
a kind of reference. What you would read there is also explained when it
occurs during the “hands on”-process. So you could directly start at Hello
World – The Android Way.
但不幸的编码不是万能的,人们必须了解在Android平台的一些基本事实,以便于充分理解。这就是在最开始的部分要描述的内容。虽然不必要全部阅读这些描述部分,但是最好还是读一下。你可以决定将其视为一种参考,你在这些部分读到的内容也会在之后实际动手的过程中有相关解释。因此,你可以直接开始你的Android旅程的第一个程序Hello World。
All codes you see in this document (the whole workspace) will be
available on:
所有代码你在这个文档中看到的(整个工作区)将会在下面的网站中提供。
http://andbook.anddev.org/sources/
Have fun reading…
接下来,请尽情地在阅读中寻找你的快乐吧…
Introduction
简介
The Open Handset Alliance (1) released the Google Android SDK on
November 12th, 2007, having announced it about a week before. The
impact was unbelievable, almost every IT/programming-related news-
page dumped a news-post about the SDK release – the Google Groups (2)
was overwhelmed with over 2000 Messages within the first two Days.
The idea of the Android Platform was and still is amazing and is of course
attracting more and more programmers every day. Especially the open
architecture based on Intents and the possibility to replace even the
Home-application grant a really large amount of flexibility to the whole
platform.
一个星期前的报道宣称,开放手机联盟在2007年11月12日发布了Google Android SDK。其影响真是令人难以置信,几乎所有IT和编程有关的页面都开辟专栏报道有关的SDK发布信息,而Google的工作小组更是在前两天被超过2000条的邮件弄的不堪重负。Android平台的想法过去并且现在仍然是令人惊异的并且每天都吸引着越来越多的程序员的加入。尤其是基于意图和甚至可能替代桌面应用的开发架构保证了真正的整个平台的灵活性。
“Android – Imagination is the limit”1
Android-想象的极限。
1 Nicolas Gramlich – anddev.org Site-Admin
尼古拉格拉姆利克 - anddev.org网站管理员
What is Android – a GPhone?
什么是Android 是一个google的手机GPhone?
The weeks and months before Google released the Android SDK there
had been a lot of rumors about a so called GPhone. It was said to be a
mobile device manufactured by Google providing free communication by
showing context-sensitive advertisements to the user on the device
itself.
几个星期和几个月前谷歌发布了Android SDK,一直有很多传言这只是所谓的Gphone。据说这是一个由google生产的移动设备,它通过在设备上显示上下文敏感的广告给用户提供免费的通信。
Picture 1 Render of a potential GPhone
But on November 5th 2007 Andy Rubin2 announced:
但在2007年11月5日安迪Rubin2宣布:
“[The] Android [Platform] – is more significant and ambitious than a single
phone.”
“该机器人平台 比单一手机更有意义并且更有雄心。
Google within the Open Handset Alliance (OHA) delivers a complete set
of software for mobile devices: an operating system, middleware and key
mobile applications. What was released a week later was not a final
product, but a “First Look SDK” what many did not realize. Major news
sites grabbed the discomforts of some developers who said that Android
is full of bugs and heavily lacks of documentation. But the majority says
that Android is not buggier than any other software at this stage.
谷歌开放手机联盟提供了一套完整用于移动设备的软件:操作系统,中间件和关键
移动应用。发布一周之后仍然不是一个最终产品,但是,在“第一印象的SDK”里,很多人都没有意识到。主要的新闻网站抓住一些开发人员对 Android 充满了错误并且严重缺乏的文档的不适。但多数不说,Android是在现阶段比任何其他软件bug更少。
2 Andy Rubin – Google Director of Mobile Platforms
安迪鲁宾 - 谷歌移动平台总监
Android from above
Let’s take a look at what the OHA emphasizes on its Android Platform:
从上面的android介绍,让我们再看一看,开放手机联盟强调的Android平台的外观。
Openness
开放性
“Android was built from the ground-up to enable developers to create
compelling mobile applications that take full advantage of all a
handset has to offer. It is built to be truly open. For example, an
application could call upon any of the phone's core functionality such
as making calls, sending text messages, or using the camera, allowing
developers to create richer and more cohesive experiences for users.”
This is true, as a developer you can do everything, from sending short
messages with just 2 lines of code, up to replacing even the HOME-
Screen of your device. One could easily create a fully customized
operating system within weeks, providing no more of Google’s default
application to the user.
Android从建立就是为了让开发人员能够充分利用移动设备可以提供的功能实现一些应用。它将是一个真正开放的平台。例如,应用程序可以调用手机的核心功能,如任何打电话,发送短信,或使用相机时,允许开发者创建更丰富,更具亲和力的用户体验应用。这是真的,作为一个开发者你可以做一切事情。发送一行短消息仅仅只需要2行代码,甚至正取代设备桌面屏幕应用。人们可以在几周内很容易地创建一个完全个性化定制操作系统,没有谷歌提供的默认更多应用给用户。
“Android is built on the open Linux Kernel. Furthermore, it utilizes a
custom virtual machine that has been designed to optimize memory
and hardware resources in a mobile environment. Android will be
open source; it can be liberally extended to incorporate new cutting
edge technologies as they emerge. The platform will continue to
evolve as the developer community works together to build innovative
mobile applications.”
Android是建立在开放的Linux内核。此外,它采用一自定义虚拟机的设计以优化移动环境的内存和硬件资源。Android将会是开源的,它可以随着先进技术的出现进行自由扩展。该平台将会继续演变为一个一起工作的开发者社区,来创立更多新的移动应用。
Here Google is talking of the so called Dalvik virtual machine (DalvikVM),
which is a register based virtual machine, designed and written by Dan
Bornstein and some other Google engineers, to be an important part of
the Android platform. In the words “register based” we find the first
difference to normal Java virtual machines (JVM) which are stack based.
See the “Dalvik.equals(Java) == false”-chapter for more details on that
issue.
谷歌提出的是这里的所谓的Dalvik虚拟机(DalvikVM)是基于寄存器的虚拟机,它由丹伯恩斯坦和其他一些谷歌工程师设计并编码,是Android平台一个重要组成部分。在该平台基于寄存器的设计中,我们发现了它区别于java虚拟机的第一个不同点那就是java虚拟机是基于堆栈设计的。在文章的“Dalvik.equals(Java) == false”这章可以看到更加详细的信息。
All applications are created equal
所有应用都是平等的。
“Android does not differentiate between the phone's core applications
and third-party applications. They can all be built to have equal access
to a phone's capabilities providing users with a broad spectrum of
applications and services. With devices built on the Android Platform,
users will be able to fully tailor the phone to their interests. They can
swap out the phone's home screen, the style of the dialer, or any of
the applications. They can even instruct their phones to use their
favorite photo viewing application to handle the viewing of all
photos.”
“Android不会区分手机的核心应用和第三方应用程序。他们都可以有平等机会使用手机的功能来提供广泛的用户应用和服务。设备建立在Android的平台,用户将能够根据自己的喜好自由定制手机。他们可以掉了手机的主屏幕,该拨号器,或任何风格申请。他们甚至可以指导他们使用他们的手机
最喜欢的照片浏览应用程序来处理所有观看照片。”
Once again this is all true. Developers can 100% customize their Android-
Device. The Android System Communication is based on so called Intents,
which are more or less just a String (with some data attached) which
defines an action that needs to be handled. An example for this is:
”android.provider.Telephony.SMS_RECEIVED”
再一次说道,这是真正的,开发人员可以100%定制自己的Android装置。Android的系统通信时基于所谓的意图,意图或多或少只是一个字符串(有一些附加的数据),其中定义了一个动作,需要加以处理。一个很好的例子来说明就是:
android.provider.Telephony.SMS_RECEIVED
One can simply listen on that Intent by writing about 5 lines of
definitions. The system would then recognize that there is more than one
application that wants to handle that Intent and ask the user to choose
which one he or she would like to handle the Intent.
程序员可以通过5行定义就能监听这个意图。系统便会知道有超过一个应用程序需要处理的意图,并且要求用户选择一个应用程序来监听这个意图。
Breaking down application boundaries
打破应用程序之间的边界
“Android breaks down the barriers to building new and innovative
applications. For example, a developer can combine information from
the web with data on an individual's mobile phone - such as the user's
contacts, calendar, or geographic location - to provide a more relevant
user experience. With Android, a developer could build an application
that enables users to view the location of their friends and be alerted
when they are in the vicinity giving them a chance to connect.”
Android打破了创立新的和创新应用的障碍。例如,一个开发人员可以把从网页上获取的信息与个人用户的移动电话,比如联系人信息,日历或者地理位置信息结合起来,带来更为全,面的用户体验。使用Android,一个开发者可以建立一个应用程序,让用户查看他们的朋友的位置,并且当他们在附近时进行提醒让他们有机会进行连接。
Fast & easy application development
快捷,方便的应用开发
“Android provides access to a wide range of useful libraries and tools
that can be used to build rich applications. For example, Android
enables developers to obtain the location of the device, and allows
devices to communicate with one another enabling rich peer-to-peer
social applications. In addition, Android includes a full set of tools that
have been built from the ground up alongside the platform providing
developers with high productivity and deep insight into their
applications.”
Android 提供了丰富的有用的库和工具来建立丰富多彩的应用。
比如说,Android允许开发者能够获得设备的位置,并允许设备互相沟通以实现点对点的社会应用。此外,Android包括了一个完整的从底层构建的平台的工具集合,为开发者在他们的应用程序中提供更高的生产力和更深的眼界。
Since the Web 2.0 revolution, making content rich applications within
minutes is no more illusion. Android has brought developing to unknown
speeds. Let me provide an example:
Someday I stumbled over the Buzzword ‘DrivingDirections’ within the
Android-Documentation.
由于Web2.0的革命,在短时间内构建内容丰富的应用程序不再是幻想。Android给开发带来了无止尽的速度。有一天,我偶然在Android的文档里发现了一个时髦的术语'DrivingDirections。
Thought – done.
Picture 2 Google DrivingDirections implementation in Android
The development process of the application in the picture above took
about 1. hours! (Including the simple user interface and all images you
see). Could one create such a sophisticated application on any other
mobile-platform? – No.
该图中的应用程序开发过程需约1.5个小时(包括简单的用户界面和所有的你看到的图片)。
你能够在其他的移动平台上在这么短的时间内建立一个如此复杂的程序么?不可能吧。
Additionally this application could be enriched with the current GPS-
position of the device within a handful of code-lines.
此外,这个应用可以用当前设备的GPS来丰富,只需要简单地手写几行代码。
Google emphasizes Androids power of providing location-based-services.
Google Maps are so neat within Android as if it was just developed for
Android. One can integrate a fully zoom and drag enabled map by adding
just 3(!) characters in the Java-Code of the Android-Default-Application
and 3 lines of XML-Code.
Google 强调Android基于位置服务的权限。Google地图在Android里应用如此容易仿佛它就是为了Android而开发的。人们可以完全集成地图的变焦和拖动只用在默认应用里添加3行java代码和3行xml代码。
Other nice features that are easy to use with Android are Animations and
media-playback. Since version m5, the Android SDK contains functions
for straight and reverse GeoCoding and in addition to mp3, playback of:
ogg-Vorbis, MIDI and a bunch of other formats.
其他一些用Android容易实现的简单功能有动画和媒体播放,从M5版本开始,Android SDK包含了为正反地理编码和支持mp3播放 ogg-Vorbis,MIDI以及其他一系列播放格式。
The first weeks
最初的几周
Unfortunately the developers had to deal with a not fully implemented
preview-SDK (initially released build: ‘m3-rc20’), where even some key-
parts of the SDK were poorly documented. The lack of documentation
leaded to an explosion of the Android-Developer-Group within the
Google-Groups.
不幸的是,在最初的几周,开发者不得不面对没有完全实施的SDK前置版本(最初的释放版’m3-rc20’),在里面甚至一些SDK的关键部分描述的仍然不够广泛。缺少文档导致了Google团队里的Google开发者团队的爆炸。
Sooner or later one had to respect the statement from
Google:
“If it is not documented it is not meant to work yet.“
Many developers did not realize that fact that the first SDK released were
first-looks or developer-previews, where changes in the API had to be
awaited.
迟早,程序员必须面对Google造成的这一情景,如果没有充分的文档,是不是就意味着不要工作呢。
许多开发者还没有意识到这样的一个事实,第一个发布的sdk只是一个第一概貌或者说只是一个开发者的前序预览,还有大量API的改变需要我们等待。
Another annoying bug was the choppy emulator-sound, which was said
fixed with the release of build ‘m3-rc37a’ about 4 weeks later, but still
happened on some setups up to m5.
另一个恼人的错误是波涛汹涌的仿真器声,据说会在‘m3-rc37a’版本中也就是4周之后修正,但是在m5安装以后这种错误依然存在。
Dalvik.equals(Java) == false
Dalvik与java不相等
Why “Dalvik”? – The Dalvik virtual machine was named by Bornstein after
the fishing village of Dalvík in Eyjafj.reur (Iceland), where some of his
ancestors lived.
为什么叫Dalvik?- Dalvik虚拟机是由Bornstein根据冰岛的小渔村Dalvik村命名的,他的祖先曾居住在那里。
As you may have heard of, Dalvik is the name of Android's virtual
machine. It is an interpreter-only virtual machine that executes files in
the Dalvik Executable (*.dex) format, a format that is optimized for
efficient storage and memory-mappable execution. The virtual machine
is register-based, and it can run classes compiled by a Java language
compiler that have been transformed into its native format using the
included "dx" tool. The VM runs on top of a Linux 2.6 kernel, which it
relies on for underlying functionality (such as threading and low level
memory management). The DalvikVM was also optimized to be running
in multiple instances with a very low memory-footprint. Several VMs
protect ones application from being dragged down by another crashed
Application.
正如你已经听说过,Dalvik是Android的虚拟机。它是一个解释执行的虚拟机,它执行Dalvik可执行文件(*.dex)格式,一个对有效存储和内存填涂执行优化的格式。这个虚拟机是基于寄存器的,并且它可以执行由java语言编译的类。编译器包含“dx”工具已经被转化为本地格式。虚拟机在Linux 2.6版本内核上运行。它依靠一些基本的功能(比如线程和低水平内存管理)。这个Dalvik虚拟机还优化运行多个实例仅仅使用一个非常低的内存足迹。几个虚拟机保护一些应用防止他们被其他突然崩溃的应用所毁坏。
Differences to a normal JavaVM
与一个正常的java虚拟机之间的区别。
JavaVM’s one can find on almost any desktop computer nowadays are
Stack-based Virtual Machines (VM).The DalvikVM on the other hand is
register based, because on mobile-processors are optimized for register-
based execution. Also of register-based VMs allow faster execution times
at the expense of programs which are larger after compilation.
Java虚拟机可以在几乎任何桌面电脑现在是
基于堆栈的虚拟机(VM)中找到。在另一方面,Dalvik虚拟机基于寄存器的,因为在移动处理器上,采用继续寄存器的执行更加优化。同样,基于移动处理器虚拟机允许更快的执行时间,但是在编译之后程序也会更大。
The Android Code Challenge
Android的编程挑战
The Android Code Challenge (ADC) is an idea of Google to encourage the
community to build cool applications for the Android Platform by
rewarding the 50 most promising applications submitted.
Android编程挑战是Google为Android平台设立的为了鼓励开发人员一起来创新更酷平台的一个想法。
Picture 3 Android Developer Challenge Logo
Of course the Android Developers Challenge, with its overall 10 Million
Dollars of prize money, was attracting even more software-developers to
create a bunch of really useful applications. On the other side many
voices said, that this was no good choice from Google, because it would
lead to less code-sharing, as many would fear sharing their ideas with a
community, during the first important months after the SDK release.
当然,Android开发者大赛,因为有整整1千万美元的奖励,所以它吸引了更多软件开发人员去开发一些真正有用的应用程序。在另一方面,也有人说,这是因为Google没有更好的选择,因为这将会导致更少的代码共享,因为很多人担心一个开发者社区在第一个重要的SDK发布之后会分享他们的思想。
There were two Challenges planned:
计划中比赛分为两个阶段:
. Android Developer Challenge I: Submissions up to April 14, 2008
. Android Developer Challenge II: This part will launch after the
first handsets built on the platform become available in the
second half of 2008.
第一阶段:2008年3月14日之前,提交建议书。
第二阶段:在2008年下半年,需要提交能在平台上运行的应用。
In the Android Developer Challenge I, the 50 most promising entries
submitted by April 14 will each receive a $25,000 award to fund further
development. Those selected will then be eligible for even greater
recognition via ten $275,000 awards and ten $100,000 awards.
Applications submitted to the Challenge were supposed to be innovative
and demonstrate all the capabilities of the Android platform, like location
based services, media consumption, gaming and social networking, to
enrich mobile experience.
在第一阶段,50个最有希望的参赛方案将收到25000美元奖励资金作为进一步发展之用。这些被选中的作品将有可能获得更大的275000美元和10万美元的奖励。参加比赛的应用程序应该有创新性并且能够在Android平台上进行使用,比如基于未知的服务,媒体消费,游戏和社交,来获得丰富的移动体验。
Creating Android Applications
创建Android应用程序
In this chapter we will concentrate on the specialties in creating any
Android-Application.
在这章之中,我们将会集中在如何创建Android应用程序。
Anatomy of an Android Application
解剖Android应用
There are four building blocks to an Android application:
. Activity
. Intent Receiver
. Service
. Content Provider
Android应用有四个主要的构建块:
活动
意向收集机
服务
内容提供
Not every application needs to have all four, but your application will be
written with some combination of these.
不是每个应用程序都拥有以上四种模块,但是您的应用程序需要把其中的一些结合起来。
Once you have decided what components you need for your application,
you should list them in a file called AndroidManifest.xml. This is an
XML file where you declare the components of your application and what
their capabilities and requirements are. We will discuss soon, what the
AndroidManifest.xml is responsible for.
一旦决定您的应用程序需要哪些组件,您应该在一个名为 AndroidManifest.xml 的文件中对其进行列表声明。这是一个声明应用程序组件的功能和需求的XML文件。我们很快就会谈到,AndroidManifest.xml是做什么用的。
Activity
活动
Activities are the most common of the four Android building blocks. An
activity is usually a single screen in your application. Each activity is
implemented as a single class that extends the Activity base class. Your
class will display a user interface composed of Views and respond to
events.
活动4个Android构造块中最常见的,一个活动通常就是在应用程序中的一个单独的界面。
每一个活动都是作为一个独立的类从活动的基类扩展实现。您的类将显示由视图组成用户界面并且响应事件。
Most applications consist of multiple screens. For example, a text
messaging application might have one screen that shows a list of
contacts to send messages to, a second screen to write the message to
the chosen contact, and other screens to review old messages or change
settings. Each of these screens would be implemented as an activity.
Moving to another screen is accomplished by a starting a new activity. In
some cases an Activity may return a value to the previous activity - for example an activity that lets the user pick a photo would return the chosen photo to the caller.
When a new screen opens, the previous screen is paused and put onto a
history stack. The user can navigate backward through previously opened
screens in the history. Screens can also choose to be removed from the
history stack when it would be inappropriate for them to remain.
Android retains history stacks for each application launched from the
home screen.
大多数应用程序由多个页面组成。例如一个文本消息的应用程序不要有一个页面显示一列联系人来发送消息,第二个页面来写消息给选中的联系人,还有一个页面来查看旧的消息或者更改设置。每一个这样的页面都被新开的一个活动来完成。在一些情况下,一个活动可能返回一个值给前一个活动。比如说一个活动让用户选择一个照片,将会返回选定的照片给调用者。当一个新的页面打开时,前一页被暂停并且放入一个历史堆栈里。用户可以向后浏览历史记录中打开过的页面。当页面不适合继续留在堆栈中时,也可以从历史栈中删除。
Android保留从主屏幕起启动的所有程序在历史栈中。
Intent and Intent Filters
Intent和Intent筛选器
Android uses a special class called Intent to move from screen to
screen. Intent describe what an application wants done. The two most
important parts of the intent data structure are the action and the data
to act upon. Typical values for action are MAIN (the front door of the
application), VIEW, PICK, EDIT, etc. The data is expressed as a Uniform
Resource Indicator (URI). For example, to view a website in the browser,
you would create an Intent with the VIEW action and the data set to a
Website-URI.
Android用一个特殊类从一个页面跳转到另外一个页面。Intent描述了一个应用程序想要做的事。Intent数据结构最重要部分是动作和接下来要用到的数据。典型的动作值就是MAIN(应用程序入口函数),VIEW,PICK,EDIT等等。这些数据用统一资源标识符URI来表示。
new Intent(android.content.Intent.VIEW_ACTION,
ContentURI.create("http://anddev.org"));
There is a related class called an IntentFilter. While an intent is
effectively a request to do something, an intent filter is a description of
what intents an activity (or intent receiver, see below) is capable of
handling. An activity that is able to display contact information for a
person would publish an IntentFilter that said that it knows how to
handle the action VIEW when applied to data representing a person.
Activities publish their IntentFilters in the AndroidManifest.xml
file.
有一个相关的类叫做IntentFilter。当一个Intent发出一个请求来做某事时,一个
当一个Intent发出某种请求时,一个IntentFilter是描述什么是这个活动需要处理的意图。
一个能够对一个人显示联系人信息的活动会发布一个IntentFilter表示它知道如何处理当代表一个人的操作数据的VIEW的这个动作。活动把他们的IntentFilters声明在AndroidManifest.xml 文件中。
Navigating from screen to screen is accomplished by resolving intents. To
navigate forward, an activity calls startActivity(myIntent). The
system then looks at the intent filters for all installed applications and
picks the activity whose intent filters best matches myIntent. The new
activity is informed of the intent, which causes it to be launched. The
process of resolving intents happens at run time when startActivity is
called, which offers two key benefits:
从页面到页面的导航通过载入intents实现。为了载入下一个页面,一个活动调用函数startActivity(myIntent)。系统将会从相应的intent filters中找出安装了的应用并且选在这些intent filters最适合自己Intent的应用。这个新的活动在这个intent中声明并启动。解析intents的过程发生在startActivity调用时,提供了两个比较方便的应用:
. Activities can reuse functionality from other components simply
by making a request in the form of an Intent
. Activities can be replaced at any time by a new Activity with an
equivalent IntentFilter
活动可以重复使用其他组件的功能,仅需要通过请求其中的一个目的形式。
活动还可以在任何时候与一个等效的IntentFilter进行替换。
Intent Receiver
Intent接收器
You can use an IntentReceiver when you want code in your
application to execute in reaction to an external event, for example,
when the phone rings, or when the data network is available, or when it's
midnight. Intent receivers do not display a UI, although they may display
Notifications to alert the user if something interesting has
happened.
当你想要在你的应用程序中编码来对一个外部事件做出响应,可以用一个IntentReceiver 。比如,当电话铃响起时或者当数据网络可以使用时,或者当半夜来临时。虽然Intent receivers可以能显示通知提醒用户如果有一些用户感兴趣的事情发生了,但是它们不会显示一个用户界面。
Intent receivers are also registered in
AndroidManifest.xml, but you can also register them from code
using Context.registerReceiver(). Your application does not
have to be running for its intent receivers to be called; the system will
start your application, if necessary, when an intent receiver is triggered.
Applications can also send their own intent broadcasts to others with
Context.broadcastIntent().
Intent receivers也会在AndroidManifest.xml中进行声明,但是您也可以在代码中声明,调用语句Context.registerReceiver()。您的应用程序并不是必须运行所谓的intent receivers;系统将会启动您的应用程序,如果有必要的话,一个intent receiver会被触发。应用程序也可以发送给其他intent一个广播用Context.broadcastIntent()。
Service
服务
A Service is code that is long-lived and runs without a UI. A good
example of this is a media player playing songs from a play list. In a
media player application, there would probably be one or more activities
that allow the user to choose songs and start playing them. However, the
music playback itself should not be handled by an activity because the
user will expect the music to keep playing even after navigating to a new
screen.
服务时一种没有用户界面的长期后台运行的代码。一个服务的好的例子就是一个播放器通过一个播放列表播放歌曲。在一个媒体播放应用中,可能会有一个或者多个活动,让用户可以选择歌曲并且开始播放它们。但是,音乐播放本身不应该由活动处理因为用户可能在进入到一个新的页面后希望音乐继续运行。
In this case, the media player activity could start a service using
Context.startService() to run in the background to keep the
music going.
在这种情况下,媒体播放器活动可以开启一个服务调用Context.startService()在后台保证音乐的运行。
The system will then keep the music playback service
running until it has finished. (You can learn more about the priority given
to services in the system by reading Life Cycle of an Android Application.)
Note that you can connect to a service (and start it if it's not already
running) with the Context.bindService() method. When
connected to a service, you can communicate with it through an
interface exposed by the service. For the music service, this might allow
you to pause, rewind, etc.
系统会在后台保持这个音乐服务直到它播放完成。(您可以通过阅读Android应用程序的生命周期学习更多在系统中关于授予服务权限的知识)记住你可以连接到服务(并且启动它如果它没有运行)通过使用Context.bindService()方法。当连接到一个服务时,你可以同服务通过一个服务的接口进行通信。对于这个音乐服务来说,这可能可以让你暂停或者重播
Content Provider
Applications can store their data in files, a SQLite database, preferences
or any other mechanism that makes sense. A content provider, however,
is useful if you want your application's data to be shared with other
applications. A content provider is a class that implements a standard set
of methods to let other applications store and retrieve the type of data
that is handled by that content provider.
应用程序可以把他们的数据保存在文件,SQLite数据库,首选项或者其他有意义的机制里。如果您想要您的应用程序数据与其他应用程序共享,那么一个content provider无疑是有用的。一个content provider就是一个类,实现一组标准的方法使其他应用程序通过自己的content provider存储和检索自己的数据
Android User Interfaces
Android 用户界面
User Interfaces (UI) in Android can be built within two ways, by defining
XML-Code or by writing Java-Code. Defining the GUI structure in XML is
highly preferable, because as one knows from the Model-Viewer-Control
principle that the UI should always be separated from the program-logic.
Additionally adapting a program from one screen-resolution to another is
a lot easier.
Android的用户界面能够用两种方法构建,通过xml代码或者java代码。定义使用xml定义图形界面结构是优先考虑的,因为一个直到UI始终分为模型-界面-控制原则的程序员认为,用户界面应该与程序的逻辑结构分离。此外,程序从一个页面跳转到另外个页面适应分辨率变得更加容易。
Defining a UI in XML is very similar to creating a common HTML-
document, where you have i.e. such a simple file:
定义一个XML的用户界面跟定义一个普通的HTML文件类似,就像下面这个简单的文件一样:
<html>
<head>
<title>Page Title</title>
</head>
<body>
The content of the body element.
</body>
</html>
Just the same as in Android’s XML-Layouts. Everything is well structured
and can be expressed by tree-structures:
可以用树结构显示。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World"/>
</LinearLayout>
Hierarchy of Screen Elements
屏幕元素的层次结构
The basic functional unit of an Android application is the activity-an
object of the class android.app.Activity. An activity can do many
things, but by itself it does not have a presence on the screen. To give
your activity a screen presence and design its UI, you work with views
and viewgroups - basic units of user interface expression on the Android
platform.
Android应用程序的基本功能单位是一个活动对象的类android.app.Activity。
一个活动可以做很多事情,但是本身并无一个出现在屏幕上。要给您的活动一个屏幕展示并且设计它的用户界面,您需要使用用视图或者视图组-Android平台上基本的用户界面表达联合类型。
Views
视图
A view is an object extending the base class android.view.View. It's
a data structure whose properties store the layout and content for a
specific rectangular area of the screen. A View object handles measuring,
its layout, drawing, focus changes, scrolling, and key/gestures for the
screen area it represents.
视图是从基类android.view.View扩展出来的一个对象。其数据结构的属性里存储了在屏幕的一个特定举行区域的内容和风格。View对象处理屏幕区域上测量,去布局,绘图,焦点的更改,滚轮,按键手势等行为。
The View class serves as a base class for all widgets - a set of fully
implemented subclasses that draw interactive screen elements. Widgets
handle their own measuring and drawing, so you can use them to build
your UI more quickly. The list of widgets available includes i.e. TextView,
EditText, Button, RadioButton, Checkbox, ScrollView, …
视图类作为所有widgets元素的基类----一套完全实现子类并且绘制交互式屏幕元素。
widgets处理自己的测量和绘图,因此您可以使用它们更快地构建您的用户界面。可用的widgets控件包括TextView, EditText, Button, RadioButton, Checkbox, ScrollView,
Viewgroups
A viewgroup is an object of class android.view.Viewgroup. As its
name indicates, a viewgroup is a special type of view object whose
function is to contain and manage a subordinate set of views and other
viewgroups, Viewgroups let you add structure to your UI and build up
complex screen elements that can be addressed as a single entity.
The Viewgroup class serves as a base class for layouts - a set of fully
implemented subclasses that provide common types of screen layout.
The layouts give you a way to build a structure for a set of views.
viewgroup是从基类android.view. Viewgroup扩展出来的一个对象。正如其名字我们可以猜测,一个viewgroup就是一个特殊类型的view对象,功能就是包含和管理从属的views和viewgroups,Viewgroups可以将结构添加到您的用户界面,并建立可作为单个实体的复杂的屏幕元素。Viewgroup就用作是一个基类,用于布局-完全实现一般的屏幕布局的子类。这个布局给了你一种方法来建立一个view的结构。
A Tree-Structured UI
On the Android platform, you define an Activity's UI using a tree of view
and viewgroup nodes, as shown in the diagram below. The tree can be as
simple or complex as you need to make it, and you can build it up using
Android's set of predefined widgets and layouts or custom view types
that you create yourself.
在Android平台上,您定义一个活动的用户界面用棵树的view 和 viewgroup 节点,来在下面显示图标。树可以是简单或者复杂都由您自己决定,您可以用Android的预定义的widgets和布局或者您自己创建的自定义视图类来建立它。
Picture 4 Android UI - Tree structure
To attach the tree to the screen for rendering, your Activity calls its
setContentView() method and passes a reference to the root node
object. Once the Android system has the reference to the root node
object, it can work directly with the node to invalidate, measure, and
draw the tree. When your Activity becomes active and receives focus, the
system notifies your activity and requests the root node to measure and
draw the tree. The root node then requests that its child nodes draw
themselves - in turn, each viewgroup node in the tree is responsible for
drawing its direct children.
要在屏幕上呈现用户界面,您的活动需要调用setContentView()并传递一个参数到树根节点。
一旦Android系统找到了根节点,它就可以直接根据节点来测量并且绘制界面。当激活您的活动并接收焦点消息,系统将会通知您的活动并请求测量和绘制树的根节点。反过来,树中每一个树中的viewgroup节点又负责画出它的直接孩子。
As mentioned previously, each view group has the responsibility of
measuring its available space, laying out its children, and calling draw()
on each child to let it render itself. The children may request a size and
location in the parent, but the parent object has the final decision on
where how big each child can be.
正如前面提到的,每个view group将有责任测量其可用空间,画出其子级布局,对每一个子布局调用draw()。子布局可以在父布局里请求一个空间和位置,但是父对象有最终决定权决定每个孩子有多大。
Comparing Android UI Elements to Swing UI Elements
比较Android UI元素和Swing UI元素
As some developers who are reading this have probably coded UIs with
Swing before 。here are some similarities between Android and Swing.
因为一些开发者在读这篇文章的同时也与之前用过swing的UI进行编程。这里有一些在Android和Swing之间的相似之处。
. Activities in Android refers almost to a (J)Frame in Swing.
. Views in Android refers to (J)Components in Swing.
. TextViews in Android refers to a (J)Labels in Swing.
. EditTexts in Android refers to a (J)TextFields in Swing.
. Buttons in Android refers to a (J)Buttons in Swing.
Android中提到的Activity几乎相当于Swing里的Frame
Android中的Views相当Swing里的Components
Android中的TextViews相当于Swing里的Labels
Android中的EditTexts相当于Swing里的TextFields
Setting listeners to a View is nearly the same in Android than in Swing.
View里设置监听和Swing里的差不多
// Android
myView.setOnClickListener(new OnClickListener(){ ...
// Swing
myButton.addActionListener(new ActionListener() {...
The AndroidManifest.xml
The AndroidManifest.xml is a required file for every Android
application. It is located in the root folder of the application, and
describes global values for your package, including the application
components (activities, services, etc) that the package exposes to the
‘outer world’, what kind of data each of our Activities and co. can handle,
and how they can be launched.
AndroidManifest.xml是一个对于每一个Android 应用都需要的。它位于应用的根目录,并且说明了为你的软件的全球的一个值。包括应用程序组件(活动,服务等),包公开向外部世界包括了每一个活动处理什么数据并且他们应该怎么运行。
An important thing to mention of this file are its so called IntentFilters.
These filters describe where and when that activity can be started. When
an activity (or the operating system) wants to perform an action such as
open a Web page or open a contact picker screen, it creates an Intent
object.
所谓的IntentFilters是这个文件的一个重要的部分。这些filters描述了何时何地可以启动这一活动。当活动(或操作系统)想要执行一个操作比如打开一个web网页或者打开一个联系人选择屏幕,它就会创建一个intent对象。
This Intent-object can hold several information describing what
you want to do, what data is needed to accomplish it and other bits of
information. Android compares the information in an Intent object with
the intent filter exposed by every application and finds the activity most
appropriate to handle the data or action specified by the caller. If there it
more than one application capable of handling that Intent, the user gets
asked, which app he would prefer handling it.
此目的对象可以保存几个要做的信息描述,需要哪些数据完成它和其他一些信息。Android 将intent中的信息对象与每一个应用程序的intent filter进行比较并且找出最适合处理这个数据的程序,或者调用者定义的特殊动作来处理。如果有超过一个应用程序恩能够处理这个Intent,用户将会获取到一个询问,让他选择一个应用程序来处理。
Besides declaring your application's Activities, Content Providers,
Services, and Intent Receivers, you can also specify permissions in
AndroidManifest.xml.
除了声明您的应用程序的Activities, Content Providers, Services, 和 Intent Receivers,你也可以在AndroidManifest.xml定义权限。
app_added.png
General
A very simple AndroidManifest.xml looks like this:
一个非常简单的AndroidManifest.xml就像如下所述
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.anddev.android.hello_android">
<application android:icon="@drawable/icon">
<activity android:name=".Hello_Android"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
. Almost every AndroidManifest.xml (as well as many other
Android XML files) will include the namespace declaration
几乎每个AndroidManifest.xml都将会包括命名空间定义
(xmlns:android=http://schemas.android.com/apk/res/android)
in its first element. This makes a variety of standard Android
attributes available in the file, which will be used to supply most
of the data for elements in that file.
(xmlns:android=http://schemas.android.com/apk/res/android)
在它的第一个元素里。这定义了一系列在这个文件里可以使用的标准的Android属性,并且在这个文件中可以补充一些数据元素。
. Almost every manifest includes a single <application> tag,
which itself contains several tags describing Applications,
IntentReceivers, etc… that are available in this application.
. If you want to make an Activity launchable directly through the
user, you will need to make it support the MAIN action and
LAUNCHER category, what result as shown here:
几乎每个清单包含一个单一的 <application>标记,而其本身包含几个关键词描述 IntentReceivers,等可在的应用</application> 的此应用程序中,这个程序中可用的IntentReceivers等等。
如果你想让一个应用可以直接通过用户执行,你需要让它支持MAIN动作和LAUNCHER 类别,这将会有如下的结果:
Picture 5 Directly launchable Activity
What follows is a detailed list of the structure of an
AndroidManifest file, describing all available <tags>, with an
Example for each:
以下是一个AndroidManifest文件的详细的列表结构,描述了所有的可用的标签,每一个都由一个例子。
<manifest>
This is the root node of each AndroisManifest.xml. It contains the
package-attribute, which points to any package in out Activity. Other
Activities-path will base relative to its value.
这是每一个AndroisManifest.xml的根节点。它包含了报属性,任何包指向我们活动的点。其他活动路径以及基于它的值。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.anddev.android.smstretcher">
<uses-permission>
Describes a security permission, which your package must be
granted in order for it to operate correctly (i.e. when you want to send
SMS or use the Phone-Contacts). The permissions get granted by the user
during installation of your application. Quantity: 0+
描述您的软件包必须被授予的权限以保证它能正常运行(比如当您要发送短信或者使用联系人电话时)。这个权限由用户在安装应用的时候获取
<uses-permission android:name=" android.permission.RECEIVE_SMS"/>
<permission>
Declares a security permission that can be used to restrict which
applications can access components or features in your (or another)
package. Quantity: 0+
声明用于限制哪些应用程序可以访问您的组件或您的软件包中的功能的安全权限。
<instrumentation>
Declares the code of an instrumentation component that is
available to test the functionality of this or another package. See
Instrumentation for more details. Quantity: 0+
声明一个检测组件,这个组件可用于测试这个或另一个包的功能的代码。有关更多的详细信息请参见Instrumentation
<application>
Root element containing declarations of the application-level
components contained in the package. This element can also include
global and/or default attributes for the application, such as a label, icon,
theme, required permission, etc. Quantity: 0 or 1.
跟元素包含了一个包里面应用程序组件级别的声明。此元素还可以包含全局和应用程序的默认属性,比如一个标签,图标,主题以及默认属性所需要的权限。
<application android:icon="@drawable/icon">
exclamation.gif
You can place 0+of each of the following children:
<activity>
An Activity is the primary thing for an application to
interact with the user. The initial screen the user sees when
launching an application is an activity, and most other screens
they use will be implemented as separate activities declared with
additional activity tags.
活动是一个成语与用户进行交流的主要工具。当启动一个程序让用户看到初始化界面的是一个活动,并且大多数其他他们用到的作为单独活动的界面将会并使用其他活动的标签。
<activity android:name=".Welcome" android:label="@string/app_name">
Note: Every Activity must have an <activity> tag in the
manifest whether it is exposed to the world or intended for use
only within its own package. If an Activity has no matching tag
in the manifest, you won't be able to launch it.
Optionally, to support late runtime lookup, you can
include 1+ <intent-filter> elements to describe the actions the
activity supports.
每个活动不管它是向全世界发布的还是只在自己包中使用的都必须在manifest文件中有一个<activity>标签
<intent-filter>
Declares what kind of Intents a component
supports. In addition to the various kinds of values that
can be specified under this element, attributes can be
given here to supply a unique label, icon, and other
information for the action being described.
声明一个组件支持的Intents种类。为了扩展这个元素里的各种值和属性可以提供一个单独的标签图标和其他描述的动作信息。
<intent-filter>
<action>
An action-type that the component
supports. Example:
<action android:name="android.intent.action.MAIN" />
<category>
A category-type that the component
supports. Example:
<category android:name="android.intent.category.LAUNCHER" />
<data>
An MIME type, URI scheme, URI
authority, or URI path that the component
supports.
You can also associate 1+ pieces of meta-
data with your activity:
一个MIME 类型URI 方案,URI 机构或组件支持的 URI 路径。
<meta-data>
Adds a new piece of meta data to the activity,
which clients can retrieve through
ComponentInfo.metaData.
<receiver>
An IntentReceiver allows an application to be told
about changes to data or actions that happen, even if it is not
currently running. As with the activity tag, you can optionally
include 1+ <intent-filter> elements that the receiver
supports or <meta-data> values, just all the same as with
<activity>.
一个 IntentReceiver 允许讲数据或执行,操作的更改,即使它当前没有运行。
与该活动标记一样,您可以有多个<intent-filter>元素并且这个receiver支持<meta-data>值跟<activity>标签一样
<receiver android:name=".SMSReceiver">
<service>
A Service is a component that can run in the background
for an arbitrary amount of time. As with the activity tag, you can
optionally include one or more <intent-filter> elements that the
service supports or <meta-data> values; see the activity's
<intent-filter> and <meta-data> descriptions for more
information.
一个服务是一个能在后门运行任意长时间的组件。与该活动的标记一样还可以包含一个或者多个<intent-filter>元素,该服务支持<meta-data>值;请参阅活动的<intent-filter>和<meta-data>描述以获得更多信息。
<provider>
A ContentProvider is a component that manages
persistent data and publishes it for access by other applications.
You can also optionally attach one or more <meta-data> values,
as described in the activity's <meta-data> description.
Of course all <tags> have to be </closed> or closed
一个ContentProvider是一个持久性的数据管理组件,它为其他应用程序提供数据访问,可以在该活动的<meta-data>中声明它。当然所有的标签都得闭合。
<directly/>.
Resources and the magic R.java
资源和神奇的R.java文件
The resources of a project and the R.java are very close related.
一个项目的资源和R.java有着非常密切的联系。
Resources
资源
Resources are external files (non-code files) that are used by your code
and compiled into your application at build time. Android supports a
number of different kinds of resource files, including XML, PNG, and JPEG
files. The XML files have very different formats depending on what they
describe.
Resources are externalized from source code, and XML files are compiled
into a binary, fast loading format for efficiency reasons. Strings are
compressed into a more efficient storage form.
资源是外部文件(非代码文件)
List of resources
资源列表
Resource-types and where to place them:
资源的种类以及放置它们的地方
. layout-files . “/res/layout/”
. images . “/res/drawable/”
. animations . “/res/anim/”
. styles, strings and arrays . “/res/values/”
o Names do not have to be exactly like:
o ‘arrays.xml’ to define arrays
o ‘colors.xml’ to define colors
. #RGB, #ARGB, #RRGGBB, #AARRGGBB
o ‘dimens.xml’ to define dimensions
o ‘strings.xml’ to define strings
o ‘styles.xml’ to define style objects
. raw files like mp3s or videos . “/res/raw/”
Using resources in code
在代码中使用资源
Using resources in code is just a matter of knowing the full resource ID
and what type of object your resource has been compiled into. Here is
the syntax for referring to a resource:
在代码中使用的资源只是知道完整的资源ID和您的已经被编译的资源类型对象。
以下就是调用某个资源的语法。
R.resource_type.resource_name
or
android.R.resource_type.resource_name
Where resource_type is the R subclass that holds a specific type of
resource.resource_name is the name attribute for resources
defined in XML files, or the file name (without the extension) for
resources defined by other file types.
其中resource_type是包含特定类型的resource.resource_name的一个R子类
Each type of resource will be added
to a specific R subclass, depending on the type of resource it is.
每种类型的资源将被添加到一个特定 R 子类,这取决于它是的资源的类型。
Resources compiled by your own application can be referred to without a
package name (simply as R.resource_type.resource_name).
编译您自己的应用可以不需要包名(只需要用R.resource_type.resource_name)
Android contains a number of standard resources, such as screen styles
and button backgrounds. To refer to these in code, you must qualify
them with android, as for example in:
Abdroid包含了许多标准的资源如屏幕样式和背景按钮。这些代码中引用,你必须用android限定它们,就像下面的例子中一样:
android.R.drawable.button_background.
Referencing Resources
A value supplied in an attribute (or resource) can also be a reference to
another resource. This is often used in layout files to supply strings (so
they can be localized) and images (which exist in another file), though a
reference can be any resource type including colors and integers.
For example, if we have color resources, we can write a layout file that
sets the text color size to be the value contained in one of those
resources:
属性(或者资源)中提供的值,也可以是另一资源的引用。虽然引用可以是任何资源类型,包括颜色和整数,但这通常用于布局文件来提供字符串(因此字符串可以本地化)和图片(在其他文件中的图片)。举个例子,比如我们有颜色的资源,我们可以写一个布局能够设置文本颜色的大小值作为包含在资源文件里的值。
<EditText
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="@color/opaque_red"
android:text="Hello, World!" />
Note here the use of the '@' prefix to introduce a resource reference --
the text following that is the name of a resource in the form of
@[package:]type/name. In this case we didn't need to specify the
package because we are referencing a resource in our own package. To
reference a system resource, you would need to write:
注意这里的@前缀,引入一个资源引用--之后的文字就是资源的名字,用这样的格式@[package:]type/name.在这种情况下,因为我们在自己包中引用的资源,所以我们不需要指定包。如果要引用系统资源,您需要写如下代码。
<EditText
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="@android:color/opaque_red"
android:text="Hello, World!" />
As another example, you should always use resource references when
supplying strings in a layout file so that they can be localized:
又如,您可以在布局文件里提供字符串时引用资源文件以保证其始终本地化:
<EditText
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="@android:color/opaque_red"
android:text="@string/hello_world" />
Alternate Resources & Localization
备用资源与本地化
Alternate Resources and Localization is a very useful issue you will love
Android for. Expect you would have to design a GUI that fits landscape
and portrait screen-orientation well at the same time – that is almost
impossible.
备用资源与本地化是一个非常有用的问题,您将会因此喜欢用Android来实现。如果您要想同时设计一个适合横向和纵向的图形界面,那几乎是不可能的。
You can supply different resources for your application according to the
UI language or hardware configuration of the device. Note that
Even though you can include different string, layout, and all other
resources, the SDK does not expose methods to let you specify which
alternate resource set to be used. Android detects the proper set for the
hardware and location, and loads them as appropriate.
您可以根据程序语言和设备的硬件配置为您的应用程序提供不同的资源。
请注意,尽管您可以包含不同的字符串,布局和所有其他的资源,SDK也不公开制定设置您的备用资源的方法。Android检测适合硬件和地区的资源集合,并且更加适合的加载它们。
Only the user can select alternate language settings using the settings panel on the device.
To include alternate resources, create parallel resource folders with
dash-separated qualifiers appended to the folder names, indicating the
configuration it applies to (language, screen orientation, dpi, resolution,
…).
只有用户可以选择使用设备上的设备面板来设置语言。若要包括备用资源,创建用下划线分隔限定符号命名名称的并行资源文件夹,使用与设置指示各种配置(包括语言,屏幕方向,dpi分辨率)。
For example, here is a project differs between differs between English
and German value-resources (here only strings):
比如,以下就是一个在英文和德文文件下的资源摆放(这仅仅指示字符串)
MyApp/
res/
values-en/
strings.xml
values-de/
strings.xml
Android supports several types of qualifiers, with various values for each.
Append these to the end of the resource folder name, separated by
dashes. You can add multiple qualifiers to each folder name, but they
must appear in the order they are listed here. For example, a folder
containing drawable resources for a fully specified configuration would
look like:
Android 支持集中类型的定义限定符,每一种使用不同的资源。将这些添加到文件夹名结尾,用短划线分隔开。您可以将多个限定符添加到每个文件夹名,但是它们必须按它们列出的顺序出现。比如文件夹包含drawable资源的完全指定配置如下所示:
MyApp/
res/
drawable-en-rUS-port-92dpi-finger-keyshidden-12key-dpad-480x320/
More typically, you will only specify a few specific configuration options
that a resource is defined for. You may drop any of the values from the
complete list, as long as the remaining values are still in the same order:
一般,将仅指定一个资源定义的几个特殊的配置选项。您可以从完整列表中删除任何值,只要剩下的值依然是按顺序的:
MyApp/
res/
drawable-en-rUS-finger/
drawable-port/
drawable-port-160dpi/
drawable-qwerty/
Android will pick which of the various underlying resource files fits best
during runtime, depending on the current device-configuration.
Android将会在运行时选取其中的各种基础资源文件,具体取决于当前最适合的设备配置
The magic R.java
神奇的R.java
A project's R.java is an auto-generated file indexing all the resources of
your project. You use this class in your source code as a sort of short-
hand way to refer to resources you've included in your project. This is
particularly powerful with the code-completion features of IDEs like
Eclipse because it lets you quickly and interactively locate the specific
reference you're looking for. Additionally you gain compile-time safety that the resource you want to use really exists.
项目的R.java文件是一个自动生成的编制索引的所有资源的文件。您在您的源代码中使用这些类来声明您在工程中要使用的资源。使用强大的有代码完成功能的比如Eclipse
将更加容易的实现,因为它让您更快更准确地定位您要寻找的资源。
另外您可以让您的资源文件在编译时更加安全。
Hello World – The Android way.
In this very first tutorial one will learn how to create an Android
Application using a XML layout. Keep in mind that, using XML-Layouts is
highly preferable!
What it will finally look like:
Picture 6 First Android Application - Final look (sdk-version: m5)
But before all that one needs to download and install the Android SDK…
Installing the Android SDK
The latest Android SDK for Windows, Mac and Linux can always be
obtained from the following URI:
http://code.google.com/android/download.html
It only needs to be downloaded and unzipped to your preferred hdd-
location.
The Android Development Tools (ADT)
Android provides an Eclipse plugin called ‘ADT’ to make programming
and debugging easier.
The ADT provides easy access to the LogCat, the Android-
Manifest/Resource-Editor, File, Thread, and Heap Control, incoming
call/sms simulation, etc… – since SDK-version m5 all for multiple
emulator instances at the same time.
Installing the Eclipse Plugin (ADT)
To download and install the ADT plugin, follow the steps Google provides
to developers:
1. Start Eclipse, then select Help > Software Updates > Find and
Install....
2. In the dialog that appears, select Search for new features to
install and press Next.
3. Press New Remote Site.
4. In the resulting dialog box, enter a name for the remote site (e.g.
Android Plugin) and enter this as its URL:
https://dl-ssl.google.com/android/eclipse/
Press OK.
5. You should now see the new site added to the search list (and
checked). Press Finish.
6. In the subsequent Search Results dialog box, select the checkbox
for Android Plugin > Developer Tools. This will check both
features: "Android Developer Tools", and "Android Editors". The
Android Editors feature is optional, but recommended. If you
choose to install it, you need the WST plugin mentioned earlier in
this page.
Now press Next.
7. Read the license agreement and then select Accept terms of the
license agreement, if appropriate. Press Next.
8. Press Finish.
9. The ADT plugin is not signed; you can accept the installation
anyway by pressing Install All.
10. Restart Eclipse.
11. After restart, update your Eclipse preferences to point to the
SDK directory:
a. Select Window > Preferences... to open the Preferences
panel. (Mac OS X: Eclipse > Preferences)
b. Select Android from the left panel.
c. For the SDK Location in the main panel, press Browse...
and locate the SDK directory.
d. Press Apply, then OK.
Updating the ADT Plugin
Updating the ADT Plugin follows the standard procedure of upgrading a
common Eclipse plugin:
1. Select Help > Software Updates > Find and Install....
2. Select Search for updates of the currently installed features and
press Finish.
3. If any update for ADT is available, select and install.
Installation done, let’s do some code
Before we can start coding we obviously have to create a new Android
Project.
Creating a new Android Project
1. The first thing that needs to be for every Android Application is
to create a new Android Project. To do that, simply open
the Package Exlporer in Eclipse right-click on some blank space
and choose:
New > Project…
Picture 7 First Android Application - Step 1
2. Select:
Android > Android Project
Picture 8 First Android Application - Step 2
3. Fill out the form with values fitting your applications purpose...
Picture 9 First Android Application - Step 3
4. This are all the files for your first Android-Application (don't
panic, mostly all of them are resource-files)
Picture 10 First Android Application - Step 4
Huh, what are all that files supposed to do ?
As you now have created your first Android Project you will see a bunch
of files appear in that new project.
The Main Activity
You’ll see some default code like the following, when you now navigate
to:
“/src/your_package_Structure/Hello_Android.java”
package org.anddev.android.Hello_Android;
import android.app.Activity;
import android.os.Bundle;
public class Hello_Android extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
/* Make this application use
* the main.xml-layout-file. */
this.setContentView(R.layout.main);
}
}
run.png
We could now immediately our Application but let me explain of the
other files too.
The XML-Layout (main.xml)
The ADT created this very basic Activity for you. As we know Activities
are somehow like JFrames in Swing. In Android we extend from Activity
and need to overwrite a single function, called onCreate(…). Within
this function we have to call i.e.
setContentView(R.layout.main)which makes our Activity use
the main.xml which was also created by the ADT:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, Hello_Android"/>
</LinearLayout>
We have a ‘fullscreen’ vertical LinearLayout, that contains a single
TextView showing a pre-defined String.
The AndroidManifest.xml
So let’s face the AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.anddev.android.hello_android">
<application android:icon="@drawable/icon">
<activity android:name=".Hello_Android"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Let’s split that up…
Every xml-file starts with the following line, it defines the xml-version and
encoding-type of the xml-text. Just copy-paste it to every new file.
<?xml version="1.0" encoding="utf-8"?>
As we know the outermost tag in every xml-file should contain this
attribute:
xmlns:android="http://schemas.android.com/apk/res/android"
Because it makes a variety of general Android attributes available in the
file.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.anddev.android.hello_android">
.....
</manifest>
The <application> tag is the root element containing declarations of
all application-level components contained in the package. This element
can also include global and/or default attributes for the application, such
as a label, icon, theme, required permission, etc…
Here we define just the icon, by making a ‘@-refer’ to a image placed
under "/res/drawable/".
<application android:icon="@drawable/icon">
.....
</application>
Inside of the <application> tag we need to define all
Activities/IntentReceivers that need to be started via Intents. In this case
we have only one simple Activity.
<activity android:name=".Hello_Android"
android:label="@string/app_name">
.....
</activity>
exclamation.gif
You probably have recognizes that the package-attribute from the
<manifest> tag together with the android:name attribute from
the <activity> tag always result in the complete package-path to the
Activity described.
The innermost tag is the <intent-filter> tag which defines on
which Intents we want to listen. Here we want the Hello_Android Activity
launchable from within the emulator by clicking the icon (that was
defined in the <application> tag).
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
Note: The debugging-process with a Android Application is
exactly the same than with a normal Java Application.
run.png
run.png
open_run_dialog.png
run_dialog.png
Running your first application
Now we need to create a ‘-Configuration’. Open the -DropDown in
the Eclipses upper menu and Click "Open Run Dialog..."
Picture 11 Opening the run-dialog
Picture 12 Creating a run-configuration
run.png
app_added.png
From now on you can run your application by clicking the button.
Having done that you’ll see this:
Picture 13 First Android Application - The result (sdk-version m5)
After the first deploy you can also see your application being listed in the
quick-menu, displayed with the default icon:
Picture 14 First Android Application - Added to QuickMenu (sdk-version m5)
UIs the Java way
The same thing as we have just done with XML-Code can be achieved by
hacking some lines of Java-Code.
Remember how we set our main.xml as the ContentView in the xml-
example. We accomplished that by doing the following:
/* Make this application use
* the main.xml-layout-file. */
this.setContentView(R.layout.main);
Activity.setContentView(…) also accepts a View as the
parameter. We will use that to set a simple TextView as our
ContentView.
package org.anddev.android.Hello_Android;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class Hello_Android extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
/* We want to view some very simple text,
* so we need a TextView associated with this Activity. */
TextView tv = new TextView(this);
/* Put some text to the newly created TextView */
tv.setText("Hello Android - by: anddev.org /n" +
"This is soooo simple =D ");
/* Tell our Activity to display that TextView */
this.setContentView(tv);
}
}
open_ddms_view.png
System.out.println(…) ?
Debugging in Android cannot be done using
System.out.println(…) because as we know Android is not
running on a normal VM but inside of emulated hardware on the
DalvikVM. ( To be honest, it can be done but is should definitely be not
your choice)
But don’t worry, Android provides a much more powerful debugging
feature – The LogCat.
The LogCat
The LogCat is a part of the DDMS (Dalvik Debug Monitor service) that
provides a mechanism for collecting and viewing system debug output.
Logs from various applications and portions of the system are collected in
the LogCat, which then can be viewed and filtered.
If you cannot see A, do it the B way.
Picture 15 Opening the DDMS View
Using the LogCat
Every Android log message has a tag and a priority associated with it.
logcat.png
The tag of a log message is a short string indicating the system
component from which the message originates (for example, "View" for
the view system).
The priority is one of the following character values, ordered from lowest
to highest priority:
. V — Verbose (lowest priority)
. D — Debug
. I — Info
. W — Warning
. E — Error (highest priority)
As we are using Eclipse we can simply filter by priority clicking the “V-D-I-
W-E” Buttons in the LogCat View one can also see below. You’ll love the
ADT plugin for that feature, because, in the masses of output the whole
system generates, it is really hard to find anything without filters.
Picture 16 The LogCat
The usage in the code is pretty simple. You need to make a single import:
import android.util.Log;
Then you are able to use debugging statements, like this:
Log.d("DEBUGTAG", "My debug-message.");
When some critical things happened you can pass the
Throwable/Exception to Log.e(…),to get the StackTrace printed
to the LogCat:
try{
throw new Exception();
}catch(Exception e){
Log.e("DEBUGTAG","Error occured", e);
}
Note:
Using Intents
As we know things needed to be done are expressed by Intents. Intents
can i.e. be used to start other Activities.
Starting (Sub)Activities
An essential thing in the lifetime of an application, that is more
sophisticated than a HelloWorld Application, is to start other Activities,
especially SubActivitites. Let’s assume the following scenario:
We want to have something like an InputDialog where the user can write
a keyword he wants to search on Google for.
So we will create a new Android Project as we already did it before. The
first thing we will do is to add a second Activity we will name
“MySecondActivity”.
In the beginning the code shall look like this:
package org.anddev.andbook.startingsubactivities;
import android.app.Activity;
import android.os.Bundle;
public class MySecondActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
}
}
open_resource_editor.png
layout_start.png
We now will add a Button to the first Activity. We do that by altering the
main.xml, of course, and not by switching to a Java UI.
Browse to “/res/layout/main.xml” and you will see code similar
to this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, StartingSubactivities" />
</LinearLayout>
Note: maybe Eclipse opened the main.xml with its default xml-Editor which is
not of any use for us. Since SDK-version m5 the ADT plugin provides a
Resource-Editor with Syntax-Highlighting.
Picture 17 Opening the Resource Editor
If we would start the Application right now it would look like this:
Picture 18 Layout default (sdk-version m5)
layout_with_button.png
As we want to have a Button in our application, we will have to come up
with some xml-code:
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Open Search-Dialog" />
As one can imagine, “fill_parent” makes a View us all space the
parent View provides and “wrap_content” uses just as much layout
space as it needs to display its content correctly.
So our button will fill the whole screen in width and wrap around the
“Open Search-Dialog” we typed for the android:text attribute.
Our application now looks like this:
Picture 19 Layout with Button (sdk-version m5)
When we now click the button – nothing happens, of course. We will
have to apply a Listener to be specific an OnClickListener to Handle clicks
to this Buttons.
But wait… how can we refer to that Button in Java Code ?
exclamation.gif
Finding XML-defined Views in Java-Code
To find a View that was defined in XML we first have to add one single
line to the XML-definition of that View, an android:id attribute. In
this case we will give it the id “btn_open_search”:
<Button
android:id="@+id/btn_open_search"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Open Search-Dialog" />
Finding that View in Java Code is same easy. Within an Activity you can
use the findViewById(int resourceID) method, to get a
reference to a View using the android:id that has been defined in
XML.
The same can be done with any other class that extends View, i.e.
EditText, TextView, MapView, etc…
But findViewById(…) can only be used with Views that are
placed within the Layout that was loaded to that Activity using
setContentView(…)!
Coming back to our example, we add the following in Code to
onCreate(…), right after the setContentView(…):
/* Find the Button from our XML-layout. */
Button b = (Button)this.findViewById(R.id.btn_open_search);
If Eclipse cannot find i.e. the Button-Class, just hit ‘CTRL+SHIFT+O’
what will organize the imports and automatically add (in this case):
import android.widget.Button;
wink.gif
Handling Clicks to Views
We now remember that we once wanted to make our button
clickable. Therefore we simply set an anonymous OnClickListener
to our Button:
b.setOnClickListener(new OnClickListener(){
public void onClick(View arg0) {
// Place code to handle Button-Click here.
}
});
Note: Eclipse might not recognize the following import by itself:
import android.view.View.OnClickListener;
Now we will add an Intent to the onClick-Event that will start our
SubActivity:
/* Create an Intent to start
* MySecondActivity. */
Intent i = new Intent(
StartingSubactivities.this,
MySecondActivity.class);
/* Send intent to the OS to make
* it aware that we want to start
* MySecondActivity as a SubActivity. */
startSubActivity(i, 0x1337);
The second parameter of startSubActivity can be any unique
Integer. It will get useful later on (then we will be placing it declared as
final to our Activity), when we want to retrieve a result from the
SubActivity.
activity_not_defined_in_manifest.png
exclamation.gif
If we would now run our code and click our button we would receive the
following error-message:
Picture 20 Activity not defined in AndroidManifest.xml
Note: Some of the messages shown are really helpful, read them.
So we need to define our “MySecondActivity” in the
AndroidManiufest.xml too. Just after the first </activity> tag
we write:
<activity android:name=".MySecondActivity"
android:label="@string/app_name">
<intent-filter>
<action
android:name="android.intent.action.VIEW" />
<category
android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
This time we did not choose “…MAIN” for <action> and
“…LAUNCHER” for <category> because there is no need to get
“MySecondActivity” launched from outside of our Application.
“MySecondActivity” is now reachable through a click to the button,
but it also refers to our main.xml:
setContentView(R.layout.main);
So we have to create an additional layout file for
“MySecondActivity”. It will contain a so called EditText what in
Swing jargon would be a TextField and another Button to return to
our “Main”-Activity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<EditText
android:id="@+id/et_keyword"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btn_return"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Submit" />
</LinearLayout>
Of course both need an android:id that we can use the in our
JavaCode. Now we can change the setContentView of
“MySecondActivity” to:
/* Get the EditText from the XML-file. */
this.et_keyword = (EditText)this.findViewById(R.id.et_keyword);
/* Get the return-Button from the XML-file. */
Button b = (Button)this.findViewById(R.id.btn_return);
/* Make that Button handle clicks to itself. */
b.setOnClickListener(new OnClickListener(){
public void onClick(View arg0) {
/* Place code to handle Button-Click here. */
}
});
Returning values from SubActivities
Returning values from SubActivities to the caller is also very simple:
/* Retrieve the Text from the EditText. */
String keyword =
MySecondActivity.this.et_keyword.getText().toString();
/* The parameters passed to this function
* will be available to the caller. */
MySecondActivity.this.setResult(1, keyword);
/* Our Activity is done and shall be closed. */
MySecondActivity.this.finish();
One could additionally pass a so called Bundle back to the caller (what
is more or less a HashMap), but I’ll tell you more of that soon.
Obviously the caller has to react on the fact that the SubActivity decided
to return. To accomplish that, we have to override a single method
coming from the Activity class. It is called onActivityResult(…):
@Override
protected void onActivityResult(int requestCode, int resultCode,
String data, Bundle extras) {
/* Place out code to react on Activity-Result here. */
super.onActivityResult(requestCode, resultCode, data, extras);
}
You probably recognized that the first parameter is called
requestCode – yes it is the same requestCode that we passed to
startSubActivity earlier. So if we have more than one SubActivity,
we can use requestCode to differentiate which SubActivity has just
returned.
Tipp: Eclipse provides a very useful function that you’ll learn to love,
especially if you are extending a base-class and search for methods to
override:
trick_override_methods.png
Picture 21 Using Eclipse to find methods to override
So now we can simply switch on the requestCode and create another
Intent to do the Google-search.
/* Check which SubActivity returned.
* (Here we have only one.) */
switch(requestCode){
case MYSECONDACTIVITY_REQUESTCODE:
/* Create a new Intent to
* show the Google-Search Page
* with the keyword returned. */
Intent webIntent = new Intent(
android.content.Intent.VIEW_ACTION,
Uri.parse("http://www.google.com/search?q=" + data));
startActivity(webIntent);
break;
}
As you probably have recognized this time we are creating the Intent
another way. Last time we said like: “We want to start XYZ.class“,
but this time we describe what we want to get done. We want to VIEW a
URI (Uniform Resource Indicator), which can be constructed by using i.e.
Uri.fromParts(…).
Our Application is now capable of starting a (Sub)Activity, grabbing its
results and launching the Browser using an Intent.
But how to pass data to a (Sub)Activity?
Passing Data to (Sub)Activities
Passing data to (Sub)Activities is, once again, not hard to manage. One
can use so called Bundles, which are more or less ordinary HashMap’s
that can take only trivial data types, to carry information from one
Activity to another. Just remember where we started our SubActivity in
the last chapter:
/* Create an Intent to start
* MySecondActivity. */
Intent i = new Intent(
StartingSubactivities.this,
MySecondActivity.class);
/* Send intent to the OS to make
* it aware that we want to start
* MySecondActivity as a SubActivity. */
startSubActivity(i, 0x1337);
Right between these two lines, we will put the following:
/* Create a bundle which will be
* attached to the Intent, to carry
* information to our SubActivity. */
Bundle b = new Bundle();
b.putString(MY_DEFAULTSTRING_ID, "anddev.org");
/* Attach Bundle to our Intent. */
i.putExtras(b);
Where MY_DEFAULTSTRING_ID can be any identifying String you can
imagine. There is also a method Intent.putExtra(…,…) which takes only
one information each call, which we could have used also.
smile.gif
Now we have to extract that information within our SubActivity. Every
Activity can access the original Intent it was started with, by calling
getIntent(). If there was a Bundle attached to the Intent we can
grab that by using getIntent().getExtras(). In this case we, we
will fill the EditText, where the user would type the keyword(s) with
the DefaultString we passed over the Intent :
//…
setContentView(R.layout.second);
/* Get the Bundle from the Intent
* this Activity was started with.*/
Bundle bundle = getIntent().getExtras();
/* Extract the default keyword
* by using the public ID we
* defined in the caller. */
String default_keyword = bundle.getString(
StartingSubactivities.MY_DEFAULTSTRING_ID);
/* Get the EditText from the XML-file. */
this.et_keyword = (EditText)this.findViewById(R.id.et_keyword);
/* Set the default keyword to the EditText. */
this.et_keyword.setText(default_keyword);
/* Get the return-Button from the XML-file. */
//…
So let’s resume what you have learned up to here:
. Create an simple Application using a XML Layout
. Do the same with a Java-based Layout
. Run Android Applications
. Using the LogCat for debugging purpose
. Use Intents to start (Sub)Activities
. Find Views defined in XML to use them in Java Code
. Handle Clicks to Views
. Return values from SubActivities
. Pass data to SubActivities using Bundles
Not bad for now .
Important Layouts and ViewGroups
Android provides many more Layouts than just the LinearLayout we used
up to here. The most important Layouts, except LinearLayout, you will
get to know closer here are:
. RelativeLayout (Views are placed relative to each other)
. TableLayout (Uses tables like in HTML)
Additionally to that I will introduce to you the following really often used
ViewGroups:
. GridView (similar to TableLayout, supports ‘Adapters’)
. ScrollView (If your content exceeds the screen-size, you’ll need
to scroll)
. TabHost (Displays content in tabs)
The RelativeLayout
According to its name, when using RelativeLayouts one defines the
position of Views relative to other ‘neighbors-Views’.
Bibliography
1. Open Hanset Alliance. Open Hanset Alliance. [Online]
http://www.openhandsetalliance.com/.
2. GoogleGroups. Android Discussion Groups. [Online]
http://code.google.com/android/groups.html.
3. Alexa Webstats. The Web Information Company. alexa.com. [Online]
http://www.alexa.com.
4. Gramlich, Nicolas. Android Development Community | Android
Tutorials. [Online] http://anddev.org.
5. Hobbs, Zach. Hello Android. [Online] http://helloandroid.com/.
6. Nguyen, Vincent. Android Community. [Online]
http://androidcommunity.com/.
7. Srinivas, Davanum. Show me the code! [Online]
http://davanum.wordpress.com/.
Lost chapters
The communities
From the first day on, a couple of communities arose from the depth of
the internet. The most important community-website to mention
(depending on Alexa-stats (3)) is anddev.org (4) , which is the most
viewed Tutorial/Community-Board for Google Android up to date. Also
well known are the Community-Boards: helloandroid.com (5) and
androidcommunity.com (6). Last but definitely not least to mention is the
davanum.wordpress.com-Blog (7), which provided some very early
sample code where many programmers found a good first source.
Some sites were more, some less promising, so sooner or later the
viewers pointed their focus to the more-important sites listed above.