B4A Library GeoLocation

DonManfred

Expert
Licensed User
This is Library which is based on the code from this Github project.

GeoLocation
...|http://www.b4x.com
Author: DonManfred
Version: 1.1
  • GeoLocator
    • Events:
      • Location (success As Boolean, Lattitude As Double, Longitude As Double)
    • Functions:
      • geoAddress
      • GetLocation
      • Initialize (EventName As String)
    • Properties:
      • Address As String [read only]
      • City As String [read only]
      • Country As String [read only]
      • KnownName As String [read only]
      • Lattitude As Double [read only]
      • Longitude As Double [read only]
      • PostalCode As String [read only]
      • State As String [read only]

If get the Location from the System. It result in using th GPS Provider, Network Provider or PASSIVE_PROVIDER. In the resultevent you get info from which Provider the Location is from.
 

Attachments

Last edited:

Luis Carrillo Escalona

Member
Licensed User
Hi, but show this message:

Registo conectado a: samsung SM-J510MN
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
sending message to waiting queue (activity_permissionresult)
running waiting messages (1)
main$ResumableSub_Activity_Createresume (java line: 396)
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:411)
at de.donmanfred.GeoLocatorwrapper.geoAddress(GeoLocatorwrapper.java:109)
at b4a.example.main$ResumableSub_Activity_Create.resume(main.java:396)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:245)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:185)
at anywheresoftware.b4a.BA$2.run(BA.java:365)
at anywheresoftware.b4a.BA.setActivityPaused(BA.java:437)
at b4a.example.main$ResumeMessage.run(main.java:306)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6816)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)
--------- beginning of crash
 

peacemaker

Well-Known Member
Licensed User
Yes, errors if try in the PC emulator (MEMU)

- the error in
B4X:
GeoLoc.geoAddress
B4X:
** Activity (main) Resume **
Error occurred on line: 33 (Main)
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
    at java.util.ArrayList.get(ArrayList.java:308)
    at de.donmanfred.GeoLocatorwrapper.geoAddress(GeoLocatorwrapper.java:109)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:783)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:363)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:260)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:171)
    at anywheresoftware.b4a.shell.DebugResumableSub$RemoteResumableSub.resume(DebugResumableSub.java:22)
    at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:245)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:137)
    at anywheresoftware.b4a.BA$2.run(BA.java:365)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5254)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
If to comment .geoAddress with log lines - it is error:
B4X:
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
GeoLocation_Location(false, null, null, Unble to Trace your location)
b4a.example.main:_geolocation_location, [false, null, null, Unble to Trace your location]
Error occurred on line: 44 (Main)
java.lang.IllegalArgumentException: method b4a.example.main._geolocation_location argument 2 has type double, got null
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:738)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:357)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:260)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
    at anywheresoftware.b4a.BA$2.run(BA.java:365)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5254)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
** Activity (main) Pause, UserClosed = true **

If to test on real device - no any errors: the address and GPS coords are got OK !
B4X:
GeoLocation_Location(true, xx.25059298891574, yy.25199742987752, GPS_PROVIDER)
Thanks, Don !
But maybe to add more internal error traps ? To debug at any emulator or real devices.
 
Last edited:

DonManfred

Expert
Licensed User
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
Make sure to call the method geoAddress only after you got a valid Location.
GeoLoc.geoAddress
Make sure to call the method geoAddress only after you got a valid Location.
GeoLocation_Location(false, null, null, Unble to Trace your location)
Check v1.01. I´ve updated the lib in #1

For any further issue: You should always start a new thread for your questions.
 

peacemaker

Well-Known Member
Licensed User
B4X:
Sub GeoLocation_Location(success As Boolean, Lattitude As Double, Longitude As Double, info As String)
    'GeoLocation_Location(true, xx.25059298891574, yy.25199742987752, GPS_PROVIDER)
    Log($"GeoLocation_Location(${success}, ${Lattitude}, ${Longitude}, ${info})"$)
    If success Then
        GeoLoc.geoAddress
        Log(GeoLoc.Address)
        Log(GeoLoc.City)
        Log(GeoLoc.Country)
        Log(GeoLoc.KnownName)
        Log(GeoLoc.PostalCode)
        Log(GeoLoc.State)
    End If
End Sub
 

shasunder

Member
Licensed User
Your library crashes if LocationProvidersAllowed is empty. I tested using the below code. I disabled Location to test this. I agree with
Luis Carrillo Escalona.

Dim Phone1 As Phone
Dim LocationProvidersAllowed As String
LocationProvidersAllowed = Phone1.GetSettings("location_providers_allowed")
 

scsjc

Well-Known Member
Licensed User
I DonManfred,.. Great Library ;)

Is it possible to force the position update to obtain the address in the current coordinates?
thanks
 

DonManfred

