Best practice for closing websocket in android - android

I am using this library for connecting to a websocket server from android.
Specifically this part :
AsyncHttpClient.getDefaultInstance().websocket("ws://192.168.2.10:8000/temp" , "my-protocol", new WebSocketConnectCallback() {
#Override
public void onCompleted(Exception ex, WebSocket webSocket) {
if (ex != null) {
ex.printStackTrace();
return;
}
webSocket.send("a string");
webSocket.setStringCallback(new StringCallback() {
#Override
public void onStringAvailable(String s) {
Debug.Log( LOGTAG ,"I got a string: " + s);
}
});
webSocket.close(); // issue here
}
});
I would like to close the socket when I click a button. Now everytime I want to send a message to the socket I open it and close it.
I would like to open it once and keep it alive and close it when I click a close button. My idea was to pass a variable to the WebSocketConnectCallback and make a static variable and based on this variable close the socket.
I would like to know what is the best practice in a situation like this.

Use the Application class (http://developer.android.com/reference/android/app/Application.html):
Inherid your own class for Application and here you can track the socket, open it, close it as you need.
See a tutorial (first google match, maybe there is a better one): http://www.intertech.com/Blog/androids-application-class/
So basically extend Application and add your class in the manifest file as application class.
Your may add a timer that might close the socket after several time while not used.

Related

LibGDX http request not working

I want to send a String message to database when user presses a specific button in the LibGDX game I am designing for android. How do I go about doing that? Following is the code I tried. But it does not work.
Net.HttpRequest httpRequest = new Net.HttpRequest();
httpRequest.setMethod("POST");
httpRequest.setUrl("URL is here");
httpRequest.setContent("INSERT INTO `game_table` (`Button`) VALUES ('Button 1 Pressed')");
Net.HttpResponseListener httpResponseListener = new Net.HttpResponseListener() {
#Override
public void handleHttpResponse(Net.HttpResponse httpResponse) {
Gdx.app.log("Log httpResponse", httpResponse.getResultAsString());
}
#Override
public void failed(Throwable t) {
}
#Override
public void cancelled() {
}
};
Gdx.net.sendHttpRequest(httpRequest,httpResponseListener);
Log does not provide anything in android monitor. I also tried using AsyncTask and without AsyncTask to implement this code. But neither works.
Am I missing something? If so could you give me small code snippet that will work?
You don't need to use an AsyncTask, libGDX' HTTPRequest is async out of the box.
You did not log anything if the request fails or is cancelled so probably that's the case.

How to call an Android app's method remotely?

I'm working on a project that improves Automation Test for Android's App. What I want to do is very "easy": I have this very simple SIP Client with a basic UI and developed just reading the API guides on the android developer website (https://developer.android.com/guide/topics/connectivity/sip.html) that receives and makes SIP calls.
I need to control remotely this app from my PC, connected at the same local network or the same wifi, by sending commands or similar (without interact with the phone) to the app itslef running normally on my phone.For a specific example I posted the method initiateCall() that calls sipAddress(in the app, sipAddress is taken from a Text Box), what I want to do is:
Starting the app on my phone
calling the method initiateCall() from my pc giving a sipAddress as a parameter (I must not use the UI from the app running, that's why I need to give the sipAddress)
check if an outgoing call starts from the app running on my phone
I thought that the solution must be something about web-services,but I don't have any better ideas and i don't know how to start and where to start solving this problem,that's why i need you help.
public void initiateCall() {
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
// set up the listener for outgoing calls
#Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
updateStatus(call, 2);
}
#Override
public void onCallEnded(SipAudioCall call) {
updateStatus("Call End");
}
};
call = manager.makeAudioCall(me.getUriString(), sipAddress,
listener, 30);
} catch (Exception e) {
Log.i("WalkieTalkieActivity/InitiateCall",
"Error when trying to close manager.", e);
if (me != null) {
try {
manager.close(me.getUriString());
} catch (Exception ee) {
Log.i("WalkieTalkieActivity/InitiateCall",
"Error when trying to close manager.", ee);
ee.printStackTrace();
}
}
if (call != null) {
call.close();
}
}
}
You could do it REST API style. You would need to set up a minimalistic webserver.
If you access for example the url phoneip/ctrl/makecall?number=yournumber a serverside method us called if set up correctly. Then you can call you method and use the GET or POST variables as arguments.
You would have to look into Java Webserver Libraries/Frameworks. You can pick a lightweight one for that purpose. For example this one.
You could then also add security features (authentification to protect it) quite easily.
Example with sparkjava
import static spark.Spark.*;
....
get("/ctrl/makecall", (request, response) -> {
String phonenum = request.queryParams("number"); //may not be accurate; you have to determine the GET variable called "number" in that case; you can rename it; see docs!!!
//call your method with proper arguments
});

