在Android上实现ONVIF WS-Discovery

时间:2018-04-22 15:20:02

标签: java android web-services onvif ws-discovery

我需要在Android应用程序中实现ONVIF,直到现在我还没有取得多大成功。 我尝试使用evercam,但使用它会导致“ClassNotFoundException”。这是完整的堆栈跟踪。

04-22 20:20:22.182 5327-5638/com.example.cooln.onvif_tester E/AndroidRuntime: FATAL EXCEPTION: pool-1-thread-2
    Process: com.example.cooln.onvif_tester, PID: 5327
    java.lang.NoClassDefFoundError: Failed resolution of: Lnet/sbbi/upnp/Discovery;
        at io.evercam.network.discovery.UpnpDiscovery.discoverAll(UpnpDiscovery.java:34)
        at io.evercam.network.UpnpRunnable.run(UpnpRunnable.java:25)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: java.lang.ClassNotFoundException: Didn't find class "net.sbbi.upnp.Discovery" on path: DexPathList[[zip file "/data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/base.apk", zip file "/data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_dependencies_apk.apk", zip file "/data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_resources_apk.apk", zip file "/data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_0_apk.apk", zip file "/data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_1_apk.apk", zip file "/data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_2_apk.apk", zip file "/data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_3_apk.apk", zip file "/data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_4_apk.apk", zip file "/data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_5_apk.apk", zip file "/data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_6_apk.apk", zip file "/data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_7_apk.apk", zip file "/data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_8_apk.apk", zip file "/data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/lib/arm64, /data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/base.apk!/lib/arm64-v8a, /data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_dependencies_apk.apk!/lib/arm64-v8a, /data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_resources_apk.apk!/lib/arm64-v8a, /data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_0_apk.apk!/lib/arm64-v8a, /data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_1_apk.apk!/lib/arm64-v8a, /data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_2_apk.apk!/lib/arm64-v8a, /data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_3_apk.apk!/lib/arm64-v8a, /data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_4_apk.apk!/lib/arm64-v8a, /data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_5_apk.apk!/lib/arm64-v8a, /data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_6_apk.apk!/lib/arm64-v8a, /data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_7_apk.apk!/lib/arm64-v8a, /data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_8_apk.apk!/lib/arm64-v8a, /data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_slice_9_apk.apk!/lib/arm64-v8a, /system/lib64, /system/vendor/lib64]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:93)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        at io.evercam.network.discovery.UpnpDiscovery.discoverAll(UpnpDiscovery.java:34) 
        at io.evercam.network.UpnpRunnable.run(UpnpRunnable.java:25) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) 
        at java.lang.Thread.run(Thread.java:764) 
        Suppressed: java.io.IOException: No original dex files found for dex location /data/app/com.example.cooln.onvif_tester-QGIXBRlgj6RGsdcqR4YWug==/split_lib_resources_apk.apk
        at dalvik.system.DexFile.openDexFileNative(Native Method)
        at dalvik.system.DexFile.openDexFile(DexFile.java:353)
04-22 20:20:22.184 5327-5638/com.example.cooln.onvif_tester E/AndroidRuntime:     at dalvik.system.DexFile.<init>(DexFile.java:100)
        at dalvik.system.DexFile.<init>(DexFile.java:74)
        at dalvik.system.DexPathList.loadDexFile(DexPathList.java:374)
        at dalvik.system.DexPathList.makeDexElements(DexPathList.java:337)
        at dalvik.system.DexPathList.<init>(DexPathList.java:157)
        at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:65)
        at dalvik.system.PathClassLoader.<init>(PathClassLoader.java:64)
        at com.android.internal.os.PathClassLoaderFactory.createClassLoader(PathClassLoaderFactory.java:43)
        at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:69)
        at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:36)
        at android.app.LoadedApk.createOrUpdateClassLoaderLocked(LoadedApk.java:669)
        at android.app.LoadedApk.getClassLoader(LoadedApk.java:702)
        at android.app.LoadedApk.getResources(LoadedApk.java:929)
        at android.app.ContextImpl.createAppContext(ContextImpl.java:2242)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5708)
        at android.app.ActivityThread.-wrap1(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1673)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:172)
        at android.app.ActivityThread.main(ActivityThread.java:6637)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

有没有人有任何想法如何以不同的方式实现它?

1 个答案:

答案 0 :(得分:0)

在onvif设备上为Android执行WS-Discovery的代码片段。 确保您的IP摄像机已连接到本地网络。 将本地网络广播地址提供给数据报套接字。

