基于Android的海康威视的二次开发

在最近的项目中使用到了海康监控的使用及简单的控制,经过网上的一番搜查及整合,在使用中我是在同一个局域网实现效果的。

  1. 首先是导入相应的sdk和jar包,网上有很多资源这里就不再讲述了
  2. 导入完包后再build.gradle中添加以下代码进行同步
android{...sourceSets.main {jniLibs.srcDirs = ['libs']}
}
dependencies {...compile files('libs/jna.jar')compile files('libs/AudioEngineSDK.jar')compile files('libs/HCNetSDK.jar')compile files('libs/PlayerSDK.jar')}
  1. 记得在AndroidManifest.xml中添加网络权限等
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!--允许应用程序完全使用网络-->
<uses-permission android:name="android.permission.INTERNET"/>
  1. 设置简单的布局文件activity_sxt.xml,通过控件SurfaceView放置监控内容,这里我用的是悬浮按钮FloatingActionButton进行接下来的控制操作
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"xmlns:fab="http://schemas.android.com/apk/res-auto"><SurfaceViewandroid:id="@+id/video_surfaceview"android:layout_width="match_parent"android:layout_height="250dp"android:layout_alignParentLeft="true" /><com.getbase.floatingactionbutton.FloatingActionsMenuandroid:layout_below="@id/video_surfaceview"android:id="@+id/multiple_actions"android:layout_width="wrap_content"android:layout_height="wrap_content"fab:fab_expandDirection="right"><com.getbase.floatingactionbutton.FloatingActionButtonandroid:id="@+id/action_right"android:layout_width="wrap_content"android:layout_height="wrap_content"fab:fab_size="mini"fab:fab_title="右转"android:background="@mipmap/sx"/><com.getbase.floatingactionbutton.FloatingActionButtonandroid:id="@+id/action_left"android:layout_width="wrap_content"android:layout_height="wrap_content"fab:fab_size="mini"fab:fab_title="左转"/><com.getbase.floatingactionbutton.FloatingActionButtonandroid:id="@+id/action_down"android:layout_width="wrap_content"android:layout_height="wrap_content"fab:fab_size="mini"fab:fab_title="向下" /><com.getbase.floatingactionbutton.FloatingActionButtonandroid:id="@+id/action_up"android:layout_width="wrap_content"android:layout_height="wrap_content"fab:fab_size="mini"fab:fab_title="向上" /></com.getbase.floatingactionbutton.FloatingActionsMenu>
</RelativeLayout>
  1. 添加HikUtil.java文件,在文件中我添加了,向上向下向左向右放大缩小的功能
