Android基础总结(精华完整版)

1. 前言

1.1. 什么是3G4G

Ÿ 第三代移动通信技术(3rd - Generation),速率一般在几百Kbps,较之前的2G2.5G在数据传输速度上有很大提升。

Ÿ 第四代移动通信技术(4th - Generation),速度可达到100Mbps以上,几乎可以满足人们的所有传输数据的需求。

Ÿ 目前主流的3G技术标准有三种:

WCDMA:全球80%以上的3G网络都是采用此种制式。中国联通运营。186

CDMA2000:目前日韩及北美使用较多。中国电信运营。 189

TD-SCDMA:中国自主知识产权的3G通信技术。中国移动运营。 188 

Ÿ 目前主流的4G技术为LTE,但还没有被广泛应用:

GSM à GPRS à EDGE à WCDMA à HSDPA à HSDPA+ à LTE

1.2. 什么是Android 

 

Ÿ Android本义指机器人”,Google2007115日宣布的基于Linux平台的开源手机操作系统的名称,官方中文名:安卓 。

Ÿ Android系统早期由原名为"Android"的公司开发,谷歌在2005年收购"Android.Inc"后,继续对Android系统开发运营

Ÿ 底层Linux内核只提供基本功能,其他的应用软件则由各公司自行开发,大部分程序以Java语言编写。

Ÿ 由于Android系统的开源特性,很多制造商都在生产Android系统的设备,如:摩托罗拉、HTC、三星、索爱、LG、小米、华为、魅族等。

Ÿ Android系统除了运行在智能手机上之外,还可以用做平板电脑、电视、汽车等很多设备上。

Ÿ Android系统架构图:

 

 

1.3. Android的版本升级

Ÿ 1.5 Cupcake(纸杯蛋糕)

拍摄/播放影片,并支持上传到Youtube

支持立体声蓝牙耳机,同时改善自动配对性能

最新的采用WebKit技术的浏览器,支持复制/贴上和页面中搜索

GPS性能大大提高

提供屏幕虚拟键盘

主屏幕增加音乐播放器和相框widgets

应用程序自动随着手机旋转

短信、Gmail、日暦,浏览器的用户接口大幅改进,如Gmail可以批量删除邮件

相机启动速度加快,拍摄图片可以直接上传到Picasa

来电照片显示

Ÿ 1.6 Donut(甜甜圈)

重新设计的Android Market 

手势支持 

支持CDMA网络 

文字转语音系统(Text-to-Speech) 

快速搜索框 

全新的拍照接口 

查看应用程序耗电 

支持虚拟私人网络(VPN) 

支持更多的屏幕分辨率。 

支持OpenCore2媒体引擎 

新增面向视觉或听觉困难人群的易用性插件

Ÿ 2.1 Éclair(闪电泡芙)

优化硬件速度

"Car Home"程序

支持更多的屏幕分辨率

改良的用户界面

新的浏览器的用户接口和支持HTML5

新的联系人名单

更好的白色/黑色背景比率

改进Google Maps 3.1.2

支持Microsoft Exchange

支持内置相机闪光灯

支持数码变焦

改进的虚拟键盘

支持蓝牙2.1

支持动态桌面的设计

Ÿ 2.2 Froyo冻酸奶)

支持将软件安装至扩展内存

集成Adobe Flash 10.1支持

加强软件即时编译的速度

新增软件启动"快速"至电话和浏览器

USB分享器和WiFi热点功能

支持在浏览器上传档案

更新Market中的批量和自动更新

增加对Microsoft Exchange的支持(安全政策, auto-discovery, GAL look-up

集成Chrome的V8 JavaScript引擎到浏览器

加强快速搜索小工具

更多软件能透过Market更新,类似2.0/2.1中的Map更新

速度和性能优化

Ÿ 2.3 Gingerbread姜饼

修补UI

支持更大的屏幕尺寸和分辨率(WXGA及更高)

系统级复制粘贴

重新设计的多点触摸屏幕键盘

本地支持多个镜头(用于视频通话等)和更多传感器(陀螺仪、气压计等)

电话簿集成Internet Call功能

支持近场通信(NFC) 

强化电源、应用程序管理功能

新增下载管理员

优化游戏开发支持

多媒体音效强化

从YAFFS转换到ext4文件系统

开放了屏幕截图功能

对黑色及白色的还原更加真实

Ÿ 3.x Honeycomb蜂巢)

仅供平板电脑使用

Google eBooks上提供数百万本书

支持平板电脑大萤幕、高分辨率

新版Gmail

Google Talk视讯功能

3D加速处理

网页版Market(Web store)详细分类显示,依个人Android分别设定安装应用程序

新的短消息通知功能

专为平板电脑设计的用户界面(重新设计的通知列与系统列)

加强多任务处理的接口

重新设计适用大屏幕的键盘及复制粘贴功能

多个标签的浏览器以及私密浏览模式

快速切换各种功能的相机

增强的图库与快速滚动的联络人接口

更有效率的Email接口

支持多核心处理器

3.2优化7吋平板显示

Ÿ 4.0 Ice Cream Sandwich奶油三明治)

虚拟按键,增大屏幕面积同时控制手机整体大小

桌面插件Widgets列表呈现在标签页中,与程序列表类似并且共存

文件夹更容易创建和管理,与iOS类似

可定制的桌面系统

可视语音邮件  

日历支持缩放操作

Gmail离线搜索,两行预览,以及底部新快捷栏

音量下键+电源键组合截图

改进虚拟键盘纠错

从锁屏界面直接访问应用程序

优化复制粘贴

新版浏览器

新的Roboto字体

流量控制系统

相机应用

人脸识别,刷脸解锁

内置照片编辑器

多任务列表

新的图库布局和组织方式

联系人应用整合社交网络信息

Android Beam

http://digi.tech.qq.com/a/20111019/001579.htm

