Android Question Please help me wrap these libraries (in java) to run on B4A

NGUYEN TUAN ANH

Active Member
Licensed User

I want to wrap these source codes to create additional libraries for B4A to serve the purpose of scientific research on GNSS satellite positioning technology in Vietnam
I only have a small budget of 30$, please help me
Thank you very much.
1729739349769.png
 
Last edited:

drgottjr

Expert
Licensed User
Longtime User
the attached will get you past the "org.orekit.errors.OrekitException: unknown navigation system: QZSS" exception. this exception is limited to the ntripclient part of your app. it has nothing to do with the very exhaustive example posted by @Johan Schoeman. i've used reflection to modify the navigation systems accepted. note: orekit also has a satellitesystem enum elsewhere. i don't know if this has to be changed as well. this change was not easy; it should be worth at least 20 years off my expected punishment in hell. just sayin'.

run the example as is. you will see the original navigation systems and then the modified systems. after that has completed successfully, you can download your sourcetable data and process it. there should be no exception. what comes next in your project, i cannot say.
 

Attachments

  • ntrip.png
    ntrip.png
    51.8 KB · Views: 68
  • ntrip2.zip
    2.7 KB · Views: 48
Upvote 0

NGUYEN TUAN ANH

Active Member
Licensed User
the attached will get you past the "org.orekit.errors.OrekitException: unknown navigation system: QZSS" exception. this exception is limited to the ntripclient part of your app. it has nothing to do with the very exhaustive example posted by @Johan Schoeman. i've used reflection to modify the navigation systems accepted. note: orekit also has a satellitesystem enum elsewhere. i don't know if this has to be changed as well. this change was not easy; it should be worth at least 20 years off my expected punishment in hell. just sayin'.

run the example as is. you will see the original navigation systems and then the modified systems. after that has completed successfully, you can download your sourcetable data and process it. there should be no exception. what comes next in your project, i cannot say.
Thank you very much. Without your help, I would have struggled for another 30 years and still not finished.
I downloaded your code and ran it, it worked and no errors. But I'm really stupid about Java, so I still don't know how to download the sourcetable data? Please guide me to the last step to get the sourcetable. PS. I think I have to use SourceTable.java, but I don't know how to
 
Last edited:
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
sourcetable is downloaded by ntripclient when you call ore.runmethod("getsourcetable",null).
it is processed immediately internally and not saved. it is broken up into 3 lists, depending on how each line of sourcetable starts (eg, "STR", etc).
you cannot access sourcetable data with orekit ntripclient. i'm not sure why you even need it since orekit ntripclient downloads it by itself.

now, if you want sourcetable just because you want it for some reason, that is a different story. and if you want sourcetable in some b4x app, that
is yet another different story. i have a library which should work on b4a. i may have to recompile it for b4j, i don't know. i don't know where you
are running your project. in any case, i attach an example app (ntrip.zip) for you to run, a sample log output of the sourcetable data, and the library and its .xml. copy the library and its .xml to your additional libraries folder. run the project.

i don't know what sourcetable.java is. if it's part of orekit-12.2, i'll take a look. i know nothing about ntrip. i was interested in your post only as it related to uniting b4x with external code. i can try to help to make that possible, but i have no idea what your project does.
 

Attachments

  • ntrip.zip
    8.3 KB · Views: 50
  • ntriplite.jar
    2.9 KB · Views: 48
  • ntriplite.xml
    2 KB · Views: 52
  • ntrip-log.txt
    2.8 KB · Views: 46
Upvote 0

NGUYEN TUAN ANH

Active Member
Licensed User
sourcetable is downloaded by ntripclient when you call ore.runmethod("getsourcetable",null).
it is processed immediately internally and not saved. it is broken up into 3 lists, depending on how each line of sourcetable starts (eg, "STR", etc).
you cannot access sourcetable data with orekit ntripclient. i'm not sure why you even need it since orekit ntripclient downloads it by itself.

now, if you want sourcetable just because you want it for some reason, that is a different story. and if you want sourcetable in some b4x app, that
is yet another different story. i have a library which should work on b4a. i may have to recompile it for b4j, i don't know. i don't know where you
are running your project. in any case, i attach an example app (ntrip.zip) for you to run, a sample log output of the sourcetable data, and the library and its .xml. copy the library and its .xml to your additional libraries folder. run the project.

i don't know what sourcetable.java is. if it's part of orekit-12.2, i'll take a look. i know nothing about ntrip. i was interested in your post only as it related to uniting b4x with external code. i can try to help to make that possible, but i have no idea what your project does.
Thank you, "i have a library which should work on b4a". I really need this, if you share with me the Ntrip library that runs in B4A, it would be great.
 
Last edited:
Upvote 0

NGUYEN TUAN ANH

Active Member
Licensed User
sourcetable is downloaded by ntripclient when you call ore.runmethod("getsourcetable",null).
it is processed immediately internally and not saved. it is broken up into 3 lists, depending on how each line of sourcetable starts (eg, "STR", etc).
you cannot access sourcetable data with orekit ntripclient. i'm not sure why you even need it since orekit ntripclient downloads it by itself.