package com.....haikang.utils;
//新建HikUtil.java文件复制以下内容即可
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import com.hikvision.netsdk.ExceptionCallBack;
import com.hikvision.netsdk.HCNetSDK;
import com.hikvision.netsdk.NET_DVR_DEVICEINFO_V30;
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO;
import com.hikvision.netsdk.PTZCommand;
import com.hikvision.netsdk.RealPlayCallBack;import org.MediaPlayer.PlayM4.Player;import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;/*** Created date: 2017/4/11* Author:  Leslie* 1.HikUtil.initSDK();* 2.HikUtil hikUtil = new HikUtil();* 2.hikUtil.initView(surfaceView);* 3.hikUtil.setDeviceData("192.168.1.22",8000,"admin","eyecool2016");* 4.hikUtil.loginDevice(mHandler,LOGIN_SUCCESS_CODE);* 5.hikUtil.playOrStopStream();*/public class HikUtil {private static final String TAG = "HikUtil";private static final int HIK_MAIN_STREAM_CODE = 0;      //主码流private static final int HIK_SUB_STREAM_CODE = 1;      //子码流private NET_DVR_DEVICEINFO_V30 m_oNetDvrDeviceInfoV30 = null;private static int m_iStartChan = 0;private  int m_iPort = -1;private  int m_iPlaybackID = -1;private static int logId = -1;private  int playId = -1;private SurfaceView mSurfaceView;private TextureView mtextureView;public String mIpAddress;private  int mPort;private String mUserName;private String mPassWord;public  onPicCapturedListener mPicCapturedListener;private SimpleDateFormat sDateFormat;private  Player.MPInteger stWidth;private  Player.MPInteger stHeight;private  Player.MPInteger stSize;/*** 定义接口,用于监听图片截图成功*/public interface onPicCapturedListener {void onPicCaptured(Bitmap bitmap, String bitmapFileAbsolutePath);void onPicDataSaved(byte[] picData);}public HikUtil() {}/*** 初始化HCNet SDK** @return*/public static boolean initSDK() {if (!HCNetSDK.getInstance().NET_DVR_Init()) {Log.e(TAG, "HCNetSDK ---------初始化失败!");return false;}//打印日志到本地,暂时不用打印
//        HCNetSDK.getInstance().NET_DVR_SetLogToFile(3, "/mnt/sdcard/sdklog/", true);return true;}/*** 停止播放*/public synchronized void stopPlay() {if (playId < 0) {Log.d(TAG, "已经停止?");return;}// 停止网络播放if (HCNetSDK.getInstance().NET_DVR_StopRealPlay(playId)) {Log.i(TAG, "停止实时播放成功!");} else {Log.e(TAG, "停止实时播放失败!" );return;}// 停止本地播放if (Player.getInstance().stop(m_iPort)) {Log.i(TAG, "停止本地播放成功!");} else {Log.e(TAG, "停止本地播放失败!");return;}// 关闭视频流if (Player.getInstance().closeStream(m_iPort)) {Log.i(TAG, "关闭视频流成功!");} else {Log.e(TAG, "关闭视频流失败!");return;}// 释放播放端口if (Player.getInstance().freePort(m_iPort)) {Log.i(TAG, "释放播放端口成功!");} else {Log.e(TAG, "释放播放端口失败!");return;}// 播放端口复位m_iPort = -1;// 正在播放标记复位playId = -1;Log.i(TAG, "停止播放成功!");}/*** 登出设备*/public void logoutDevice() {//        if (HCNetSDK.getInstance().NET_DVR_Logout_V30(logId)) {//            playId = -1;
//            Log.i(TAG, "登出设备成功!");
//        } else {//            playId = 0;
//            Log.e(TAG, "登出设备失败!");
//        }// 是否登出if (!HCNetSDK.getInstance().NET_DVR_Logout_V30(logId)) {Log.e(TAG, " 用户注销失败!");}else {Log.e(TAG,"用户注销成功!");}logId = -1;}/*** 释放海康SDK*/public void freeSDK() {// 清理缓存if (HCNetSDK.getInstance().NET_DVR_Cleanup()) {Log.i(TAG, "释放SDK资源成功!");} else {Log.e(TAG, "释放SDK资源失败!");}}//控制台操作public static void startup(){if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(logId, m_iStartChan, PTZCommand.TILT_UP, 0)) {Log.e(TAG,"start PAN_LEFT failed with error code: "+ HCNetSDK.getInstance().NET_DVR_GetLastError());} else {Log.i(TAG, "start TILT_UP succ");}}public static void stopup(){if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(logId, m_iStartChan, PTZCommand.TILT_UP, 1)) {Log.e(TAG,"start PAN_LEFT failed with error code: "+ HCNetSDK.getInstance().NET_DVR_GetLastError());} else {Log.i(TAG, "stop TILT_UP succ");}}public static void startdown(){if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(logId, m_iStartChan, PTZCommand.TILT_DOWN, 0)) {Log.e(TAG,"start PAN_LEFT failed with error code: "+ HCNetSDK.getInstance().NET_DVR_GetLastError());} else {Log.i(TAG, "start TILT_DOWN succ");}}public static void stopdown(){if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(logId, m_iStartChan, PTZCommand.TILT_DOWN, 1)) {Log.e(TAG,"start PAN_LEFT failed with error code: "+ HCNetSDK.getInstance().NET_DVR_GetLastError());} else {Log.i(TAG, "stop TILT_DOWN succ");}}public static void startleft(){if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(logId, m_iStartChan, PTZCommand.PAN_LEFT, 0)) {Log.e(TAG,"start PAN_LEFT failed with error code: "+ HCNetSDK.getInstance().NET_DVR_GetLastError());} else {Log.i(TAG, "start PAN_LEFT succ");}}public static void stopleft(){if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(logId, m_iStartChan, PTZCommand.PAN_LEFT, 1)) {Log.e(TAG,"start PAN_LEFT failed with error code: "+ HCNetSDK.getInstance().NET_DVR_GetLastError());} else {Log.i(TAG, "stop PAN_LEFT succ");}}public static void startright(){if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(logId, m_iStartChan, PTZCommand.PAN_RIGHT, 0)) {Log.e(TAG,"start PAN_LEFT failed with error code: "+ HCNetSDK.getInstance().NET_DVR_GetLastError());} else {Log.i(TAG, "start PAN_RIGHT succ");}}public static void stopright(){if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(logId, m_iStartChan, PTZCommand.PAN_RIGHT, 1)) {Log.e(TAG,"start PAN_LEFT failed with error code: "+ HCNetSDK.getInstance().NET_DVR_GetLastError());} else {Log.i(TAG, "stop PAN_RIGHT succ");}}public static void startfd(){if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(logId, m_iStartChan, PTZCommand.ZOOM_IN, 0)) {Log.e(TAG,"start PAN_LEFT failed with error code: "+ HCNetSDK.getInstance().NET_DVR_GetLastError());} else {Log.i(TAG, "start ZOOM_IN succ");}}public static void stopfd(){if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(logId, m_iStartChan, PTZCommand.ZOOM_IN, 1)) {Log.e(TAG,"start PAN_LEFT failed with error code: "+ HCNetSDK.getInstance().NET_DVR_GetLastError());} else {Log.i(TAG, "stop ZOOM_IN succ");}}public static void startsx(){if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(logId, m_iStartChan, PTZCommand.ZOOM_OUT   , 0)) {Log.e(TAG,"start PAN_LEFT failed with error code: "+ HCNetSDK.getInstance().NET_DVR_GetLastError());} else {Log.i(TAG, "start ZOOM_OUT succ");}}public static void stopsx(){if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(logId, m_iStartChan, PTZCommand.ZOOM_OUT   , 1)) {Log.e(TAG,"start PAN_LEFT failed with error code: "+ HCNetSDK.getInstance().NET_DVR_GetLastError());} else {Log.i(TAG, "stop ZOOM_OUT succ");}}public  void initView(SurfaceView surfaceView) {mSurfaceView = surfaceView;mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {@Overridepublic void surfaceCreated(SurfaceHolder holder) {mSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);Log.i(TAG, "surface is created" + m_iPort);if (-1 == m_iPort) {return;}Surface surface = holder.getSurface();if (surface.isValid()) {if (!Player.getInstance().setVideoWindow(m_iPort, 0, holder)) {Log.e(TAG, "播放器设置或销毁显示区域失败!");}else {Log.e(TAG, "播放器设置或销毁显示区域成功!");}}}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {Log.i(TAG, "Player setVideoWindow release!" + m_iPort);if (-1 == m_iPort) {return;}if (holder.getSurface().isValid()) {if (!Player.getInstance().setVideoWindow(m_iPort, 0, null)) {Log.e(TAG, "播放器设置或销毁显示区域失败!");}}}});}/*** 配置网络摄像头参数* @param ipAddress IP 地址* @param port 端口号,默认是 8000* @param userName 用户名* @param passWord 密码*/public  void setDeviceData(String ipAddress, int port, String userName, String passWord) {mIpAddress = ipAddress;mPort = port;mUserName = userName;mPassWord = passWord;}public  void loginDevice(final Handler handler, final int resultCode) {new Thread(new Runnable() {@Overridepublic void run() {boolean loginState = login(mIpAddress, mPort, mUserName, mPassWord);Message message = handler.obtainMessage();message.obj = loginState;message.what = resultCode;handler.sendMessage(message);}}).start();}/*** 播放或者停止播放视频流*/public  void playOrStopStream() {if (logId < 0) {Log.e(TAG, "请先登录设备");return;}if (playId < 0) {   //播放RealPlayCallBack fRealDataCallBack = getRealPlayerCbf();if (fRealDataCallBack == null) {Log.e(TAG, "fRealDataCallBack object is failed!");return;}Log.i(TAG, "m_iStartChan:" + m_iStartChan);NET_DVR_PREVIEWINFO previewInfo = new NET_DVR_PREVIEWINFO();previewInfo.lChannel = m_iStartChan;previewInfo.dwStreamType = HIK_SUB_STREAM_CODE;                                                             //子码流previewInfo.bBlocked = 1;// HCNetSDK start previewplayId = HCNetSDK.getInstance().NET_DVR_RealPlay_V40(logId, previewInfo, fRealDataCallBack);if (playId < 0) {Log.e(TAG, "实时预览失败!-----------------Err:" + HCNetSDK.getInstance().NET_DVR_GetLastError());return;}Log.i(TAG, "NetSdk 播放成功 !");
//            mPlayButton.setText("停止");} else {    //停止播放if (playId < 0) {Log.e(TAG, "m_iPlayID < 0");return;}//  net sdk stop previewif (!HCNetSDK.getInstance().NET_DVR_StopRealPlay(playId)) {Log.e(TAG, "停止预览失败!----------------错误:" + HCNetSDK.getInstance().NET_DVR_GetLastError());return;}playId = -1;Player.getInstance().stopSound();// player stop playif (!Player.getInstance().stop(m_iPort)) {Log.e(TAG, "-------------------暂停失败!");return;}else {Log.e(TAG, "-------------------暂停成功!");}if (!Player.getInstance().closeStream(m_iPort)) {Log.e(TAG, "-------------------关流失败!");return;}if (!Player.getInstance().freePort(m_iPort)) {Log.e(TAG, "-------------------释放播放端口失败!" + m_iPort);return;}m_iPort = -1;logId = -1;playId = -1;
//            mPlayButton.setText("播放");}}private RealPlayCallBack getRealPlayerCbf() {RealPlayCallBack cbf = new RealPlayCallBack() {public void fRealDataCallBack(int iRealHandle, int iDataType, byte[] pDataBuffer, int iDataSize) {// 播放通道1processRealData(1, iDataType, pDataBuffer, iDataSize, Player.STREAM_REALTIME);}};return cbf;}public  void processRealData(int iPlayViewNo, int iDataType, byte[] pDataBuffer, int iDataSize, int iStreamMode) {if (HCNetSDK.NET_DVR_SYSHEAD == iDataType) {if (m_iPort >= 0) {return;}m_iPort = Player.getInstance().getPort();if (m_iPort == -1) {Log.e(TAG, "获取端口失败!: " + Player.getInstance().getLastError(m_iPort));return;}Log.i(TAG, "获取端口成功!: " + m_iPort);if (iDataSize > 0) {if (!Player.getInstance().setStreamOpenMode(m_iPort, iStreamMode))  //set stream mode{Log.e(TAG, "设置流播放模式失败!");return;}if (!Player.getInstance().openStream(m_iPort, pDataBuffer, iDataSize, 2 * 1024 * 1024)) //open stream{Log.e(TAG, "打开流失败!");return;}if (!Player.getInstance().play(m_iPort, mSurfaceView.getHolder())) {Log.e(TAG, "播放失败!");return;}if (!Player.getInstance().playSound(m_iPort)) {Log.e(TAG, "以独占方式播放音频失败!失败码 :" + Player.getInstance().getLastError(m_iPort));return;}}} else {if (!Player.getInstance().inputData(m_iPort, pDataBuffer, iDataSize)) {//                  Log.e(TAG, "inputData failed with: " + Player.getInstance().getLastError(m_iPort));for (int i = 0; i < 4000 && m_iPlaybackID >= 0; i++) {if (!Player.getInstance().inputData(m_iPort, pDataBuffer, iDataSize))Log.e(TAG, "输入流数据失败: " + Player.getInstance().getLastError(m_iPort));elsebreak;try {Thread.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}}private  boolean login(String ipAddress, int portNum, String userName, String passWord) {try {if (logId < 0) {// 登录设备logId = loginDevice(ipAddress, portNum, userName, passWord);if (logId < 0) {Log.e(TAG, "设备登录失败!");return false;}// 获取异常回调和异常设置的回调ExceptionCallBack oexceptionCbf = getExceptiongCbf();if (oexceptionCbf == null) {Log.e(TAG, "异常回调对象失败!");return false;}if (!HCNetSDK.getInstance().NET_DVR_SetExceptionCallBack(oexceptionCbf)) {Log.e(TAG, "注册接收异常、重连消息回调函数失败 !");return false;}//                loginButton.setText("注销");Log.i(TAG, "登录成功 !");return true;} else {// 是否登出if (!HCNetSDK.getInstance().NET_DVR_Logout_V30(logId)) {Log.e(TAG, " 用户注销失败!");return false;}else {Log.e(TAG,"用户注销成功!");}
//                loginButton.setText("登录");logId = -1;return true;}} catch (Exception err) {Log.e(TAG, "错误: " + err.toString());return false;}}private  int loginDevice(String ipAddress, int portNum, String userName, String passWord) {//实例化设备信息对象m_oNetDvrDeviceInfoV30 = new NET_DVR_DEVICEINFO_V30();if (null == m_oNetDvrDeviceInfoV30) {Log.e(TAG, "实例化设备信息(NET_DVR_DEVICEINFO_V30)失败!");return -1;}// call NET_DVR_Login_v30 to login on, port 8000 as defaultint iLogID = HCNetSDK.getInstance().NET_DVR_Login_V30(ipAddress, portNum, userName, passWord, m_oNetDvrDeviceInfoV30);if (iLogID < 0) {Log.e(TAG, "网络设备登录失败!-------------Err:" + HCNetSDK.getInstance().NET_DVR_GetLastError());return -1;}if (m_oNetDvrDeviceInfoV30.byChanNum > 0) {m_iStartChan = m_oNetDvrDeviceInfoV30.byStartChan;} else if (m_oNetDvrDeviceInfoV30.byIPChanNum > 0) {m_iStartChan = m_oNetDvrDeviceInfoV30.byStartDChan;}Log.i(TAG, "网络设备登录成功!");return iLogID;}private ExceptionCallBack getExceptiongCbf() {ExceptionCallBack oExceptionCbf = new ExceptionCallBack() {public void fExceptionCallBack(int iType, int iUserID, int iHandle) {System.out.println("recv exception------------------------------, type:" + iType);}};return oExceptionCbf;}/*** 截取一帧图片,成功返回bitmap对象,失败返回null* 经测试得出:* 获取截图数据耗时 <10ms* 获取截图数据后保存到磁盘耗时 ≈25ms* 从获取截图数-保存到磁盘-解码文件到 bitmap 耗时 ≈45ms*/public Bitmap captureFrame(onPicCapturedListener picCapturedListener) {try {long time1 = System.currentTimeMillis();mPicCapturedListener = picCapturedListener;Player.MPInteger stWidth = new Player.MPInteger();Player.MPInteger stHeight = new Player.MPInteger();if (!Player.getInstance().getPictureSize(m_iPort, stWidth, stHeight)) {Log.e(TAG, "获取图片尺寸失败---> error code:" + Player.getInstance().getLastError(m_iPort));return null;}int nSize = 5 * stWidth.value * stHeight.value;byte[] picBuf = new byte[nSize];Player.MPInteger stSize = new Player.MPInteger();if (!Player.getInstance().getBMP(m_iPort, picBuf, nSize, stSize)) {Log.e(TAG, "获取位图失败----> error code:" + Player.getInstance().getLastError(m_iPort));return null;}long time2 = System.currentTimeMillis();if (sDateFormat == null) {sDateFormat = new SimpleDateFormat("yyyy-MM-dd-hh_mm_ss_Sss");}String date = sDateFormat.format(new java.util.Date());File dir = new File(Environment.getExternalStorageDirectory() + "/capture");if (!dir.exists()) {dir.mkdir();}File file = new File(dir, date + ".jpg");FileOutputStream fos = new FileOutputStream(file);fos.write(picBuf, 0, stSize.value);fos.close();long time3 = System.currentTimeMillis();Bitmap bitmap = BitmapFactory.decodeFile(dir.getAbsolutePath() + "/" + date + ".jpg");long time4 = System.currentTimeMillis();//图片保存成功了,通知给外面mPicCapturedListener.onPicCaptured(bitmap, file.getAbsolutePath());return bitmap;} catch (Exception err) {Log.e(TAG, "error: " + err.toString());} finally {return null;}}/*** 截取一帧图片,成功返回bitmap对象,失败返回null* 图片数据存放在内存中*/public  byte[] captureFrameOnMemroy(onPicCapturedListener picCapturedListener, Handler handler) {try {long start = System.currentTimeMillis();mPicCapturedListener = picCapturedListener;if (stWidth == null) {stWidth = new Player.MPInteger();}if (stHeight == null) {stHeight = new Player.MPInteger();}if (!Player.getInstance().getPictureSize(m_iPort, stWidth, stHeight)) {Log.e(TAG, "获取图片尺寸失败---> error code:" + Player.getInstance().getLastError(m_iPort));return null;}int nSize = 5 * stWidth.value * stHeight.value;byte[] picBuf = new byte[nSize];if (stSize == null) {stSize = new Player.MPInteger();}if (!Player.getInstance().getBMP(m_iPort, picBuf, nSize, stSize)) {//                mPicCapturedListener.onPicDataSavedError();Log.e(TAG, "获取位图失败----> error code:" + Player.getInstance().getLastError(m_iPort));return null;}//图片保存数据获取成功了,通知给外面。或者用handler发送出去/* mPicCapturedListener.onPicDataSaved(picBuf);Message message = handler.obtainMessage();message.obj = picBuf;message.what = Constant.VIDEO_FRAME_PIC_DATA_SAVED;handler.sendMessage(message);long end = System.currentTimeMillis();*/return picBuf;} catch (Exception err) {Log.e(TAG, "error: " + err.toString());}return null;}
}
  1. 接下来就是设置连接摄像头进行登录播放操作,连接摄像头需要的参数包括IP,账号,密码,端口信息(我这里用的端口信息是8000)
