B4A Library BGCellLocation v1.0 - Location using CellID

gorelshv

Member
Licensed User
BGCellLocation v1.01 - Location using CellID

Hello everyone!
This library contains functions that return latitude and longitude coordinates using cellular tower information :sign0060:
It also contains a function to get neiboring cell IDs for getting more accurate position using triangulation, for instance.

- The following proceudre describes how to get the lat,lon of the currently associated cell tower:
It needs two parameters to work: Cell ID (cid) and Location Area Code (lac).
To extract them we can use the Reflection library:
B4X:
Dim Obj1 As Reflector
Dim cid, lac As Int
Obj1.Target = Obj1.GetContext
Obj1.Target = Obj1.RunMethod2("getSystemService", "phone", "java.lang.String")
Obj1.Target = Obj1.RunMethod("getCellLocation") ' get a GsmCellLocation 
cid = Obj1.RunMethod("getCid") ' gsm cell id
lac = Obj1.RunMethod("getLac") ' gsm location area code
then we can use this data to get the coordinates:
B4X:
Dim location as String
location = BGCell.getCellLocation(cid,lac)
Additional information is inside the library.
Please note: to get the coordinates this library uses an undocumented Google API (the same one used by Google Maps) which means it can break without notice.
Also note: the code will run on GUI thread! Using the Threading library is a good idea to keep the interface responsive.

Permissions used: "android.permission.ACCESS_COARSE_LOCATION" and "android.permission.INTERNET"
Tested on GSM device only. Users of CDMA devices please report your results.

Update 1.01
Added 2 new methods:
- getCellLocation2 returns lat,lon without decimal point. This is useful when using certain online APIs.
- getNeiboringCells returns a List with pairs of neighboring cell IDs and their Rssi separated by comma (,). Will return -1 as cell ID in UMTS mode.

Enjoy!

- Benny
 

Attachments

Last edited:

petri2000

Member
Licensed User
Not working even with CellId & Areacode

Thanks for the library this is really what I would need.
However, I cannot get this to work on a GSM network (HTC Desire device)
Below is the code I am testing.


cid = Obj1.RunMethod("getCid") ' gsm cell id
lac = Obj1.RunMethod("getLac") ' gsm location area code

sLocation = BGCell.getCellLocation(cid, lac)
Log("sLocation = " & sLocation)
Log("cid = " & cid)
Log("lac = " & lac)

As you see I log the result and this is the following results of the Log

sLocation = not found
cid = 197780
lac = 201

Any Ideas?
Thanks for any assistance.
 

gorelshv

Member
Licensed User
This is probably because the cellular tower you are connected to is not registered in Google's database. It happened to me also. Try moving around or switch between 2g/3g which will make the phone switch to another tower and see if you get any results. Also, make sure that you have a working connection to the internet.
I will try and add a functionality that reads nearby cell towers thus increasing the chance of getting results from Google. It will also allow you to do cellular triangulation which will help you get a better position.
 

bluejay

Active Member
Licensed User
The Google API has been broken for a long time now as is all the other Cell ID 'Databases'.

I assume the PLMN code which is also needed is already being supplied by the BGCellLocation library.

Since the cid reported here by the phone is greater than 65535 you are clearly on a 3G cell. 3G UMTS cells broadcast 'Global Cell ID' which is (RNC_ID * 65536 + Cell_ID).

An RNC is a Radio Network Controller which can be changed by the operator at any time as can the LAC thus invalidating the database information.

Unlike in GSM, in 3G each new transmitter added to an existing location gets a new cell id. It takes some time for these new cells to become registered with location data in the Google database.

Google may already be filtering out the RNC ID (ie cid mod 65356) in their database - don't know, may be worth a try.

Another approach would be also use the neighbour cell list, which should also have GSM cells in it, then triangulate. Try the search box at the top of the page for more on this.

In general I think this will always be an unreliable method of getting location so you need allow for this in the design.

Bluejay
 

petri2000

Member
Licensed User
Will keep trying.

