android视频android播放器源码码 播放本地视频,其他基本就行,如果可以,加个登录界面

1.1.&什么是3G、4G
&Y&第三代移动通信技术(3rd&-&Generation),速率一般在几百Kbps,较之前的和在数据传输速度上有很大提升。
&Y&第四代移动通信技术(),速度可达到<span style="color: #Mbps以上,几乎可以满足人们的所有传输数据的需求。
&Y&目前主流的技术标准有三种:
WCDMA:全球以上的网络都是采用此种制式。中国联通运营。
CDMA2000:目前日韩及北美使用较多。中国电信运营。&
TD-SCDMA:中国自主知识产权的通信技术。中国移动运营。&
&Y&目前主流的技术为LTE,但还没有被广泛应用:
GSM&&&GPRS&&&EDGE&&&WCDMA&&&HSDPA&&&HSDPA+&&&LTE
1.2.&什么是Android&
&Y&Android本义指&,Google于年月日宣布的基于Linux平台的开源手机操作系统的名称,官方中文名:安卓&。
&Y&Android系统早期由原名为的公司开发,谷歌在年收购后,继续对系统开发运营。
&Y&底层内核只提供基本功能,其他的应用软件则由各公司自行开发,大部分程序以Java语言编写。
&Y&由于系统的开源特性,很多制造商都在生产系统的设备,如:摩托罗拉、、三星、索爱、、小米、华为、魅族等。
&Y&Android系统除了运行在智能手机上之外,还可以用做平板电脑、电视、汽车等很多设备上。
&Y&Android系统架构图:
1.3.&Android的版本升级
&Y&1.5&Cupcake(纸杯蛋糕)
拍摄播放影片,并支持上传到
支持立体声耳机,同时改善自动配对性能
最新的采用技术的浏览器,支持复制贴上和页面中搜索
性能大大提高
提供屏幕虚拟键盘
主屏幕增加音乐播放器和相框
应用程序自动随着手机旋转
短信、、日暦,浏览器的用户接口大幅改进,如可以批量删除邮件
相机启动速度加快,拍摄图片可以直接上传到
来电照片显示
&Y&1.6&Donut(甜甜圈)
重新设计的
文字转语音系统()&
快速搜索框&
全新的拍照接口&
查看应用程序耗电&
支持更多的屏幕分辨率。&
支持媒体引擎&
新增面向视觉或听觉困难人群的易用性插件
&Y&2.1&&Eclair(闪电泡芙)
优化硬件速度
"Car&Home"程序
支持更多的屏幕分辨率
改良的用户界面
新的浏览器的用户接口和支持
新的联系人名单
更好的白色黑色背景比率
改进&3.1.2
支持内置相机闪光灯
支持数码变焦
改进的虚拟键盘
支持动态桌面的设计
&Y&2.2&Froyo(冻酸奶)
支持将软件安装至扩展内存
加强软件的速度
新增软件启动快速至电话和浏览器
USB分享器和热点功能
支持在浏览器上传档案
更新中的批量和自动更新
增加对的支持(安全政策)
集成的到浏览器
加强快速搜索小工具
更多软件能透过更新,类似中的更新
速度和性能优化
&Y&<span style="color: #&Gingerbread(姜饼)
支持更大的屏幕尺寸和分辨率(及更高)
系统级复制粘贴
重新设计的多点触摸屏幕键盘
本地支持多个镜头(用于视频通话等)和更多传感器(陀螺仪、气压计等)
电话簿集成功能
强化电源、应用程序管理功能
新增下载管理员
优化游戏开发支持
多媒体音效强化
从转换到文件系统
开放了屏幕截图功能
对黑色及白色的还原更加真实
&Y&3.x&Honeycomb(蜂巢)
仅供平板电脑使用
Google&eBooks上提供数百万本书
支持平板电脑大萤幕、高分辨率
Google&Talk视讯功能
3D加速处理
网页版详细分类显示,依个人分别设定安装应用程序
新的短消息通知功能
专为平板电脑设计的用户界面(重新设计的通知列与系统列)
加强多任务处理的接口
重新设计适用大屏幕的键盘及复制粘贴功能
多个标签的浏览器以及私密浏览模式
快速切换各种功能的相机
增强的图库与快速滚动的联络人接口
更有效率的接口
支持多核心处理器
3.2优化吋平板显示
&Y&4.0&Ice&Cream&Sandwich(奶油三明治)
虚拟按键,增大屏幕面积同时控制手机整体大小
桌面插件列表呈现在标签页中,与程序列表类似并且共存
文件夹更容易创建和管理,与类似
可定制的桌面系统
可视语音邮件&&
日历支持缩放操作
Gmail离线搜索,两行预览,以及底部新快捷栏
音量下键电源键组合截图
改进虚拟键盘纠错
从锁屏界面直接访问应用程序
优化复制粘贴
新版浏览器
流量控制系统
人脸识别,刷脸解锁
内置照片编辑器
多任务列表
新的图库布局和组织方式
联系人应用整合社交网络信息
Android&Beam
1.4.&主流智能手机操作系统
2.&搭建开发环境
2.1.&所需资源
&Y&JDK,开发环境。下载地址:
&Y&Eclipse,公司开发的一款开源。
&Y&Android&SDK,开发工具,包含开发程序所需类库、源码、文档、案例等资源。
&Y&ADT插件,ADT&是&平台下用来开发&应用程序的插件。
2.2.&Eclipse安装ADT插件
2.3.&配置SDK路径
2.4.&启动虚拟机
&O&点击机器人图标
&O&弹出虚拟机管理器
&O&修改虚拟机默认目录
指定环境变量android_sdk_home,通常指定为所在目录,可以随意指定。
重启之后将会以这个目录作为存放虚拟机文件的位置。
&O&配置虚拟机
&Y&Name:虚拟机的名字,可随意定义
&Y&Target:虚拟机版本
&Y&SD&Card&-&Size:虚拟机的大小,会在本地硬盘创建指定大小的文件用来存储数据,模拟真实手机的
如果使用原有文件,可以选择并点击指定文件
&Y&Snapshot:&保存快照,可以提高虚拟机启动速度
&Y&Skin&-&Built-in:选择分辨率
WQVGA400:
WQVGA432:
也可以选择自行指定
&O&成功进入操作系统界面
&Y&如果虚拟机显示无信号,需要对电脑的网络连接进行配置
无论电脑是否联网,地址、子网掩码、默认网关、首选服务器都需要配置
&Y&电脑如果未连接局域网或互联网,可以见默认网关和首选服务器配置成本机,例如:
&Y&电脑如果已连接局域网,需要将网关和首选服务器进行设置,例如:
&Y&如果电脑已连接互联网,正常情况虚拟机不会显示无信号,重启虚拟机
2.5.&命令行操作
为了能在任意目录使用一下命令,需要将目录下的platform-tools文件夹路径和tools文件夹路径配置到环境变量中
&Y&列出可以使用的版本
android&list&targets
&Y&列出可以使用的虚拟机
android&list&avd
&Y&创建虚拟机
android&create&avd&&n&&虚拟机名版本卡大小屏幕尺寸
&Y&启动虚拟机
emulator&&avd&&虚拟机名
&Y&显示已连接的设备
adb&devices
&Y&导入文件到手机
adb&push&&Windows源文件路径手机目标路径
&Y&从手机导出文件
adb&pull&&手机源文件路径目录路径
&Y&安装程序
adb&install&&apk文件路径
&Y&卸载程序
adb&uninstall&&包名
adb&kill-server
abd&start-server
3.&开发一个程序
3.1.&创建Android程序
&Y&Project&name:项目名
&Y&Build&Target:版本
&Y&Application&name:程序名,显示在程序列表中,以及程序启动后的标题栏
&Y&Package&name:包名,程序的唯一标识
&Y&Create&Activity:选择程序启动时是否创建一个窗体,设置主窗体名字
&Y&Min&SDK&Version:设置运行该程序所需的最低版本
3.2.&安装、卸载程序
&Y&Eclipse安装
右键点击工程&&&Run&as&&&Android&Application
&Y&虚拟机卸载
设置&&&应用程序&&&管理应用程序&&&选中要卸载的程序&&&卸载
3.3.&了解项目目录结构
&Y&src:源代码
&Y&gen:系统自动生成的文件
R.java&中记录了项目中各种资源
&Y&res:系统资源,所有文件都会在文件生成资源
drawable:图片
layout:界面布局
values:数据
anim:定义动画的
raw:原生文件
&Y&assets:资源路径,不会在文件注册
&Y&project.properties:供使用,读取该项目使用版本号。早期版本名为:
&Y&AndroidManifest.xml:清单文件,在软件安装的时候被读取
Android中的四大组件(、、、)都需要在该文件中注册
程序所需的权限也需要在此文件中声明,例如:电话、短信、互联网、访问卡
&Y&bin:二进制文件,包括、资源文件、、等
&Y&proguard.cfg:用来混淆代码的配置文件,防止别人反编译
3.4.&程序启动过程
&Y&Eclipse将源文件编译成
&Y&使用工具将所有文件转换为文件
&Y&再将文件和所有资源打包成文件
&Y&将文件安装到虚拟机完成程序安装
&Y&启动程序&&&开启进程&&&开启主线程
&Y&创建对象&&&执行方法
&Y&按照文件初始化界面
4.&演示案例
4.1.&电话拨号
&Y&搭建界面需要组件:、、
&Y&当点击时获取中文本
&Y&使用向系统内置的电话拨号器发送意图拨打电话
&Y&注册拨打电话权限
4.2.&查看程序错误信息
&Y&Android程序中如果出错,错误不会显示在中,而是显示在界面下。可以从&&show&view中打开
&Y&日志信息分为个级别:高级的包含低级的
&Y&可以创建过滤器对日志进行过滤显示,点击绿色加号,可以按照、、进行筛选
4.3.&将程序安装到真实手机
&Y&在电脑上安装手机驱动
有些手机自带驱动,有些没有,可以从官网下载。或者可以使用&豌豆荚&软件自动安装。
&Y&在手机设置中打开调试,将手机用数据线连接到电脑
我的手机是:三星&&&
双核1228MHz、1GB&RAM&、4GB&ROM、480&800像素、Android&2.3、4.3英寸
&Y&检查的设备管理器中是否显示出新设备
如果未能显示出设备,检查驱动安装是否正常,调试是否打开
&Y&Eclipse安装程序
Eclipse上右键点击工程&&&Run&as&&&Android&Application&&&自动安装运行
&Y&手动打包安装
右键点击工程&&&Export&&&Export&Android&Application&&&选择或创建密钥对程序签名并打包生成文件
将文件放到手机的卡中,通过手机文件浏览器执行安装
4.4.&短信发送
&Y&搭建界面需要组件:、、
&Y&给添加监听器,当被点击的时候获取号码,获取内容
&Y&使用发送短信
&Y&需要注册短信发送权限
&O&RelativeLayout(相对布局)
&Y&android-sdk-windows/docs/guide/topics/ui/layout-objects.html#relativelayout
&O&TableLayout(表格布局)
android-sdk-windows/docs/guide/topics/ui/layout-objects.html#tablelayout
&O&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
&O&项目中添加测试类
&Y&在清单文件中添加配置
&instrumentation&android:targetPackage="cn.itcast.junit"&android:name="android.test.InstrumentationTestRunner"&/&
&uses-library&android:name="android.test.runner"&/&
&Y&定义一个类继承,定义测试方法
&Y&在视图下右键点击测试方法&&&Run&as&&&Android&Junit&Test
&O&创建测试项目
&Y&输入项目名,选择一个已存在的工程,可以自动配置环境
4.7.&日志信息
&Y&在视图中我们可以看到程序的日志信息,也可以在程序中输出信息到中
&Y&程序中我们可以使用类来输出信息
&Y&System.out和输出的信息也会显示在中,注意输出信息是级别,是级别
5.&文件操作(、、)
5.1.&读写文件
&O&写入文件到卡
&Y&需要在清单文件中注册权限
&uses-permission&android:name="android.permission.WRITE_EXTERNAL_STORAGE"&/&
&Y&2.1版本以下的位置和之后版本不同
可以通过Environment.getExternalStorageDirectory()获取当前位置,兼容所有版本
&Y&获取状态
通过Environment.getExternalStorageState()方法获取当前状态
常量&Environment.MEDIA_MOUNTED&为已安装
&O&写入文件
&Y&通过openFileOutput(String&name,&int&mode)可以获取一个文件输入流
name为文件名,为文件模式,有种模式
输出流指向路径为:包名
&Y&文件模式在中有定义常量
MODE_PRIVATE 私有
MODE_WORLD_READABLE 其他程序可读(不可写)
MODE_WORLD_WRITEABLE 其他程序可写(不可读)
模式可以组合使用,例如:MODE_WORLD_READABLE&+&MODE_WORLD_WRITEABLE
MODE_APPEND 追加
&O&读取文件
&Y&通过openFileInput(String&name)可以获取一个文件输入流
该输入流可以读取&包名路径下的文件
&Y&获取当前程序文件路径
ContextWrapper.getFilesDir()
&O&Pull简介
&Y&常见的解析方式有三种,、、,系统中推荐使用
&Y&Pull解析器是一个开源的项目,系统内部解析文件均为此种方式,也可用于项目
&Y&Android&SDK中已经集成了解析器,无需添加任何文件
&Y&Pull解析器运行方式与类似,提供各种事件的判断
&Y&官方网站:
&O&使用解析器解析文件
&Y&Xml.newPullParser()&获得解析器
&Y&parser.setInput(in,&"UTF-8")&设置输入流以及编码
&Y&parser.next()&获取下一个解析事件,得到一个事件代码
&Y&XmlPullParser中定义了常量来标识各种解析事件
START_DOCUMENT、END_DOCUMENT&、、END_TAG&、
&O&使用XmlSerializer写出
&Y&使用以下方法生成,和文档顺序类似
startDocument
endDocument
5.3.&偏好设定(SharedPreferences)&
&Y&在程序中保存一些配置参数的时候我们经常使用
Context.getSharedPreferences(String&name,int&mode)
该方法可以在目录下创建一个以命名的文件,文件为模式
&Y&存储偏好
调用edit()方法可以获取一个对象,对数据进行存储,存储之后需要调用commit()保存到文件
&Y&读取偏好
获得SharedPreferences之后调用、等方法获取其中设置的值
&Y&在中获取SharedPreferences
在中可以调用getPreferences(int&mode)方法获得一个SharedPreferences,文件名和名一致
6.&数据库()
6.1.&SQLite特点
&Y&Android平台中嵌入了一个关系型数据库,和其他数据库不同的是存储数据时不区分类型
例如一个字段声明为类型,我们也可以将一个字符串存入,一个字段声明为布尔型,我们也可以存入浮点数。
除非是主键被定义为,这时只能存储位整数
&Y&创建数据库的表时可以不指定数据类型,例如:
CREATE&TABLE&person(id&INTEGER&PRIMARY&KEY&AUTOINCREMENT,&name&VARCHAR(20))
CREATE&TABLE&person(id&INTEGER&PRIMARY&KEY&AUTOINCREMENT,&name)
&Y&SQLite支持大部分标准语句,增删改查语句都是通用的,分页查询语句和相同
SELECT&*&FROM&person&LIMIT&20&OFFSET&10
SELECT&*&FROM&person&LIMIT&10,20
6.2.&创建数据库
&Y&定义类继承SQLiteOpenHelper
&Y&声明构造函数,个参数
&Y&重写()方法
&Y&重写方法
&Y&注意:数据库中列一旦创建不能修改,如果一定要修改,需要重新创建表,拷贝数据
6.3.&CRUD操作
&Y&和访问数据库不同,操作数据库无需加载驱动,不用获取连接,直接可以使用
获取对象之后通过该对象直接可以执行语句
SQLiteDatabase.execSQL()
SQLiteDatabase.rawQuery()
&Y&getReadableDatabase()和getWritableDatabase()的区别
查看源代码后我们发现getReadableDatabase()在通常情况下返回的就是getWritableDatabase()拿到的数据库
只有在抛出异常的时候才会以只读方式打开
&Y&数据库对象缓存
getWritableDatabase()方法最后会使用一个成员变量记住这个数据库对象,下次打开时判断是否重用
&Y&SQLiteDatabase封装了、()、()、()四个方法也可以对数据库进行操作
这些方法封装了部分语句,通过参数进行拼接
6.4.&事务管理
&Y&在使用数据库时可以用SQLiteDatabase类中定义的相关方法控制事务
beginTransaction()&开启事务
setTransactionSuccessful()&设置事务成功标记
endTransaction()&结束事务
&Y&endTransaction()需要放在中执行,否则事务只有到超时的时候才自动结束,会降低数据库并发效率
7.&内容提供者()
7.1.&什么是内容提供者
&Y&内容提供者是中的四大组件之一,可以将应用中的数据对外进行共享
&Y&内容提供者将数据的访问方式统一,不必针对不同数据类型采取不同的访问策略
&Y&内容提供者将数据封装,只暴露出我们希望提供给其他程序的数据
&Y&内容提供者中数据更改可被监听
7.2.&创建内容提供者
&Y&定义类继承,根据需要重写内部方法
&Y&在清单文件的节点下进行配置,标签中需要指定和属性
name为类名,包名从程序开始,以&&开始
authorities:是访问时的路径,要唯一
&Y&URI代表要操作的数据,由、、三部分组成
content://cn.itcast.sqlite.provider/person
scheme:固定为,代表访问内容提供者
authorites:节点中的属性
path:程序定义的路径,可根据业务逻辑定义
7.3.&完成CRUD方法
&Y&当程序调用方法时会传入
&Y&我们通过判断调用者要操作的数据
可以使用工具类来判断
addURI方法可以添加
match方法可以匹配一个判断其类型
&Y&根据业务逻辑操作数据
7.4.&访问内容提供者
&Y&通过获得对象
&Y&调用对象的方法即可访问内容提供者
7.5.&完成getType方法
&Y&如果返回数据是单条数据:vnd.android.cursor.item&
&Y&如果返回数据是多条数据:vnd.android.cursor.dir
7.6.&监听内容提供者数据变化
&Y&在内容提供者中可以通知其他程序数据发生变化
通过的getContentResolver()方法获取ContentResolver
调用其notifyChange()方法发送数据修改通知
&Y&在其他程序中可以通过ContentObserver监听数据变化
通过的getContentResolver()方法获取ContentResolver
调用其registerContentObserver()方法指定对某个注册ContentObserver
自定义ContentObserver,重写方法获取数据
7.7.&GIT获取源代码
&O&资源地址
GIT1.7.7安装后不能卸载,可以用其他版本覆盖后再卸载。
使用时不要使用中文目录,否则会报错无法启动。删除盘中.gitconfig文件可以解决。
7.8.&监听短信
&Y&Android系统提供了对短信进行查询,当发出短信时也会发送更改通知
&Y&短信数据库在&
&Y&定义一个监听"content://sms"
&Y&在方法中查询"content://sms"
&Y&需要权限android.permission.READ_SMS
7.9.&操作联系人
&O&获取所有联系人
&Y&Android系统中的联系人也是通过来对外提供数据的
&Y&数据库路径为:
&Y&我们需要关注的有张表
raw_contacts:其中保存了联系人
data:和是多对一的关系,保存了联系人的各项数据
mimetypes:为数据类型
&Y&Provider的为com.android.contacts
&Y&查询表的路径为:contacts
&Y&查询表的路径为:contacts/#/data
这个路径为连接查询,直接查询&&字段就可以根据&&查询到表中的数据
&Y&先查询得到每个联系人的,在使用从表中查询对应数据,根据分类数据
&O&通过电话号码获取联系人
&Y&系统内部提供了根据电话号码获取表数据的功能,路径为:data/phones/filter/*
&Y&用电话号码替换&&部分就可以查到所需数据,获取&&可以获取到联系人显示名
&O&添加联系人
&Y&先向表插入,路径为:raw_contacts
&Y&得到之后再向表插入数据,路径为:data
&O&使用事务添加联系人
&Y&在添加联系人得时候是分多次访问,如果在过程中出现异常,会出现数据不完整的情况,这些操作应该放在一次事务中
&Y&使用ContentResolver的applyBatch(String&authority,ArrayList&ContentProviderOperation&&operations)&方法可以将多个操作在一个事务中执行
&Y&文档位置
8.&网络通信
8.1.&获取文本数据
&Y&通过对象封装地址,打开一个
&Y&设置头信息之后获取响应码,如果成功返回即可从中获取输入流读取数据
&Y&代码过长屏幕显示不全可以使用进行显示
&Y&需要访问网络的权限
&uses-permission&android:name="android.permission.INTERNET"&/&
8.2.&获取网络图片
&Y&通过的decodeByteArray(byte[]&data,&int&offset,&int&length)方法将数据转换为图片对象
8.3.&获取XML
&Y&使用封装路径,打开一个
&Y&设置头信息之后获取相应码,从输入流中获取数据
&Y&使用解析
8.4.&获取JSON
&Y&使用封装路径,打开一个
&Y&设置头信息之后获取相应码,从输入流中获取数据
&Y&将数据转为,封装成对象
&Y&遍历对象,调用获取其中的
&Y&再从中获取每个字段的信息
8.5.&发送GET请求
&Y&拼接路径和参数,通过进行封装,打开一个,发送请求
&Y&如果参数是中文会出现乱码
&Y&URL中包含的中文参数需要使用进行编码
&Y&服务器端如果是,其默认使用编码,接收时需要处理编码问题
8.6.&发送POST请求
&Y&通过打开一个
&Y&头信息中除了超时时间和请求方式之外还必须设置Content-Type和Content-Length
&Y&从获得输出流输出参数数据
&Y&服务端可以使用对象的setCharacterEncoding方法设置编码
8.7.&发送XML,访问WebService
&Y&通过封装路径打开一个
&Y&设置请求方式,Content-Type和Content-Length
XML文件的Content-Type为:text/&charset=UTF-8
&Y&使用获取输出流输出数据
&O&WebService
&Y&WebService是发布在网络上的,可以通过发送调用,返回结果也是数据
&Y&WebService没有语言限制,只要可以发送数据和接收数据即可
&Y&&网站上提供了一些服务,我们可以对其进行调用
&Y&&中提供了电话归属地查询的使用说明
8.8.&HTTP协议上传文件
&Y&搭建服务器,完成上传功能
&Y&使用浏览器上传,查看请求信息
&O&HttpURLConnection
&Y&通过封装路径打开一个
&Y&设置请求方式以及头字段:Content-Type、Content-Length、Host
&Y&拼接数据发送
&Y&使用发送时内部有缓存机制,如果上传较大文件会导致内存溢出
&Y&我们可以使用发送请求,将上传数据分段发送
&O&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.&多线程断点续传下载器
&Y&在下载的时候多个线程并发可以占用服务器端更多资源,从而加快下载速度
&Y&手机端下载数据时难免会出现无信号断线、电量不足等情况,所以需要断点续传功能
&Y&根据下载数据长度计算每个线程下载的数据位置,程序中开启多个线程并发下载
在请求头中设置字段就可以获取指定位置的数据,例如:
&Y&在下载过程中记录每个线程已拷贝数据的数量,如果下载中断,下次启动时从记录位置继续下载
&O&多线程下载
&Y&进度条使用进行配置
默认为圆形进度条,水平进度条需要配置属性,?android:attr/progressBarStyleHorizontal
使用progressBarStyleHorizontal作为样式
&Y&当点击下载按钮时开启多线程下载,下载过程中修改进度条进度
设置最大刻度:setMax()
设置当前进度:setProgress()
&O&断点续传
&Y&断点续传需要在下载过程中记录每条线程的下载进度
&Y&每次下载开始之前先读取数据库,查询是否有未完成的记录,有就继续下载,没有则创建新记录插入数据库
&Y&在每次向文件中写入数据之后,在数据库中更新下载进度
&Y&下载完成之后删除数据库中下载记录
&O&Handler传输数据
&Y&主线程中创建的只能在主线程中修改,其他线程只能通过和主线程通信,在主线程中改变数据
&Y&我们使用可以处理这种需求
主线程中创建,重写handleMessage()方法
新线程中使用发送消息,主线程即可收到消息,并且执行handleMessage()方法
&O&动态生成新
&Y&创建文件,将要生成的配置好
&Y&获取系统服务,用来生成新的
LayoutInflater&inflater&=&(LayoutInflater)&getSystemService(LAYOUT_INFLATER_SERVICE);
&Y&使用inflate(int&resource,&ViewGroup&root)方法生成新的
&Y&调用当前页面中某个容器的,将新创建的添加进来
9.&活动()
9.1.&创建Activity
&Y&定义类继承
&Y&在的节点中声明
&O&显式意图创建方式
&Y&构造函数,代码少
new&Intent(this,&NewActivity.class);
&Y&类名形式,灵活,可扩展性强
intent.setClassName(this,&"cn.itcast.activity.NewActivity");
&Y&包名类名形式,可启动其他程序中的
intent.setClassName("cn.itcast.downloader",&"cn.itcast.downloader.MainActivity");
&O&创建并传递数据
&Y&在意图对象中封装了一个对象,可以用来携带数据
&Y&在新中可以获得意图对象以获取其中保存的数据
&O&创建获取返回数据
&Y&使用startActivityForResult(Intent&intent,&int&requestCode)&方法打开
&Y&重写onActivityResult(int&requestCode,&int&resultCode,&Intent&data)&方法
&Y&新中调用setResult(int&resultCode,&Intent&data)&设置返回数据之后,关闭就会调用onActivityResult方法
&O&隐式意图创建
&Y&显式意图是指在创建意图时指定了组件,而隐式意图则不指定组件,通过动作、类型、数据匹配对应的组件
&Y&在清单文件中定义时需要定义才能被隐式意图启动
&Y&&intent-filter&中至少配置一个和一个,否则无法被启动
&Y&Intent对象中设置的、、在必须全部包含才能启动
&Y&&intent-filter&中的、、都可以配置多个,对象中不用全部匹配,每样匹配一个即可启动
&Y&如果一个意图可以匹配多个,系统会提示选择
9.2.&生命周期
&Y&Acitivity三种状态
运行:在最前端运行
暂停:可见,但前端还有其他 vity,被覆盖一部分,或者前端透明
停止:不可见,完全被覆盖
&Y&生命周期相关方法
onCreate:创建时调用,或者程序在暂停、停止状态下被杀死之后重新打开时也会调用
onStart:之后或者从停止状态恢复时调用
onResume:之后或者从暂停状态恢复时调用,从停止状态恢复时由于调用,也会调用
onPause:进入暂停、停止状态,或者销毁时会调用
onStop:进入停止状态,或者销毁时会调用
onDestroy:销毁时调用
onRestart:从停止状态恢复时调用
&Y&保存信息相关方法
onSaveInstanceState:在被动的摧毁或停止的时候调用,用于保存运行数据,可以将数据存在在中
onRestoreInstanceState:该方法在被重新绘制的时候调用,例如改变屏幕方向,savedInstanceState为onSaveInstanceState保存的数据
9.3.&启动模式
&Y&在中的标签中可以配置属性,用来控制的启动模式
&Y&在系统中我们创建的是以栈的形式呈现的
standard:每次调用启动时都会创建一个新的放在栈顶
singleTop:如果启动的时,指定不在栈顶就创建,如在栈顶,则不再创建
singleTask:如果启动的不存在就创建,如果存在直接跳转到指定的所在位置
singleInstance:如果启动的不存在就创建,如果存在就将指定的移动到栈顶
9.4.&内存管理
&Y&Android系统在运行多个进程时,如果系统资源不足,会强制结束一些进程。优先选择哪个进程来结束是有优先级的。以下顺序靠上的优先结束
空:进程中所有都已销毁
后台:进程中有一个停止状态的
可见:进程中有一个暂停状态的
前台:进程中正在运行一个
10.&广播接收者
10.1.&定义广播接收者
&Y&定义类继承,重写方法
&Y&清单文件中声明&receiver&,需要在其中配置&intent-filter&指定接收广播的动作
&Y&当接收到匹配广播之后就会执行方法
&Y&BroadcastReceiver除了在清单文件中声明,也可以在代码中声明,使用registerReceiver方法注册Receiver
10.2.&发送广播
&O&无序广播
&Y&使用sendBroadcast方法发送
&Y&被所有广播接收者接收,无序,不可中断
&Y&广播时可设置接收者权限,仅当接收者含有权限才能接收
&Y&接收者的&receiver&也可设置发送方权限,只接收含有权限应用的广播
&O&有序广播
&Y&使用sendOrderedBroadcast方法发送
&Y&接收者可以在&intent-filter&中定义android:priority定义优先级,数字越大优先级越高
&Y&被各个广播接收者逐个接收,中途可以中断或者添加数据
abortBroadcast()&&
getResultExtras(true).putString("data",&"新增数据);
10.3.&监听短信接收
&Y&Android系统在收到短信的时候会发送一条有序广播,我们如果定义一个接收者接收这个广播,就可以得到短信内容,也可以拦截短信
&Y&定义广播接收者接收广播android.provider.Telephony.SMS_RECEIVED
&Y&在方法内部调用的再调用获取其中字段,得到一个Object[],其中每一个元素都是一个
&Y&通过SmsMessage类的createFromPdu方法创建对象
&Y&从对象中即可获取发送者号码、短信内容、发送时间等信息
&Y&需要接收短信权限:&uses-permission&android:name="android.permission.RECEIVE_SMS"/&
&Y&Android系统中收到短信的通知是一个有序通知,我们如需拦截垃圾短信,可以配置较高的priority,收到信息进行判断是否abortBroadcast()
10.4.&监听呼出电话
&Y&定义广播接收者接收&android.intent.action.NEW_OUTGOING_CALL
&Y&需要权限&&uses-permission&android:name="android.permission.PROCESS_OUTGOING_CALLS"/&
&Y&在方法中使用getResultData()&和&方法获取和设置电话号码
10.5.&生命周期
&Y&广播接收者的生命周期是非常短暂的,在接收到广播的时候创建,方法结束之后销毁
&Y&广播接收者中不要做一些耗时的工作,否则会弹出错误对话框
&Y&最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉
&Y&耗时的较长的工作最好放在服务中完成
11.1.&基本概念
&Y&Service是一种在后台运行,没有界面的组件,由其他组件调用开始。
&Y&创建,定义类继承,中定义&service&
&Y&开启,在其他组件中调用startService方法
&Y&停止,调用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&=&incomingN
case&TelephonyManager.CALL_STATE_OFFHOOK:
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();
case&TelephonyManager.CALL_STATE_IDLE:
if&(recorder&!=&null)&{
recorder.stop();
recorder.release();
11.3.&绑定本地服务
&Y&使用bindService绑定服务,传入一个自定义的ServiceConnection用来接收
&Y&定义一个业务接口,其中定义需要的使用的方法
&Y&服务中自定义一个继承并实现业务接口,在onBind方法中返回
&Y&调用端将转为接口类型,调用接口中的方法即可调用到服务中的方法
11.4.&绑定远程服务
&Y&远程绑定服务时无法通过同一个接口来调用方法,这时就需要使用技术
&Y&将接口扩展名改为&.aidl&
&Y&去掉权限修饰符
&Y&gen文件夹下会生成同名接口
&Y&将服务中自定义的类改为继承接口中的tub
&Y&ServiceConnection中返回的是代理对象,不能使用强转,改用tub.asInterface()
11.5.&AIDL使用自定义类型
&Y&AIDL默认只能使用中基本数据类型和、、,和中的元素类型也只能是这些类型。
&Y&如果需要使用其他类型数据,使用的类必须实现接口以完成序列化和反序列化工作
重写&public&void&writeToParcel(Parcel&dest,&int&flags)
定义&public&static&final&Parcelable.Creator&Person&&CREATOR
&Y&定义该类对应的
package&包名
parcelable&类名
&Y&在接口中导入该类,注意:即使是同一个包也需要导入
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.&拍照
&Y&需要权限
&uses-permission&android:name="android.permission.CAMERA"&/&
&Y&打开摄像头
Camera.open()
SDK2.3之后支持前置摄像头,方法可以接收一个参数,用来指定哪个摄像头
&Y&设置预览显示位置
setPreviewDisplay(SurfaceHolder&holder)
注意不在前端显示的时候会被销毁,恢复之后会重绘
&Y&开始预览&
startPreview()
将摄像头拍摄画面显示在中,在此之前可对摄像头进行参数配置
getParameters()&方法可以获取摄像头的相关参数Parameters,调用其内部方法即可进行配置
&Y&自动对焦
autoFocus(AutoFocusCallback&cb)
自动对焦是一个异步操作,如果我们向等待自动对焦结束之后才开始拍照,需要传入一个回调对象,在其回调函数中调用拍照方法
takePicture(ShutterCallback&shutter,&PictureCallback&raw,&PictureCallback&jpeg)
拍照也是异步操作,需要通过回调函数来得到拍照之后的数据
注意拍照之后摄像头不回自动回到预览状态,需要重写调用startPreview()方法
12.4.&录像
&Y&需要权限
&uses-permission&android:name="android.permission.RECORD_AUDIO"/&
&uses-permission&android:name="android.permission.CAMERA"/&
&Y&创建MediaRecorder
new&MediaRecorder()
&Y&设置音频输入源
setAudioSource(int&audio_source)
&Y&设置视频输入源
setVideoSource(int&video_source)
&Y&设置输出格式
setOutputFormat(int&output_format)
&Y&设置音频编码器
setAudioEncoder(int&audio_encoder)
&Y&设置视频编码器
setVideoEncoder(int&video_encoder)
&Y&设置预览显示位置
setPreviewDisplay(Surface&sv)
&Y&设置输出文件
setOutputFile(String&path)
&Y&准备录制
&Y&开始录制
开始录制之前需要结束摄像头的预览
&Y&结束录制释放资源
13.1.&吐司通知
&Y&创建通知
Toast.makeText(Context&context,&CharSequence&text,&int&duration)
Toast.makeText(Context&context,&int&resId,&int&duration)
&Y&发送通知
13.2.&状态栏通知
&Y&获取系统通知服务&
NotificationManager&nm&=&(NotificationManager)&getSystemService(NOTIFICATION_SERVICE)
&Y&创建通知
通过构造函数创建:&Notification(int&icon,&CharSequence&tickerText,&long&when)
icon:&通知的图片资源ID
tickerText:&状态栏中显示的消息内容
when:&时间
&Y&创建PendingIntent以供点击时发送
PendingIntent.getActivity(Context&context,&int&requestCode,&Intent&intent,&int&flags)
context:&当前上下文
requestCode:&请求码
intent:&点击时要发送的意图
flags:&类型,&PendingIntent中提供了常量选择
&Y&设置通知点击事件
调用Notification&对象方法:&setLatestEventInfo(Context&context,&CharSequence&contentTitle,&CharSequence&contentText,&PendingIntent&contentIntent)
context:&当前上下文
contentTitle:&标题
contentText:&内容
contentIntent:&点击时触发的意图
&Y&设置通知点击后清除
设置Notification&对象属性&n.flags&=&Notification.FLAG_AUTO_CANCEL;
&Y&发送消息
调用Notification对象方法:&notify(int&id,&Notification&notification)
13.3.&对话框通知
&O&普通对话框
new&AlertDialog.Builder(this)&//
.setTitle("普通对话框")&//
.setMessage("普通内容")&//
.setCancelable(false)&//
.setPositiveButton("YES",&listener)&//&listener&为监听器对象监听按钮被选中
.setNeutralButton("CANCEL",&listener)&//
.setNegativeButton("NO",&listener)&//
&O&列表对话框
new&AlertDialog.Builder(this)&//
.setTitle("列表对话框")&//
.setCancelable(false)&//
.setItems(items,&listener)&//&listener&为监听器对象监听列表项被选中
&O&单选对话框
new&AlertDialog.Builder(this)&//
.setTitle("单选对话框")&//
.setCancelable(false)&//
.setSingleChoiceItems(items,&0,&choiceLinstener)&//&0,&为默认选中索引,&choiceLinstener&为&监听器对象监听单选按钮被选中
.setPositiveButton("确定",&positiveLinstener)&//&positiveLinstener&为&监听器对象监听确定按钮点击
&O&多选对话框
new&AlertDialog.Builder(this)&//
.setTitle("多选对话框")&//
.setCancelable(false)&//
.setMultiChoiceItems(items,&checkedArr,&choiceListener)&//&checkedArr&为默认选中,&choiceListener&为&监听器对象监听多选按钮被选中
.setPositiveButton("确定",&positiveLinstener)&//&positiveLinstener&为&监听器对象监听确定按钮点击
&O&进度对话框
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(); //&对话框结束
关于通知的文档位置:
14.1.&列表视图(ListView)
&O&XML配置
&Y&在主界面中配置标签
&Y&在文件夹下创建一个新的文件指定每个条目的布局
&O&Java代码构建
&Y&获取对象
&Y&设置一个
BaseAdapter:实现内部抽象方法
SimpleAdapter:以形式封装数据
SimpleCursorAdapter:以对象封装数据,中需要有&&一列
调用的getItemAtPosition(int)方法可以获取封装数据的容器
如果传入的是,获取到的就是我们自定义方法中返回的内容
如果传入的是SimpleAdapter,获取到的就是一个
如果传入的是SimpleCursorAdapter,获得到的就是一个,并且以指向选中的一条记录
14.2.&单选(RadioGroup)
&Y&在中定义和
&Y&处理的点击事件
&Y&根据获取对象,调用其getCheckedRadioButtonId()方法可以获取其中被选中的RadioGroup的
&RadioGroup
&&&&android:id="@+id/lessonsRG"
&&&&android:layout_width="fill_parent"
&&&&android:layout_height="wrap_content"
&&&&android:orientation="horizontal"&&
&&&&&RadioButton
&&&&&&&&android:id="@+id/javaRB"
&&&&&&&&android:layout_width="fill_parent"
&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&android:layout_weight="1"
&&&&&&&&android:text="Java"&/&
&&&&&RadioButton
&&&&&&&&android:id="@+id/netRB"
&&&&&&&&android:layout_width="fill_parent"
&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&android:layout_weight="1"
&&&&&&&&android:text=".Net"&/&
&&&&&RadioButton
&&&&&&&&android:id="@+id/phpRB"
&&&&&&&&android:layout_width="fill_parent"
&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&android:layout_weight="1"
&&&&&&&&android:text="PHP"&/&
&&&&&Button
&&&&&&&&android:layout_width="fill_parent"
&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&android:layout_weight="1"
&&&&&&&&android:onClick="onRradioClick"
&&&&&&&&android:text="确定"&/&
&/RadioGroup&
public&void&onRradioClick(View&view)&{
RadioGroup&lessonRG&=&(RadioGroup)&findViewById(R.id.lessonsRG);
int&id&=&lessonRG.getCheckedRadioButtonId();& //&获取选中的id
String&msg&=&null;
switch&(id)&{
case&R.id.javaRB:
msg&=&"Java";
case&R.id.netRB:
msg&=&".Net";
case&R.id.phpRB:
msg&=&"PHP";
Toast.makeText(this,&msg,&0).show();
14.3.&多选(CheckBox)
&Y&定义若干和一个
&Y&处理的点击事件
&Y&根据获取每个,调用其isChecked()方法判断是否被选中
&LinearLayout
&&&&android:layout_width="fill_parent"
&&&&android:layout_height="wrap_content"&&
&&&&&CheckBox
&&&&&&&&android:id="@+id/javaCB"
&&&&&&&&android:layout_width="fill_parent"
&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&android:layout_weight="1"
&&&&&&&&android:text="Java"&/&
&&&&&CheckBox
&&&&&&&&android:id="@+id/netCB"
&&&&&&&&android:layout_width="fill_parent"
&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&android:layout_weight="1"
&&&&&&&&android:text=".Net"&/&
&&&&&CheckBox
&&&&&&&&android:id="@+id/phpCB"
&&&&&&&&android:layout_width="fill_parent"
&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&android:layout_weight="1"
&&&&&&&&android:text="PHP"&/&
&&&&&Button
&&&&&&&&android:layout_width="fill_parent"
&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&android:layout_weight="1"
&&&&&&&&android:onClick="checkboxOnClick"
&&&&&&&&android:text="确定"&/&
&/LinearLayout&
public&void&checkboxOnClick(View&view)&{
CheckBox&javaCB&=&(CheckBox)&findViewById(R.id.javaCB);
CheckBox&netCB&=&(CheckBox)&findViewById(R.id.netCB);
CheckBox&phpCB&=&(CheckBox)&findViewById(R.id.phpCB);
StringBuilder&sb&=&new&StringBuilder();
sb.append(javaCB.isChecked()&?&javaCB.getText()&+&"&"&:&"");
sb.append(netCB.isChecked()&?&netCB.getText()&+&"&"&:&"");
sb.append(phpCB.isChecked()&?&phpCB.getText()&+&"&"&:&"");
Toast.makeText(this,&sb,&0).show();
14.4.&下拉列表(Spinner)
&Y&定义标签
&Y&创建一个适配器
&Y&获取标签,调用setAdapter(SpinnerAdapter&adapter)方法设置一个适配器
&Y&调用setOnItemSelectedListener(OnItemSelectedListener&listener)方法设置监听器监听选中事件
&O&XML配置
&&&&android:id="@+id/spinner"
&&&&android:layout_width="fill_parent"
&&&&android:layout_height="wrap_content"&/&
&O&使用字符串构建适配器
private&void&setSpinnerByString()&{
final&Spinner&spinner&=&(Spinner)&findViewById(R.id.spinner);
ArrayAdapter&String&&adapter&=&new&ArrayAdapter&String&(this,&android.R.layout.simple_spinner_item);& //&设置样式
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); //&设置下拉后样式
adapter.add("Java");
adapter.add(".Net");
adapter.add("PHP");
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new&OnItemSelectedListener()&{
public&void&onItemSelected(AdapterView&?&&parent,&View&view,&int&position,&long&id)&{
String&selection&=&(String)&spinner.getItemAtPosition(position);
Toast.makeText(getApplicationContext(),&selection,&0).show();
public&void&onNothingSelected(AdapterView&?&&parent)&{
&O&使用构建适配器
private&void&setSpinnerByJavaBean()&{
final&Spinner&spinner&=&(Spinner)&findViewById(R.id.spinner);
ArrayAdapter&User&&adapter&=&new&ArrayAdapter&User&(this,&android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
adapter.add(new&User(1,&"lhm",&""));
adapter.add(new&User(2,&"yzk",&""));
adapter.add(new&User(3,&"hsp",&""));
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new&OnItemSelectedListener()&{
public&void&onItemSelected(AdapterView&?&&parent,&View&view,&int&position,&long&id)&{
User&selection&=&(User)&spinner.getItemAtPosition(position);
Toast.makeText(getApplicationContext(),&selection.getName(),&0).show();
public&void&onNothingSelected(AdapterView&?&&parent)&{
&O&使用资源文件构建适配器
&string-array&name="items"&
&&&&&item&Java&/item&
&&&&&item&.Net&/item&
&&&&&item&PHP&/item&
&/string-array&
private&void&setSpinnerByResource()&{
final&Spinner&spinner&=&(Spinner)&findViewById(R.id.spinner);
ArrayAdapter&CharSequence&&adapter&=&ArrayAdapter.createFromResource(this,&R.array.items,&android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new&OnItemSelectedListener()&{
public&void&onItemSelected(AdapterView&?&&parent,&View&view,&int&position,&long&id)&{
CharSequence&selection&=&(CharSequence)&spinner.getItemAtPosition(position);
Toast.makeText(getApplicationContext(),&selection,&0).show();
public&void&onNothingSelected(AdapterView&?&&parent)&{
&O&自定义适配器样式
&?xml&version="1.0"&encoding="utf-8"?&
&LinearLayout&xmlns:android="http://schemas.android.com/apk/res/android"
&&&&android:layout_width="match_parent"
&&&&android:layout_height="match_parent"
&&&&android:orientation="horizontal"&&
&&&&&ImageView
&&&&&&&&android:layout_width="50dp"
&&&&&&&&android:layout_height="50dp"
&&&&&&&&android:src="@android:drawable/ic_delete"&/&
&&&&&TextView
&&&&&&&&android:id="@+id/content"
&&&&&&&&android:layout_width="fill_parent"
&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&android:textSize="50sp"&/&
&/LinearLayout&
private&void&setSpinnerByCustom()&{
final&Spinner&spinner&=&(Spinner)&findViewById(R.id.spinner);
ArrayAdapter&CharSequence&&adapter&=&new&ArrayAdapter&CharSequence&(this,&R.layout.item,&R.id.content);
adapter.add("Java");
adapter.add(".Net");
adapter.add("PHP");
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new&OnItemSelectedListener()&{
public&void&onItemSelected(AdapterView&?&&parent,&View&view,&int&position,&long&id)&{
String&selection&=&(String)&spinner.getItemAtPosition(position);
Toast.makeText(getApplicationContext(),&selection,&0).show();
public&void&onNothingSelected(AdapterView&?&&parent)&{
14.5.&菜单(Menu)
&O&添加菜单项
&Y&重写的onCreateOptionsMenu(Menu&menu)方法
&Y&添加菜单项
调用方法中参数的add(CharSequence&title)&方法
&Y&添加子菜单
调用对象的addSubMenu(final&CharSequence&title)
该方法返回一个SubMenu对象
&Y&添加子菜单的菜单项
调用SubMenu对象的add(CharSequence&title)&方法
&O&处理菜单点击事件
&Y&重写的onOptionsItemSelected(MenuItem&item)&方法
参数即为被选中的菜单项
public&boolean&onCreateOptionsMenu(Menu&menu)&{
menu.add("增加");
menu.add("修改");
menu.add("删除");
SubMenu&subMenu&=&menu.addSubMenu("查询");
subMenu.add("按照序号查询");
subMenu.add("按照姓名查询");
subMenu.add("按照邮箱查询");
return&super.onCreateOptionsMenu(menu);
public&boolean&onOptionsItemSelected(MenuItem&item)&{
Toast.makeText(this,&item.getTitle(),&0).show();
return&super.onOptionsItemSelected(item);
14.6.&内容提示文本框(AutoCompleteTextView)
&O&单次提示
&AutoCompleteTextView
&&&&android:id="@+id/actv"
&&&&android:layout_width="fill_parent"
&&&&android:layout_height="wrap_content"
&&&&android:completionThreshold="1"&/&
private&void&setAutoCompleteTextView()&{
AutoCompleteTextView&actv&=&(AutoCompleteTextView)&findViewById(R.id.actv);
String[]&items&=&{&"tom",&"tony",&"terry",&"张孝祥",&"张海军",&"张泽华"&};
ArrayAdapter&String&&adapter&=&new&ArrayAdapter&String&(this,&android.R.layout.simple_dropdown_item_1line,&items);
actv.setAdapter(adapter);
&O&多次提示
&MultiAutoCompleteTextView
&&&&android:id="@+id/mactv"
&&&&android:layout_width="fill_parent"
&&&&android:layout_height="wrap_content"
android:completionThreshold="1"&/&
private&void&setMultiAutoCompleteTextView()&{
MultiAutoCompleteTextView&mactv&=&(MultiAutoCompleteTextView)&findViewById(R.id.mactv);
String[]&items&=&{&"tom",&"tony",&"terry",&"张孝祥",&"张海军",&"张泽华"&};
ArrayAdapter&String&&adapter&=&new&ArrayAdapter&String&(this,&android.R.layout.simple_dropdown_item_1line,&items);
mactv.setAdapter(adapter);
mactv.setTokenizer(new&MultiAutoCompleteTextView.CommaTokenizer());
14.7.&手势识别(GestureOverlayView)
&O&创建手势库
&Y&导入中的工程
android-sdk-windows\samples\android-8\GestureBuilder
这个工程不能直接导入,需要添加三个配置文件:.classpath、.project、default.properties
&Y&将工程部署到手机中,创建手势库
手势库会存储在手机卡的根目录,文件名为:gestures
将gestures放入文件夹下
&android.gesture.GestureOverlayView
&&&&android:id="@+id/gov"
&&&&android:layout_width="fill_parent"
&&&&android:layout_height="fill_parent"
android:gestureStrokeType="multiple"&/&
GestureOverlayView&gov&=&(GestureOverlayView)&findViewById(R.id.gov);
final&GestureLibrary&library&=&GestureLibraries.fromRawResource(this,&R.raw.gestures);
library.load();
gov.addOnGesturePerformedListener(new&OnGesturePerformedListener()&{
public&void&onGesturePerformed(GestureOverlayView&overlay,&Gesture&gesture)&{
ArrayList&Prediction&&list&=&library.recognize(gesture);
for&(Prediction&p&:&list)
System.out.println(p.name&+&":&"&+&p.score);
14.8.&网页视图(WebView)
&&&&android:id="@+id/webView"
&&&&android:layout_width="fill_parent"
&&&&android:layout_height="fill_parent"&/&
WebView&webView&=&(WebView)&findViewById(R.id.webView);
webView.getSettings().setBuiltInZoomControls(true); //&放大缩小按钮
webView.getSettings().setJavaScriptEnabled(true); //&JS允许&
webView.setWebChromeClient(new&WebChromeClient()); //&Chrome内核
webView.loadUrl("http://192.168.1.100:8080");
15.&样式与主题
15.1.&样式
&O&定义样式
&Y&设置样式,在文件夹下的任意文件中的&resources&中配置标签
&style&name="style1"&
&item&name="android:layout_width"&fill_parent&/item&
&item&name="android:layout_height"&wrap_content&/item&
&Y&继承样式,在标签中配置属性
&style&name="style2"&parent="@style/style1"&
&item&name="android:textColor"&#FF0000&/item&
&Y&继承样式,在中引用其他样式
&style&name="style2.style3"&
&item&name="android:textSize"&30sp&/item&
&O&使用样式
&Y&在文件的标签中配置属性
style="@style/style2.style3"
&&&&android:text="这是一个按钮"
15.2.&主题
&Y&定义过的样式也可以应用在和标签中,使用theme属性尽心配置
&style&name="theme"&
&item&name="android:windowNoTitle"&true&/item&
&item&name="android:windowFullscreen"&?android:windowNoTitle&/item&
&activity&android:name=".MainActivity"
&&&&&&&&&&&&&&&&&&android:label="@string/app_name"
&&&&&&&&&&&&&&&&&&android:theme="@style/theme"
&Y&?&表示引用其他属性的值
&Y&@&表示访问资源文件
&Y&如果使用内置的样式,自动提示的&&要替换成&&
16.&国际化与屏幕适配
16.1.&国际化
&Y&在和文件夹后加上语言以及地区名,程序中需要国际化的部分使用资源
values-en-rUK
values-en-rUS
values-zh-rCN
values-zh-rTW
&Y&匹配规则
在匹配资源时先会找语言、地区完全匹配的
如果没有地区匹配的,则查找语言匹配的
如果没有语言匹配的则找默认
16.2.&屏幕适配
&Y&在文件夹后加上分辨率,系统会根据屏幕尺寸自动选择
注意分辨率中的乘号是&&不是&&
&Y&如果没有匹配的分辨率会找默认文件夹
17.&动画特效
17.1.&Frame
&Y&通过多个画面连续播放实现动画效果
&Y&详见文档&android-sdk-windows/docs/guide/topics/resources/animation-resource.html
17.2.&Tween
&Y&将某个组件以渐变的方式实现透明、缩放、移动、旋转等动画效果
&Y&详见文档&android-sdk-windows/docs/guide/topics/resources/animation-resource.html
17.3.&使用动画切换Activity
&Y&在方法调用之后调用overridePendingTransition(int&enterAnim,&int&exitAnim)方法
enterAnim&进入的动画资源id
exitAnim&退出的动画 资源id
17.4.&使用动画翻页
&Y&XML配置
&ViewFlipper
android:id="@+id/viewFlipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
&&& &ImageView
&&&&android:layout_width="wrap_content"
&&&&android:layout_height="wrap_content"
&&&android:src="@drawable/bb2"
&&& &ImageView
&&&&android:layout_width="wrap_content"
&&&&android:layout_height="wrap_content"
&&&android:src="@drawable/bb3"
&/ViewFlipper&
&Y&Java代码
public&boolean&onTouchEvent(MotionEvent&event)&{
ViewFlipper&viewFlipper&=&(ViewFlipper)&findViewById(R.id.viewFlipper);
switch&(event.getAction())&{
case&MotionEvent.ACTION_DOWN:
start&=&event.getX();
case&MotionEvent.ACTION_UP:
float&end&=&event.getX();
if&(end&&&start)&{
viewFlipper.setInAnimation(this,&R.anim.previous_enter);
viewFlipper.setOutAnimation(this,&R.anim.previous_exit);
viewFlipper.showPrevious();
}&else&if&(end&&&start)&{
viewFlipper.setInAnimation(this,&R.anim.next_enter);
viewFlipper.setOutAnimation(this,&R.anim.next_exit);
viewFlipper.showNext();
return&super.onTouchEvent(event);
18.1.&传感器
&O&传感器参数
&Y&传感器类型
方向 Sensor.TYPE_ORIENTATION
加速 Sensor.TYPE_ACCELEROMETER
光线 Sensor.TYPE_LIGHT
磁场 Sensor.TYPE_MAGNETIC_FIELD
距离 Sensor.TYPE_PROXIMITY
温度 Sensor.TYPE_TEMPERATURE
&Y&传感器反应速度
SensorManager.SENSOR_DELAY_FASTEST
SensorManager.SENSOR_DELAY_GAME
SensorManager.SENSOR_DELAY_UI
SensorManager.SENSOR_DELAY_NORMAL
&O&使用方向传感器
&Y&获得传感器管理器
SensorManager&manager&=&(SensorManager)&getSystemService(SENSOR_SERVICE);
&Y&获得方向传感器
Sensor&sensor&=&manager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
&Y&注册监听器
manager.registerListener(listener,&sensor,&SensorManager.SENSOR_DELAY_NORMAL);
private&final&class&MySensorEventListener&implements&SensorEventListener&{
public&void&onSensorChanged(SensorEvent&event)&{
System.out.println(event.values[0]);
public&void&onAccuracyChanged(Sensor&sensor,&int&accuracy)&{
&Y&取消监听器
manager.unregisterListener(listener,&sensor);
18.2.&触摸事件
&Y&XML配置
&ImageView
&&&&android:id="@+id/image"
&&&&android:layout_width="wrap_content"
&&&&android:layout_height="wrap_content"
&&&&android:scaleType="matrix"
&&&&android:src="@drawable/image"&/&
&Y&Java代码
ImageView&imageView&=&(ImageView)&findViewById(R.id.image);
imageView.setOnTouchListener(new&MyOnTouchListener());
private&class&MyOnTouchListener&implements&OnTouchListener&{
private&float&x;
private&float&y;
private&Matrix&currentMatrix&=&new&Matrix(); //&用来操作图片的矩阵
private&Matrix&oldMatrix&=&new&Matrix();
public&boolean&onTouch(View&v,&MotionEvent&event)&{
switch&(event.getAction())&{
case&MotionEvent.ACTION_DOWN:& //&按下时
x&=&event.getX();&
//&获取x轴坐标
y&=&event.getY();
//&获取y轴坐标
oldMatrix.set(imageView.getImageMatrix()); //&记住位置
case&MotionEvent.ACTION_MOVE:& //&移动时
currentMatrix.set(oldMatrix);& //&设置成按下时记住的位置
currentMatrix.postTranslate(event.getX()&-&x,&event.getY()&-&y); //&改变位置
imageView.setImageMatrix(currentMatrix); //&移动图片
return&true;
&O&多点触摸
private&class&MyOnTouchListener&implements&OnTouchListener&{
private&float&x; //&图片移动前的x轴坐标
private&float&y; //&图片移动前的y轴坐标
private&Matrix&currentMatrix&=&new&Matrix();& //&用来移动图片的矩阵
private&Matrix&oldMatrix&=&new&Matrix(); //&图片移动前的矩阵
private&int&type; //&操作类型,&一根手指触摸还是两根手指触摸
private&float&start; //&第二根手指按下时的距离
private&float&end; //&两根手指移动后的距离
private&PointF&point; //&放大时的中心点
public&boolean&onTouch(View&v,&MotionEvent&event)&{
switch&(event.getAction()&&&MotionEvent.ACTION_MASK)&{
case&MotionEvent.ACTION_DOWN:
x&=&event.getX();
y&=&event.getY();
oldMatrix.set(imageView.getImageMatrix());
case&MotionEvent.ACTION_MOVE:
currentMatrix.set(oldMatrix);
if&(type&==&1)&{& //&1根手指触摸
currentMatrix.postTranslate(event.getX()&-&x,&event.getY()&-&y);
//&2跟手指触摸
end&=&countDistance(event);&
//&计算结束时距离
float&scale&=&end&/&start;& //&计算缩放比例
currentMatrix.postScale(scale,&scale,&point.x,&point.y);& //&设置缩放
case&MotionEvent.ACTION_POINTER_DOWN:
start&=&countDistance(event);&
//&计算开始时距离
point&=&countPoint(event);&
//&计算中心点
oldMatrix.set(imageView.getImageMatrix());
imageView.setImageMatrix(currentMatrix);& //&改变图片
return&true;
public&float&countDistance(MotionEvent&event)&{
float&a&=&event.getX(1)&-&event.getX(0);& //&x轴距离
float&b&=&event.getY(1)&-&event.getY(0);& //&y轴距离
return&(float)&Math.sqrt(a&*&a&+&b&*&b);& //&勾股定理
public&PointF&countPoint(MotionEvent&event)&{
float&x&=&(event.getX(0)&+&event.getX(1))&/&2;& //&x轴中间点
float&y&=&(event.getY(0)&+&event.getY(1))&/&2;& //&y轴中间点
return&new&PointF(x,&y);
18.3.&读取SIM卡
&O&电话号码、运营商信息
&Y&需要权限
&uses-permission&android:name="android.permission.READ_PHONE_STATE"&/&
&uses-permission&android:name="android.permission.ACCESS_COARSE_LOCATION"&/&
&Y&Java代码
TelephonyManager&manager&=&(TelephonyManager)&getContext().getSystemService(Context.TELEPHONY_SERVICE);
System.out.println("电话号码:&"&+&manager.getLine1Number());
System.out.println("运营商编号:&"&+&manager.getNetworkOperator());
System.out.println("运营商名字:&"&+&manager.getNetworkOperatorName());
&Y&需要权限
&uses-permission&android:name="android.permission.READ_CONTACTS"&/&
&uses-permission&android:name="android.permission.WRITE_CONTACTS"&/&
&Y&Java代码
Uri&uri&=&Uri.parse("content://icc/adn");
Cursor&c&=&getContentResolver().query(uri,&null,&null,&null,&null);
while&(c.moveToNext())
System.out.println(c.getString(c.getColumnIndex("name"))&+&":&"&+&c.getString(c.getColumnIndex("number")));
&O&通话记录
&Y&需要权限
&uses-permission&android:name="android.permission.READ_CONTACTS"&/&
&uses-permission&android:name="android.permission.WRITE_CONTACTS"&/&
&Y&Java代码
Uri&uri&=&CallLog.Calls.CONTENT_URI;
Cursor&c&=&getContentResolver().query(uri,&null,&null,&null,&null);
while&(c.moveToNext())
System.out.println(c.getString(c.getColumnIndex("number"))&+&":&"&+&c.getString(c.getColumnIndex("type")));
ContactsProvider\src\com\android\providers\contacts\&CallLogProvider.java
18.4.&安装程序
&Y&需要权限
&uses-permission&android:name="android.permission.INSTALL_PACKAGES"&/&
&Y&Java代码
File&file&=&new&File(Environment.getExternalStorageDirectory(),&"test.apk");
Intent&intent&=&new&Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file),&"application/vnd.android.package-archive");
startActivity(intent);
18.5.&关闭程序
&Y&杀死当前进程
Process.killProcess(Process.myPid());
&Y&退出虚拟机
System.exit(0);
&Y&根据包名关闭后台进程
ActivityManager&manager&=&(ActivityManager)&getSystemService(ACTIVITY_SERVICE);
manager.restartPackage("cn.itcast.test");
&uses-permission&android:name="android.permission.RESTART_PACKAGES"&/&
18.6.&使用HTML构建界面
&!DOCTYPE&html&PUBLIC&"-//W3C//DTD&HTML&4.01&Transitional//EN"&"http://www.w3.org/TR/html4/loose.dtd"&
&meta&http-equiv="Content-Type"&content="text/&charset=UTF-8"&
&title&Insert&title&here&/title&
&script&type="text/javascript"&
function&show(jsondata)&{
var&jsonobjs&=&eval(jsondata);
var&table&=&document.getElementById("personTable");
for&(&var&y&=&0;&y&&&jsonobjs.&y++)&{
var&tr&=&table.insertRow(table.rows.length);
var&td1&=&tr.insertCell(0);
var&td2&=&tr.insertCell(1);
td2.align&=&"center";
var&td3&=&tr.insertCell(2);
td3.align&=&"center";
td1.innerHTML&=&jsonobjs[y].
td2.innerHTML&=&jsonobjs[y].
td3.innerHTML&=&"&a&href='javascript:contact.call(\""&+&jsonobjs[y].phone&+&"\")'&"&+&jsonobjs[y].phone&+&"&/a&";
&body&onload="javascript:contact.showContacts()"&
&table&border="0"&width="100%"&id="personTable"&cellspacing="0"&
&td&width="30%"&姓名&/td&
&td&width="30%"&align="center"&存款&/td&
&td&align="center"&电话&/td&
&Y&XML代码
&&&&&&&&android:id="@+id/webView"
&&&&&&&&android:layout_width="fill_parent"
&&&&&&&&android:layout_height="fill_parent"&/&
&Y&Java代码
public&class&MainActivity&extends&Activity&{
private&WebView&webView;
public&void&onCreate(Bundle&savedInstanceState)&{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webView&=&(WebView)&findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("file:///android_asset/index.html");
webView.addJavascriptInterface(new&Contact(),&"contact");
private&final&class&Contact&{
public&void&showContacts()&{
String&json&=&"[{\"name\":\"zxx\",&\"amount\":\"99999\",&\"phone\":\"\"}]";
webView.loadUrl("javascript:show('"&+&json&+&"')");
public&void&call(String&phone)&{
startActivity(new&Intent(Intent.ACTION_CALL,&Uri.parse("tel:"&+&phone)));
18.7.&apk文件反编译
&Y&使用解压缩工具打开文件,找到其中文件
&Y&创建工程,导入dex2jar中的所有文件
&Y&创建运行环境运行其中pxb.android.dex2jar.v3.Main&类,&指定文件地址,会在同目录下生成文件
&Y&使用jd-gui打开文件获取源码
阅读(...) 评论()

我要回帖

更多关于 安卓音乐播放器源码 的文章

 

随机推荐