public class sxt extends Activity{private static final String TAG = "sxt";//----------------------------------------------------------------------------------------------SurfaceView video_surfaceview;//----------------------------------------------------------------------------------------------private static final int PLAY_HIK_STREAM_CODE = 1001;private static final int PLAY_HIK_STREAM_CODE_2 = 1002;private  String IP_ADDRESS ="设置自己摄像头的ip地址";private static final int PORT = 8000;private static final String USER_NAME = "用户名";private static final String PASSWORD = "密码";//----------------------------------------------------------------------------------------------private Handler mHandler = new Handler(new Handler.Callback() {@Overridepublic boolean handleMessage(Message msg) {switch (msg.what) {case PLAY_HIK_STREAM_CODE:hikUtil.playOrStopStream();break;case PLAY_HIK_STREAM_CODE_2:hikUtil2.playOrStopStream();break;default:break;}return false;}});private HikUtil hikUtil;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_sxt);video_surfaceview = findViewById(R.id.video_surfaceview); /*设置三个悬浮按钮的监听事件*///摄像头向上转动final FloatingActionButton actionA = (FloatingActionButton) findViewById(R.id.action_up);actionA.setOnTouchListener(new View.OnTouchListener() {//由于调用向左转动的方法,会停不下来,所以这里我加了监听点击按键不放即调用启动向左转动方法,松开按键即调用停止向左转动的方法public boolean onTouch(View v, MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {HikUtil.startup();}else if (event.getAction() == MotionEvent.ACTION_UP) {HikUtil.stopup();}return false;}});//摄像头向下转动final FloatingActionButton actionB = (FloatingActionButton) findViewById(R.id.action_down);actionB.setOnTouchListener(new View.OnTouchListener() {public boolean onTouch(View v, MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {HikUtil.startdown();}else if (event.getAction() == MotionEvent.ACTION_UP) {HikUtil.stopdown();}return false;}});//左转final FloatingActionButton actionC = (FloatingActionButton) findViewById(R.id.action_left);actionC.setOnTouchListener(new View.OnTouchListener() {public boolean onTouch(View v, MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {HikUtil.startleft();}else if (event.getAction() == MotionEvent.ACTION_UP) {HikUtil.stopleft();}return false;}});//右转final FloatingActionButton actionD = (FloatingActionButton) findViewById(R.id.action_right);actionD.setOnTouchListener(new View.OnTouchListener() {public boolean onTouch(View v, MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {HikUtil.startright();}else if (event.getAction() == MotionEvent.ACTION_UP) {HikUtil.stopright();}return false;}});HikUtil.initSDK();hikUtil = new HikUtil();hikUtil.initView(video_surfaceview);hikUtil.setDeviceData(IP_ADDRESS, PORT, USER_NAME, PASSWORD);//登录设备hikUtil.loginDevice(mHandler, PLAY_HIK_STREAM_CODE);//播放设备hikUtil.playOrStopStream();}
}
  1. 到此为止即可正常调用摄像头,但是有些项目会遇到只有一个SurfaceView控件进行切换摄像头的操作,切换摄像头就是通过改变之前提到的四个参数来调用其他的摄像头,重点来了,再改变参数之前需要释放掉在原控件中的sdk资源,只需要调用以下方法,再使用步骤七中的登录方法即可
 //停止播放hikUtil.stopPlay();//注销设备hikUtil.logoutDevice();//释放sdk资源hikUtil.freeSDK();