Thanks for the replies folks, it makes things clearer. I'll look around the tips and try to figure out how to get it working. yes, I am aware that using this method is not an accurate option for determine location. But it is a good option saving battery and if you only need an approximate location.

Cheers,
 

gorelshv

Member
Licensed User
Ok, I managed to get the neighboring cell IDs and LACs when I'm on 2G(GSM).
When using 3G(UMTS) i can only get the PSC for every cell. There are no 2G cells inculded in the list.
Is there a way to get the cell ID using the PSC?
Also, if someone could have a look at this page and maybe tell me if there is a way to get 2G (GSM) cells even if using 3G mode, it would be great.
 
Last edited:

Shay

Well-Known Member
Licensed User
Hi

I am getting the cid, and lac
but I don't understand what next, meaning, how do I get lon / lat
such as GPS
can I get from cell tower my location
 

Shay

Well-Known Member
Licensed User
I was missing the:
Dim BGCell As BGCellLocation

I am also getting "not found"
any examples what to do next?
 

gorelshv

Member
Licensed User
Just read the thread again. I'm still working on a version that gets all cells in range but it only works on gsm and only in 2g mode.
 

gorelshv

Member
Licensed User
Update 1.01
Added 2 new methods:
- getCellLocation2 returns lat,lon without decimal point. This is useful when using certain online APIs.
- getNeiboringCells returns a List with pairs of neighboring cell IDs and their Rssi separated by comma (,). Will return -1 as cell ID in UMTS mode.
 

synasir

Member
Licensed User
Getting CID with LAC for the getNeiboringCells function.

Thanks for the great libary. Question, how do I get the LAC along with the CID for the getNeiboringCells function.
 

gorelshv

Member
Licensed User
Sorry for the delayed replay.
Currently, it is not possible. You can assume that the LAC extracted using the first code snippet is the same with the neighboring cells.
I will add the functionality later.
 

Rick Harris

Well-Known Member
Licensed User
A few comments

Your code works fine! Well done.

Just a few observations:

1. You forgot to add:
Dim BGCell As BGCellLocation

2. It would be nice if you added:
BGCell.getLatitude
BGCell.getLongitude

Now having to search for the comma in the location string is not so pleasant.
Here is my test program:

B4X:
Sub Process_Globals
End Sub

Sub Globals
   Dim BGCell As BGCellLocation
End Sub

Sub Activity_Create(FirstTime As Boolean)
    MY_LOCATION1
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

Sub MY_LOCATION1
    Dim Obj1 As Reflector
   Dim cid, lac As Int
   Dim Location As String
   Dim LatHu1 As String
   Dim LonHu1 As String
   Dim Latid2 As Double
   Dim Longi2 As Double
   Dim n As Long 

   Obj1.Target = Obj1.GetContext
   Obj1.Target = Obj1.RunMethod2("getSystemService", "phone", "java.lang.String")
   Obj1.Target = Obj1.RunMethod("getCellLocation") ' get a GsmCellLocation 
   cid = Obj1.RunMethod("getCid") ' gsm cell id
   lac = Obj1.RunMethod("getLac") ' gsm location area code
   Location = BGCell.getCellLocation(cid,lac) & "     "
   ToastMessageShow(Location,True)
   n = Location.IndexOf(",")
   If n<=0 Then Return
   LatHu1 = Location.SubString2(0,n)
   LonHu1 = Location.SubString2(n+1,Location.Length).trim
   Latid2 = LatHu1
   Longi2 = LonHu1
   ToastMessageShow("Lat= " & LatHu1 & ", Lon= " & LonHu1, True)
End Sub
 
Last edited:

ttsolution

Member
Licensed User
An error has occurred in Sub

When run I faced with below error

An error has occurred in Sub : main_my_location1 (java line 408)
android.os.NetworkOnMainThreadException

many thanks for your hepl

ttsolution
 

gorelshv

Member
Licensed User
The problem is that you're trying to perform a network I/O on the main thread, which, starting from android 3.0, is not allowed.
Try running it on a different thread using the Threading lib.
 
Top