Jun 4, 2011

Convert cellLocation to real location (Latitude and Longitude), using "http://www.google.com/glm/mmap"

The post "Get cell location on a GSM phone, getCellLocation()" get cell id and location area code. It's not a useful info with converted to real location.

"http://www.google.com/glm/mmap" is a non-public API to convert cellLocation to latitude and longitude. Some nice guy developed the method to retrieve location from cellLocation.

Convert cellLocation to Latitude and Longitude

We need the following permission in this example:
  • android.permission.ACCESS_COARSE_LOCATION
  • android.permission.ACCESS_FINE_LOCATION
  • android.permission.READ_PHONE_STATE
  • android.permission.INTERNET


package com.AndroidTelephonyManager;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
import android.widget.TextView;

public class AndroidTelephonyManager extends Activity {

int myLatitude, myLongitude;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textGsmCellLocation = (TextView)findViewById(R.id.gsmcelllocation);
TextView textCID = (TextView)findViewById(R.id.cid);
TextView textLAC = (TextView)findViewById(R.id.lac);
TextView textGeo = (TextView)findViewById(R.id.geo);

//retrieve a reference to an instance of TelephonyManager
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
GsmCellLocation cellLocation = (GsmCellLocation) telephonyManager.getCellLocation();

int cid = cellLocation.getCid();
int lac = cellLocation.getLac();
textGsmCellLocation.setText(cellLocation.toString());
textCID.setText("gsm cell id: " + String.valueOf(cid));
textLAC.setText("gsm location area code: " + String.valueOf(lac));

if(RqsLocation(cid, lac)){
textGeo.setText(
String.valueOf((float)myLatitude/1000000)
+ " : "
+ String.valueOf((float)myLongitude/1000000));
}else{
textGeo.setText("Can't find Location!");
}

}

private Boolean RqsLocation(int cid, int lac){

Boolean result = false;

String urlmmap = "http://www.google.com/glm/mmap";

try {
URL url = new URL(urlmmap);
URLConnection conn = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setRequestMethod("POST");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
httpConn.connect();

OutputStream outputStream = httpConn.getOutputStream();
WriteData(outputStream, cid, lac);

InputStream inputStream = httpConn.getInputStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);

dataInputStream.readShort();
dataInputStream.readByte();
int code = dataInputStream.readInt();
if (code == 0) {
myLatitude = dataInputStream.readInt();
myLongitude = dataInputStream.readInt();

result = true;

}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return result;

}

private void WriteData(OutputStream out, int cid, int lac)
throws IOException
{
DataOutputStream dataOutputStream = new DataOutputStream(out);
dataOutputStream.writeShort(21);
dataOutputStream.writeLong(0);
dataOutputStream.writeUTF("en");
dataOutputStream.writeUTF("Android");
dataOutputStream.writeUTF("1.0");
dataOutputStream.writeUTF("Web");
dataOutputStream.writeByte(27);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(3);
dataOutputStream.writeUTF("");

dataOutputStream.writeInt(cid);
dataOutputStream.writeInt(lac);

dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.flush();
}

}


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<TextView
android:id="@+id/gsmcelllocation"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/cid"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/lac"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/geo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>


It's another open source project, OpenCellID, which provide tools, and database to retrieve location informations of CellID worldwide.

Related Post:
- Get location of Cell ID, from opencellid.org using HttpGet().

13 comments:

  1. Hi,

    I Want to know that, this will continuously monitor the GSM cell id or only at the first run.

    I mean I want to keep track of my cell id. is this code enough to do so.

    I want to run it in background and whenever I my cell phone changes the cell id, it should notify the same.

    Expecting your favorable reply.

    ReplyDelete
  2. i ve tried the same code but i am getting force close....i checked every thing including manifest file.......wat may went wrong......plz help me eric.........waiting for ur reply

    ReplyDelete
    Replies
    1. Put network call inside an async task

      new AsyncTask()
      {
      @Override
      protected Boolean doInBackground(Object[] objects) {
      b=RqsLocation(cid, lac);
      return false;
      }

      @Override
      protected void onPostExecute(Object o) {

      super.onPostExecute(o);


      if (b) {
      textGeo.setText(
      String.valueOf((float) myLatitude / 1000000)
      + " : "
      + String.valueOf((float) myLongitude / 1000000));
      } else {
      textGeo.setText("Can't find Location!");
      }
      }
      }.execute();


      }

      Delete
  3. krishna,

    You can download and try here.

    It's in project form, tested on Nexus One.

    ReplyDelete
  4. Hi somebody! I canot run on Android Virtual Manager. Can you hepl me?

    ReplyDelete
  5. Hello ...
    i am not getting the real location.
    can't find location

    ReplyDelete
  6. i ve tried the same code but i am getting force close....i checked every thing including manifest file.......wat may went wrong......plz help me eric.........waiting for ur reply

    ReplyDelete
  7. can't find location message; last value returns vulue -1. Something has changed because this code was working for me.

    ReplyDelete
  8. please help me
    cant find location message arrayindexoutofexception.

    ReplyDelete
  9. Hi,
    Is it possible to get LAC of the area if MCC,MNC,Lat and Long is known?

    If yes, how?

    Thanks in advance,
    tspshikari

    ReplyDelete
  10. hey thnx Eric@android, u save me :)

    ReplyDelete
  11. It gives me the completely wrong location.
    My accurate Location is
    "Kot Lakhpat
    Lahore, Pakistan
    31.463615, 74.319295"

    But I am getting this
    "Tiruchirappalli
    Tamil Nadu, India
    10.888575, 78.720813"

    ReplyDelete

Infolinks In Text Ads