WiFiDirect discoverServices keeps failing with error 3 (NO_SERVICE_REQUESTS) - android

I'm using WiFi P2P for network service discovery, and I'm following the instructions as outlined on the developer guide. Here's the relevant code in my service class:
public void onCreate() {
manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
channel = manager.initialize(this, getMainLooper(), null);
registerP2pService();
lookForServices();
}
private void registerP2pService() {
WifiP2pDnsSdServiceInfo serviceInfo =
WifiP2pDnsSdServiceInfo.newInstance("_service.name", "_presence._tcp", new HashMap<String, String>());
manager.addLocalService(channel, serviceInfo, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.i("tag", "REGISTERED SERVICE");
}
#Override
public void onFailure(int arg0) {
Log.e("tag", "FAILED to register service");
}
});
}
private void setServiceListeners() {
WifiP2pDnsSdServiceRequest serviceRequest = WifiP2pDnsSdServiceRequest.newInstance();
manager.addServiceRequest(channel, serviceRequest,
new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.d("SCOPE", "Added a service request.");
discoverServices();
}
#Override
public void onFailure(int code) {
Log.e("tag", "Error adding service request.");
}
});
}
public void discoverServices() {
manager.discoverServices(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.d("tag", "Service discovery was initiated");
}
#Override
public void onFailure(int code) {
// This is where it keeps failing with error code 3 (NO_SERVICE_REQUESTS)
Log.d("SCOPE", "Service discovery failure code " + code);
}
});
}
The first time I run my service after rebooting the phone, service discovery is initiated just fine, but if I kill the service by stopping it from the app settings page, then open it again, it always fails with error code 3. If I reboot my phone and run the app again it works just fine. I am confused because I am explicitly calling discoverServices only when the service request has been successfully added.
My hunch is that it may be due to some code that is unrelated to service discovery because the service discovery code seems extremely straightforward, but if you see anything wrong with what I've posted, let me know. I'm grasping at straws here.
I'm running this on a Nexus 5 with Android 4.4.2.

I'm seeing this same problem on a second generation Nexus 7. It works fine the first time, subsequent attempts error out. Specifically, the addServiceRequest action listener reports success, but then discoverServices reports NO_SERVICE_REQUESTS.
(Teardown removeLocalService and removeServiceRequest succeed before exiting the app after the initial successful use.)
While it isn't an ideal answer, toggling wifi off then on again appears to reset whatever is stuck. That can be done programatically.

WifiDirect/NSD on Android has been a thorn in my side for the last couple of weeks.
I spent half of last week trying to figure out why my peer discovery calls would fail without any consistency with NO_SERVICE_REQUESTS and finally found a solution that works fairly well. It does seem to be a bug in the OS, and luckily the fine folks of P2Feed figured out a workaround:
if (code == WifiP2pManager.NO_SERVICE_REQUESTS) {
// initiate a stop on service discovery
manager.stopPeerDiscovery(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
// initiate clearing of the all service requests
manager.clearServiceRequests(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
// reset the service listeners, service requests, and discovery
setServiceListeners();
}
#Override
public void onFailure(int i) {
Log.d(TAG, "FAILED to clear service requests ");
}
});
}
#Override
public void onFailure(int i) {
Log.d(TAG, "FAILED to stop discovery");
}
});
}

Related

SMS Retriever API not working in emulator

