- 浏览: 1578124 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (289)
- java 语法基础 (51)
- spring (8)
- mvc struct /Ant --build.xml (8)
- SOA (0)
- oracle 9i/10g (23)
- sql server 2000-2005 (3)
- 数据库基础知识 (6)
- 设计模式与软件架构 (10)
- Hibernate 持久化 (9)
- J2SE/J2EE/J2ME/AJAX 技术 (8)
- JSF 技术 (3)
- JAVA 图形化 (0)
- JMS (40)
- Eclipse 3.2 IDE 开发技巧 (13)
- 项目处理方法集合 (2)
- html/jsp/javascript (2)
- Unix/Linux (9)
- j2me/ARM/windriver/嵌入式 (4)
- 电信科学 (8)
- jsp (1)
- c/c++ (1)
- LZW压缩算法(java) (2)
- Android (77)
- 版本管理git/svn (2)
最新评论
-
huihai:
有demo吗?
NamingStrategy实现动态表名映射 -
cangbaotu:
推荐给大家一些有用的爬虫源码:https://github.c ...
网络爬虫(源代码参考) -
tuspark:
除了.classpath文件以外,.project文件也应该了 ...
Eclipse .classpath文件浅谈 -
tuspark:
造成eclipse自动关闭的原因有很多,这里有很多介绍:ecl ...
eclipse 自动关闭 解决方案 -
DEMONU:
网上都是这些,这种文章。。。
ActiveMQ中的消息持久性
Android 是一个面向应用程序开发的富平台,它拥有许多具有吸引力的用户界面元素和数据管理功能。Android
还提供了一组丰富的接口选项。在本文中,学习如何配合使用 Android 的各种传感器选项监控您的环境。样例代码展示了如何在 Android
电话中录制音频。想构建自己的婴儿监视器吗?想用声音来接听电话或者打开房门吗?请学习如何利用配备有 Android 的设备的硬件功能。
简介
对于 Java™ 开发人员来说,Android 平台是通过使用硬件传感器创建创新应用程序的理想平台。我们将学习一些可用于 Android 应用程序的接口连接选项,包括使用传感器子系统和录制音频片段。
利用配备 Android
的设备的硬件功能可以构建哪些应用程序呢?任何需要电子监视和监听的应用程序都可以构建。婴儿监视器、安全系统,甚至地震仪都可以。理论上讲,您不能同时
出现在两个地方,但 Android 可以利用一些可行的方法实现这一点。纵观本文始末,您必须记住,使用的 Android 设备不仅仅局限于
“手机”,还可以是部署在固定位置、具有无线网络连接的设备,比如 EDGE 或 WiFi。
Android 传感器功能
使用 Android 平台有一个很新颖的地方,那就是您可以在设备内部访问一些
“好工具”。过去,访问设备底层硬件的能力一度让移动开发人员感到非常棘手。尽管 Android Java 环境的角色仍然是您和设备的桥梁,但
Android 开发团队让许多硬件功能浮出了水面。该平台是一个开源平台,因此您可以自由地编写代码实现您的任务。
如果尚未安装 Android,您可以 下载 Android SDK。您还可以 浏览 android.hardware 包的内容并参考本文的示例。android.media 包 包含了一些提供有用和新颖功能的类。
Android SDK 中包含的一些面向硬件的功能描述如下。
表 1. Android SDK 中提供的面向硬件的特性
特性 描述
android.hardware.Camera 允许应用程序与相机交互的类,可以截取照片、获取预览屏幕的图像,修改用来治理相机操作的参数。
android.hardware.SensorManager 允许访问 Android 平台传感器的类。并非所有配备 Android 的设备都支持 SensorManager 中的所有传感器,虽然这种可能性让人非常兴奋。(可用传感器的简介见下文)
android.hardware.SensorListener 在传感器值实时更改时,希望接收更新的类要实现的接口。应用程序实现该接口来监视硬件中一个或多个可用传感器。例如,本文中的 代码 包含实现该接口的类,实现后可以监视设备的方向和内置的加速表。
android.media.MediaRecorder
用于录制媒体样例的类,对于录制特定位置(比如婴儿保育)的音频活动非常有用。还可以分析音频片段以便在访问控件或安全应用程序时进行身份鉴定。例如,它
可以帮助您通过声音打开门,以节省时间,不需要从房产经纪人处获取钥匙。
android.FaceDetector 允许对人脸(以位图形式包含)进行基本识别的类。不可能有两张完全一样的脸。可以使用该类作为设备锁定方法,无需记密码 — 这是手机的生物特征识别功能。
android.os.* 包含几个有用类的包,可以与操作环境交互,包括电源管理、文件查看器、处理器和消息类。和许多可移动设备一样,支持
Android 的电话可能会消耗大量电能。让设备在正确的时间 “醒来” 以监视感兴趣的事件是在设计时需要首先关注的方面。
java.util.Date
java.util.Timer
java.util.TimerTask 当测量实际的事件时,数据和时间往往很重要。例如,java.util.Date
类允许您在遇到特定的事件或状况时获取时间戳。您可以使用 java.util.Timer 和 java.util.TimerTask
分别执行周期性任务或时间点任务。
android.hardware.SensorManager 包含几个常量,这表示 Android 传感器系统的不同方面,包括:
传感器类型
方向、加速表、光线、磁场、临近性、温度等。
采样率
最快、游戏、普通、用户界面。当应用程序请求特定的采样率时,其实只是对传感器子系统的一个提示,或者一个建议。不保证特定的采样率可用。
准确性
高、低、中、不可靠。
SensorListener 接口是传感器应用程序的中心。它包括两个必需方法:
onSensorChanged(int sensor,float values[])
方法在传感器值更改时调用。该方法只对受此应用程序监视的传感器调用(更多内容见下文)。该方法的参数包括:一个整数,指示更改的传感器;一个浮点值数
组,表示传感器数据本身。有些传感器只提供一个数据值,另一些则提供三个浮点值。方向和加速表传感器都提供三个数据值。
当传感器的准确性更改时,将调用 onAccuracyChanged(int sensor,int accuracy) 方法。参数包括两个整数:一个表示传感器,另一个表示该传感器新的准确值。
要与传感器交互,应用程序必须注册以侦听与一个或多个传感器相关的活动。注册使用 SensorManager 类的 registerListener 方法完成。本文中的 代码示例 演示了如何注册和注销 SensorListener。
记住,并非所有支持 Android 的设备都支持 SDK 中定义的所有传感器。如果某个传感器无法在特定的设备上使用,您的应用程序就会适当地降级。
传感器示例
样例应用程序仅监控对方向和加速表传感器的更改。当收到更改时,传感器值在 TextView 小部件的屏幕上显示。图 1 展示了该应用程序的运行情况。
使用 Eclipse 环境和 Android Developer Tools 插件创建的应用程序。(关于使用 Eclipse 开发 Android 应用程序的信息,请参见 参考资料。)清单 1 展示了该应用程序的代码。
清单 1. IBMEyes.java
- view
plaincopy to clipboardprint?package com.msi.ibm.eyes; import
android.app.Activity; import android.os.Bundle; import
android.util.Log; import android.widget.TextView; import
android.hardware.SensorManager; import
android.hardware.SensorListener; public class IBMEyes extends
Activity implements SensorListener { final String tag =
"IBMEyes"; SensorManager sm = null; TextView xViewA =
null; TextView yViewA = null; TextView zViewA = null;
TextView xViewO = null; TextView yViewO = null; TextView
zViewO = null; /** Called when the activity is first created.
*/ @Override public void onCreate(Bundle savedInstanceState)
{ super.onCreate(savedInstanceState); // get
reference to SensorManager sm = (SensorManager)
getSystemService(SENSOR_SERVICE);
setContentView(R.layout.main); xViewA = (TextView)
findViewById(R.id.xbox); yViewA = (TextView)
findViewById(R.id.ybox); zViewA = (TextView)
findViewById(R.id.zbox); xViewO = (TextView)
findViewById(R.id.xboxo); yViewO = (TextView)
findViewById(R.id.yboxo); zViewO = (TextView)
findViewById(R.id.zboxo); } public void onSensorChanged(int
sensor, float[] values) { synchronized (this) {
Log.d(tag, "onSensorChanged: " + sensor + ", x: " + values[0] + ",
y: " + values[1] + ", z: " + values[2]); if (sensor ==
SensorManager.SENSOR_ORIENTATION) {
xViewO.setText("Orientation X: " + values[0]);
yViewO.setText("Orientation Y: " + values[1]);
zViewO.setText("Orientation Z: " + values[2]); }
if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
xViewA.setText("Accel X: " + values[0]);
yViewA.setText("Accel Y: " + values[1]);
zViewA.setText("Accel Z: " + values[2]); }
} } public void onAccuracyChanged(int
sensor, int accuracy) { Log.d(tag,"onAccuracyChanged: " +
sensor + ", accuracy: " + accuracy); } @Override
protected void onResume() { super.onResume(); //
register this class as a listener for the orientation and accelerometer
sensors sm.registerListener(this,
SensorManager.SENSOR_ORIENTATION
|SensorManager.SENSOR_ACCELEROMETER,
SensorManager.SENSOR_DELAY_NORMAL); } @Override
protected void onStop() { // unregister listener
sm.unregisterListener(this); super.onStop(); }
} package com.msi.ibm.eyes;
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.Log;
- import android.widget.TextView;
- import android.hardware.SensorManager;
- import android.hardware.SensorListener;
- public class IBMEyes extends Activity implements SensorListener {
- final String tag = "IBMEyes";
- SensorManager sm = null;
- TextView xViewA = null;
- TextView yViewA = null;
- TextView zViewA = null;
- TextView xViewO = null;
- TextView yViewO = null;
- TextView zViewO = null;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // get reference to SensorManager
- sm = (SensorManager) getSystemService(SENSOR_SERVICE);
- setContentView(R.layout.main);
- xViewA = (TextView) findViewById(R.id.xbox);
- yViewA = (TextView) findViewById(R.id.ybox);
- zViewA = (TextView) findViewById(R.id.zbox);
- xViewO = (TextView) findViewById(R.id.xboxo);
- yViewO = (TextView) findViewById(R.id.yboxo);
- zViewO = (TextView) findViewById(R.id.zboxo);
- }
- public void onSensorChanged(int sensor, float[] values) {
- synchronized (this) {
- Log.d(tag, "onSensorChanged: " + sensor + ", x: " +
- values[0] + ", y: " + values[1] + ", z: " + values[2]);
- if (sensor == SensorManager.SENSOR_ORIENTATION) {
- xViewO.setText("Orientation X: " + values[0]);
- yViewO.setText("Orientation Y: " + values[1]);
- zViewO.setText("Orientation Z: " + values[2]);
- }
- if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
- xViewA.setText("Accel X: " + values[0]);
- yViewA.setText("Accel Y: " + values[1]);
- zViewA.setText("Accel Z: " + values[2]);
- }
- }
- }
-
- public void onAccuracyChanged(int sensor, int accuracy) {
- Log.d(tag,"onAccuracyChanged: " + sensor + ", accuracy: " + accuracy);
- }
- @Override
- protected void onResume() {
- super.onResume();
- // register this class as a listener for the orientation and accelerometer sensors
- sm.registerListener(this,
- SensorManager.SENSOR_ORIENTATION |SensorManager.SENSOR_ACCELEROMETER,
- SensorManager.SENSOR_DELAY_NORMAL);
- }
-
- @Override
- protected void onStop() {
- // unregister listener
- sm.unregisterListener(this);
- super.onStop();
- }
- }
编写应用程序必须基于常见的活动,因为它只是利用从传感器获取的数据更新屏幕。在设备可能在前台执行其他活动的应用程序中,将应用程序构建为服务可能更加合适。
该活动的 onCreate 方法可以引用 SensorManager,其中包含所有与传感器有关的函数。onCreate 方法还建立了对 6 个 TextView 小部件的引用,您需要使用传感器数据值更新这些小部件。
onResume() 方法使用对 SensorManager 的引用通过 registerListener 方法注册传感器更新:
第一个参数是实现 SensorListener 接
第二个参数是所需传感器的位掩码。在本例中,应用程序从 SENSOR_ORIENTATION 和 SENSOR_ACCELEROMETER 请求数据。
第三个参数是一个系统提示,指出应用程序更新传感器值所需的速度。
应用程序(活动)暂停后,需要注销侦听器,这样以后就不会再收到传感器更新。这通过 SensorManager 的 unregisterListener 方法实现。惟一的参数是 SensorListener 的实例。
在 registerListener 和 unregisterListener 方法调用中,应用程序使用关键字 this。注意类定义中的
implements 关键字,其中声明了该类实现 SensorListener 接口。这就是要将它传递到 registerListener 和
unregisterListener 的原因。
SensorListener 必须实现两个方法 onSensorChange 和
onAccuracyChanged。示例应用程序不关心传感器的准确度,但关注传感器当前的 X、Y 和 Z
值。onAccuracyChanged 方法实质上不执行任何操作;它只在每次调用时添加一个日志项。
似乎经常需要调用 onSensorChanged
方法,因为加速表和方向传感器正在快速发送数据。查看第一个参数确定哪个传感器在发送数据。确认了发送数据的传感器之后,将使用方法第二个参数传递的浮点
值数组中所包含的数据更新相应的 UI
元素。该示例只是显示这些值,但在更加高级的应用程序中,还可以分析这些值,比较原来的值,或者设置某种模式识别算法来确定用户(或外部环境)的行为。
现在您已经了解了传感器子系统,接下来的部分将回顾一个在 Android 手机上录制音频的代码样例。该样例运行在 DEV1 开发设备上。
使用 MediaRecorder
android.media 包包含与媒体子系统交互的类。使用 android.media.MediaRecorder
类进行媒体采样,包括音频和视频。MediaRecorder
作为状态机运行。您需要设置不同的参数,比如源设备和格式。设置后,可执行任何时间长度的录制,直到用户停止。
清单 2 包含的代码在 Android 设备上录制音频。显示的代码不包括应用程序的 UI 元素。
清单 2. 录制音频片段
- view
plaincopy to clipboardprint?MediaRecorder mrec ; File audiofile =
null; private static final String TAG="SoundRecordingDemo";
protected void startRecording() throws IOException {
mrec.setAudioSource(MediaRecorder.AudioSource.MIC);
mrec.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mrec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); if
(mSampleFile == null) { File sampleDir =
Environment.getExternalStorageDirectory(); try {
audiofile = File.createTempFile("ibm", ".3gp", sampleDir);
} catch (IOException e) {
Log.e(TAG,"sdcard access error"); return; }
} mrec.setOutputFile(audiofile.getAbsolutePath());
mrec.prepare(); mrec.start(); } protected void
stopRecording() { mrec.stop(); mrec.release();
processaudiofile(audiofile.getAbsolutePath()); } protected void
processaudiofile() { ContentValues values = new
ContentValues(3); long current = System.currentTimeMillis();
values.put(MediaStore.Audio.Media.TITLE, "audio" +
audiofile.getName());
values.put(MediaStore.Audio.Media.DATE_ADDED, (int) (current /
1000)); values.put(MediaStore.Audio.Media.MIME_TYPE,
"audio/3gpp"); values.put(MediaStore.Audio.Media.DATA,
audiofile.getAbsolutePath()); ContentResolver contentResolver =
getContentResolver(); Uri base =
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; Uri newUri =
contentResolver.insert(base, values); sendBroadcast(new
Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, newUri));
} MediaRecorder mrec ;
- File audiofile = null;
- private static final String TAG="SoundRecordingDemo";
- protected void startRecording() throws IOException
- {
- mrec.setAudioSource(MediaRecorder.AudioSource.MIC);
- mrec.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
- mrec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
- if (mSampleFile == null)
- {
- File sampleDir = Environment.getExternalStorageDirectory();
- try
- {
- audiofile = File.createTempFile("ibm", ".3gp", sampleDir);
- }
- catch (IOException e)
- {
- Log.e(TAG,"sdcard access error");
- return;
- }
- }
- mrec.setOutputFile(audiofile.getAbsolutePath());
- mrec.prepare();
- mrec.start();
- }
- protected void stopRecording()
- {
- mrec.stop();
- mrec.release();
- processaudiofile(audiofile.getAbsolutePath());
- }
- protected void processaudiofile()
- {
- ContentValues values = new ContentValues(3);
- long current = System.currentTimeMillis();
- values.put(MediaStore.Audio.Media.TITLE, "audio" + audiofile.getName());
- values.put(MediaStore.Audio.Media.DATE_ADDED, (int) (current / 1000));
- values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/3gpp");
- values.put(MediaStore.Audio.Media.DATA, audiofile.getAbsolutePath());
- ContentResolver contentResolver = getContentResolver();
-
- Uri base = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
- Uri newUri = contentResolver.insert(base, values);
-
- sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, newUri));
- }
在 startRecording 方法中,实例化并初始化 MediaRecorder 的实例:
输入源被设置为麦克风(MIC)。
输出格式被设置为 3GPP(*.3gp 文件),这是移动设备专用的媒体格式。
编码器被设置为 AMR_NB,这是音频格式,采样率为 8 KHz。NB 表示窄频。SDK 文档 解释了不同的数据格式和可用的编码器。
音频文件存储在存储卡而不是内存中。External.getExternalStorageDirectory()
返回存储卡位置的名称,在该目录中将创建一个临时文件名。然后,通过调用 setOutputFile 方法将文件关联到 MediaRecorder
实例。音频数据将存储到该文件中。
调用 prepare 方法完成 MediaRecorder 的初始化。准备开始录制流程时,将调用 start 方法。在调用 stop 方法之前,将对存储卡上的文件进行录制。release 方法将释放分配给 MediaRecorder 实例的资源。
音频采样完成之后,需要采取以下步骤:
向设备的媒体库添加该音频。
执行一些模式识别步骤确定声音:
这是婴儿的啼哭声吗?
这是所有人的声音吗?是否要解锁手机?
这是 “芝麻开门” 吗?是否要打开通往 “秘密通道” 的大门?
自动将音频文件上传到网络位置以便处理。
在该代码样例中,processaudiofile 方法将音频添加到媒体库。使用 Intent 通知设备上的媒体应用程序有新内容可用。
关于该代码片段最后要注意的是:如果您试用,它一开始不会录制音频。您将看到创建的文件,但是没有任何音频。您需要向 AndroidManifest.xml 文件添加权限:
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
现在,您已经学了一点关于与 Android 传感器和录制音频相关的内容。下一节将更全面的介绍与数据采集和报告系统有关的应用程序架构。
Android 作为传感器平台
Android 平台包含各种用于监视环境的传感器选项。有了输入或模拟选项数组,以及高级计算和互联功能,Android 成为构建实际系统的最佳平台。图 2 显示了输入、应用程序逻辑、通知方法或输出之间的简单视图。
该架构很灵活;应用程序逻辑可以划分为本地 Android 设备和服务器端资源(可以实现更大的数据库和计算功能)。例如,本地 Android
设备上录制的音轨可以 POST 到 Web 服务器,其中将根据音频模式数据库比较数据。很明显,这仅仅是冰山一角。希望您能更深入地研究,让
Android 平台超越移动电话的范畴。
结束语
在本文中,我们介绍了 Android 传感器。样例应用程序度量了方向和加速,以及使用 MediaRecorder 类与录制功能进行交互。对于构建实际系统,Android 是一个灵活、有吸引力的平台。Android 领域发展迅速,并且不断壮大。
发表评论
-
APN(default、mms、supl、dun、hipri接入点类型的区别)
2013-10-10 19:31 45593设置APN上网时,大家可能经常遇到这个问题:为什么有时要填写 ... -
AMR音频编码器概述及文件格式分析
2013-10-10 19:29 3911全称Adaptive Multi-Rate,自适应多速率编码 ... -
pad 强制加载 Hdpi资源 (2.3 dpi < 240)
2012-07-16 16:47 0pad 强制加载 Hdpi资源 (2.3 dpi < ... -
android 设计模式-享元模式
2011-12-16 23:01 2152享元(FlyWeight)模式,原意是“轻量级”模式,它用来解 ... -
statusbar 2.3
2011-11-08 16:04 1243以前我的文章分析过Stat ... -
android 输入法默认设置
2011-07-07 14:00 7146设置默认输入法 在 frameworks\base\co ... -
Android Media Scanner Process
2011-06-06 22:58 3353下面是系统图 Medi ... -
handler与多线程消息处理
2011-06-04 13:42 8240在Android下面也有多线程的概念,在C/C++中,子线程可 ... -
android light
2011-03-24 16:15 3375背光设置是在:设置->声音和显示->亮度,通过进度 ... -
PowerManagerService sensor
2011-03-22 20:06 2632默认分类 2010-12-24 14:34:55 阅读144 ... -
android 单例
2011-02-15 09:26 41871. Framework层的代码: A ... -
Android 开发之 Services 服务
2010-11-02 18:21 4191Service Service ... -
深入学习android之AlarmManager
2010-11-01 16:50 34679对应AlarmManage有一个Alarm ... -
eclipse+android+ddms+adt
2010-09-14 10:30 8386用eclipse + ADT作为android ... -
Menus
2010-09-05 19:01 1754Android Menus 文章分类:移动开发 1.O ... -
Android开机自启动应用开发
2010-08-28 10:07 4551目前需要开发一个开机自启动的GTD应用程序来提醒用户的 ... -
Android2.1_Launcher学习笔记
2010-08-11 13:40 3805文章分类:移动开发 好么,2.0的源码没看几天,2.1的 ... -
Browsing Android Source in Eclipse
2010-08-09 16:00 3389Google’s Android SDK includes ... -
android 编译
2010-08-07 16:31 24911 我的系统是Ubuntu 8.04 * 2 系统上 ... -
Ubuntu linux 右键添加"以管理员身份打开","在终端中打开"
2010-08-02 15:04 4552Ubuntu linux 右键添加"以管理员身份打开 ...
相关推荐
我们介绍了 Android 传感器。样例应用程序度量了方向和加速,以及使用 MediaRecorder 类与录制功能进行交互。对于构建实际系统,Android 是一个灵活、有吸引力的平台。Android 领域发展迅速,并且不断壮大。请务必...
本文内容包括:简介Android传感器功能传感器示例使用MediaRecorderAndroid作为传感器平台结束语下载参考资料Android是一个面向应用程序开发的富平台,它拥有许多具有吸引力的用户界面元素和数据管理功能。...
Android应用已经不断渗透到人们的...本书不仅探讨了行之有效的应用设计和实现方式,还深入地讨论了传感器、本地开发、3D图形等所有Android应用开发者需要掌握的主题,完美地展示了如何在不同的平台上构建Android应用。
《Android程序设计》内容简介:...本书不仅探讨了行之有效的应用设计和实现方式,还深入地讨论了传感器、本地开发、3D图形等所有Android应用开发者需要掌握的主题,完美地展示了如何在不同的平台上构建Android应用
◆ 深入分析了Android应用程序的组件和生命周期 ◆ 探讨了Android的UI原理、设计理念和UI API,使用户界 面在手机、平板电脑和电视上都引人注目 ◆ 介绍了创建基于地图的应用程序和使用基于位置的服务 的相关知识 ◆...
◆ 深入分析了Android应用程序的组件和生命周期 ◆ 探讨了Android的UI原理、设计理念和UI API,使用户界 面在手机、平板电脑和电视上都引人注目 ◆ 介绍了创建基于地图的应用程序和使用基于位置的服务 的...
《Android 4高级编程(第3版)》特色:深入分析了Android应用程序的组件和生命周期;探讨了Android的UI原理、设计理念和UI API,使用户界面在手机、平板电脑和电视上都引人注目;介绍了创建基于地图的应用程序和使用...
3.7 深入探讨Android活动 63 3.7.1 创建一个活动 63 3.7.2 活动生命周期 65 3.7.3 Android活动类 70 3.8 小结 70 第4章 创建用户界面 73 4.1 Android UI基本设计 74 4.2 View简介 74 4.2.1 使用View创建...
书中不仅结合数独游戏开发案例形象生动地讲解了Android生命周期、用户界面、2D图形、多媒体,以及本地数据存储等基础知识,而且通过“Hello, Android”项目深入探讨了外部通信、基于位置的服务、内置SQLite数据库、...
◆ 深入分析了Android应用程序的组件和生命周期 ◆ 探讨了Android的UI原理、设计理念和UI API,使用户界 面在手机、平板电脑和电视上都引人注目 ◆ 介绍了创建基于地图的应用程序和使用基于位置的服务 的相关知识 ◆...
◆ 深入分析了Android应用程序的组件和生命周期 ◆ 探讨了Android的UI原理、设计理念和UI API,使用户界 面在手机、平板电脑和电视上都引人注目 ◆ 介绍了创建基于地图的应用程序和使用基于位置的服务 的相关知识 ◆...
◆ 深入分析了Android应用程序的组件和生命周期 ◆ 探讨了Android的UI原理、设计理念和UI API,使用户界 面在手机、平板电脑和电视上都引人注目 ◆ 介绍了创建基于地图的应用程序和使用基于位置的服务 的相关知识 ◆...
第三部分深入探讨Android平台。这一部分介绍外部通信、基于位置的服务、内置SQLite数据库和三维图形。 本书最后提供了一个附录,其中列出了Android与Java SE(Java Standard Edition,Java标准版)之间的不同之...
, 第3-6章深入地探讨了基本的Android应用程序组件。首先讲述了组成Android应用程序和它的生命周期的每个部分,在介绍“活动”内容及其生存期与生命周期之前,将简要介绍应用程序清单和外部资源。, 之后将学习如何...