Android Question How to get Magnetic Declination from the GPS location services

Discussion in 'Android Questions' started by Angel Maza, Aug 3, 2018.

  1. Angel Maza

    Angel Maza Member Licensed User

    The GPS locations service has functions to get Lat, Lon, Bearing, Speed, etc. What seems to be missing is a way to get the magnetic declination. I tried the code below to use the native java function but it gives a compiler error code.

    How can I get the magnetic Declination at a specified Lat/Lon/Altitude?

    Thanks in advance!

    Compiler error:
    Code:
    Generating R file.    (0.69s)
    Compiling generated Java code.    Error
    javac 
    1.8.0_181
    src\com\calypsoinstruments\CalypsoUltrasonicAPI\main.java:
    1124: error: cannot find symbol
        GeomagneticField mGeoField = new GeomagneticField(Lat, Lon, Altitude, Millis);
        ^
      symbol:   class GeomagneticField
      
    location: class main
    Note: Some input files use 
    or override a deprecated API.
    Note: Recompile with -Xlint:deprecation 
    for details.
    1 error
    B4a code:
    Code:
    Public gpsManager As GPS
    Public javaInline As JavaObject
    ..
    gpsManager.Initialize(
    "GPS")
    Starter.javaInline.InitializeContext
    ...

    Sub GPS_LocationChanged(myLocation As Location)
        
    ' store the current location data in the global dictionary 'sensorData'
        sensorData.Put("LAT", myLocation.Latitude)
        sensorData.Put(
    "LON", myLocation.Longitude)
        
    If myLocation.BearingValid Then
            sensorData.Put(
    "COG", myLocation.Speed)
        
    Else
            sensorData.Put(
    "COG"0.0)
        
    End If
        
    If myLocation.SpeedValid Then
            sensorData.Put(
    "SOG", myLocation.Bearing)
        
    Else
            sensorData.Put(
    "SOG"0.0)
        
    End If
        
    If myLocation.AccuracyValid Then
            sensorData.Put(
    "STATUS", myLocation.Accuracy)
        
    Else
            sensorData.Put(
    "STATUS"0.0)
        
    End If
        
    If myLocation.AltitudeValid Then
            sensorData.Put(
    "ALT", myLocation.Altitude)
        
    Else
            sensorData.Put(
    "ALT"10.0)
        
    End If
        
    If localDeclination = 999 Then
            localDeclination = magDeclination 
    ' get the magnetic delication at the current location & altitude
        End If
        sensorData.Put(
    "DEC", localDeclination)   
    End Sub


    Sub magDeclination() As Float
        
    ' get the magnetic declination for the current location
        Dim magDec As Float = 0.0              ' default value
        #if B4A
            
    Dim millis As Long = DateTime.Now
            magDec = javaInline.RunMethod(
    "getDeclination"Array As Object(sensorData.Get("LAT"), sensorData.Get("LON"), sensorData.Get("ALT"), millis))
            
    Log("Starter->magDeclination(): mag Declination = " & magDec & " | " & millis)
        
    #end if
        
    Return magDec
    End Sub

    #If JAVA
    public float getDeclination(float Lat, float Lon, float Altitude, long Millis) {
       GeomagneticField mGeoField = new GeomagneticField(Lat, Lon, Altitude, Millis);
        return mGeoField.getDeclination();   
    }
    #End If
     
  2. DonManfred

    DonManfred Expert Licensed User

    add a
    Code:
    import android.hardware.GeomagneticField;
    to the beginning of the inline java
     
    JordiCP and Angel Maza like this.
  3. Angel Maza

    Angel Maza Member Licensed User

    DonManfred,
    that got rid of the Compiler error. Now I get the run-time error (java.lang.RuntimeException: Method: getDeclination not matched).

    Any suggestions?

    Code:
    Logger connected to:  motorola Moto G (5) Plus
    --------- beginning of crash
    --------- beginning of system
    --------- beginning of main
    *** 
    Service (starter) Create ***
    Initialize: alpha = 
    0  smoothing: 0
    ** 
    Service (starter) Start **
    ** 
    Activity (main) Create, isFirst = true **
    Main->Create_User_Preference_Screen(): Creating the User Preferences 
    Screen for the first time...
    ** 
    Activity (main) Resume **
    Initialize: alpha = 
    0.3499999940395355  smoothing: 0.3499999940395355
    Main->Launch_Background_Services(): pref 
    Mac: C7:59:53:20:73:F9
    starter_magdeclination (java line: 
    1057)
    java.lang.RuntimeException: Method: getDeclination 
    not matched.
        at anywheresoftware.b4j.object.JavaObject.RunMethod(
    JavaObject.java:129)
        at com.calypsoinstruments.CalypsoUltrasonicAPI.starter._magdeclination(starter.java:
    1057)
        at com.calypsoinstruments.CalypsoUltrasonicAPI.starter._gps_locationchanged(starter.java:
    1029)
        at java.lang.reflect.Method.invoke(Native Method)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    191)
        at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    171)
        at anywheresoftware.b4a.gps.GPS$
    1.onLocationChanged(GPS.java:65)
        at android.location.LocationManager$ListenerTransport._handleMessage(
    LocationManager.java:297)
        at android.location.LocationManager$ListenerTransport.-wrap0(
    LocationManager.java)
        at android.location.LocationManager$ListenerTransport$
    1.handleMessage(LocationManager.java:242)
        at android.os.Handler.dispatchMessage(Handler.java:
    102)
        at android.os.Looper.loop(Looper.java:
    154)
        at android.app.ActivityThread.main(ActivityThread.java:
    6123)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    867)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    757)
     
  4. DonManfred

    DonManfred Expert Licensed User

  5. Angel Maza

    Angel Maza Member Licensed User

    I thought that's what I'm doing in the Java Code section. Please note that I tried and renamed the function to getDeclinationJava() to differentiate it from the GeometricField method getDeclination(). The error reads now "java.lang.RuntimeException: Method: getDeclinationJava not matched." Thus it looks like B4a has a problem finding the native Java code function getDeclinationJava().

    Thoughts?


    native Java Code section in Main():
    Code:
    #If JAVA
    public float getDeclinationJava(float Lat, float Lon, float Altitude, long Millis) {
        import android.hardware.GeomagneticField;                                                    // import the GeomagneticField class
        GeomagneticField mGeoField = new GeomagneticField(Lat, Lon, Altitude, Millis);    // initialize the class
        return mGeoField.getDeclination();                                                               // call the getDeclination() method
    }
    #End If
    My B4a code:
    Code:
    in Starter()
    Public javaInline As JavaObject
    ..
    magDec = javaInline.RunMethod(
    "getDeclinationJava"Array As Object(sensorData.Get("LAT"), sensorData.Get("LON"), sensorData.Get("ALT"), millis))
    in Main()
    Starter.javaInline.InitializeContext
    [/CODE]
     
  6. JordiCP

    JordiCP Well-Known Member Licensed User

    "Not matched" means that it is expecting a different signature that the one it is receiving.
    Your function expects (float,float,float,long) and your data (Lat, Lon, Alt) is double
    You can change it this way
    Code:
    public float getDeclinationJava(double Lat, double Lon, double Altitude, long Millis) {
       GeomagneticField mGeoField = new GeomagneticField((float)Lat, (float)Lon, (float)Altitude, Millis);
        
    return mGeoField.getDeclination();  
    }
     
    DonManfred and Angel Maza like this.
  7. Angel Maza

    Angel Maza Member Licensed User

    That did the trick. Thanks a bunch JordiCP & DonManfred for your kind assistance!
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice