├── IVI.png ├── src └── main │ ├── res │ ├── drawable-hdpi │ │ └── ic_launcher.png │ ├── drawable-mdpi │ │ └── ic_launcher.png │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ ├── values │ │ ├── strings.xml │ │ └── styles.xml │ ├── values-v11 │ │ └── styles.xml │ └── values-v14 │ │ └── styles.xml │ ├── aidl │ └── com │ │ └── roadrover │ │ ├── services │ │ ├── media │ │ │ ├── StMusic.aidl │ │ │ ├── IGetMediaListCallback.aidl │ │ │ ├── IMusicControlCallback.aidl │ │ │ ├── IMediaScannerCallback.aidl │ │ │ ├── IMediaInfoCallback.aidl │ │ │ ├── IMediaControlCallback.aidl │ │ │ ├── StMusic.java │ │ │ └── IMedia.aidl │ │ ├── voice │ │ │ ├── IVoiceCallback.aidl │ │ │ └── IVoice.aidl │ │ ├── dab │ │ │ ├── IDABCallback.aidl │ │ │ └── IDAB.aidl │ │ ├── navigation │ │ │ ├── INavigation.aidl │ │ │ └── INavigationCallback.aidl │ │ ├── car │ │ │ ├── IMcuUpgradeCallback.aidl │ │ │ ├── ICarCallback.aidl │ │ │ └── ICar.aidl │ │ ├── audio │ │ │ ├── IAudioCallback.aidl │ │ │ └── IAudio.aidl │ │ ├── system │ │ │ ├── IGpsCallback.aidl │ │ │ ├── ISystemCallback.aidl │ │ │ └── ISystem.aidl │ │ ├── avin │ │ │ ├── IAVInCallback.aidl │ │ │ └── IAVIn.aidl │ │ └── radio │ │ │ ├── IRadioCallback.aidl │ │ │ └── IRadio.aidl │ │ └── btservice │ │ └── bluetooth │ │ ├── BluetoothDevice.aidl │ │ ├── BluetoothVCardBook.aidl │ │ ├── IBluetoothExecCallback.aidl │ │ ├── IBluetoothLinkDeviceCallback.aidl │ │ ├── IDeviceCallback.aidl │ │ ├── IBluetoothStatusCallback.aidl │ │ ├── ISearchDeviceCallback.aidl │ │ ├── IBluetoothVCardCallback.aidl │ │ ├── IBluetoothCallback.aidl │ │ ├── BluetoothDevice.java │ │ └── BluetoothVCardBook.java │ ├── AndroidManifest.xml │ └── java │ └── com │ └── roadrover │ └── sdk │ ├── car │ ├── ClimateGroup.java │ ├── ClimateView.java │ ├── TirePressureGroup.java │ ├── CarSettingsGroup.java │ ├── Trip.java │ ├── AmpAudio.java │ ├── HardwareVersion.java │ ├── StudyKeyUtil.java │ └── ByteBitsDesc.java │ ├── setting │ └── Provider.java │ ├── utils │ ├── PermissionsUtil.java │ ├── BaseThreeAppUtil.java │ ├── AndroidAutoUtil.java │ ├── CarPlayUtil.java │ ├── EventBusUtil.java │ ├── ListUtils.java │ ├── TimerUtil.java │ ├── LogNameUtil.java │ └── FileUtils.java │ ├── radio │ ├── Provider.java │ └── RadioModel.java │ ├── cluster │ └── IVICluster.java │ ├── devices │ └── carrecord │ │ ├── CarRecordManager.java │ │ └── IVICarRecord.java │ ├── Param.java │ ├── dab │ ├── DABManager.java │ └── IVIDAB.java │ ├── voice │ └── IVIVoice.java │ ├── avin │ ├── IVITV.java │ ├── CameraUtil.java │ ├── ATCCameraVideoSetting.java │ └── VideoParam.java │ ├── bluetooth │ └── CmdExecResultUtil.java │ ├── system │ └── IVISystemConfig.java │ └── navigation │ └── NavigationManager.java ├── .gitignore └── LICENSE /IVI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roadrover/sdk/HEAD/IVI.png -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roadrover/sdk/HEAD/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roadrover/sdk/HEAD/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roadrover/sdk/HEAD/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.roadrover.car.sdk 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/media/StMusic.aidl: -------------------------------------------------------------------------------- 1 | // BtDevice.aidl 2 | package com.roadrover.services.media; 3 | 4 | parcelable StMusic; 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/btservice/bluetooth/BluetoothDevice.aidl: -------------------------------------------------------------------------------- 1 | // BtDevice.aidl 2 | package com.roadrover.btservice.bluetooth; 3 | 4 | parcelable BluetoothDevice; 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/btservice/bluetooth/BluetoothVCardBook.aidl: -------------------------------------------------------------------------------- 1 | // BtDevice.aidl 2 | package com.roadrover.btservice.bluetooth; 3 | 4 | parcelable BluetoothVCardBook; 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/voice/IVoiceCallback.aidl: -------------------------------------------------------------------------------- 1 | // IVoiceCallback.aidl 2 | package com.roadrover.services.voice; 3 | 4 | // 语音回调 5 | 6 | interface IVoiceCallback { 7 | 8 | void openVoiceApp(); 9 | 10 | void closeVoiceApp(); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/dab/IDABCallback.aidl: -------------------------------------------------------------------------------- 1 | // IDABCallback.aidl 2 | package com.roadrover.services.dab; 3 | 4 | interface IDABCallback { 5 | 6 | /** 7 | * 系统状态通知 8 | * 9 | * @param systemState 见{@link com.roadrover.sdk.dab.IVIDAB.SystemState} 10 | */ 11 | void onSystemNotification(int systemState); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/btservice/bluetooth/IBluetoothExecCallback.aidl: -------------------------------------------------------------------------------- 1 | // IBluetoothExecCallback.aidl 2 | package com.roadrover.btservice.bluetooth; 3 | 4 | // 蓝牙命令执行结果 5 | 6 | interface IBluetoothExecCallback { 7 | 8 | /** 9 | * 蓝牙命令执行成功 10 | * @param msg 执行成功的消息,有些命令是查询设备名等等,通过该参数返回 11 | */ 12 | void onSuccess(String msg); 13 | 14 | /** 15 | * 蓝牙命令执行失败 16 | * @param errorCode 对应 IVIBluetooth.BluetoothExecErrorMsg 里面的错误码 17 | */ 18 | void onFailure(int errorCode); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/navigation/INavigation.aidl: -------------------------------------------------------------------------------- 1 | // INavigation.aidl 2 | package com.roadrover.services.navigation; 3 | 4 | import com.roadrover.services.navigation.INavigationCallback; 5 | 6 | interface INavigation { 7 | /** 8 | * 注册监听导航回调 9 | * @param callback 10 | * @param packageName 当前应用的包名 11 | */ 12 | void registerNavigationCallback(INavigationCallback callback, String packageName); 13 | 14 | /** 15 | * 注销监听导航回调 16 | */ 17 | void unRegisterNavigationCallback(INavigationCallback callback); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/media/IGetMediaListCallback.aidl: -------------------------------------------------------------------------------- 1 | // IGetMediaListCallback.aidl 2 | package com.roadrover.services.media; 3 | 4 | import com.roadrover.services.media.StMusic; 5 | 6 | // 获取媒体列表的回调 7 | 8 | interface IGetMediaListCallback { 9 | 10 | /** 11 | * @param stAudios 进度数据 12 | * @param path 获取的目录 13 | */ 14 | void onProgress(in List stAudios, String path); 15 | 16 | /** 17 | * @param stAudios 进度数据,APP需要在结尾的时候将 onProgress的数据和OnFinish的数据综合起来 18 | * @param path 获取的目录 19 | */ 20 | void onFinish(in List stAudios, String path); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/car/IMcuUpgradeCallback.aidl: -------------------------------------------------------------------------------- 1 | // IMcuUpgradeCallback.aidl 2 | package com.roadrover.services.car; 3 | 4 | // mcu 升级回调 5 | 6 | interface IMcuUpgradeCallback { 7 | 8 | /** 9 | * 整个升级过程成功 10 | */ 11 | void onSuccess(String mcuVersion); 12 | 13 | /** 14 | * 等待mcu重启 15 | */ 16 | void onWaitMcuReboot(); 17 | 18 | /** 19 | * 升级失败 20 | * @param errorCode 对应 IVICar.McuUpgradeErrorMsg 定义 21 | */ 22 | void onFailure(int errorCode); 23 | 24 | /** 25 | * 升级进度 26 | * @param progress 进度值 27 | */ 28 | void onProgress(int progress); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/media/IMusicControlCallback.aidl: -------------------------------------------------------------------------------- 1 | // IMediaControlCallback.aidl 2 | package com.roadrover.services.media; 3 | 4 | /** 5 | * 该接口音乐app使用,语音控制时,及时当前焦点不在音乐,音乐也可以收到该接口回调 6 | */ 7 | interface IMusicControlCallback { 8 | 9 | /** 10 | * 设置播放模式
11 | * @param mode 对应 IVIVoice.MediaPlayMode 定义 12 | */ 13 | void setPlayMode(int mode); 14 | 15 | /** 16 | * 随便听听
17 | */ 18 | void playRandom(); 19 | 20 | /** 21 | * 播放指定媒体,音乐或者视频
22 | * @param title 音乐或者视频名 23 | * @param singer 歌手名 24 | */ 25 | void filter(String title, String singer); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/btservice/bluetooth/IBluetoothLinkDeviceCallback.aidl: -------------------------------------------------------------------------------- 1 | // IBluetoothLinkDeviceCallback.aidl 2 | package com.roadrover.btservice.bluetooth; 3 | 4 | // 蓝牙连接设备的回调 5 | 6 | interface IBluetoothLinkDeviceCallback { 7 | 8 | /** 9 | * 调用linkDevice 成功 10 | * @param status 对应 IVIBluetooth.BuletoothConnectStats 状态 11 | * @param addr 配对装置的蓝牙地址 12 | * @param name 配对装置的蓝牙名称 13 | */ 14 | void onSuccess(int status, String addr, String name); 15 | 16 | /** 17 | * 蓝牙命令执行失败 18 | * @param errorCode 对应 IVIBluetooth.BluetoothExecErrorMsg 里面的错误码 19 | */ 20 | void onFailure(int errorCode); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/btservice/bluetooth/IDeviceCallback.aidl: -------------------------------------------------------------------------------- 1 | // IDeviceCallback.aidl 2 | package com.roadrover.btservice.bluetooth; 3 | 4 | import com.roadrover.btservice.bluetooth.BluetoothDevice; 5 | 6 | // 获取配对设备回调 7 | 8 | interface IDeviceCallback { 9 | 10 | /** 11 | * 执行成功,直接返回设备列表 12 | * @param bluetoothDevices 设备列表 13 | * @param curBluetoothDevices 当前连接的蓝牙设备 14 | */ 15 | void onSuccess(in List bluetoothDevices, in BluetoothDevice curBluetoothDevices); 16 | 17 | /** 18 | * 蓝牙查找设备执行失败 19 | * @param errorCode 对应{@link IVIBluetooth.BluetoothExecErrorMsg} 里面的错误码 20 | */ 21 | void onFailure(int errorCode); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/btservice/bluetooth/IBluetoothStatusCallback.aidl: -------------------------------------------------------------------------------- 1 | // IBluetoothStatusCallback.aidl 2 | package com.roadrover.btservice.bluetooth; 3 | 4 | // 蓝牙状态查询回调接口 5 | 6 | interface IBluetoothStatusCallback { 7 | 8 | /** 9 | * 状态查询命令执行成功 10 | * @param status 状态 IVIBluetooth.BluetoothModuleStatus 11 | * @param hfpstatus IVIBluetooth.BluetoothHIDStatus 12 | * @param a2dpStatus IVIBluetooth.BluetoothA2DPStatus 13 | */ 14 | void onSuccess(int status, int hfpStatus, int a2dpStatus); 15 | 16 | /** 17 | * 蓝牙命令执行失败 18 | * @param errorCode 对应 IVIBluetooth.BluetoothExecErrorMsg 里面的错误码 19 | */ 20 | void onFailure(int errorCode); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/btservice/bluetooth/ISearchDeviceCallback.aidl: -------------------------------------------------------------------------------- 1 | // IDeviceCallback.aidl 2 | package com.roadrover.btservice.bluetooth; 3 | 4 | import com.roadrover.btservice.bluetooth.BluetoothDevice; 5 | 6 | // 查找设备列表 7 | 8 | interface ISearchDeviceCallback { 9 | 10 | /** 11 | * 执行成功,直接返回设备列表 12 | * @param bluetoothDevices 设备列表 13 | */ 14 | void onSuccess(in BluetoothDevice bluetoothDevices); 15 | 16 | /** 17 | * 搜索设备 18 | */ 19 | void onProgress(in BluetoothDevice bluetoothDevices); 20 | 21 | /** 22 | * 蓝牙查找设备执行失败 23 | * @param errorCode {@link IVIBluetooth.BluetoothExecErrorMsg} 里面的错误码 24 | */ 25 | void onFailure(int errorCode); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/dab/IDAB.aidl: -------------------------------------------------------------------------------- 1 | // IDAB.aidl 2 | package com.roadrover.services.dab; 3 | 4 | import com.roadrover.services.dab.IDABCallback; 5 | 6 | interface IDAB { 7 | /** 8 | * 打开设备 9 | * @param callback 回调接口 10 | */ 11 | void open(IDABCallback callback); 12 | 13 | /** 14 | * 关闭设备 15 | */ 16 | void close(); 17 | 18 | /** 19 | * 获取中间件版本 20 | */ 21 | String getMiddlewareVersion(); 22 | 23 | /** 24 | * 获取固件版本 25 | */ 26 | String getSWVersion(); 27 | 28 | /** 29 | * 获取硬件版本 30 | */ 31 | String getHWVersion(); 32 | 33 | /** 34 | * 单个调谐器系统以触发全频段扫描 35 | */ 36 | void triggerBandScan(); 37 | } 38 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/btservice/bluetooth/IBluetoothVCardCallback.aidl: -------------------------------------------------------------------------------- 1 | // IBluetoothPhoneBookCallback.aidl.aidl 2 | package com.roadrover.btservice.bluetooth; 3 | 4 | import com.roadrover.btservice.bluetooth.BluetoothVCardBook; 5 | 6 | // 蓝牙通讯录查询的接口类 7 | 8 | interface IBluetoothVCardCallback { 9 | 10 | /** 11 | * 电话本下载进度 12 | * @param books 下载进度,根据模块不同,可以不同,一次十条左右 13 | */ 14 | void onProgress(in List books); 15 | 16 | /** 17 | * 蓝牙命令执行失败 18 | * @param errorCode 错误码 {@link IVIBluetooth.BluetoothExecErrorMsg} 19 | */ 20 | void onFailure(int errorCode); 21 | 22 | /** 23 | * 蓝牙电话本下载成功 24 | */ 25 | void onSuccess(String msg); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/car/ClimateGroup.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.car; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * 空调信息组 8 | */ 9 | public class ClimateGroup { 10 | protected Map mItems = new HashMap<>(); 11 | public void set(int id, int rawValue) { 12 | Climate item = mItems.get(id); 13 | if (item != null) { 14 | item.mRawValue = rawValue; 15 | } else { 16 | mItems.put(id, new Climate(id, rawValue)); 17 | } 18 | } 19 | 20 | public Climate get(int id) { 21 | return mItems.get(id); 22 | } 23 | 24 | public boolean contains(int id) { 25 | return mItems.containsKey(id); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/audio/IAudioCallback.aidl: -------------------------------------------------------------------------------- 1 | package com.roadrover.services.audio; 2 | 3 | interface IAudioCallback { 4 | /** 5 | * 音量值被改变 6 | * @param id 比如 AudioParam.Id.VOLUME_MASTER, AudioParam.Id.VOLUME_BLUETOOTH 7 | * @param value 具体的音量值 8 | */ 9 | void onVolumeChanged(int id, int value); 10 | 11 | /** 12 | * 静音状态被改变 13 | * @param mute 是否被静音 14 | * @param source 静音动作的来源 15 | */ 16 | void onMuteChanged(boolean mute, int source); 17 | 18 | /** 19 | * 音量条的显示和隐藏, id 为AudioParam.Id.NONE时为隐藏 20 | * 只有SystemUI才关心该方法,其他应用不需要关心 21 | */ 22 | void onVolumeBar(int id, int value, int maxValue); 23 | 24 | /** 25 | * 次通道静音状态被改变 26 | * @param mute 是否被静音 27 | */ 28 | void onSecondaryMuteChanged(boolean mute); 29 | } -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/system/IGpsCallback.aidl: -------------------------------------------------------------------------------- 1 | // IGpsCallback.aidl 2 | package com.roadrover.services.system; 3 | 4 | // Declare any non-default types here with import statements 5 | 6 | interface IGpsCallback { 7 | /** 8 | * gps 定位回调 9 | * @param longitude 经度 10 | * @param latitude 维度 11 | * @param accuracy 精度 12 | * @param altitude 海拔 13 | * @param fSpeed 速度,km/h 14 | */ 15 | void onGpsLocationInfoChanged(String longitude, String latitude, float accuracy, double altitude, float fSpeed); 16 | 17 | /** 18 | * gps 可以使用的数量 19 | * @param iGpsInView 20 | * @param iGpsInUse 21 | * @param iGlonassInView 22 | * @param iGLonassInUse 23 | */ 24 | void onGpsCountChanged(int iGpsInView, int iGpsInUse, int iGlonassInView, int iGLonassInUse); 25 | } 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #built application files 2 | *.apk 3 | *.ap_ 4 | 5 | 6 | # files for the dex VM 7 | *.dex 8 | 9 | 10 | # Java class files 11 | *.class 12 | 13 | 14 | # generated files 15 | bin/ 16 | gen/ 17 | 18 | 19 | # Local configuration file (sdk path, etc) 20 | local.properties 21 | 22 | 23 | # Windows thumbnail db 24 | Thumbs.db 25 | 26 | 27 | # OSX files 28 | .DS_Store 29 | 30 | 31 | # Eclipse project files 32 | .classpath 33 | .project 34 | 35 | 36 | # Android Studio 37 | .idea 38 | #.idea/workspace.xml - remove # and delete .idea if it better suit your needs. 39 | .gradle 40 | build/ 41 | 42 | 43 | # Signing files 44 | .signing/ 45 | 46 | 47 | # User-specific configurations 48 | .idea/libraries/ 49 | .idea/workspace.xml 50 | .idea/tasks.xml 51 | .idea/.name 52 | .idea/compiler.xml 53 | .idea/copyright/profiles_settings.xml 54 | .idea/encodings.xml 55 | .idea/misc.xml 56 | .idea/modules.xml 57 | .idea/scopes/scope_settings.xml 58 | .idea/vcs.xml 59 | *.iml 60 | 61 | # Gradle files 62 | gradle/ 63 | gradle.properties 64 | gradlew.bat 65 | gradlew -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/media/IMediaScannerCallback.aidl: -------------------------------------------------------------------------------- 1 | // IMediaScannerCallback.aidl 2 | package com.roadrover.services.media; 3 | 4 | // 媒体扫描回调 5 | 6 | interface IMediaScannerCallback { 7 | 8 | /** 9 | * 扫描开始 10 | * @param type 对应 Media.MediaScannerType 中类型 11 | * @param sqlType {@link Media.MediaSqlDataType},只有当 type 为 删除,重命名,创建 类型时才有效 12 | */ 13 | void onScanStart(int type, int sqlType); 14 | 15 | /** 16 | * 扫描结束 17 | * @param type 对应 Media.MediaScannerType 中类型 18 | * @param sqlType {@link Media.MediaSqlDataType},只有当 type 为 删除,重命名,创建 类型时才有效 19 | * @param path 当前操作的目录,如果是扫描全部,为空 20 | * @param oldPath 当操作是重命名的时候,才会有该参数,其他类型不需要关心该参数 21 | */ 22 | void onScanFinish(int type, int sqlType, String path, String oldPath); 23 | 24 | /** 25 | * 盘符卸载 26 | * @param path 卸载目录 27 | * @param isDiskPowerDown 是否是盘符掉电,如果是盘符掉电,音乐,视频等不做处理,但是状态栏需要处理 28 | */ 29 | void onEject(String path, boolean isDiskPowerDown); 30 | 31 | /** 32 | * 盘符挂载 33 | * @param path 挂载目录 34 | */ 35 | void onMount(String path); 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Shenzhen RoadRover Technology Co.,Ltd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/avin/IAVInCallback.aidl: -------------------------------------------------------------------------------- 1 | package com.roadrover.services.avin; 2 | 3 | interface IAVInCallback { 4 | /** 5 | * 视频信号发生变化 6 | * @param avId IVIAVIn.Id 7 | * @param signal IVIAVIn.Signal 8 | */ 9 | void onVideoSignalChanged(int avId, int signal); 10 | /** 11 | * 视频是否允许观看 12 | * @param show true允许观看,false不允许观看 13 | */ 14 | void onVideoPermitChanged(boolean show); 15 | /** 16 | * 停止 17 | */ 18 | void stop(); 19 | /** 20 | * 恢复播放 21 | */ 22 | void resume(); 23 | /** 24 | * 下一曲 25 | */ 26 | void next(); 27 | /** 28 | * 上一曲 29 | */ 30 | void prev(); 31 | /** 32 | * 退出应用 33 | */ 34 | void quitApp(); 35 | /** 36 | * 选择指定下标播放 37 | * @param index 指定的下标 38 | */ 39 | void select(int index); 40 | /** 41 | * 视频CVBS制式发生变化 42 | * @param avId IVIAVIn.Id 43 | * @param cvbsType VideoParam.CvbsType 44 | */ 45 | void onCvbsTypeChanged(int avId, int cvbsType); 46 | /** 47 | * AVIN源插入状态发生变化,比如导游麦克风 48 | * @param avId IVIAVIn.Id 49 | * @param plugin true插入,false拔出 50 | */ 51 | void onSourcePluginChanged(int avId, boolean plugin); 52 | } -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/media/IMediaInfoCallback.aidl: -------------------------------------------------------------------------------- 1 | package com.roadrover.services.media; 2 | 3 | // 媒体信息监听回调 4 | interface IMediaInfoCallback { 5 | 6 | /** 7 | * 媒体发生改变,例:切歌,切视频,切收音 8 | * @param mediaType 对应Media.MediaType 9 | * @param name 名字 10 | * @param info 一般为歌手等附带信息 11 | * @param artWidth 图片(比如专辑封面)的宽度,单位像素 12 | * @param artHeight 图片的高度,单位像素 13 | * @param artPixels 图片的bytes, 14 | * @param index 第几首歌(-1 未知) 15 | * @param totalCount 总歌曲数 (-1 未知) 16 | * @param popup 是否需要弹出媒体信息通知栏 17 | */ 18 | void onMediaChange(int mediaType, String name, String info, int artWidth, int artHeight, in byte[] artPixels, int index, int totalCount, boolean popup); 19 | 20 | /** 21 | * 媒体播放状态发生改变,例:音乐进度变化、播放暂停等 22 | * @param mediaType 对应Media.MediaType 23 | * @param progress 进度信息(单位秒) 24 | * @param duration 总进度(单位秒) 25 | */ 26 | void onPlayStateChange(int mediaType, int playState, int position, int duration); 27 | 28 | /** 29 | * 媒体播放的输出区发生改变 30 | * @param mediaType 对应Media.MediaType 31 | * @param zone IVIMedia.Zone 32 | */ 33 | void onMediaZoneChanged(int mediaType, int zone); 34 | 35 | /** 36 | * 当前媒体源显示的媒体类型信息发生改变。 37 | */ 38 | void onCurrentShownMediaTypeChanged(int mediaType); 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/setting/Provider.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.setting; 2 | 3 | import android.net.Uri; 4 | import android.provider.BaseColumns; 5 | 6 | /** 7 | * 存放跟数据库有关的常量 8 | */ 9 | 10 | public class Provider { 11 | /**这个是每个Provider的标识,在Manifest中使用, 其值 {@value}*/ 12 | public static final String AUTHORITY = "com.roadrover.settings.provider"; 13 | /**内容类型, 其值 {@value}*/ 14 | public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.roadrover.settings"; 15 | /**内容单项类型, 其值 {@value}*/ 16 | public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.roadrover.settings"; 17 | 18 | /** 19 | * 跟NameValue表相关的常量 20 | */ 21 | public static final class NameValueColumns implements BaseColumns { 22 | /**CONTENT_URI跟数据库的表关联,最后根据CONTENT_URI来查询对应的表, 其值 {@value}*/ 23 | public static final Uri CONTENT_URI = Uri.parse("content://"+ AUTHORITY +"/settings"); 24 | /**表名字, 其值 {@value}*/ 25 | public static final String TABLE_NAME = "settings"; 26 | /**排序, 其值 {@value}*/ 27 | public static final String DEFAULT_SORT_ORDER = "_id desc"; 28 | /**名字, 其值 {@value}*/ 29 | public static final String NAME = "name"; 30 | /**数值, 其值 {@value}*/ 31 | public static final String VALUE = "value"; 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/car/ClimateView.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.car; 2 | 3 | import android.view.View; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class ClimateView { 9 | public static final int DRAWABLE_ID_HIDE = -1; 10 | public static final int DRAWABLE_ID_SHOW = -2; 11 | 12 | /** 13 | * mValue空调对应的值 14 | * mDrawableId该值对应的图片在R中的ID 15 | */ 16 | public static class Value2Image{ 17 | public int mValue; 18 | public int mDrawableId; 19 | public Value2Image(int value, int drawableId) { 20 | mValue = value; 21 | mDrawableId = drawableId; 22 | } 23 | } 24 | 25 | public int mClimateId; 26 | public View mView; 27 | public List mValue2Images = new ArrayList<>(); 28 | 29 | public ClimateView addValue(int value, int drawableId) { 30 | mValue2Images.add(new Value2Image(value, drawableId)); 31 | return this; 32 | } 33 | 34 | public ClimateView addDefaultValue() { 35 | mValue2Images.add(new Value2Image(0, DRAWABLE_ID_HIDE)); 36 | mValue2Images.add(new Value2Image(1, DRAWABLE_ID_SHOW)); 37 | return this; 38 | } 39 | 40 | public ClimateView(int climateId, View view) { 41 | mClimateId = climateId; 42 | mView = view; 43 | } 44 | } -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/utils/PermissionsUtil.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.utils; 2 | 3 | import android.Manifest; 4 | import android.app.Activity; 5 | import android.content.pm.PackageManager; 6 | import android.support.v4.app.ActivityCompat; 7 | 8 | /** 9 | * 权限定义的工作类 10 | */ 11 | public class PermissionsUtil { 12 | 13 | // Storage Permissions 14 | private static final int REQUEST_EXTERNAL_STORAGE = 1; 15 | private static String[] PERMISSIONS_STORAGE = { 16 | Manifest.permission.READ_EXTERNAL_STORAGE, 17 | Manifest.permission.WRITE_EXTERNAL_STORAGE}; 18 | 19 | /** 20 | * Checks if the app has permission to write to device storage 21 | *

