Android Question JavaObject not works in Android 14

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
Hi,

Hello,

My app works perfectly on Android version 9 and older. However, starting from version 14, an issue occurs that causes the app to crash.

I would appreciate support in solving this problem.

B4X:
Dim socket As JavaObject = r.GetField("socket")
Dim jo As JavaObject = Me
 jo.RunMethod("setKeepaliveSocketOptions", Array(socket, 1000, 1000, 3))


I didn’t have any problems with this on Android 9.
 

aeric

Expert
Licensed User
Longtime User
I suggest you share the error message that you get.
Can it be changes in protocol?
 
Upvote 0

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
"Is there a way to modify this code so that it also runs on Android 14?"

B4X:
Dim r As Reflector
    r.Target = Socket1
    Dim socket As JavaObject = r.GetField("socket")
    Dim jo As JavaObject = Me
    jo.RunMethod("setKeepaliveSocketOptions", Array(socket, 1000, 1000, 3))
 
Upvote 0

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
Error MSG

winsock_subcalling (java line: 1543)
java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:132)
at yamutec.app.winsock._subcalling(winsock.java:1543)
at yamutec.app.winsock._astreams_newdata(winsock.java:397)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:221)
at anywheresoftware.b4a.BA$2.run(BA.java:395)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:8919)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Caused by: java.lang.NoSuchMethodException: libcore.io.ForwardingOs.setsockoptInt [class java.io.FileDescriptor, int, int, int]
at java.lang.Class.getMethod(Class.java:2937)
at java.lang.Class.getDeclaredMethod(Class.java:2914)
at yamutec.app.winsock.setKeepaliveSocketOptions(winsock.java:2009)
... 15 more
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:258)
at anywheresoftware.b4a.BA$2.run(BA.java:395)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:8919)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:132)
at yamutec.app.winsock._subcalling(winsock.java:1543)
at yamutec.app.winsock._astreams_newdata(winsock.java:397)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:221)
... 9 more
Caused by: java.lang.NoSuchMethodException: libcore.io.ForwardingOs.setsockoptInt [class java.io.FileDescriptor, int, int, int]
at java.lang.Class.getMethod(Class.java:2937)
at java.lang.Class.getDeclaredMethod(Class.java:2914)
at yamutec.app.winsock.setKeepaliveSocketOptions(winsock.java:2009)
... 15 more
** Activity (input_output) Create (first time) **
** Activity (input_output) Resume **
Connected with Modulname wird in das LABEL geschrieben
Connected with Modulname wird in das LABEL geschrieben
** Activity (input_output) Pause, UserClosed = false **
** Activity (main) Create (first time) **
The time now is: 11/07/2024 - 16:36:57
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (generalsettings) Create (first time) **
 
Upvote 0

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
This

B4X:
Dim r As Reflector
    r.Target = Socket1
    Dim socket As JavaObject = r.GetField("socket")
    Dim jo As JavaObject = Me
    jo.RunMethod("setKeepaliveSocketOptions", Array(socket, 1000, 1000, 3))


And this one:
B4X:
Service.StartForeground(1,Notification1)

and this one
B4X:
StartService(Winsock)
 
Upvote 0

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
1. The notifications are no longer displayed in Android 14.
2. In addition, the app crashes immediately as soon as the StartService(Winsock) function is called.
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
2. In addition, the app crashes immediately as soon as the StartService(Winsock) function is called.
Hiding the full error is a good way not to get help.

What about posting the relevant code AND the full error? This may help to understand the problem.
 
Upvote 0

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
I try to call this Method, and in this case the App crashed up

B4X:
Sub Activity_Click
   Dim s As Socket
   s.Initialize("S")
   Dim r As Reflector
   r.Target = s
   Dim socket As JavaObject = r.GetField("socket")
   Dim jo As JavaObject = Me
   jo.RunMethod("setKeepaliveSocketOptions", Array(socket, 1000, 1000, 3))
End Sub

#if Java

import java.io.FileDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.Socket;
private final static int SOL_TCP = 6;
     private final static int TCP_KEEPIDLE = 4;
     private final static int TCP_KEEPINTVL = 5;
     private final static int TCP_KEEPCNT = 6;

