Wednesday, February 6, 2013

Android Get location without GPS (using opencellid)

A class OpenCellID was created to handle the http communication with opencellid.org. To simplify the job, request with "fmt=txt" is sent, such that we can simply splite the result to retrieve our latitude, longitude.

I used the API 
http://www.opencellid.org/cell/getmcc=404&mnc=71&cellid=20414908&lac=3311&fmt=txt

Make a project with name LocationWithoutGPS and have a main activity with name AndroidTelephonyManager.java with following code


package com.JITESH.locationwithoutgps;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

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 {

 public class OpenCellID {
  String mcc;  //Mobile Country Code
  String mnc;  //mobile network code
  String cellid; //Cell ID
  String lac;  //Location Area Code
   
  Boolean error;
  String strURLSent;
  String GetOpenCellID_fullresult;
   
  String latitude;
  String longitude;
   
  public Boolean isError(){
   return error;
  }
   
  public void setMcc(String value){
   mcc = value;
  }
   
  public void setMnc(String value){
   mnc = value;
  }
   
  public void setCallID(int value){
   cellid = String.valueOf(value);
  }
   
  public void setCallLac(int value){
   lac = String.valueOf(value);
  }
   
  public String getLocation(){
   return(latitude + " : " + longitude);
  }
   
  public void groupURLSent(){
   strURLSent =
    "http://www.opencellid.org/cell/get?mcc=" + mcc
    +"&mnc=" + mnc
    +"&cellid=" + cellid
    +"&lac=" + lac
    +"&fmt=txt";
  }
   
  public String getstrURLSent(){
   return strURLSent;
  }
   
  public String getGetOpenCellID_fullresult(){
   return GetOpenCellID_fullresult;
  }
   
  public void GetOpenCellID() throws Exception {
   groupURLSent();
   HttpClient client = new DefaultHttpClient();
   HttpGet request = new HttpGet(strURLSent);
   HttpResponse response = client.execute(request);
   GetOpenCellID_fullresult = EntityUtils.toString(response.getEntity()); 
   spliteResult();
  }
   
  private void spliteResult(){
   if(GetOpenCellID_fullresult.equalsIgnoreCase("err")){
    error = true;
   }else{
    error = false;
    String[] tResult = GetOpenCellID_fullresult.split(",");
    latitude = tResult[0];
    longitude = tResult[1];
   }
     
    
  }
 }

 int myLatitude, myLongitude;
 OpenCellID openCellID;

  
   /** 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 textMCC = (TextView)findViewById(R.id.mcc);
       TextView textMNC = (TextView)findViewById(R.id.mnc);
       TextView textCID = (TextView)findViewById(R.id.cid);
       TextView textLAC = (TextView)findViewById(R.id.lac);
       TextView textGeo = (TextView)findViewById(R.id.geo);
       TextView textRemark = (TextView)findViewById(R.id.remark);
       
       //retrieve a reference to an instance of TelephonyManager
       TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
       GsmCellLocation cellLocation = (GsmCellLocation)telephonyManager.getCellLocation();
       
       String networkOperator = telephonyManager.getNetworkOperator();
       String mcc = networkOperator.substring(0, 3);
       String mnc = networkOperator.substring(3);
       textMCC.setText("mcc: " + mcc);
       textMNC.setText("mnc: " + mnc);
       
       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));
       
       openCellID = new OpenCellID();
       
       openCellID.setMcc(mcc);
       openCellID.setMnc(mnc);
       openCellID.setCallID(cid);
       openCellID.setCallLac(lac);
       try {
   openCellID.GetOpenCellID();
    
   if(!openCellID.isError()){
    textGeo.setText(openCellID.getLocation());
    textRemark.setText( "\n\n"
      + "URL sent: \n" + openCellID.getstrURLSent() + "\n\n"
      + "response: \n" + openCellID.GetOpenCellID_fullresult);
   }else{
    textGeo.setText("Error");
   }
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   textGeo.setText("Exception: " + e.toString());
  }
   }   
}

and the main.xml is having the following layout


<?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_world"
   />
<TextView
   android:id="@+id/gsmcelllocation"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   />
<TextView
   android:id="@+id/mcc"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   />
<TextView
   android:id="@+id/mnc"
   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"
   />
<TextView
   android:id="@+id/remark"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   />
</LinearLayout>

the manifest is having few permissions as follows


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.JITESH.locationwithoutgps"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.JITESH.locationwithoutgps.AndroidTelephonyManager"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

</manifest>

The source code can be downloaded from USEOpencellid in Android





7 comments:

  1. in manifest file, twice time ??

    ReplyDelete
  2. what about if there's two android device and they want to know
    where they;re without the need of the server / internet aop?

    ReplyDelete
  3. I am getting error NullPointerException: API key is either null or empty string

    ReplyDelete
    Replies
    1. oh ok , as i wrote this code a long before so please investigate through opencellid apis and do accordingly!!

      Delete