环境准备
支持 Android Studio 1.4 以上
支持 JDK 7.0 以上版本
支持 Android 手机系统 4.0 以上版本
首先,你需要在萤石开放平台官网的 “ 开发者服务-我的应用-应用秘钥 ” 查看Appkey。
SDK 的安装方式
如果是之前采用过直接下载方式的需要删除之前拷贝进来的所有so库文件以及jar包
dependencies { compile 'com.hikvision.ezviz:ezviz-sdk:4.8.0' }
如果是之前采用过直接下载方式的需要删除之前拷贝进来的所有so库文件以及jar包
<dependency> <groupId>com.hikvision.ezviz</groupId> <artifactId>ezviz-sdk</artifactId> <version>4.8.0</version> </dependency>
下载EZOpenSDK
1、拷贝/libs/armeabi-v7a目录下so文件到自己工程对应目录;
2、拷/libs下jar包到自己工程对应目录(包含jmdns和gson);
在 AndroidMainfest.xml 文件中添加:
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.READ_LOGS"/> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
defaultConfig { ... targetSdkVersion 22//小于23 ... ndk { abiFilters "armeabi-v7a"//只支持32位 } } sourceSets { main { jniLibs.srcDirs = ['libs'] } }
注意:
ndk { abiFilters "armeabi-v7a"//只支持32位 }
添加如下activity定义,用于sdk中间页显示,包含登录、开通云存储等。
<activity android:name="com.videogo.main.EzvizWebViewActivity" android:screenOrientation="portrait" android:configChanges="orientation|keyboardHidden" </activity>
添加如下广播接收器,用于接收网络变化刷新SDK网络状态,接收中间页登录成功消息启动其他界面。其中##you_BroadcastReceiver替换为自己代码中定义的BroadcastReceiver
<receiver android:name="you_BroadcastReceiver" android:exported="false" > <intent-filter> <action android:name="com.videogo.action.OAUTH_SUCCESS_ACTION" /> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver>
一般建议在application中初始化
/** * sdk日志开关,正式发布需要去掉 */ EZOpenSDK.showSDKLog(true); /** * 设置是否支持P2P取流,详见api */ EZOpenSDK.enableP2P(false); /** * APP_KEY请替换成自己申请的 */ EZOpenSDK.initLib(this, APP_KEY);
/** * sdk日志开关,正式发布需要去掉 */ EZGlobalSDK.showSDKLog(true); /** * 设置是否支持P2P取流,详见api */ EZGlobalSDK.enableP2P(false); /** * APP_KEY请替换成自己申请的 */ EZGlobalSDK.initLib(this, APP_KEY);
-dontwarn com.ezviz.player.** -keep class com.ezviz.player.** { *;} -dontwarn com.ezviz.statistics.** -keep class com.ezviz.statistics.** { *;} -dontwarn com.ezviz.stream.** -keep class com.ezviz.stream.** { *;} -dontwarn com.ezviz.hcnetsdk.** -keep class com.ezviz.hcnetsdk.** { *;} -dontwarn com.hik.** -keep class com.hik.** { *;} -dontwarn com.hikvision.** -keep class com.hikvision.** { *;} -dontwarn com.videogo.** -keep class com.videogo.** { *;} -dontwarn org.MediaPlayer.PlayM4.** -keep class org.MediaPlayer.PlayM4.** { *;} -dontwarn com.google.android.gcm.** -keep class com.google.android.gcm.** { *;} -dontwarn org.eclipse.paho.client.mqttv3.** -keep class org.eclipse.paho.client.mqttv3.** { *;} -dontwarn com.google.zxing.** -keep class com.google.zxing.** { *;} #Gson混淆配置 -keepattributes Annotation -keep class sun.misc.Unsafe { *; } -keep class com.idea.fifaalarmclock.entity.* -keep class com.google.gson.stream.* { *; } #引用mars的xlog,混淆配置 -keep class com.tencent.mars.** { public protected private *; }
本文档用于说明萤石开放平台SDK Android版本接口之间的关系以及接口调用顺序,对开放平台SDK Android版本各接口都有详细的说明。
对接主要接口在EZOpenSDK和EZPlayer中,请查看api。
名词 | 释义 |
---|---|
accessToken | 访问令牌,由server返回给client用于认证 |
AppKey | 应用程序key AppKey的申请可以参阅: https://open.ys7.com/view/app/app_edit.html |
deviceSerial | 设备序列号 |
CameraNo | 设备通道号 |
deviceSerial+CameraNo | 摄像头唯一标志 |
OSD | 视频当前时间 |
PTZ | 云台控制,可以通过终端控制操作设备 |
V3.0: 账号对接(授权登录、sdk接口登录)、获取摄像头列表、直播预览、查看回放(SD卡、云存储)、设备添加删除、设备的设置功能(h5)、设备控制接口(云台、镜头画面)、WiFi配置、视频本地录像、视频截屏、报警消息等。
V3.1: 安全验证接口、获取设置设备验证码、数据解密接口等,主要功能是完成UI版本的开源项目。
V4.*: 账号对接(授权登录、sdk接口登录)、获取摄像头列表、直播预览、查看回放(SD卡、云存储)、设备添加删除、设备的设置功能、设备控制接口(云台、镜头画面)、WiFi配置、视频本地录像、视频截屏、报警消息等
第三方服务器通过服务端api接口获取accesstoken和过期时间,accesstoken用来授权,过期时间用来定时刷新accesstoken
第三方服务器将获取到的accesstoken下发到第三方app(需集中EZOpenSDK),第三方app调用EZOpenSDK.getInstance().setAccessToken(String accesstoken),来完成授权
EZOpenSDK会文件缓存accesstoken,下次打开app,初始化时会自动完成授权
退出登录后需要调用EZOpenSDK.getInstance().logout(),或者调用EZOpenSDK.getInstance().setAccessToken(null);
使用 EZGlobalSDK.getInstance().getAreaList()方法获取区域列表,选择当前所在区域areaId通过EZGlobalSDK.getInstance().openLoginPage(String areaId)方法跳转到登录H5页,此页面可以登录萤石账号
登录成功之后会发送广播action为Constant.OAUTH_SUCCESS_ACTION为登录成功,登录成功后,app可以开展自己的业务,以及调用EZGlobalSDK的接口,注意登录成功后EZGlobalSDK自动完成accesstoken设置授权,第三个app无需再设置accesstoken;
EZGlobalSDK会文件缓存accesstoken,下次打开app,初始化时会自动完成授权
目前针对H5页面获取accesstoken授权的,EZGlobalSDK会内部自动刷新accesstoken,不用担心过期或者失效
如果需要获取EZGlobalSDK内部缓存的accesstoken,调用方法EZGlobalSDK.getInstance().getEZAccessToken(),得到EZAccessToken对象,包含accessToken和过去时间,拿accessToken自己去调用萤石api的需要考虑accessToken过期的情况‘’
1.查询设备信息(probeDeviceInfo接口)的所获得对象是EZProbeDeviceInfo,正常查询到设备信息对象说明查询成功,直接可以进行设备添加操作;
2.设备序列号输入正确的情况下报设备不存在的错误是因为全新设备没有注册到平台,直接进行配网流程成功以后就可以查询到设备信息了;
3.probeDeviceInfo主要是根据不同的错误码来处理不同的UI,跟Demo的业务相关性较高;
4.startWifiConfig和stopWifiConfig要成对出现,EZWifiConfigStatus的内容通过回调函数EZOpenSDKListener.EZStartConfigWifiCallback返回的EZConstants.EZWifiConfigStatus 获取的,见快速接入示范和demo。
DEVICE_WIFI_CONNECTED(2), 设备连接WiFi成功 DEVICE_PLATFORM_REGISTED(3);设备注册平台成功
当状态为"PLAT"时方可添加成功。
特别说明: 账户下删除设备重新wifi配置并且添加过程中,请在重置设备等待2分钟以后再调用wifi配置的相关接口可以提高wifi配置的成功率,否则会降低成功率,因为重置设备以后我们平台将在2分钟内得到设备下线的状态,只有平台认为下线了,wifi配置成功率才会高。
注意:DEVICE_WIFI_CONNECTED和DEVICE_PLATFORM_REGISTED状态上报可能会丢失,此时可在适当时机查询设备当前的状态,根据设备状态进行后续操作,详见demo中示例代码。
本节旨在引导开发者进行快速接入,通过介绍几个关键的接口,并给出对应的界面和接口,以及代码范例,让开发者对sdk有个初步了解.
首先请下载并安装萤石云app, 登陆以后,进入的是监控列表界面,如下所示 图中橙色矩形框仅作为标注,并非原生app界面。
new Thread(new Runnable() { @Override public void run() { try { List<EZDeviceInfo> result = null; result = mEZOpenSDK.getDeviceList(0, 10); return result; } catch (BaseException e) { mErrorCode = e.getErrorCode(); return null; } } }).start();
说明
通过调用getDeviceList,可以得到一个列表,列表每一项代表一个设备,每个设备下面又包含多个通道或者探测器。开发者可以通过list adapter将列表展示
代码参考
src\com\videogo\ui\cameralist\EZCameraListActivity.java
说明:
需要添加设备时,可以点击界面1中的加号(+),进入界面2,界面2是一个二维码扫描,用户可以通过扫描二维码获取设备序列号,也可以点击界面右上角的图标(橙色标注),进入界面3,界面3是一个手动输入序列号界面。
界面2(二维码扫描)代码在
src\com\videogo\scan\main\CaptureActivity.java
界面3(手动输入)代码在
src\com\videogo\ui\devicelist\SeriesNumSearchActivity
用户输入设备序列号,只有当设备没有被其他人添加,并且设备已经在线(注册上平台)时,才能够被添加,因此,必须要查询一下该设备状态,调用的接口是probeDeviceInfo
try { mEZProbeDeviceInfo = mEZOpenSDK.probeDeviceInfo(deviceSerial); sendMessage(MSG_QUERY_CAMERA_SUCCESS); LogUtil.infoLog(TAG, "probeDeviceInfo success"); } catch (BaseException e) { sendMessage(MSG_QUERY_CAMERA_FAIL, e.getErrorCode()); LogUtil.infoLog(TAG, " probeDeviceInfo fail :" + e.getErrorCode()); e.printStackTrace(); }
如果该接口返回成功,则说明该设备状态正常,继续调用addDevice接口添加。
try { boolean result = mEZOpenSDK.addDevice(deviceSerial, mVerifyCode); // 添加成功 sendMessage(MSG_ADD_CAMERA_SUCCESS); } catch (BaseException e) { sendMessage(MSG_ADD_CAMERA_FAIL, e.getErrorCode()); LogUtil.errorLog(TAG, "add camera fail"); }
如果该接口返回错误,开发者需要处理以下几个错误码,告诉用户该设备不可添加的原因:
20020 设备在线,已经被自己添加 (给出提示)
20022 设备在线,已经被别的用户添加 (给出提示)
20023 设备不在线,未被用户添加 (这里需要调用wifi一键配置)
20002 设备不存在,未被用户添加 (这里需要调用wifi一键配置)
20024 设备不在线,已经被别的用户添加 (给出提示)
20029 设备不在线,已经被自己添加 (给出提示)
至此,一个简单的设备添加就完成了。
在上述调用接口probeDeviceInfo
过程中,如果返回的错误码是20023或者2002,说明设备还没有联网,这时需要让设备联网,如果是有线设备,需要提示用户插入网线。如果是无线设备,则需要进行wifi配置。
开始一键配置需要调用startConfigWifi接口:
new Thread(new Runnable() { @Override public void run() { EzvizApplication.getOpenSDK().startConfigWifi(AutoWifiConnectingActivity.this, serialNo, wifiSSID, wifiPassword, mEZStartConfigWifiCallback); } }).start();
结束一键配置需要调用stopConfigWiFi接口(需要传入一个回调函数,用于处理事件):
EZOpenSDKListener.EZStartConfigWifiCallback mEZStartConfigWifiCallback = new EZOpenSDKListener.EZStartConfigWifiCallback() { @Override public void onStartConfigWifiCallback(EZConstants.EZWifiConfigStatus status) { if (status == EZConstants.EZWifiConfigStatus.DEVICE_WIFI_CONNECTING) { } else if (status == EZConstants.EZWifiConfigStatus.DEVICE_WIFI_CONNECTED) { if (isWifiConnected) { LogUtil.i(TAG, "defiveFindHandler: receiver WIFI while isWifiConnected is true"); return; } LogUtil.debugLog(TAG, "接收到设备连接上WIFI " + serialNo); isWifiOkBonjourget = true; isWifiConnected = true; t2 = System.currentTimeMillis(); stopWifiConfigOnThread(); changeStatuss(STATUS_REGISTING); } else if (status == EZConstants.EZWifiConfigStatus.DEVICE_PLATFORM_REGISTED) { LogUtil.debugLog(TAG, "接收到设备连接上PLAT信息 " + serialNo); if (isPlatConnected) { LogUtil.i(TAG, "defiveFindHandler: receiver PLAT while isPlatConnected is true"); return; } isPlatBonjourget = true; isPlatConnected = true; t3 = System.currentTimeMillis(); cancelOvertimeTimer(); changeStatuss(STATUS_ADDING_CAMERA); } } };
该回调用于处理WIFI和PLAT事件。
WIFI表示设备已经连上WIFI, PLAT表示设备已经注册上平台。一旦设备注册上平台之后,就可以调用addDevice进行添加
预览视频的代码参见
src\com\videogo\ui\realplay\EZRealPlayActivity.java
if (mCameraInfo != null) { if (mEZPlayer == null) { mEZPlayer = EzvizApplication.getOpenSDK().createPlayer(mCameraInfo.getDeviceSerial(), mCameraInfo.getCameraNo()); } if (mEZPlayer == null) return; if (mDeviceInfo == null) { return; } if (mDeviceInfo.getIsEncrypt() == 1) { mEZPlayer.setPlayVerifyCode(DataManager.getInstance().getDeviceSerialVerifyCode(mCameraInfo.getDeviceSerial())); } mEZPlayer.setHandler(mHandler); mEZPlayer.setSurfaceHold(mRealPlaySh); mEZPlayer.startRealPlay(); }
代码说明:
1、创建EZPlayer对象需要deviceSerial设备序列号以及cameraNo通道号,即摄像头的唯一标识,deviceSerial与cameraNo可从EZCameraInfo对象中获取
2、需要创建一个handler,用于接收播放器消息,比如播放器播放成功,失败等消息
public boolean handleMessage(Message msg) { switch (msg.what) { case EZRealPlayConstants.MSG_REALPLAY_PLAY_SUCCESS: handlePlaySuccess(msg); break; case EZRealPlayConstants.MSG_REALPLAY_PLAY_FAIL: handlePlayFail(msg.arg1, msg.arg2); break; }
3、播放需要一个surfaceView,因此在你的xml layout 文件重要放置一个SurfaceView
<RelativeLayout android:id="@+id/realplay_play_rl" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@color/black_bg" > <SurfaceView android:id="@+id/realplay_sv" android:layout_width="600dp" android:layout_height="200dp" android:layout_alignParentTop="true" android:layout_centerInParent="false" android:background="@android:color/transparent" /> </RelativeLayout>
在surface创建的过程中,保存SurfaceHolder对象:
@Override public void surfaceCreated(SurfaceHolder holder) { if (mEZPlayer != null) { mEZPlayer.setSurfaceHold(holder); } mRealPlaySh = holder; }
4、调用startRealPlay()
整个代码参见
src\com\videogo\ui\realplay\EZRealPlayActivity.java