I have started developing live streaming using kurento media server. I have Installed kurento media server in Ubuntu 14.04TLS. It gets successfully Installed and also started successfully.
I have used STUN server, I have uncommented these two lines
stunServerAddress=<stun_ip_address>
stunServerPort=<stun_port>
And used IP, PORT as follows: 173.194.66.127:19302
.After doing all these thing I started kurento media server and it gets started.
Now I create Android native application by implementing RoomListener Interface.
Here is the Code to connect with Kurento Media Server.
public class MainActivity extends AppCompatActivity implements RoomListener {
private LooperExecutor executor;
private static KurentoRoomAPI kurentoRoomAPI;
private String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
executor = new LooperExecutor();
executor.requestStart();
String wsRoomUri = "wss://173.194.66.127:19302/room";
kurentoRoomAPI = new KurentoRoomAPI(executor, wsRoomUri, this);
kurentoRoomAPI.connectWebSocket();
}
#Override
public void onRoomResponse(RoomResponse response) {
Log.d(TAG, "Response");
}
#Override
public void onRoomError(RoomError error) {
Log.d(TAG, "Error: " + error.toString());
}
#Override
public void onRoomNotification(RoomNotification notification) {
Log.d(TAG, "Notification Received");
}
#Override
public void onRoomConnected() {
Log.d(TAG, "Connected");
}
#Override
public void onRoomDisconnected() {
Log.d(TAG, "Room Disconnected");
}
}
But when I run the application, it shows the following error:
Process: com.base.videostreamingkurento, PID: 1880
java.lang.AssertionError: java.net.SocketTimeoutException: failed to connect to /173.194.66.127 (port 19302) after 90000ms
at libcore.io.IoBridge.connect(IoBridge.java:117)
at java.nio.SocketChannelImpl.connect(SocketChannelImpl.java:199)
at org.java_websocket.client.WebSocketClient.interruptableRun(WebSocketClient.java:210)
at org.java_websocket.client.WebSocketClient.run(WebSocketClient.java:188)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.net.SocketTimeoutException: failed to connect to /173.194.66.127 (port 19302) after 90000ms
at libcore.io.IoBridge.connectErrno(IoBridge.java:189)
at libcore.io.IoBridge.connect(IoBridge.java:127)
at libcore.io.IoBridge.connect(IoBridge.java:115)
It seems that you have a little confusion with your deployment and IPs. You are trying to connect, from your client, to the STUN server. Instead, try setting the IP and PORT where your app server is located in this line
String wsRoomUri = "wss://APP_SERVER_IP:8443/room";
If you can draw that down, you'll see more clearly where everything goes and what should connect to what.
Related
I have trouble with connecting to a local web interface (192.168.10.13:3671) that are connected to my KNX network from the emulator/phone in Android Studio.
I've tried to connect to the same web interface with a already developed app called KNXwizard and that works, but I see in the code that that app uses AsyncTask.
Always getting this error: Error creating KNXnet/IP tunneling link: tuwien.auto.calimero.KNXException: connecting from /192.168.163.198:3671 to /192.168.10.13:3671: socket failed: EPERM (Operation not permitted)
I've checked this posts
Socket failed 1
Socket failed 2
Tried everything there, added permissions to my AndroidManifest.xml, uninstalled, used physical phone etc. But nothing works.
It could be my code, I've tried searching for an alternative method for AsyncTask. So it could be that the code is written wrong. Hope someone could help me out.
MainActivity:
public class MainActivity extends AppCompatActivity {
private static InetSocketAddress local = new InetSocketAddress("192.168.163.198", 3671);
private static InetSocketAddress server = new InetSocketAddress("192.168.10.13",
KNXnetIPConnection.DEFAULT_PORT);
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button)findViewById(R.id.button);
ExecutorService executorService = Executors.newSingleThreadExecutor();
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
executorService.execute(new Runnable() {
#Override
public void run() {
//doInBackground
System.out.println("This example establishes a tunneling connection to the KNXnet/IP server " + server);
// A KNX tunneling link supports NAT (Network Address Translation) if required.
// We also indicate that the KNX installation uses twisted-pair (TP) medium, with TP1 being the most common.
// KNXNetworkLink is the base interface implemented by all supported Calimero links to a KNX network.
try (KNXNetworkLink knxLink = KNXNetworkLinkIP.newTunnelingLink(local, server, false, TPSettings.TP1)) {
System.out.println("Connection established to server " + knxLink.getName());
System.out.println("Close connection again");
} catch (KNXException | InterruptedException e) {
// KNXException: all Calimero-specific checked exceptions are subtypes of KNXException
// InterruptedException: longer tasks that might block are interruptible, e.g., connection procedures. In
// such case, an instance of InterruptedException is thrown.
// If a task got interrupted, Calimero will clean up its internal state and resources accordingly.
// Any deviation of such behavior, e.g., where not feasible, is documented in the Calimero API.
System.out.println("Error creating KNXnet/IP tunneling link: " + e);
}
}
});
}
});
}
I figured it out.
It was a stupid mistake with the IP address, should have seen that before. I just change the IP address to that I have on the phone I was connected to (192.168.10.15).
I am trying to work with NSD and I find myself stuck at the very begining..
I set up a very basic layout with a single big button. This button's purpose is to start and register a service on my device so other devices would be able to connect to it through LAN. One press of the said button calls the folowing method in my only Activity :
public void startService(View view){
initSocket();
initRegList();
regService();
}
Following the DevBytes: Network Service Discovery video, I implemented the methods called above, like so (pardon my YOLO-ing for debugging purposes) :
public void initSocket(){
try {
mSocket = new ServerSocket(0);
} catch (IOException e) {
e.printStackTrace();
}
mPort = mSocket.getLocalPort();
Log.e("YOLO-PORT", String.valueOf(mPort));
}
public void regService(){
NsdServiceInfo serviceInfo = new NsdServiceInfo();
serviceInfo.setServiceName("MyCoolService");
serviceInfo.setServiceType("_myapp.tcp.");
serviceInfo.setPort(mPort);
mNsdman = (NsdManager) this.getSystemService(this.NSD_SERVICE);
mNsdman.registerService(serviceInfo,NsdManager.PROTOCOL_DNS_SD,mReglist);
}
public void initRegList() {
mReglist = new NsdManager.RegistrationListener() {
#Override
public void onRegistrationFailed(NsdServiceInfo nsdServiceInfo, int i) {
Log.e("YOLO-FAIL", "REG_FAIL, errcode = " + String.valueOf(i));
}
#Override
public void onUnregistrationFailed(NsdServiceInfo nsdServiceInfo, int i) {
Log.e("YOLO-FAIL", "UNREG_FAIL, errcode = " + String.valueOf(i));
}
#Override
public void onServiceRegistered(NsdServiceInfo nsdServiceInfo) {
mServName = nsdServiceInfo.getServiceName();
Log.e("YOLO-NAME", mServName);
}
#Override
public void onServiceUnregistered(NsdServiceInfo nsdServiceInfo) {
Log.e("YOLO-OK", "UNREG");
}
};
}
My problem is I keep falling into onUnregistrationFailed method of the listener with a return code = 0.
Below you will find Logcat entries apearing when I press the said button :
09-14 21:54:03.904 18672-18672/fr.lpnsk.lollibox E/YOLO-PORT﹕ 48321
09-14 21:54:04.124 180-531/? E/MDnsDS﹕ service register request 22 got an error from DNSServiceRegister -65540
09-14 21:54:04.125 538-607/? E/NsdService﹕ Failed to execute registerService com.android.server.NativeDaemonConnector$NativeDaemonArgumentException: command '76 mdnssd register 22 MyCoolService _myapp.tcp. 48321' failed with '501 76 serviceRegister request got an error from DNSServiceRegister'
09-14 21:54:04.126 180-531/? E/MDnsDS﹕ register stop used unknown requestId 22
09-14 21:54:04.126 538-607/? E/NsdService﹕ Failed to execute unregisterService com.android.server.NativeDaemonConnector$NativeDaemonArgumentException: command '77 mdnssd stop-register 22' failed with '501 77 Unknown requestId'
09-14 21:54:04.127 18672-19953/fr.lpnsk.lollibox E/YOLO-FAIL﹕ REG_FAIL, errcode = 0
Am I missing something obvious here ?
Thank you for your help !
Am I missing something obvious here?
Yes. You missed the underscore _ sign before tcp when setting the service type. It should be:
serviceInfo.setServiceType("_myapp._tcp.");
From the official documentation:
...the service type specifies which protocol and transport layer the application uses. The syntax is "_protocol._transportlayer".
I am following a quick guide from Smack Documentation, for me to connect my asmack xmpp client with openfire xmpp server. But unfortunately, there a exception errors that I got from following the codes on smack documentation.
Since that I am not actually using smack but instead I am using asmack (smack version for android), I read from here that I should call SmackAndroid.init(Context)in order to initialize Smack on Android or Smack won't work as expected.
I aslo build add and dnsjava library, for me to execute this single line of code SmackAndroid.init(Context). I Thought that these steps will solve my problem upon connecting asmack client with openfire server but its not.
Here is my code:
public class MainActivity extends Activity {
public static final String HOST = "Kirbys-Mac-mini.local";
public static final int PORT = 5222;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new ConnectToServer().execute();
}
private class ConnectToServer extends AsyncTask <Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
SmackAndroid.init(MainActivity.this);
boolean isConnected = false;
ConnectionConfiguration config = new ConnectionConfiguration(HOST, PORT);
XMPPConnection conn2 = new XMPPTCPConnection(config);
try {
conn2.connect();
isConnected = true;
}
catch (IOException e){
Log.e("XMPPIOExceptionj", e.toString());
} catch (SmackException e){
Log.e("XMPPSmackException", e.toString()+" Host:"+conn2.getHost()+"Port:"+conn2.getPort());
} catch (XMPPException e){
Log.e("XMPPChatDemoActivity", "Failed to connect to "+ conn2.getHost());
Log.e("XMPPChatDemoActivity", e.toString());
}
return null;
}
After I run the application, Errors will show up in my logcat because there is something wrong happened while connecting to my server. These are the error that was catched by the exception:
11-26 04:24:19.783: E/XMPPSmackException(3964): org.jivesoftware.smack.SmackException$ConnectionException Host:nullPort:0
I don't now why is this happening to my app. Even the way that I setup my openfire is on default and I also use its embedded database. Please help me with my problem.
Wifi P2P service discovery is not behaving as expected. I am seeing intermittent issues where the DNSSD listeners are not called always and hence I have no clue of nearby devices running the same app. I am using the following two APIs - one to register a service to be discovered by other devices and the other to discover the nearby services running on other devices. Any idea if I am doing anything wrong here or is there some specific sequence of other android API calls that need to be made before I call these APIs to ensure that the listeners are always called whenever there is a new service registered or even if a service is registered before we call the API to discover the local services.
API to register a local service:
private void registerService() {
Map<String, String> values = new HashMap<String, String>();
values.put("name", "Steve");
values.put("port", "8080");
WifiP2pServiceInfo srvcInfo = WifiP2pDnsSdServiceInfo.newInstance(mMyDevice.deviceName, "_http._tcp", values);
manager.addLocalService(channel, srvcInfo, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(WiFiDirectActivity.this, "Local service added successfully",
Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(int reasonCode) {
Toast.makeText(WiFiDirectActivity.this, "Local service addition failed : " + reasonCode,
Toast.LENGTH_SHORT).show();
}
});
}
API to discover local services:
public void discoverService() {
manager.clearServiceRequests(channel, null);
DnsSdTxtRecordListener txtListener = new DnsSdTxtRecordListener() {
#Override
/* Callback includes:
* fullDomain: full domain name: e.g "printer._ipp._tcp.local."
* record: TXT record data as a map of key/value pairs.
* device: The device running the advertised service.
*/
public void onDnsSdTxtRecordAvailable(String fullDomain, Map record, WifiP2pDevice device) {
Log.d(TAG, "DnsSdTxtRecord available -" + record.toString());
}
};
DnsSdServiceResponseListener servListener = new DnsSdServiceResponseListener() {
#Override
public void onDnsSdServiceAvailable(String instanceName, String registrationType, WifiP2pDevice resourceType) {
Log.d(TAG, "onBonjourServiceAvailable " + instanceName);
}
};
manager.setDnsSdResponseListeners(channel, servListener, txtListener);
WifiP2pDnsSdServiceRequest serviceRequest = WifiP2pDnsSdServiceRequest.newInstance();
manager.addServiceRequest(channel, serviceRequest, new ActionListener() {
#Override
public void onSuccess() {
// Success!
Log.d(TAG, "addServiceRequest success");
}
#Override
public void onFailure(int code) {
// Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY
Log.d(TAG, "addServiceRequest failure with code " + code);
}
});
manager.discoverServices(channel, new ActionListener() {
#Override
public void onSuccess() {
// Success!
Log.d(TAG, "discoverServices success");
}
#Override
public void onFailure(int code) {
// Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY
if (code == WifiP2pManager.P2P_UNSUPPORTED) {
Log.d(TAG, "P2P isn't supported on this device.");
} else {
Log.d(TAG, "discoverServices failure");
}
}
});
}
Note: manager & channel are initialized as
WifiP2pManager manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
Channel channel = manager.initialize(this, getMainLooper(), null);
WifiP2p (in general):
Some time ago I was developing an application with a pretty complex network connectivity system based on WifiP2p with Service Broadcasting/Discovery. And based on that experience I already wrote few posts here on SO about how difficult, wearing and problematic that is. Here are two of them (they are quite full of the inside knowledge I acquired about WifiP2p with Service Discovery, and WifiP2p itself):
Why is discovering peers for Android WifiDirect so unreliable
Wi-fi P2P. Inform all peers available of some event
I would advise you to read both of my answers (even though they are focused a bit more on the WifiP2p itself). They should give you some perspective on the things you should be looking for when working with the WifiP2p Service Discovery.
I can easily say that if you want to build an efficient, relatively reliable and robust WifiP2p connection system (especially with Service Discovery), you will have to work your ass off.
WifiP2p Service Discovery:
To better answer your exact question, I will tell you what I did (different from you) to make my Service Discovery work pretty reliably.
1. Broadcasting Service:
First of all: before registering your Service (with addLocalService method) you should use the WifiP2pManager's clearLocalServices method. And it is important, that you should only call addLocalService if the listener passed in the clearLocalServices returned with the onSuccess callback.
Although this sets up the broadcasting pretty nicely, I found that other nodes were not always able to detect the broadcasted service (especially when those nodes weren't already actively detecting services at the moment of registering your local Service - but they "joined" later). I couldn't find a way to fix this issue 100% reliably. And believe me I was trying probably everything WifiP2p-related. And no, the clearLocalServices-addLocalService sequence wasn't really giving satisfying results. Or more so: doing something different was working much better. What I decided to do, was after I successfully added local service (onSuccess callback from addLocalService), I started a Thread that would periodically call WifiP2pManager's method discoverPeers. That seemed to be forcing to rebroadcast all the service information.
So... basically the base of your broadcasting code should look more-less like this (bare in mind that every single piece of code I will post here is stripped-off of all "checks" if the network connectivity system is in the right state, you should design them yourself to fit your solution the best):
public void startBroadcastingService(){
mWifiP2pManager.clearLocalServices(mWifiP2pChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
mWifiP2pManager.addLocalService(mWifiP2pChannel, mWifiP2pServiceInfo,
new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
// service broadcasting started
mServiceBroadcastingHandler
.postDelayed(mServiceBroadcastingRunnable,
SERVICE_BROADCASTING_INTERVAL);
}
#Override
public void onFailure(int error) {
// react to failure of adding the local service
}
});
}
#Override
public void onFailure(int error) {
// react to failure of clearing the local services
}
});
}
where the mServiceBroadcastingRunnable should be:
private Runnable mServiceBroadcastingRunnable = new Runnable() {
#Override
public void run() {
mWifiP2pManager.discoverPeers(mWifiP2pChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
}
#Override
public void onFailure(int error) {
}
});
mServiceBroadcastingHandler
.postDelayed(mServiceBroadcastingRunnable, SERVICE_BROADCASTING_INTERVAL);
}
};
2. Discovering Service:
For the discovering of your service I used similar approach. Both with the setting up the discovering, and with trying to force "rediscovery" of services.
Setting up was performed with the sequence of the following three WifiP2pManager's methods:
removeServiceRequest, addServiceRequest, discoverServices
They were called in this exact order and a particular method (second or the third one to be exact) has been called only after the previous one had "returned" with the onSuccess callback.
The rediscovery of services was being performed with the intuitive method (just by repeating the mentioned sequence: removeServiceRequest -> addServiceRequest -> discoverServices).
The base of my code looked more-less like this (to start Service Discovery I would first call prepareServiceDiscovery() and then startServiceDiscovery()):
public void prepareServiceDiscovery() {
mWifiP2pManager.setDnsSdResponseListeners(mWifiP2pChannel,
new WifiP2pManager.DnsSdServiceResponseListener() {
#Override
public void onDnsSdServiceAvailable(String instanceName,
String registrationType, WifiP2pDevice srcDevice) {
// do all the things you need to do with detected service
}
}, new WifiP2pManager.DnsSdTxtRecordListener() {
#Override
public void onDnsSdTxtRecordAvailable(
String fullDomainName, Map<String, String> record,
WifiP2pDevice device) {
// do all the things you need to do with detailed information about detected service
}
});
mWifiP2pServiceRequest = WifiP2pDnsSdServiceRequest.newInstance();
}
private void startServiceDiscovery() {
mWifiP2pManager.removeServiceRequest(mWifiP2pChannel, mWifiP2pServiceRequest,
new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
mWifiP2pManager.addServiceRequest(mWifiP2pChannel, mWifiP2pServiceRequest,
new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
mWifiP2pManager.discoverServices(mWifiP2pChannel,
new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
//service discovery started
mServiceDiscoveringHandler.postDelayed(
mServiceDiscoveringRunnable,
SERVICE_DISCOVERING_INTERVAL);
}
#Override
public void onFailure(int error) {
// react to failure of starting service discovery
}
});
}
#Override
public void onFailure(int error) {
// react to failure of adding service request
}
});
}
#Override
public void onFailure(int reason) {
// react to failure of removing service request
}
});
}
the mServiceDiscoveringRunnable was just:
private Runnable mServiceDiscoveringRunnable = new Runnable() {
#Override
public void run() {
startServiceDiscovery();
}
};
All this made my system work quite well. It wasn't perfect yet, but with the lack of documentation on this subject I think I couldn't do much more to improve it.
If you test this approach, be sure to tell me how it works for you (or if it works for you ;) ).
if the problem is the detection of the service i believe that crearing group is the best way to make the device and service detectable but the if created group in the all devices then you cannot connect in direct.
but as wifi network.
i do it every day and it works.
During the first implementation of the NSDManager using the examples and the tutorial on the developer page , the application successfully started the discovery and found the devices.
However now it seems to be broken...
When the program is started, after some initialization, the code enters the following method and successfully run:
public void discoverServices() {
Log.d(TAG, "Initializing discovery on NSD");
mNsdManager.discoverServices(
SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
}
The log-message is received. After a good while (say approx 5 mins.) this is outputted from the program:
05-21 11:08:32.518: E/NsdCamera(12236): Discovery failed: Error code:0
05-21 11:08:32.518: W/dalvikvm(12236): threadid=12: thread exiting with uncaught exception (group=0x40c9c930)
05-21 11:08:32.518: E/AndroidRuntime(12236): FATAL EXCEPTION: NsdManager
05-21 11:08:32.518: E/AndroidRuntime(12236): java.lang.NullPointerException
05-21 11:08:32.518: E/AndroidRuntime(12236): at android.net.nsd.NsdManager$ServiceHandler.handleMessage(NsdManager.java:338)
05-21 11:08:32.518: E/AndroidRuntime(12236): at android.os.Handler.dispatchMessage(Handler.java:99)
05-21 11:08:32.518: E/AndroidRuntime(12236): at android.os.Looper.loop(Looper.java:137)
05-21 11:08:32.518: E/AndroidRuntime(12236): at android.os.HandlerThread.run(HandlerThread.java:60)
Also from the services:
05-21 11:50:49.108: E/NativeDaemonConnector.ResponseQueue(8858): Timeout waiting for response
05-21 11:50:49.108: E/mDnsConnector(8858): timed-out waiting for response to 10 mdnssd discover 6 _http._tcp.
05-21 11:50:49.108: E/NsdService(8858): Failed to discoverServices com.android.server.NativeDaemonConnector$NativeDaemonFailureException: command '10 mdnssd discover 6 _http._tcp.' failed with 'null'
Error code "0" is described in the NSDManager class as an internal error.
The major updates I did was the access to the context in the helper-class called NsdCamera.
Here is some probably evil code-snippets:
Helper-class constructor:
public NsdCamera(CameraChooseActivity context) {
mContext = context;
updateUI = new UpdateUI();
mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
mServiceName = new Vector<NsdServiceInfo>();
Helper-class NSD initialization:
public void initializeNsd() {
initializeDiscoveryListener();
}
public void initializeDiscoveryListener() {
mDiscoveryListener = new NsdManager.DiscoveryListener() {
#Override
public void onDiscoveryStarted(String regType) {
Log.d(TAG, "Service discovery started");
}
/**
* A name check to see if the DNS discovery was correct. Checks if it contains
* AXIS and has the desired MAC address-space
* #param hostname ,the inputted hostname from the discovery cycle
* #return true if it's an Axis camera.
*/
public boolean nameCheck(String hostname){
return (hostname.contains("AXIS") && hostname.contains("00408C"));
}
#Override
public void onServiceFound(NsdServiceInfo service) {
Log.d(TAG, "Service discovery success: " + service.getServiceName());
if (!service.getServiceType().equals(SERVICE_TYPE)) {
Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
} else if (nameCheck(service.getServiceName())){
mServiceName.add(service);
// updateUI.execute(new BundleUI(mContext,service, null));
}
}
#Override
public void onServiceLost(NsdServiceInfo service) {
Log.e(TAG, "service lost" + service);
if(mServiceName.remove(service)){
//TODO
Log.e(TAG, "remove the view, service is lost");
}
}
#Override
public void onDiscoveryStopped(String serviceType) {
Log.i(TAG, "Discovery stopped: " + serviceType);
//Necessary??
mServiceName.clear();
}
#Override
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
mNsdManager.stopServiceDiscovery(this);
}
#Override
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
mNsdManager.stopServiceDiscovery(this);
}
};
}
CameraChooseActivity -> onCreate is calling the helper-class
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camerachoose);
//Setup the animation for the text in the Relativelayout
mDescription = (TextSwitcher) findViewById(R.id.camera_add);
mDescription.setFactory(this);
mDescription.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in));
mDescription.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));
mDescription.setText(getText(R.string.camera_add));
//Building alert dialog
mBuilder = new AlertDialog.Builder(this,AlertDialog.THEME_HOLO_DARK);
mBuilder.setMessage(R.string.dialog_about).setTitle(R.string.action_about);
mBuilder.setIcon(android.R.drawable.ic_dialog_info);
mLayout = (RelativeLayout) findViewById(R.id.layout_camerachoose);
//Initialize the NSD
mNSDHelper = new NsdCamera(this);
mNSDHelper.initializeNsd();
Base on my experience, I suppose this is a listener lifetime issue.
Because you supply two listeners to the system NSD service, one is for startServiceDiscovery() and another for stopServiceDiscovery(). you need to make sure these listeners still alive when the system accesses these listeners.
One fact is that onStartDiscoveryFailed() is called 2 minutes after startServiceDiscovery() is called, it should be a long time compared to the lifetime of the listener.
So if the listener is a local object and is released after calling the startServiceDiscovery(), it maybe cause the NSD service to crash.
public void stopServiceDiscovery (NsdManager.DiscoveryListener
listener)
Stop service discovery initiated with discoverServices(). An active
service discovery is notified to the application with
onDiscoveryStarted(String) and it stays active until the application
invokes a stop service discovery. A successful stop is notified to
with a call to onDiscoveryStopped(String).
Upon failure to stop service discovery, application is notified
through onStopDiscoveryFailed(String, int).
Parameters listener This should be the listener object that was passed
to discoverServices(String, int, NsdManager.DiscoveryListener). It
identifies the discovery that should be stopped and notifies of a
successful stop.
and below snippet make sure do not call any NsdManager api.
#Override
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
Log.i(TAG, "onStartDiscoveryFailed : Error code:" + errorCode);
}
#Override
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
Log.i(TAG, "onStopDiscoveryFailed : Error code:" + errorCode);
}
Good Luck.
A simple restart of the DUT proved to be the solution. Must say that the error is pretty odd.
I think the daemon crashed and didn't restart.
(If someone can post an analysis or have a much better solution, please post it)