now, if you want sourcetable just because you want it for some reason, that is a different story. and if you want sourcetable in some b4x app, that
is yet another different story. i have a library which should work on b4a. i may have to recompile it for b4j, i don't know. i don't know where you
are running your project. in any case, i attach an example app (ntrip.zip) for you to run, a sample log output of the sourcetable data, and the library and its .xml. copy the library and its .xml to your additional libraries folder. run the project.

i don't know what sourcetable.java is. if it's part of orekit-12.2, i'll take a look. i know nothing about ntrip. i was interested in your post only as it related to uniting b4x with external code. i can try to help to make that possible, but i have no idea what your project does.
Thank you very much, great, i have repeared your code:
repeare your code:
Sub Button1_Click
'    ntriplite.readFromSocket("192.106.234.17", 2101, "HTTP/1.1")
    ntriplite.readFromSocket("14.238.1.125", 2101, "HTTP/1.1")
    wait for ntlite_sourcetable(data As String)
    'Log(data)
    Dim Lmpt As List
    Lmpt.Initialize
    Dim St() As String = Regex.Split(CRLF,data)
    Dim i As Int
    For i = 0 To St.Length - 1
        If St(i).StartsWith("STR") Then
            Dim St1() As String = Regex.Split(";",St(i))
            'Log(St1(1))
            Lmpt.Add(St1(1))
        End If
    Next
End Sub
 
Upvote 0

NGUYEN TUAN ANH

Active Member
Licensed User
@drgottjr, you are my friend, are you come from Ukraine ? I know the Ukrainian people are very good, in the past, Ukrainian experts have helped Vietnam a lot. Currently your country is facing many difficulties, but you are very resilient.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
with regard to post #21, my inline java snippet works with b4j. it does not work as is with b4a because one of the elements referenced in the snippet does not exist in android's implementation of reflection. below please find a suitable inline snippet which does work in b4a.

B4X:
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.util.List;
import java.util.ArrayList;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.HashMap;

    public static void listEnums( Object o) {
        try {
            // Obtain the Class object for the enum
            Class<?> c = (Class) o;   //Class.forName("NavigationSystem");
            BA.Log("class: " + c.getCanonicalName());
           
            // Get the enum constants
            Object[] constants = c.getEnumConstants();
            System.out.println("Enum Constants:");
            for (Object constant : constants) {
                System.out.println(" - " + constant);
            }

            Field[] flds = c.getDeclaredFields();
       
            List<Field> cst = new ArrayList<Field>();  // enum constants
            List<Field> mbr = new ArrayList<Field>();  // member fields
       
            for (Field f : flds) {
                if (f.isEnumConstant()) {
                    cst.add(f);
                }
                else {
                    mbr.add(f);
                    if (f.toString().contains("KEYWORDS_MAP")) {
                        BA.Log("found keywords map");
                        f.setAccessible(true);
                        BA.Log("setaccessible");
                       
                        //NOTE: ANDROID DOES NOT HAVE A "MODIFIERS" FIELD
                        //      THIS CODE WORKED IN B4J.  APPARENTLY NOT
                        //      NEEDED IN B4A (OR EVEN LEGAL)
                /*      
                        Field modifiers = Field.class.getDeclaredField("modifiers");
                        BA.Log("modifiers");
                       
                        modifiers.setAccessible(true);
                        BA.Log("set accessible");
                       
                        int mods = f.getModifiers();
                        BA.Log("modifiers: " + mods);
                       
                        modifiers.setInt(f, f.getModifiers() & ~Modifier.FINAL);
                        BA.Log("unfinalized");
                */
                       
                        BA.Log("field name: " + f.getName());
                        BA.Log("class name: " + c.getCanonicalName());
                        Map map = (Map) f.get(c);
                        BA.Log("before reflection:");
                        BA.Log("values: " + map.values());
                        BA.Log("keys: " + map.keySet());
               
                        map.put( "QZSS",  map.get("QZS") );
                   
                        BA.Log("upon reflection...");
                        BA.Log("values: " + map.values());
                        BA.Log("keys: " + map.keySet());
                    }
                }
            }
      } catch (Exception e) {
          e.printStackTrace();
      }
    }

for interested parties, orekit's library creates a map of recognized navigation systems (gps, glonoss, beidou, etc). whether by error or design, one of the systems may have been keyed incorrectly. this results in a crash when orekit's ntripclient downloads the so-called "sourcetable" data and tries to parse it. there are 4 ways to correct this (4 that i am aware of):
1) intercept the sourcetable data on download and change the unrecognized system to some that is recognized.
2) download the sourcetable separately, edit it, and repost it on your own server for download by orekit.
3) recompile the orekit library from source after editing the class that contains the errant system name.
4) use java.lan.reflect to modify the library in situ as it's running.

