I tried to start socket connection and maintain it in a service. The service work well, but i cant connect to the my socket. Is it my code wrong or there some other way to do it?
This is my code
public class SocketService extends Service {
private Socket mSocket;
{
try {
mSocket = IO.socket("http://192.91.25.99:3000");
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mSocket.connect();
mSocket.on("message", handleIncomingMessages);
Toast.makeText(getApplicationContext(),"Start Service",Toast.LENGTH_LONG).show();
return Service.START_STICKY;
}
private Emitter.Listener handleIncomingMessages = new Emitter.Listener(){
#Override
public void call(final Object... args){
System.out.println(args[0].toString());
Toast.makeText(getApplicationContext(),"LALALALA",Toast.LENGTH_LONG).show();
}
};
}
Thanks in advance
Related
I am very beginner in Android, I am creating android application, communication with Siemens PLC its working fine but if i click button only the data shown in android , I want to run this code in service I don't know how to add code(below) in service
protected String doInBackground(String... strings) {
try{
client.SetConnectionType(S7.S7_BASIC);
int res = client.ConnectTo("10.0.2.2",0,1);
if(res == 0)
{
byte[] data = new byte[4];
res = client.ReadArea(S7.S7AreaDB,1,0,2,data);
ret = "Values "+S7.GetWordAt(data,0);
}
else {
ret = "Err:"+S7Client.ErrorText(res);
}
client.Disconnect();
}
catch (Exception e)
{
ret= "Exe"+e.toString();
Thread.interrupted();
}
return "Executed";
}
Above code is working fine but this code added to service I create one service
public class MyService extends Service {
S7Client client = new S7Client();
String ret = "";
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
PlcReader task=new PlcReader();
task.execute("");
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public class PlcReader extends android.os.AsyncTask<String,Void,String>{
#Override
protected String doInBackground(String... strings) {
try{
client.SetConnectionType(S7.S7_BASIC);
int res = client.ConnectTo("10.0.2.2",0,1);
if(res == 0)
{
byte[] data = new byte[4];
client.ReadArea(S7.S7AreaDB,1,0,4,data);
ret = "Values "+S7.GetWordAt(data,0);
}
else {
ret = "Err:"+S7Client.ErrorText(res);
}
client.Disconnect();
}
catch (Exception e)
{
ret= "Exe"+e.toString();
Thread.interrupted();
}
return "Executed";
}
#Override
protected void onPostExecute(String s) {
Toast.makeText(getApplicationContext(),ret,Toast.LENGTH_LONG).show();
}
}
I added code with service but shows connection problem
See this example:-
public class ExtractService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
AsyncTask task=new AsyncTask();
task.execute();
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public class AsyncTask extends android.os.AsyncTask<Void,Void,Void>{
#Override
protected Void doInBackground(Void... voids) {
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
}
You can call your AsyncTask from the method onStartCommand in the Service:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
new MyAsyncTask().execute("stringParameter")
return START_STICKY;
}
A couple of tips:
I see that you return a String value from your AsyncTask, just avoid using
String result = new MyAsyncTask().execute("stringParameter").get()
As it will block your main thread (unless you start your async task in a different thread).
A more appropriate solution is to handle the result in the onPostExecute method in your AsyncTask (just override it)
Another thing to think about is that AsyncTask is deprecated in Android R, some good alternatives are the java.util.concurrent package and RxJava library
I created a service class in my application to run some task in the background. When I close the application the service still running and it's ok. But the problem is, When I run the application again, a new service running and every time when I restart the application a new service create. Here's my code
public class myService extends Service {
Socket socket;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
connectSocket();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
socket.disconnect();
}
private void connectSocket() {
try {
socket = IO.socket("http://192.168.1.52:2500");
socket.on(Socket.EVENT_CONNECT, onConnected);
socket.on(Socket.EVENT_CONNECT_ERROR, onConnectionError);
socket.on(Socket.EVENT_CONNECT_TIMEOUT, onConnectionTimout);
socket.on(Socket.EVENT_DISCONNECT, onDisconnect);
socket.on("test_callback", eventCallback );
socket.connect();
} catch (URISyntaxException e) {
Log.d(getClass().getSimpleName(), "Socket Connection Exception");
e.printStackTrace();
}
}
private Emitter.Listener onConnected = new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.d("SocketIO","onConnected");
socket.connect();
}
};
private Emitter.Listener onConnectionError = new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.d("SocketIO","onConnectionError");
socket.connect();
}
};
private Emitter.Listener onConnectionTimout = new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.d("SocketIO","onConnectionTimout");
socket.connect();
}
};
private Emitter.Listener onDisconnect = new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.d("SocketIO","onDisconnect");
socket.disconnect();
}
};
int notno = 0;
private Emitter.Listener eventCallback = new Emitter.Listener() {
#Override
public void call(Object... args) {
JSONObject data = (JSONObject) args[0];
String message;
try {
message = data.getString("message").toString();
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(myService.this)
.setSmallIcon(R.drawable.head)
.setContentTitle("Message")
.setContentText(message);
NotificationManager nfm = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
nfm.notify(notno ,mBuilder.build());
notno++;
} catch (JSONException ignored) {
}
}
};
}
and in onCreate method in main class run this code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
startService(new Intent(getBaseContext(), myService.class));
}
This is by design. Every time startService is called, onStartCommand will be called. This allows it to be started wth different intents. However it will only be created once (unless stopped for resources, of course). If you want to only have a single instance of a socket or thread, its your job to make sure you only instantiate them the first time onStartCommand is called.
Also, your code as is won't work. Services do not have their own threads or processes by default. That mean you need to launch a new Thread to do your socket work, or you'll get a NetworkOnMainThreadErrror.
I am working on a Chat messenger.I have used socket.io-client library.I have created a service that will instantiate Socket class.
SocketService.java
public class SocketService extends Service {
public static Socket mSocket;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
String data = intent.getStringExtra("Socket");
Log.e("intent data", data);
Log.e("Service", "Called");
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onCreate() {
super.onCreate();
Log.e("Service", "created");
try {
mSocket = IO.socket(Constants.CHAT_SERVER_URL);
Log.e("ValueSocket", String.valueOf(mSocket));
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
I am starting the service in SplashActivity.java.I have to pass Socket instance i.e. mSocket to Activity SplashActivity.java .How can i achieve this in android?Please help .
Trying to keep an xmpp connection alive using a service in android
public class XMPPService extends Service {
XMPPTCPConnection connection;
String USERNAME;
String PASSWORD;
public XMPPService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
onHandleIntent();
return START_STICKY;
}
private void onHandleIntent() {
connection = XMPPClient.getConnection();
connection.addConnectionListener(
new AbstractConnectionListener() {
public void connectionClosed() {
Log.i("connection", "closed");
}
public void connectionClosedOnError(Exception e) {
Log.i("connection", "closed on error");
}
public void reconnectionFailed(Exception e) {
Log.i("reconnection", "failed");
}
public void reconnectionSuccessful() {
if (connection.isAuthenticated()) {
Log.i("isauthenticauted : ", String.valueOf(connection.isAuthenticated()));
Log.i("reconnection", "succesful");
} else {
try {
connection.login(USERNAME, PASSWORD);
} catch (XMPPException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Log.i("reconnection", "succesful");
}
}
public void reconnectingIn(int seconds) {
Log.i("reconnectingIn", String.valueOf(seconds));
}
}
);
}
#Override
public void onCreate() {
Log.i("service", "created");
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
My service restarts when I kill my app. Why is this happening? When I restart it gives me an exception NetworkOnMainThreadException at connection = XMPPClient.getConnection();
I don't want my service to restart when I kill my app.
The START_STICKY flag causes your service to auto-restart when it's destroyed. Your onstartCommand should return START_NOT_STICKY instead of START_STICKY.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
onHandleIntent();
return START_NOT_STICKY;
}
Make use of START_NOT_STICKY in the onStartCommand(Intent, int, int) function of your service.
example:
public static final int START_NOT_STICKY http://developer.android.com/reference/android/app/Service.html
I am creating bound service for socket connection.Which means it is creating a long polling connection and listens my server.If user closes the app in task manager my service is killing i have no problem with this.But when user presses the back button I am calling activity.finish() method for close app.But with this method my service doesn't kill,it is still connected to socket server.
Is this normal ? And Could be this drain the battery ?
My service:
public class SocketService extends Service {
//you need constants to tell servise and activity what you are sending a message for
public static final int REGISTER_CHAT_ACTIVITY = 1;
public static final int MESSAGE_RECEIVED = 2;
final Messenger mMessenger = new Messenger(new IncomingHandler());
Messenger chat;
private Socket socket;
#Override
public void onCreate() {
try {
socket = IO.socket("ip");
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
}
}).on("connected", new Emitter.Listener() {
#Override
public void call(Object... args) {
}
}).on("message", new Emitter.Listener() {
#Override
public void call(Object... args) {
try {
chat.send(android.os.Message.obtain(null, MESSAGE_RECEIVED, args[0]));
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
//and add all the other on listeners here
socket.connect();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (socket != null) {
socket.disconnect();
socket.connect();
} else {
try {
socket = IO.socket("ip");
socket.connect();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
class IncomingHandler extends Handler {
#Override
public void handleMessage(android.os.Message msg) {
switch(msg.what){
case REGISTER_CHAT_ACTIVITY:
chat = msg.replyTo;
break;
}
}
}
public class LocalBinder extends Binder {
SocketService getService() {
return SocketService.this;
}
}
}
I had something similar a while ago i solved the issue by using shared preferences.(Note: I dont think it's the best answer but it solved my problem)
I saved in preferences a boolean to register when i dont need the service anymore but lost reference of it.
public class YourService extends Service {
private YourService serv;
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
serv = this;
Then Somehwere on your code that the service does frequently.
if(!sharedPref.getBoolean("TurnOffService", false)){
serv.stopSelf();
}
Hope it helps.