onvif在android上实现局域网搜索得到当前编码配置
来源:互联网 发布:网络架构师考试 编辑:程序博客网 时间:2024/04/28 08:48
关于onvif在Android上实现,与IPC之间的通讯
实现局域网下搜索IPC,显示修改编码配置,显示修改网络配置
直接上代码
首先,要写一个server,并在放listview的页面监听
写server所需一下几步
创建CamCameraDevice.java
interface OnSoapDoneListener { void onSoapDone(CameraDevice device, boolean success);}public class CameraDevice implements IPCam { public UUID uuid; public String serviceURL; private int id; private String name; private String ipAddr; private boolean isOnline = false; private String rtspUri = ""; private FFmpegFrameGrabber mGrabber; private SurfaceView mSurfaceView; private OnSoapDoneListener mListener; public int width; public int height; public int rate; public String username; public String password; public CameraDevice(UUID uuid, String serviceURL) { this.uuid = uuid; this.serviceURL = serviceURL; } public void setSecurity(String username, String password) { this.username = username; this.password = password; } public void setProperties(int width, int height, int rate) { this.width = width; this.height = height; this.rate = rate; } public void setId(int id) { this.id = id; } public void setIpAddr(String ipAddr) { this.ipAddr = ipAddr; } public void setOnline(boolean isOnline) { this.isOnline = isOnline; } @Override public void IPCamInit() { if (this.isOnline) { HttpSoap soap = new HttpSoap(this); soap.setOnHttpSoapListener(listener); soap.start(); } } public void setOnSoapDoneListener(OnSoapDoneListener listener) { mListener = listener; } private OnHttpSoapListener listener = new OnHttpSoapListener() { @Override public void OnHttpSoapDone(CameraDevice camera, String uri, boolean success) { if (success) { rtspUri = uri.substring(0, uri.indexOf("//") + 2) + camera.username + ":" + camera.password + "@" + uri.substring(uri.indexOf("//") + 2); mGrabber = new FFmpegFrameGrabber(rtspUri); mGrabber.setImageWidth(width); mGrabber.setImageHeight(height); try { mGrabber.start(); } catch (Exception e) { e.printStackTrace(); } } if (mListener != null) { mListener.onSoapDone(CameraDevice.this, success); } } }; @Override public int getId() { return this.id; } @Override public String getName() { return this.name; } @Override public String getIpAddress() { return this.ipAddr; } @Override public boolean isOnline() { return this.isOnline; } @Override public void setSurfaceView(SurfaceView surfaceView) { // TODO what to do ? mSurfaceView = surfaceView; } @Override public IplImage grab() { if (mGrabber != null) { try { return mGrabber.grab(); } catch (Exception e) { e.printStackTrace(); return null; } } else { return null; } } @Override public void IPCamRelease() { try { mGrabber.stop(); } catch (Exception e) { e.printStackTrace(); } }}
创建CameraFinder.java
interface OnCameraFinderListener { public void OnCameraListUpdated();}public class CameraFinder{ public static final String DISCOVERY_PROBE_TDS = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Envelope xmlns:tds=\"http://www.onvif.org/ver10/device/wsdl\" xmlns=\"http://www.w3.org/2003/05/soap-envelope\"><Header><wsa:MessageID xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">uuid:5101931c-dd3e-4f14-a8aa-c46144af3433</wsa:MessageID><wsa:To xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">urn:schemas-xmlsoap-org:ws:2005:04:discovery</wsa:To><wsa:Action xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</wsa:Action></Header><Body><Probe xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\"><Types>dn:NetworkVideoTransmitter</Types><Scopes /></Probe></Body></Envelope>"; public static final int BROADCAST_SERVER_PORT = 3702; public static final String TAG = "CameraFinder"; private DatagramSocket mSocket; private DatagramPacket mPacket; private Context mContext; private boolean mIsSearching = false; private OnCameraFinderListener mListener; private List<CameraDevice> mCameraList; public CameraFinder(Context context) { mContext = context; mCameraList = new ArrayList<CameraDevice>(); new Thread(mSearchingRunnable).start(); } public List<CameraDevice> getCameraList() { return mCameraList; } public void setOnCameraFinderListener(OnCameraFinderListener onCameraFinderListener) { mListener = onCameraFinderListener; } private Runnable mSearchingRunnable = new Runnable() { @Override public void run() { initSocket(); sendProbe(); mIsSearching = true; byte[] Buff = new byte[4096]; DatagramPacket packet = new DatagramPacket(Buff, Buff.length); while (mIsSearching) { try { mSocket.receive(packet); if (packet.getLength() > 0) { String strPacket = new String(packet.getData(), 0, packet.getLength()); Log.v("ws-discovery", " receive packets:" + strPacket ); processReceivedPacket(strPacket); } } catch (InterruptedIOException e) { Log.d(TAG, "receive timeout!!"); } catch (IOException e) { e.printStackTrace(); break; } } mSocket.close(); } }; private String getMid(String src, String head, String foot) { int headIndex = src.indexOf(head); if (headIndex == -1) { return null; } String tmp = src.substring(headIndex + head.length()); int footIndex = tmp.indexOf(foot); if (footIndex == -1) { return null; } return tmp.substring(0, footIndex); } private void processReceivedPacket(String packet) { try { String uuid = getMid(packet, "Address>", "<").split(":")[2]; String url = getMid(packet, "XAddrs>", "<").split(" ")[0]; if (uuid != null && url != null) { UUID myUUID = UUID.fromString(uuid); if (!isUuidExistInCameraList(myUUID)) { CameraDevice cd = new CameraDevice( UUID.fromString(uuid), url); cd.setOnline(true); mCameraList.add(cd); if (mListener != null) { mListener.OnCameraListUpdated(); } } } } catch (Exception e) { } } private boolean isUuidExistInCameraList(UUID uuid) { boolean result = false; for (CameraDevice device : mCameraList) { if (device.uuid.equals(uuid)) { result = true; } } return result; } public String getLocalIpAddress() { try { for (Enumeration<NetworkInterface> en = NetworkInterface .getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf .getInetAddresses(); enumIpAddr.hasMoreElements();) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress()) { return inetAddress.getHostAddress().toString(); } } } } catch (SocketException ex) { } return null; } public static String getBroadcast() throws SocketException { System.setProperty("java.net.preferIPv4Stack", "true"); for (Enumeration<NetworkInterface> niEnum = NetworkInterface .getNetworkInterfaces(); niEnum.hasMoreElements();) { NetworkInterface ni = niEnum.nextElement(); if (!ni.isLoopback()) { for (InterfaceAddress interfaceAddress : ni .getInterfaceAddresses()) { if (interfaceAddress.getBroadcast() != null) { return interfaceAddress.getBroadcast().toString() .substring(1); } } } } return null; } private void initSocket() { try { mSocket = new DatagramSocket(); mSocket.setBroadcast(true); mSocket.setSoTimeout(10000); } catch (SocketException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void sendProbe() { new Thread(new Runnable() { @Override public void run() { mCameraList.clear(); if (mListener != null) { mListener.OnCameraListUpdated(); } byte[] buf = DISCOVERY_PROBE_TDS.getBytes(); try { String strBroadcast = getBroadcast(); if (strBroadcast == null) { throw new IOException("Broadcast is null"); } Log.d("ws-discovery", "Broadcast to:" + strBroadcast); mPacket = new DatagramPacket(buf, buf.length, InetAddress.getByName(strBroadcast), BROADCAST_SERVER_PORT); mSocket.send(mPacket); Log.d(TAG, "send probe!"); } catch (IOException e) { Log.e(TAG, "Exception sending broadcast probe", e); return; } } }).start(); }}
创建CameraService.java
public class CameraService extends Service { private CameraFinder mFinder; private CameraBinder mBinder = new CameraBinder(); private Database mDb; private List<CameraDevice> mDevices; public CameraFinder getFinder() { return mFinder; } public class CameraBinder extends Binder { public CameraService getService() { return CameraService.this; } } public void sendBroadcast() { if (mFinder != null) { mFinder.sendProbe(); } } public Database getDb() { return mDb; } public List<CameraDevice> getDevices() { return mDevices; } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub mDb = new Database(getApplicationContext()); mDevices = mDb.getCameraDevices(); return mBinder; } @Override public void onCreate() { mFinder = new CameraFinder(getApplicationContext()); mFinder.setOnCameraFinderListener(finderListener); super.onCreate(); } private OnCameraFinderListener finderListener = new OnCameraFinderListener() { @Override public void OnCameraListUpdated() { if (mDevices != null && mDevices.size() > 0) { for (CameraDevice cd1 : mDevices) { for (CameraDevice cd2 : mFinder.getCameraList()) { if (cd1.uuid.equals(cd2.uuid)) { cd1.setOnline(true); break; } } } } } }; @Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); System.out.println("关闭mserver"); }}
创建Database.java
public class Database { public static final String DATABASE_NAME = "xmic.tvonvif.db"; public static final String T_TABLE = "t_onvif_cameras"; public static final String C_USERNAME = "username"; public static final String C_PASSWORD = "password"; public static final String C_NAME = "name"; public static final String C_WIDTH = "width"; public static final String C_HEIGHT = "height"; public static final String C_UUID = "UUID"; public static final String C_RATE = "rate"; private SQLiteDatabase mDbRead, mDbWrite; private DatabaseHelper mDh; public Database(Context context) { mDh = new DatabaseHelper(context, DATABASE_NAME); mDbRead = mDh.getReadableDatabase(); mDbWrite = mDh.getWritableDatabase(); } public boolean addCamera(CameraDevice cd) { if (this.getCameraByUUID(cd.uuid) != null) { return false; } else { ContentValues cv = new ContentValues(); cv.put(C_HEIGHT, cd.height); cv.put(C_WIDTH, cd.width); cv.put(C_RATE, cd.rate); cv.put(C_UUID, cd.uuid.toString()); cv.put(C_USERNAME, cd.username); cv.put(C_PASSWORD, cd.password); cd.setId((int)mDbWrite.insert(T_TABLE, null, cv)); return true; } } public boolean deleteCamera(CameraDevice cd) { if (this.getCameraByUUID(cd.uuid) != null) { int result = mDbWrite.delete(T_TABLE, C_UUID+"=?", new String[]{cd.uuid.toString()}); if (result > 0) { return true; } else { return false; } } else { return false; } } public boolean updateCamera(CameraDevice cd) { if (this.getCameraByUUID(cd.uuid) != null) { ContentValues cv = new ContentValues(); cv.put(C_HEIGHT, cd.height); cv.put(C_WIDTH, cd.width); cv.put(C_RATE, cd.rate); cv.put(C_UUID, cd.uuid.toString()); cv.put(C_USERNAME, cd.username); cv.put(C_PASSWORD, cd.password); mDbWrite.update(T_TABLE, cv, C_UUID+"=?", new String[]{cd.uuid.toString()}); return true; } else { return false; } } public CameraDevice getCameraByid(int id) { String sql = "SELECT * FROM " + T_TABLE + " WHERE id = %d;"; sql = String.format(sql, id); Cursor c = mDbRead.rawQuery(sql, null); if (c.getCount() == 0) { return null; } else { c.moveToFirst(); return this.getCameraDevice(c); } } public CameraDevice getCameraByUUID(UUID uuid) { String sql = "SELECT * FROM " + T_TABLE + " WHERE " + C_UUID + " = '%s';"; sql = String.format(sql, uuid.toString()); Cursor c = mDbRead.rawQuery(sql, null); if (c.getCount() == 0) { return null; } else { c.moveToFirst(); return this.getCameraDevice(c); } } public List<CameraDevice> getCameraDevices() { List<CameraDevice> list = new ArrayList<CameraDevice>(); String sql = "SELECT * FROM " + T_TABLE; Cursor c = mDbRead.rawQuery(sql, null); while (c.moveToNext()) { UUID uuid = UUID.fromString(c.getString(c.getColumnIndex(C_UUID))); CameraDevice cd = new CameraDevice(uuid, ""); cd.setId(c.getInt(0)); cd.setProperties(c.getInt(c.getColumnIndex(C_WIDTH)), c.getInt(c.getColumnIndex(C_HEIGHT)), c.getInt(c.getColumnIndex(C_RATE))); cd.setSecurity(c.getString(c.getColumnIndex(C_USERNAME)), c.getString(c.getColumnIndex(C_PASSWORD))); list.add(cd); } return list; } public CameraDevice getCameraDevice(Cursor c) { UUID uuid = UUID.fromString(c.getString(c.getColumnIndex(C_UUID))); CameraDevice cd = new CameraDevice(uuid, ""); cd.setId(c.getInt(0)); cd.setProperties(c.getInt(c.getColumnIndex(C_WIDTH)), c.getInt(c.getColumnIndex(C_HEIGHT)), c.getInt(c.getColumnIndex(C_RATE))); cd.setSecurity(c.getString(c.getColumnIndex(C_USERNAME)), c.getString(c.getColumnIndex(C_PASSWORD))); return cd; }}
创建DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper { public static final String CREATE_SQL = "CREATE TABLE t_onvif_cameras (id integer PRIMARY KEY AUTOINCREMENT, UUID varchar(32), name varchar(32), username varchar(16), password varchar(16), width integer, height integer, rate integer);"; public DatabaseHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub } public DatabaseHelper(Context context, String name) { this(context, name, null, 1); } @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub try { db.execSQL(CREATE_SQL); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub } @Override public void onOpen(SQLiteDatabase db) { // TODO Auto-generated method stub super.onOpen(db); }}
创建HttpSoap
import java.io.ByteArrayInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import java.security.MessageDigest;import java.sql.Struct;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.List;import java.util.Locale;import java.util.Random;import org.xmlpull.v1.XmlPullParser;import android.R.integer;import android.util.Base64;import android.util.Xml;interface OnHttpSoapListener { public void OnHttpSoapDone(CameraDevice camera, String uri, boolean success);}public class HttpSoap implements Runnable { public static final String GET_SUBSERVICE_POST = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\"><s:Body xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><GetServices xmlns=\"http://www.onvif.org/ver10/device/wsdl\"><IncludeCapability>false</IncludeCapability></GetServices></s:Body></s:Envelope>"; public static final String IS_NEED_AUTH = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\"><s:Body xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><GetClientCertificateMode xmlns=\"http://www.onvif.org/ver10/device/wsdl\"></GetClientCertificateMode></s:Body></s:Envelope>"; public static final String GET_CAPABILITIES = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\"><s:Header><Security s:mustUnderstand=\"1\" xmlns=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"><UsernameToken><Username>%s</Username><Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">%s</Password><Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">%s</Nonce><Created xmlns=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">%s</Created></UsernameToken></Security></s:Header><s:Body xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><GetCapabilities xmlns=\"http://www.onvif.org/ver10/device/wsdl\"><Category>All</Category></GetCapabilities></s:Body></s:Envelope>"; public static final String GET_PROFILES = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\"><s:Header><wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"><wsse:UsernameToken><wsse:Username>%s</wsse:Username><wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">%s</wsse:Password><wsse:Nonce>%s</wsse:Nonce><wsu:Created>%s</wsu:Created></wsse:UsernameToken></wsse:Security></s:Header><s:Body xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><GetProfiles xmlns=\"http://www.onvif.org/ver10/media/wsdl\"></GetProfiles></s:Body></s:Envelope>"; public static final String GET_PROFILE = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\"><s:Header><wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"><wsse:UsernameToken><wsse:Username>%s</wsse:Username><wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">%s</wsse:Password><wsse:Nonce>%s</wsse:Nonce><wsu:Created>%s</wsu:Created></wsse:UsernameToken></wsse:Security></s:Header><s:Body xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><GetProfile xmlns=\"http://www.onvif.org/ver10/media/wsdl\"><ProfileToken>%s</ProfileToken></GetProfile></s:Body></s:Envelope>"; public static final String CREATE_PROFILE_BODY = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\"><s:Header><wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"><wsse:UsernameToken><wsse:Username>%s</wsse:Username><wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">%s</wsse:Password><wsse:Nonce>%s</wsse:Nonce><wsu:Created>%s</wsu:Created></wsse:UsernameToken></wsse:Security></s:Header><s:Body xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><CreateProfile xmlns=\"http://www.onvif.org/ver10/media/wsdl\"><Name>%s</Name></CreateProfile></s:Body></s:Envelope>"; public static final String GET_URI_BODY = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\"><s:Header><wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"><wsse:UsernameToken><wsse:Username>%s</wsse:Username><wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">%s</wsse:Password><wsse:Nonce>%s</wsse:Nonce><wsu:Created>%s</wsu:Created></wsse:UsernameToken></wsse:Security></s:Header><s:Body xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><GetStreamUri xmlns=\"http://www.onvif.org/ver10/media/wsdl\"><StreamSetup><Stream xmlns=\"http://www.onvif.org/ver10/schema\">RTP-Unicast</Stream><Transport xmlns=\"http://www.onvif.org/ver10/schema\"><Protocol>RTSP</Protocol></Transport></StreamSetup><ProfileToken>%s</ProfileToken></GetStreamUri></s:Body></s:Envelope>"; public static final String XMIC_PROFILE = "xmic_profile"; private HttpURLConnection mUrlConn; private OnHttpSoapListener mListener; private CameraDevice mCamera; private String mCreated, mNonce, mAuthPwd; public HttpSoap(CameraDevice device) { mCamera = device; createAuthString(); } public void setOnHttpSoapListener(OnHttpSoapListener listener) { mListener = listener; } private void createAuthString() { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.CHINA); mCreated = df.format(new Date()); mNonce = getNonce(); mAuthPwd = getPasswordEncode(mNonce, mCamera.password, mCreated); } private void initConn(String url) { try { URL url1 = new URL(url); mUrlConn = (HttpURLConnection) url1.openConnection(); mUrlConn.setDoInput(true); mUrlConn.setDoOutput(true); mUrlConn.setRequestMethod("POST"); mUrlConn.setUseCaches(false); mUrlConn.setInstanceFollowRedirects(true); mUrlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); } catch (Exception e) { e.printStackTrace(); } } public void start() { new Thread(this).start(); } public String inputStream2String(InputStream in) throws IOException { StringBuffer out = new StringBuffer(); byte[] b = new byte[4096]; for (int n; (n = in.read(b)) != -1;) { out.append(new String(b, 0, n)); } return out.toString(); } public String getNonce() { String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < 24; i++) { int number = random.nextInt(base.length()); sb.append(base.charAt(number)); } return sb.toString(); } public String getPasswordEncode(String nonce, String password, String date) { try { MessageDigest md = MessageDigest.getInstance("SHA-1"); // 从官方文档可以知道我们nonce还需要用Base64解码一次 byte[] b1 = Base64.decode(nonce.getBytes(), Base64.DEFAULT); // 生成字符字节流 byte[] b2 = date.getBytes(); // "2013-09-17T09:13:35Z"; byte[] b3 = password.getBytes(); // 根据我们传得值的长度生成流的长度 byte[] b4 = new byte[b1.length + b2.length + b3.length]; // 利用sha-1加密字符 md.update(b1, 0, b1.length); md.update(b2, 0, b2.length); md.update(b3, 0, b3.length); // 生成sha-1加密后的流 b4 = md.digest(); // 生成最终的加密字符串 String result = new String(Base64.encode(b4, Base64.DEFAULT)); return result.replace("\n", ""); } catch (Exception e) { e.printStackTrace(); return ""; } } @Override public void run() { try { // =========获取子服务========= initConn(mCamera.serviceURL); mUrlConn.connect(); String content = String.format(GET_CAPABILITIES, mCamera.username, mAuthPwd, mNonce, mCreated); mUrlConn.getOutputStream().write(content.getBytes()); InputStream inStream = mUrlConn.getInputStream(); String res = inputStream2String(inStream); String mediaUrl = findMediaServiceUrl(res); // =========获取Profile========= initConn(mediaUrl); mUrlConn.connect(); content = String.format(GET_PROFILES, mCamera.username, mAuthPwd, mNonce, mCreated); mUrlConn.getOutputStream().write(content.getBytes()); inStream = mUrlConn.getInputStream(); res = inputStream2String(inStream); String profile = getOldProfileToken(res); /* * if (profile.isEmpty()) { //=========创建Profile========= * initConn(mediaUrl); mUrlConn.connect(); content = * String.format(CREATE_PROFILE_BODY, mCamera.username, mAuthPwd, * mNonce, mCreated, XMIC_PROFILE); * mUrlConn.getOutputStream().write(content.getBytes()); inStream = * mUrlConn.getInputStream(); res = inputStream2String(inStream); * profile = getProfileToken(res); } */ // =========读取RTSP的配置信息==== initConn(mediaUrl); mUrlConn.connect(); content = String.format(GET_PROFILE, mCamera.username, mAuthPwd, mNonce, mCreated, profile); mUrlConn.getOutputStream().write(content.getBytes()); inStream = mUrlConn.getInputStream(); res = inputStream2String(inStream); analyseVideoEncoderConfiguration(res); // =========配置RTSP============== // =========获取RTSP的URI========= initConn(mediaUrl); mUrlConn.connect(); content = getURIContent(profile); mUrlConn.getOutputStream().write(content.getBytes()); inStream = mUrlConn.getInputStream(); res = inputStream2String(inStream); String uri = getStreamURI(res); if (mListener != null) { mListener.OnHttpSoapDone(mCamera, uri, true); } } catch (Exception e) { if (mListener != null) { mListener.OnHttpSoapDone(mCamera, "", false); } e.printStackTrace(); } } private void analyseVideoEncoderConfiguration(String xml) { XmlPullParser parser = Xml.newPullParser(); InputStream input = new ByteArrayInputStream(xml.getBytes()); try { parser.setInput(input, "UTF-8"); int eventType = parser.getEventType(); boolean done = false; while (eventType != XmlPullParser.END_DOCUMENT || done) { switch (eventType) { case XmlPullParser.START_DOCUMENT: break; case XmlPullParser.START_TAG: if (parser.getName().equals("Width")) { eventType = parser.next(); mCamera.width = Integer.parseInt(parser.getText()); } else if (parser.getName().equals("Height")) { eventType = parser.next(); mCamera.height = Integer.parseInt(parser.getText()); } else if (parser.getName().equals("FrameRateLimit")) { eventType = parser.next(); mCamera.rate = Integer.parseInt(parser.getText()); } break; case XmlPullParser.END_TAG: break; default: break; } eventType = parser.next(); } } catch (Exception e) { e.printStackTrace(); } } private String getURIContent(String profile) { String content = String.format(GET_URI_BODY, mCamera.username, mAuthPwd, mNonce, mCreated, profile); return content; } private String findMediaServiceUrl(String xml) { XmlPullParser parser = Xml.newPullParser(); InputStream input = new ByteArrayInputStream(xml.getBytes()); try { parser.setInput(input, "UTF-8"); int eventType = parser.getEventType(); boolean done = false; while (eventType != XmlPullParser.END_DOCUMENT || done) { switch (eventType) { case XmlPullParser.START_DOCUMENT: break; case XmlPullParser.START_TAG: if (parser.getName().equals("Media")) { eventType = parser.next(); if (parser.getName().equals("XAddr")) { eventType = parser.next(); if (!parser.getText().isEmpty()) { return parser.getText(); } } } break; case XmlPullParser.END_TAG: break; default: break; } eventType = parser.next(); } } catch (Exception e) { e.printStackTrace(); } return ""; } class TProfile { public String token; public int width; public int height; public int FrameRateLimit; public TProfile(String token) { this.token = token; } } private String getOldProfileToken(String xml) { XmlPullParser parser = Xml.newPullParser(); ArrayList<TProfile> profiles = new ArrayList<TProfile>(); InputStream input = new ByteArrayInputStream(xml.getBytes()); try { parser.setInput(input, "UTF-8"); int eventType = parser.getEventType(); boolean done = false; while (eventType != XmlPullParser.END_DOCUMENT || done) { switch (eventType) { case XmlPullParser.START_DOCUMENT: break; case XmlPullParser.START_TAG: if (parser.getName().equals("Profiles")) { String token = parser.getAttributeValue(null, "token"); TProfile profile = new TProfile(token); while (!(eventType == XmlPullParser.START_TAG && parser.getName().equals("Resolution"))) { eventType = parser.next(); } while (!(eventType == XmlPullParser.START_TAG && parser.getName().equals("Width"))) { eventType = parser.next(); } parser.next(); profile.width = Integer.parseInt(parser.getText()); profiles.add(profile); } break; case XmlPullParser.END_TAG: break; default: break; } eventType = parser.next(); } } catch (Exception e) { e.printStackTrace(); } if (profiles.size() > 0) { TProfile tmpProfile = profiles.get(0); for (int i=1;i<profiles.size();i++) { if (tmpProfile.width > profiles.get(i).width) { tmpProfile = profiles.get(i); } } return tmpProfile.token; } else { return ""; } } private String getStreamURI(String xml) { XmlPullParser parser = Xml.newPullParser(); InputStream input = new ByteArrayInputStream(xml.getBytes()); try { parser.setInput(input, "UTF-8"); int eventType = parser.getEventType(); boolean done = false; while (eventType != XmlPullParser.END_DOCUMENT || done) { switch (eventType) { case XmlPullParser.START_DOCUMENT: break; case XmlPullParser.START_TAG: if (parser.getName().equals("Uri")) { eventType = parser.next(); return parser.getText(); } break; case XmlPullParser.END_TAG: break; default: break; } eventType = parser.next(); } } catch (Exception e) { e.printStackTrace(); } return ""; }}
创建RtspClient.java
interface OnRtspListener { public void OnRtspStartPlay(String uri);}public class RtspClient implements Runnable { public static final String DESCRIBE = "DESCRIBE %s RTSP/1.0\r\nCSeq:0\r\nAccept:application/sdp\r\nAuthorization:Basic %s\r\n\r\n"; public static final String SETUP = "SETUP %s/trackID=1 RTSP/1.0\r\nCSeq:1\r\nAuthorization:Basic %s\r\nTransport:RTP/AVP/TCP;unicast;interleaved=0-1;ssrc=0\r\nUser-Agent:NKPlayer-1.00.00.081112\r\n\r\n"; public static final String PLAY = "PLAY %s RTSP/1.0\r\nCSeq:2\r\nAuthorization:Basic %s\r\nRate-Control:yes\r\nScale:1.000\r\nUser-Agent:NKPlayer-1.00.00.081112\r\n\r\n"; private String mUsername, mPassword, mUri, mAuthorization; private Socket mSocket; private OnRtspListener mListener; public RtspClient(String mUsername, String mPassword) { super(); this.mUsername = mUsername; this.mPassword = mPassword; String auth = this.mUsername + ":" + this.mPassword; mAuthorization = new String(Base64.encode(auth.getBytes(), Base64.DEFAULT)); mAuthorization = mAuthorization.replace("\n", ""); } public void setOnRtspListener(OnRtspListener listener) { mListener = listener; } private int getPort(String uri) { String port = uri.substring(uri.indexOf("//") + 2); port = port.substring(port.indexOf(":") + 1, port.indexOf("/")); return Integer.parseInt(port); } private String getHost(String uri) { String host = uri.substring(uri.indexOf("//") + 2); host = host.substring(0, host.indexOf(":")); return host; } public void start(String uri) { mUri = uri; try { mSocket = new Socket(getHost(uri), getPort(uri)); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } new Thread(this).start(); } public void doDescribe() { String content = String.format(DESCRIBE, mUri, mAuthorization); try { mSocket.getOutputStream().write(content.getBytes()); //byte[] b = new byte[2048]; //int length = mSocket.getInputStream().read(b); //String res = new String(b, 0, length); //Log.v("a", res); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void doSetup() { String content = String.format(SETUP, mUri, mAuthorization); try { mSocket.getOutputStream().write(content.getBytes()); //byte[] b = new byte[2048]; //int length = mSocket.getInputStream().read(b); //String res = new String(b, 0, length); //Log.v("a", res); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void doPlay() { String content = String.format(PLAY, mUri, mAuthorization); try { mSocket.getOutputStream().write(content.getBytes()); //byte[] b = new byte[32]; //Arrays.fill(b, (byte) 0); //InputStream is = mSocket.getInputStream(); //int tmp, count = 0;// while ((tmp = is.read()) != -1) {// b[count] = (byte) tmp;// count++;// if (count == 32) {// Log.d("RTSP Stream", new String(b, 0, count));// count = 0;// Arrays.fill(b, (byte) 0);// }// } // String res = new String(b, 0, length); // res.trim(); if (mListener != null) { mListener.OnRtspStartPlay(mUri); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void run() { doDescribe(); doSetup(); doPlay(); }}
做完这几步,现在需要写一个server监听,去监听他获得一个List
/** * 启动调用server */ mServiceConnection = null; if (mServiceConnection == null) { mServiceConnection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { mService = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { CameraBinder cb = (CameraBinder) service; mService = cb.getService(); List<CameraDevice> lists = mService.getFinder().getCameraList(); // CameraDevice object = null; // lists.add(object); adapter = new Fragment_one_MainListAdapter(getActivity(), lists, ""); main_listview_list.setAdapter(adapter); mService.getFinder().setOnCameraFinderListener(new OnCameraFinderListener() { @Override public void OnCameraListUpdated() { // TODO Auto-generated method stub // 用线程刷新,不然报错view视图 handler.sendEmptyMessage(0); } }); // adapter = new // FragmentOne_main_ListAdapter(getActivity(), // List); } }; } getActivity().bindService(new Intent(getActivity(), CameraService.class), mServiceConnection, Service.BIND_AUTO_CREATE); if (mService != null) { mService.sendBroadcast(); }
用线程去更新adapter
Handler handler = new Handler() { public void dispatchMessage(android.os.Message msg) { adapter.notifyDataSetChanged(); }; };
接下来是获得onvif返回的一个Service Address用于以后的请求
我西写的是listview上选中的时候,得到不同设备的不同service Address
private static String listitem = ""OnItemClickListener main_listview_list_click = new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub if (((ListView) parent).getTag() != null) { ((View) ((ListView) parent).getTag()).setBackgroundDrawable(null); } ((ListView) parent).setTag(view); view.setBackgroundColor(color.liang); List<CameraDevice> lists = mService.getFinder().getCameraList(); if (lists != null) { //得到一个Service Address listitem = lists.get(position).serviceURL; deviceid = listitem.substring(7, 22); } } };
得到这个地址之后跳转另外的页面用来显示得到的IPC的配置如ipc时间,ipc网络配置,ipc编码配置
if (listitem != "") { Intent intent = new Intent(getActivity(), FragmentOne_btn6.class); intent.putExtra("listitem", listitem); startActivity(intent); } else { Toast.makeText(getActivity(), "请选择一行", 200).show(); ; }
private String listitem Intent intent = getIntent(); listitem = intent.getExtras().getString("listitem");
接下来需要得到ipc当前的配置用于显示
GetDeviceInformation();方法********************************** private void GetDeviceInformation() { // TODO Auto-generated method stub handler.sendEmptyMessage(0); handler1.sendEmptyMessage(0); }
因为onvif工具上请求是发送的xml,在Android上同样也要得到xml去发送
xml可以用onvif测试工具生成,需要的可以去官网上下载,也可以在这个地址去下载http://www.cr173.com/soft/66448.html
下载完后
接下来,我们要在Android上实现得到当前编码配置
Handler handler1 = new Handler() { public void dispatchMessage(android.os.Message msg) { new Thread(new Runnable() { @Override public void run() { //这里的xml就是在工具上显示的xml复制下来即可 String xml = "<?xml version='1.0' encoding='utf-8'?><soap:Envelope xmlns:soap='http://www.w3.org/2003/05/soap-envelope' xmlns:trt='http://www.onvif.org/ver10/media/wsdl' xmlns:tt='http://www.onvif.org/ver10/schema'><soap:Body><trt:GetVideoEncoderConfiguration><trt:ConfigurationToken>" + JPEG001 + "</trt:ConfigurationToken></trt:GetVideoEncoderConfiguration></soap:Body></soap:Envelope>"; String httpserver = listitem; Map<String, Map> map = OnvifRequest.onvifrequest(xml, httpserver); System.out.println(map); if (map.size() != 0) { //map里面已经有该设备的编码配置的一些信息了解析map } else { } handlerui.sendEmptyMessage(0); } }).start(); }; };
请求的java文件
public class OnvifRequest { public static Map<String, Map> map; public static String XML=""; public static String SETVER=""; public static Map<String, Map> onvifrequest(String xml,String server){ map=new HashMap<String, Map>(); InputStream input = null; HttpURLConnection conn = null; DataOutputStream out = null; try { input = new StringBufferInputStream(xml); byte[] data; data = new byte[input.available()]; input.read(data); // 把XML的数据转成字符串 String str = new String(data); byte[] bb = str.getBytes(); // 请求地址 URL url; url = new URL(server); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setReadTimeout(20*1000); conn.setConnectTimeout(5 * 1000);// 设置超时的时间 conn.setDoInput(true); conn.setDoOutput(true);// 如果通过post提交数据,必须设置允许对外输出数据 conn.setRequestProperty("Content-Type", "text/xml; charset=UTF-8"); conn.setRequestProperty("Content-Length", String.valueOf(bb.length)); conn.connect(); out = new DataOutputStream(conn.getOutputStream()); out.writeBytes(str); // 写入请求的字符串 out.flush(); if (conn.getResponseCode() == 200) { // 请求返回的数据 BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); try { StringBuffer sb = new StringBuffer(); String r = ""; while((r = reader.readLine()) != null){ sb.append(r); } Map<String, Map> mapa = new HashMap<String, Map>(); mapa=XmltoMap.xml2map(sb.toString()); if (mapa!=null) { mapa=(Map<String, Map>) mapa.get("Envelope").get("Body"); } map=mapa; } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } else { System.out.println("no++"); } } catch (Exception e) { e.printStackTrace(); // TODO: handle exception }finally { if(input != null){ try { input.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(conn != null){ conn.disconnect(); conn = null; } if(out != null){ try { out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } return map; }
将的到的xml 转换为Map
public class XmltoMap { public static Map xml2map(String xmlString) throws DocumentException { Document doc = DocumentHelper.parseText(xmlString); Element rootElement = doc.getRootElement(); Map<String, Object> map = new HashMap<String, Object>(); ele2map(map, rootElement); return map; } private static void ele2map(Map map, Element ele) { //System.out.println(ele); // 获得当前节点的子节点 List<Element> elements = ele.elements(); saveAttribute2Map(map,ele); if (elements.size() == 0) { // 没有子节点说明当前节点是叶子节点,直接取值即可 map.put(ele.getName(), ele.getText()); } else if (elements.size() == 1) { // 只有一个子节点说明不用考虑list的情况,直接继续递归即可 Map<String, Object> tempMap = new HashMap<String, Object>(); ele2map(tempMap, elements.get(0)); map.put(ele.getName(), tempMap); } else { // 多个子节点的话就得考虑list的情况了,比如多个子节点有节点名称相同的 // 构造一个map用来去重 Map<String, Object> tempMap = new HashMap<String, Object>(); for (Element element : elements) { //System.out.println(element.attribute("token")); tempMap.put(element.getName(), null); } Set<String> keySet = tempMap.keySet(); for (String string : keySet) { Namespace namespace = elements.get(0).getNamespace(); List<Element> elements2 = ele.elements(new QName(string, namespace)); // 如果同名的数目大于1则表示要构建list if (elements2.size() > 1) { List<Map> list = new ArrayList<Map>(); for (Element element : elements2) { Map<String, Object> tempMap1 = new HashMap<String, Object>(); ele2map(tempMap1, element); list.add(tempMap1); } map.put(string, list); } else { // 同名的数量不大于1则直接递归去 Map<String, Object> tempMap1 = new HashMap<String, Object>(); ele2map(tempMap1, elements2.get(0)); map.put(string, tempMap1); } } } } private static void saveAttribute2Map(Map map, Element e) { ContentListFacade attributes = (ContentListFacade) e.attributes(); if (attributes.size() > 0) { HashMap<String, String> attrMap = new HashMap<String, String>(); map.put("attribute", attrMap); DefaultAttribute attrTmp = null; for (int i = 0, j = attributes.size(); i < j; i++) { attrTmp = (DefaultAttribute) attributes.get(i); attrMap.put(attrTmp.getName(), attrTmp.getValue()); } } } }
**以上就得到的需要的一些编码配置,,作为例子给大家参考,共同学习。
如有关于onvif不懂的问题,可加QQ群号465200732,共同讨论。**
0 0
- onvif在android上实现局域网搜索得到当前编码配置
- Onvif协议及其在Android下的实现
- Linux设备上的Onvif实现16:实现Onvif鉴权
- linux设备上的Onvif 实现2:ONVIF框架基础知识
- 完整的Onvif的检索-鉴权-配置-得到rtstp过程
- linux设备上的Onvif 实现14: 修改子通道的配置数据
- linux设备上的Onvif 实现13: 获取子通道的配置数据范围
- linux设备上的Onvif 实现12: 获取媒体配置数据
- linux设备上的Onvif 实现11: 修改媒体配置数据的流程
- java/android 编程实现通过日期得到当前的星期
- SqlServer中在当前数据库服务器上得到另一数据库服务器上数据的方法
- 在XP上实现广域网到局域网的远程桌面连接
- Mysql在数据库链接上配置编码
- ONVIF 客户端简单实现Discovery,实现设备搜索.
- 怎样在客户端得到页面上的dropdownlist当前选中的项目的文字?
- ONVIF学习-设备搜索的实现(结合MFC)
- Android如何得到当前正在屏幕上运行的程序包名?
- onvif搜索设备
- rcv_msg.c
- java 性能优化:提升 java 代码的运行效率
- RedHat虚拟机打不开磁盘问题的解决办法
- 使用浏览器来查看线程堆栈
- Mac 下Android Studio2.3更新Gradle3.3踩坑记录
- onvif在android上实现局域网搜索得到当前编码配置
- 关于ios::sync_with_stdio(false);和 cin.tie(0)加速c++输入输出流
- 字符串转为整数
- Android Studio下修改应用的包名
- Oozie分布式工作流——EL表达式
- Android软件设计架构简介
- 整数分解为若干项之和——递归思想
- winuser.h中的sendMessage函数
- python 学习笔记