我有一个由机器人和台式机组成的分布式系统,它们需要在它们之间传递数据(一个简单的序列化对象)。我对类似 jini 的 android 发现系统感兴趣,使用该系统 androids/desktop 机器可以发现彼此,然后相互传输数据。分布式系统是非常动态的,从某种意义上说,设备来来去去非常突然和频繁。
我尝试使用Cling,我可以发现我的路由器,但无法发现其他设备,例如 android 手机。所以我想知道android设备是否真的兼容UPnP,或者我的代码可能有问题。
我正在使用Cling 用户手册中讨论的代码。
编辑:发布下面的代码-
public class UpnpBrowserActivity extends ListActivity {
private AndroidUpnpService upnpService;
Registry registry;
private ArrayAdapter<DeviceDisplay> listAdapter;
private BrowseRegistryListener registryListener = new BrowseRegistryListener();
private ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
upnpService = (AndroidUpnpService) service;
registry = upnpService.getRegistry();
// Refresh the list with all known devices
listAdapter.clear();
for (Device device : registry.getDevices()) {
registryListener.deviceAdded(registry,device);
}
// Getting ready for future device advertisements
registry.addListener(registryListener);
// Search asynchronously for all devices
upnpService.getControlPoint().search();
}
public void onServiceDisconnected(ComponentName className) {
upnpService = null;
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upnp_browser);
listAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1);
setListAdapter(listAdapter);
getApplicationContext().bindService(new Intent(this, AndroidUpnpServiceImpl.class),serviceConnection, Context.BIND_AUTO_CREATE);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.upnp_browser, menu);
menu.add(0, 0, 0, "Menu1").setIcon(android.R.drawable.ic_menu_search);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == 0 && upnpService != null) {
upnpService.getRegistry().removeAllRemoteDevices();
upnpService.getControlPoint().search();
}
return false;
}
@Override
protected void onDestroy() {
super.onDestroy();
if (upnpService != null) {
upnpService.getRegistry().removeListener(registryListener);
}
getApplicationContext().unbindService(serviceConnection);
}
class BrowseRegistryListener extends DefaultRegistryListener {
@Override
public void remoteDeviceDiscoveryStarted(Registry registry, RemoteDevice device) {
deviceAdded(device);
}
@Override
public void remoteDeviceDiscoveryFailed(Registry registry, final RemoteDevice device, final Exception ex) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(
UpnpBrowserActivity.this,
"Discovery failed of '" + device.getDisplayString() + "': " +
(ex != null ? ex.toString() : "Couldn't retrieve device/service descriptors"),
Toast.LENGTH_LONG
).show();
}
});
deviceRemoved(device);
}
@Override
public void remoteDeviceAdded(Registry registry, RemoteDevice device) {
deviceAdded(device);
}
@Override
public void remoteDeviceRemoved(Registry registry, RemoteDevice device) {
deviceRemoved(device);
}
@Override
public void localDeviceAdded(Registry registry, LocalDevice device) {
deviceAdded(device);
}
@Override
public void localDeviceRemoved(Registry registry, LocalDevice device) {
deviceRemoved(device);
}
public void deviceAdded(final Device device) {
runOnUiThread(new Runnable() {
public void run() {
DeviceDisplay d = new DeviceDisplay(device);
int position = listAdapter.getPosition(d);
if (position >= 0) {
// Device already in the list, re-set new value at same position
listAdapter.remove(d);
listAdapter.insert(d, position);
} else {
listAdapter.add(d);
}
}
});
}
public void deviceRemoved(final Device device) {
runOnUiThread(new Runnable() {
public void run() {
listAdapter.remove(new DeviceDisplay(device));
}
});
}
}
}
我也在SO 上阅读了这个问题,但是如果无法使用 Cling 或其他类似库发现 android 设备,我更愿意使用 TCP/IP 套接字编写一个小型发现系统。
如果我遗漏或误解某些内容,请指导我。任何帮助表示赞赏。提前致谢。