根据摩拜单车的理念开发的一款app,app通过蓝牙与车子进行连接,在行走过程app可以提供车子信息实时展示的功能,在此功能之上,app还提供当前位置信息,并以当前位置为基点提供附近用户位置并可进行好友的添加,聊天等。app还提供了一套hybrid框架用于功能的扩展,通过原生提供的一些接口,可以通过H5快速增加某些特定模块.
后面关于这个项目的android apk安装包我直接弄个二维码下载,接下来android端的开发可能会停止了(因为lz准备转后台了),后面服务器的代码也会开始进行写文档,关于接口这方面会全部开放出来。所以敬请期待吧哈哈!
- 完善蓝牙搜索模块
- 完善小车绑定界面的稳定性,在首页右上角也可显示小车的实时速度(更加符合实际用户使用)
- 通信加密
- RSA+AES
- Android aes密钥通过rsa公钥加密,放在http请求头中,rsa公钥由服务器生成放在assets中,rsa密钥存放在服务器
- 加入驾驶模式
- 通过特定的协议,app使用蓝牙模块与STC进行通信,从而实时对蓝牙小车的速度进行展示(暂时只显示PWM的占空比,测速模块还在快递路上)
- 硬件模块传送门,主要通过k1,k2按键来改变PWM从而达到调速效果,蓝牙模块使用HC-06,协议也是我自己制定的,具体可以进去看看
启动界面 | 首页一角 | 好友界面 |
---|---|---|
个人头像修改 | 图片选择 | 聊天界面 |
ps:本来觉得hybrid部分不用传上来的,因为全部都是h5写的,但是想展示下原生部分,由下图可以看到标题栏还有浮动按钮都是原生的,是以JsBridge为桥梁来做到html与原生的双向通信,从而达到js中也能控制原生ui的展示,也就是说我可以通过html来修改app中的控件,从而达到这个模块可以热更新的效果(但是现在这个方案还不太成熟,我还在不断完善中)
信息列表 | 详情 | 发布界面 |
---|---|---|
查看个人发布信息 | ||
实现了STC与android通过蓝牙通信从而达到信息交互,可以看看我的文章:SCMAndroidCommunicate,只要遵守我制定好的数据协议,便可以与app的驾驶模块进行交互
在线演示视频观看(模块在线演示地址)
- 用户模块:支持好友的聊天,表情图片的发送,添加好友,同意好友请求等,离线消息接收,多处登陆(挤下线),消息多种提醒方式。
- 自动登陆:双token机制保证了用户在本机app中只需登陆一次,即可做到以后都自动登陆
- 位置系统:服务器端使用geo编码来实现附近的人,每次登陆都会自动上传自己当前的位置并展示出附近的人。足迹功能:在移动端用户也可以主动记录自己当前的位置和发表动态与上传照片,服务器会根据时间来判断是否符合发表的条件,用户可以查看自己的足迹(百度地图的覆盖物有点小问题,这个功能很快可以完善,现在只有一个雏形)
- 硬件通信模块:与单片机通过蓝牙通信,达到双工通信,app实时显示蓝牙小车速度信息
1.服务器
- MyEclipse 10.7 + Tomcat7
- J2EE:structs2+hibernate+spring
- MySQL5.0
2.图片服务器
- 阿里云oss
- node.js
3.android
- android studio 1.0+
- android sdk r16+
4.其他
- hybrid前端框架:SuiMobile
- 单片机:STC89C51,c语言
- Retrofit+Rxjava
- Glide
- Materia Design
- 即时通讯|推送:环信sdk
- 百度地图sdk
- 图片上传:阿里云oss
- 本地图片选取:GalleryPick,自带图片裁剪,对activity的入侵比较小
- easeui:环信sdk的工具类
- JsBridge:webview与js沟通的桥梁(正在研究新方案)
- (已去除)
内存泄漏检测 LeakCommpany
自己写的一个RxJava风格的网络访问异常处理机制:
- 识别网络访问过程中的各种异常和错误
- 根据与服务器约定好的错误码进行友好的信息提示
- 不入侵view层,大大降低耦合度
- 密钥过期处理:当发现token过期会自动向服务器索取token并重新发起之前失败的那个请求
- 了解更多:传送门
这个模块暂时只用于webview中图片处理相关,因为在native中有glide的存在了,完全没有必要再用自己的 基本原理:CacheManager会先根据图片url去md5为key去检查本地二重缓存(内存缓存和硬盘缓存),当发现没有的时候再从网络去读取,然后压缩,存储,再让webview去加载,特点:
- 利用RxJava的多个操作符完成缓存的层级检查
- 内存和硬盘存储的算法都是采用LRU算法
- 在webview中发挥这个模块作用的地方有俩个:1.当加载网络图片的时候 2.当从手机本地选取大量图片加载到webview中的时候
- github地址,guthub的图片显示有点不正常,也可以去 CSDN地址 看看
整个app各个模块都有独立的缓存管理器(DiskLruCache),在各种弱网络的环境下都能取出缓存中的数据提前进行展示,用户体验棒棒哒。每个模块都可以指定缓存文件大小的最大值,根据LRU算法可以设置定时自动清理,当然也可以由用户手动进行缓存的清理。
用到俩个开源项目:Othershe的RecyclerViewAdapter和LinHongHong的PullToRefreshRecyclerView 把这俩个轮子合在了一起,不知道会不会翻车,反正现在用着是挺好的。 当时太纠结了,PullToRefreshRecyclerView有SwipeRefreshLayout(太喜欢这个控件了),而RecyclerViewAdapter的公共view处理我又太喜欢了,结果就自己动手把这PullToRefreshRecyclerView的多余功能删掉,只保留SwipeRefreshLayout和header部分。然后adapter加入loading监听,特点:
- 一键设置空数据提示,网络错误提示,重新加载提示的view
- SwipeRefreshLayout嵌套recycleView,效果跟知乎首页一样
- 具备下拉刷新和上拉加载更多的功能
- (地址下次po上,不知道是何原因那个demo一直push不上来)
在项目的实际应用中,二者之间传递的信息类型太多了,比如实时速度,电量,还有车子灯光打开,或者修改车子密码等等信息,那么单片机或者app要怎么去判断传递过来的是哪种信息呢?那么我们就必须去制定一套数据协议,这里看看我的方案,协议规定:
包头 | 类型位 | 数据位 | 数据位 | 结束位 |
---|---|---|---|---|
0xFF | 0x** | 0x** | 0x** | 0xFF |
那么我们的数据位可以分别代表高二位和低二位,那么通常情况下这种方案就可以满足我们的需求了。举个例子:
类型位 | 数据位 | 数据位 | 功能 |
---|---|---|---|
0X00 | 0X02 | 0X00 | 前进 |
0X00 | 0X01 | 0X00 | 后退 |
0X00 | 0X03 | 0X00 | 左转 |
0X00 | 0X04 | 0X00 | 右转 |
0X00 | 0X00 | 0X00 | 停止 |
0X02 | 0x00 | 0X01 | 车灯亮 |
0X02 | 0x00 | 0X02 | 车灯灭 |
0X03 | 雷达数据高位 | 雷达数据低位 | 发送雷达数据 |
详情看我写的另外一个硬件交互的项目 |