Expert
Licensed User
You can call the method to get the location. It checks different providers and returns the one with a result.
B4X:
    public void GetLocation(BA ba) {
        LocationManager locationManager = (LocationManager) ba.context.getSystemService(ba.context.LOCATION_SERVICE);

        if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {

            // showSettingsAlert();
            //Toast.makeText(context, "Permission Denied", Toast.LENGTH_SHORT).show();
        String info = "Permission Denied";
            ba.raiseEventFromDifferentThread(this, null, 0, eventName + "_location", true, new Object[] {Boolean.valueOf(false),null,null,info});

        } else if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            

            Location location1 = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            Location location2 = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
            if (location != null) {
                double latti = location.getLatitude();
                double longi = location.getLongitude();
                lattitude = latti;
                longitude = longi;
                fromMockProvider = location.isFromMockProvider();
            String info = "NETWORK_PROVIDER";
          ba.raiseEventFromDifferentThread(this, null, 0, eventName + "_location", true, new Object[] {Boolean.valueOf(true),lattitude,longitude, info, fromMockProvider});
            } else if (location1 != null) {
                double latti = location1.getLatitude();
                double longi = location1.getLongitude();
                lattitude = latti;
                longitude = longi;
            String info = "GPS_PROVIDER";
                fromMockProvider = location1.isFromMockProvider();
          ba.raiseEventFromDifferentThread(this, null, 0, eventName + "_location", true, new Object[] {Boolean.valueOf(true),lattitude,longitude, info, fromMockProvider});
            } else if (location2 != null) {
                double latti = location2.getLatitude();
                double longi = location2.getLongitude();
                lattitude = latti;
                longitude = longi;
                fromMockProvider = location2.isFromMockProvider();
            String info = "PASSIVE_PROVIDER";
          ba.raiseEventFromDifferentThread(this, null, 0, eventName + "_location", true, new Object[] {Boolean.valueOf(true),lattitude,longitude, info, fromMockProvider});
            } else {
                //Toast.makeText(context, "Unble to Trace your location", Toast.LENGTH_SHORT).show();
            double value = 0;
                fromMockProvider = false;
                String info = "Unble to Trace your location";
          ba.raiseEventFromDifferentThread(this, null, 0, eventName + "_location", true, new Object[] {Boolean.valueOf(false),value,value, info, fromMockProvider});
            }
        }
    }
I don´t know if there is something to FORCE a faster result.
 

scsjc

Well-Known Member
Licensed User
You can call the method to get the location. It checks different providers and returns the one with a result.
B4X:
    public void GetLocation(BA ba) {
        LocationManager locationManager = (LocationManager) ba.context.getSystemService(ba.context.LOCATION_SERVICE);

        if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {

            // showSettingsAlert();
            //Toast.makeText(context, "Permission Denied", Toast.LENGTH_SHORT).show();
        String info = "Permission Denied";
            ba.raiseEventFromDifferentThread(this, null, 0, eventName + "_location", true, new Object[] {Boolean.valueOf(false),null,null,info});

        } else if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
           

            Location location1 = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            Location location2 = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
            if (location != null) {
                double latti = location.getLatitude();
                double longi = location.getLongitude();
                lattitude = latti;
                longitude = longi;
                fromMockProvider = location.isFromMockProvider();
            String info = "NETWORK_PROVIDER";
          ba.raiseEventFromDifferentThread(this, null, 0, eventName + "_location", true, new Object[] {Boolean.valueOf(true),lattitude,longitude, info, fromMockProvider});
            } else if (location1 != null) {
                double latti = location1.getLatitude();
                double longi = location1.getLongitude();
                lattitude = latti;
                longitude = longi;
            String info = "GPS_PROVIDER";
                fromMockProvider = location1.isFromMockProvider();
          ba.raiseEventFromDifferentThread(this, null, 0, eventName + "_location", true, new Object[] {Boolean.valueOf(true),lattitude,longitude, info, fromMockProvider});
            } else if (location2 != null) {
                double latti = location2.getLatitude();
                double longi = location2.getLongitude();
                lattitude = latti;
                longitude = longi;
                fromMockProvider = location2.isFromMockProvider();
            String info = "PASSIVE_PROVIDER";
          ba.raiseEventFromDifferentThread(this, null, 0, eventName + "_location", true, new Object[] {Boolean.valueOf(true),lattitude,longitude, info, fromMockProvider});
            } else {
                //Toast.makeText(context, "Unble to Trace your location", Toast.LENGTH_SHORT).show();
            double value = 0;
                fromMockProvider = false;
                String info = "Unble to Trace your location";
          ba.raiseEventFromDifferentThread(this, null, 0, eventName + "_location", true, new Object[] {Boolean.valueOf(false),value,value, info, fromMockProvider});
            }
        }
    }
I don´t know if there is something to FORCE a faster result.
How call this code from b4a ?
 

ashraffarid

Member
Licensed User
thanks DonManfred

first time i use the sample it works good(on real device )
it tried again on the same device
i have error

** Activity (main) Resume **
Error occurred on line: 33 (Main)
java.io.IOException: grpc failed
at android.location.Geocoder.getFromLocation(Geocoder.java:136)
at de.donmanfred.GeoLocatorwrapper.geoAddress(GeoLocatorwrapper.java:112)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:777)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:354)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:176)
at anywheresoftware.b4a.shell.DebugResumableSub$RemoteResumableSub.resume(DebugResumableSub.java:22)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:250)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:137)
at anywheresoftware.b4a.BA$2.run(BA.java:370)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)


and other question
How i get data for other location

thanks
 
Last edited:

prajinpraveen

Active Member
Licensed User
Great Library

same results as ashraffarid on Android 8 Hauwei

also if the gps location is disabled, the app crashes on line GeoLoc.geoAddress
Error : java.lang.IndexOutOfBoundsException: Index: 0, Size: 0

When the GPS location is enabled, same error continues until "Google Maps" application is opened and closed.
 

PumaCyan

Member
Licensed User
I apologize
I found an error like this in the log editor
is there anything that needs to be corrected?
 

Attachments

jtare

Active Member
Licensed User
I apologize
I found an error like this in the log editor
is there anything that needs to be corrected?
What does your sub looks like? It should be something like this:
B4X:
Sub GeoLocation_Location(success As Boolean, Lattitude As Double, Longitude As Double, info As String)
'Something
Ens Sub
I've never tried this library, but should work. Also next time I suggest you to create a new thread to make questions.
 
Top