Android高级终端开发笔记
2021/6/19 下午 13:34开始
Android支持的音频格式有:MP3 WAV 3GP等。支持的视频格式有MP4 3GP等。
多媒体数据既可以来自android应用的资源文件,也可以来自外部存储器上的文件,还可以是来自网络的文件流。
android也提供了对摄像头 麦克风的支持。
11.1 音频和视频的播放
11.1.1 android 9增强的MediaPlayer
使用MediaPlayer装载音频文件完成之后,调用MediaPlayer对象的三个方法进行播放:
Start()函数,开始和回复播放
Stop()函数,停止播放
Pauser()函数,暂停播放
装载文件的时候,mediaplayer对象提供了如下的静态方法:
Create(Context context, Uri uri)函数,从指定的Uri装载音频文件,并返回创建的MediaPlayeru对象
Create(Context context,int resid)函数,从制定的资源文件id来装载音频文件,并返回MediaPlayer对象。
当需要循环播放多个音频文件的时候,使用MediaPlayer对象的setDataSource()方法来制定播放的音频文件的。
setDataSource(String path)函数,装载path路径代表的文件。
setDataSource(FileDecriptor fd,long offset,long length)函数,制定装载fd做代表的文件中从offset开始,长度为length的文件内容。
setDataSource(FileDecriptor fd),制定转载fd多代表的文件。
setDataSource(Context context,Uri uri)方法之后,指定装载uri所代表的文件。
使用上述的setDataSource()方法之后,MediaPlayer对象并没有真正地装载文件,需要使用其中的prepare()方法准备音频。(就是真正地装载音频文件)
Mediaplayer对象还提供了一些监听播放事件的方法:
setOnCompletionListener()方法为mediaPlayer对象增加播放完成事件绑定事件监听器。
setOnErrorListener()方法为该对象的播放错误事件绑定事件监听器。
setOnPreparedListener()方法为mediaplayer对象调用prepare()方法触发该监听器。
setOnSeekCompleteListener()方法,当mediaplayer对象调用seek()或seekTo()方法时候触发该监听器。
归纳一下使用MediaPlayer对象播放不同来源的音频文件:
播放应用的资源文件
1.调用MediapLayer对象的create()方法装载指定的资源文件。
播放应用的原始资源文件
注意:使用openFd()方法打开资源的时候,不管是哪一个,使用MediaPlayer播放的时候总是从资源的第一个开始。
播放外部存储器上的音频文件
播放来自网络的音频文件
有两种方式:
使用第二种方法播放来自网络的音频文件的步骤如下:
注意:mediaPlayer对象除了可以使用prepare()方法来准备声音之外,还可以使用prepareAsync()方法来准备声音。
两种方法的区别在于:prepareAsync()方法是异步的,不会阻塞当前的UI线程。
播放带数字版权保护(DRP)的媒体文件
Android 8 对MediaPlayer的功能进行了增强-从android 8 开始,mediaPlayer提供了方法来支持播放带有数字版权保护的媒体文件。MediaPlayer并没有提供MediaDrm的全部功能,但对大部分通用场景,MediaPlayer的功能已经足够。
mediaplayer支持处理以下内容类型
Widvine保护的本地媒体文件
Widvine保护的远程媒体文件
为了处理有数字版权保护的媒体文件,mediaPlayer对象在执行了prepare()方法之后调用getDrmInfo()方法来获得该媒体文件的数字版权保护信息,如果该方法返回的数字版权信息不是null,那么说明该文件存在数字版权保护,接下来程序就需要处理媒体文件的数字版权信息了。
使用mediapLayer对象的prepaerDrm()
使用MediaPlayer对象的getKeyRequest()方法
使用player对象的provideKeyResponse()方法
如果需要使用异步的方式来处理数字版权信息,MediaPlayer对象提供了setOnDrmListener()方法,为该方法传入的Mediaplayer.OnDrmInfoListener参数负责监听该媒体文件的数字版权信息。
Android 9 对mediaplayer进行了增强,内置了HDR VP9 视频的本地解码器,所以开发者可以直接使用Android本地解码器来播放HDR视频。
11.1.2 音乐特效控制
android可以控制播放音乐时的均衡器 重低音 音场 显示音乐波形等。
这些都是需要AudioEffect及其子类来完成的。
其包含的常用子类如下:
AcousticEchoCanceler:取消回声控制器
AutomaticGainControl:自动增益控制器。
NoiseSuppressor:噪音压制控制器
BassBoost:重低音控制器
Equalizer:均衡控制器
PresetReverb:预设音场控制器
Visualizer:示波器
上述的子类中前三个子类用法简单,只需要调用其中的create()方法创建相应的实例,然后调用他们的isAvailable()方法判断是否可用即可。再调用setEnabled(boolean enabled)方法启用相应效果即可。
后边四个类都需要调用构造器来创建实例,创建实例时,需要传入一个audioSession参数,为了启用他们,同样需要调用AudioEffect基类的setEnabled()方法。
获取BassBoost对象之后,调用它的setStrength(shot strength)方法来设置重低音的强度。
获取PresetReverb对象之后,可调用它的setPreset()方法设置使用预设置的音场。
Equalizer对象提供了getNumberOfPresets()方法获得系统所有预设的音场,并提供了getPresetName()方法获得预设音场的名称。
实例:音乐的示波器 均衡 重低音 和音场
//
使用上述子类的时候需要用到RECORD_AUDIO权限,因此需要设置权限。
在使用Visualizer对象绘制波形图的时候,这里创建了一个内部类View,用来将Visualizer对象传过来的数据动态绘制波形效果。
11.1.3 使用VolumeShaper控制声音效果
Android 8 新增了VolumnShaper对象来控制声音效果,VolumnShaper对象可以实现音量的淡入,淡出等自动音量转换效果。
使用该对象进行音量控制实际上是使用VolumnShapaer.Configuration来实现的,创建该对象时,主要通过三个方法来指定三个参数。
持续时间:duration,指定该声音效果的持续时间,以毫秒为单位。
插值方式:interpolator type:指定声音变化的插值方式。
音量曲线:volumn curve:指定音量变化的曲线。该参数需要两个长度相同的数组,第一个数组表示各时间点,第二个数组表示个时间点对应的音量。
这些数组的值必须在0-1f之间。
在创建了VolumnShaper.Configuration对象之后,调用支持VolumnShaper的声音播放器(如mediaplayer audioTrack等)的createVolumnShaper()方法创建VolumnShaper即可。
在使用声音播放器创建了VolumnShaper之后,必须调用VolumnShaper的play()方法,否则,只有第一个音量控制点指定的音量会作用于该声音效果。
综上所述,使用VolumnShaper控制声音效果的步骤如下:
11.1.4 使用SoundPool播放音效
可以管理短促的音效
可以在开始时加载多个音效,然后使用id来控制不同的音效来进行播放。
Android系统SoundPool提供了一个Builder内部类,该内部类专门用于创建SoundPool。
创建该对象之后,就可以使用该对象的四个load()方法来加载声音了。
Int load(Context context,int resid,int priority):从resid所对应的资源加载声音。
Int load(FileDescriptor fd,long offest,long length,int priority):加载fd对应的文件中从offset开始长度为length的声音。
使用SoundPool播放指定声音的方法如下:
注意:
使用SoundPool播放声音的步骤如下:
实例:
创建SoundPool对象的代码:
重点注意:
11.1.5 使用VideoView播放视频
该组件位于android.widget包下的组件
使用VideoView组件加载指定视频的方法:
setVideoPath(String path)加载path文件所代表的视频
setVideoURI(Uri uri)方法加载uri所对应的视频。
实际上,与VideoView结合使用的还有一个MediaController类,作用是提供一个友好的图形界面,可以通过该界面实现对视频的播放控制。
重要代码实例:
当视频文件存在时:
注意:
11.1.6 使用MediaPlayer和SurfaceView播放视频
使用上述两种对象播放视频的步骤如下:
注意:由于程序需要使用SurfaceView来显示MediaPlayer的图像输出,所以需要使用一些代码来维护SurfaceView,SurfaceHolder对象。
代码如下:
11.2 使用MediaRecorder录制音频
步骤:
核心代码:
需要增加的权限:
重点:
11.3 控制摄像头拍照
11.3.1 Android 9 改进的Camera v2
使用Camera v2 API来控制摄像头拍照的步骤:
//实例:拍照时自动对焦
获得摄像头信息的代码:
通过stateCallback中的onOpened()方法的参数可以获得被打开的摄像头设备。
此外,在onOpened()方法中调用createCameraPreviewSession()方法创建了CameraCaptureSession,并开始预览取景。
重点注意:
11.3.2 录制视频短片
步骤:
其他代码和录制音频的一样。
//实例:录制生活短片
重要代码:
需要增加的权限:
录制声音的权限
使用摄像头的权限
使用外部存储器的权限
11.4 屏幕捕捉
使用android提供的MediaPlayerManager管理器。
步骤如下:
核心代码:
11.5 本章小结
OpenGL本身是高效、简洁的开放图形库接口。
定义了一个跨编程语言、跨平台的编程接口规范。
12.1 3D图形和3D开发基本知识
绘制3D图形需要用到的数据:
12.2 OpenGL 和 OpenGL ES简介
OpenGL具有更广泛的适应性。
OpenGL ES 是 OpenGL的一个子集。
12.3 绘制2D图形
12.3.1 在android中使用OpenGL ES
Android中支持提供了GLSurfaceView组件,该组件用于显示3D图形。
GLSurfaceView本身不提供绘制3D图形,而是由GLSurfaceView.Renderer来完成SurfaceView中3D图形的绘制。
步骤:
Abstract void onDrawFrame(GL10 gl):Renderer对象调用该方法绘制GLSurfaceView的当前帧。
Abstract void onSurfaceChanged(GL10 gl,int width,int height):当GLSurfaceView的大小改变时回调该方法。
Abstract void onSurfaceViewCreated(Gl10 gl,EGLConfig config):当GLSurfaceView被创建的时候回调该方法。
绘制3D图形的难点是:如何设置Renderer类。
当SurfaceView被创建时,系统会回调Renderer对象的onSurfaceCreated()方法,该方法可以对OpenGL ES执行一些无需任何改变的初始化,初始化代码如下:
GL10 就是OpenGL ES 的绘图接口。
关于上述代码中的方法说明如下:
在onSurfaceChanged()方法中用于初始化3D场景的代码是:
一些说明:
GLSurfaceView上的所有3D图形都是由Renderer的onDrawFrame(GL10 gl)方法绘制出来的,重写该方法的时候就要把所有的3D图形都绘制出来。
然后下面就可以调用gl10对象的方法开始绘制了。
12.3.2 绘制平面上的多边形
绘制3D图形就是通过多个平面图形形成的。
绘制2D图形如下:
上述第三个方法中的参数pointer参数用于指定顶点坐标值。是一个三维数组。
第一个参数size指定多少个pointer数组中的元素成为一个顶点位置。通常为3。
type参数指定顶点坐标值的类型。
第4个方法中pointer参数指定顶点的颜色值,也是一个一维数组。
其中的size通常设置为4,表示指定pointer数组中每4个元素作为一个顶点坐标值。
//实例
代码:
在onDrawFrame()方法中绘制图形:
其中,使用glTranslatef()方法目的是将图形的绘制保证在中心点上。
在onCreate()方法中使用如下代码即可实现绘制:
可以借助maya或3dMAX将顶点坐标数据导入到程序中实现绘制。
12.3.3 旋转
GL10提供了使用glRotatef()方法用于控制旋转。
该方法中的angle控制旋转角度,x,y,z参数则共同决定了旋转轴的方向。
实现不断旋转的特效只需要将旋转的角度增加即可。
只需要在onDrawFrame()方法最后添加:rotate+= 1;即可。
12.4 绘制3D图形
定义的顶点不在同一个平面上,并使用三角形将合适的顶点连接起来,就可以绘制出来一个3D图形了。
12.4.1 构建3D图形
GL10 提供了glDrawElements()方法,参数为:int mode,int count,int type,Buffer indices。根据indices指定的索引点来绘制三角形。
该方法的第一个参数指定绘制的图形类型,第二个参数指定一共包含多少个顶点,第三个参数最重要:其包装了一个长度为3N的数组,其中三个元素表示一个顶点。
3D图形的绘制需要在程序中指定每一个面由哪三个顶点组成。
12.4.2 应用纹理贴图
在Renderer实现类中的onSurfaceCreated()方法中启用纹理贴图。代码如下:
准备的图片的规格需要是:长,宽是2的N次方。
加载图片生成贴图的代码如下:
说明:
该方法所生成的纹理代号放入其中的testures数组中,offsets指定从第几个数组元素开始放置纹理代号。
在3D绘制中设置纹理贴图:
12.5 本章小结
第13章 android网络应用
android支持JDK自带的网络编程。
由于android删除了Apache HttpClient支持,有一个OkHttp框架的支持。可以取代原来的Apache HttpClietn支持。
13.1 基于TCP协议的网络通信
13.1.1 TCP协议基础
//略
13.1.2 使用ServeSocket创建TCP服务器端
可以接受其他实体连接请求的类是ServerSocket。
该对象包含的方法:
通常使用循环控制不断调用ServerSocket的accept()方法。
代码实例如下:
当未指定I地址的时候,ServerSocket会绑定到指定的本机默认IP地址。
推荐使用1024以上的端口号作为接收的端口号。
13.1.3 使用Socket进行通信
连接到服务器端时的客户端的socket的创建:
一旦服务器和客户端连接之后,就不需要在分服务器和客户端了。因为两者都可以发送和接受消息进行交互。
其中Socket提供了两个方法来实现消息的交互:
服务器端代码实例:
客户端代码实例:
注意:直接在UI线程中建立连接,是不合适的,会阻塞线程。
使用Socket对象的setSoTimeout(int timeout)方法来设置超时时长。
使用下述代码可以实现创建以恶搞Socket对象来直接在链接的时候设置超时时长:
13.1.4 加入多线程
服务器应当给每一个Socket单独启动一个线程。每个线程负责与一个客户端进行通信。
可以使用List保存所有的Socket对象。
代码:
其中的另外一个线程代码:
在run()方法中设置:
上述代码实际上实现了群发消息的功能。
每个客户端包含两个线程:
为了避免UI线程阻塞,程序将建立网络连接,与网络服务器通信等工作都交给ClientThread线程完成。
使用handler主要是为了实现子线程和UI界面进行数据交互。
13.2 使用URL访问网络资源
URL是指向互联网资源的指针。
URL的格式:
URL包含一个可以打开到资源的输入流。
URI的实例代表一个统一资源标识符,java中的URL不可以用来定位任何资源,唯一作用是解析。
URL对象的方法:
13.2.1 Android 9 安全性增强的URL
由于从Android 9 网络连接默认是加密的,那么如果访问的服务器是http的就需要在配置文件中加上:
第一种方式实例:
13.2.2 使用URLConnection对象提交请求:
URL的openConnection()方法创建URLConnection对象,程序可以使用该对象向URL请求获得资源。
创建一个URL的连接的步骤:
在建立和远程资源的实际连接之前,程序通过如下方法设置请求头字段:
注意:一定要先使用输入流然后再使用输出流。
JDK提供的访问特定响应头字段的值:
注意:发送post请求必须获得如下两行:
发送post请求:
13.3 使用HTTP访问网络:
13.3.1 使用HTTPURLConnection对象
该对象继承了URLConnection,也可以放松GET和POST请求。
该对象提供了如下便捷的方法:
//实例:多线程下载:
实现步骤:
代码中需要使用:inputStream的skip()方法跳过指定数量的字节。
13.3.2 使用OKHttp
如果只是向一个页面提交请求并获得服务器的响应,则完全可以使用前面所介绍的HttpURLConnetion来完成。
为了处理WEB站点包含的Session Cookie等,使用OKHttp实现。
使用步骤:
//实例:访问被保护的资源
(使用OKHttp来访问被保护的页面)
需要使用OKHttpClient对象实现登录网页。
只要应用程序使用同一个OKHttpClient对象发送请求,并让该对象管理Cookies,那么该对象就会自动维护和服务器之间的session状态。
OKHTTPClient有自己的线程池和连接池,可以进行复用。
为了在android中使用OKHTTP,首先需要下载OKHttp的两个jar包。(Okio)。
也可以使用Gradle下载:
这里总结一下实现网络通信的时候app端的activity常用代码块:
1.需要设置一个MyHandler类继承自Handler类,主要是为了获得线程传来的数据更新UI界面。
2.需要在onCreate()方法中初始化各种对象,然后添加一个requestPermission()来获得用户权限。
3.在Activity类内部创建一个线程类,主要是为了在和服务器端交互数据的时候不阻塞UI线程。
4.在使用了OKHttp框架的onCreate()方法内部,创建默认的该对象:
为了创建一个可以输入用户名和密码的对话框。
上述的FromBody对象用来封装请求的参数。
13.4 使用WebView组件进行混合开发
一种混合的开发方式:
Android + HTML 5混合开发
13.4.1 使用WebView浏览网页
//实例:迷你浏览器
13.4.2 使用WebView加载HTML代码
使用该对象的loadData()方法或者loadDataWithBaseURL()方法
后者中的参数:
13.4.3 使用webView中的javaScript调用Android方法
使用WebSettings工具类,该工具类提供了大量方法来管理WebView组件的选项设置。
其中的setJavaScriptEnabled(true)方法即可让WebView组件中的javaScript脚本调用Android中的方法。
为了将android对象暴漏给WebView中的js代码,WebView还提供了addJavascriptInterface(Object object,String name)方法。该方法负责将object对象暴漏给js中的name对象。
步骤:
在android将暴漏对象中的方法上添加上注释:@JavascriptInterface即表示:将该类中的该方法提供给了webView组件加载的html界面中的js代码。
在WebView组件中的代码如下:
13.5 本章小结
第14章 管理Android系统桌面
14.1 改变壁纸
使用WallpaperManager对象来改变壁纸,在该对象中改变壁纸的方法如下:
14.1.1 开发动态壁纸
开发动态壁纸的步骤如下:
(还可以有选择性地重写SurfaceHolder.Callback中的三个方法)
//14.1.2 实例:动态壁纸
还需要在配置文件中进行配置:
需要指定:
详细的配置实例:
才算完成了配置。
14.2 快捷方式
Android 8 提供了Pinned快捷方式替代原有的桌面快捷方式。
还提供了一个管理类ShortcutManager管理类。
Android中提供的添加快捷方式的方法:
14.2 静态快捷方式
步骤:
实例代码:
然后在/res/xml文件下创建一个xml文件:
对上述快捷方式配置的解释说明:
其中的子元素对应的启动的activity通过子元素指定。
android要求必须为 元素指定action属性。
14.2.2 动态快捷方式
方法如下:
14.2.4 桌面快捷方式(Pinned Shortcut)
//实例:让程序占领桌面
其中的button组件的点击事件为:
上述代码中的2中的Null参数位置表示可以设置当该桌面快捷方式创建成功的时候的回调方法。
14.3 管理桌面控件
14.3.1 开发桌面控件
桌面控件通过BroadcaseReceiver的形式来进行控制的。每一个桌面控件对应一个BroadcastReceiver。
为了简化桌面控件的开发,android系统提供了一个AppWidgetProvider类。
该类是AppWidgetProvider的子类。该类的生命周期方法(有四个):
步骤如下:
一般来说,RemoteViews组件所加载的界面中主要包含了ImageView和TextView组件两个组件。
具体代码实例:
由于AppWidgetProvider对象继承了BroadcastReceiver类,所以需要在配置文件中配置它。
需要指定: 和
具体代码实例:
此外还需要在/res/xml文件下设置一个appwidget_provider.xml文件:
文件的内容如下:
其中使用了 元素来描述桌面控件的基本信息。
使用桌面控件开发者可以将应用程序的运行界面直接放到桌面上。
//实例:液晶时钟
核心代码:
使用循环实现对数据的更新。
然后在配置文件中进行配置:
其中的resource的文件对应的详细内容和
大致一样。
14.3.2 显示带数据集的桌面控件(重点)
android为RemoteViews提供了如下的方法:
setRemoteAdapter()方法:该方法可以使用intent更新RemoteViews中ViewId对应的组件。
上面的方法的Intent参数应该封装一个RemoteViewsService参数。该参数虽然继承了Service组件,但是主要作用是为RemoteViews中viewId对应的组件提供列表项。
实例代码:
其中的RemoteViews xxx()方法返回的是一个RemoteViews对象。
提供了StackWidgetService之后,接下来开发AppWidgetProvider子类与开发普通AppWidgetProvider子类的步骤基本相同,此时调用的是:setRemoteAdapter(int viewId,Intent intent)方法。
其中,在provider实现类的onUpdate()方法中的代码为:
上述实例文件中的代码如下:
该实例同样需要在res/xml目录下添加一个元数据配置文件(主要是为了配置控件的显示等)。
14.4 本章小结
第15章 传感器应用开发
开发者只需要为传感器注册一个监听器即可。
15.1 利用android的传感器
步骤:
对监听器的说明:
实现简单的传感器监听事件逻辑:
注意:android模拟器没有提供传感器支持。
15.2 Android的常用传感器
15.2.1 方向传感器
对于手机围绕着三个轴转动的情况说明:
15.2.2 陀螺仪传感器
用于感应手机设备的旋转速度。
旋转速度的单位是:弧度/秒,旋转速度为正值代表逆时针旋转,负值代表顺时针旋转。
返回的三个角速度说明如下:
//截止到:2021/6/20日下午12:17
//2021/6/25日下午22:41开始学习笔记
15.2.3 磁场传感器
主要用于读取手机设备外部磁场的强度。
磁场数据的单位是微特斯拉(uT)。
15.2.4 重力传感器
会返回一个三维坐标向量,这个三维向量可显示重力的方向和强度。
重力传感器的坐标系统和加速度传感器的坐标系统是相同的。
15.2.5 线性加速度传感器
返回一个三维向量显示设备在各个方向上的加速度。
加速度传感器 = 重力传感器 + 线性加速度传感器
15.2.7 光传感器
用于获得环境中的光照强度。单位是lux。
15.2.8 湿度传感器
返回一个数据表示相对环境中空气湿度百分比。
15.2.9 压力传感器
用于获得手机设备所处环境的压力大小。
15.2.10 心率传感器
可以返回佩戴该设备的人每分钟的心跳次数。
15.2.11 离身传感器
用于感知设别的佩戴状态。适合处理手表等可穿戴设备。
使用获得系统服务的代码得到传感器管理对象:
为不同的传感器设置监听器:
在onSensorChanged()方法中代码:
获得触发的传感器类型:
//15.3 传感器应用实例
实例:指南针
//实例:水平仪
代码实现思路:
//15.4 本章小结
//截止到:2021/6/25 23:15截至
//2021/6/26日上午9:07开始学习笔记
android为支持GPS提供了LocationManager类。
16.1 支持GPS的核心API
使用getSystemService()函数获得manager类。
提供的方法有:
addGPSStatusListener()函数添加一个监听GPS状态的监听器。
addProximity()函数添加一个临近警告。
List getAllProvider()函数获得所有的LocationProvider列表。
String getBestProvider()函数:根据指定条件返回最优的LocationManager对象。
GpsStatus getGpsStatus()函数获得GPS状态。
Location getLastKnownLocation()根据provider(函数中的参数)获得最近一次已知的Location。
LocationProvider getProvider()函数:根据名称获得LocationProvider对象。
List getProvider():获得所有可用的LocationProvider对象。
Boolean isProviderEnabled()函数:判断指定名称的LocationProvider是否可用。
removeGpsStatusListener()函数:删除Gps状态监听器。
RemoveProximityAlert()函数:删除一个临近警告。
requestLocationUpdates()函数:通过指定的LocationProvider周期性地获得定位信息,通过intent启动相应的组件。
requestLocationUpdates()函数通过指定的LocationProvider对象周期性地获得定位信息。触发Listener对象的触发器。
LocationProvider对象是重要的定位提供者。通过该对象可以获得相关组件的定位信息。
其中的常用方法是:
GPS定位支持还有一个API:Location,是一个代表位置信息的抽象类。提供了如下方法来获得定位信息。
使用上述三个组件对象获得定位信息的步骤如下:
16.2 获得LocationProvider对象
16.2.1 获得所有可用的LocationProvider对象
提供了一个getAllProviders()方法来获得系统所有可用的LocationProvider对象。
注意:如果使用真机,那么会出现一个network的LocationProvider对象,表示通过移动网络获得定位信息的LocationProvider对象。
16.2.2 通过名称获得指定LocationProvider对象
程序调用LocationManager对象的getAllProviders()函数获得所有的LocationProvider对象。
16.3 获得定位信息
在获得了LocationManager对象之后,就可以通过指定的LocationProvider对象来获得定位信息了。
16.3.1 通过模拟器发送GPS信息
android模拟器本身并不能 作为GPS接收机,因此无法得到GPS的定位信息。
16.3.2 获得定位数据
需要在清单文件中增加对应的权限。
16.3.3 Android新增的室内WI-FI定位
Android 9 新增了队RTT WI-FI协议的支持
可以使用设备测量与多个WIFI接入点的距离,可以使用定位算法来对改设备进行定位。
室内WIFI定位管理器对象是:WifiRttManager。
获得了该对象之后,程序调用startRanging()函数开始定位:
使用室内WIFI定位步骤:
注意:只有当版本大于Android 9 时才可以使用WIFI定位功能。
实例步骤:
16.4 临近警告
需要说明的是:addProsimityAlert()方法中,如果设备只是简单地通过被检测区域,系统可能不会激发Intent,需要在真机上运行。
16.5 本章小结
17.1 调用高德Map服务
17.1.1 获得Map API key
步骤如下:
注意:
17.1.2 高德地图入门
高德地图提供了一个MapView组件,该组件继承了FrameLayour组件,本质上就是一个普通的容器组件。
MapView组件是一个容器,真正地MapView提供地图支持的是AMap类。MapView可以通过getMap()方法来获得所封装的AMap对象,AMap提供了大量的方法来控制地图。
建立的包名和申请的时候设置的需要保持一致。
需要添加高德地图的SDK:
登录官网,下载SDK包,将解压缩之后的jar包制到app/libs目录下。在app/src/mani目录下新建一个jniLibs子目录。然后将arm64-v8a,armeabi,armeabi-v7a,x86,x86_64这5个文件夹复制到该目录下。
打开清单文件,在该文件中的application元素中添加如下:meta-data子元素:
在清单文件中添加权限文件:
注意:
MapView组件需要在Activity的生命周期中回调该MapView组件的生命周期方法。
17.2 根据GPS信息在地图上定位
AMap提供如下的方法来控制地图:
然后设置监听地图,用于响应用户操作:
步骤:
为了表示Map上的指定点,高德地图还提供了LatLng类。该类就是对经纬度的封装。
还提供了一个CameraUpdate类,该类需要通过CameraUpdateFactory来创建该类的实例。
CameraUpdate可控制地图的缩放级别、定位、倾斜角度等信息。
程序调用AMap对象的moveCamera()方法根据CameraUpdate对地图进行缩放等操作。
根据经纬度在AMap上定位的步骤:
17.3 实际定位
17.3.1 地址解析和反向地址解析
地址解析:将用户输入的字符串地址转换成为精度和纬度
方向地址解析:将精度和纬度转换成普通的字符串。
高德地图提供了GeocodeSearch工具类,该工具类提供如下方法:
实际上该类需要调用网络上的高德地图服务。
上述的两种地址解析使用异步交互的方法进行。
步骤:
17.3.2 根据地址执行定位
17.4 GPS导航
高德地图提供了RouteSearch查询类。专门用于查询各种路线:
使用RouteSearch获得导航路线只需要如下3步:
//截止到2021/6/26日 上午11:28