22 | * If the app does not has permission then the user will be prompted to 23 | * grant permissions 24 | * 25 | * @param activity 26 | */ 27 | public static void verifyStoragePermissions(Activity activity) { 28 | // Check if we have write permission 29 | int permission = ActivityCompat.checkSelfPermission(activity, 30 | Manifest.permission.WRITE_EXTERNAL_STORAGE); 31 | 32 | if (permission != PackageManager.PERMISSION_GRANTED) { 33 | // We don't have permission so prompt the user 34 | ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE, 35 | REQUEST_EXTERNAL_STORAGE); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/radio/Provider.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.radio; 2 | 3 | import android.net.Uri; 4 | import android.provider.BaseColumns; 5 | 6 | /** 7 | * 存放跟数据库有关的常量. 8 | */ 9 | 10 | public class Provider { 11 | 12 | // 这个是每个Provider的标识,在Manifest中使用 13 | public static final String AUTHORITY = "com.roadrover.radio_v2.provider"; 14 | 15 | public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.roadrover.radio_v2"; 16 | 17 | /** 18 | * 跟表相关的常量 19 | */ 20 | public static final class TableColumns implements BaseColumns { 21 | // CONTENT_URI跟数据库的表关联,最后根据CONTENT_URI来查询对应的表 22 | public static final Uri CONTENT_URI = Uri.parse("content://"+ AUTHORITY +"/provider"); 23 | public static final String TABLE_NAME = "tbRadio"; 24 | public static final String DEFAULT_SORT_ORDER = "_id desc"; 25 | 26 | public static final String KEY_ID = "_id"; 27 | public static final String KEY_NAME = "name"; 28 | public static final String KEY_FREQ = "mFreq"; 29 | public static final String KEY_KIND = "kind"; 30 | public static final String KEY_BAND = "mBand"; 31 | public static final String KEY_POSITION = "position"; 32 | public static final String KEY_RDSNAME = "rdsname"; 33 | public static final String KEY_ISLOVE = "isLove"; 34 | public static final String KEY_DESP = "desp"; 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/car/TirePressureGroup.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.car; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * 胎压信息组 8 | */ 9 | 10 | public class TirePressureGroup { 11 | 12 | private Map mItems = new HashMap<>(); 13 | 14 | /** 15 | * @param id ID 定义 见{@link com.roadrover.sdk.car.TirePressure} 16 | * @param rawValue 数据 见{@link com.roadrover.sdk.car.TirePressure} 17 | * @param extraValue 附加状态数据 见{@link com.roadrover.sdk.car.TirePressure} 18 | * @param dotType 温度小数点标志 见{@link com.roadrover.sdk.car.TirePressure} 19 | */ 20 | public void set(int id, int rawValue, int extraValue, int dotType) { 21 | TirePressure item = mItems.get(id); 22 | if (item != null) { 23 | item.rawValue = rawValue; 24 | item.extraValue = extraValue; 25 | item.dotType = dotType; 26 | } else { 27 | mItems.put(id, new TirePressure(id, rawValue, extraValue, dotType)); 28 | } 29 | } 30 | 31 | public TirePressure get(int id) { 32 | return mItems.get(id); 33 | } 34 | 35 | public boolean contains(int id) { 36 | return mItems.containsKey(id); 37 | } 38 | 39 | public Map getTtems() { 40 | return mItems; 41 | } 42 | 43 | public int size() { 44 | return mItems.size(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/car/CarSettingsGroup.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.car; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * 原车设置类 8 | */ 9 | public abstract class CarSettingsGroup { 10 | public int mCarId; 11 | public static class Item { 12 | public int mValue; 13 | public ByteBitsDesc mBits; 14 | 15 | public void load(byte[] buff) { 16 | mValue = mBits.get(buff); 17 | } 18 | 19 | public Item(String desc) { 20 | mBits = new ByteBitsDesc(desc); 21 | } 22 | } 23 | 24 | public Map mItems = new HashMap<>(); 25 | public CarSettingsGroup() { 26 | } 27 | 28 | public void insertItem(int id, String desc) { 29 | Item item = mItems.get(id); 30 | if (item != null) { 31 | item.mBits.setDesc(desc); 32 | } else { 33 | mItems.put(id, new Item(desc)); 34 | } 35 | } 36 | 37 | public void loadFromBytes(byte[] buff) { 38 | if (buff == null) { 39 | return; 40 | } 41 | 42 | mCarId = buff[0]; 43 | for (Map.Entry entry : mItems.entrySet()) { 44 | entry.getValue().load(buff); 45 | } 46 | } 47 | 48 | public int get(int id) { 49 | return mItems.get(id).mValue; 50 | } 51 | 52 | public boolean set(int id, int value) { 53 | Item item = mItems.get(id); 54 | if (item == null) 55 | return false; 56 | 57 | item.mValue = value; 58 | return true; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/btservice/bluetooth/IBluetoothCallback.aidl: -------------------------------------------------------------------------------- 1 | // IBluetoothCallback.aidl 2 | package com.roadrover.btservice.bluetooth; 3 | 4 | // 蓝牙数据接口回调 5 | 6 | interface IBluetoothCallback { 7 | 8 | /** 9 | * 在连接过程中,断开,连接等都会调用该状态 10 | */ 11 | void onConnectStatus(int nStatus, String addr, String name); 12 | 13 | /** 14 | * 电话状态回调 15 | * @param nStatus IVIBluetooth.BluetoothCallStatus 16 | * @param phoneNumber 只有来电的状态才会有phoneNumber 17 | * @param contactName 联系人名字,有可能没有 18 | */ 19 | void onCallStatus(int nStatus, String phoneNumber, String contactName); 20 | 21 | /** 22 | * 语音切换 23 | * @param type 语音切换在哪一端 IVIBluetooth.BluetoothAudioTransferStatus 24 | */ 25 | void onVoiceChange(int type); 26 | 27 | /** 28 | * 状态查询命令执行成功 29 | * @param avstatus IVIBluetooth.BluetoothA2DPStatus 30 | * @param isStoped 是否停止 31 | */ 32 | void onA2DPConnectStatus(int avstatus, boolean isStoped); 33 | 34 | /** 35 | * 蓝牙音乐 id3 信息 36 | * @param name 名字 37 | * @param artist 歌手 38 | * @param album 专辑 39 | * @param duration 总时长 40 | */ 41 | void onBtMusicId3Info(String name, String artist, String album, long duration); 42 | 43 | /** 44 | * 手机电量 45 | * @param value 电量值 0-100 46 | */ 47 | void onBtBatteryValue(int value); 48 | 49 | /** 50 | * 手机信号 51 | * @param value 信号值 0-5 52 | */ 53 | void onBtSignalValue(int value); 54 | 55 | /** 56 | * 蓝牙开关状态 57 | * @param value 58 | */ 59 | void onPowerStatus(boolean value); 60 | } 61 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/voice/IVoice.aidl: -------------------------------------------------------------------------------- 1 | // IVoice.aidl 2 | package com.roadrover.services.voice; 3 | 4 | import com.roadrover.services.voice.IVoiceCallback; 5 | 6 | // 语音控制接口 7 | 8 | interface IVoice { 9 | // 媒体接口 10 | void selectMediaItem(int index); 11 | void playMedia(String title, String singer); 12 | void play(); 13 | void pause(); 14 | void prev(); 15 | void next(); 16 | void favourMedia(boolean isFavour); 17 | 18 | /** 19 | * 设置播放模式 20 | * @param mode 对应 IVIVoice.MediaPlayMode 定义 21 | */ 22 | void setPlayMode(int mode); 23 | void playRandom(); 24 | 25 | // 声音控制 26 | void incVolume(); 27 | void decVolume(); 28 | void setVolume(int volume); 29 | void setMute(boolean isMute); 30 | 31 | // 收音机接口 32 | void setFreq(int freq); 33 | void startScan(); 34 | void stopScan(); 35 | 36 | /** 37 | * 设置FM 还是 Am 38 | * @param band 对应 IVIRadio.Band 39 | */ 40 | void setBand(int band); 41 | 42 | // 应用操作接口 43 | /** 44 | * 打开应用 45 | * @param packageName 包名 46 | * @param className 类名,可以缺省 47 | */ 48 | void openApp(String packageName, String className); 49 | void closeApp(String packageName); 50 | 51 | // 系统操作相关接口 52 | void openScreen(); 53 | void closeScreen(); 54 | 55 | // 打开/关闭语音app 56 | void openVoiceApp(); 57 | void closeVoiceApp(); 58 | 59 | // 以下两个接口,在语音播放声音的时候调用 startVoice,在语音停止播报的时候调用 endVoice 60 | void startVoice(); 61 | void endVoice(); 62 | 63 | // 注册语音回调 64 | void registerVoiceCallback(IVoiceCallback callback); 65 | void unregisterVoiceCallback(IVoiceCallback callback); 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/car/Trip.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.car; 2 | 3 | import com.roadrover.sdk.utils.LogNameUtil; 4 | 5 | public class Trip { 6 | /** 7 | * 里程ID 8 | */ 9 | public static class Id { 10 | /** 总里程 */ 11 | public static final int TOTAL = 0; 12 | /** 从车辆启动 */ 13 | public static final int START = 1; 14 | /** 里程A */ 15 | public static final int A = 2; 16 | /** 里程B */ 17 | public static final int B = 3; 18 | /** 里程C */ 19 | public static final int C = 4; 20 | } 21 | 22 | /** 23 | * 参数值在float[]中的索引 24 | */ 25 | public static class Index { 26 | /** 距离km */ 27 | public static final int DISTANCE = 0; 28 | /** 时间分钟 */ 29 | public static final int TIME_MINUTES = 1; 30 | /** 平均油耗 */ 31 | public static final int AVG_FUEL_CONSUMPTION = 2; 32 | /** 平均速度 */ 33 | public static final int AVG_SPEED = 3; 34 | /** 距离0.1km */ 35 | public static final int DIST_DISTANCE = 4; 36 | } 37 | 38 | public int mId; 39 | public int mIndex; 40 | public float mValue; //具体值 41 | 42 | public Trip(int id, int index, float value) { 43 | mId = id; 44 | mIndex = index; 45 | mValue = value; 46 | } 47 | 48 | public static int getKey(int id, int index) { 49 | return (id << 8 | index); 50 | } 51 | 52 | public static float getUnknownValue(int id) { 53 | return -1.0f; 54 | } 55 | 56 | /** 57 | * 将类打印成String 58 | * @return 59 | */ 60 | @Override 61 | public String toString() { 62 | return "Id:" + LogNameUtil.getName(mId, Id.class) + 63 | " index:" + LogNameUtil.getName(mIndex, Index.class) + 64 | " value:" + mValue; 65 | } 66 | } -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/system/ISystemCallback.aidl: -------------------------------------------------------------------------------- 1 | // ISystemCallback.aidl 2 | package com.roadrover.services.system; 3 | 4 | // 设置的回调 5 | 6 | interface ISystemCallback { 7 | 8 | /** 9 | * 打开屏幕 10 | */ 11 | void onOpenScreen(int from); 12 | 13 | /** 14 | * 关闭屏幕 15 | * @param from {@link IVISystem.EventScreenOperate} 是应用调用还是系统调用关闭屏幕 16 | */ 17 | void onCloseScreen(int from); 18 | 19 | /** 20 | * 屏幕亮度发生改变 21 | * @param id {@link com.roadrover.sdk.setting.IVISetting.ScreenBrightnessId} 22 | * @param brightness 亮度 23 | */ 24 | void onScreenBrightnessChange(int id, int brightness); 25 | 26 | /** 27 | * 屏幕亮度ID发生改变 28 | * @param id {@link com.roadrover.sdk.setting.IVISetting.ScreenBrightnessId} 29 | * @param brightness 亮度 30 | */ 31 | void onCurrentScreenBrightnessChange(int id, int brightness); 32 | 33 | /** 34 | * 退出应用 35 | */ 36 | void quitApp(); 37 | 38 | /** 39 | * 启动导航app 40 | */ 41 | void startNavigationApp(); 42 | 43 | /** 44 | * 媒体app发生改变 45 | * @param packageName 当前是什么媒体在操作 46 | * @param isOpen 打开还是关闭操作 47 | */ 48 | void onMediaAppChanged(String packageName, boolean isOpen); 49 | 50 | /** 51 | * 系统被休眠 52 | */ 53 | void gotoSleep(); 54 | 55 | /** 56 | * 系统被唤醒 57 | */ 58 | void wakeUp(); 59 | 60 | /** 61 | * 该接口竖屏项目才用到 62 | * 用来控制中间的悬浮窗显示或者隐藏 63 | * @param visibility 对应 View.GONE View.VISIBILITY 等参数 64 | */ 65 | void onFloatBarVisibility(int visibility); 66 | 67 | /** 68 | * T-box开关发生改变 69 | * @param isOpen {@link com.roadrover.sdk.system.IVISystem.EventTboxOpen} 70 | */ 71 | void onTboxChange(boolean isOpen); 72 | 73 | /** 74 | * 屏幕保护状态改变 75 | * @param isEnterScreenProtection 是否是进入屏保 76 | */ 77 | void onScreenProtection(boolean isEnterScreenProtection); 78 | } 79 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/media/IMediaControlCallback.aidl: -------------------------------------------------------------------------------- 1 | // IMediaControlCallback.aidl 2 | package com.roadrover.services.media; 3 | 4 | interface IMediaControlCallback { 5 | /** 6 | * 挂起媒体 7 | */ 8 | void suspend(); 9 | 10 | /** 11 | * 恢复媒体 12 | */ 13 | void resume(); 14 | 15 | /** 16 | * 暂停 17 | */ 18 | void pause(); 19 | 20 | /** 21 | * 播放 22 | */ 23 | void play(); 24 | 25 | /** 26 | * 播放暂停 27 | */ 28 | void playPause(); 29 | 30 | /** 31 | * 退出媒体应用 32 | * @param quitSource 退出来源 {@link IVIMedia.QuitMediaSource} 33 | */ 34 | void quitApp(int quitSource); 35 | 36 | /** 37 | * 停止媒体 38 | */ 39 | void stop(); 40 | 41 | /** 42 | * 设置媒体音量,1最大,0最小 43 | */ 44 | void setVolume(float volume); 45 | 46 | /** 47 | * 下一曲 48 | */ 49 | void next(); 50 | 51 | /** 52 | * 下一曲 53 | */ 54 | void prev(); 55 | 56 | /** 57 | * 选择第几首 58 | */ 59 | void select(int index); 60 | 61 | /** 62 | * 收藏当前播放的媒体项 63 | */ 64 | void setFavour(boolean isFavour); 65 | 66 | /** 67 | * 视频是否被允许显示,比如手刹控制 68 | */ 69 | void onVideoPermitChanged(boolean show); 70 | 71 | /** 72 | * 拖动音乐进度,从外部控制音乐进度 73 | * @param msec 进度,ms 74 | */ 75 | void seekTo(int msec); 76 | 77 | /** 78 | * 设置播放模式
79 | * 接口弃用,新接口使用{@link IMusicControlCallback#setPlayMode} 80 | * @param mode 对应 IVIVoice.MediaPlayMode 定义 81 | */ 82 | void setPlayMode(int mode); 83 | 84 | /** 85 | * 随便听听
86 | * 接口弃用,新接口使用{@link IMusicControlCallback#playRandom} 87 | */ 88 | void playRandom(); 89 | 90 | /** 91 | * 播放指定媒体,音乐或者视频
92 | * 接口弃用,新接口使用{@link IMusicControlCallback#filter} 93 | * @param title 音乐或者视频名 94 | * @param singer 歌手名 95 | */ 96 | void filter(String title, String singer); 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/utils/BaseThreeAppUtil.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.utils; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.IntentFilter; 7 | import android.support.annotation.NonNull; 8 | 9 | /** 10 | * 与第三方应用通信的工具类
11 | * 一般第三方APP通讯都是通过广播,将广播流程封装 12 | */ 13 | 14 | public abstract class BaseThreeAppUtil { 15 | 16 | protected Context mContext; 17 | private boolean mIsRegister = false; 18 | 19 | private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 20 | @Override 21 | public void onReceive(Context context, Intent intent) { 22 | BaseThreeAppUtil.this.onReceive(context, intent); 23 | } 24 | }; 25 | 26 | public BaseThreeAppUtil(@NonNull Context context) { 27 | if (context != null) { 28 | mContext = context.getApplicationContext(); 29 | } 30 | } 31 | 32 | /** 33 | * 初始化监听 34 | * @param actions 35 | */ 36 | public void init(String... actions) { 37 | if (mContext != null && !mIsRegister) { 38 | if (!ListUtils.isEmpty(actions)) { 39 | mIsRegister = true; 40 | IntentFilter filter = new IntentFilter(); 41 | for (String action : actions) { 42 | filter.addAction(action); 43 | } 44 | mContext.registerReceiver(mBroadcastReceiver, filter); 45 | } 46 | } 47 | } 48 | 49 | /** 50 | * 注销监听 51 | */ 52 | public void release() { 53 | if (mIsRegister && mContext != null) { 54 | mIsRegister = false; 55 | mContext.unregisterReceiver(mBroadcastReceiver); 56 | } 57 | } 58 | 59 | /** 60 | * 广播监听 61 | * @param context 62 | * @param intent 63 | */ 64 | protected abstract void onReceive(Context context, Intent intent); 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/cluster/IVICluster.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.cluster; 2 | 3 | import com.roadrover.sdk.utils.LogNameUtil; 4 | 5 | /** 6 | * 仪表通信的定义数据. 7 | */ 8 | 9 | public class IVICluster { 10 | 11 | /** 12 | * 和仪表通信的ID 13 | */ 14 | public static class ID { 15 | /** 16 | * 未定义仪表通信功能 17 | */ 18 | public static final int UNKNOWN = -1; 19 | /** 20 | * 通过MCU和仪表进行通信 21 | */ 22 | public static final int MCU = 0; 23 | /** 24 | * 通过I2C和仪表进行通信 25 | */ 26 | public static final int I2C = 1; 27 | /** 28 | * 通过SPI和仪表进行通信 29 | */ 30 | public static final int SPI = 2; 31 | /** 32 | * 通过以太网和仪表进行通信 33 | */ 34 | public static final int ETHERNET = 3; 35 | } 36 | 37 | 38 | /** 39 | * 互动APP类型 40 | */ 41 | public static class AppType { 42 | 43 | /** 44 | * 音乐类型,其值为 {@value} 45 | */ 46 | public static final int MUSIC = 0; 47 | 48 | /** 49 | * 收音机类型,其值为 {@value} 50 | */ 51 | public static final int RADIO = 1; 52 | /** 53 | * 蓝牙类型,其值为 {@value} 54 | */ 55 | public static final int BLUETOOTH = 2; 56 | 57 | } 58 | 59 | /** 60 | * 控制类型Event 61 | */ 62 | public static class EventControl { 63 | public static class Action { 64 | public static final int UP = 0; 65 | public static final int DOWN = 1; 66 | } 67 | 68 | /** 69 | * app 类型 {@link AppType} 70 | */ 71 | public int mAppType; 72 | public int mAction; 73 | 74 | public EventControl(int appType, int action) { 75 | mAppType = appType; 76 | mAction = action; 77 | } 78 | 79 | public static String getName(int action) { 80 | return LogNameUtil.getName(action, Action.class); 81 | } 82 | 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/navigation/INavigationCallback.aidl: -------------------------------------------------------------------------------- 1 | // INavigationCallback.aidl 2 | package com.roadrover.services.navigation; 3 | 4 | 5 | interface INavigationCallback { 6 | /** 7 | * 导航过程中发送引导类型,和引导属性 8 | * @param twelveClock {@link com.roadrover.sdk.navigation.IVINavigation.TwelveClockType} 9 | * @param turnID twelveClock参数为TwelveClockType.NORMAL时
10 | * {@link com.roadrover.sdk.navigation.IVINavigation.NormalTurnId}
11 | * twelveClock参数为TwelveClockType.TWELVE_CLOCK时
12 | * {@link com.roadrover.sdk.navigation.IVINavigation.TwelveClockTurnId}
13 | * @param arrayTurn 方向背景,twelveClock参数为TwelveClockType.TWELVE_CLOCK时,有背景
14 | * {@link com.roadrover.sdk.navigation.IVINavigation.TwelveClockTurnId}
15 | * @param guideType 引导点属性 {@link com.roadrover.sdk.navigation.IVINavigation.GuideType} 16 | * @param distance 到下一个引导点的距离,单位 m 17 | * @param destDistance 到目的地的距离,单位 m 18 | * @param destTime 到目的地所需要的时间,单位 s 19 | * @param roadName 当前道路的名称,utf-8编码 20 | * @param nextRoadName 下一个道路的名称,utf-8编码 21 | * @param destName 目的地的名字 22 | */ 23 | void onNavigationType(int twelveClock, int turnID, in int []arrayTurn,int guideType, int distance, 24 | int destDistance,int destTime, String roadName, String nextRoadName,String destName); 25 | 26 | /** 27 | * 发自车行政区变更时,发送该消息,例:广东省深圳市南山区 28 | * @param province 省 29 | * @param city 市 30 | * @param county 区域 31 | */ 32 | void onNavigationAddress(String province, String city, String county); 33 | 34 | /** 35 | * 设置指南针的指向 36 | * @param direction 指向 37 | */ 38 | void onNavigationGuide(int direction); 39 | 40 | /** 41 | * 设置电子眼的信息 42 | * @param type 电子眼的类型,{@link com.roadrover.sdk.navigation.IVINavigation.ElectronicEyeType} 43 | * @param distance 到下一个电子眼的距离,单位 m 44 | * @param speedLimit 限速多少 45 | */ 46 | void onNavigationEyeInfo(int type, int distance, int speedLimit); 47 | } 48 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/btservice/bluetooth/BluetoothDevice.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.btservice.bluetooth; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | import android.text.TextUtils; 6 | 7 | /** 8 | * 蓝牙设备对象
9 | * 1) 用户调用 searchNewDevice 接口时,返回该对象
10 | * 2) 用户调用 getPairedDevice 接口时,返回该对象列表
11 | */ 12 | 13 | public class BluetoothDevice implements Parcelable { 14 | 15 | public String name = ""; 16 | public String addr = ""; 17 | 18 | protected BluetoothDevice(Parcel in) { 19 | readFromParcel(in); 20 | } 21 | 22 | @Override 23 | public void writeToParcel(Parcel dest, int flags) { 24 | dest.writeString(name); 25 | dest.writeString(addr); 26 | } 27 | 28 | public void readFromParcel(Parcel source) { 29 | if (null != source) { 30 | name = source.readString(); 31 | addr = source.readString(); 32 | } 33 | } 34 | 35 | @Override 36 | public int describeContents() { 37 | return 0; 38 | } 39 | 40 | public static final Creator CREATOR = new Creator() { 41 | @Override 42 | public BluetoothDevice createFromParcel(Parcel in) { 43 | return new BluetoothDevice(in); 44 | } 45 | 46 | @Override 47 | public BluetoothDevice[] newArray(int size) { 48 | return new BluetoothDevice[size]; 49 | } 50 | }; 51 | 52 | /** 53 | * 创建一个蓝牙设备 54 | * @param addr 55 | * @param name 56 | * @return 57 | */ 58 | public static BluetoothDevice createDevice(String addr, String name) { 59 | BluetoothDevice device = CREATOR.createFromParcel(null); 60 | device.name = name; 61 | device.addr = addr; 62 | return device; 63 | } 64 | 65 | @Override 66 | public boolean equals(Object o) { 67 | if (null == o || !(o instanceof BluetoothDevice)) { 68 | return false; 69 | } 70 | BluetoothDevice bluetoothDevice = (BluetoothDevice) o; 71 | if (bluetoothDevice == this || TextUtils.equals(bluetoothDevice.addr, addr)) { 72 | return true; 73 | } 74 | return false; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/devices/carrecord/CarRecordManager.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.devices.carrecord; 2 | 3 | import android.content.Context; 4 | 5 | import com.roadrover.sdk.car.CarManager; 6 | import com.roadrover.sdk.car.IVICar; 7 | 8 | /** 9 | * 功能:行车记录仪管理类 10 | * 11 | */ 12 | public class CarRecordManager implements IVICarRecord.CarRecordListener{ 13 | 14 | private CarManager mCarManager; 15 | private int mCarId; 16 | 17 | /** 18 | * 构造函数 19 | * @param context 上下文 20 | */ 21 | public CarRecordManager(Context context, int carId) { 22 | mCarManager = new CarManager(context, null, null, false); 23 | this.mCarId = carId; 24 | } 25 | 26 | @Override 27 | public void onClickMenu() { 28 | setExtraDeviceData(IVICarRecord.UserKeyOperation.MENU); 29 | } 30 | 31 | @Override 32 | public void onClickModel() { 33 | setExtraDeviceData(IVICarRecord.UserKeyOperation.MODEL); 34 | } 35 | 36 | @Override 37 | public void onClickUp() { 38 | setExtraDeviceData(IVICarRecord.UserKeyOperation.UP); 39 | } 40 | 41 | @Override 42 | public void onClickDown() { 43 | setExtraDeviceData(IVICarRecord.UserKeyOperation.DOWN); 44 | } 45 | 46 | @Override 47 | public void onClickEnsure() { 48 | setExtraDeviceData(IVICarRecord.UserKeyOperation.ENSURE); 49 | } 50 | 51 | /** 52 | * 向MCU发送触摸坐标值 53 | * @param x 54 | * @param y 55 | */ 56 | @Override 57 | public void onCLickCoordinate(int x, int y) { 58 | if (mCarManager != null) { 59 | mCarManager.setTouch(x, y, IVICar.TouchClickEvent.DOWN); 60 | } 61 | } 62 | 63 | @Override 64 | public void onDestroy() { 65 | mCarManager.disconnect(); 66 | } 67 | 68 | /** 69 | * 向MCU发送按键状态码 70 | * 71 | * @param extraDeviceData 行车记录仪功能码组 72 | */ 73 | public void setExtraDeviceData(byte extraDeviceData) { 74 | if (mCarManager != null) { 75 | byte[] bytes = new byte[]{IVICarRecord.OperationType.KeyOperation, extraDeviceData}; 76 | mCarManager.setExtraDevice(mCarId, IVICar.ExtraDevice.DeviceId.DRIVING_RECORDER, bytes); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/utils/AndroidAutoUtil.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.utils; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.support.annotation.NonNull; 6 | import android.text.TextUtils; 7 | 8 | import com.roadrover.sdk.system.IVISystem; 9 | 10 | /** 11 | * 用来适配AndroidAuto的工具类 12 | */ 13 | 14 | public class AndroidAutoUtil extends BaseThreeAppUtil { 15 | 16 | private boolean mIsAndroidAutoStatus = false; // 当前是否是AndroidAuto状态 17 | 18 | /** 19 | * auto状态 20 | */ 21 | public interface AndroidAutoListener { 22 | /** 23 | * auto进入 24 | */ 25 | void onStartAuto(); 26 | 27 | /** 28 | * auto结束 29 | */ 30 | void onEndAuto(); 31 | } 32 | private AndroidAutoListener mAndroidAutoListener; // 监听auto状态 33 | 34 | public AndroidAutoUtil(@NonNull Context context) { 35 | super(context); 36 | 37 | // 注册监听 38 | init(IVISystem.ACTION_ANDROID_AUTO_START, IVISystem.ACTION_ANDROID_AUTO_END); 39 | } 40 | 41 | /** 42 | * 监听安卓auto的打开和关闭状态 43 | * @param listener 44 | */ 45 | public void setAndroidAutoListener(AndroidAutoListener listener) { 46 | mAndroidAutoListener = listener; 47 | } 48 | 49 | /** 50 | * 判断当前是否连接Auto状态 51 | * @return 52 | */ 53 | public boolean isAndroidAutoStatus() { 54 | return mIsAndroidAutoStatus; 55 | } 56 | 57 | @Override 58 | protected void onReceive(Context context, Intent intent) { 59 | if (intent != null) { 60 | String action = intent.getAction(); 61 | Logcat.d("action:" + action); 62 | if (TextUtils.equals(action, IVISystem.ACTION_ANDROID_AUTO_START)) { // 进入Android Auto 63 | mIsAndroidAutoStatus = true; 64 | if (mAndroidAutoListener != null) { 65 | mAndroidAutoListener.onStartAuto(); 66 | } 67 | } else if (TextUtils.equals(action, IVISystem.ACTION_ANDROID_AUTO_END)) { // 退出Android Auto 68 | mIsAndroidAutoStatus = false; 69 | if (mAndroidAutoListener != null) { 70 | mAndroidAutoListener.onEndAuto(); 71 | } 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/devices/carrecord/IVICarRecord.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.devices.carrecord; 2 | 3 | import com.roadrover.sdk.utils.LogNameUtil; 4 | 5 | /** 6 | * 功能:行车记录仪常用静态常量和接口 7 | * 8 | */ 9 | 10 | public class IVICarRecord { 11 | 12 | /** 13 | * 行车记录仪用户按键操作标记 14 | */ 15 | public static class InterType { 16 | 17 | /** 菜单 */ 18 | public static final int TYPE_MENU = 1; 19 | 20 | /** 向上 */ 21 | public static final int TYPE_UP = 2; 22 | 23 | /** 向下 */ 24 | public static final int TYPE_DOWN = 3; 25 | 26 | /** 确认 */ 27 | public static final int TYPE_ENSURE = 4; 28 | 29 | /** 模式 */ 30 | public static final int TYPE_MODEL = 5; 31 | 32 | /** 紧急录制 */ 33 | public static final int TYPE_EMERGENCY = 6; 34 | 35 | public static String getName(int id) { 36 | return LogNameUtil.getName(id, InterType.class); 37 | } 38 | } 39 | 40 | /** 41 | * 行车记录仪用户按键协议 42 | */ 43 | public static class UserKeyOperation { 44 | 45 | /** 菜单 */ 46 | public static final byte MENU = 0x01; 47 | 48 | /** 向上 */ 49 | public static final byte UP = 0x02; 50 | 51 | /** 向下 */ 52 | public static final byte DOWN = 0x03; 53 | 54 | /** 确认 */ 55 | public static final byte ENSURE = 0x04; 56 | 57 | /** 模式 */ 58 | public static final byte MODEL = 0x05; 59 | 60 | /** 紧急录制 */ 61 | public static final byte EMERGENCY = 0x06; 62 | 63 | public static String getName(int id) { 64 | return LogNameUtil.getName(id, UserKeyOperation.class); 65 | } 66 | } 67 | 68 | /***用户操作状态***/ 69 | public static class OperationType{ 70 | /** 按键 */ 71 | public static final byte KeyOperation = 0x01; 72 | } 73 | 74 | 75 | public interface CarRecordListener{ 76 | 77 | /** 点击菜单键 */ 78 | void onClickMenu(); 79 | 80 | /** 点击模式键 */ 81 | void onClickModel(); 82 | 83 | /** 点击向上键 */ 84 | void onClickUp(); 85 | 86 | /** 点击向下键 */ 87 | void onClickDown(); 88 | 89 | /** 点击确认键 */ 90 | void onClickEnsure(); 91 | 92 | /** 点击视频坐标 */ 93 | void onCLickCoordinate(int x, int y); 94 | 95 | /** 销毁内部注册**/ 96 | void onDestroy(); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/radio/IRadioCallback.aidl: -------------------------------------------------------------------------------- 1 | package com.roadrover.services.radio; 2 | 3 | interface IRadioCallback { 4 | /** 5 | * 收音频率发生变化 6 | * @param freq 收音频率 7 | */ 8 | void onFreqChanged(int freq); 9 | /** 10 | * 搜索电台结果信息回调 11 | * @param freq 收音频率 12 | * @param signalStrength 信号强度 13 | */ 14 | void onScanResult(int freq, int signalStrength); 15 | /** 16 | * 收音开始搜索 17 | * @param isScanAll true全部搜索,false上下扫台 18 | */ 19 | void onScanStart(boolean isScanAll); 20 | /** 21 | * 收音搜索正常结束 22 | * @param isScanAll true全部搜索,false上下扫台 23 | */ 24 | void onScanEnd(boolean isScanAll); 25 | /** 26 | * 收音搜索异常结束(被打断) 27 | * @param isScanAll true全部搜索,false上下扫台 28 | */ 29 | void onScanAbort(boolean isScanAll); 30 | /** 31 | * 收音当前信号强度更新(不在搜台状态下) 32 | * @param freq 收音频率 33 | * @param signalStrength 信号强度 34 | */ 35 | void onSignalUpdate(int freq, int signalStrength); 36 | /** 37 | * 挂起 38 | */ 39 | void suspend(); 40 | /** 41 | * 恢复 42 | */ 43 | void resume(); 44 | /** 45 | * 暂停 46 | */ 47 | void pause(); 48 | /** 49 | * 播放 50 | */ 51 | void play(); 52 | /** 53 | * 播放暂停 54 | */ 55 | void playPause(); 56 | /** 57 | * 停止 58 | */ 59 | void stop(); 60 | /** 61 | * 下一曲 62 | */ 63 | void next(); 64 | /** 65 | * 上一曲 66 | */ 67 | void prev(); 68 | /** 69 | * 退出应用 70 | */ 71 | void quitApp(); 72 | /** 73 | * 选择指定index的电台进行收听 74 | */ 75 | void select(int index); 76 | /** 77 | * 设置收藏/取消收藏频点 78 | * @param isFavour true收藏,false取消收藏 79 | */ 80 | void setFavour(boolean isFavour); 81 | 82 | /** 83 | * RDS,Program Service信息发生变化 84 | * @param pi PI码 85 | * @param freq 收音频率 86 | * @param ps PS字符串,最多8个字符 87 | */ 88 | void onRdsPsChanged(int pi, int freq, String ps); 89 | 90 | /** 91 | * RDS,Radio Text信息发生变化 92 | * @param pi PI码 93 | * @param freq 收音频率 94 | * @param rt RT字符串,最多64个字符 95 | */ 96 | void onRdsRtChanged(int pi, int freq, String rt); 97 | 98 | /** 99 | * RDS,mask,包括TP, TA, PTY等 100 | * @param pi PI码 101 | * @param freq 收音频率 102 | * @param pty PTY码 103 | * @param tp TP 104 | * @param ta TA 105 | */ 106 | void onRdsMaskChanged(int pi, int freq, int pty, int tp, int ta); 107 | 108 | /** 109 | * 频率调节旋钮 110 | * @param add 顺时针,一般为增加频率 111 | */ 112 | void onTuneRotate(boolean add); 113 | 114 | /** 115 | * 向上搜台 116 | */ 117 | void scanUp(); 118 | 119 | /** 120 | * 向下搜台 121 | */ 122 | void scanDown(); 123 | 124 | /** 125 | * 全部搜索 126 | */ 127 | void scanAll(); 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/utils/CarPlayUtil.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.utils; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.support.annotation.NonNull; 6 | import android.text.TextUtils; 7 | 8 | import com.roadrover.sdk.system.IVISystem; 9 | 10 | /** 11 | * 用来适配CarPlay的工具类 12 | */ 13 | 14 | public class CarPlayUtil extends BaseThreeAppUtil { 15 | 16 | /** 当前是否在CarPlay状态 */ 17 | private boolean mIsCarPlayStatus = false; 18 | 19 | /** 20 | * CarPlay状态监听 21 | */ 22 | public interface CarPlayListener { 23 | /** 24 | * CarPlay状态连接 25 | */ 26 | void onStartCarPlay(); 27 | 28 | /** 29 | * CarPlay断开 30 | */ 31 | void onEndCarPlay(); 32 | 33 | /** 34 | * CarPlay电话开始 35 | */ 36 | void onStartPhone(); 37 | 38 | /** 39 | * CarPlay电话结束 40 | */ 41 | void onEndPhone(); 42 | } 43 | /** CarPlay接口回调 */ 44 | private CarPlayListener mCarPlayListener; 45 | 46 | public CarPlayUtil(@NonNull Context context) { 47 | super(context); 48 | 49 | // 注册监听 50 | init(IVISystem.ACTION_CARPLAY_START, IVISystem.ACTION_CARPLAY_END, 51 | IVISystem.ACTION_CARPLAY_PHONE_START, IVISystem.ACTION_CARPLAY_PHONE_END); 52 | } 53 | 54 | /** 55 | * 判断当前是否在CarPlay状态 56 | * @return 57 | */ 58 | public boolean isCarPlayStatus() { 59 | return mIsCarPlayStatus; 60 | } 61 | 62 | /** 63 | * 设置CarPlay 64 | * @param listener 65 | */ 66 | public void setCarPlayListener(CarPlayListener listener) { 67 | mCarPlayListener = listener; 68 | } 69 | 70 | @Override 71 | protected void onReceive(Context context, Intent intent) { 72 | if (intent != null) { 73 | String action = intent.getAction(); 74 | Logcat.d("action:" + action); 75 | if (TextUtils.equals(action, IVISystem.ACTION_CARPLAY_START)) { // 进入CarPlay 76 | mIsCarPlayStatus = true; 77 | if (mCarPlayListener != null) { 78 | mCarPlayListener.onStartCarPlay(); 79 | } 80 | } else if (TextUtils.equals(action, IVISystem.ACTION_CARPLAY_END)) { // 退出CarPlay 81 | mIsCarPlayStatus = false; 82 | if (mCarPlayListener != null) { 83 | mCarPlayListener.onEndCarPlay(); 84 | } 85 | } else if (TextUtils.equals(action, IVISystem.ACTION_CARPLAY_PHONE_START)) { // carPlay 电话开始 86 | if (mCarPlayListener != null) { 87 | mCarPlayListener.onStartPhone(); 88 | } 89 | } else if (TextUtils.equals(action, IVISystem.ACTION_CARPLAY_PHONE_END)) { // carPlay 电话结束 90 | if (mCarPlayListener != null) { 91 | mCarPlayListener.onEndPhone(); 92 | } 93 | } 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/utils/EventBusUtil.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.utils; 2 | 3 | import org.greenrobot.eventbus.EventBus; 4 | 5 | /** 6 | * event bus util class. 7 | */ 8 | 9 | public class EventBusUtil { 10 | 11 | private EventBus mEventBus; // 封装的EventBus对象 12 | 13 | public EventBusUtil(boolean useDefaultEventBus) { 14 | this(null, useDefaultEventBus); 15 | } 16 | 17 | /** 18 | * Eventbus封装类构造 19 | * @param useDefaultEventBus 是否使用默认的EventBus,如果需要不使用默认的EventBus,可以使用false 20 | */ 21 | public EventBusUtil(Object object, boolean useDefaultEventBus) { 22 | if (useDefaultEventBus) { 23 | mEventBus = EventBus.getDefault(); 24 | } else { 25 | mEventBus = new EventBus(); 26 | } 27 | if (object != null) { 28 | register(object); 29 | } 30 | } 31 | 32 | /** 33 | * 销毁 34 | */ 35 | public void destroy(Object object) { 36 | unregister(object); 37 | mEventBus = null; 38 | } 39 | 40 | /** 41 | * 注册eventBus的监听 42 | * @param object 43 | */ 44 | public void register(Object object) { 45 | try { 46 | if (object != null) { 47 | if (mEventBus != null && !mEventBus.isRegistered(object)) { 48 | mEventBus.register(object); 49 | } 50 | } 51 | } catch (Exception e) { 52 | e.printStackTrace(); 53 | } 54 | } 55 | 56 | /** 57 | * 注销eventBus的监听 58 | * @param object 59 | */ 60 | public void unregister(Object object) { 61 | try { 62 | if (mEventBus != null && mEventBus.isRegistered(object)) { 63 | mEventBus.unregister(object); 64 | } 65 | } catch (Exception e) { 66 | e.printStackTrace(); 67 | } 68 | } 69 | 70 | /** 71 | * 是否注册 72 | * @return 73 | */ 74 | public boolean isRegistered(Object object) { 75 | if (mEventBus != null) { 76 | try { 77 | return mEventBus.isRegistered(object); 78 | } catch (Exception e) { 79 | e.printStackTrace(); 80 | } 81 | } 82 | return false; 83 | } 84 | 85 | /** 86 | * 发送一个消息 87 | * @param object 88 | */ 89 | public void post(Object object) { 90 | if (mEventBus != null) { 91 | try { 92 | mEventBus.post(object); 93 | } catch (Exception e) { 94 | e.printStackTrace(); 95 | } 96 | } 97 | } 98 | 99 | /** 100 | * 发送一个粘性消息 101 | * @param object 102 | */ 103 | public void postSticky(Object object) { 104 | if (mEventBus != null) { 105 | try { 106 | mEventBus.postSticky(object); 107 | } catch (Exception e) { 108 | e.printStackTrace(); 109 | } 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/Param.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk; 2 | 3 | import android.view.View; 4 | import android.widget.SeekBar; 5 | import android.widget.TextView; 6 | 7 | public class Param { 8 | public int mId; 9 | public int mValue; 10 | public int mMin; 11 | public int mMax; 12 | public int mDefault; 13 | 14 | public Param() { 15 | mId = 0; 16 | } 17 | 18 | /** 19 | * 普通参数 20 | */ 21 | public Param(int id, int min, int max, int def, int value) { 22 | mId = id; 23 | mMin = min; 24 | mMax = max; 25 | mDefault = def; 26 | mValue = value; 27 | } 28 | 29 | /** 30 | * 普通参数 31 | */ 32 | public Param(int id, int min, int max, int defaultValue) { 33 | mId = id; 34 | mMin = min; 35 | mMax = max; 36 | mDefault = defaultValue; 37 | mValue = defaultValue; 38 | } 39 | 40 | /** 41 | * 布尔型参数 42 | */ 43 | public Param(int id, boolean defaultValue) { 44 | mId = id; 45 | mMin = 0; 46 | mMax = 1; 47 | mDefault = defaultValue ? 1 : 0; 48 | mValue = mDefault; 49 | } 50 | 51 | /** 52 | * 只读的参数,是一个属性值 53 | */ 54 | public Param(int id, int value) { 55 | mId = id; 56 | mMin = value; 57 | mMax = value; 58 | mDefault = value; 59 | mValue = value; 60 | } 61 | 62 | public boolean set(int value) { 63 | int nextValue; 64 | if (value < mMin) { 65 | nextValue = mMin; 66 | } else if(value > mMax) { 67 | nextValue = mMax; 68 | } else { 69 | nextValue = value; 70 | } 71 | 72 | if (mValue != nextValue) { 73 | mValue = nextValue; 74 | return true; 75 | } else { 76 | return false; 77 | } 78 | } 79 | 80 | public boolean isReadOnly() { 81 | return (mMax == mMin); 82 | } 83 | public boolean isOn() { 84 | return mValue == 1; 85 | } 86 | 87 | public String getName() { 88 | return ""; 89 | } 90 | 91 | public String getValueText() { 92 | return String.valueOf(mValue); 93 | } 94 | 95 | public static void updateSeekBarAndTextView(Param param, SeekBar seekBar, 96 | TextView textView, String unit) { 97 | if (seekBar != null) { 98 | if (param == null) { 99 | seekBar.setVisibility(View.INVISIBLE); 100 | } else { 101 | seekBar.setVisibility(View.VISIBLE); 102 | seekBar.setMax(param.mMax - param.mMin); 103 | seekBar.setProgress(param.mValue - param.mMin); 104 | } 105 | } 106 | 107 | if (textView != null) { 108 | if (param == null) { 109 | textView.setVisibility(View.INVISIBLE); 110 | } else { 111 | textView.setVisibility(View.VISIBLE); 112 | textView.setText(String.valueOf(param.mValue) + unit); 113 | } 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/media/StMusic.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.services.media; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | import android.support.annotation.NonNull; 6 | import android.text.TextUtils; 7 | 8 | /** 9 | * Created by y on 2017/2/24. 10 | * 音乐的结构体类,该类主要用作id3信息传递 11 | */ 12 | 13 | public class StMusic implements Parcelable { 14 | 15 | /** 音乐文件路径 */ 16 | public String mPath = ""; 17 | /** track信息 */ 18 | public String mTrack = ""; 19 | /** 专辑信息 */ 20 | public String mAlbum = ""; 21 | /** 歌手名字 */ 22 | public String mArtist = ""; 23 | /** 歌曲名字 */ 24 | public String mName = ""; 25 | /** 歌曲时长 */ 26 | public long mDuration = 0; 27 | 28 | protected StMusic(Parcel in) { 29 | readFromParcel(in); 30 | } 31 | 32 | public static final Creator CREATOR = new Creator() { 33 | @Override 34 | public StMusic createFromParcel(Parcel in) { 35 | return new StMusic(in); 36 | } 37 | 38 | @Override 39 | public StMusic[] newArray(int size) { 40 | return new StMusic[size]; 41 | } 42 | }; 43 | 44 | @Override 45 | public int describeContents() { 46 | return 0; 47 | } 48 | 49 | @Override 50 | public void writeToParcel(Parcel parcel, int i) { 51 | parcel.writeString(mPath); 52 | parcel.writeString(mTrack); 53 | parcel.writeString(mAlbum); 54 | parcel.writeString(mArtist); 55 | parcel.writeString(mName); 56 | parcel.writeLong(mDuration); 57 | } 58 | 59 | public void readFromParcel(Parcel source) { 60 | if (null != source) { 61 | mPath = source.readString(); 62 | mTrack = source.readString(); 63 | mAlbum = source.readString(); 64 | mArtist = source.readString(); 65 | mName = source.readString(); 66 | mDuration = source.readLong(); 67 | // Logcat.d("mPath:" + mPath); 68 | } 69 | } 70 | 71 | /** 72 | * 创建一个音乐的数据传输对象 73 | * @param path 路径 74 | * @param track 音轨信息 75 | * @param album 歌手 76 | * @param artist 歌曲 77 | * @param name 名字 78 | * @param duration 时长 79 | * @return 80 | */ 81 | public static StMusic createStMusic(@NonNull String path, @NonNull String track, 82 | @NonNull String album, @NonNull String artist, 83 | @NonNull String name, long duration) { 84 | StMusic stMusic = CREATOR.createFromParcel(null); 85 | stMusic.mPath = path; 86 | stMusic.mTrack = track; 87 | stMusic.mAlbum = album; 88 | stMusic.mArtist = artist; 89 | stMusic.mName = name; 90 | stMusic.mDuration = duration; 91 | return stMusic; 92 | } 93 | 94 | @Override 95 | public boolean equals(Object o) { 96 | if (o == this) { 97 | return true; 98 | } 99 | if (o != null && o instanceof StMusic) { 100 | StMusic other = (StMusic) o; 101 | return TextUtils.equals(mPath, other.mPath); 102 | } 103 | return super.equals(o); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/avin/IAVIn.aidl: -------------------------------------------------------------------------------- 1 | package com.roadrover.services.avin; 2 | 3 | import com.roadrover.services.avin.IAVInCallback; 4 | 5 | interface IAVIn { 6 | /** 7 | * 打开AVIn 8 | * @param avId IVIAVIn.Id 9 | * @param callback 回调接口 10 | * @param packageName 包名 11 | */ 12 | void open(int avId, IAVInCallback callback, String packageName); 13 | 14 | /** 15 | * 关闭AVIn 16 | * @param avId IVIAVIn.Id 17 | */ 18 | void close(int avId); 19 | 20 | /** 21 | * 检查AVIn设备是否为打开状态 22 | * @param avId IVIAVIn.Id 23 | */ 24 | boolean isOpen(int avId); 25 | 26 | /** 27 | * 指定ID是否有效 28 | * @param id 由avId和subId 组合而成 VideoParam#makeId 29 | */ 30 | boolean isParamAvailable(int id); 31 | 32 | /** 33 | * 获取指定ID的最小值 34 | * @param id 由avId和subId 组合而成 VideoParam#makeId 35 | */ 36 | int getParamMinValue(int id); 37 | 38 | /** 39 | * 获取指定ID的最大值 40 | * @param id 由avId和subId 组合而成 VideoParam#makeId 41 | */ 42 | int getParamMaxValue(int id); 43 | 44 | /** 45 | * 获取指定ID的默认值 46 | * @param id 由avId和subId 组合而成 VideoParam#makeId 47 | */ 48 | int getParamDefaultValue(int id); 49 | 50 | /** 51 | * 获取指定ID的值 52 | * @param id 由avId和subId 组合而成 VideoParam#makeId 53 | */ 54 | int getParam(int id); 55 | 56 | /** 57 | * 设置视频参数 58 | * @param id 由avId和subId 组合而成 VideoParam#makeId 59 | * @param value 参数的值 60 | */ 61 | void setParam(int id, int value); 62 | 63 | /** 64 | * 获取视频信号 65 | * @param avId IVIAVIn.Id 66 | */ 67 | int getVideoSignal(int avId); 68 | 69 | /** 70 | * 是否允许播放视频 71 | */ 72 | boolean isVideoPermit(); 73 | 74 | /** 75 | * 反注册AVIn回调 76 | * @param callback IAVInCallback回调对象 77 | */ 78 | void unRegisterCallback(IAVInCallback callback); 79 | 80 | /** 81 | * 通知Service,应用即将要打开Android的摄像头 82 | * @param avId IVIAVIn.Id 83 | */ 84 | void setAndroidCameraOpenPrepared(int avId); 85 | 86 | /** 87 | * 通知Service,应用已经打开或者关闭了Android的摄像头 88 | * @param avId IVIAVIn.Id 89 | * @param isOpen true 打开状态,false 关闭状态 90 | */ 91 | void setAndroidCameraOpen(int avId, boolean isOpen); 92 | 93 | /** 94 | * 获取AVIN源的插入状态,目前只支持导游麦克风插入状态 95 | * @param avId IVIAVIn.Id 96 | */ 97 | boolean getSourcePlugin(int avId); 98 | 99 | /** 100 | * 临时开始播放avId的声音,不作为媒体 101 | * @param avId AV ID 102 | * @param zone IVIMedia.Zone 103 | * @param mix 是否混音, 104 | * true:混音,媒体降低音量,类似导航提示音 105 | * false:不混音,暂停当前媒体,类似电话和声控提示音 106 | */ 107 | void startTempSound(int avId, int zone, boolean mix); 108 | 109 | /** 110 | * 结束临时播放的avId声音 111 | * @param avId IVIAVIn.Id 112 | */ 113 | void endTempSound(int avId); 114 | 115 | /** 116 | * 注册AVIN callback,使得不打开avin也可以检测到一些消息 117 | * @param callback IAVInCallback回调对象 118 | */ 119 | void registerCallback(IAVInCallback callback); 120 | 121 | /** 122 | * 控制TV 123 | * @param control 控制码,见{com.roadrover.sdk.avin.IVITV.Control} 124 | */ 125 | boolean controlTV(int control); 126 | 127 | /** 128 | * 发送触摸坐标,范围{255, 255} 129 | * @param x X坐标 130 | * @param y Y坐标 131 | */ 132 | boolean sendTouch(int x, int y); 133 | } -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/btservice/bluetooth/BluetoothVCardBook.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.btservice.bluetooth; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | import android.text.TextUtils; 6 | 7 | /** 8 | * 蓝牙电话本,通话记录, 传递数据类 9 | */ 10 | 11 | public class BluetoothVCardBook implements Parcelable { 12 | 13 | /** 14 | * 编码类型 15 | */ 16 | public String codingType; 17 | 18 | /** 19 | * 名字 20 | */ 21 | public String name; 22 | 23 | /** 24 | * 类型,已拨或者未接等 25 | */ 26 | public String type; 27 | 28 | /** 29 | * 电话号码 30 | */ 31 | public String phoneNumber; 32 | 33 | /** 34 | * 通话记录,通话时间,时间为 20170109T211652 2017/01/09 21:16:52 35 | */ 36 | public String callTime; 37 | 38 | protected BluetoothVCardBook(Parcel in) { 39 | readFromParcel(in); 40 | } 41 | 42 | /** 43 | * 创建电话本工具类 44 | * @param codingType 编码类型 45 | * @param name 名字 46 | * @param type 类型 已拨或者未接等 47 | * @param phoneNumber 电话号码 48 | * @param callTime 通话记录,通话时间 49 | * @return 50 | */ 51 | public static BluetoothVCardBook createVCardBook(String codingType, String name, String type, String phoneNumber, String callTime) { 52 | BluetoothVCardBook book = CREATOR.createFromParcel(null); 53 | book.codingType = codingType; 54 | book.name = name; 55 | book.type = type; 56 | book.phoneNumber = phoneNumber; 57 | book.callTime = callTime; 58 | return book; 59 | } 60 | 61 | public static final Creator CREATOR = new Creator() { 62 | @Override 63 | public BluetoothVCardBook createFromParcel(Parcel in) { 64 | return new BluetoothVCardBook(in); 65 | } 66 | 67 | @Override 68 | public BluetoothVCardBook[] newArray(int size) { 69 | return new BluetoothVCardBook[size]; 70 | } 71 | }; 72 | 73 | @Override 74 | public String toString() { 75 | return "coding:" + codingType + " name:" + name + 76 | " type:" + type + " number:" + phoneNumber + 77 | " time:" + callTime; 78 | } 79 | 80 | @Override 81 | public int describeContents() { 82 | return 0; 83 | } 84 | 85 | @Override 86 | public void writeToParcel(Parcel parcel, int i) { 87 | parcel.writeString(codingType); 88 | parcel.writeString(name); 89 | parcel.writeString(type); 90 | parcel.writeString(phoneNumber); 91 | parcel.writeString(callTime); 92 | } 93 | 94 | public void readFromParcel(Parcel source) { 95 | if (null != source) { 96 | codingType = source.readString(); 97 | name = source.readString(); 98 | type = source.readString(); 99 | phoneNumber = source.readString(); 100 | callTime = source.readString(); 101 | } 102 | } 103 | 104 | /** 105 | * 判断两条记录是否是同一条记录 106 | * @param o 107 | * @return 名字一样,并且电话号码一样,并且通话时间一样,认为是同一条,同一条返回 true 108 | */ 109 | @Override 110 | public boolean equals(Object o) { 111 | if (o == this) { 112 | return true; 113 | } 114 | if (o != null && o instanceof BluetoothVCardBook) { 115 | BluetoothVCardBook other = (BluetoothVCardBook) o; 116 | if (TextUtils.equals(name, other.name) && 117 | TextUtils.equals(phoneNumber, other.phoneNumber) 118 | && TextUtils.equals(callTime, other.callTime)) { 119 | return true; 120 | } 121 | } 122 | return false; 123 | } 124 | 125 | @Override 126 | public int hashCode() { 127 | if (name != null) { 128 | return name.hashCode(); 129 | } 130 | return 0; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/radio/IRadio.aidl: -------------------------------------------------------------------------------- 1 | package com.roadrover.services.radio; 2 | 3 | import com.roadrover.services.radio.IRadioCallback; 4 | 5 | interface IRadio { 6 | /** 7 | * 打开设备 8 | * @param callback 回调接口 9 | */ 10 | void open(IRadioCallback callback, String packageName); 11 | 12 | /** 13 | * 关闭设备 14 | */ 15 | void close(); 16 | 17 | /** 18 | * 设置频率 19 | * @param freq 当前频率点 20 | */ 21 | void setFreq(int freq); 22 | 23 | /** 24 | * 获取当前频率 25 | */ 26 | int getFreq(); 27 | 28 | /** 29 | * 设置 fm, am 30 | * @param band 31 | */ 32 | void setBand(int band); 33 | 34 | /** 35 | * 获取当前是fm还是am 36 | */ 37 | int getBand(); 38 | 39 | /** 40 | * 设置 区域 41 | * @param location 42 | */ 43 | void setLocation(int location); 44 | 45 | /** 46 | * 上搜索 47 | * @param freqStart 搜索的起始位置 48 | */ 49 | void scanUp(int freqStart); 50 | 51 | /** 52 | * 下搜索 53 | * @param freqStart 搜索的起始位置 54 | */ 55 | void scanDown(int freqStart); 56 | 57 | /** 58 | * 全局搜索 59 | */ 60 | void scanAll(); 61 | 62 | /** 63 | * 停止搜索 64 | */ 65 | boolean scanStop(); 66 | 67 | /** 68 | * 向上/下调一步频率 69 | * @param direction 1:向上,-1:向下 70 | */ 71 | void step(int direction); 72 | 73 | /** 74 | * 得到收音机的设备ID 75 | */ 76 | int getId(); 77 | 78 | /** 79 | * RDS 打开或者关闭TA 80 | */ 81 | void selectRdsTa(boolean on); 82 | 83 | /** 84 | * RDS 打开或者关闭AF 85 | */ 86 | void selectRdsAf(boolean on); 87 | 88 | /** 89 | * RDS 选择PTY, PTY_UNKNOWN : 取消选择 90 | */ 91 | void selectRdsPty(int pty); 92 | 93 | /** 94 | * RDS 选择是否只收听包含TP的节目 95 | */ 96 | void selectRdsTp(boolean on); 97 | 98 | /** 99 | * 设置媒体信息,电台名或者RDS PS 100 | * @param popup 是否弹出媒体信息小窗口 101 | */ 102 | void setStationDisplayName(String name, boolean popup); 103 | 104 | /** 105 | * 选择收音机声音输出区 106 | * @param zone IVIMedia.Zone 107 | */ 108 | void setZone(int zone); 109 | 110 | /** 111 | * 获取收音机声音输出区 112 | * @param zone IVIMedia.Zone 113 | */ 114 | int getZone(); 115 | 116 | /** 117 | * 打开收音机双区媒体专用 118 | * @param callback 回调接口 119 | * @param zone IVIMedia.Zone 120 | */ 121 | void openInZone(IRadioCallback callback, String packageName, int zone); 122 | 123 | /** 124 | * 获取PS文本 125 | * @param freq 指定频率 126 | */ 127 | String getPSText(int freq); 128 | 129 | /** 130 | * 获取搜台动作 131 | */ 132 | int getScanAction(); 133 | 134 | /** 135 | * 设置FM搜台条件,开发者工具使用,协助硬件、销售支持、业务等部门现场调解搜台参数 136 | * @param usn UltraSonic Noise,超声波噪声,范围 0-100.0f 137 | * @param wam Wideband AM ,范围 0-100.0f 138 | * @param offset level-offset 电平偏移可用于校正天线增益,范围 0-100.0f 139 | * @param bw IF bandwidth 中频带宽,范围0-100.0f 140 | * @param autoLevel 自动搜台门限 范围 0-255.0f 141 | * @param manualLevel 手动搜台门限 范围 0-255.0f 142 | */ 143 | void setFMScanCondition(float usn, float wam, float offset, float bw, float autoLevel, float manualLevel); 144 | 145 | /** 146 | * 获取FM搜台条件 147 | * @return float[0]:usn 148 | * float[1]:wam 149 | * float[2]:offset 150 | * float[3]:bw 151 | * float[4]:autoLevel 152 | * float[5]:manualLevel 153 | */ 154 | float[] getFMScanConditions(); 155 | 156 | /** 157 | * 设置AM搜台条件,开发者工具使用,协助硬件、销售支持、业务等部门现场调解搜台参数 158 | * @param offset level-offset 电平偏移可用于校正天线增益,范围 0-100.0f 159 | * @param bw IF bandwidth 中频带宽,范围0-100.0f 160 | * @param autoLevel 自动搜台门限 范围 0-255.0f 161 | * @param manualLevel 手动搜台门限 范围 0-255.0f 162 | */ 163 | void setAMScanCondition(float offset, float bw, float autoLevel, float manualLevel); 164 | 165 | /** 166 | * 获取AM搜台条件 167 | * @return float[0]:offset 168 | * float[1]:bw 169 | * float[2]:autoLevel 170 | * float[3]:manualLevel 171 | */ 172 | float[] getAMScanConditions(); 173 | } -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/car/AmpAudio.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.car; 2 | 3 | import com.roadrover.sdk.utils.Logcat; 4 | 5 | /** 6 | * 协议外部功放音效类 7 | */ 8 | 9 | public class AmpAudio { 10 | public static final int INVALID = 0xff; 11 | public boolean mIsHasAmpAudio = false; 12 | public byte[] mData; 13 | public int mMaxVolume; 14 | public int mMaxBass; 15 | public int mMaxMiddle; 16 | public int mMaxTreble; 17 | public int mMaxBalance; 18 | public int mMaxFade; 19 | public int mDefaultPreVolume; 20 | 21 | public static class Id { 22 | /**音量最大值*/ 23 | public static final int VOLUME = 0; 24 | /**低音最大值*/ 25 | public static final int BASS = 1; 26 | /**中音最大值*/ 27 | public static final int MIDDLE = 2; 28 | /**高音最大值*/ 29 | public static final int TREBLE = 3; 30 | /**平衡音最大值*/ 31 | public static final int BALANCE = 4; 32 | /**衰减音最大值*/ 33 | public static final int FADE = 5; 34 | } 35 | 36 | public AmpAudio() { 37 | mMaxVolume = INVALID; 38 | mMaxBass = INVALID; 39 | mMaxMiddle = INVALID; 40 | mMaxTreble = INVALID; 41 | mMaxBalance = INVALID; 42 | mMaxFade = INVALID; 43 | mIsHasAmpAudio = false; 44 | } 45 | 46 | public AmpAudio(byte[] buff) { 47 | mData = buff; 48 | parseAudioMaxData(buff); 49 | } 50 | 51 | /** 52 | * 设置数据值 53 | * @param buff 54 | */ 55 | public void setAmpMaxData(byte[] buff) { 56 | mData = buff; 57 | parseAudioMaxData(buff); 58 | } 59 | 60 | /** 61 | * 解析串口数据 62 | * @param buff 63 | */ 64 | private void parseAudioMaxData(byte[] buff) { 65 | if (buff != null && buff.length > 8) { 66 | mMaxVolume = buff[0] & 0xff; 67 | mMaxBass = buff[1] & 0xff; 68 | mMaxMiddle = buff[2] & 0xff; 69 | mMaxTreble = buff[3] & 0xff; 70 | mMaxBalance = buff[4] & 0xff; 71 | mMaxFade = buff[5] & 0xff; 72 | mDefaultPreVolume = buff[7] & 0xff; 73 | mIsHasAmpAudio = true; 74 | } else { 75 | Logcat.w("Invalid buff value !"); 76 | mMaxVolume = INVALID; 77 | mMaxBass = INVALID; 78 | mMaxMiddle = INVALID; 79 | mMaxTreble = INVALID; 80 | mMaxBalance = INVALID; 81 | mMaxFade = INVALID; 82 | mDefaultPreVolume = INVALID; 83 | mIsHasAmpAudio = false; 84 | } 85 | } 86 | 87 | /** 88 | * 是否存在外部功放的音效调节功能 89 | * @return 90 | */ 91 | public boolean isAmpAudioExist() { 92 | return mIsHasAmpAudio; 93 | } 94 | 95 | /** 96 | * 获取默认的前置音量 97 | * @return 98 | */ 99 | public int getDefaultPreVolume() { 100 | return mDefaultPreVolume; 101 | } 102 | 103 | /** 104 | * 获取外部功放各个项可调节的最大值 105 | * @param id 106 | * @return 107 | */ 108 | public int getMaxAmpValue(int id) { 109 | switch (id) { 110 | case Id.VOLUME: 111 | return mMaxVolume; 112 | case Id.BASS: 113 | return mMaxBass; 114 | case Id.MIDDLE: 115 | return mMaxMiddle; 116 | case Id.TREBLE: 117 | return mMaxTreble; 118 | case Id.BALANCE: 119 | return mMaxBalance; 120 | case Id.FADE: 121 | return mMaxFade; 122 | default: 123 | break; 124 | } 125 | return INVALID; 126 | } 127 | 128 | /** 129 | * 获取外部功放各个项可调节的最小值 130 | * @param id 131 | * @return 132 | */ 133 | public int getMinAmpValue(int id) { 134 | return 0; 135 | } 136 | 137 | /** 138 | * 获取外部功放各个项可调节的默认值 139 | * @param id 140 | * @return 141 | */ 142 | public int getDefaultAmpValue(int id) { 143 | final int max = getMaxAmpValue(id); 144 | if (max == INVALID) { 145 | return 0; 146 | } else { 147 | return (max >> 1); 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/dab/DABManager.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.dab; 2 | 3 | import android.content.Context; 4 | import android.os.IBinder; 5 | import android.os.RemoteException; 6 | 7 | import com.roadrover.sdk.BaseManager; 8 | import com.roadrover.services.dab.IDAB; 9 | import com.roadrover.services.dab.IDABCallback; 10 | import com.roadrover.sdk.utils.Logcat; 11 | 12 | /** 13 | * 数字音频广播管理类,提供数字音频广播接口 14 | */ 15 | 16 | public class DABManager extends BaseManager { 17 | 18 | /** 19 | * DAB接口类对象 20 | */ 21 | private IDAB mDABInterface = null; 22 | 23 | /** 24 | * DAB服务回调对象 25 | */ 26 | private IDABCallback mDABCallback = new IDABCallback.Stub() { 27 | 28 | @Override 29 | public void onSystemNotification(int systemState) throws RemoteException { 30 | post(new IVIDAB.EventSystemStateChanged(systemState)); 31 | } 32 | }; 33 | 34 | public DABManager(Context context, ConnectListener connectListener) { 35 | super(context, connectListener, true); 36 | } 37 | 38 | @Override 39 | public void disconnect() { 40 | mDABCallback = null; 41 | 42 | super.disconnect(); 43 | } 44 | 45 | @Override 46 | protected String getServiceActionName() { 47 | return ServiceAction.DAB_ACTION; 48 | } 49 | 50 | @Override 51 | protected void onServiceConnected(IBinder service) { 52 | mDABInterface = IDAB.Stub.asInterface(service); 53 | } 54 | 55 | @Override 56 | protected void onServiceDisconnected() { 57 | mDABInterface = null; 58 | } 59 | 60 | /** 61 | * 打开设备,电台以上次的为准 62 | */ 63 | public void open() { 64 | if (mDABInterface != null) { 65 | try { 66 | mDABInterface.open(mDABCallback); 67 | } catch (RemoteException e) { 68 | e.printStackTrace(); 69 | } 70 | } else { 71 | Logcat.d("Service not connected"); 72 | } 73 | 74 | super.registerCallback(mDABCallback); 75 | } 76 | 77 | /** 78 | * 关闭设备 79 | */ 80 | public void close() { 81 | if (mDABInterface != null) { 82 | try { 83 | mDABInterface.close(); 84 | } catch (RemoteException e) { 85 | e.printStackTrace(); 86 | } 87 | } else { 88 | Logcat.d("Service not connected"); 89 | } 90 | } 91 | 92 | /** 93 | * 获取中间件版本 94 | */ 95 | public String getMiddlewareVersion() { 96 | if (mDABInterface != null) { 97 | try { 98 | return mDABInterface.getMiddlewareVersion(); 99 | } catch (RemoteException e) { 100 | e.printStackTrace(); 101 | } 102 | } else { 103 | Logcat.d("Service not connected"); 104 | } 105 | return null; 106 | } 107 | 108 | /** 109 | * 获取固件版本 110 | */ 111 | public String getSWVersion() { 112 | if (mDABInterface != null) { 113 | try { 114 | return mDABInterface.getMiddlewareVersion(); 115 | } catch (RemoteException e) { 116 | e.printStackTrace(); 117 | } 118 | } else { 119 | Logcat.d("Service not connected"); 120 | } 121 | return null; 122 | } 123 | 124 | /** 125 | * 获取硬件版本 126 | */ 127 | public String getHWVersion() { 128 | if (mDABInterface != null) { 129 | try { 130 | return mDABInterface.getMiddlewareVersion(); 131 | } catch (RemoteException e) { 132 | e.printStackTrace(); 133 | } 134 | } else { 135 | Logcat.d("Service not connected"); 136 | } 137 | return null; 138 | } 139 | 140 | /** 141 | * 单个调谐器系统以触发全频段扫描 142 | */ 143 | public void triggerBandScan() { 144 | if (mDABInterface != null) { 145 | try { 146 | mDABInterface.triggerBandScan(); 147 | } catch (RemoteException e) { 148 | e.printStackTrace(); 149 | } 150 | } else { 151 | Logcat.d("Service not connected"); 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/system/ISystem.aidl: -------------------------------------------------------------------------------- 1 | // ISystem.aidl 2 | package com.roadrover.services.system; 3 | 4 | import com.roadrover.services.system.IGpsCallback; 5 | import com.roadrover.services.system.ISystemCallback; 6 | 7 | // 设置需要使用的aidl文件 8 | 9 | interface ISystem { 10 | 11 | /** 12 | * 设置屏幕亮度 13 | * @param id {@link com.roadrover.sdk.setting.IVISetting.ScreenBrightnessId} 14 | * @param brightness 屏幕亮度级别 15 | */ 16 | void setScreenBrightness(int id, int brightness); 17 | 18 | /** 19 | * 获取当前屏幕亮度 20 | * @param id {@link com.roadrover.sdk.setting.IVISetting.ScreenBrightnessId} 21 | */ 22 | int getScreenBrightness(int id); 23 | 24 | /** 25 | * 获取最大的屏幕亮度,最小为0 26 | */ 27 | int getMaxScreenBrightness(); 28 | 29 | /** 30 | * 获取屏幕亮度调节为白天还是黑夜 31 | */ 32 | int getCurrentBrightnessId(); 33 | 34 | /** 35 | * 注册监听设置回调 36 | * @param callback 37 | * @param packageName 当前应用的包名 38 | */ 39 | void registerSystemCallback(ISystemCallback callback, String packageName); 40 | 41 | /** 42 | * 注销监听设置回调 43 | */ 44 | void unRegisterSystemCallback(ISystemCallback callback); 45 | 46 | /** 47 | * 开始打印日志到文件 48 | */ 49 | void startPrintLogcat(String filePath); 50 | 51 | /** 52 | * 停止打印 53 | */ 54 | void stopPrintLogcat(); 55 | 56 | /** 57 | * 重启 58 | */ 59 | void reboot(); 60 | 61 | /** 62 | * 关屏 63 | */ 64 | void closeBackLight(); 65 | 66 | /** 67 | * 点亮屏幕 68 | */ 69 | void openBackLight(); 70 | 71 | /** 72 | * ACC off 情况下 双击点亮屏幕 73 | */ 74 | void openBackLightUnitOn(); 75 | 76 | /** 77 | * 屏幕是否是关闭 78 | */ 79 | boolean isOpenBackLight(); 80 | 81 | /** 82 | * 恢复出厂设置 83 | * @param isClearINand 是否清理本机 84 | */ 85 | void recoverySystem(boolean isClearINand); 86 | 87 | /** 88 | * 关闭指定App 89 | */ 90 | void closeApp(String packageName); 91 | 92 | /** 93 | * 关闭所有App 94 | */ 95 | void closeAllApp(); 96 | 97 | /** 98 | * 获取正在运行的列表,SystemUI获取 99 | * @param historyPackages 历史列表 100 | */ 101 | List getNotRunActivityPackageNames(in List historyPackages); 102 | 103 | /** 104 | * 打开记忆的app 105 | */ 106 | void openMemoryApp(); 107 | 108 | /** 109 | * 获取记忆的app包名 110 | */ 111 | String getMemoryAppPackageName(); 112 | 113 | /** 114 | * 打开导航应用,供其他应用想打开导航使用 115 | */ 116 | void openNaviApp(); 117 | 118 | /** 119 | * 重启mute动作,在上位机进行自重启时,需要进行mute动作,防止爆音 120 | */ 121 | void resetMute(); 122 | 123 | /** 124 | * 监听 gps 数据 125 | */ 126 | void registerGpsLocationInfoListener(IGpsCallback callback); 127 | 128 | /** 129 | * 注销监听 gps 数据 130 | */ 131 | void unregisterGpsLocationInfoListener(IGpsCallback callback); 132 | 133 | /** 134 | * 是否已经定位 135 | */ 136 | boolean isInPosition(); 137 | 138 | /** 139 | * 启用/禁用TP触摸 140 | */ 141 | void setTPTouch(boolean enable); 142 | 143 | /** 144 | * 打开还是关闭操作 145 | * @param isOpen {@link com.roadrover.sdk.system.IVISystem.EventTboxOpen} 146 | */ 147 | void setTboxOpen(boolean isOpen); 148 | 149 | /** 150 | * 获取T-box开关状态值 151 | */ 152 | boolean isTboxOpen(); 153 | 154 | /** 155 | * 设置屏幕保护间隔时间 156 | * @param time 时间 <= 0 取消定时 157 | */ 158 | void setScreenProtectionTime(int time); 159 | 160 | /** 161 | * 获取设置屏幕保护的间隔时间 162 | * @return 163 | */ 164 | int getScreenProtectionTime(); 165 | 166 | /** 167 | * 设置当前屏幕保护状态,当取消屏保时候需要调用该接口通知services 168 | * @param isEnterScreenProtection 是否是屏幕状态 169 | */ 170 | void setScreenProtectionStatus(boolean isEnterScreenProtection); 171 | 172 | /** 173 | * 申请屏幕操作状态 174 | * @param from 175 | */ 176 | void requestScreenOperate(int from); 177 | 178 | /** 179 | * 设置通话状态 180 | * @param status {@link IVISystem.EventTelPhone.Status} 181 | * @param phoneNumber 电话号码,没有可以不填 182 | * @param phoneName 联系人名字,没有可以不填 183 | */ 184 | void setTelPhoneStatus(int status, String phoneNumber, String phoneName); 185 | } 186 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/utils/ListUtils.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.utils; 2 | 3 | import android.support.annotation.NonNull; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | /** 11 | * 针对list的一些公共方法,列入剔除重复数据 12 | * 13 | * @author Administrator 14 | */ 15 | public class ListUtils { 16 | 17 | /** 18 | * 剔除重复数据,该方法效率较低,如果可以,尽量直接用 Set 19 | * 20 | * @param sources 21 | * @return 22 | */ 23 | public List removeDuplicateWithOrder(List sources) { 24 | List result = new ArrayList(); 25 | 26 | for (T s : sources) { 27 | if (Collections.frequency(result, s) < 1) 28 | result.add(s); 29 | } 30 | return result; 31 | } 32 | 33 | /** 34 | * 合并两个数组 35 | * 36 | * @param a 37 | * @param b 38 | * @return 39 | */ 40 | public static T[] concat(T[] a, T[] b) { 41 | if (null == a) return b; 42 | if (null == b) return a; 43 | T[] c = Arrays.copyOf(a, a.length + b.length); 44 | System.arraycopy(b, 0, c, a.length, b.length); 45 | return c; 46 | } 47 | 48 | /** 49 | * 是不是为空 50 | * 51 | * @param data 52 | * @return 53 | */ 54 | public static boolean isEmpty(List data) { 55 | if (null == data || data.size() == 0) { 56 | return true; 57 | } 58 | return false; 59 | } 60 | 61 | /** 62 | * 判断数组是否为空 63 | * 64 | * @param datas 65 | * @return 66 | */ 67 | public static boolean isEmpty(T[] datas) { 68 | if (null == datas || datas.length == 0) { 69 | return true; 70 | } 71 | return false; 72 | } 73 | 74 | /** 75 | * 判断数组是否为空 76 | * @param datas 77 | * @return 78 | */ 79 | public static boolean isEmpty(byte[] datas) { 80 | if (null == datas || datas.length == 0) { 81 | return true; 82 | } 83 | return false; 84 | } 85 | 86 | /* 87 | * ArrayList转int[] 88 | */ 89 | public static int[] listToIntArray(ArrayList list) { 90 | 91 | if (list != null) { 92 | Integer[] arryInter = new Integer[list.size()]; 93 | int[] arryint = new int[list.size()]; 94 | list.toArray(arryInter); 95 | for (int i = 0; i < arryInter.length; i++) { 96 | arryint[i] = arryInter[i].intValue(); 97 | } 98 | return arryint; 99 | } 100 | 101 | return null; 102 | } 103 | 104 | /** 105 | * 子项转换为字符串 106 | * @param item 107 | * @return 108 | */ 109 | public String toString(T item) { 110 | if (null == item) { 111 | return "null"; 112 | } else { 113 | return item.toString(); 114 | } 115 | } 116 | 117 | /** 118 | * 列表转换为字符串 119 | * @param list 120 | * @param separator 分隔符,一般传入", " 121 | * @return 122 | */ 123 | public String listToString(List list, @NonNull String separator) { 124 | String ret = ""; 125 | 126 | if (null != list) { 127 | final int size = list.size(); 128 | if (size > 0) { 129 | ret = toString(list.get(0)); 130 | for (int i = 1;i < size;i++) { 131 | ret += separator + toString(list.get(i)); 132 | } 133 | } 134 | } 135 | return ret; 136 | } 137 | 138 | /** 139 | * 比较两个列表是否完全相等 140 | * @param srcs 原始列表 141 | * @param dests 需要进行比较的列表 142 | * @return 143 | */ 144 | public static boolean equals(List srcs, List dests) { 145 | if (srcs == dests) { 146 | return true; 147 | } 148 | if (srcs != null && dests != null) { 149 | if (srcs.size() == dests.size()) { 150 | boolean isEqual = true; 151 | for (int i = 0; i < srcs.size(); ++i) { 152 | if (srcs.get(i) != dests.get(i)) { 153 | isEqual = false; 154 | break; 155 | } 156 | } 157 | return isEqual; 158 | } 159 | } 160 | return false; 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/car/HardwareVersion.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.car; 2 | 3 | /** 4 | * 设置硬件版本号类 5 | * 1. 启动后,应用自动在U盘中检索pcb_version.txt文件,并校验项目编码是否跟当前系统版本匹配,如匹配则通过CMD_HW_VER下发给MCU,并开启一个2秒的定时器 6 | * 2. MCU把版本信息写入EEPROM,并立即从EEPROM回读 7 | * 3. 若2秒内收到MCU反馈,上位机弹出提示框,显示“硬件版本信息写入成功,当前版本x.x”或“硬件版本信息写入失败,MCU存储异常” 8 | * 4.若2秒定时器超时仍未收到MCU反馈,则弹出提示框显示“硬件版本信息写入失败,MCU无响应” 9 | * 5.每次开机时,MCU从EEPROM读出版本号发送给上位机(间隔3秒发送10次),如读取不到记录则不发送 10 | * 6. 上位机根据MCU发来的版本号显示,如未收到则不显示 11 | */ 12 | 13 | import com.roadrover.sdk.utils.ByteUtil; 14 | import com.roadrover.sdk.utils.Logcat; 15 | 16 | public class HardwareVersion { 17 | private String TAG = "HardwareVersion"; 18 | 19 | public byte[] mData; 20 | public int status; // 写入硬件版本号返回状态 0x04表示MCU写入失败(可能EEPROM故障等) 0x05表示MCU写入成功 21 | public String mHardwareVersion; // 硬件版本号 22 | public String mSupplier; // PCB版本 23 | public String mEcnCode; // ECN/DCN编码 24 | public String mDate; // SMT日期 25 | public String mManufactureDate; //机器生产日期 26 | public boolean mIsHardwareWriteFeedback; // 是否收到MCU反馈 27 | 28 | public HardwareVersion(int status, String hardware, String supplier, String ecn, String date, String manufactureDate) { 29 | this.status = status; 30 | this.mHardwareVersion = hardware; 31 | this.mSupplier = supplier; 32 | this.mEcnCode = ecn; 33 | this.mDate = date; 34 | this.mManufactureDate = manufactureDate; 35 | this.mIsHardwareWriteFeedback = false; 36 | } 37 | 38 | public HardwareVersion(byte[] data) { 39 | this.mIsHardwareWriteFeedback = true; 40 | this.mData = data; 41 | parseData(mData); 42 | } 43 | 44 | /** 45 | * 根据下位机返回的数据进行解析 46 | * 1. data[0] 表示车机主控板 47 | * 2. data[1] 操作或状态 0x05表示成功 0x04表示失败 48 | * 3. data[2] PCB版本号 例如返回 3,需显示0.3 49 | * 4. data[3] PCB供应商 50 | * 5. data[4] - data[6] ECN/DCN编号 将data[4]+ data[5] +data[6]拼接一起 51 | * 6. data[7] - data[9] SMT日期 将data[7] 表示年的后两位 data[8]表示月 data[9]表示日,通过.拼接成年.月.日 52 | * 7. data[10] - data[12] 机器生产日期 将data[10] 表示年的后两位 data[11]表示月 data[12]表示日,通过.拼接成年.月.日 53 | * 8. 例如 Data = 00 05 07 0c 01 48 17 12 01 17 12 01 0d 54 | * a. 則data[1] = 0x05,表示成功 55 | * b. data[2] = 0x07, PCB版本号为7,显示0.7 56 | * c. data[3] = 0x0c, PCB供应商为12 57 | * d. 将data[4] + data[5] + data[6]拼接为: 17223 58 | * e. 将data[7] + data[8] + data[9]拼接为: 2018.1.13 59 | * f. 将data[10] + data[11] + data[12]拼接为: 2018.1.13 60 | */ 61 | private void parseData(byte[] data) { 62 | Logcat.d("data = " + ByteUtil.bytesToString(ByteUtil.subBytes(data, 0, data.length))); 63 | if (data != null && data.length > 0) { 64 | status = (int) data[1]; 65 | if (data.length > 2) { 66 | mHardwareVersion = String.format("%.1f", (data[2] / 10f));// PCB版本号(一位小数) 67 | } 68 | 69 | if (data.length > 3) { 70 | mSupplier = String.format("%02d", data[3]); 71 | } 72 | 73 | if (data.length > 6) { 74 | mEcnCode = String.format("%02d", data[4]) + String.format("%02d", data[5]) + String.format("%02d", data[6]); 75 | } 76 | 77 | if (data.length > 9) { 78 | mDate = getYear(data[7]) + getMonth(data[8]) + getDay(data[9]); 79 | } 80 | 81 | if (data.length > 12) { 82 | mManufactureDate = getYear(data[10]) + getMonth(data[11]) + getDay(data[12]); 83 | } 84 | Logcat.d(TAG, "status = " + status + " mHardwareVersion = " + mHardwareVersion 85 | + " mSupplier = " + mSupplier + " mEcnCode = " + mEcnCode + " mDate = " + mDate + " mManufactureDate = " +mManufactureDate); 86 | } 87 | } 88 | 89 | /** 90 | * 获取年 91 | * @param year 92 | * @return 93 | */ 94 | public String getYear(byte year) { 95 | return "20" + String.format("%02d", year); 96 | } 97 | 98 | /** 99 | * 获取月 100 | * @param month 101 | * @return 102 | */ 103 | public String getMonth(byte month) { 104 | return String.format("%02d", month); 105 | } 106 | 107 | /** 108 | * 获取天 109 | * @param day 110 | * @return 111 | */ 112 | public String getDay(byte day) { 113 | return String.format("%02d", day); 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/utils/TimerUtil.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.utils; 2 | 3 | import java.util.TimerTask; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.ScheduledFuture; 6 | import java.util.concurrent.ScheduledThreadPoolExecutor; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | import android.os.Handler; 10 | import android.os.Message; 11 | 12 | /** 13 | * 安卓的定时器 14 | * @使用方法 TimerUtil timer TimerUtil(callback, isNeedHandler); 15 | * isNeedHandler 该变量传false,回调函数在次线程执行,不能刷新UI 16 | * 该变量传true, 回调函数在主线程执行,可以刷新UI 17 | * start(传定时时间); 当定时结束时,需要调用 stop();尤其是Activity的销毁,必须调用stop() 18 | * 如果只是做一次的延时处理,可以使用Handler的sendMessageDelayed处理 19 | * @author bin.xie 20 | * @修改时间 2015/7/22 21 | */ 22 | 23 | public class TimerUtil { 24 | public interface TimerCallback { 25 | /** 26 | * 定时器时间到了,进行回调操作 27 | */ 28 | void timeout(); 29 | } 30 | 31 | private TimerCallback mTimerCallback = null; // 定时器时间到了的回调 32 | 33 | private final static int TIMER_MESSAGE_HANDLE = 0; // 定时器到了,发送消息 34 | private ScheduledFuture mScheduledFuture = null; 35 | private TimerTask mTimerTask = null; 36 | private Handler mHandler = null; 37 | 38 | private ScheduledThreadPoolExecutor mScheduledThreadPoolExecutor ; 39 | 40 | private boolean mIsNeedHandler = true; // 是否需要通过handler转换到主线程,如果需要直接UI操作,需要该操作位true 41 | 42 | public TimerUtil(TimerCallback callback) { 43 | this(callback, true); 44 | } 45 | 46 | public TimerUtil(TimerCallback callback, boolean isNeedHandler) { 47 | mTimerCallback = callback; 48 | 49 | mIsNeedHandler = isNeedHandler; 50 | 51 | mScheduledThreadPoolExecutor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1); 52 | 53 | if (isNeedHandler) { 54 | mHandler = new Handler() { 55 | 56 | @Override 57 | public void handleMessage(Message msg) { 58 | if (TIMER_MESSAGE_HANDLE == msg.what) { 59 | if (null != mTimerCallback) { 60 | mTimerCallback.timeout(); 61 | } 62 | } 63 | } 64 | }; 65 | } 66 | } 67 | 68 | private void initTimerTask() { 69 | mTimerTask = new TimerTask() { 70 | 71 | @Override 72 | public void run() { 73 | if (mIsNeedHandler) { 74 | // 定时器中不能刷新界面,所以发送message 75 | postHandler(); 76 | } else { 77 | // 不需要handler转换,直接调用 78 | if (null != mTimerCallback) { 79 | mTimerCallback.timeout(); 80 | } 81 | } 82 | } 83 | }; 84 | } 85 | 86 | /** 87 | * 开始定时器 88 | * @param nMesc 多长时间触发一次 89 | * 如果传小于等于0的数,仅且只会调用一次timeout() 90 | */ 91 | public void start(int nMesc) { 92 | stop(); 93 | 94 | if (0 >= nMesc) { // 时间如果为0,不开启定时器, 95 | if (null != mHandler) { // 直接post一下 96 | postHandler(); 97 | } else { 98 | if (null != mTimerCallback) { // 直接调用结果,并且只会调用一次 99 | mTimerCallback.timeout(); 100 | } 101 | } 102 | return; 103 | } 104 | 105 | initTimerTask(); 106 | 107 | mScheduledFuture = mScheduledThreadPoolExecutor.scheduleAtFixedRate(mTimerTask, nMesc, 108 | nMesc, TimeUnit.MILLISECONDS); 109 | 110 | } 111 | 112 | /** 113 | * 停止定时器 114 | */ 115 | public void stop() { 116 | try { 117 | if (null != mScheduledFuture) { 118 | mScheduledFuture.cancel(true); 119 | mScheduledFuture = null; 120 | } 121 | 122 | if (null != mTimerTask) { 123 | mTimerTask.cancel(); 124 | mTimerTask = null; 125 | } 126 | } catch (Exception e) { 127 | e.printStackTrace(); 128 | } 129 | } 130 | 131 | /** 132 | * 定时器是否为激活状态 133 | * @return 激活状态返回true 134 | */ 135 | public boolean isActive() { 136 | return (mScheduledFuture != null); 137 | } 138 | 139 | private void postHandler() { 140 | Message msg = mHandler.obtainMessage(); 141 | msg.what = TIMER_MESSAGE_HANDLE; 142 | mHandler.sendMessage(msg); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/voice/IVIVoice.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.voice; 2 | 3 | import android.os.Message; 4 | 5 | import com.roadrover.sdk.utils.LogNameUtil; 6 | 7 | /** 8 | * 语音类型定义 9 | */ 10 | 11 | public class IVIVoice { 12 | 13 | /** 14 | * 播放模式的定义,用作语音控制当前媒体的播放模式 15 | */ 16 | public static class MediaPlayMode { 17 | /** 顺序循环,值为{@value} */ 18 | public static final int LIST_MODE = 0; 19 | /** 单曲模式,值为{@value} */ 20 | public static final int SINGLE_MODE = 1; 21 | /** 随机循环模式,值为{@value} */ 22 | public static final int RAND_MODE = 2; 23 | 24 | /** 最小值,用于做判断 */ 25 | public static final int MIN = LIST_MODE; 26 | /** 最大值,用于做判断 */ 27 | public static final int MAX = RAND_MODE; 28 | 29 | /** 30 | * 通过mode id获取定义的名字 31 | * @param mode {@link MediaPlayMode} 32 | * @return 例:1 返回 "SINGLE_MODE" 33 | */ 34 | public static String getName(int mode) { 35 | return LogNameUtil.getName(mode, MediaPlayMode.class); 36 | } 37 | } 38 | 39 | /** 40 | * 语音控制媒体的 event 类 41 | */ 42 | public static class EventVoiceMedia { 43 | 44 | /** 选择媒体,值为{@value} */ 45 | public static final int SWITCH_MEDIA = 0; 46 | /** 设置播放模式,值为{@value} */ 47 | public static final int SET_PLAY_MODE = 1; 48 | /** 随机播放,值为{@value} */ 49 | public static final int PLAY_RANDOM = 2; 50 | /** 播放指定媒体,值为{@value} */ 51 | public static final int PLAY_MEDIA = 3; 52 | /** 收藏媒体,值为{@value} */ 53 | public static final int FAVOUR_MEDIA = 4; 54 | 55 | /** 当前id */ 56 | public int mId = SWITCH_MEDIA; 57 | /** 媒体控制带的参数,例:第几首歌 */ 58 | public int mArg1 = 0; 59 | /** 是否收藏带的参数 */ 60 | public boolean mIsFavour = false; 61 | /** 播放指定媒体带的参数 */ 62 | public String mMediaName, mSingerName; 63 | 64 | /** 65 | * 构造函数,使用该构造函数,只做控制,例:PLAY_RANDOM 66 | * @param id {@link EventVoiceMedia} 67 | */ 68 | public EventVoiceMedia(int id) { 69 | mId = id; 70 | } 71 | 72 | /** 73 | * 带参数的构造函数,例:SWITCH_MEDIA 选择媒体 74 | * @param id {@link EventVoiceMedia} 75 | * @param arg1 76 | */ 77 | public EventVoiceMedia(int id, int arg1) { 78 | mId = id; 79 | mArg1 = arg1; 80 | } 81 | 82 | /** 83 | * 收藏媒体的构造函数 84 | * @param id {@link EventVoiceMedia} 85 | * @param isFavour 是否收藏 86 | */ 87 | public EventVoiceMedia(int id, boolean isFavour) { 88 | mId = id; 89 | mIsFavour = isFavour; 90 | } 91 | 92 | /** 93 | * 指定媒体播放的构造函数 94 | * @param id {@link EventVoiceMedia} 95 | * @param mediaName 媒体名字 96 | * @param singerName 歌手名字 97 | */ 98 | public EventVoiceMedia(int id, String mediaName, String singerName) { 99 | mId = id; 100 | mMediaName = mediaName; 101 | mSingerName = singerName; 102 | } 103 | } 104 | 105 | /** 106 | * 语音控制收音机的Event定义类 107 | */ 108 | public static class EventVoiceRadio { 109 | /** 设置频率,值为{@value} */ 110 | public static final int SET_FREQ = 0; 111 | /** 开始扫描,值为{@value} */ 112 | public static final int START_SCAN = 1; 113 | /** 停止扫描,值为{@value} */ 114 | public static final int STOP_SCAN = 2; 115 | /** 设置am和fm,值为{@value} */ 116 | public static final int SET_BAND = 3; 117 | 118 | /** id */ 119 | public int mId = SET_FREQ; 120 | /** 传递过程中带的参数,例:频率点 */ 121 | public int mArg1 = 0; 122 | 123 | /** 124 | * 单纯控制命令的构造,例:STOP_SCAN 125 | * @param id {@link EventVoiceRadio} 126 | */ 127 | public EventVoiceRadio(int id) { 128 | mId = id; 129 | } 130 | 131 | /** 132 | * 带参数的构造函数,例:SET_BAND 133 | * @param id {@link EventVoiceRadio} 134 | * @param arg1 参数,例:频率点 135 | */ 136 | public EventVoiceRadio(int id, int arg1) { 137 | this(id); 138 | mArg1 = arg1; 139 | } 140 | } 141 | 142 | /** 143 | * 语音回调的event类 144 | */ 145 | public static class EventVoiceCallback { 146 | /** 打开语音app,值为{@value} */ 147 | public static final int OPEN_VOICE_APP = 0; 148 | 149 | public static final int CLOSE_VOICE_APP = 1; 150 | 151 | /** 定义的类型 */ 152 | public int mType; 153 | 154 | /** 155 | * 构造函数 156 | * @param type {@link EventVoiceCallback} 157 | */ 158 | public EventVoiceCallback(int type) { 159 | mType = type; 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/avin/IVITV.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.avin; 2 | 3 | import com.roadrover.sdk.utils.LogNameUtil; 4 | 5 | /** 6 | * TV定义. 7 | */ 8 | 9 | public class IVITV { 10 | 11 | /** 12 | * TV模块 13 | */ 14 | public static class Module { 15 | /** 16 | * 无, 其值 {@value} 17 | */ 18 | public static final int NONE = 0; 19 | /** 20 | * 瑞信达, 其值 {@value} 21 | */ 22 | public static final int RISHTA = 1; 23 | 24 | /** 25 | * 获取名字 26 | * @param module 模块,见{@link Module} 27 | * @return 28 | */ 29 | public static String getName(int module) { 30 | return LogNameUtil.getName(module, Module.class); 31 | } 32 | } 33 | 34 | /** 35 | * TV控制码 36 | */ 37 | public static class Control { 38 | /** 39 | * 开/关机, 其值 {@value} 40 | */ 41 | public static final int POWER = 1; 42 | /** 43 | * 切入TV, 其值 {@value} 44 | */ 45 | public static final int TV = 2; 46 | /** 47 | * 收音机, 其值 {@value} 48 | */ 49 | public static final int RADIO = 3; 50 | /** 51 | * 搜索, 其值 {@value} 52 | */ 53 | public static final int SEARCH = 4; 54 | /** 55 | * 静音, 其值 {@value} 56 | */ 57 | public static final int MUTE = 5; 58 | /** 59 | * 数字1, 其值 {@value} 60 | */ 61 | public static final int NUM1 = 6; 62 | /** 63 | * 数字2, 其值 {@value} 64 | */ 65 | public static final int NUM2 = 7; 66 | /** 67 | * 数字3, 其值 {@value} 68 | */ 69 | public static final int NUM3 = 8; 70 | /** 71 | * 数字4, 其值 {@value} 72 | */ 73 | public static final int NUM4 = 9; 74 | /** 75 | * 数字5, 其值 {@value} 76 | */ 77 | public static final int NUM5 = 10; 78 | /** 79 | * 数字6, 其值 {@value} 80 | */ 81 | public static final int NUM6 = 11; 82 | /** 83 | * 数字7, 其值 {@value} 84 | */ 85 | public static final int NUM7 = 12; 86 | /** 87 | * 数字8, 其值 {@value} 88 | */ 89 | public static final int NUM8 = 13; 90 | /** 91 | * 数字9, 其值 {@value} 92 | */ 93 | public static final int NUM9 = 14; 94 | /** 95 | * 数字0, 其值 {@value} 96 | */ 97 | public static final int NUM0 = 15; 98 | /** 99 | * 重拨, 其值 {@value} 100 | */ 101 | public static final int RECALL = 16; 102 | /** 103 | * TTX, 其值 {@value} 104 | */ 105 | public static final int TTX = 17; 106 | /** 107 | * FAV, 其值 {@value} 108 | */ 109 | public static final int FAV = 18; 110 | /** 111 | * SUB, 其值 {@value} 112 | */ 113 | public static final int SUB = 19; 114 | /** 115 | * 上一台, 其值 {@value} 116 | */ 117 | public static final int CH_ADD = 20; 118 | /** 119 | * EPG, 其值 {@value} 120 | */ 121 | public static final int EPG = 21; 122 | /** 123 | * 信息, 其值 {@value} 124 | */ 125 | public static final int INFO = 22; 126 | /** 127 | * 降低音量, 其值 {@value} 128 | */ 129 | public static final int VOL_SUB = 23; 130 | /** 131 | * 确认, 其值 {@value} 132 | */ 133 | public static final int ENTER = 24; 134 | /** 135 | * 增大音量, 其值 {@value} 136 | */ 137 | public static final int VOL_ADD = 25; 138 | /** 139 | * 音效, 其值 {@value} 140 | */ 141 | public static final int AUDIO = 26; 142 | /** 143 | * 菜单, 其值 {@value} 144 | */ 145 | public static final int MENU = 27; 146 | /** 147 | * 下一台, 其值 {@value} 148 | */ 149 | public static final int CH_SUB = 28; 150 | /** 151 | * 退出, 其值 {@value} 152 | */ 153 | public static final int EXIT = 29; 154 | /** 155 | * 红, 其值 {@value} 156 | */ 157 | public static final int RED = 30; 158 | /** 159 | * 绿, 其值 {@value} 160 | */ 161 | public static final int GREEN = 31; 162 | /** 163 | * 黄, 其值 {@value} 164 | */ 165 | public static final int YELLOW = 32; 166 | /** 167 | * 蓝, 其值 {@value} 168 | */ 169 | public static final int BLUE = 33; 170 | 171 | /** 172 | * 获取名字 173 | * @param control 控制命令,见{@link Control} 174 | * @return 175 | */ 176 | public static String getName(int control) { 177 | return LogNameUtil.getName(control, Control.class); 178 | } 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/dab/IVIDAB.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.dab; 2 | 3 | import com.roadrover.sdk.utils.LogNameUtil; 4 | 5 | /** 6 | * 数字音频广播定义. 7 | */ 8 | 9 | public class IVIDAB { 10 | 11 | /** 12 | * DAB 芯片 13 | */ 14 | public static class DABChip { 15 | public static final int NONE = 0; 16 | public static final int NXP_SAF3602 = 1; 17 | 18 | public static String getName(int chip) { 19 | switch (chip) { 20 | case NONE: return "None"; 21 | case NXP_SAF3602: return "NXP SAF3602"; 22 | default: 23 | return "Unknown chip: " + chip; 24 | } 25 | } 26 | } 27 | 28 | /** 29 | * DAB运行状态 30 | */ 31 | public static class SystemState { 32 | public static final int STOPPED = 0x0; 33 | public static final int RUNNING = 0x1; 34 | public static final int INIT_SUCCESSFUL = 0x2; 35 | public static final int DOWNLOAD_SDRAM = 0x3; 36 | public static final int DOWNLOAD_FLASH = 0x4; 37 | public static final int DOWNLOAD_SUCCESSFUL = 0x5; 38 | public static final int TUNE_IN_PROGRESS = 0x6; 39 | public static final int BACKGROUND_SCAN_STARTED = 0x7; 40 | public static final int BACKGROUND_SCAN_FINISHED = 0x8; 41 | 42 | public static String getName(int state) { 43 | switch (state) { 44 | case STOPPED: 45 | return "Stopped"; 46 | case RUNNING: 47 | return "Running"; 48 | case INIT_SUCCESSFUL: 49 | return "Init successful"; 50 | case DOWNLOAD_SDRAM: 51 | return "Download SDRam"; 52 | case DOWNLOAD_FLASH: 53 | return "Download flash"; 54 | case DOWNLOAD_SUCCESSFUL: 55 | return "Download successful"; 56 | case TUNE_IN_PROGRESS: 57 | return "Tune in progress"; 58 | case BACKGROUND_SCAN_STARTED: 59 | return "Background scan started"; 60 | case BACKGROUND_SCAN_FINISHED: 61 | return "Background scan finished"; 62 | default: 63 | return "Unknown state: " + state; 64 | } 65 | } 66 | } 67 | 68 | /** 69 | * 服务链接状态 70 | */ 71 | public static class ServiceLinkingStatus { 72 | /** friendly name: 'DAB original', ordinal=0 */ 73 | public static final int DAB_ORIGINAL = 0x0; 74 | /** friendly name: 'FM Backup', ordinal=1 */ 75 | public static final int FM_BACKUP = 0x1; 76 | /** friendly name: 'DAB alternative', ordinal=2 */ 77 | public static final int DAB_ALTERNATIVE = 0x2; 78 | 79 | public static String getName(int status) { 80 | return LogNameUtil.getName(status, ServiceLinkingStatus.class); 81 | } 82 | } 83 | 84 | /** 85 | * 服务链接模式 86 | */ 87 | public static class ServiceLinkingMode { 88 | public static final int NONE = 0x00; 89 | /** dab-fm自动无缝连接(转播) */ 90 | public static final int DABFM = 0x01; 91 | /** dab-dab自动无缝连接(可选服务)(only for dual tuner systems) */ 92 | public static final int DABDAB = 0x02; 93 | /** (only for dual tuner systems) */ 94 | public static final int DABFMDAB = 0x03; 95 | 96 | public static String getName(int mode) { 97 | return LogNameUtil.getName(mode, ServiceLinkingStatus.class); 98 | } 99 | } 100 | 101 | /** 102 | * 烧录软件来源 103 | */ 104 | public static class FirmwareDestination { 105 | public static final int SDRAM = 0; 106 | public static final int FLASH = 1; 107 | 108 | public static String getName(int destination) { 109 | return LogNameUtil.getName(destination, FirmwareDestination.class); 110 | } 111 | } 112 | 113 | /** 114 | * 软件烧录结果 115 | */ 116 | public static class DownloadFirmwareResult { 117 | public static final int SUCCESSFUL = 0; 118 | public static final int ERROR_NO_MEMORY = 1; 119 | public static final int ERROR_BOOTLOADER_NOT_FOUND = 2; 120 | public static final int ERROR_SPI_CONFIG_FAILURE = 3; 121 | public static final int ERROR_SECONDARY_BOOTLOAD_WRITE = 4; 122 | public static final int ERROR_IMAGE_WRITE = 5; 123 | public static final int ERROR_MIDDLEWARE_RUNNING = 6; 124 | public static final int ERROR_OTHER = 99; 125 | 126 | public static String getName(int result) { 127 | return LogNameUtil.getName(result, DownloadFirmwareResult.class); 128 | } 129 | } 130 | 131 | public static class EventSystemStateChanged { 132 | public int mSystemState; 133 | 134 | EventSystemStateChanged(int systemState) { 135 | mSystemState = systemState; 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/bluetooth/CmdExecResultUtil.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.bluetooth; 2 | 3 | import android.os.IInterface; 4 | import android.os.RemoteException; 5 | 6 | import com.roadrover.btservice.bluetooth.BluetoothDevice; 7 | import com.roadrover.btservice.bluetooth.BluetoothVCardBook; 8 | import com.roadrover.btservice.bluetooth.IBluetoothExecCallback; 9 | import com.roadrover.btservice.bluetooth.IBluetoothLinkDeviceCallback; 10 | import com.roadrover.btservice.bluetooth.IBluetoothStatusCallback; 11 | import com.roadrover.btservice.bluetooth.IBluetoothVCardCallback; 12 | import com.roadrover.btservice.bluetooth.IDeviceCallback; 13 | import com.roadrover.btservice.bluetooth.ISearchDeviceCallback; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * 命令执行返回工具类 19 | * 该类主要是Services回调给sdk时使用 20 | */ 21 | 22 | public class CmdExecResultUtil { 23 | 24 | /** 25 | * 执行出错,通知应用 26 | * @param callback 应用回调 27 | * @param errorCode 错误码 28 | */ 29 | public static void execError(IInterface callback, int errorCode) { 30 | if (null != callback) { 31 | try { 32 | if (callback instanceof IBluetoothExecCallback) { // 执行命令 33 | ((IBluetoothExecCallback) callback).onFailure(errorCode); 34 | } else if (callback instanceof IDeviceCallback) { // 查找设备 35 | ((IDeviceCallback) callback).onFailure(errorCode); 36 | } else if (callback instanceof IBluetoothLinkDeviceCallback) { // 连接设备 37 | ((IBluetoothLinkDeviceCallback) callback).onFailure(errorCode); 38 | } else if (callback instanceof IBluetoothVCardCallback) { // 获取蓝牙电话本 39 | ((IBluetoothVCardCallback) callback).onFailure(errorCode); 40 | } else if (callback instanceof IBluetoothStatusCallback) { // 获取蓝牙状态 41 | ((IBluetoothStatusCallback) callback).onFailure(errorCode); 42 | } else if (callback instanceof ISearchDeviceCallback) { // 搜索蓝牙设备 43 | ((ISearchDeviceCallback) callback).onFailure(errorCode); 44 | } 45 | } catch (RemoteException e) { 46 | e.printStackTrace(); 47 | } 48 | } 49 | } 50 | 51 | /** 52 | * 执行查询设备列表成功 53 | * @param callback 54 | * @param btDevices 蓝牙列表 55 | * @param curBluetoothDevices 当前连接的蓝牙设备 56 | */ 57 | public static void execSearchDeviceListSuccess(IDeviceCallback callback, List btDevices, BluetoothDevice curBluetoothDevices) { 58 | if (null != callback) { 59 | try { 60 | callback.onSuccess(btDevices, curBluetoothDevices); 61 | } catch (RemoteException e) { 62 | e.printStackTrace(); 63 | } 64 | } 65 | } 66 | 67 | /** 68 | * 执行连接设备成功 69 | * @param callback 70 | * @param status 连接设备状态 71 | * @param addr 目标地址 72 | * @param name 目标名字 73 | */ 74 | public static void execLinkeDeviceSuccess(IBluetoothLinkDeviceCallback callback, int status, String addr, String name) { 75 | if (null != callback) { 76 | try { 77 | callback.onSuccess(status, addr, name); 78 | } catch (RemoteException e) { 79 | e.printStackTrace(); 80 | } 81 | } 82 | } 83 | 84 | /** 85 | * 命令执行成功 86 | * @param callback 回调 87 | * @param msg 消息 88 | */ 89 | public static void execSuccess(IBluetoothExecCallback callback, String msg) { 90 | if (null != callback) { 91 | try { 92 | callback.onSuccess(msg); 93 | } catch (RemoteException e) { 94 | e.printStackTrace(); 95 | } 96 | } 97 | } 98 | 99 | /** 100 | * 执行命令成功 101 | * @param msg 102 | */ 103 | public static void execSuccess(IBluetoothVCardCallback callback, String msg) { 104 | if (null != callback) { 105 | try { 106 | callback.onSuccess(msg); 107 | } catch (RemoteException e) { 108 | e.printStackTrace(); 109 | } 110 | } 111 | } 112 | 113 | /** 114 | * 查询状态命令执行成功 115 | * @param callback 116 | * @param status 状态 {@link IVIBluetooth.BluetoothModuleStatus} 117 | * @param hfpStatus hf的状态 {@link IVIBluetooth.BluetoothHIDStatus} 118 | * @param avStatus a2dp的状态 {@link IVIBluetooth.BluetoothA2DPStatus} 119 | */ 120 | public static void execGetBluetoothStatusSuccess(IBluetoothStatusCallback callback, int status, int hfpStatus, int avStatus) { 121 | if (null != callback) { 122 | try { 123 | callback.onSuccess(status, hfpStatus, avStatus); 124 | } catch (RemoteException e) { 125 | e.printStackTrace(); 126 | } 127 | } 128 | } 129 | 130 | /** 131 | * 获取电话本,通话记录等信息执行进度回调 132 | * @param callback 133 | * @param books 下载进度 134 | */ 135 | public static void execGetECardProgress(IBluetoothVCardCallback callback, List books) { 136 | if (null != callback) { 137 | try { 138 | callback.onProgress(books); 139 | } catch (RemoteException e) { 140 | e.printStackTrace(); 141 | } 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/car/StudyKeyUtil.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.car; 2 | 3 | import android.text.TextUtils; 4 | import android.util.SparseArray; 5 | 6 | import com.roadrover.sdk.utils.IniFileUtil; 7 | import com.roadrover.sdk.utils.Logcat; 8 | 9 | import java.io.File; 10 | import java.util.List; 11 | import java.util.Map; 12 | import java.util.Set; 13 | 14 | /** 15 | * 方控学习键值工具类 16 | */ 17 | 18 | public class StudyKeyUtil { 19 | 20 | // 配置文件路径,方控学习的ini要支持写的操作,所以单独建一个文件 21 | private static final String INI_STUDY_FILE_PATH = "/data/rr_data/ivi-studykey.ini"; 22 | // 协议方控学习节点 23 | private static final String SECTION_STUDY_KEY = "StudyKey"; 24 | // 长按分割符 25 | private static final String LONG_KEY_SPLIT = ","; 26 | // INI文件工具类对象 27 | public static IniFileUtil mIniFileUtil = null; 28 | 29 | /** 30 | * 获取配置字段 31 | * 32 | * @return 配置字段 33 | */ 34 | public static synchronized SparseArray getStudyKeyCodes() { 35 | SparseArray keyCodes = new SparseArray<>(); 36 | if (checkRead() && mIniFileUtil != null) { 37 | IniFileUtil.Section section = mIniFileUtil.get(SECTION_STUDY_KEY); 38 | if (section != null) { 39 | Map values = section.getValues(); 40 | if (values != null) { 41 | Set keys = values.keySet(); 42 | for (String key : keys) { 43 | try { 44 | int keyCode = Integer.valueOf(key); 45 | String value = (String) values.get(key); 46 | keyCodes.append(keyCode, value); // 获取所有键值 47 | } catch (Exception e) { 48 | 49 | } 50 | } 51 | } 52 | } 53 | } 54 | return keyCodes; 55 | } 56 | 57 | /** 58 | * 获取长短按功能 59 | * 60 | * @param mixValue 61 | * @return 62 | */ 63 | public static String[] loadStringValue(String mixValue) { 64 | if (!TextUtils.isEmpty(mixValue)) { 65 | if (mixValue.contains(LONG_KEY_SPLIT)) { 66 | String[] strs = mixValue.split(LONG_KEY_SPLIT); 67 | if (strs != null) { 68 | return strs; 69 | } 70 | } 71 | return new String[]{mixValue, ""}; 72 | } 73 | return null; 74 | } 75 | 76 | /** 77 | * 获取AD通道值 78 | * 79 | * @param mixkey 80 | * @return 81 | */ 82 | public static int loadChannel(int mixkey) { 83 | if (mixkey > 0) { 84 | return (mixkey >> 16) & 0xFF; 85 | } 86 | return 0; 87 | } 88 | 89 | /** 90 | * 获取范围最大值 91 | * 92 | * @param mixkey 93 | * @return 94 | */ 95 | public static int loadMax(int mixkey) { 96 | if (mixkey > 0) { 97 | return (mixkey >> 8) & 0xFF; 98 | } 99 | return 0; 100 | } 101 | 102 | /** 103 | * 获取范围最小值 104 | * 105 | * @param mixkey 106 | * @return 107 | */ 108 | public static int loadMin(int mixkey) { 109 | if (mixkey > 0) { 110 | return mixkey & 0xFF; 111 | } 112 | return 0; 113 | } 114 | 115 | /** 116 | * 生成存储键值混合Id 117 | * 118 | * @param channel 119 | * @param max 120 | * @param min 121 | * @return 122 | */ 123 | public static String makeMixKeyId(int channel, int max, int min) { 124 | if (channel >= 0 && max >= 0 && min >= 0) { 125 | return ((channel << 16) | (max << 8) | min) + ""; 126 | } 127 | return 0+""; 128 | } 129 | 130 | /** 131 | * 生成存储键值混合值 132 | * @param shortAction 133 | * @param longAction 134 | * @return 135 | */ 136 | public static String makeMixKeyValue(String shortAction, String longAction) { 137 | if (TextUtils.isEmpty(longAction)) { 138 | return shortAction; 139 | } else { 140 | return shortAction == null ? "," + longAction : shortAction + "," + longAction; 141 | } 142 | } 143 | 144 | /** 145 | * 存储学习完的方控表到ini文件 146 | * @param list 147 | */ 148 | public static void saveListToFile(List list) { 149 | if (list == null || list.size() == 0) { 150 | return; 151 | } 152 | if (checkRead() && mIniFileUtil != null) { 153 | mIniFileUtil.remove(SECTION_STUDY_KEY); 154 | for (IVICar.StudyKeyItem item : list) { 155 | mIniFileUtil.set(SECTION_STUDY_KEY, 156 | makeMixKeyId(item.mChannel, item.mMax, item.mMin), 157 | makeMixKeyValue(item.mShortAction, item.mLongAction)); 158 | } 159 | mIniFileUtil.save(); 160 | } 161 | } 162 | 163 | /** 164 | * 检查可读 165 | */ 166 | private static boolean checkRead() { 167 | if (null == mIniFileUtil) { 168 | File file = new File(INI_STUDY_FILE_PATH); 169 | if (file.exists()) { 170 | Logcat.d("ready to read " + INI_STUDY_FILE_PATH); 171 | mIniFileUtil = new IniFileUtil(file); 172 | return true; 173 | } else { 174 | Logcat.e("failed, file " + INI_STUDY_FILE_PATH + " not exist."); 175 | return false; 176 | } 177 | } else { 178 | return true; 179 | } 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/avin/CameraUtil.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.avin; 2 | 3 | import android.content.Context; 4 | import android.hardware.Camera; 5 | import android.view.Surface; 6 | import android.view.SurfaceHolder; 7 | 8 | import java.io.IOException; 9 | 10 | /** 11 | * Camera工具类,用来适配不同平台的Camera 12 | */ 13 | 14 | public class CameraUtil { 15 | 16 | private ATCCamera mATCCamera; // ATC平台摄像头对象 17 | private Camera mCamera; // 标准的摄像头接口 18 | 19 | /** 20 | * 创建一个CameraUtil对象 21 | */ 22 | public static CameraUtil open(int cameraId, Context context) { 23 | return new CameraUtil(cameraId, context); 24 | } 25 | 26 | /** 27 | * 判断是否是ATC平台 28 | * @return 29 | */ 30 | public static boolean isATCPlatform() { 31 | return ATCCamera.detectionIsATCPlatform(); 32 | } 33 | 34 | /** 35 | * 是否是ATC摄像头被打开 36 | * @return 37 | */ 38 | public boolean isATCCamera() { 39 | return mATCCamera != null; 40 | } 41 | 42 | /** 43 | * 获取视频信号 44 | * @return 45 | */ 46 | public int getVideoSignal() { 47 | if (mATCCamera != null) { 48 | return mATCCamera.getVideoSignal(); 49 | } 50 | return IVIAVIn.Signal.UNSTABLE_SIGNAL; 51 | } 52 | 53 | private CameraUtil(int cameraId, Context context) { 54 | if (ATCCamera.detectionIsATCPlatform()) { 55 | mATCCamera = ATCCamera.open(cameraId, context); 56 | } else { 57 | mCamera = Camera.open(cameraId); 58 | } 59 | } 60 | 61 | /** 62 | * 设置视频监听回调 63 | * @param listener 64 | */ 65 | public void setAVInCallback(IVIAVIn.AVInListener listener) { 66 | if (mATCCamera != null) { // ATC平台需要通过该方法返回当前信号状态 67 | mATCCamera.setAVInCallback(listener); 68 | } 69 | } 70 | 71 | /** 72 | * 初始化摄像头参数 73 | * @param avId 设置参数id 74 | * @param brightness 亮度 75 | * @param contrast 对比度 76 | * @param saturation 饱和度 77 | */ 78 | public void initVideoParam(int avId, VideoParam brightness, VideoParam contrast, VideoParam saturation) { 79 | if (mATCCamera != null) { // atc 平台需要在UI起来之前,先刷一遍参数 80 | if (brightness != null) { 81 | mATCCamera.setParam(VideoParam.makeId(avId, VideoParam.SubId.BRIGHTNESS), 82 | brightness.mValue); 83 | } 84 | 85 | if (contrast != null) { 86 | mATCCamera.setParam(VideoParam.makeId(avId, VideoParam.SubId.CONTRAST), 87 | contrast.mValue); 88 | } 89 | 90 | if (saturation != null) { 91 | mATCCamera.setParam(VideoParam.makeId(avId, VideoParam.SubId.SATURATION), 92 | saturation.mValue); 93 | } 94 | } 95 | } 96 | 97 | /** 98 | * Returns the current settings for this Camera service.
99 | * ATC平台不需要该方法 100 | */ 101 | public Camera.Parameters getParameters() { 102 | if (mCamera != null) { 103 | return mCamera.getParameters(); 104 | } 105 | return null; 106 | } 107 | 108 | /** 109 | * Changes the settings for this Camera service.
110 | * ATC平台不需要该方法 111 | */ 112 | public void setParameters(Camera.Parameters params) { 113 | if (mCamera != null) { 114 | mCamera.setParameters(params); 115 | } 116 | } 117 | 118 | /** 119 | * 释放适配 120 | */ 121 | public final void release() { 122 | if (mATCCamera != null) { 123 | mATCCamera.release(); 124 | } else if (mCamera != null) { 125 | mCamera.release(); 126 | } 127 | } 128 | 129 | /** 130 | * Starts capturing and drawing preview frames to the screen. 131 | * Preview will not actually start until a surface is supplied 132 | */ 133 | public void startPreview() { 134 | if (mATCCamera != null) { 135 | mATCCamera.startPreview(); 136 | } else if (mCamera != null) { 137 | mCamera.startPreview(); 138 | } 139 | } 140 | 141 | /** 142 | * Stops capturing and drawing preview frames to the surface, and 143 | * resets the camera for a future call to {@link #startPreview()}. 144 | */ 145 | public final void stopPreview() { 146 | if (mATCCamera != null) { 147 | mATCCamera.stopPreview(); 148 | } else if (mCamera != null) { 149 | mCamera.stopPreview(); 150 | } 151 | } 152 | 153 | /** 154 | * Sets the {@link Surface} to be used for live preview. 155 | * Either a surface or surface texture is necessary for preview, and 156 | * preview is necessary to take pictures. The same surface can be re-set 157 | * without harm. Setting a preview surface will un-set any preview surface 158 | * texture that was set via . 159 | */ 160 | public final void setPreviewDisplay(SurfaceHolder holder) throws IOException { 161 | if (mATCCamera != null) { 162 | mATCCamera.setPreviewDisplay(holder); 163 | } else if (mCamera != null) { 164 | mCamera.setPreviewDisplay(holder); 165 | } 166 | } 167 | 168 | /** 169 | * 设置ATC摄像头视频参数 170 | * @param id 171 | * @param value 172 | */ 173 | public void setATCCameraParam(int id, int value) { 174 | if (mATCCamera != null) { 175 | mATCCamera.setParam(id, value); 176 | } 177 | } 178 | 179 | /** 180 | * 获取ATC摄像头的视频参数 181 | * @param id 182 | * @return 183 | */ 184 | public int getATCCameraParam(int id) { 185 | if (mATCCamera != null) { 186 | return mATCCamera.getParamValue(id); 187 | } 188 | return 0; 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/system/IVISystemConfig.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.system; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.roadrover.sdk.utils.IniFileUtil; 6 | import com.roadrover.sdk.utils.Logcat; 7 | 8 | import java.io.File; 9 | 10 | /** 11 | * 底层配置获取全局类 12 | */ 13 | 14 | public class IVISystemConfig { 15 | 16 | private static final String RR_SYSTEM_CONFIG_PATH = "system/etc/RR-system-config.ini"; 17 | private static final String SECTION_NAVI = "Navi"; 18 | private static final String KEY_NAVI_LOCATION = "location"; 19 | 20 | private static IniFileUtil sIniFileUtil = null; // INI文件工具类对象 21 | 22 | /** 23 | * 获取导航栏位置 24 | * 25 | * @return true代表左,false代表右 26 | */ 27 | public static boolean isNaviLocationLeft() { 28 | String location = getString(SECTION_NAVI, KEY_NAVI_LOCATION); 29 | return "left".equals(location); 30 | } 31 | 32 | /** 33 | * 获取INI解析对象 34 | * 35 | * @return INI解析对象 36 | */ 37 | public static IniFileUtil getIniFileUtil() { 38 | checkRead(); 39 | return sIniFileUtil; 40 | } 41 | 42 | /** 43 | * 获取配置文件中的 StringList 44 | * 45 | * @param section 46 | * @param name 47 | * @return 48 | */ 49 | private static String[] getStringList(String section, String name) { 50 | String tmp = getString(section, name); 51 | if (!TextUtils.isEmpty(tmp)) { 52 | return tmp.split(","); 53 | } 54 | return new String[0]; 55 | } 56 | 57 | /** 58 | * 获取配置字符串 59 | * 60 | * @param section section名称 61 | * @param key key名称 62 | * @return 配置字符串 63 | */ 64 | public static synchronized String getString(String section, String key) { 65 | String ret = null; 66 | if (checkRead() && sIniFileUtil != null) { 67 | Object object = sIniFileUtil.get(section, key); 68 | if (object instanceof String) { 69 | ret = (String) object; 70 | } else { 71 | Logcat.w("failed, " + object + " is not instanceof String."); 72 | } 73 | } 74 | 75 | return ret; 76 | } 77 | 78 | /** 79 | * 获取配置的字符串 80 | * 81 | * @param section 82 | * @param key 83 | * @param defValue 默认值 84 | * @return 85 | */ 86 | public static String getString(String section, String key, String defValue) { 87 | String ret = getString(section, key); 88 | if (TextUtils.isEmpty(ret)) { 89 | ret = defValue; 90 | } 91 | return ret; 92 | } 93 | 94 | /** 95 | * 获取整型 96 | * 97 | * @param section section名称 98 | * @param key key名称 99 | * @return 整型值 100 | */ 101 | public static Integer getInteger(String section, String key) { 102 | Integer ret = null; 103 | try { 104 | ret = Integer.valueOf(getString(section, key)); 105 | } catch (Exception e) { 106 | Logcat.w("failed, " + section + " " + key); 107 | } 108 | return ret; 109 | } 110 | 111 | /** 112 | * 获取浮点值 113 | * 114 | * @param section section名称 115 | * @param key key名称 116 | * @return 浮点值 117 | */ 118 | private static Float getFloat(String section, String key) { 119 | Float ret = null; 120 | try { 121 | ret = Float.valueOf(getString(section, key)); 122 | } catch (Exception e) { 123 | Logcat.w("failed, " + section + " " + key); 124 | } 125 | return ret; 126 | } 127 | 128 | /** 129 | * 获取整型 130 | * 131 | * @param section section名称 132 | * @param key key名称 133 | * @param defaultValue 默认值 134 | * @return 整型值 135 | */ 136 | public static int getInteger(String section, String key, int defaultValue) { 137 | Integer ret = getInteger(section, key); 138 | if (ret != null) { 139 | return ret; 140 | } else { 141 | return defaultValue; 142 | } 143 | } 144 | 145 | /** 146 | * 获取浮动数 147 | * 148 | * @param section section名称 149 | * @param key key名称 150 | * @param defaultValue 默认值 151 | * @return 整型值 152 | */ 153 | public static float getFloat(String section, String key, float defaultValue) { 154 | Float ret = getFloat(section, key); 155 | if (ret != null) { 156 | return ret; 157 | } else { 158 | return defaultValue; 159 | } 160 | } 161 | 162 | /** 163 | * 获取布尔型 164 | * 165 | * @param section section名称 166 | * @param key key名称 167 | * @param defaultValue 默认值 168 | * @return 整型值 169 | */ 170 | public static synchronized boolean getBoolean(String section, String key, boolean defaultValue) { 171 | boolean ret = defaultValue; 172 | final String string = getString(section, key); 173 | if ("true".equals(string)) { 174 | ret = true; 175 | } else if ("false".equals(string)) { 176 | ret = false; 177 | } else { 178 | Logcat.w("failed, " + section + " " + key + " " + defaultValue); 179 | } 180 | return ret; 181 | } 182 | 183 | /** 184 | * 检查可读 185 | */ 186 | private static boolean checkRead() { 187 | if (null == sIniFileUtil) { 188 | File file = new File(RR_SYSTEM_CONFIG_PATH); 189 | if (file.exists()) { 190 | Logcat.d("ready to read " + RR_SYSTEM_CONFIG_PATH); 191 | sIniFileUtil = new IniFileUtil(file); 192 | return true; 193 | } else { 194 | Logcat.e("failed, file " + RR_SYSTEM_CONFIG_PATH + " not exist."); 195 | return false; 196 | } 197 | } else { 198 | return true; 199 | } 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/avin/ATCCameraVideoSetting.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.avin; 2 | 3 | import com.roadrover.sdk.utils.FieldUtil; 4 | import com.roadrover.sdk.utils.Logcat; 5 | 6 | /** 7 | * atc 摄像头视频参数调节 8 | */ 9 | 10 | public class ATCCameraVideoSetting { 11 | 12 | /** AtcVcpSettings 类名 */ 13 | private static final String ATC_VCP_SETTINGS_CLASS_NAME = "com.autochips.settings.AtcVcpSettings"; 14 | /** 亮度,对比度,饱和度调节的对象类名 */ 15 | private static final String CONTR_BRIT_SATR_CLASS_NAME = ATC_VCP_SETTINGS_CLASS_NAME + "$ContrBritSatr"; 16 | /** SrcType类名 */ 17 | private static final String SRC_TYPE_CLASS_NAME = ATC_VCP_SETTINGS_CLASS_NAME + "$SrcType"; 18 | 19 | /** 亮度,对比度,饱和度,调节对象 */ 20 | private Object mContrastBrightnessSaturation; 21 | 22 | public ATCCameraVideoSetting() { 23 | mContrastBrightnessSaturation = FieldUtil.createObject(ATC_VCP_SETTINGS_CLASS_NAME, CONTR_BRIT_SATR_CLASS_NAME); 24 | } 25 | 26 | /** 27 | * 设置视频参数 28 | * @param cameraIndex 摄像头index 29 | * @param id {@link VideoParam#makeId(int, int)} 获得 30 | * @param value 参数值 31 | */ 32 | public void setParam(int cameraIndex, int id, int value) { 33 | int srcType = videoIdToSrcType(cameraIndex); 34 | Logcat.d("srcType:" + srcType); 35 | 36 | int subId = VideoParam.getSubId(id); 37 | switch (subId) { 38 | case VideoParam.SubId.BRIGHTNESS: 39 | setBrightnessLevel(srcType, value); 40 | break; 41 | 42 | case VideoParam.SubId.CONTRAST: 43 | setContrastLevel(srcType, value); 44 | break; 45 | 46 | case VideoParam.SubId.SATURATION: 47 | setSaturationLevel(srcType, value); 48 | break; 49 | 50 | default: 51 | Logcat.d("subId:" + VideoParam.SubId.getName(subId) + " is invalid!"); 52 | break; 53 | } 54 | } 55 | 56 | /** 57 | * 获取视频参数的值 58 | * @param cameraIndex 摄像头index 59 | * @param id {@link VideoParam#makeId(int, int)} 获得 60 | * @return 61 | */ 62 | public int getParamValue(int cameraIndex, int id) { 63 | int srcType = videoIdToSrcType(cameraIndex); 64 | Logcat.d("srcType:" + srcType); 65 | 66 | int subId = VideoParam.getSubId(id); 67 | switch (subId) { 68 | case VideoParam.SubId.BRIGHTNESS: 69 | return getBrightnessLevel(srcType); 70 | 71 | case VideoParam.SubId.CONTRAST: 72 | return getContrastLevel(srcType); 73 | 74 | case VideoParam.SubId.SATURATION: 75 | return getSaturationLevel(srcType); 76 | 77 | default: 78 | Logcat.d("subId:" + VideoParam.SubId.getName(subId) + " is invalid!"); 79 | break; 80 | } 81 | return -1; 82 | } 83 | 84 | /** 85 | * 设置亮度 86 | * @param brightness 87 | */ 88 | private void setBrightnessLevel(int srcType, int brightness) { 89 | Object contrBritSatr = getContrBritSatr(srcType); 90 | FieldUtil.setFieldValue(contrBritSatr, "i4Brit", brightness); 91 | FieldUtil.invoke(ATC_VCP_SETTINGS_CLASS_NAME, "SetVcpContrBritSatrLevel", contrBritSatr); 92 | 93 | Logcat.d("brightness:" + brightness + " " + getBrightnessLevel(srcType)); 94 | } 95 | 96 | /** 97 | * 获取当前实际亮度 98 | * @param srcType 源类型 99 | * @return 100 | */ 101 | private int getBrightnessLevel(int srcType) { 102 | return FieldUtil.getFieldIntValue(CONTR_BRIT_SATR_CLASS_NAME, getContrBritSatr(srcType), "i4Brit"); 103 | } 104 | 105 | /** 106 | * 设置对比度 107 | * @param srcType 设置的源类型 108 | * @param contrast 109 | */ 110 | private void setContrastLevel(int srcType, int contrast) { 111 | Object contrBritSatr = getContrBritSatr(srcType); 112 | FieldUtil.setFieldValue(contrBritSatr, "i4Contr", contrast); 113 | FieldUtil.invoke(ATC_VCP_SETTINGS_CLASS_NAME, "SetVcpContrBritSatrLevel", contrBritSatr); 114 | Logcat.d("contrast:" + contrast + " " + getContrastLevel(srcType)); 115 | } 116 | 117 | /** 118 | * 获取当前的实际对比度 119 | * @return 120 | */ 121 | private int getContrastLevel(int srcType) { 122 | return FieldUtil.getFieldIntValue(CONTR_BRIT_SATR_CLASS_NAME, getContrBritSatr(srcType), "i4Contr"); 123 | } 124 | 125 | /** 126 | * 设置饱和度 127 | * @param srcType 设置的视频源 128 | * @param saturation 饱和度 129 | */ 130 | private void setSaturationLevel(int srcType, int saturation) { 131 | Object contrBritSatr = getContrBritSatr(srcType); 132 | FieldUtil.setFieldValue(contrBritSatr, "i4Satr", saturation); 133 | FieldUtil.invoke(ATC_VCP_SETTINGS_CLASS_NAME, "SetVcpContrBritSatrLevel", contrBritSatr); 134 | Logcat.d("saturation:" + saturation + " " + getSaturationLevel(srcType)); 135 | } 136 | 137 | /** 138 | * 获取当前的实际饱和度 139 | * @param srcType 源类型 140 | * @return 141 | */ 142 | private int getSaturationLevel(int srcType) { 143 | return FieldUtil.getFieldIntValue(CONTR_BRIT_SATR_CLASS_NAME, getContrBritSatr(srcType), "i4Satr"); 144 | } 145 | 146 | /** 147 | * 获取当前的对比度,亮度 148 | * @return 149 | */ 150 | private Object getContrBritSatr(int srcType) { 151 | FieldUtil.setFieldValue(CONTR_BRIT_SATR_CLASS_NAME, mContrastBrightnessSaturation, "srctype", srcType); 152 | FieldUtil.invoke(ATC_VCP_SETTINGS_CLASS_NAME, "GetVcpContrBritSatrLevel", mContrastBrightnessSaturation); 153 | return mContrastBrightnessSaturation; 154 | } 155 | 156 | /** 157 | * 将视频id转换成 srcType 158 | * @param cameraIndex 摄像头index 159 | * @return 160 | */ 161 | private int videoIdToSrcType(int cameraIndex) { 162 | return FieldUtil.getFieldIntValue(SRC_TYPE_CLASS_NAME, null, "AVIN_" + cameraIndex); 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/radio/RadioModel.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.radio; 2 | 3 | import android.content.ContentProviderClient; 4 | import android.content.Context; 5 | import android.database.ContentObserver; 6 | import android.database.Cursor; 7 | import android.database.SQLException; 8 | import android.net.Uri; 9 | import android.os.Handler; 10 | 11 | import com.roadrover.sdk.utils.Logcat; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | /** 17 | * 收音机数据. 18 | */ 19 | 20 | public class RadioModel { 21 | 22 | public static class Station { 23 | public String mName; // 名字 24 | public int mFreq; // 频率 25 | public int mKind; // 频率 26 | public int mBand; // 波段,取值见{@link IVIRadio#Band} 27 | public int mPosition;// 28 | public int mIsLove; 29 | public String mDesp;// 30 | 31 | @Override 32 | public String toString() { 33 | return "mName = " + mName + ", mFreq = " + mFreq + 34 | ", mKind = " + mKind + ", mBand = " + mBand + 35 | ", mPosition = " + mPosition + ", mIsLove = " + mIsLove + 36 | ", mDesp = " + mDesp; 37 | } 38 | } 39 | 40 | /** 41 | * 获取收音机站台频率列表,该方法时直接获取收音机数据库的数据 42 | * 43 | * @param context 44 | * @return 45 | */ 46 | public static List getStationList(Context context) { 47 | List stations = new ArrayList<>(); 48 | if (context != null && checkValidProvider(Provider.TableColumns.CONTENT_URI, context)) { 49 | Cursor cursor = null; 50 | try { 51 | cursor = context.getContentResolver().query(Provider.TableColumns.CONTENT_URI, 52 | new String[]{Provider.TableColumns.KEY_ID 53 | , Provider.TableColumns.KEY_NAME, Provider.TableColumns.KEY_FREQ 54 | , Provider.TableColumns.KEY_DESP, Provider.TableColumns.KEY_BAND 55 | , Provider.TableColumns.KEY_KIND, Provider.TableColumns.KEY_POSITION 56 | , Provider.TableColumns.KEY_ISLOVE}, 57 | null, null, null); 58 | if (cursor != null && cursor.moveToFirst()) { 59 | do { // 获取收音机站台频率数据 60 | RadioModel.Station station = new RadioModel.Station(); 61 | station.mName = cursor.getString(cursor.getColumnIndex(Provider.TableColumns.KEY_NAME)); 62 | station.mFreq = cursor.getInt(cursor.getColumnIndex(Provider.TableColumns.KEY_FREQ)); 63 | station.mDesp = cursor.getString(cursor.getColumnIndex(Provider.TableColumns.KEY_DESP)); 64 | station.mBand = cursor.getInt(cursor.getColumnIndex(Provider.TableColumns.KEY_BAND)); 65 | station.mKind = cursor.getInt(cursor.getColumnIndex(Provider.TableColumns.KEY_KIND)); 66 | station.mPosition = cursor.getInt(cursor.getColumnIndex(Provider.TableColumns.KEY_POSITION)); 67 | station.mIsLove = cursor.getInt(cursor.getColumnIndex(Provider.TableColumns.KEY_ISLOVE)); 68 | stations.add(station); 69 | Logcat.d("station = " + station.toString()); 70 | } while (cursor.moveToNext()); 71 | } 72 | } catch (SQLException e) { 73 | e.printStackTrace(); 74 | } finally { 75 | if (cursor != null) { 76 | cursor.close(); 77 | cursor = null; 78 | } 79 | } 80 | } 81 | return stations; 82 | } 83 | 84 | public interface ModelListener { 85 | void onChange(List stations); 86 | } 87 | 88 | private static ContentObserver mContentObserver = null; 89 | 90 | /** 91 | * 监听收音站台频率的接口,语音等应用需要知道收音站台频率发生改变 92 | * 93 | * @param context 94 | * @param listener 95 | */ 96 | public static void registerStationListener(final Context context, final ModelListener listener) { 97 | if (context != null && listener != null) { 98 | if (mContentObserver != null) { 99 | return; 100 | } 101 | mContentObserver = new ContentObserver(new Handler()) { 102 | @Override 103 | public void onChange(boolean selfChange) { 104 | Logcat.d("selfChange:" + selfChange); 105 | if (!selfChange) { 106 | if (listener != null) { 107 | listener.onChange(getStationList(context)); 108 | } 109 | } 110 | } 111 | }; 112 | context.getContentResolver().registerContentObserver(Provider.TableColumns.CONTENT_URI, false, mContentObserver); 113 | } 114 | } 115 | 116 | /** 117 | * 不再监听收音站台频率的改变消息 118 | * 119 | * @param context 120 | */ 121 | public static void unregisterStationListener(Context context) { 122 | if (context != null && mContentObserver != null) { 123 | context.getContentResolver().unregisterContentObserver(mContentObserver); 124 | mContentObserver = null; 125 | } 126 | } 127 | 128 | /** 129 | * 检测这个contentprovider是否合法 130 | * 131 | * @param uri 132 | * @return 合法返回true, 否则返回false 133 | */ 134 | private static boolean checkValidProvider(Uri uri, Context context) { 135 | if (null == context) { 136 | return false; 137 | } 138 | ContentProviderClient client = context.getContentResolver().acquireContentProviderClient(uri); 139 | if (null == client) { 140 | return false; 141 | } else { 142 | client.release(); 143 | return true; 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/car/ICarCallback.aidl: -------------------------------------------------------------------------------- 1 | // ICarCallback.aidl 2 | package com.roadrover.services.car; 3 | 4 | interface ICarCallback { 5 | /** 6 | * 下位机版本号 7 | * @param version 版本号 8 | */ 9 | void onMcuVersion(String version); 10 | /** 11 | * ACC状态发生变化 12 | * @param on true表示上了ACC,false表示无ACC 13 | */ 14 | void onAccChanged(boolean on); 15 | /** 16 | * 倒车状态发生变化 17 | * @param on true表示处于倒车状态,false表示不在倒车状态 18 | */ 19 | void onCcdChanged(int status); 20 | /** 21 | * 刹车状态发生变化 22 | * @param hold IVICar.Handbrake 23 | */ 24 | void onHandbrakeChanged(boolean hold); 25 | /** 26 | * 车门状态发生变化 27 | * @param changeMask 变化掩码 28 | * @param statusMask 状态掩码 29 | */ 30 | void onDoorChanged(int changeMask, int statusMask); 31 | /** 32 | * 车灯状态发生变化 33 | * @param changeMask 变化掩码 34 | * @param statusMask 状态掩码 35 | */ 36 | void onLightChanged(int changeMask, int statusMask); 37 | /** 38 | * 大灯状态发生变化 39 | * @param on true表示大灯打开,false表示大灯关闭 40 | */ 41 | void onHeadLightChanged(boolean on); 42 | /** 43 | * 空调状态发生变化 44 | * @param id Climate.java 45 | * @param rawValue 空调的数值 46 | */ 47 | void onClimateChanged(int id, int rawValue); 48 | /** 49 | * 外部温度发生变化 50 | * @param rawValue 外部温度 51 | */ 52 | void onOutsideTempChanged(int rawValue); 53 | /** 54 | * 按键被按下 55 | * @param id IVICar.Key.Id 56 | * @param type IVICar.Key.Type 57 | */ 58 | void onKeyPushed(int id, int type); 59 | /** 60 | * 来了车辆故障和警告信息 61 | * @param messageCode 消息值 62 | */ 63 | void onAlertMessage(int messageCode); 64 | /** 65 | * 油耗发生变化 66 | * @param id Trip.Id 67 | * @param index Trip.Index 68 | * @param value 油耗值 69 | */ 70 | void onTripChanged(int id, int index, float value); 71 | /** 72 | * 瞬时信息发生变化 73 | * @param id IVICar.RealTimeInfo 74 | * @param value 瞬时信息的值 75 | */ 76 | void onRealTimeInfoChanged(int id, float value); 77 | /** 78 | * 原车其它参数发生变化 79 | * @param id IVICar.ExtraState 80 | * @param value 其它参数的数值 81 | */ 82 | void onExtraStateChanged(int id, float value); 83 | /** 84 | * 原车雷达数据发生变化 85 | * @param radarType IVICar.Radar.Type 86 | * @param radarData 雷达数据的值 87 | */ 88 | void onRadarChanged(int radarType, in byte[] radarData); 89 | /** 90 | * 原车设置信息发生变化 91 | * @param carId 汽车Id 92 | * @param settingData 设置数据的值 93 | */ 94 | void onCarSettingChanged(int carId, in byte[] settingData); 95 | /** 96 | * 原车外部设备数据发生变化 97 | * @param carId IVICar.ExtraDevice.CarId 98 | * @param deviceId IVICar.ExtraDevice.DeviceId 99 | * @param extraDeviceData 原车外部设备数据 100 | */ 101 | void onExtraDeviceChanged(int carId, int deviceId, in byte[] extraDeviceData); 102 | /** 103 | * 原车配置参数发生变化 104 | * @param id IVICar.CmdParam.Id 105 | * @param paramData 配置参数的值 106 | */ 107 | void onCmdParamChanged(int id, in byte[] paramData); 108 | /** 109 | * 原车保养信息发生变化 110 | * @param id IVICar.Maintenance.Id 111 | * @param mileage 里程数值 112 | * @param days 天数 113 | */ 114 | void onMaintenanceChanged(int id, int mileage, int days); 115 | /** 116 | * 车辆识别码发生变化 117 | * @param VIN 车辆识别码VIN(VIN码由17位字符组成) 118 | * @param keyNumber 匹配钥匙数目 119 | */ 120 | void onCarVINChanged(String VIN, int keyNumber); 121 | /** 122 | * 原车故障码发生变化 123 | * @param carid IVICar.CarReport.Car 124 | * @param type IVICar.CarReport.Type 125 | * @param list 故障码数据 126 | */ 127 | void onCarReportChanged(int carid, int type, in int[] list); 128 | /** 129 | * 自动泊车发生变化 130 | * @param status 自动泊车系统状态 131 | */ 132 | void onAutoParkChanged(int status); 133 | /** 134 | * 原车故障码发生变化 135 | * @param battery 电池电量,最大值由具体的车型确定 136 | * @param engineToTyre 发动机(A)和驱动轮(B)流向 137 | * @param engineToMotor 发动机(A)和马达(B)流向 138 | * @param motorToTyre 马达(A)和驱动轮(B)流向 139 | * @param motorToBattery 马达(A)和电池(B)的流向 140 | */ 141 | void onEnergyFlowChanged(int battery, int engineToTyre, int engineToMotor, int motorToTyre, int motorToBattery); 142 | /** 143 | * 快速倒车状态发生变化 144 | * @param on true为快速倒车状态,false为正常倒车状态 145 | */ 146 | void onFastReverseChanged(boolean on); 147 | /** 148 | * AD按键发生变化 149 | * @param channel AD通道 150 | * @param value 按键AD值 151 | */ 152 | void onADKeyChanged(int channel, int value); 153 | /** 154 | * 从仪表发送数据到APP 155 | * @param datas 仪表发送过来的数据 156 | */ 157 | void onClusterMessage(in byte[] datas); 158 | 159 | /** 160 | * 胎压状态发生变化 161 | * @param id ID 定义 见{@link com.roadrover.sdk.car.TirePressure} 162 | * @param rawValue 数据 见{@link com.roadrover.sdk.car.TirePressure} 163 | * @param extraValue 附加状态数据 见{@link com.roadrover.sdk.car.TirePressure} 164 | * @param dotType 温度小数点标志 见{@link com.roadrover.sdk.car.TirePressure} 165 | */ 166 | void onTirePressureChanged(int id, int rawValue, int extraValue, int dotType); 167 | 168 | /** 169 | * @param status 写入硬件版本号返回状态 见{@link com.roadrover.sdk.car.HardwareVersion} 170 | * @param hardware 硬件版本号 见{@link com.roadrover.sdk.car.HardwareVersion} 171 | * @param supplier PCB版本 见{@link com.roadrover.sdk.car.HardwareVersion} 172 | * @param ecn ECN/DCN编码 见{@link com.roadrover.sdk.car.HardwareVersion} 173 | * @param date SMT日期 见{@link com.roadrover.sdk.car.HardwareVersion} 174 | * @param manufactureDate 机器生产日期 见{@link com.roadrover.sdk.car.HardwareVersion} 175 | */ 176 | void onEventHardwareVersion(int status, String hardware, String supplier, String ecn, String date, String manufactureDate); 177 | 178 | /** 179 | * 保养提示 180 | */ 181 | void onMaintainWarning(boolean show); 182 | 183 | } 184 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/media/IMedia.aidl: -------------------------------------------------------------------------------- 1 | // IMedia.aidl 2 | package com.roadrover.services.media; 3 | 4 | import com.roadrover.services.media.IGetMediaListCallback; 5 | import com.roadrover.services.media.IMediaControlCallback; 6 | import com.roadrover.services.media.IMediaInfoCallback; 7 | import com.roadrover.services.media.IMediaScannerCallback; 8 | import com.roadrover.services.media.IMusicControlCallback; 9 | 10 | interface IMedia { 11 | 12 | /** 13 | * 打开媒体 14 | * @param type 媒体类型 15 | * @param callback 回调接口 16 | */ 17 | void open(int mediaType, IMediaControlCallback callback, String packageName); 18 | 19 | /** 20 | * 关闭媒体 21 | * @param type 对应 IVIMedia.Type中的类型 22 | */ 23 | void close(int mediaType); 24 | 25 | /** 26 | * 注册媒体扫描的回调 27 | * @param callback 媒体扫描回调接口对象 28 | */ 29 | void registerScannerCallback(IMediaScannerCallback callback); 30 | 31 | /** 32 | * 注销媒体扫描回调 33 | * @param callback 媒体扫描回调接口对象 34 | */ 35 | void unRegisterScannerCallback(IMediaScannerCallback callback); 36 | 37 | /** 38 | * 注册媒体数据监听的回调,主要在小屏或者主界面等希望获取到当前多媒体数据的应用使用 39 | * @param callback 媒体数据回调 40 | */ 41 | void registerMediaInfoCallback(IMediaInfoCallback callback); 42 | 43 | /** 44 | * 注销媒体数据 45 | */ 46 | void unRegisterMediaInfoCallback(IMediaInfoCallback callback); 47 | 48 | /** 49 | * 得到当前播放的媒体 50 | * @return IVIMedia.Type中的类型 51 | */ 52 | int getActiveMedia(); 53 | 54 | /** 55 | * 播放音频,视频 56 | * @param mediaType 媒体类型 57 | * @param name 播放名字信息 58 | * @param info 播放的信息,一般为歌手等 59 | * @param artWidth 图片(比如专辑封面)的宽度,单位像素 60 | * @param artHeight 图片的高度,单位像素 61 | * @param artPixels 图片的bytes,比如专辑封面 62 | * @param index 当前是第几首 63 | * @param totalCount 当前歌曲总数 64 | * @param popup 是否弹出小窗口显示媒体信息,一般上下曲的时候为true,其他为false 65 | */ 66 | void setMediaInfo(int mediaType, String name, String info, int artWidth, int artHeight, in byte[] artPixels, int index, int totalCount, boolean popup); 67 | 68 | /** 69 | * 设置当前进度 70 | * @param playState 播放状态,参考IVIMedia.MediaState里面的定义 71 | * @param position 当前进度s 72 | * @param duration 总时间s 73 | */ 74 | void setMediaState(int mediaType, int playState, int position, int duration); 75 | 76 | /** 77 | * 获取该目录下的所有媒体列表,包含子目录 78 | * @param path 该目录,以及子目录的媒体数据 79 | */ 80 | void getAllMediaList(String type, String startWidtPath, IGetMediaListCallback callback); 81 | 82 | /** 83 | * 获取指定目录的媒体信息,不会获取子目录的媒体 84 | */ 85 | void getAppointPathMediaList(String type, String path, IGetMediaListCallback callback); 86 | 87 | /** 88 | * 是否允许播放视频 89 | */ 90 | boolean isVideoPermit(); 91 | 92 | /** 93 | * 反注册MediaControlCallback,断开连接的时候调用 94 | */ 95 | void unRegisterMediaControlCallback(IMediaControlCallback callback); 96 | 97 | /** 98 | * 是否允许播放媒体,在倒车、蓝牙等状态下不能恢复播放媒体 99 | */ 100 | boolean canPlayMedia(); 101 | 102 | /** 103 | * 控制当前媒体:播放 104 | */ 105 | void play(); 106 | 107 | /** 108 | * 控制当前媒体:暂停 109 | */ 110 | void pause(); 111 | 112 | /** 113 | * 控制当前媒体:播放和暂停的循环 114 | */ 115 | void playPause(); 116 | 117 | /** 118 | * 控制当前媒体:上一曲 119 | */ 120 | void prev(); 121 | 122 | /** 123 | * 控制当前媒体:下一曲 124 | */ 125 | void next(); 126 | 127 | /** 128 | * 拖动当前音乐的进度 129 | * param msec 单位毫秒 130 | */ 131 | void seekTo(int msec); 132 | 133 | /** 134 | * 打开媒体UI(APK) 135 | */ 136 | void launchApp(int mediaType); 137 | 138 | /** 139 | * 请求service发送当前媒体信息和播放状态消息 140 | */ 141 | void requestMediaInfoAndStateEvent(); 142 | 143 | /** 144 | * 打开媒体,双区媒体专用 145 | * @param mediaType 媒体类型 146 | * @param callback 回调接口 147 | * @param index 媒体索引号,双区系统从0开始,支持0到1 148 | * @param zone IVIMedia.Zone 149 | * @param stream Android的Stream,比如STREAM_MUSIC 150 | */ 151 | void openMediaInZone(int mediaType, IMediaControlCallback callback, String packageName, int zone); 152 | 153 | /** 154 | * 得到双区媒体某个区域的媒体 155 | * @param zone IVIMedia.Zone,只支持MASTER和SECONDARY 156 | * @return IVIMedia.Type中的类型 157 | */ 158 | int getMediaFromZone(int zone); 159 | 160 | /** 161 | * 设置媒体输出区 162 | * @param mediaType IVIMedia.Type 163 | * @param zone IVIMedia.Zone 164 | */ 165 | void setMediaZone(int mediaType, int zone); 166 | 167 | /** 168 | * 得到媒体的输出区 169 | * @param mediaType IVIMedia.Type 170 | * @return IVIMedia.Zone 171 | */ 172 | int getMediaZone(int mediaType); 173 | 174 | /** 175 | * 选择某个媒体输出区是Enable还是Disable,必须在open mediaType之后才起作用 176 | * @param mediaType IVIMedia.Type, 只支持MASTER和SECONDARY, 177 | * @param targetZone IVIMedia.Zone 目的Zone 178 | * @param enable true 打开,false 关闭 179 | */ 180 | void switchMediaZone(int mediaType, int targetZone, boolean enable); 181 | 182 | /** 183 | * 判断某个媒体是否被打开 184 | * @param mediaType IVIMedia.Type 185 | * @return true 被打开 186 | */ 187 | boolean isOpened(int mediaType); 188 | 189 | /** 190 | * 删除文件
191 | * 部分平台刚刚插入U盘时,删除文件,通过MultiFileObserver没办法监听到,所以增加接口,在删除文件时通知services
192 | * 目前IMX6存在该问题,T3不存在
193 | * @param path 文件路径 194 | */ 195 | void sendDeleteFileEvent(String path); 196 | 197 | /** 198 | * 文件写入完成
199 | * 部分平台刚刚插入U盘时,拷贝文件,通过MultiFileObserver没办法监听到,所以增加接口,在拷贝文件,写入文件时候通知Services
200 | * @param path 文件路径 201 | */ 202 | void sendWriteFinishedEvent(String path); 203 | 204 | /** 205 | * 注册语音控制音乐的回调接口
206 | * 与 IMediaCtonrlCallback 区别在于,该接口注册后,及时当前不在音频焦点状态,也可以获取到回调信息
207 | */ 208 | void registerMusicControlCallback(IMusicControlCallback callback); 209 | 210 | /** 211 | * 注销语音控制音乐的回调接口 212 | */ 213 | void unregisterMusicControlCallback(IMusicControlCallback callback); 214 | 215 | /** 216 | * 设置当前用于显示的媒体类型信息 217 | * 用于设置当前不能作为媒体源的媒体类型信息供三方使用,如图库等。 218 | */ 219 | void setCurrentShownMediaType(int meidaType); 220 | } 221 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/navigation/NavigationManager.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.navigation; 2 | 3 | import android.content.Context; 4 | import android.os.IBinder; 5 | import android.os.IInterface; 6 | import android.os.RemoteException; 7 | 8 | import com.roadrover.sdk.BaseManager; 9 | import com.roadrover.sdk.utils.Logcat; 10 | import com.roadrover.services.navigation.INavigation; 11 | import com.roadrover.services.navigation.INavigationCallback; 12 | 13 | import org.greenrobot.eventbus.EventBus; 14 | import org.greenrobot.eventbus.Subscribe; 15 | import org.greenrobot.eventbus.ThreadMode; 16 | 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | 20 | /** 21 | * 导航的管理类 22 | */ 23 | public class NavigationManager extends BaseManager { 24 | 25 | private INavigation mNavigationInterface = null; // 导航接口类 26 | 27 | private NavigationListener mNavigationListener; 28 | 29 | public interface NavigationListener { 30 | 31 | /** 32 | * 导航过程中发送引导类型,和引导属性 33 | */ 34 | void onNavigationType(int twelveClock, int turnID, int []arrayTurn,int guideType, int distance, 35 | int destDistance,int destTime, String roadName, String nextRoadName,String destName); 36 | 37 | /** 38 | * 发自车行政区变更时,发送该消息,例:广东省深圳市南山区 39 | */ 40 | void onNavigationAddress(String province, String city, String county); 41 | 42 | /** 43 | * 设置指南针的指向 44 | */ 45 | void onNavigationGuide(int direction); 46 | 47 | /** 48 | * 设置电子眼的信息 49 | */ 50 | void onNavigationEyeInfo(int type, int distance, int speedLimit); 51 | } 52 | 53 | 54 | public NavigationManager(Context context, ConnectListener listener, NavigationListener navigationListener) { 55 | super(context, listener, true); 56 | mNavigationListener = navigationListener; 57 | } 58 | 59 | @Override 60 | public void disconnect() { 61 | mINavigationCallback = null; 62 | mNavigationInterface = null; 63 | mNavigationListener = null; 64 | super.disconnect(); 65 | } 66 | 67 | @Override 68 | protected String getServiceActionName() { 69 | return ServiceAction.NAVIGATION_ACTION; 70 | } 71 | 72 | @Override 73 | protected void onServiceConnected(IBinder service) { 74 | mNavigationInterface = INavigation.Stub.asInterface(service); 75 | 76 | // 如果服务挂了,重启,必须在该位置重新注册回调,否则会没反应 77 | registerNavigationCallback(); 78 | } 79 | 80 | @Override 81 | protected void onServiceDisconnected() { 82 | mNavigationInterface = null; 83 | } 84 | 85 | /** 86 | * 注册Navigation回调 87 | */ 88 | private void registerNavigationCallback() { 89 | if (mNavigationInterface != null && mContext != null) { 90 | try { 91 | mNavigationInterface.registerNavigationCallback(mINavigationCallback, mContext.getPackageName()); 92 | } catch (RemoteException e) { 93 | e.printStackTrace(); 94 | } 95 | } else { 96 | Logcat.w("mNavigationInterface = " + mNavigationInterface + " mContext = " + mContext); 97 | } 98 | } 99 | 100 | /** 101 | * 注销Navigation回调 102 | */ 103 | private void unRegisterSystemCallback() { 104 | if (mNavigationInterface != null) { 105 | try { 106 | mNavigationInterface.unRegisterNavigationCallback(mINavigationCallback); 107 | } catch (RemoteException e) { 108 | e.printStackTrace(); 109 | } 110 | } 111 | } 112 | 113 | @Subscribe(threadMode = ThreadMode.MAIN) 114 | public void onNavigationEyeInfo(IVINavigation.EventNavigationEyeInfo event) { 115 | if (mNavigationListener != null) { 116 | mNavigationListener.onNavigationEyeInfo(event.mType, event.mDistance, event.mSpeedLimit); 117 | } 118 | } 119 | 120 | @Subscribe(threadMode = ThreadMode.MAIN) 121 | public void onNavigationGuide(IVINavigation.EventNavigationGuide event) { 122 | if (mNavigationListener != null) { 123 | mNavigationListener.onNavigationGuide(event.mDirection); 124 | } 125 | } 126 | 127 | @Subscribe(threadMode = ThreadMode.MAIN) 128 | public void onNavigationAddress(IVINavigation.EventNavigationAddress event) { 129 | if (mNavigationListener != null) { 130 | mNavigationListener.onNavigationAddress(event.mProvince, event.mCity, event.mCounty); 131 | } 132 | } 133 | 134 | @Subscribe(threadMode = ThreadMode.MAIN) 135 | public void onNavigationType(IVINavigation.EventNavigationType event) { 136 | if (mNavigationListener != null) { 137 | mNavigationListener.onNavigationType(event.mTwelveClock, 138 | event.mTurnID, 139 | event.mArrayTurn, 140 | event.mGuideType, 141 | event.mDistance, 142 | event.mDestDistance, 143 | event.mDestTime, 144 | event.mRoadName, 145 | event.mNextRoadName, 146 | event.mDestName); 147 | } 148 | } 149 | 150 | private INavigationCallback.Stub mINavigationCallback = new INavigationCallback.Stub() { 151 | 152 | @Override 153 | public void onNavigationType(int twelveClock, int turnID, int[] arrayTurn, int guideType, int distance, int destDistance, int destTime, String roadName, String nextRoadName, String destName) throws RemoteException { 154 | post(new IVINavigation.EventNavigationType(twelveClock, turnID, arrayTurn, guideType, distance, destDistance, destTime, roadName, nextRoadName, destName)); 155 | } 156 | 157 | @Override 158 | public void onNavigationAddress(String province, String city, String county) throws RemoteException { 159 | post(new IVINavigation.EventNavigationAddress(province, city, county)); 160 | } 161 | 162 | @Override 163 | public void onNavigationGuide(int direction) throws RemoteException { 164 | post(new IVINavigation.EventNavigationGuide(direction)); 165 | } 166 | 167 | @Override 168 | public void onNavigationEyeInfo(int type, int distance, int speedLimit) throws RemoteException { 169 | post(new IVINavigation.EventNavigationEyeInfo(type, distance, speedLimit)); 170 | } 171 | }; 172 | 173 | 174 | } 175 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/utils/LogNameUtil.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.utils; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.lang.reflect.Field; 6 | import java.util.ArrayList; 7 | 8 | /** 9 | * 用来协助打印每个常量类的 getName 方法 10 | */ 11 | 12 | public class LogNameUtil { 13 | 14 | /** 15 | * 打印出 class 里面定义的常量名 16 | * 例: class 里面定义了 public static final int ID_MUSIC = 0; 17 | * 如果 id 传 0, 则返回 "ID_MUSIC" 18 | * @param id 需要打印的id 19 | * @param c 类对象,一般传 类.class 20 | * @return 21 | */ 22 | public static String getName(int id, Class c) { 23 | return getName(id, c, "unknown:" + id); 24 | } 25 | 26 | /** 27 | * 打印出 class 里面定义的常量名 28 | * @param id 29 | * @param c 30 | * @param unknownString 未定义的提示 31 | * @return 32 | */ 33 | public static String getName(int id, Class c, String unknownString, String... exceptArray) { 34 | if (c != null) { 35 | Field[] fields = c.getDeclaredFields(); 36 | if (fields != null) { 37 | for (Field field : fields) { 38 | if (null != field) { 39 | field.setAccessible(true); 40 | if (field.getType() == int.class) { 41 | try { 42 | int value = field.getInt(null); 43 | if (value == id) { 44 | final String string = field.getName(); 45 | boolean find = true; 46 | if (null != exceptArray) { 47 | for (int i = 0;i < exceptArray.length;i++) { 48 | if (TextUtils.equals(string, exceptArray[i])) { 49 | find = false; 50 | break; 51 | } 52 | } 53 | } 54 | if (find) { 55 | return string; 56 | } 57 | } 58 | } catch (IllegalAccessException e) { 59 | e.printStackTrace(); 60 | } catch (Exception e) { 61 | 62 | } 63 | } 64 | } 65 | } 66 | } 67 | } 68 | return unknownString; 69 | } 70 | 71 | /** 72 | * 获取指定类名的所有值域 73 | * @param c 74 | * @return 75 | */ 76 | public static ArrayList getFields(Class c) { 77 | ArrayList ret = new ArrayList<>(); 78 | if (c != null) { 79 | Field[] fields = c.getDeclaredFields(); 80 | if (fields != null) { 81 | for (Field field : fields) { 82 | if (null != field) { 83 | field.setAccessible(true); 84 | if (field.getType() == int.class) { 85 | try { 86 | int value = field.getInt(null); 87 | ret.add(value); 88 | } catch (IllegalAccessException e) { 89 | e.printStackTrace(); 90 | } catch (Exception e) { 91 | 92 | } 93 | } 94 | } 95 | } 96 | } 97 | } 98 | return ret; 99 | } 100 | 101 | /** 102 | * 获取filed名称对应的值 103 | * @param c 类名 104 | * @param name filed名称 105 | * @param def 默认值 106 | * @return 107 | */ 108 | public static int getValue(Class c, String name, int def) { 109 | if (!TextUtils.isEmpty(name)) { 110 | ArrayList list = getFields(c); 111 | if (null != list) { 112 | for (Integer id : list) { 113 | if (name.equals(getName(id, c))) { 114 | return id; 115 | } 116 | } 117 | } 118 | } 119 | return def; 120 | } 121 | 122 | /** 123 | * 将 object 对象里面的 int, String, long, float 等可以打印的数据,打印出来 124 | * @param object 对象 125 | * @return 返回打印结果 126 | */ 127 | public static String toString(Object object) { 128 | String ret = ""; 129 | if (object != null) { 130 | Field[] fields = FieldUtil.getAllDeclaredFields(object.getClass()); // 获取所有的属性 131 | if (!ListUtils.isEmpty(fields)) { 132 | try { 133 | for (Field field : fields) { 134 | field.setAccessible(true); 135 | try { 136 | field.get(null); // 常量不做处理 137 | continue; 138 | } catch (Exception e) { 139 | 140 | } 141 | 142 | if (field.getType() == int.class) { 143 | ret += (field.getName() + "=" + field.getInt(object)); 144 | } else if (field.getType() == long.class) { 145 | ret += (field.getName() + "=" + field.getLong(object)); 146 | } else if (field.getType() == float.class) { 147 | ret += (field.getName() + "=" + field.getFloat(object)); 148 | } else if (field.getType() == String.class) { 149 | ret += (field.getName() + "=" + field.get(object)); 150 | } else if (field.getType() == short.class) { 151 | ret += (field.getName() + "=" + field.getShort(object)); 152 | } else if (field.getType() == short.class) { 153 | ret += (field.getName() + "=" + field.getDouble(object)); 154 | } else if (field.getType() == boolean.class) { 155 | ret += (field.getName() + "=" + field.getBoolean(object)); 156 | } else { // 其他类型不打印 157 | continue; 158 | } 159 | ret += " "; 160 | } 161 | } catch (IllegalAccessException e) { 162 | e.printStackTrace(); 163 | } 164 | } 165 | } 166 | return ret; 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/car/ByteBitsDesc.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.car; 2 | 3 | import android.util.Log; 4 | 5 | import com.roadrover.sdk.utils.Logcat; 6 | 7 | /** 8 | * 处理一些字节相关的流程,字符串描述格式为以下几种 9 | * BYTE[X]:BIT[Y-Z],第X个字节,BIT位从Y到Z的值,Y可以比Z大也可以比Z小 10 | * BYTE[X],第X个字节整个值 11 | * BYTE[X]:BIT[Y], 第X个字节,BIT Y单个Bit 12 | * 大小写不敏感,BYTE和BIT中间的‘:’可以不要或者换别的字符, 13 | * Y和Z中间的-可以换成别的字符,但不能没有分隔符 14 | */ 15 | public class ByteBitsDesc { 16 | public static final String BYTE_NAME = "BYTE"; 17 | public static final String BIT_NAME = "BIT"; 18 | 19 | private String mDesc; 20 | private boolean mFormatIsValid = false; 21 | private int mByteIndex = -1; 22 | private int mBitMask = 0; 23 | private int mBitHighIndex; 24 | private int mBitLowIndex; 25 | 26 | public ByteBitsDesc() { 27 | } 28 | 29 | public ByteBitsDesc(String desc) { 30 | setDesc(desc); 31 | } 32 | 33 | public void setDesc(String desc) { 34 | mDesc = desc; 35 | if (!getByteIndex()) { 36 | mFormatIsValid = false; 37 | Logcat.e("error BYTE format " + desc); 38 | } else { 39 | if (!getBitMask()) { 40 | mFormatIsValid = false; 41 | Logcat.e("error BIT format " + desc); 42 | } else { 43 | mFormatIsValid = true; 44 | } 45 | } 46 | } 47 | 48 | public int get(byte[] buff) { 49 | if (!mFormatIsValid || mByteIndex >= buff.length) { 50 | return 0; 51 | } 52 | 53 | return (buff[mByteIndex] & mBitMask) >> mBitLowIndex; 54 | } 55 | 56 | public void set(byte[] buff, int value) { 57 | if (!mFormatIsValid || mByteIndex >= buff.length) { 58 | return; 59 | } 60 | 61 | if (value > (mBitMask >> mBitLowIndex)) { 62 | Logcat.e("Warning value is overflow at " + mDesc + " value is " + value); 63 | } 64 | 65 | buff[mByteIndex] &= ~mBitMask; 66 | buff[mByteIndex] |= (value << mBitLowIndex); 67 | } 68 | 69 | private boolean getByteIndex() { 70 | int start = mDesc.toUpperCase().indexOf(BYTE_NAME); 71 | if (start < 0) { 72 | return false; 73 | } 74 | 75 | start = mDesc.indexOf('[', start); 76 | if (start < 0) { 77 | return false; 78 | } 79 | 80 | int end = mDesc.indexOf(']', start); 81 | if (end < 0) { 82 | return false; 83 | } 84 | 85 | mByteIndex = Integer.parseInt(mDesc.substring(start+1, end), 10); 86 | return true; 87 | } 88 | 89 | private boolean getBitMask() { 90 | int start = mDesc.toUpperCase().indexOf(BIT_NAME); 91 | if (start < 0) { 92 | Logcat.e("Can not find " + BIT_NAME + " from " + mDesc); 93 | return false; 94 | } 95 | 96 | start = mDesc.indexOf('[', start); 97 | if (start < 0) { 98 | Logcat.e("Can not find [ after BIT from " + mDesc); 99 | return false; 100 | } 101 | 102 | int end = mDesc.indexOf(']', start); 103 | if (end < 0) { 104 | Logcat.e("Can not find ] after BIT from " + mDesc); 105 | return false; 106 | } 107 | 108 | String bitMaskDesc = mDesc.substring(start+1, end); 109 | if (bitMaskDesc.length() != 1 && bitMaskDesc.length() != 3) { 110 | return false; 111 | } 112 | 113 | if (bitMaskDesc.length() == 1) { 114 | mBitLowIndex = Integer.parseInt(bitMaskDesc, 10); 115 | mBitMask = (1 << mBitLowIndex); 116 | } else if (bitMaskDesc.length() == 3) { 117 | int bitsIndex0 = Integer.parseInt(String.valueOf(bitMaskDesc.charAt(0)), 10); 118 | int bitsIndex1 = Integer.parseInt(String.valueOf(bitMaskDesc.charAt(2)), 10); 119 | if (bitsIndex0 >= bitsIndex1) { 120 | mBitLowIndex = bitsIndex1; 121 | mBitHighIndex = bitsIndex0; 122 | } else { 123 | mBitLowIndex = bitsIndex0; 124 | mBitHighIndex = bitsIndex1; 125 | } 126 | 127 | mBitMask = 0; 128 | for (int i = mBitLowIndex; i <= mBitHighIndex; i++) { 129 | mBitMask |= (1 << i); 130 | } 131 | } 132 | 133 | return true; 134 | } 135 | 136 | /** 137 | * 测试流程 138 | */ 139 | public static void test() { 140 | int TEST_COUNT = 10; 141 | byte[] buff = new byte[TEST_COUNT]; 142 | 143 | /** 144 | * 测试例子 "Byte[x] 145 | */ 146 | for (int i=0; i getSubIds() { 58 | return LogNameUtil.getFields(SubId.class); 59 | } 60 | } 61 | 62 | /** 63 | * CVBS类型 64 | */ 65 | public static class CvbsType { 66 | /** 67 | * 自动, 其值 {@value} 68 | */ 69 | public static final int AUTO = 0; 70 | /** 71 | * NTSC制式, 其值 {@value} 72 | */ 73 | public static final int NTSC = 1; 74 | /** 75 | * PAL制式, 其值 {@value} 76 | */ 77 | public static final int PAL = 2; 78 | /** 79 | * SECAM制式, 其值 {@value} 80 | */ 81 | public static final int SECAM = 3; 82 | /** 83 | * 最小值, 其值 {@value} 84 | */ 85 | public static final int MIN = AUTO; 86 | /** 87 | * 最大值, 其值 {@value} 88 | */ 89 | public static final int MAX = SECAM; 90 | 91 | /** 92 | * 获取CVBS类型的名字 93 | * @param type CVBS类型,见{@link CvbsType} 94 | * @return 95 | */ 96 | public static String getName(int type) { 97 | return LogNameUtil.getName(type, CvbsType.class, "Unknown CVBS type " + type, "MIN", "MAX"); 98 | } 99 | 100 | /** 101 | * 获取视频高度 102 | * @param type CVBS类型,见{@link CvbsType} 103 | * @return 104 | */ 105 | public static int getVideoHeight(int type) { 106 | if (AUTO == type) { 107 | type = IVIConfig.getAVInDefaultCVBSType(); 108 | } 109 | return getCVBSVideoHeight(type); 110 | } 111 | 112 | /** 113 | * 获取视频宽度 114 | * @param type CVBS类型,见{@link CvbsType} 115 | * @return 116 | */ 117 | public static int getVideoWidth(int type) { 118 | if (AUTO == type) { 119 | type = IVIConfig.getAVInDefaultCVBSType(); 120 | } 121 | return getCVBSVideoWidth(type); 122 | } 123 | 124 | /** 125 | * 获取指定CVBS格式视频高度 126 | * @param type CVBS类型,见{@link CvbsType} 127 | * @return 128 | */ 129 | private static int getCVBSVideoHeight(int type) { 130 | switch (type) { 131 | case NTSC: 132 | return 480; 133 | case PAL: 134 | // fall through 135 | case SECAM: 136 | // fall through 137 | default: 138 | return 576; 139 | } 140 | } 141 | 142 | /** 143 | * 获取指定CVBS格式视频宽度 144 | * @param type CVBS类型,见{@link CvbsType} 145 | * @return 146 | */ 147 | private static int getCVBSVideoWidth(int type) { 148 | return 720; 149 | } 150 | } 151 | 152 | /** 153 | * 构造函数 154 | * @param avId AVIN ID,见{@link com.roadrover.sdk.avin.IVIAVIn.Id} 155 | * @param subId Sub ID,见{@link VideoParam.SubId} 156 | * @param min 最小值 157 | * @param max 最大值 158 | * @param defaultValue 默认值 159 | */ 160 | public VideoParam(int avId, int subId, int min, int max, int defaultValue) { 161 | super(makeId(avId, subId), min, max, defaultValue); 162 | } 163 | 164 | /** 165 | * 构造函数 166 | * @param id 视频ID,通过{@link #makeId(int, int)}获得 167 | * @param min 最小值 168 | * @param max 最大值 169 | * @param defaultValue 默认值 170 | */ 171 | public VideoParam(int id, int min, int max, int defaultValue) { 172 | super(id, min, max, defaultValue); 173 | } 174 | 175 | /** 176 | * 构造函数 177 | * @param id 视频ID,通过{@link #makeId(int, int)}获得 178 | * @param defaultValue 默认值 179 | */ 180 | public VideoParam(int id, boolean defaultValue) { 181 | super(id, defaultValue); 182 | } 183 | 184 | /** 185 | * 构造函数 186 | * @param id 视频ID,通过{@link #makeId(int, int)}获得 187 | * @param value 当前值 188 | */ 189 | public VideoParam(int id, int value) { 190 | super(id, value); 191 | } 192 | 193 | /** 194 | * 获取AVIN ID 195 | * @param id 视频ID,通过{@link #makeId(int, int)}获得 196 | * @return 197 | */ 198 | public static int getAVId(int id) { 199 | return (id & 0xFF00) >> 8; 200 | } 201 | 202 | /** 203 | * 获取Sub ID 204 | * @param id 视频ID,通过{@link #makeId(int, int)}获得 205 | * @return 206 | */ 207 | public static int getSubId(int id) { 208 | return (id & 0xFF); 209 | } 210 | 211 | /** 212 | * 视频参数,ID由两部分组成 213 | * @param avId Bit[16-8] 视频通道号,见{@link com.roadrover.sdk.avin.IVIAVIn.Id} 214 | * @param subId Bit[8-0] 亮度、对比度,见{@link VideoParam.SubId} 215 | * @return 216 | */ 217 | public static int makeId(int avId, int subId) { 218 | return ((avId & 0xFF) << 8) | (subId & 0xFF); 219 | } 220 | 221 | /** 222 | * 获取视频参数名字 223 | * @return 224 | */ 225 | public String getName() { 226 | return getName(mId); 227 | } 228 | 229 | /** 230 | * 通过视频参数ID获取名字 231 | * @param id 视频ID,通过{@link #makeId(int, int)}获得 232 | * @return 233 | */ 234 | public static String getName(int id) { 235 | return IVIAVIn.Id.getName(getAVId(id)) + ":" + SubId.getName(getSubId(id)); 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/car/ICar.aidl: -------------------------------------------------------------------------------- 1 | // ICar.aidl 2 | package com.roadrover.services.car; 3 | import com.roadrover.services.car.ICarCallback; 4 | import com.roadrover.services.car.IMcuUpgradeCallback; 5 | 6 | interface ICar { 7 | /** 8 | * 获取协议卡MCU的软件版本 9 | */ 10 | String getProtocolMcuVersion(); 11 | 12 | /** 13 | * 获取车型ID 14 | */ 15 | int getCarId(); 16 | 17 | /** 18 | * 注册回调 19 | * @param callback 回调接口 20 | */ 21 | void registerCallback(ICarCallback callback); 22 | 23 | /** 24 | * 注销回调 25 | * @param callback 回调接口 26 | */ 27 | void unRegisterCallback(ICarCallback callback); 28 | 29 | /** 30 | * 注册高频实时车辆信息ID,只有注册后才能获取该ID的实时回调 31 | * @param id IVICar.RealTimeInfoId 32 | * @param callback 被调用的回调接口 33 | */ 34 | void registerRealTimeInfo(int id, ICarCallback callback); 35 | 36 | /** 37 | * 注销高频实时车辆信息ID,不再接收该ID的回调 38 | * @param id IVICar.RealTimeInfoId 39 | * @param callback 实时信息id更新后不再被调用的回调接口 40 | */ 41 | void unRegisterRealTimeInfo(int id, ICarCallback callback); 42 | 43 | /** 44 | * 获取实时车辆信息 45 | * @param id IVICar.RealTimeInfoId 46 | */ 47 | float getRealTimeInfo(int id); 48 | 49 | /** 50 | * 获取CCD状态,返回IVICar.CcdStatus 51 | */ 52 | int getCcdStatus(); 53 | 54 | /** 55 | * 获取手刹状态,返回IVICar.HandbrakeStatus 56 | */ 57 | int getHandbrakeStatus(); 58 | 59 | /** 60 | * 获取车门状态mask 61 | */ 62 | int getDoorStatusMask(); 63 | 64 | /** 65 | * 获取车灯状态mask 66 | */ 67 | int getLightStatusMask(); 68 | 69 | /** 70 | * 获取大灯状态mask 71 | */ 72 | boolean getHeadLightStatus(); 73 | 74 | /** 75 | * 获取空调原始值,有的需要通过IVICar.Climate来解析 76 | * @param id Climate.Id 77 | */ 78 | int getClimate(int id); 79 | 80 | /** 81 | * 设置空调值 82 | * @param id Climate.Id 83 | * @param value 空调值 84 | */ 85 | void setClimate(int id, int value); 86 | 87 | /** 88 | * 获取原车设置值,原始字节串 89 | */ 90 | byte[] getCarSettingBytes(); 91 | 92 | /** 93 | * 设置原车设置值 94 | * @param id 参数ID 95 | * @param value 设置值 96 | */ 97 | void setCarSetting(int id, int value); 98 | 99 | /** 100 | * 获取雷达距离值 101 | */ 102 | byte[] getRadarDistanceBytes(); 103 | 104 | /** 105 | * 获取雷达报警值 106 | */ 107 | byte[] getRadarWarmingBytes(); 108 | 109 | /** 110 | * 通知mcu发送雷达数据 111 | */ 112 | void needRadarValue(); 113 | 114 | /** 115 | * 获取车外温度,需要通过IVICar.OutsideTemp来解析 116 | */ 117 | int getOutsideTempRawValue(); 118 | 119 | /** 120 | * 获取里程信息 121 | * @param id Trip.Id 122 | * @param index Trip.Index 123 | */ 124 | float getTrip(int id, int index); 125 | 126 | /** 127 | * 获取额外车辆信息 128 | * @param id IVICar.ExtraState.Id 129 | */ 130 | float getExtraState(int id); 131 | 132 | /** 133 | * 升级mcu 134 | * @param filePath 升级mcu文件 135 | * @param callback 回调通知 136 | */ 137 | void upgradeMcu(String filePath, IMcuUpgradeCallback callback); 138 | 139 | /** 140 | * 设置倒车摄像头的电源 141 | * @param on true打开电源,false关闭电源 142 | */ 143 | void setCcdPower(boolean on); 144 | 145 | /** 146 | * 退出操作系统启动过程中提供的快速倒车功能 147 | */ 148 | void disableFastReverse(); 149 | 150 | /** 151 | * 系统是否处于快速倒车状态 152 | */ 153 | boolean isInFastReverse(); 154 | 155 | /** 156 | * 设置外设参数 157 | * @param carId IVICar.ExtraDevice.CarId 158 | * @param deviceId IVICar.ExtraDevice.DeviceId 159 | * @param extraDeviceData 外设参数输入数据 160 | */ 161 | void setExtraDevice(int carId, int deviceId, in byte[] extraDeviceData); 162 | 163 | /** 164 | * 设置氛围灯音频参数 165 | * @param extraAudioData 氛围灯音频参数数据 166 | */ 167 | void setExtraAudioParameters(in byte[] extraAudioData); 168 | 169 | /** 170 | * 请求发送所有service端缓存的外设参数,通过ICarCallback回调获取 171 | */ 172 | void requestExtraDeviceEvent(); 173 | 174 | /** 175 | * 设置CMD_PARAM参数 176 | * @param id IVICar.CmdParam.Id 177 | * @param paramData 参数数据 178 | */ 179 | void setCmdParam(int id, in byte[] paramData); 180 | 181 | /** 182 | * 获取CMD_PARAM参数 183 | * @param id IVICar.CmdParam.Id 184 | */ 185 | byte[] getCmdParams(int id); 186 | 187 | /** 188 | * 请求发送所有service端缓存的CMD_PARAM参数,通过ICarCallback回调获取 189 | */ 190 | void requestCmdParamEvent(); 191 | 192 | /** 193 | * 发送触摸消息给单片机 194 | * X: 0 -> Left, 255 -> Right 195 | * Y: 0 -> Top, 255 -> Bottom 196 | */ 197 | void sendTouchClick(int x, int y); 198 | 199 | /** 200 | * 获取保养里程(保养周期或保养检查) 201 | * @param id IVICar.Maintenance.Id 202 | */ 203 | int getMaintenanceMileage(int id); 204 | 205 | /** 206 | * 获取保养天数(保养周期或保养检查) 207 | * @param id IVICar.Maintenance.Id 208 | */ 209 | int getMaintenanceDays(int id); 210 | 211 | /** 212 | * 获取车辆识别码VIN 213 | */ 214 | String getCarVIN(); 215 | 216 | /** 217 | * 获取匹配钥匙数目 218 | */ 219 | int getPairKeyNumber(); 220 | 221 | /** 222 | * 获取故障码数组 223 | * @param carId IVICar.CarReport.Car 224 | * @param reportType IVICar.CarReport.Type 225 | */ 226 | int[] getReportArray(int carId, int reportType); 227 | 228 | /** 229 | * 获取自动泊车数据 230 | */ 231 | int getAutoPark(); 232 | 233 | /** 234 | * 获取能量流动数据 235 | */ 236 | byte[] getEnergyFlowData(); 237 | 238 | /** 239 | * 下发原车LedKey值 240 | * @param key 按键值 241 | * @param pushType 按键种类,长短按等 242 | */ 243 | void setCarLedKey(int key, int pushType); 244 | 245 | /** 246 | * 下发ADKey值 247 | * @param channel 通道 248 | * @param key 值 249 | */ 250 | void setADKey(int channel, int key); 251 | 252 | /** 253 | * 发送命令给仪表 254 | * @param params 数据 255 | */ 256 | void setClusterParam(in byte[] params); 257 | 258 | /** 259 | * 发送触摸坐标给单片机 260 | * @param x x轴坐标 261 | * @param y y轴坐标 262 | * @param type 见{@link com.roadrover.sdk.car.IVICar.TouchClickEvent} 263 | */ 264 | void setTouch(in int x, in int y, in int type); 265 | 266 | /** 267 | * 发送暂停心跳命令给下位机 268 | */ 269 | void pauseHeartbeat(); 270 | 271 | /** 272 | * 半小时模式下,发数据给下位机开屏 273 | */ 274 | void setAccOffUintOn(); 275 | 276 | /** 277 | * 请求发送所有service端缓存的CMD_TPMS参数,通过ICarCallback回调获取 278 | */ 279 | void requestCmdTpmsEvent(); 280 | 281 | /** 282 | * 获取ACC状态,返回IVICar.Acc 283 | */ 284 | boolean isAccOn(); 285 | 286 | /** 287 | * 获取硬件版本等信息; 组成规则:由#分开如:{硬件版本号}#{PCB版本}#{ECN/DCN编码}#{日期} 288 | */ 289 | String getHardwareVersionString(); 290 | 291 | /** 292 | * 给MCU发送按键 293 | */ 294 | void sendKeyToMcu(in int key); 295 | 296 | /** 297 | * 清空空调缓存值 298 | * @param id Climate.Id 299 | */ 300 | void clearClimate(int id, int value); 301 | } 302 | -------------------------------------------------------------------------------- /src/main/aidl/com/roadrover/services/audio/IAudio.aidl: -------------------------------------------------------------------------------- 1 | // IAudio.aidl 2 | package com.roadrover.services.audio; 3 | import com.roadrover.services.audio.IAudioCallback; 4 | 5 | interface IAudio { 6 | /** 7 | * 注册IAudioCallback的回调对象 8 | * @param callback 回调对象 9 | */ 10 | void registerCallback(IAudioCallback callback); 11 | /** 12 | * 反注册IAudioCallback的回调对象 13 | * @param callback 回调对象 14 | */ 15 | void unRegisterCallback(IAudioCallback callback); 16 | 17 | /** 18 | * 指定参数是否有效 19 | * @param id AudioParam.Id 20 | * @return true 有效,false 无效 21 | */ 22 | boolean isParamAvailable(int id); 23 | /** 24 | * 获取指定参数的最小值 25 | * @param id AudioParam.Id 26 | * @return 指定参数的最小值 27 | */ 28 | int getParamMinValue(int id); 29 | /** 30 | * 获取指定参数的最大值 31 | * @param id AudioParam.Id 32 | * @return 指定参数的最大值 33 | */ 34 | int getParamMaxValue(int id); 35 | /** 36 | * 获取指定参数的默认值 37 | * @param id AudioParam.Id 38 | * @return 指定参数的默认值 39 | */ 40 | int getParamDefaultValue(int id); 41 | /** 42 | * 获取指定参数 43 | * @param id AudioParam.Id 44 | * @return 指定参数 45 | */ 46 | int getParam(int id); 47 | /** 48 | * 设置指定参数的值 49 | * @param id AudioParam.Id 50 | * @param value 指定参数的值 51 | */ 52 | void setParam(int id, int value); 53 | /** 54 | * 获取十段EQ增益 55 | * @param eqMode EQ模式的值 56 | * @return 十段EQ增益 57 | */ 58 | int[] getEqGains(int eqMode); 59 | 60 | /** 61 | * 开发者接口,判断前置音频通道增益是否有效 62 | * @param channel IVIAudio.Channel 63 | * @return true 有效,false无效 64 | */ 65 | boolean isBuildInPreVolumeAvailable(int channel); 66 | /** 67 | * 开发者接口,获取前置音频通道增益的最小值 68 | * @param channel IVIAudio.Channel 69 | * @return 前置音频通道增益的最小值 70 | */ 71 | float getBuildInPreVolumeMinValue(int channel); 72 | /** 73 | * 开发者接口,获取前置音频通道增益的最大值 74 | * @param channel IVIAudio.Channel 75 | * @return 前置音频通道增益的最大值 76 | */ 77 | float getBuildInPreVolumeMaxValue(int channel); 78 | /** 79 | * 开发者接口,获取前置音频通道增益的默认值 80 | * @param channel IVIAudio.Channel 81 | * @return 前置音频通道增益的默认值 82 | */ 83 | float getBuildInPreVolumeDefaultValue(int channel); 84 | /** 85 | * 开发者接口,获取前置音频通道增益的值 86 | * @param channel IVIAudio.Channel 87 | * @return 前置音频通道增益的值 88 | */ 89 | float getBuildInPreVolumeValue(int channel); 90 | /** 91 | * 开发者接口,设置前置音频通道增益的值 92 | * @param channel IVIAudio.Channel 93 | * @param value 前置音频通道增益的值 94 | */ 95 | void setBuildInPreVolumeValue(int channel, float value); 96 | /** 97 | * 开发者接口,重置所有前置音频通道增益的值 98 | */ 99 | void resetBuildInPreVolumeValue(); 100 | 101 | /** 102 | * 开发者接口,判断辅助音频通道增益是否有效 103 | * @param channel IVIAudio.Channel 104 | * @return true 有效,false无效 105 | */ 106 | boolean isSecondaryBuildInPreVolumeAvailable(int channel); 107 | /** 108 | * 开发者接口,获取辅助音频通道增益的最小值 109 | * @param channel IVIAudio.Channel 110 | * @return 辅助音频通道增益的最小值 111 | */ 112 | float getSecondaryBuildInPreVolumeMinValue(int channel); 113 | /** 114 | * 开发者接口,获取辅助音频通道增益的最大值 115 | * @param channel IVIAudio.Channel 116 | * @return 辅助音频通道增益的最大值 117 | */ 118 | float getSecondaryBuildInPreVolumeMaxValue(int channel); 119 | /** 120 | * 开发者接口,获取辅助音频通道增益的默认值 121 | * @param channel IVIAudio.Channel 122 | * @return 辅助音频通道增益的默认值 123 | */ 124 | float getSecondaryBuildInPreVolumeDefaultValue(int channel); 125 | /** 126 | * 开发者接口,获取辅助音频通道增益的值 127 | * @param channel IVIAudio.Channel 128 | * @return 辅助音频通道增益的值 129 | */ 130 | float getSecondaryBuildInPreVolumeValue(int channel); 131 | /** 132 | * 开发者接口,设置辅助音频通道增益的值 133 | * @param channel IVIAudio.Channel 134 | * @param value 辅助音频通道增益的值 135 | */ 136 | void setSecondaryBuildInPreVolumeValue(int channel, float value); 137 | /** 138 | * 开发者接口,重置所有辅助音频通道增益的值 139 | */ 140 | void resetSecondaryBuildInPreVolumeValue(); 141 | 142 | /** 143 | * 开发者接口,判断主音频设备是否有效 144 | * @return true 有效,false无效 145 | */ 146 | boolean isMasterAudioDeviceAvailable(); 147 | /** 148 | * 开发者接口,获取音量增益的最小值 149 | * @return 音量增益的最小值 150 | */ 151 | float getMasterVolumeGainMinValue(); 152 | /** 153 | * 开发者接口,获取音量增益的最大值 154 | * @return 音量增益的最大值 155 | */ 156 | float getMasterVolumeGainMaxValue(); 157 | /** 158 | * 开发者接口,获取音量增益的默认值 159 | * @param volume 音量值 160 | * @return 音量增益的默认值 161 | */ 162 | float getMasterVolumeGainDefaultValue(int volume); 163 | /** 164 | * 开发者接口,获取音量增益的值 165 | * @param volume 音量值 166 | * @return 音量增益的值 167 | */ 168 | float getMasterVolumeGainValue(int volume); 169 | /** 170 | * 开发者接口,设置音量增益的值 171 | * @param volume 音量值 172 | * @param value 音量增益的值 173 | */ 174 | void setMasterVolumeGainValue(int volume, float value); 175 | /** 176 | * 开发者接口,重置所有音量增益的值 177 | */ 178 | void resetMasterVolumeGainValue(); 179 | 180 | /** 181 | * 开发者接口,判断辅助音频设备是否有效 182 | * @return true 有效,false无效 183 | */ 184 | boolean isSecondaryAudioDeviceAvailable(); 185 | /** 186 | * 开发者接口,获取辅助音量增益的最小值 187 | * @return 辅助音量增益的最小值 188 | */ 189 | float getSecondaryVolumeGainMinValue(); 190 | /** 191 | * 开发者接口,获取辅助音量增益的最大值 192 | * @return 辅助音量增益的最大值 193 | */ 194 | float getSecondaryVolumeGainMaxValue(); 195 | /** 196 | * 开发者接口,获取辅助音量增益的默认值 197 | * @param volume 音量值 198 | * @return 辅助音量增益的默认值 199 | */ 200 | float getSecondaryVolumeGainDefaultValue(int volume); 201 | /** 202 | * 开发者接口,获取辅助音量增益的值 203 | * @param volume 音量值 204 | * @return 辅助音量增益的值 205 | */ 206 | float getSecondaryVolumeGainValue(int volume); 207 | /** 208 | * 开发者接口,设置辅助音音量增益的值 209 | * @param volume 音量值 210 | * @param value 辅助音量增益的值 211 | */ 212 | void setSecondaryVolumeGainValue(int volume, float value); 213 | /** 214 | * 开发者接口,重置所有辅助音量增益的值 215 | */ 216 | void resetSecondaryVolumeGainValue(); 217 | 218 | /** 219 | * 显示音量条 220 | */ 221 | void showVolumeBar(); 222 | 223 | /** 224 | * 隐藏音量条 225 | */ 226 | void hideVolumeBar(); 227 | 228 | /** 229 | * 如果音量条是显示的,则隐藏,反之显示 230 | */ 231 | void toggleVolumeBar(); 232 | 233 | /** 234 | * 显示次通道(后排或者乘客区)的音量条 235 | */ 236 | void showSecondaryVolumeBar(); 237 | 238 | /** 239 | * 获取当前激活的音量ID 240 | */ 241 | int getActiveVolumeId(); 242 | 243 | /** 244 | * 获取前置最小音量 245 | */ 246 | int getMasterVolumeMin(); 247 | 248 | /** 249 | * 获取前置最大音量 250 | */ 251 | int getMasterVolumeMax(); 252 | 253 | /** 254 | * 获取辅助最小音量 255 | */ 256 | int getSecondaryVolumeMin(); 257 | 258 | /** 259 | * 获取辅助最大音量 260 | */ 261 | int getSecondaryVolumeMax(); 262 | 263 | /** 264 | * 请求内部先静音,隔一段时候反静音 265 | * @param muteDurationMs 静音后反静音时间ms 266 | */ 267 | void requestInternalShortMute(int muteDurationMs); 268 | 269 | /** 270 | * 在收音机、AV、TV、AUX、BC05的A2DP等场景下,有了导航提示音,此时的媒体音量应该下降, 271 | * 调用此函数来设置媒体音量的百分比 272 | * @param percent 100最大,0没有 273 | */ 274 | void setAnalogMediaVolumePercent(int percent); 275 | 276 | /** 277 | * 获取当前主音频通道 278 | * @return IVIAudio.Channel 279 | */ 280 | int getMasterAudioChannel(); 281 | 282 | /** 283 | * 设置音频DSP的参数,专家音效畅友使用 284 | */ 285 | void setChipParam(int chipId, int paramId, double v0, double v1, double v2, double v3); 286 | 287 | /** 288 | * 添加专家音效配置文件,将机器内部的音效文件替换成pathName文件内的内容 289 | * @param effect AudioParam.ExpertAudioEffect 290 | * @param pathName 音效文件路径全名 291 | * @param apply 是否立即起作用 292 | */ 293 | void addExpertAudioEffect(int effect, String pathName, boolean apply); 294 | 295 | /** 296 | * 获取当前支持的专家音效场景列表 297 | * @return 数组内部存放 AudioParam.ExpertAudioEffect 298 | */ 299 | int[] getAvailableExpertAudioEffects(); 300 | 301 | /** 302 | * 获取专家音效文件名 303 | * @param effect AudioParam.ExpertAudioEffect 304 | * @return 文件路径全名 305 | */ 306 | String getExpertAudioEffectFile(int effect); 307 | } 308 | -------------------------------------------------------------------------------- /src/main/java/com/roadrover/sdk/utils/FileUtils.java: -------------------------------------------------------------------------------- 1 | package com.roadrover.sdk.utils; 2 | 3 | import android.content.Context; 4 | import android.text.TextUtils; 5 | 6 | import java.io.File; 7 | import java.io.FileInputStream; 8 | import java.io.FileNotFoundException; 9 | import java.io.FileOutputStream; 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.io.OutputStream; 13 | 14 | /** 15 | * 文件的工具类 16 | * 实现和文件相关的方法,目前主要只实现了文件拷贝的方法 17 | * @author bin.xie 18 | * @date 2016/4/25 19 | */ 20 | public class FileUtils { 21 | 22 | public FileUtils() { 23 | // TODO Auto-generated constructor stub 24 | } 25 | 26 | public interface FileOptionProgressCallback { 27 | void onOptionProgress(long totalSize, long proSizes); 28 | } 29 | 30 | /** 31 | * 拷贝 assets 下面的文件到本机,最终目录为 /data/data/包名/files/assets/ 32 | * @param context 33 | * @param assetsFileName assets下面需要拷贝的文件名 34 | * @param destFileName 目标文件名 35 | * @return 拷贝完之后,返回拷贝结果目录 36 | */ 37 | public static String copyAssetsFileToLocal(Context context, String assetsFileName, String destFileName) { 38 | if (context == null) { 39 | return ""; 40 | } 41 | 42 | String dir = context.getFilesDir().toString() + "/assets/"; 43 | File dirFile = new File(dir); 44 | if (!dirFile.exists()) { 45 | dirFile.mkdirs(); 46 | } 47 | String destFilePath = dir + destFileName; 48 | if (!(new File(destFilePath)).exists()) { // 文件不存在,从assets下面拷贝过来 49 | try { 50 | if (fileChannelCopy(context.getAssets().open(assetsFileName), destFilePath)) { 51 | return destFilePath; 52 | } else { 53 | return ""; 54 | } 55 | } catch (IOException e) { 56 | e.printStackTrace(); 57 | return ""; 58 | } 59 | } 60 | return destFilePath; 61 | } 62 | 63 | /** 64 | * 使用文件通道的方式复制文件 65 | * @param in 66 | * @param destPath 67 | * @return 68 | */ 69 | public static boolean fileChannelCopy(InputStream in, String destPath) { 70 | if (in == null || TextUtils.isEmpty(destPath)) { 71 | return false; 72 | } 73 | 74 | OutputStream os = null; 75 | try { 76 | os = new FileOutputStream(destPath); 77 | byte[] buffer = new byte[4096]; 78 | int len; 79 | while((len = in.read(buffer)) != -1) { 80 | os.write(buffer, 0, len); 81 | } 82 | return true; 83 | } catch (FileNotFoundException e) { 84 | e.printStackTrace(); 85 | } catch (IOException e) { 86 | e.printStackTrace(); 87 | } finally { 88 | try { 89 | if (os != null) { 90 | os.flush(); 91 | os.close(); 92 | } 93 | } catch (IOException e) { 94 | e.printStackTrace(); 95 | } 96 | 97 | try { 98 | if (in != null) { 99 | in.close(); 100 | } 101 | } catch (IOException e) { 102 | e.printStackTrace(); 103 | } 104 | } 105 | return false; 106 | } 107 | 108 | /** 109 | * 拷贝文件 110 | * @param srcPath 111 | * @param destPath 112 | * @return 113 | */ 114 | public static boolean copyFile(String srcPath, String destPath) { 115 | return copyFile(srcPath, destPath, true); 116 | } 117 | 118 | public static boolean copyFile(String srcPath, String destPath, boolean overlay) { 119 | return copyFile(srcPath, destPath, overlay, null); 120 | } 121 | 122 | /** 123 | * 拷贝文件 124 | * @param srcPath 原目录 125 | * @param destPath 目标目录 126 | * @param overlay 覆盖文件 127 | * @throws Exception 128 | */ 129 | public static boolean copyFile(String srcPath, String destPath, boolean overlay, FileOptionProgressCallback callback) { 130 | if (TextUtils.isEmpty(srcPath) || TextUtils.isEmpty(destPath)) { 131 | return false; 132 | } 133 | File srcFile = new File(srcPath); 134 | 135 | // 判断源文件是否存在 136 | if (!srcFile.exists()) { 137 | Logcat.d("srcFile:" + srcPath + " not exists!"); 138 | return false; 139 | } else if (!srcFile.isFile()) { 140 | Logcat.d("srcFile:" + srcPath + " not file!"); 141 | return false; 142 | } 143 | 144 | // 判断目标文件是否存在 145 | File destFile = new File(destPath); 146 | if (destFile.exists()) { 147 | // 如果目标文件存在并允许覆盖 148 | if (overlay) { 149 | // 删除已经存在的目标文件,无论目标文件是目录还是单个文件 150 | if (TextUtils.equals(srcPath, destPath)) { // 排除同目录下复制 151 | return true; 152 | } 153 | new File(destPath).delete(); 154 | } 155 | } else { 156 | // 如果目标文件所在目录不存在,则创建目录 157 | if (!destFile.getParentFile().exists()) { 158 | // 目标文件所在目录不存在 159 | if (!destFile.getParentFile().mkdirs()) { 160 | // 复制文件失败:创建目标文件所在目录失败 161 | return false; 162 | } 163 | } 164 | } 165 | 166 | long total = srcFile.length(); 167 | long pro = 0; 168 | 169 | FileInputStream in = null; 170 | FileOutputStream out = null; 171 | int byteread = 0; // 读取的字节数 172 | try { 173 | in = new FileInputStream(srcPath); 174 | out = new FileOutputStream(destPath); 175 | byte[] buffer = new byte[8192]; 176 | 177 | while ((byteread = in.read(buffer)) != -1) { 178 | out.write(buffer, 0, byteread); 179 | if (callback != null) { 180 | pro += byteread; 181 | callback.onOptionProgress(total, pro); 182 | } 183 | } 184 | return true; 185 | } catch (FileNotFoundException e) { 186 | return false; 187 | } catch (IOException e) { 188 | return false; 189 | } finally { 190 | try { 191 | if (out != null) 192 | out.close(); 193 | } catch (IOException e) { 194 | e.printStackTrace(); 195 | } 196 | try { 197 | if (in != null) 198 | in.close(); 199 | } catch (IOException e) { 200 | e.printStackTrace(); 201 | } 202 | } 203 | } 204 | 205 | /** 206 | * 删除文件 207 | * @param file 208 | * @return 209 | */ 210 | public static boolean deleteFile(File file) { 211 | if (file != null) { 212 | if (file.isDirectory()) { 213 | File[] childs = file.listFiles(); 214 | for (File child : childs) { 215 | deleteFile(child); 216 | } 217 | } 218 | return file.delete(); 219 | } 220 | return false; 221 | } 222 | 223 | /** 224 | * 判断文件是否存在 225 | * @param strFile 226 | * @return 227 | */ 228 | public static boolean fileIsExists(String strFile) { 229 | try { 230 | File f = new File(strFile); 231 | if(!f.exists()){ 232 | return false; 233 | } 234 | } catch (Exception e) { 235 | e.printStackTrace(); 236 | return false; 237 | } 238 | return true; 239 | } 240 | 241 | 242 | /** 243 | * 从文件里面读取 readSize 大小的字符 244 | * @param fileName 文件名 245 | * @param readSize 读取大小 246 | * @return 返回读取内容 247 | */ 248 | public static String readFile(String fileName, int readSize) { 249 | if (TextUtils.isEmpty(fileName) || readSize < 0) { 250 | Logcat.w("fileName:" + fileName + " readSize:" + readSize); 251 | return ""; 252 | } 253 | File file = new File(fileName); 254 | if (!file.exists() || !file.canRead()) { 255 | // Logcat.w("file:" + fileName + " not exists or not canRead!"); 256 | return ""; 257 | } 258 | InputStream in = null; 259 | try { 260 | in = new FileInputStream(file); 261 | byte[] buffer = new byte[readSize]; 262 | in.read(buffer); 263 | 264 | String str = new String(buffer); 265 | // Logcat.d(fileName + ": " + str); 266 | return str; 267 | } catch (Exception e){ 268 | Logcat.e("exception at read file " + fileName); 269 | e.printStackTrace(); 270 | } finally { 271 | try { 272 | if (in != null) { 273 | in.close(); 274 | } 275 | } catch (IOException e) { 276 | e.printStackTrace(); 277 | } 278 | } 279 | 280 | return ""; 281 | } 282 | 283 | /** 284 | * 往文件里面写一个字符 285 | * @param filePath 指定路径 286 | * @param value 写的字符 287 | */ 288 | public static void writeFile(String filePath, String value) { 289 | if (TextUtils.isEmpty(filePath) || value == null) { 290 | Logcat.w("filePath:" + filePath + " value:" + value); 291 | return ; 292 | } 293 | 294 | OutputStream out = null; 295 | try { 296 | out = new FileOutputStream(filePath); 297 | byte[] bytes = value.getBytes(); 298 | out.write(bytes); 299 | } catch (IOException e) { 300 | Logcat.e("exception at write register file"); 301 | e.printStackTrace(); 302 | } finally { 303 | try { 304 | if (out != null) { 305 | out.close(); 306 | } 307 | } catch (IOException e) { 308 | e.printStackTrace(); 309 | } 310 | } 311 | } 312 | } 313 | --------------------------------------------------------------------------------