public static void setKeepaliveSocketOptions(Socket socket, int idleTimeout, int interval, int count) throws Exception{
      socket.setKeepAlive(true);
      Field socketImplField = Class.forName("java.net.Socket").getDeclaredField("impl");
      socketImplField.setAccessible(true);
      if(socketImplField != null) {
      Object plainSocketImpl = socketImplField.get(socket);
      Field fileDescriptorField = Class.forName("java.net.SocketImpl").getDeclaredField("fd");
      if(fileDescriptorField != null) {
      fileDescriptorField.setAccessible(true);
      FileDescriptor fileDescriptor = (FileDescriptor)fileDescriptorField.get(plainSocketImpl);
      Class libCoreClass = Class.forName("libcore.io.Libcore");
      Field osField = libCoreClass.getDeclaredField("os");
      osField.setAccessible(true);
      Object libcoreOs = osField.get(libCoreClass);
      Method setSocketOptsMethod = Class.forName("libcore.io.ForwardingOs").getDeclaredMethod("setsockoptInt", FileDescriptor.class, int.class, int.class, int.class);
      if(setSocketOptsMethod != null) {
      setSocketOptsMethod.invoke(libcoreOs, fileDescriptor, SOL_TCP, TCP_KEEPIDLE, idleTimeout);
      setSocketOptsMethod.invoke(libcoreOs, fileDescriptor, SOL_TCP, TCP_KEEPINTVL, interval);
      setSocketOptsMethod.invoke(libcoreOs, fileDescriptor, SOL_TCP, TCP_KEEPCNT, count);
      }
      }
      }
     }
#End If
 
Upvote 0

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
Hi,

if I do this so:


JavaScript:
#Region "KeepAlive"
#if Java

import java.io.FileDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.Socket;
private final static int SOL_TCP = 6;
     private final static int TCP_KEEPIDLE = 4;
     private final static int TCP_KEEPINTVL = 5;
     private final static int TCP_KEEPCNT = 6;

public static void setKeepaliveSocketOptions(Socket socket, int idleTimeout, int interval, int count) throws Exception{
    try{
      socket.setKeepAlive(true);
      try {
      Field socketImplField = Class.forName("java.net.Socket").getDeclaredField("impl");
      socketImplField.setAccessible(true);
      if(socketImplField != null) {
      Object plainSocketImpl = socketImplField.get(socket);
      Field fileDescriptorField = Class.forName("java.net.SocketImpl").getDeclaredField("fd");
      if(fileDescriptorField != null) {
      fileDescriptorField.setAccessible(true);
      FileDescriptor fileDescriptor = (FileDescriptor)fileDescriptorField.get(plainSocketImpl);
      Class libCoreClass = Class.forName("libcore.io.Libcore");
      Field osField = libCoreClass.getDeclaredField("os");
      osField.setAccessible(true);
      Object libcoreOs = osField.get(libCoreClass);
      Method setSocketOptsMethod = Class.forName("libcore.io.ForwardingOs").getDeclaredMethod("setsockoptInt", FileDescriptor.class, int.class, int.class, int.class);
      if(setSocketOptsMethod != null) {
      setSocketOptsMethod.invoke(libcoreOs, fileDescriptor, SOL_TCP, TCP_KEEPIDLE, idleTimeout);
      setSocketOptsMethod.invoke(libcoreOs, fileDescriptor, SOL_TCP, TCP_KEEPINTVL, interval);
      setSocketOptsMethod.invoke(libcoreOs, fileDescriptor, SOL_TCP, TCP_KEEPCNT, count);
      }
        }
      }
    }
    catch (Exception reflectionException) {}
  } catch (SocketException e) {}
}
#End If
#End Region

then I get a copiler error:
B4A Version: 13.00
Parse den Code. (0.15s)
Java Version: 19
Building folders structure. (0.09s)
Kompiliere den Code. (0.20s)
Kompiliere Layoutcode. (0.03s)
Organisiere Libraries. (0.00s)
(AndroidX SDK)
Ressourcen zusammenstellen (0.05s)
Ressourcen verknüpfen (0.43s)
build tools: 34.0.0, android jar: android-34
Kompiliere generierten Java Code. Error
src\app\winsock.java:2037: Fehler: Symbol nicht gefunden
} catch (SocketException e) {}
^
Symbol: Klasse SocketException
Ort: Klasse winsock
Hinweis: src\app\winsock.java verwendet oder überschreibt eine veraltete API.
Hinweis: Wiederholen Sie die Kompilierung mit -Xlint:deprecation, um Details zu erhalten.
1 Fehler
 
Upvote 0

SJQ

Member
Licensed User
Longtime User
As a side note you should look into...

Notifications don't work as they used to, with Android 14, I think you need to use a specific permission now.

Also in Android 14, SSLv3, TSLv1.0, TSL1.1 no longer work at all.
Support stopped back in Android 8 but they still worked upto Android 14 where Google removed the protocols.
This will cause your app to crash immediately and you'll need to look through the unfiltered logs for the error.

From what I found out TSL1.2 is out of support but still in operation, TSL1.3 is supported

I've no idea how to resolve this. I did see a code snippet on the forum to set network socket protocol, not sure if it would work for your issue especially as your using a private API.

I'm still waiting on the company I work for to provide a new server and Database server to see if this resoves the issue I'm seeing.
 
Upvote 0

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
In my case the problem is the keepalive method. If I remove that, it actually works.
But I need the keepalive method to maintain the established connection.
 
  • Like
Reactions: SJQ
Upvote 0
Top