Socket.io-client-java: Socket IO Android Client Not Working In Android 8.0 Oreo Above

Created on 7 Aug 2018  路  16Comments  路  Source: socketio/socket.io-client-java

Notification with socketIO not work with app that target Android 8.0 above. This because behavior changes in Android 8.x for background executing limit and start using JobScheduler.

Any work around for this?
Or we shoudl migrate to Firebase Cloud Messaging ?

Most helpful comment

@jenrus00 Thanks for the information. I have added below code in AndroidManifest.xml . Issue got fixed.
android:usesCleartextTraffic="true">

All 16 comments

What do you mean by "target Android 8.0", do you refer to the SDK version ?

Yes, Android SDK version 8.0 above. Socket IO Service is not running, because background execution limits in newest Android API.

Reference
https://developer.android.com/about/versions/oreo/android-8.0-changes

Notifications are working except for background services. If you can live with a permanent notification for your app, a possible workaround is to use startForegroundService.

i Have Done some of stuff and working fine in background and forground but when i kill it will not working.

public class ChatServiceWorker extends Worker {

private static final String TAG = "SocketService";

private Socket mSocket;

private Context mContext;

private NotificationManager notificationManager;

private NotificationCompat.Builder notificationBuilder;

private int currentNotificationID = 0;

@NonNull
@Override
public Result doWork() {

mContext = getApplicationContext();

notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);

try {
    IO.Options opts = new IO.Options();
    opts.reconnection = true;
    mSocket = IO.socket(Constants.CHAT_SERVER_URL, opts);
} catch (URISyntaxException e) {
    throw new RuntimeException(e);
}
initSocket();


return Result.SUCCESS;

}

private void initSocket() {
mSocket.connect();
mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
mSocket.on(Socket.EVENT_CONNECT, onConnect);
mSocket.on(Socket.EVENT_RECONNECT, onConnect);
mSocket.on(Socket.EVENT_DISCONNECT, onConnectError);

//I send the an auth event to the socket.io server

// auth();
mSocket.on("chat message", onReceived);
}

private Emitter.Listener onConnect = new Emitter.Listener() {
@Override
public void call(Object... args) {
Log.d(TAG, "connected " + mSocket.connected());
}
};

private Emitter.Listener onConnectError = new Emitter.Listener() {
@Override
public void call(Object... args) {
Log.d(TAG, "error " + args[0].toString());
}
};

private Emitter.Listener onReceived = new Emitter.Listener() {
@Override
public void call(final Object... args) {
Log.d(TAG, "received rtm");
// I parse the object...
// binder.messageArrived(args[0].toString() + "," + args[1].toString());

    Intent i = new Intent(Constants.ACTION_DASHBOARD_CONTENT);
    i.putExtra(Constants.RECEIVED_USERNAME, args[0].toString());
    i.putExtra(Constants.RECEIVED_MESSAGE, args[1].toString());
    LocalBroadcastManager.getInstance(mContext).sendBroadcast(i);

/*    Data output = new Data.Builder()
            .putString(Constants.RECEIVED_USERNAME, args[0].toString())
            .putString(Constants.RECEIVED_MESSAGE, args[1].toString())
            .build();

    setOutputData(output);*/

    setDataForSimpleNotification(args[1].toString());
}

};
/* @subscribe
public void sendMessage(SendMessageEvent event) {
mSocket.emit("send", event.getMessage());
}*/

/* @override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
mSocket.disconnect();
mSocket.off(Socket.EVENT_CONNECT_ERROR, onConnectError);
mSocket.off(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
mSocket.off(Socket.EVENT_CONNECT, onConnect);
mSocket.off("chat message", onReceived);

// mBus.getInstance().unregister(this);
}*/

/* @override
public IBinder onBind(Intent intent) {
return binder;
}
*/
private void setDataForSimpleNotification(String message) {
notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(mContext)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Chat")
.setContentText(message);
sendNotification();
}

private void sendNotification() {
Intent notificationIntent = new Intent(mContext, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.setContentIntent(contentIntent);
Notification notification = notificationBuilder.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_SOUND;
currentNotificationID++;
int notificationId = currentNotificationID;
if (notificationId == Integer.MAX_VALUE - 1)
notificationId = 0;
notificationManager.notify(notificationId, notification);
}

public void sendMessage(String variable,String mUsername , String message){

if (!mSocket.connected()) return;

mSocket.emit(variable, mUsername , message);

}
}

calling from Fragment

Constraints myConstraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();

OneTimeWorkRequest compressionWork =
        new OneTimeWorkRequest.Builder(ChatServiceWorker.class)
                .setConstraints(myConstraints)
                .build();
WorkManager.getInstance().enqueue(compressionWork);

any help will be appreciated.

Thank you.

Instead of running a background service for notification use FCM + Socket.IO
if(app is in foreground&& user is online){
connect socket;
}else{
send FCM message(clicking on FCM notification will open it and connect the socket)
}

Yes, the solution is must involved in Firebase Cloud Messaging too.
if app is going background or getting killed by System.

excuse me, can someone answer my question? If I make an android project and with minsdk is 24 and target is 25 (which mean around android 7), can I still use socketio library to make a service run in background with START_STICKY?

maybe. You can run the socket.io in the background in Oreo using a persistent notification. e.g(gmap, music player).

Socket.io not working on Android 9 (API level 28) .Please share any work around .

If anyone have a problem with socket.io implementation in android api 24: https://developer.android.com/training/articles/security-config#CleartextTrafficPermitted

Socket.io not working on Android 9 (API level 28) .Please share any work around .

It should work. Please explain the problem

@jenrus00 Thanks for the information. I have added below code in AndroidManifest.xml . Issue got fixed.
android:usesCleartextTraffic="true">

@sudhashini thank you!

@kishan2612 issue with socket io for Android 9:

  • It works fine when the app is in background, i m using it in foreground service. But when the phone goes to sleep mode and if internet reconnects, the socket fails to reconnect, 70% of the time. The moment phone wakes up, the socket reconnects.
    Can u see how it can be resolved?
  • one more question please.. When i call connect() two times to trigger a reconnection, it creates two socket connections. How can i avoid this?

The solution is :
When app in background, use Firebase Service or WorkManager to periodically fetch data from Socket IO

When app in foreground, just connect to Socket IO regularly

I'm sending GPS locations through socket. I want it to work even when screen is off. Socket stops reporting few minutes of screen off. And the moment screen comes online, it starts working again. Android even stops REST API calls after few minutes.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sojharo picture sojharo  路  10Comments

emanuelet picture emanuelet  路  7Comments

AljoSt picture AljoSt  路  8Comments

jaumard picture jaumard  路  4Comments

mrgame64 picture mrgame64  路  10Comments