1.4. 主流智能手机操作系统

 

2. 搭建开发环境

2.1. 所需资源

Ÿ JDKJava开发环境。下载地址:http://www.oracle.com

Ÿ EclipseIBM公司开发的一款开源IDEhttp://www.eclipse.org

Ÿ Android SDKAndroid 开发工具,包含开发Android程序所需类库、源码、文档、案例等资源。http://www.android.com

Ÿ ADT插件,ADT 是 Eclipse 平台下用来开发 Android 应用程序的插件http://www.android.com

2.2. Eclipse安装ADT插件

 

 

 

 

 

 

 

 

 

 

2.3. 配置SDK路径

 

 

 

 

 

 

 

2.4. 启动虚拟机

Ø 点击机器人图标

 

Ø 弹出虚拟机管理器

 

 

Ø 修改虚拟机默认目录

指定环境变量android_sdk_home,通常指定为SDK所在目录,可以随意指定。

重启Eclipse之后将会以这个目录作为存放虚拟机文件的位置。

 

 

Ø 配置虚拟机

Ÿ Name:虚拟机的名字,可随意定义

Ÿ Target:虚拟机版本

Ÿ SD Card - Size:虚拟机的SDCard大小,会在本地硬盘创建指定大小的文件用来存储数据,模拟真实手机的SDCard

如果使用原有文件,可以选择File并点击Browse指定文件

Ÿ Snapshot: 保存快照,可以提高虚拟机启动速度

Ÿ Skin - Built-in:选择分辨率

HVGA480x320

QVGA320x240

WQVGA400400x240

WQVGA432432x240

WVGA800800x480

WVGA854854x480

也可以选择Resolution自行指定

 

 

 

 

Ø 成功进入Android操作系统界面

 

Ÿ 如果虚拟机显示无信号,需要对电脑的网络连接进行配置

无论电脑是否联网,IP地址、子网掩码、默认网关、首选DNS服务器都需要配置

Ÿ 电脑如果未连接局域网或互联网,可以见默认网关和首选DNS服务器配置成本机IP,例如:

 

 

Ÿ 电脑如果已连接局域网,需要将网关和首选DNS服务器进行设置,例如:

 

 

Ÿ 如果电脑已连接互联网,正常情况虚拟机不会显示无信号,重启虚拟机

2.5. 命令行操作

为了能在任意目录使用一下命令,需要将SDK目录下的platform-tools文件夹路径和tools文件夹路径配置到path环境变量中

Ÿ 列出可以使用的android版本

android list targets

Ÿ 列出可以使用的虚拟机

android list avd

Ÿ 创建虚拟机

android create avd –n <虚拟机名> -t 版本ID> -c 卡大小> -s <屏幕尺寸>

Ÿ 启动虚拟机

emulator –avd <虚拟机名>

Ÿ 显示已连接的设备

adb devices

Ÿ 导入文件到手机

adb push 源文件路径> <手机目标路径>

Ÿ 从手机导出文件

adb pull <手机源文件路径目录路径>

Ÿ 安装程序

adb install 文件路径>

Ÿ 卸载程序

adb uninstall <包名>

Ÿ 重启adb

adb kill-server

abd start-server

 

3. 开发一个Android程序

3.1. 创建Android程序

 

 

 

 

 

Ø 创建Android Project

Ÿ Project name:项目名

Ÿ Build TargetAndroid版本

Ÿ Application name:程序名,显示在程序列表中,以及程序启动后的标题栏

Ÿ Package name:包名,程序的唯一标识

Ÿ Create Activity:选择程序启动时是否创建一个窗体,设置主窗体名字

Ÿ Min SDK Version:设置运行该程序所需的最低版本

3.2. 安装、卸载程序

Ÿ Eclipse安装

右键点击工程 – Run as – Android Application

Ÿ 虚拟机卸载

设置 – 应用程序 – 管理应用程序 – 选中要卸载的程序 – 卸载

3.3. 了解项目目录结构

Ÿ src:源代码

Ÿ gen:系统自动生成的文件

R.java 中记录了项目中各种资源ID

Ÿ res:系统资源,所有文件都会在R文件生成资源ID

drawable:图片

layout:界面布局

values:数据

anim:定义动画的XML

raw:原生文件

Ÿ assets:资源路径,不会在R文件注册

Ÿ project.properties:供Eclipse使用,读取该项目使用Android版本号。早期版本名为:default.properties

Ÿ AndroidManifest.xml:清单文件,在软件安装的时候被读取

Android中的四大组件(ActivityContentProviderBroadcastReceiverService)都需要在该文件中注册

程序所需的权限也需要在此文件中声明,例如:电话、短信、互联网、访问SD

Ÿ bin:二进制文件,包括class、资源文件、dexapk

Ÿ proguard.cfg:用来混淆代码的配置文件,防止别人反编译

3.4. 程序启动过程

Ÿ Eclipse.java源文件编译成.class

Ÿ 使用dx工具将所有.class文件转换为.dex文件

Ÿ 再将.dex文件和所有资源打包成.apk文件

Ÿ 将.apk文件安装到虚拟机完成程序安装

Ÿ 启动程序 – 开启进程 – 开启主线程

Ÿ 创建Activity对象 – 执行OnCreate()方法

Ÿ 按照main.xml文件初始化界面

4. 演示案例

4.1. 电话拨号

 

Ÿ 搭建界面需要组件:TextViewEditTextButton

Ÿ 当点击Button时获取EditText中文本

Ÿ 使用Intent向系统内置的电话拨号器发送意图拨打电话

Ÿ 注册拨打电话权限

4.2. 查看程序错误信息

Ÿ Android程序中如果出错,错误不会显示在Console中,而是显示在LogCat界面下。可以从window – show view中打开

Ÿ 日志信息分为5个级别:verbose > debug > info > warn > error 高级的包含低级的