Robospice service running until it finish it job after application finished

I have an application that access to a server. When I quit the application, I have to disconnect from the server first, then close the application.
I would like to know if it's possible (and how) to make a Robospice service (background task) that disconnect from the server even if the application is closed (and the Robospice service is still running to finish the deconnection, and then auto kill itself after).
The problem is that the deconnection is too long (sometimes more than 5 secondes) and I would like to avoid blocking the phone during the deconnection, and allow the user to use it's phone.
Another question : is the Robospice librairy will be maintained and improved in the future (if necessary) ?
Yes, RoboSpice works just as well when attached to a Service Context as it works with an Activity one.
But you should probably try executing disconnect in the com.octo.android.robospice.SpiceService#onDestroy method of your implementation. This service is stopped whenever it has no meaningful work to do, so I guess it is the most appropriate solution for your use case.
I've solved my problem (that may be wasn't really a problem !) by ending my application with finish()
In my MainActivity, I use a Robospice service :
private final class LogoutListener implements PendingRequestListener<String> {
#Override
public void onRequestFailure(SpiceException spiceException) {
Log.e(TAG, spiceException.getMessage());
}
#Override
public void onRequestSuccess(String result) {
// nothing special
}
#Override
public void onRequestNotFound() {
Log.w(TAG, "Not found");
}
}
private void Alarm_Logout(boolean exit) {
Logout request = new Logout(url);
spiceManager.execute(request, new LogoutListener());
this.finish();
}
And the Lougout class :
public class Logout extends OkHttpSpiceRequest<String> {
private String url_logout;
public Logout(String url) {
super(String.class);
this.url_logout = url;
}
#Override
public String loadDataFromNetwork() throws Exception {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url_logout)
.build();
Response response = client.newCall(request).execute();
return "ok";
}
}
Before I closed the app with System.exit(0) in onRequestSuccess, so I had to wait the Logout complete. Now the app close (with finish()), but the Logout continue in background, and then, when done, the service finish...

AndroidAsync Socket.IO receive callback value

I'm trying to build an application for Android using this library: https://github.com/koush/AndroidAsync and I was trying to receive a callback value from the server like this but the app crashes:
client.emit("callbackTry", new Acknowledge() {
#Override
public void acknowledge(JSONArray arg0) {
Log.e(TAG,"acknowledge: "+ arg0);
}
});
I leave you the server-side:
socket.on('callbackTry', function (callback) {
console.log(callback);
var hello = "Hello";
callback(hello);
});
How can I return the data back to the client?
I found a solution myself which consists on changing emit method to emitEvent. Hope it really help someone else too.

Unlocking achievement in OpenFeint

I'm very new to OpenFeint, actually started integrating it into my game today. I can't understand one simple thing that every OpenFeint using developer should probably know. Here's the example of unlocking an achievement from OpenFeint official tutorial:
new Achievement("achievementID").unlock(new Achievement.UnlockCB () {
#Override public void onSuccess() {
MyClass.this.setResult(Activity.RESULT_OK);
MyClass.this.finish();
}
#Override public void onFailure(String exceptionMessage) {
Toast.makeText( MyClass.this,
"Error (" + exceptionMessage + ") unlocking achievement.",
Toast.LENGTH_SHORT).show();
MyClass.this.setResult(Activity.RESULT_CANCELED);
MyClass.this.finish();
}
});
Problem is that I don't want to finish my activity in onSuccess or onFailure, I just don't need to do anything here. If I just leave these two methods codeless, my game freezes an becomes totally unresponsive. What should I do? Thanks in advance.
P.S. How do you create Test Users? I've tryed every email-password combination possible and could not get it to go..
Its generally a good idea to put all your communication with the internet in a AsyncTask. Not everyone has fast internet, so this will make sure the main thread doesn't lock up because of that.
That being said, I think that the setResult function is used in a startActivityForResult construction. The intent that is created in this way is only sent back to the original class if the activity is finished. So to fix this you would need to put the code in a separate activity.
I simply wrote this method in my Utility class
public static void unlockAchievement(final String achievementId, final Activity context){
final Achievement achievement = new Achievement(achievementId);
achievement.unlock(new Achievement.UnlockCB() {
#Override
public void onSuccess(boolean newUnlock) {
context.setResult(Activity.RESULT_OK);
}
#Override
public void onFailure(String exceptionMessage) {
context.setResult(Activity.RESULT_CANCELED);
Toast.makeText(context, "Error (" + exceptionMessage + ") unlocking achievement.", Toast.LENGTH_SHORT).show();
FlurryAgent.onError("unlockingAchievement", exceptionMessage, this.getClass().getSimpleName());
}
});
}

Categories

Resources