#1 can't be used as orekit's ntripclient downloads the data and immediately begins working on it, thus throwing the exception.
#2 i suppose this would work, although i'm not sure how it affects the realtime updating of satellite data.
#3 doesn't work with slc (file name too long error). this is presumably a job for eclipse.
#4 i went with this (not generally recommended). the part of the library that needs to be changed is declared as final and private. reflection can often get around these constraints. it can in this case. i was able to add another navigation system to orekit's code. this avoid the unrecognized system exception. what's involved is making the data object accessible and not final. since the object is a map, i added a new navigation system to it. when orekit's ntripclient downloads the data, the new system is in place, and the exception is avoided. this works as is in b4j, but android has a slightly different implementation of reflection, so i had to edited out a few lines of code which were required for b4j. to my surprise, and for whatever reason, there was no problem - ie, no exception - when the snippet was run in b4a. op seems to think the b4j version runs ok, so i'm guessing the b4a version does the same.
 
Last edited:
Upvote 0

Johan Schoeman

Expert
Licensed User
Longtime User
the attached will get you past the "org.orekit.errors.OrekitException: unknown navigation system: QZSS" exception. this exception is limited to the ntripclient part of your app. it has nothing to do with the very exhaustive example posted by @Johan Schoeman. i've used reflection to modify the navigation systems accepted. note: orekit also has a satellitesystem enum elsewhere. i don't know if this has to be changed as well. this change was not easy; it should be worth at least 20 years off my expected punishment in hell. just sayin'.

run the example as is. you will see the original navigation systems and then the modified systems. after that has completed successfully, you can download your sourcetable data and process it. there should be no exception. what comes next in your project, i cannot say.
The attached (B4J) adds to your B4J project. It extracts the data from the returned table (table returned as a JavaObject) using JavaObject.

B4X:
Sub Button1_Click
    Dim port As Int = 2101
    Dim host As String = "14.238.1.125"
    Dim ore As JavaObject
    
    Dim navigationsystem As JavaObject
    navigationsystem.InitializeStatic("org.orekit.gnss.metric.ntrip.NavigationSystem")
    
    Dim jo As JavaObject
    jo = Me
    Log("enums:")
    jo.RunMethod("listEnums",Array(navigationsystem))
    
    Dim table As JavaObject
    table.InitializeStatic("org.orekit.gnss.metric.ntrip.SourceTable")
    ore.InitializeNewInstance("org.orekit.gnss.metric.ntrip.NtripClient", Array(host, port))
    table = ore.RunMethod("getSourceTable", Null)
    Dim ll As List
    ll.Initialize
    ll = table.RunMethod("getDataStreams", Null)
    
    Log(" ")
    Dim dataStreamRecord(ll.Size) As JavaObject
    
    For i = 0 To ll.Size - 1
        dataStreamRecord(i).InitializeStatic("org.orekit.gnss.metric.ntrip.DataStreamRecord")
        dataStreamRecord(i) = ll.Get(i)
        Log(dataStreamRecord(i).RunMethod("getRecordType", Null))
        Log(dataStreamRecord(i).RunMethod("getMountPoint", Null))
        Log(dataStreamRecord(i).RunMethod("getSourceIdentifier", Null))
        Log(dataStreamRecord(i).RunMethod("getFormat", Null))
        Log(dataStreamRecord(i).RunMethod("getFormatDetails", Null))            'returns a list od StreamedMessage
        Log(dataStreamRecord(i).RunMethod("getCarrierPhase", Null))             '(NO = 0, L1 = 1, L1_L2 = 2)
        Log(dataStreamRecord(i).RunMethod("getNavigationSystems", Null))        'returns a list of NavigationSystems
        Log(dataStreamRecord(i).RunMethod("getNetwork", Null))
        Log(dataStreamRecord(i).RunMethod("getCountry", Null))
        Log(dataStreamRecord(i).RunMethod("getLatitude", Null))
        Log(dataStreamRecord(i).RunMethod("getLongitude", Null))
        Log(dataStreamRecord(i).RunMethod("isNMEARequired", Null))
        Log(dataStreamRecord(i).RunMethod("isNetworked", Null))
        Log(dataStreamRecord(i).RunMethod("getGenerator", Null))
        Log(dataStreamRecord(i).RunMethod("getCompressionEncryption", Null))
        Log(dataStreamRecord(i).RunMethod("getAuthentication", Null))            'None = N, BASIC = B, DIGEST = D
        Log(dataStreamRecord(i).RunMethod("areFeesRequired", Null))
        Log(dataStreamRecord(i).RunMethod("getBitRate", Null))
        Log(" ")
    Next
 

Attachments

  • ntrip2.zip
    3.1 KB · Views: 48
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
does work with 11. has warning.
use my latest snippet for 14 and 19.
java 8 allowed access to modifiers (eg, final). java 11 set a warning. 14, 19 don't allow access, which is how android behaves. if you use my snippet in post #28, you're good to go.
 
Upvote 0
Top