2013-08-03 73 views
2

我想使用Cyber​​Garage“Cyber​​Link for Java”API为Android编写UPnP控制点应用程序。为了测试API,我实现了一个非常简单的应用程序。在此应用程序中,UPnP控制点主动搜索任何UPnP根设备,侦听响应和设备通知,并打印网络上可用设备的列表。适用于Android的使用Cyber​​Garage的简单UPnP/DLNA控制点Cyber​​Link for Java

该应用在Android手机上运行,​​但没有找到我网络上的UPnP设备。我在两款不同的Android手机上尝试了这一点。要检查这是否是Android特定的问题,我实现了与Java控制台应用程序相同的功能。有趣的是,Java控制台应用程序工作得很好,并且始终显示我的网络上的所有UPnP设备!

那么为什么这不适用于Android?请注意,在Android应用程序中,我必须使用AsyncTask在独立线程上实现网络特定功能。否则,我会得到错误,因为我不应该在UI线程上运行它。但是这不应该是问题,我是对的吗?

下面的两个应用程序的源代码。

Android应用程序:

MainActivity.java

package com.example.controller_v1; 

import org.cybergarage.upnp.DeviceList; 
import org.cybergarage.upnp.UPnP; 

import android.app.Activity; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.Process; 
import android.util.Log; 

public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     UPnP.setEnable(UPnP.USE_ONLY_IPV4_ADDR); 
     new StartControlPointTask().execute(); 
    } 

    private class StartControlPointTask extends AsyncTask { 
     public static final String TAG = "StartControlPointTask"; 

     @Override 
     protected Object doInBackground(Object... params) { 
      Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND); 
      MyControlPoint controlPoint = new MyControlPoint(); 
      controlPoint.start(); 
//   controlPoint.search(); 
      try { 
       Thread.sleep(5000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      DeviceList rootDevices = controlPoint.getDeviceList(); 
      int numDevices = rootDevices.size(); 
      if (numDevices > 0) { 
       for (int i = 0; i < numDevices; i++) { 
        Log.i(TAG, "device " + i + ": " + rootDevices.getDevice(i).getFriendlyName()); 
       } 
      } else { 
       Log.i(TAG, "no root devices found");// 
      } 
      return null; 
     } 
    } 
} 

MyControlPoint.java

package com.example.controller_v1; 

import org.cybergarage.upnp.ControlPoint; 
import org.cybergarage.upnp.device.NotifyListener; 
import org.cybergarage.upnp.device.SearchResponseListener; 
import org.cybergarage.upnp.ssdp.SSDPPacket; 

import android.util.Log; 

public class MyControlPoint extends ControlPoint implements NotifyListener, SearchResponseListener { 
    public MyControlPoint() { 
     addNotifyListener(this); 
     addSearchResponseListener(this); 
    } 

    @Override 
    public void deviceNotifyReceived(SSDPPacket ssdpPacket) { // NotifyListener 
     final String TAG = "deviceNotifyReceived"; 
     Log.i(TAG, "executed"); 
    } 

    @Override 
    public void deviceSearchResponseReceived(SSDPPacket ssdpPacket) { // SearchResponseListener 
     final String TAG = "deviceSearchResponseReceived"; 
     Log.i(TAG, "executed"); 
    } 

} 

AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.controller_v1" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="8" 
     android:targetSdkVersion="17" /> 
    <uses-permission android:name="android.permission.INTERNET"/> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name="com.example.controller_v1.MainActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

Java控制台应用程序:

Main.java

import org.cybergarage.upnp.DeviceList; 
import org.cybergarage.upnp.UPnP; 


public class Main { 
    public Main() { 
     UPnP.setEnable(UPnP.USE_ONLY_IPV4_ADDR); 
     MyControlPoint controlPoint = new MyControlPoint(); 
     controlPoint.start(); 
//  controlPoint.search(); 

     try { 
      Thread.sleep(5000); // wait for devices to be found 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     DeviceList rootDevices = controlPoint.getDeviceList(); 
     int numDevices = rootDevices.size(); 
     if (numDevices > 0) { 
      for (int i = 0; i < numDevices; i++) { 
       System.out.println("found device " + i + ": " + rootDevices.getDevice(i).getFriendlyName()); 
      } 
     } else { 
      System.out.println("no root devices found"); 
     } 
    } 

    public static void main(String[] args) { 
     new Main(); 
    } 
} 

MyControlPoint.java

import org.cybergarage.upnp.ControlPoint; 
import org.cybergarage.upnp.device.NotifyListener; 
import org.cybergarage.upnp.device.SearchResponseListener; 
import org.cybergarage.upnp.ssdp.SSDPPacket; 

public class MyControlPoint extends ControlPoint implements /*DeviceChangeListener,*/ NotifyListener, SearchResponseListener { 
    public MyControlPoint() { 
     addNotifyListener(this); 
     addSearchResponseListener(this); 
    } 

    @Override 
    public void deviceNotifyReceived(SSDPPacket packet) { // NotifyListener 
     System.out.println("deviceNotifyReceived"); 
    } 

    @Override 
    public void deviceSearchResponseReceived(SSDPPacket packet) { // SearchResponseListener 
     System.out.println("deviceSearchReceived"); 
    } 
} 

我没有任何想法,为什么Java控制台应用程序的工作原理及Android应用程序没有。我没有从文档中得到任何答案。有谁能够帮助我?

+0

您的AndroidManifest.xml中是否已启用网络权限?另一个可能的原因:如果您的设备配置为使用IPv6,则强制使用IPv4地址,而不是您的地址;) – Andreas

回答

1

我解除了代码,使用Eclipse ADT进行编译,并在运行Android 4.0(eeepc)的虚拟机(VMWare播放器)上完美运行。

在Cyber​​Garage网站上有一个Android版块,它表示讯连科技不能在模拟器上运行,因为它还不支持多播,可能这就是您的问题。

希望不会太晚帮忙。 Andrew

1

在我的情况下,它显示所有的设备,可能是因为我用电话而不是模拟器来检查。

相关问题