Ÿ 可以创建过滤器对日志进行过滤显示,点击绿色加号,可以按照tagpidlevel进行筛选

 

4.3. 将程序安装到真实手机

Ÿ 在电脑上安装手机驱动

有些手机自带驱动,有些没有,可以从官网下载。或者可以使用“豌豆荚”软件自动安装。

Ÿ 在手机设置中打开USB调试,将手机用USB数据线连接到电脑

我的手机是:三星 i9100  

双核1228MHz、1GB RAM 、4GB ROM、480×800像素、Android 2.3、4.3英寸

Ÿ 检查Eclipse的设备管理器中是否显示出新设备

如果未能显示出设备,检查驱动安装是否正常,USB调试是否打开

Ÿ Eclipse安装程序

Eclipse上右键点击工程 – Run as – Android Application – 自动安装运行

Ÿ 手动打包安装

右键点击工程 – Export – Export Android Application – 选择或创建密钥对程序签名并打包生成apk文件

apk文件放到手机的SD卡中,通过手机文件浏览器执行安装

 

4.4. 短信发送

 

Ÿ 搭建界面需要组件:TextViewEditTextButton

Ÿ 给Button添加监听器,当被点击的时候获取号码,获取内容

Ÿ 使用SmsManager发送短信

Ÿ 需要注册短信发送权限

4.5. 布局

Ø RelativeLayout(相对布局)

Ÿ android-sdk-windows/docs/guide/topics/ui/layout-objects.html#relativelayout

 

Ø TableLayout(表格布局)

android-sdk-windows/docs/guide/topics/ui/layout-objects.html#tablelayout

Ø FrameLayout(帧布局)

android-sdk-windows/docs/guide/topics/ui/layout-objects.html#framelayout

 

 

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

4.6. Junit

Ø 项目中添加测试类

Ÿ 在AndroidManifest.xml清单文件中添加配置

<instrumentation android:targetPackage="cn.itcast.junit" android:name="android.test.InstrumentationTestRunner" />

<uses-library android:name="android.test.runner" />

Ÿ 定义一个类继承AndroidTestCase,定义测试方法

Ÿ 在Outline视图下右键点击测试方法 – Run as – Android Junit Test

Ø 创建测试项目

Ÿ 创建Android Test Project

Ÿ 输入项目名,选择一个已存在的工程,Eclipse可以自动配置Junit环境

4.7. 日志信息

Ÿ 在LogCat视图中我们可以看到程序的日志信息,也可以在程序中输出信息到LogCat

Ÿ 程序中我们可以使用Log类来输出信息

Ÿ System.outSystem.err输出的信息也会显示在LogCat中,注意System.out输出信息是Info级别,System.errWarn级别