private void discoverWsDevices() throws SocketException {
    final int WS_DISCOVERY_PORT = 3702;
    final String WS_DISCOVERY_ADDRESS_IPv4 = "192.168.49.255";//"239.255.255.250";

    new Thread() {
        public void run() {

            final String probe = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                    "<e:Envelope xmlns:e=\"http://www.w3.org/2003/05/soap-envelope\"\n" +
                    "xmlns:w=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\"\n" +
                    "xmlns:d=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\"\n" +
                    "xmlns:dn=\"http://www.onvif.org/ver10/network/wsdl\">\n" +
                    "<e:Header>\n" +
                    "<w:MessageID>uuid:84ede3de-7dec-11d0-c360-f01234567890</w:MessageID>\n" +
                    "<w:To e:mustUnderstand=\"true\">urn:schemas-xmlsoap-org:ws:2005:04:discovery</w:To>\n" +
                    "<w:Action\n" +
                    "a:mustUnderstand=\"true\">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</w:Action>\n" +
                    "</e:Header>\n" +
                    "<e:Body>\n" +
                    "<d:Probe>\n" +
                    "<d:Types>dn:NetworkVideoTransmitter</d:Types>\n" +
                    "</d:Probe>\n" +
                    "</e:Body>\n" +
                    "</e:Envelope>\n";

            DatagramSocket datagramSocket = null;

            try {
                datagramSocket = new DatagramSocket();
                datagramSocket.setBroadcast(true);
                datagramSocket.setSoTimeout(4000);
            } catch (SocketException e) {
                Log.e(LOG_TAG, "In discoverWsDevices datagram socket exception" + datagramSocket);
                e.printStackTrace();
            }

            byte[] soapMessageByteArray = probe.getBytes();
            DatagramPacket datagramPacketSend = null;
            try {
                datagramPacketSend = new DatagramPacket(soapMessageByteArray,
                        soapMessageByteArray.length, InetAddress.getByName(WS_DISCOVERY_ADDRESS_IPv4), WS_DISCOVERY_PORT);
            } catch (UnknownHostException e) {
                Log.e(LOG_TAG, "Unknown host in send packet");
                e.printStackTrace();
            }

            try {
                datagramSocket.send(datagramPacketSend);
            } catch (IOException e) {
                Log.e(LOG_TAG, "In discoverWsDevices datagram socket IOException send " + datagramSocket);
                e.printStackTrace();
            }
            Log.e(LOG_TAG, "sent port=" + datagramPacketSend.getAddress().getHostName());

            List<ByteArrayInputStream> probeMatches = new ArrayList<ByteArrayInputStream>();
            while (true) {

                byte[] responseMessageByteArray = new byte[4000];

                DatagramPacket datagramPacketRecieve = new DatagramPacket(responseMessageByteArray,
                        responseMessageByteArray.length);
                try {
                    datagramSocket.receive(datagramPacketRecieve);
                } catch (SocketTimeoutException e) {
                    datagramSocket.close();
                    Log.e(LOG_TAG, "In discoverWsDevices datagram socket timeout exception");
                    break;
                } catch (IOException e) {
                    Log.e(LOG_TAG, "In discoverWsDevices datagram socket ioexception");
                    e.printStackTrace();
                    break;
                }
                Log.e(LOG_TAG, "recieved" + datagramPacketRecieve.getData().toString());
                probeMatches.add(new ByteArrayInputStream(datagramPacketRecieve.getData(), 0, datagramPacketRecieve.getLength()));
            }


            for (ByteArrayInputStream input : probeMatches) {
                byte[] bytes = new byte[input.available()];
                input.read(bytes, 0, input.available());
                String stream = new String(bytes);

                EnvelopeProbeMatch probeMatch =
                        (EnvelopeProbeMatch) (new WiFiCameraSoapMessageUtil()).deserialize(stream,
                                "com.wifiservice.Utility.WSDiscovery.EnvelopeProbeMatch");

                String xAddrs = probeMatch.getXaddress();
                Log.e(LOG_TAG, "xaddress=" + probeMatch.getXaddress());

                String[] split = xAddrs.split("/");
                String serverIpPort = split[2];
                String iPaddress = ((split[2]).split(":"))[0];
                Log.e(LOG_TAG, "xAddress=" + xAddrs + "Ip Address=" + iPaddress);

                if (!mWiFiCameraDeviceList.containsKey(iPaddress)) {
                    WiFiCameraDeviceInformation wiFiCameraDeviceInformation =
                            new WiFiCameraDeviceInformation(null, "",
                                    null, null, iPaddress, "notProbed");
                    mWiFiCameraDeviceList.put(iPaddress, wiFiCameraDeviceInformation);

                    Log.e(LOG_TAG, "hashmap=" + mWiFiCameraDeviceList.toString());

                    (mWiFiCameraDeviceList.get(iPaddress)).mWiFiCameraClient =
                            WiFiCameraClientFactory.getWiFiCameraClient(
                                    WiFiCameraClientProtocolType.WiFiCameraClientType_Onvif,
                                    clientCallback, serverIpPort);
                    (mWiFiCameraDeviceList.get(iPaddress)).mProbeStatus = "Probed";
                    (mWiFiCameraDeviceList.get(iPaddress)).mWiFiCameraClient.getStreamURL();
                }
            }
        }
    }.start();
}