希望对大家有所帮助,如有疑问欢迎在评论区留言。

基于Android的海康威视的二次开发相关推荐

  1. 基于Android的聊天网络应用(安卓开发实验报告)

    ** 安卓开发实验及其报告(基于Android的聊天网络应用) ** 实验一 手机联系人管理 教学目标 了解安卓手机联系人的数据库:掌握安卓手机联系人信息的读取.添加.删除. 教学内容 手机通讯录管理 ...

  2. 开篇--基于Android的小巫新闻客户端开发

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 开篇-- ...

  3. 项目总结25:海康威视SDK-Java二次开发-客流量分析

    项目总结25:海康威视SDK-Java二次开发-客流量分析 前言 本来一个很简单的SDK接口对接,折腾了好久:总结下原因有: 海康的SDK底层使用C++写的,我不熟悉C++: 海康Java源码示例写的 ...

  4. 海康威视SDK二次开发通过云台参数设置控制摄像机的位置

    海康威视SDK二次开发通过云台参数设置控制摄像机的位置 由于最近在开发海康威视摄像头,特此记录一下通过云台参数控制摄像机的位置,我这里是通过properties配置文件输入的参数,也可以不用配置文件, ...

  5. Python基于周立功盒子的二次开发的封装和调用

    Python基于周立功盒子的二次开发的封装和调用 一.介绍     前面我们介绍如何拿到官网给的例程并使用起来,但在使用的过程中,我们发现官网给的例子非常的冗长,可读性不好,于是我进行分解和封装,使得 ...

  6. 基于百度编辑器Ueditor的二次开发

    基于百度编辑器Ueditor的二次开发 官网下载 基本配置 简化后端配置,不请求后端配置项 后端接口规范 修改图片上传 说明及修改 新增按钮及弹窗(自定义附件上传) 按钮文案修改 在业务开发的时候,曾 ...

  7. 基于Qt大恒工业相机二次开发demo-C++

    目录 1.新建工程 2.文件及属性配置 2.1文件拷贝 2.2VS项目属性配置 2.2.1包含目录和库目录添加 2.2.2附加依赖项添加 3.添加基于官方mfc代码改写的CGXBitmap类 3.1添 ...

  8. 基于屌丝青年网样式二次开发的WordPress主题:LIiu-One主题

    源码下载:基于屌丝青年网样式二次开发的WordPress主题:LIiu-One主题-小程序文档类资源-CSDN下载 wordpress主题,基于屌丝青年网样式二次开发LIiu-One主题仿屌丝青年网模 ...

  9. android音乐播放器ppt,基于Android音乐播放器设计与开发.ppt

    基于Android音乐播放器设计与开发 毕业设计 基于Android的音乐播放器 设计与开发 设计概述 研究背景 研究意义 研究目标 系统演示 研究背景 随着Android智能手机的普及,用户越来越能 ...

  10. 基于康耐视cognexVisionpro用C#二次开发的多相机视觉对位框架

    基于康耐视cognexVisionpro用C#二次开发的多相机视觉对位框架 支持1:多相机对位逻辑运算,旋转标定坐标关联运算(可供参考学习)可以协助理解做对位贴合项目思路. 支持2:直接连接运动控制卡 ...