5. 文件操作(FileXMLSharedPreferences

5.1. 读写文件

 

 

Ø 写入文件到SD

Ÿ 需要在清单文件中注册权限

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

Ÿ 2.1版本以下的SDCard位置和2.2之后版本不同

可以通过Environment.getExternalStorageDirectory()获取当前SDCard位置,兼容所有版本

Ÿ 获取SDCard状态

通过Environment.getExternalStorageState()方法获取SDCard当前状态

常量 Environment.MEDIA_MOUNTED 为已安装

 

Ø 写入文件

Ÿ 通过Context.openFileOutput(String name, int mode)可以获取一个文件输入流

name为文件名,mode为文件模式,有4种模式

输出流指向路径为:/data/data/包名/files/ 

Ÿ 文件模式在Context中有定义常量

MODE_PRIVATE 私有

MODE_WORLD_READABLE 其他程序可读(不可写)

MODE_WORLD_WRITEABLE 其他程序可写(不可读)

模式可以组合使用,例如:MODE_WORLD_READABLE + MODE_WORLD_WRITEABLE

MODE_APPEND 追加

Ø 读取文件

Ÿ 通过Context.openFileInput(String name)可以获取一个文件输入流

该输入流可以读取 /data/data/包名/files/ 路径下的文件

Ÿ 获取当前程序Files文件路径

ContextWrapper.getFilesDir()

5.2. XML

Ø Pull简介

Ÿ 常见的XML解析方式有三种,DOMSAXPullAndroid系统中推荐使用Pull

Ÿ Pull解析器是一个开源的Java项目,Android系统内部解析XML文件均为此种方式,也可用于JavaEE项目

Ÿ Android SDK中已经集成了Pull解析器,无需添加任何jar文件

Ÿ Pull解析器运行方式与SAX类似,提供各种事件的判断

Ÿ 官方网站:http://xmlpull.org/

Ø 使用Pull解析器解析XML文件

Ÿ Xml.newPullParser() 获得解析器

Ÿ parser.setInput(in, "UTF-8") 设置输入流以及编码

Ÿ parser.next() 获取下一个解析事件,得到一个事件代码

Ÿ XmlPullParser中定义了常量来标识各种解析事件

START_DOCUMENTEND_DOCUMENT START_TAG 、END_TAG TEXT 

Ø 使用XmlSerializer写出XML

Ÿ 使用以下方法生成XML,和XML文档顺序类似

startDocument

startTag

attribute

text

endTag

endDocument

5.3. 偏好设定(SharedPreferences) 

 

 

Ÿ 在程序中保存一些配置参数的时候我们经常使用SharedPreferences

Context.getSharedPreferences(String name,int mode)

该方法可以在/data/data//shared_pref/目录下创建一个以name命名的xml文件,mode文件为模式

Ÿ 存储偏好

调用edit()方法可以获取一个Editor对象,对数据进行存储,存储之后需要调用commit()保存到文件

Ÿ 读取偏好

获得SharedPreferences之后调用getString()getInt()等方法获取其中设置的值

Ÿ 在Activity中获取SharedPreferences

Activity中可以调用getPreferences(int mode)方法获得一个SharedPreferences,文件名和Activity名一致

 

6. 数据库(SQLite

6.1. SQLite特点

Ÿ Android平台中嵌入了一个关系型数据库SQLite,和其他数据库不同的是SQLite存储数据时不区分类型

例如一个字段声明为Integer类型,我们也可以将一个字符串存入,一个字段声明为布尔型,我们也可以存入浮点数。

除非是主键被定义为Integer,这时只能存储64位整数

Ÿ 创建数据库的表时可以不指定数据类型,例如:

CREATE TABLE person(id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20))

CREATE TABLE person(id INTEGER PRIMARY KEY AUTOINCREMENT, name)

Ÿ SQLite支持大部分标准SQL语句,增删改查语句都是通用的,分页查询语句和MySQL相同

SELECT * FROM person LIMIT 20 OFFSET 10

SELECT * FROM person LIMIT 10,20

6.2. 创建数据库

Ÿ 定义类继承SQLiteOpenHelper

Ÿ 声明构造函数,4个参数

Ÿ 重写onCreate()方法

Ÿ 重写upGrade()方法

Ÿ 注意:SQLite数据库中列一旦创建不能修改,如果一定要修改,需要重新创建表,拷贝数据

6.3. CRUD操作

Ÿ 和JDBC访问数据库不同,操作SQLite数据库无需加载驱动,不用获取连接,直接可以使用

获取SQLiteDatabase对象之后通过该对象直接可以执行SQL语句

SQLiteDatabase.execSQL()

SQLiteDatabase.rawQuery()

Ÿ getReadableDatabase()和getWritableDatabase()的区别

查看源代码后我们发现getReadableDatabase()在通常情况下返回的就是getWritableDatabase()拿到的数据库

只有在抛出异常的时候才会以只读方式打开

Ÿ 数据库对象缓存

getWritableDatabase()方法最后会使用一个成员变量记住这个数据库对象,下次打开时判断是否重用

Ÿ SQLiteDatabase封装了insert()delete()、update()、query()四个方法也可以对数据库进行操作

这些方法封装了部分SQL语句,通过参数进行拼接

6.4. 事务管理

Ÿ 在使用SQLite数据库时可以用SQLiteDatabase类中定义的相关方法控制事务

beginTransaction() 开启事务

setTransactionSuccessful() 设置事务成功标记

endTransaction() 结束事务

Ÿ endTransaction()需要放在finally中执行,否则事务只有到超时的时候才自动结束,会降低数据库并发效率

7. 内容提供者(ContentProvider

7.1. 什么是内容提供者

Ÿ 内容提供者是Android中的四大组件之一,可以将应用中的数据对外进行共享

Ÿ 内容提供者将数据的访问方式统一,不必针对不同数据类型采取不同的访问策略

Ÿ 内容提供者将数据封装,只暴露出我们希望提供给其他程序的数据

Ÿ 内容提供者中数据更改可被监听

7.2. 创建内容提供者

Ÿ 定义类继承ContentProvider,根据需要重写内部方法

Ÿ 在清单文件的节点下进行配置,标签中需要指定nameauthorities属性

name为类名,包名从程序Package开始,以“.”开始

authorities:是访问Provider时的路径,要唯一

Ÿ URI代表要操作的数据,由schemeauthoritespath三部分组成

content://cn.itcast.sqlite.provider/person

scheme:固定为content,代表访问内容提供者

authorites节点中的authorites属性

path:程序定义的路径,可根据业务逻辑定义

7.3. 完成CRUD方法

Ÿ 当程序调用CRUD方法时会传入Uri

Ÿ 我们通过Uri判断调用者要操作的数据

可以使用工具类UriMatcher来判断Uri

addURI方法可以添加Uri

match方法可以匹配一个Uri判断其类型

Ÿ 根据业务逻辑操作数据

7.4. 访问内容提供者

Ÿ 通过Context获得ContentResolver对象

Ÿ 调用ContentResolver对象的方法即可访问内容提供者

7.5. 完成getType方法

Ÿ 如果返回数据是单条数据:vnd.android.cursor.item 

Ÿ 如果返回数据是多条数据:vnd.android.cursor.dir

7.6. 监听内容提供者数据变化

Ÿ 在内容提供者中可以通知其他程序数据发生变化

通过ContextgetContentResolver()方法获取ContentResolver

调用其notifyChange()方法发送数据修改通知

Ÿ 在其他程序中可以通过ContentObserver监听数据变化

通过ContextgetContentResolver()方法获取ContentResolver

调用其registerContentObserver()方法指定对某个Uri注册ContentObserver

自定义ContentObserver,重写onChange()方法获取数据

7.7. GIT获取源代码

Ø 资源地址

Ÿ Git

http://code.google.com/p/msysgit/

Ÿ 源码

https://github.com/android

 

注意:

GIT1.7.7安装后不能卸载,可以用其他版本覆盖后再卸载。

使用GIT时不要使用中文目录,否则GIT GUI会报错无法启动。删除C盘中.gitconfig文件可以解决。

7.8. 监听短信

Ÿ Android系统提供了Provider对短信进行查询,当发出短信时也会发送更改通知

Ÿ 短信数据库在 com.android.providers.telephony

Ÿ 定义一个Observer监听"content://sms"

Ÿ 在onChange()方法中查询"content://sms"

Ÿ 需要权限android.permission.READ_SMS

7.9. 操作联系人

Ø 获取所有联系人

Ÿ Android系统中的联系人也是通过ContentProvider来对外提供数据的

Ÿ 数据库路径为:/data/data/com.android.providers.contacts/database/contacts2.db

Ÿ 我们需要关注的有3张表

raw_contacts:其中保存了联系人id

data:和raw_contacts是多对一的关系,保存了联系人的各项数据

mimetypes:为数据类型

Ÿ Providerauthoritescom.android.contacts

Ÿ 查询raw_contacts表的路径为:contacts

Ÿ 查询data表的路径为:contacts/#/data

这个路径为连接查询,直接查询“mimetype”字段就可以根据“mimetype_id”查询到mimetypes表中的数据

Ÿ 先查询raw_contacts得到每个联系人的id,在使用iddata表中查询对应数据,根据mimetype分类数据

Ø 通过电话号码获取联系人

Ÿ 系统内部提供了根据电话号码获取data表数据的功能,路径为:data/phones/filter/*

Ÿ 用电话号码替换“*”部分就可以查到所需数据,获取“display_name”可以获取到联系人显示名

Ø 添加联系人

Ÿ 先向raw_contacts表插入id,路径为:raw_contacts

Ÿ 得到id之后再向data表插入数据,路径为:data

Ø 使用事务添加联系人

Ÿ 在添加联系人得时候是分多次访问Provider,如果在过程中出现异常,会出现数据不完整的情况,这些操作应该放在一次事务中

Ÿ 使用ContentResolver的applyBatch(String authority,ArrayList operations) 方法可以将多个操作在一个事务中执行

Ÿ 文档位置:

file:///F:/Itcast/lib/android-sdk-windows/docs/reference/android/provider/ContactsContract.RawContacts.html

8. 网络通信

8.1. 获取文本数据

Ÿ 通过URL对象封装地址,打开一个HttpURLConnection

Ÿ 设置头信息之后获取响应码,如果成功返回200即可从HttpURLConnection中获取输入流读取数据

Ÿ 代码过长屏幕显示不全可以使用进行显示

Ÿ 需要访问网络的权限

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

8.2. 获取网络图片

Ÿ 通过BitmapFactorydecodeByteArray(byte[] data, int offset, int length)方法将数据转换为图片对象

8.3. 获取XML

Ÿ 使用URL封装路径,打开一个HttpURLConnection

Ÿ 设置头信息之后获取相应码,从输入流中获取数据

Ÿ 使用XmlPullPaser解析

8.4. 获取JSON

Ÿ 使用URL封装路径,打开一个HttpURLConnection

Ÿ 设置头信息之后获取相应码,从输入流中获取数据

Ÿ 将数据转为String,封装成JSONArray对象

Ÿ 遍历JSONArray对象,调用获取其中的JSONObject

Ÿ 再从JSONObject中获取每个字段的信息

8.5. 发送GET请求

Ÿ 拼接路径和参数,通过URL进行封装,打开一个HttpURLConnection,发送请求

Ÿ 如果参数是中文会出现乱码

Ÿ URL中包含的中文参数需要使用URLEncoder进行编码

Ÿ 服务器端如果是TOMCAT,其默认使用ISO8859-1编码,接收时需要处理编码问题

8.6. 发送POST请求

Ÿ 通过URL打开一个HttpURLConnection

Ÿ 头信息中除了超时时间和请求方式之外还必须设置Content-Type和Content-Length

Ÿ 从HttpURLConnection获得输出流输出参数数据

Ÿ 服务端可以使用request对象的setCharacterEncoding方法设置编码

8.7. 发送XML,访问WebService

Ø 发送XML

Ÿ 通过URL封装路径打开一个HttpURLConnection

Ÿ 设置请求方式,Content-Type和Content-Length

XML文件的Content-Type为:text/xml; charset=UTF-8

Ÿ 使用HttpURLConnection获取输出流输出数据

Ø WebService

Ÿ WebService是发布在网络上的API,可以通过发送XML调用,WebService返回结果也是XML数据

Ÿ WebService没有语言限制,只要可以发送XML数据和接收XML数据即可

Ÿ http://www.webxml.com.cn 网站上提供了一些WebService服务,我们可以对其进行调用

Ÿ http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?op=getMobileCodeInfo 中提供了电话归属地查询的使用说明

 

 

 

 

 

 

 

 

 

8.8. HTTP协议上传文件

Ÿ 搭建服务器,完成上传功能

Ÿ 使用浏览器上传,查看请求信息

Ø HttpURLConnection

Ÿ 通过URL封装路径打开一个HttpURLConnection

Ÿ 设置请求方式以及头字段:Content-Type、Content-Length、Host

Ÿ 拼接数据发送

Ø Socket

Ÿ 使用HttpURLConnection发送时内部有缓存机制,如果上传较大文件会导致内存溢出

Ÿ 我们可以使用Socket发送TCP请求,将上传数据分段发送

Ø HttpClient

public void upload(String name, String password, String path) throws Exception {

// 创建HttpClient对象

HttpClient client = new HttpClient();

// 设置超时事件

client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);

// 创建一个Post请求指定路径

PostMethod postMethod = new PostMethod("http://192.168.1.102:8080/14.Web/LoginServlet");

// 封装每个表单项

Part[] parts = { new StringPart("name", name), new StringPart("password", password), new FilePart("file"new File(path)) };

// Post请求设置实体

postMethod.setRequestEntity(new MultipartRequestEntity(parts, postMethod.getParams()));

// 执行Post请求

client.executeMethod(postMethod);

// Post请求是释放资源

postMethod.releaseConnection();

}

8.9. 多线程断点续传下载器

 

 

 

Ÿ 在下载的时候多个线程并发可以占用服务器端更多资源,从而加快下载速度

Ÿ 手机端下载数据时难免会出现无信号断线、电量不足等情况,所以需要断点续传功能

Ÿ 根据下载数据长度计算每个线程下载的数据位置,程序中开启多个线程并发下载

在请求头中设置Range字段就可以获取指定位置的数据,例如:Range: bytes=100-200

Ÿ 在下载过程中记录每个线程已拷贝数据的数量,如果下载中断,下次启动时从记录位置继续下载

Ø 多线程下载

 

 

Ÿ 进度条使用进行配置

默认为圆形进度条,水平进度条需要配置style属性,?android:attr/progressBarStyleHorizontal

使用android.R.attr.progressBarStyleHorizontal作为样式

Ÿ 当点击下载按钮时开启多线程下载,下载过程中修改进度条进度

设置最大刻度:setMax()

设置当前进度:setProgress()

Ø 断点续传

Ÿ 断点续传需要在下载过程中记录每条线程的下载进度

Ÿ 每次下载开始之前先读取数据库,查询是否有未完成的记录,有就继续下载,没有则创建新记录插入数据库

Ÿ 在每次向文件中写入数据之后,在数据库中更新下载进度

Ÿ 下载完成之后删除数据库中下载记录

Ø Handler传输数据

Ÿ 主线程中创建的View只能在主线程中修改,其他线程只能通过和主线程通信,在主线程中改变View数据

Ÿ 我们使用Handler可以处理这种需求

主线程中创建Handler,重写handleMessage()方法

新线程中使用Handler发送消息,主线程即可收到消息,并且执行handleMessage()方法

Ø 动态生成新View

Ÿ 创建XML文件,将要生成的View配置好

Ÿ 获取系统服务LayoutInflater,用来生成新的View

LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);

Ÿ 使用inflate(int resource, ViewGroup root)方法生成新的View

Ÿ 调用当前页面中某个容器的addView,将新创建的View添加进来

 

9. 活动(Activity

9.1. 创建Activity

Ø 定义Activity

Ÿ 定义类继承Activity

Ÿ 在AndroidManifest.xml节点中声明

Ø 显式意图创建方式

Ÿ 构造函数,代码少

new Intent(this, NewActivity.class);

Ÿ 类名形式,灵活,可扩展性强

intent.setClassName(this"cn.itcast.activity.NewActivity");

Ÿ 包名类名形式,可启动其他程序中的Activity

intent.setClassName("cn.itcast.downloader""cn.itcast.downloader.MainActivity");

Ø 创建Activity并传递数据

Ÿ 在意图对象中封装了一个Bundle对象,可以用来携带数据

Ÿ 在新Activity中可以获得意图对象以获取其中Bundle保存的数据

Ø 创建Activity获取返回数据

Ÿ 使用startActivityForResult(Intent intent, int requestCode) 方法打开Activity

Ÿ 重写onActivityResult(int requestCode, int resultCode, Intent data) 方法

Ÿ 新Activity中调用setResult(int resultCode, Intent data) 设置返回数据之后,关闭Activity就会调用onActivityResult方法

Ø 隐式意图创建Activity

Ÿ 显式意图是指在创建意图时指定了组件,而隐式意图则不指定组件,通过动作、类型、数据匹配对应的组件

Ÿ 在清单文件中定义时需要定义才能被隐式意图启动

Ÿ 中至少配置一个和一个,否则无法被启动

Ÿ Intent对象中设置的actioncategorydata必须全部包含才能启动

Ÿ 中的都可以配置多个,Intent对象中不用全部匹配,每样匹配一个即可启动

Ÿ 如果一个意图可以匹配多个ActivityAndroid系统会提示选择

9.2. 生命周期

Ÿ Acitivity三种状态

运行:activity在最前端运行

暂停:activity可见,但前端还有其他acti vity,被覆盖一部分,或者前端activity透明

停止:activity不可见,完全被覆盖

Ÿ 生命周期相关方法

onCreate:创建时调用,或者程序在暂停、停止状态下被杀死之后重新打开时也会调用

onStartonCreate之后或者从停止状态恢复时调用

onResumeonStart之后或者从暂停状态恢复时调用,从停止状态恢复时由于调用onStart,也会调用onResume

onPause:进入暂停、停止状态,或者销毁时会调用

onStop:进入停止状态,或者销毁时会调用

onDestroy:销毁时调用

onRestart:从停止状态恢复时调用

 

 

Ÿ 保存信息相关方法

onSaveInstanceState:在Activity被动的摧毁或停止的时候调用,用于保存运行数据,可以将数据存在在Bundle

onRestoreInstanceState:该方法在Activity被重新绘制的时候调用,例如改变屏幕方向,savedInstanceState为onSaveInstanceState保存的数据

9.3. 启动模式

Ÿ 在AndroidManifest.xml中的标签中可以配置android:launchMode属性,用来控制Actvity的启动模式

Ÿ 在Android系统中我们创建的Acitivity是以栈的形式呈现的

standard:每次调用startActivity()启动时都会创建一个新的Activity放在栈顶

singleTop:如果启动的Activity时,指定Activity不在栈顶就创建,如在栈顶,则不再创建

singleTask:如果启动的Activity不存在就创建,如果存在直接跳转到指定的Activity所在位置

singleInstance:如果启动的Activity不存在就创建,如果存在就将指定的Activity移动到栈顶

9.4. 内存管理

Ÿ Android系统在运行多个进程时,如果系统资源不足,会强制结束一些进程。优先选择哪个进程来结束是有优先级的。以下顺序靠上的优先结束

空:进程中所有Activity都已销毁

后台:进程中有一个停止状态的Activity

可见:进程中有一个暂停状态的Activity

前台:进程中正在运行一个Activity

10. 广播接收者(BroadcastReceiver)

10.1. 定义广播接收者

Ÿ 定义类继承BroadcastReceiver,重写onReceive方法

Ÿ 清单文件中声明,需要在其中配置指定接收广播的动作

Ÿ 当接收到匹配广播之后就会执行onReceive方法

Ÿ BroadcastReceiver除了在清单文件中声明,也可以在代码中声明,使用registerReceiver方法注册Receiver

10.2. 发送广播

Ø 无序广播

Ÿ 使用sendBroadcast方法发送

Ÿ 被所有广播接收者接收,无序,不可中断

Ÿ 广播时可设置接收者权限,仅当接收者含有权限才能接收

Ÿ 接收者的也可设置发送方权限,只接收含有权限应用的广播

Ø 有序广播

Ÿ 使用sendOrderedBroadcast方法发送

Ÿ 接收者可以在中定义android:priority定义优先级,数字越大优先级越高

Ÿ 被各个广播接收者逐个接收,中途可以中断或者添加数据

abortBroadcast()  

getResultExtras(true).putString("data""新增数据");

10.3. 监听短信接收

Ÿ Android系统在收到短信的时候会发送一条有序广播,我们如果定义一个接收者接收这个广播,就可以得到短信内容,也可以拦截短信

Ÿ 定义广播接收者接收广播android.provider.Telephony.SMS_RECEIVED

Ÿ 在onReceive方法内部调用IntentgetExtras()再调用get(String)获取其中pdus字段,得到一个Object[],其中每一个元素都是一个byte[]

Ÿ 通过SmsMessage类的createFromPdu方法创建SmsMessage对象

Ÿ 从SmsMessage对象中即可获取发送者号码、短信内容、发送时间等信息

Ÿ 需要接收短信权限:<uses-permission android:name="android.permission.RECEIVE_SMS"/>

Ÿ Android系统中收到短信的通知是一个有序通知,我们如需拦截垃圾短信,可以配置较高的priority,收到信息进行判断是否abortBroadcast()

10.4. 监听呼出电话

Ÿ 定义广播接收者接收 android.intent.action.NEW_OUTGOING_CALL

Ÿ 需要权限 <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

Ÿ 在onReceive方法中使用getResultData() 和 setResultData() 方法获取和设置电话号码

10.5. 生命周期

Ÿ 广播接收者的生命周期是非常短暂的,在接收到广播的时候创建,onReceive()方法结束之后销毁

Ÿ 广播接收者中不要做一些耗时的工作,否则会弹出Application No Response错误对话框

Ÿ 最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉

Ÿ 耗时的较长的工作最好放在服务中完成

11. 服务(Service)

11.1. 基本概念

Ÿ Service是一种在后台运行,没有界面的组件,由其他组件调用开始。

Ÿ 创建Service,定义类继承ServiceAndroidManifest.xml中定义

Ÿ 开启Service,在其他组件中调用startService方法

Ÿ 停止Service,调用stopService方法

11.2. 电话录音

需要权限:android.permission.READ_PHONE_STATE

 

TelephonyManager manager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);

manager.listen(new MyListener(), PhoneStateListener.LISTEN_CALL_STATE);

 

private final class MyListener extends PhoneStateListener {

private String num;

private MediaRecorder recorder;

public void onCallStateChanged(int state, String incomingNumber) {

switch (state) {

case TelephonyManager.CALL_STATE_RINGING:

num = incomingNumber;

break;

case TelephonyManager.CALL_STATE_OFFHOOK:

try {

File file = new File(Environment.getExternalStorageDirectory(), num + "_" + System.currentTimeMillis() + ".3gp");

recorder = new MediaRecorder();

recorder.setAudioSource(AudioSource.MIC);

recorder.setOutputFormat(OutputFormat.THREE_GPP);

recorder.setAudioEncoder(AudioEncoder.AMR_NB);

recorder.setOutputFile(file.getAbsolutePath());

recorder.prepare();

recorder.start();

catch (Exception e) {

e.printStackTrace();

}

break;

case TelephonyManager.CALL_STATE_IDLE:

if (recorder != null) {

recorder.stop();

recorder.release();

}

break;

}

}

}

11.3. 绑定本地服务

Ÿ 使用bindService绑定服务,传入一个自定义的ServiceConnection用来接收IBinder

Ÿ 定义一个业务接口,其中定义需要的使用的方法

Ÿ 服务中自定义一个IBinder继承Binder并实现业务接口,在onBind方法中返回

Ÿ 调用端将IBinder转为接口类型,调用接口中的方法即可调用到服务中的方法

11.4. 绑定远程服务

Ÿ 远程绑定服务时无法通过同一个接口来调用方法,这时就需要使用AIDL技术

Ÿ 将接口扩展名改为“.aidl”

Ÿ 去掉权限修饰符

Ÿ gen文件夹下会生成同名接口

Ÿ 将服务中自定义的IBinder类改为继承接口中的Stub

Ÿ ServiceConnection中返回的IBinder是代理对象,不能使用强转,改用Stub.asInterface()

11.5. AIDL使用自定义类型

Ÿ AIDL默认只能使用Java中基本数据类型和StringListMapListMap中的元素类型也只能是这些类型。

Ÿ 如果需要使用其他类型数据,使用的类必须实现Parcelable接口以完成序列化和反序列化工作

重写 public void writeToParcel(Parcel dest, int flags)

定义 public static final Parcelable.Creator CREATOR

Ÿ 定义该类对应的AIDL

package 包名

parcelable 类名

Ÿ 在接口AIDL中导入该类,注意:即使是同一个包也需要导入

12. 多媒体

12.1. 音频播放器

 

 

12.2. 视频播放器

 

 

screenSV.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  // 设置缓冲区数据

screenSV.getHolder().setKeepScreenOn(true);  // 设置屏幕保持

screenSV.getHolder().addCallback(new MyCallback());  // 设置回调函数

 

player.reset();

player.setDisplay(screenSV.getHolder()); // 设置显式

player.setDataSource("/mnt/sdcard/1.mp4"); // 设置数据源

player.prepare(); // 准备

player.seekTo(position); // 跳转到指定位置

player.start();

12.3. 拍照

Ÿ 需要权限

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

Ÿ 打开摄像头

Camera.open()

SDK2.3之后支持前置摄像头,open方法可以接收一个int参数,用来指定哪个摄像头

Ÿ 设置预览显示位置

setPreviewDisplay(SurfaceHolder holder)

注意SurfaceView不在前端显示的时候会被销毁,恢复之后会重绘

Ÿ 开始预览 

startPreview()

将摄像头拍摄画面显示在SurfaceView中,在此之前可对摄像头进行参数配置

getParameters() 方法可以获取摄像头的相关参数Parameters,调用其内部方法即可进行配置

Ÿ 自动对焦

autoFocus(AutoFocusCallback cb)

自动对焦是一个异步操作,如果我们向等待自动对焦结束之后才开始拍照,需要传入一个回调对象,在其回调函数中调用拍照方法

Ÿ 拍照 

takePicture(ShutterCallback shutter, PictureCallback raw, PictureCallback jpeg)

拍照也是异步操作,需要通过回调函数来得到拍照之后的数据

注意拍照之后摄像头不回自动回到预览状态,需要重写调用startPreview()方法

12.4. 录像

Ÿ 需要权限

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

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

Ÿ 创建MediaRecorder

new MediaRecorder()

Ÿ 设置音频输入源

setAudioSource(int audio_source)

Ÿ 设置视频输入源

setVideoSource(int video_source)

Ÿ 设置输出格式

setOutputFormat(int output_format)

Ÿ 设置音频编码器

setAudioEncoder(int audio_encoder)

Ÿ 设置视频编码器

setVideoEncoder(int video_encoder)

Ÿ 设置预览显示位置

setPreviewDisplay(Surface sv)

Ÿ 设置输出文件

setOutputFile(String path)

Ÿ 准备录制

prepare()

Ÿ 开始录制

start()

开始录制之前需要结束摄像头的预览

Ÿ 结束录制释放资源

stop()

release()

13. 通知

13.1. 吐司通知

Ÿ 创建通知

Toast.makeText(Context context, CharSequence text, int duration)

Toast.makeText(Context context, int resId, int duration)

Ÿ 发送通知

show()

13.2. 状态栏通知

 

Ÿ 获取系统通知服务 

NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE)

Ÿ 创建通知

通过构造函数创建Notification(int icon, CharSequence tickerText, long when)

icon: 通知的图片资源ID

tickerText: 状态栏中显示的消息内容

when: 时间

Ÿ 创建PendingIntent以供点击时发送

PendingIntent.getActivity(Context context, int requestCode, Intent intent, int flags)

context: 当前上下文

requestCode: 请求码

intent: 点击时要发送的意图

flags: 类型PendingIntent中提供了常量选择

Ÿ 设置通知点击事件

调用Notification 对象方法setLatestEventInfo(Context context, CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent)

context: 当前上下文

contentTitle: 标题

contentText: 内容

contentIntent: 点击时触发的意图

Ÿ 设置通知点击后清除

设置Notification 对象属性 n.flags = Notification.FLAG_AUTO_CANCEL;

Ÿ 发送消息

调用Notification对象方法notify(int id, Notification notification)

13.3. 对话框通知

Ø 普通对话框

 

new AlertDialog.Builder(this//

.setTitle("普通对话框"//

.setMessage("普通内容"//

.setCancelable(false//

.setPositiveButton("YES", listener) // listener 为OnClickListener 监听器对象监听按钮被选中

.setNeutralButton("CANCEL", listener) //

.setNegativeButton("NO", listener) //

.show();

Ø 列表对话框

 

new AlertDialog.Builder(this//

.setTitle("列表对话框"//

.setCancelable(false//

.setItems(items, listener) // listener 为OnClickListener 监听器对象监听列表项被选中

.show();

Ø 单选对话框

 

new AlertDialog.Builder(this//

.setTitle("单选对话框"//

.setCancelable(false//

.setSingleChoiceItems(items, 0, choiceLinstener) // 0, 为默认选中索引choiceLinstener 为 OnClickListener 监听器对象监听单选按钮被选中

.setPositiveButton("确定", positiveLinstener) // positiveLinstener 为 OnClickListener 监听器对象监听确定按钮点击

.show();

Ø 多选对话框

 

new AlertDialog.Builder(this//

.setTitle("多选对话框"//

.setCancelable(false//

.setMultiChoiceItems(items, checkedArr, choiceListener) // checkedArr 为默认选中choiceListener 为 OnMultiChoiceClickListener 监听器对象监听多选按钮被选中

.setPositiveButton("确定", positiveLinstener) // positiveLinstener 为 OnClickListener 监听器对象监听确定按钮点击

.show();

Ø 进度对话框

 

ProgressDialog dialog = new ProgressDialog(this);

dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); // 设置进度条样式

dialog.setTitle("下载中");

dialog.setMessage("请稍候...");

dialog.setCancelable(false);

dialog.setMax(100);

dialog.show();

 

dialog.setProgress(10); // 设置进度

dialog.dismiss(); // 对话框结束

 

关于通知的文档位置:android-sdk-windows/docs/guide/topics/ui/notifiers/index.html

14. 常用UI

14.1. 列表视图(ListView)

 

Ø XML配置

Ÿ 在主界面中配置标签

Ÿ 在res/layout/文件夹下创建一个新的xml文件指定每个条目的布局

Ø Java代码构建ListView

Ÿ 获取ListView对象

Ÿ 设置一个Adapter

BaseAdapter:实现内部抽象方法

SimpleAdapter:以List>形式封装数据

SimpleCursorAdapter:以Cursor对象封装数据,Cursor中需要有“_id”一列

Ÿ 添加OnItemClickListener

调用ListViewgetItemAtPosition(int)方法可以获取封装数据的容器

如果传入的是BaseAdapter,获取到的就是我们自定义方法中返回的内容

如果传入的是SimpleAdapter,获取到的就是一个Map

如果传入的是SimpleCursorAdapter,获得到的就是一个Cursor,并且Cursor以指向选中的一条记录

14.2. 单选(RadioGroup)

 

Ÿ 定义

Ÿ 在中定义