#Override
public void startClient(final Callback callback) {
SmsRetrieverClient client = SmsRetriever.getClient(context);
client.startSmsRetriever();
Task<Void> task = client.startSmsRetriever();
task.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
callback.onSuccess();
}
});
task.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
callback.onFail(e);
}
});
}
The code above is the suggested way Google encourages to use their SMS Reytriever API. This method is meant to start a client before the BroadcastReceiver looks for incoming sms messages. The problem here is that onSuccess and onFailure are never called, none of them, and only happens with a Android emulators. I put some breakpoints and logs to confirmed this, the client never notifies back what happened.
This is not a hash problem since this is only related to the initialization of the SmsRetrieverClient.
I'm really confused and don't know what's happening. To never notify a listener is a behaviour nobody would expect, I'm even thinking that this problem might be related to other factors since I recenlty formatted my computer and re-installed latest Android Studio, because before that this code was working on both emulators and physical devices.
Try removing the redundant client.startSmsRetriever(); in the second line.
Make sure the play services version on your emulator/device is > 10.2.0
You can check the play services version using -
private static final String MIN_SUPPORTED_PLAY_SERVICES_VERSION = "10.2";
public static boolean isSmsRetrieverApiAvailable(Context context) {
if (!isPlayServicesAvailable(context)) {
return false;
}
try {
String playServicesVersionName = context.getPackageManager().getPackageInfo(GoogleApiAvailability.GOOGLE_PLAY_SERVICES_PACKAGE, 0).versionName; // should be >10.2.0
return playServicesVersionName.compareTo(MIN_SUPPORTED_PLAY_SERVICES_VERSION) > 0;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
private static boolean isPlayServicesAvailable(Context context) {
GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
int resultCode = googleApiAvailability.isGooglePlayServicesAvailable(context);
return resultCode == ConnectionResult.SUCCESS;

Best way to keepAlive Connection With Xmpp Server in Android

I am working on chat application and using ejabberd saas edition as xmpp server for it. I am using smack library ver-4.2.3. To keep connection alive I am using ping manager. Here is the code I am using:
ReconnectionManager.getInstanceFor(AppController.mXmpptcpConnection).enableAutomaticReconnection();
ServerPingWithAlarmManager.onCreate(context);
ServerPingWithAlarmManager.getInstanceFor(AppController.mXmpptcpConnection).setEnabled(true);
ReconnectionManager.setEnabledPerDefault(true);
//int i = 1;
// PingManager.setDefaultPingInterval(i);
PingManager.getInstanceFor(AppController.mXmpptcpConnection).setPingInterval(300);
I am using sticky-service also for connection, but when I keep my application open (ideal-state) for 15-20 mins then the connection is lost, so I am using ping manger to resolve this issue.
Is there any other better way of doing it or ping manager is the only option?
Insted of pinging chat server constantly, you better to use ConnectionListener() in smack library. You need to use something like this:
XMPPTCPConnection connection;
// initialize your connection
// handle the connection
connection.addConnectionListener(new ConnectionListener() {
#Override
public void connected(XMPPConnection connection) {
}
#Override
public void authenticated(XMPPConnection connection, boolean resumed) {
}
#Override
public void connectionClosed() {
// when the connection is closed, try to reconnect to the server.
}
#Override
public void connectionClosedOnError(Exception e) {
// when the connection is closed, try to reconnect to the server.
}
#Override
public void reconnectionSuccessful() {
}
#Override
public void reconnectingIn(int seconds) {
}
#Override
public void reconnectionFailed(Exception e) {
// do something here, did you want to reconnect or send the error message?
}
});
Best way to keep the alive connection with XMPP server you should reconnect after every network change.
Like this:
public class NetworkStateChangeReceiver extends BroadcastReceiver {
private Context context;
private static NetworkStateChangeListener mListener;
#Override
public void onReceive(Context context, Intent intent) {
this.context = context;
try {
if (!ApplicationHelper.isInternetOn(context)) {
if (mListener != null) {
mListener.OnInternetStateOff();
}
return;
} else {
XMPPTCPConnection xmpptcpConnection = XmppConnectionHelper.getConnection();
if(!StringHelper.isNullOrEmpty(new SessionManager(context).getAuthenticationToken())) {
Intent XmppConnectionServicesIntent = new Intent(context, XmppConnectionServices.class);
context.stopService(XmppConnectionServicesIntent);
context.startService(XmppConnectionServicesIntent);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
//to initialize NetworkStateChangeListener because null pointer exception occurred
public static void setNetworkStateChangeListener(NetworkStateChangeListener listener) {
mListener = listener;
}
}
Yes, There is. Few points before the solution
Make your service STICKY, with a foreground notification as it would be necessary to work on or after Build.VERSION_CODES.O
This sticky service, you should start on every boot, via BOOT_COMPLETED intent action and starting this foreground service from receiver.
Yes, Now it is always there, Now you can always go for checking your connection
You can use google-volley for making connections and even you can communicate using it.
There is no good documentation on it, But i like it much, as it works flawlessly once added the dependency successfully.
Adding this dependency will take time as i said no good documentation..
For communication :
StringRequest stringRequest = new StringRequest(Request.Method.POST, "https://oniony-leg.000webhostapp.com/user_validation.php",
new Response.Listener<String>()
{
#Override
public void onResponse(String response)
{
serverKeyResponse = response;
// get full table entries from below toast and writedb LICENSETABLE
//Toast.makeText(getActivity(),response,Toast.LENGTH_LONG).show();
showKeyResponse();
// Log.d("XXXXXX XXXXX", "\n SUCCESS : "+serverKeyResponse);
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
serverKeyResponse = error.toString();
// show below toast in alert dialog and it happens on slow internet try again after few minutes
// on ok exit app
// Toast.makeText(getActivity(),error.toString(),Toast.LENGTH_LONG).show();
showKeyResponse();
//Log.d("YYYYYY YYYYYY", "\n FAILURE : "+serverKeyResponse);
}
})
{
#Override
protected Map<String,String> getParams()
{
Map<String,String> params = new HashMap<String, String>();
params.put("INPUT",LicenseKey.getText().toString());
params.put("USER", MainActivity.deviceid);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
requestQueue.add(stringRequest);
You just have to reply ECHO "SUCCESS" from server using a php ( or whatever server side language you like ). In response check for SUCCESS presence, any any other cases.., Use other KEYWORDS YOU LIKE. You can handle Server response errors too. Even you can communicate from android in request - response handshake. But you have to implement few handshake on your own.
I Hope, It helps...
Use the ReconnectionManager class as described here.
ReconnectionManager manager = ReconnectionManager.getInstanceFor(connection);
manager.enableAutomaticReconnection();
It will automatically re-connect when necessary.

WebSocketClient socket closes after the android device is kept idle for some time

I am working on an android application which has a client-server architecture. I am creating a WebSocketClient to connect to a server. Every thing works fine till I keep the device idle for sometime. When the device is kept idle for sometime, I connection with the server closes for some reason.
Refer to the following code :
WebSocketClient client = new WebSocketClient(new URI(path), draft) {
#Override
public void onMessage(String message) {
// some code here
}
#Override
public void onOpen(ServerHandshake handshake) {
// Some code here
}
#Override
public void onError(Exception ex) {
// Some code here
}
};
client.connect();
I would appreciate if someone would help me as I am not able to resolve this issue since many days.

What Payload to send to the Chromecast Default Media Receiver via Cast.CastApi.sendMessage

I have been trying to build a little test application that sends data from an android app (sender) to my chromecast. I am using the Default Media Receiver to avoid paying for registration while I learn.
All the code is implemented in an service, the receiver is found and ready but i don't know how to format the payload to actually get the Media Receiver to do anything (display images for example)
Here is a bit of code (if more is needed I gladly post it). The onConnected() method is called and runs without errors, the receiver is connected and ready, showing the chromecast symbol but the picture of which I send the URL is not shown.
private class ConnectionCallbacks implements GoogleApiClient.ConnectionCallbacks
{
#Override
public void onConnected(Bundle bundle)
{
Log.d(TAG, "on connected for callback");
Cast.CastApi.launchApplication(mApiClient,
CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID, false)
.setResultCallback(new ResultCallback<Cast.ApplicationConnectionResult>()
{
#Override
public void onResult(Cast.ApplicationConnectionResult result)
{
Log.d(TAG, "OnResultCallback... ");
Status status = result.getStatus();
Log.d(TAG, "ApplicationConnectionResultCallback.onResult: statusCode" + status.getStatusCode());
if (status.isSuccess())
{
mApplicationStarted=true;
ApplicationMetadata applicationMetadata = result.getApplicationMetadata();
mSessionId = result.getSessionId();
String applicationStatus = result.getApplicationStatus();
boolean wasLaunched = result.getWasLaunched();
Log.d(TAG, mSessionId+" "+applicationStatus);
try
{
Cast.CastApi.sendMessage(mApiClient, "urn:x-cast:com.google.cast.media",
"http://www.randomwebsite.com/images/head.jpg")
.setResultCallback(new ResultCallback<Status>()
{
#Override
public void onResult(Status result)
{
if (!result.isSuccess())
{
Log.e(TAG, "Sending message failed");
}
}
});
}
catch(Exception e)
{
Log.e(TAG, "Sending message to chromecast failed... hard.");
}
}
}
});
}
#Override
public void onConnectionSuspended(int i)
{
Log.d(TAG, "on connection suspended for callback");
}
}
This and most of the code is similar to the https://github.com/googlecast/CastHelloText-android example from google.
My problem, I think is the line Cast.CastApi.sendMessage(mApiClient, "urn:x-cast:com.google.cast.media", "http://www.randomwebsite.com/images/head.jpg") especially the third parameter which i suspect just isn't formatted the way the Default Media Receiver expects data. However I could not find any working examples on this.
So, how does one get a working example using the Default Media Receiver to run?
If you want to send you own messages (non-media), you should create a custom receiver with your own namespace. The Default Receiver/Styled Receiver only understands media namespace and to use that namespace, do not use sendMessage; use RemoteMediaPlayer to send common actions like play/pause/stop/seek/... There are some samples on our GitHub repo.

android mqtt-client-1.5 listener with apollo

https://github.com/fusesource/mqtt-client
i have an android application starting a background service where i have initiated an mqtt connection towards an apollo broker. when startService is called im initiating the MQTT from the onStartCommand setting hostname, port username, password etc.. followed by
connection = mqtt.callbackConnection();
the connect is successfull and i can clearly see that i have a consumer on my topic "uniqueId".
But when i send messages to my topic , the listener never calles the onPublish.. Another strange occurence is that if i loose my connection towards the broker , e.g i shut down the broker so that the active connection is broken, when the mqtt-client reconnects, it seems that it calles the listener and also the onPublish because then all the messages that i have stacked on my durable subscriber topic is delivered.. am i missing anything here regarding the listener?
isnt it suppose to actively consume the topic due to connection.subscribe??
Topic[] topics = { new Topic("uniqueId", QoS.AT_LEAST_ONCE) };
connection.subscribe(topics, new Callback<byte[]>() {
public void onSuccess(byte[] qoses) {
}
public void onFailure(Throwable value) {
value.printStackTrace();
}
});
connection.listener(new Listener() {
#Override
public void onConnected() {
}
#Override
public void onDisconnected() {
}
#Override
public void onFailure(Throwable value) {
}
#Override
public void onPublish(UTF8Buffer topic, Buffer payload, Runnable ack) {
ack.run();
}
});
I'm not familiar with Apollo, but I agree that the behaviour sounds incorrect. You could try testing against another broker to see if it works as expected, then file a bug against Apollo if necessary.
You could use e.g. test.mosquitto.org:1883 to test against, or use one of the other public ones listed on mqtt.org/software

Categories

Resources