最新文章

  1. .net3.5的安装与修复
  2. 软件的一切关乎成本,以消亡为结束
  3. R安德森-达令检验( Anderson-Darling Test)
  4. 【ABAP】SAP供应商自定义决裁生成实现
  5. 几种常用控件的使用方法
  6. Intellj Idea 如何设置类头注释和方法注释
  7. 烧光86亿元,还是没造出来车!拜腾“造车梦”断?
  8. Linux中安装oracle
  9. Linux 的软件管理及配置 - 安装、卸载、升级、依赖
  10. java入门之内部类
  11. exp参数feedback_Oracle数据库逻辑增量备份恢复之exp/imp参数inctype
  12. Win1909+vs2019+Windows 10 WDK 2004(10.0.19041.1) + Windows 10 SDK 2004(10.0.19041.1)环境搭建
  13. 微搭低代码中实现数据的联动选择
  14. 数学之美——google大脑和人工神经网络
  15. 图的广度和深度优先路径搜索算法(python实现)
  16. webstorm的 快捷键(Keymap)
  17. SQL Server Note [vaynexiao]
  18. 卡车智能驾驶进入“后法规”时代
  19. 网络工程数据通信课程设计之--校园小型网络规划与设计
  20. SpringBoot_liquibase使用

热门文章

  1. excel服务器模板修改,勤哲Excel服务器设计查询模板
  2. 如何下载csdn的文章并保存成pdf格式呢?并实现某个博主的全部博文下载?
  3. 3套看漫画学python视频教程
  4. 社工库源码mysql_体验盒子:社工库源码大全(持续更新)
  5. Unity简单实现调用电脑打印机打印图片功能
  6. wsdl2java 参数_wsdl2java参数详解
  7. java wsdl 服务端代码_wsdl2java 生成 webservice服务端代码:
  8. 油猴脚本(Tampermonkey)的安装和使用小结
  9. java编程手册_Java编程手册
  10. 数字电子技术基础-阎石老师版本-学习记录