Android Development Notes Simple base station location program implementation _ios

Source: Internet
Author: User
Tags event listener getmessage readline stub stringbuffer

After learning, has a general understanding of the development process of the Android program, in order to improve our interest in learning, in this section we will write a simple base station locator program. Now lbs (Location Based service, location-based services) mobile applications are quite popular (such as: micro-letters, customers, muttering, street, etc.), base station positioning is one of the key technologies used in such programs, let's uncover its mystery.

In this section, we will be exposed to events, Telephonymanager, HTTP communications, use of JSON and other knowledge points.

In the Android operating system, base station positioning is actually very simple, first of all, to say the implementation process:

Invoke the APIs in the SDK (Telephonymanager) to obtain information about MCC, MNC, LAC, CID, and then through Google's API to get the latitude and longitude of the location, and finally through the Google Map API to obtain the actual location. (Google Real cow!) )

There are alumni ask: MNC, MCC, LAC, cid What are these things? How does Google get latitude and longitude through these things?

Let's study together:

Mcc,mobile Country code, mobile country codes (460 in China);

Mnc,mobile Network Code, mobile network number (China Mobile for 00, Unicom for 01);

Lac,location area code, location region code;

Cid,cell Identity, base station number, is a 16-bit data (range is 0 to 65535).

Understand the meaning of these nouns, I believe some friends already know the next thing: Google stores this information, direct query can get latitude and longitude degree. (As for how Google gets mobile, Unicom's base station information, this is not known, anyway, Google provides free interface, direct call is)

Here we go.

First, set the interface

We developed on the basis of the previous program and implemented this feature on the Demoactivity interface.

First, we'll modify the layout used by demoactivity:

1th behavior TextView, display prompt text, 2nd behavior a button, triggering event; line 3rd and 4th show the base station information and geographic location (now empty, not visible).

The contents of the Layout/main.xml file are as follows:

 <?xml version= "1.0" encoding= "Utf-8"?> <linearlayout "xmlns:android="
  Schemas.android.com/apk/res/android "android:layout_width=" fill_parent "android:layout_height=" Fill_parent " android:orientation= "vertical" > <textview android:layout_width= "fill_parent" android:layout_height= "Wra" P_content "android:text=" please click the button below to get your location "/> <button android:id=" @+id /button1 "android:layout_width=" wrap_content android:layout_height= "wrap_content" android:text= "click Me"/&G
 
  T <textview android:id= "@+id/celltext" android:layout_width= wrap_content "android:layout_height=" Wrap_conten
    T "android:text=" "/> <textview android:id=" @+id/lacationtext "android:layout_width=" Wrap_content " android:layout_height= "wrap_content" android:text= "/> </LinearLayout> 

Next we open Demoactivity.java to write code.

Two, the button to bind events

We bind the event when the activity is created and add the following code to Setcontentview (R.layout.main);

/** for Button binding event * *
btngetlocation = (button) Findviewbyid (r.id.button1);
Btngetlocation.setonclicklistener (New Onclicklistener () {
  @Override public
  void OnClick (View arg0) {
    // TODO auto-generated Method Stub
    Onbtnclick ();
  }
});

Also need to import related components in the head:

Import Android.view.View;
Import Android.widget.Button;
Import Android.view.View.OnClickListener;

Let's take a look at this piece of code:

First we find the object of the button through Findviewbyid (R.id.button1), and the Front Plus (button) indicates that the display is converted to a button object;

Then set the button to click on the event listener, the parameter is Onclicklistener object, reload this class's OnClick method, calls the Onbtnclick method (this method must be written by ourselves, he is called when clicking the button).

Well, the call method is written, and we write the implementation (what needs to be done after the call). Start coding in the brain before the idea to form good habits.

We need to add the following private methods to the Demoactivty class:

We need the Onbtnclick callback method just mentioned, when we get the base station information, obtain the latitude and longitude degree, obtain the geographical position, display function. But obviously, it's not a good idea to rub it all in one way, and we'll split it into several ways;

    • Add the method of obtaining base station information Getcellinfo, return base station information;
    • Adding the method of obtaining the latitude and longitude getitude, passing in the base station information, returning the latitude and longitude degree;
    • Add the method of obtaining geographical location getlocation, incoming latitude and longitude degree, return geographical position;
    • Add the method that displays the result Showresult, the incoming information is displayed on the interface.

OK, first add the method, the complete code is as follows:

Package Com.android.demo; Import Android.
R.bool; Import Android.
R.integer;
Import android.app.Activity;
Import Android.os.Bundle;
Import Android.view.View;
Import Android.widget.Button;
 
Import Android.view.View.OnClickListener;  The public class Demoactivity extends activity {/** called the ' when the ' is the ' The activity ' is a./@Override public void
    OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
     
    Setcontentview (R.layout.main);
    /** for Button binding event * * btngetlocation = (button) Findviewbyid (R.id.button1); Btngetlocation.setonclicklistener (New Onclicklistener () {@Override public void OnClick (View arg0) {/
      /TODO auto-generated Method Stub Onbtnclick ();
  }
    });
    /** Base Station INFORMATION Structure * * public class scell{public int MCC;
    public int MNC;
    public int LAC;
  public int CID;
    /** latitude and longitude information structure body/public class situde{public String latitude;
  public String longitude; }
   
  /* * button click callback function/private void Onbtnclick () {}/** get base station information * * Private Scell Getcellinfo () {}/** obtained
     
  Learn Latitude * * Private situde Getitude (Scell cell) {}/** get geographic location/private String getLocation (Situde itude) {
 /** Display result */private void Showresult (Scell cell, String location) {}}

Now encode in the Onbtnclick method, call the following methods in turn, following the code:

/** button click the callback function
/private void Onbtnclick () {
  /** pops up a waiting state box * *
  progressdialog mprogressdialog = new ProgressDialog (this);
  Mprogressdialog.setmessage ("Getting in ...");
  Mprogressdialog.setprogressstyle (Progressdialog.style_spinner);
  Mprogressdialog.show ();
   
  try {
    /** get base Station data *
    /Scell cell = Getcellinfo ();
     
    /** according to base station data to obtain latitude and longitude degree * *
    situde itude = getitude (cell);
     
    /** acquisition Location
    /String location = GetLocation (itude);
     
    /** Display Result * *
    showresult (cell, location);
     
    /** Closes the dialog box * *
    Mprogressdialog.dismiss ();
  } catch (Exception e) {
    /** closes the dialog box *
    /Mprogressdialog.dismiss ();
    /** Display Error *
    /TextView celltext = (TextView) Findviewbyid (r.id.celltext);
    Celltext.settext (E.getmessage ());
  }

Button-related work is done, and then write a method to get the base station information.

Third, to obtain base station information

To get base station information we need to invoke the Telephonymanager in the API provided by the SDK, which needs to be introduced in the file header:

Import Android.telephony.TelephonyManager;
Import android.telephony.gsm.GsmCellLocation;

The complete code is:

/**
 * Access to base station information
 * 
 * @throws Exception * *
private Scell Getcellinfo () throws Exception {
  Scell cell = new Scell ();
 
  /** call API to get base station information *
  /Telephonymanager mtelnet = (telephonymanager) getsystemservice (context.telephony_service);
  Gsmcelllocation location = (gsmcelllocation) mtelnet.getcelllocation ();
  if (location = = null)
    throw new Exception ("failed to get base station information");
 
  String operator = Mtelnet.getnetworkoperator ();
  int MCC = Integer.parseint (operator.substring (0, 3));
  int MNC = Integer.parseint (operator.substring (3));
  int cid = Location.getcid ();
  int lac = Location.getlac ();
 
  /** the obtained data into the structure of the * *
  cell. MCC = MCC;
  Cell. MNC = MNC;
  Cell. LAC = LAC;
  Cell. CID = CID;
 
  return cell;
}

If the obtained location information is NULL, an error is thrown and no further execution is performed. Finally, the obtained base station information is encapsulated as the structure body return.

Iv. obtaining latitude and longitude degree

In this step, we need to use HTTP to invoke Google's API to get the latitude and longitude of the base station.

Android as an Internet phone, networking is essential. Android offers a number of interfaces for us to use, and here we use defaulthttpclient.

The complete method code is as follows:

/** * Gain Latitude and longitude * * @throws Exception/private situde getitude (Scell cell) throws Exception {situde itude = new SIt
 
  Ude ();
  /** uses the android default HttpClient */httpclient client = new Defaulthttpclient ();
  /** using POST method */HttpPost post = new HttpPost ("Http://www.google.com/loc/json");
    The JSON data for the try {/** construct post/jsonobject holder = new Jsonobject ();
    Holder.put ("Version", "1.1.0");
    Holder.put ("Host", "maps.google.com");
    Holder.put ("Address_language", "ZH_CN");
    Holder.put ("Request_address", true);
    Holder.put ("Radio_type", "GSM");
 
    Holder.put ("Carrier", "HTC");
    Jsonobject tower = new Jsonobject (); Tower.put ("Mobile_country_code", cell.
    MCC); Tower.put ("Mobile_network_code", cell.
    MNC); Tower.put ("cell_id", cell.
    CID); Tower.put ("Location_area_code", cell.
 
    LAC);
    Jsonarray Towerarray = new Jsonarray ();
    Towerarray.put (tower);
 
    Holder.put ("Cell_towers", Towerarray); stringentity query = new Stringentity (Holder.tostriNg ());
 
    post.setentity (query);
    /** issue the post data and obtain the return data */httpresponse response = Client.execute (POST);
    httpentity entity = response.getentity ();
    BufferedReader buffreader = new BufferedReader (New InputStreamReader (Entity.getcontent ()));
    StringBuffer Strbuff = new StringBuffer ();
    String result = null;
    while (result = Buffreader.readline ())!= null) {strbuff.append (result);
    /** parse the returned JSON data to obtain latitude and longitude * * * jsonobject JSON = new Jsonobject (strbuff.tostring ());
 
    Jsonobject subjosn = new Jsonobject (json.getstring ("location"));
    Itude.latitude = subjosn.getstring ("latitude");
     
    Itude.longitude = subjosn.getstring ("longitude");
     
  LOG.I ("Itude", Itude.latitude + itude.longitude);
    catch (Exception e) {log.e (E.getmessage (), e.tostring ());
  throw new Exception ("Get latitude and longitude error:" +e.getmessage ());
    } finally{Post.abort ();
  client = null;
return itude;

 }

Here, the Post method is used to send the JSON data to the Googleapi,google to return the JSON data, and then we get the data and get the latitude and longitude information.

V. Acquiring physical location

When we get the latitude and longitude, we convert it to the physical address.

We still use Defaulthttpclient to invoke the Google Maps API to get physical information, but here we use the Getting method.

The complete method code is as follows:

/** * Access to geographical location * * @throws Exception * * Private String getLocation (Situde itude) throws Exception {String ResultStr
 
  ing = ""; /** here The Get method is used to add parameters directly to the URL/String urlstring = String.Format ("http://maps.google.cn/maps/geo?key=abcdefg&amp;q=%s,%
  S ", Itude.latitude, Itude.longitude);
 
  LOG.I ("URL", urlstring);
  /** New HttpClient * * httpclient client = new Defaulthttpclient ();
  /** using Get method * * HttpGet get = new HttpGet (urlstring);
    Try {/** initiates a GET request and obtains the return data */httpresponse response = Client.execute (gets);
    httpentity entity = response.getentity ();
    BufferedReader buffreader = new BufferedReader (New InputStreamReader (Entity.getcontent ()));
    StringBuffer Strbuff = new StringBuffer ();
    String result = null;
    while (result = Buffreader.readline ())!= null) {strbuff.append (result);
 
    } resultstring = Strbuff.tostring (); /** parse JSON data, get Physical Address */if (resultstring!= null &amp;&amp; resultstring.length () &gt; 0) {jsonobject jsonobjECT = new Jsonobject (resultstring);
      Jsonarray Jsonarray = new Jsonarray (Jsonobject.get ("Placemark"). toString ());
      resultstring = "";
      for (int i = 0; i &lt; jsonarray.length (); i++) {resultstring = Jsonarray.getjsonobject (i)-getString ("address");
  (Exception e) {throw new Exception ("Get the Physical location error:" + e.getmessage ());
    finally {get.abort ();
  client = null;
return resultstring;
 }

The Get method is much simpler than the Post method, and the resulting data is also in JSON format, parsing to get the physical address.

Vi. Display of results

OK, we've got the information we want, we'll show it, the method code is as follows:

/** Display result */
private void Showresult (Scell cell, String location) {
  TextView celltext = (TextView) Findviewbyid (r.i D.celltext);
  Celltext.settext (String.Format ("Base station information: mcc:%d, mnc:%d, lac:%d, cid:%d",
      cell.) MCC, Cell. MNC, Cell. LAC, Cell. CID));
 
  TextView Locationtext = (TextView) Findviewbyid (r.id.lacationtext);
  Locationtext.settext ("Physical Location:" + location);
}

VII. Operating Procedures

Our coding work has been completed. In the code above, some of the required introduction code is not mentioned, and the complete code is posted below:

Package Com.android.demo;
Import Java.io.BufferedReader;
 
Import Java.io.InputStreamReader;
Import org.apache.http.HttpEntity;
Import Org.apache.http.HttpResponse;
Import org.apache.http.client.HttpClient;
Import Org.apache.http.client.methods.HttpGet;
Import Org.apache.http.client.methods.HttpPost;
Import org.apache.http.entity.StringEntity;
 
Import org.apache.http.impl.client.DefaultHttpClient;
Import Org.json.JSONArray;
 
Import Org.json.JSONObject;
Import android.app.Activity;
Import Android.app.ProgressDialog;
Import Android.content.Context;
Import Android.os.Bundle;
Import Android.telephony.TelephonyManager;
Import android.telephony.gsm.GsmCellLocation;
Import Android.util.Log;
Import Android.view.View;
Import Android.widget.Button;
Import Android.widget.TextView;
 
Import Android.view.View.OnClickListener;  The public class Demoactivity extends activity {/** called the ' when the ' is the ' The activity ' is a./@Override public void OnCreate (Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate);
 
    Setcontentview (R.layout.main);
    /** for Button binding event * * btngetlocation = (button) Findviewbyid (R.id.button1); Btngetlocation.setonclicklistener (New Onclicklistener () {@Override public void OnClick (View arg0) {/
      /TODO auto-generated Method Stub Onbtnclick ();
  }
    });
    /** Base Station INFORMATION Structure * * public class scell{public int MCC;
    public int MNC;
    public int LAC;
  public int CID;
    /** latitude and longitude information structure body/public class situde{public String latitude;
  public String longitude; /** button click the callback function/private void Onbtnclick () {/** pops up a waiting state box * * ProgressDialog mprogressdialog = new Progr
    Essdialog (this);
    Mprogressdialog.setmessage ("Getting in ...");
    Mprogressdialog.setprogressstyle (Progressdialog.style_spinner);
 
    Mprogressdialog.show ();
 
      try {/** get base station data */Scell cell = Getcellinfo ();
 
    /** according to base station data to obtain latitude and longitude degree * * situde itude = getitude (cell);  /** Acquisition location/String location = GetLocation (itude);
 
      /** Display Result * * Showresult (cell, location);
    /** Closes the dialog box * * Mprogressdialog.dismiss ();
      The catch (Exception e) {/** Closes the dialog box */Mprogressdialog.dismiss ();
      /** Display Error */TextView Celltext = (TextView) Findviewbyid (R.id.celltext);
      Celltext.settext (E.getmessage ());
    LOG.E ("Error", E.getmessage ()); /** * Get Base Station information * * @throws Exception * * Private Scell Getcellinfo () throws Exception {Scell
 
    Cell = new Scell ();
    /** call API to get base station information */Telephonymanager mtelnet = (telephonymanager) getsystemservice (Context.telephony_service);
    Gsmcelllocation location = (gsmcelllocation) mtelnet.getcelllocation ();
 
    if (location = = null) throw new Exception ("failed to get base station information");
    String operator = Mtelnet.getnetworkoperator ();
    int MCC = Integer.parseint (operator.substring (0, 3));
    int MNC = Integer.parseint (operator.substring (3)); int cid = LoCation.getcid ();
 
    int lac = Location.getlac (); /** the obtained data into the structure of the * * cell.
    MCC = MCC; Cell.
    MNC = MNC; Cell.
    LAC = LAC; Cell.
 
    CID = CID;
  return cell; /** * Obtain latitude and longitude * * @throws Exception/private situde getitude (Scell cell) throws Exception {SIt
 
    Ude itude = new Situde ();
    /** uses the android default HttpClient */httpclient client = new Defaulthttpclient ();
    /** using POST method */HttpPost post = new HttpPost ("Http://www.google.com/loc/json");
      The JSON data for the try {/** construct post/jsonobject holder = new Jsonobject ();
      Holder.put ("Version", "1.1.0");
      Holder.put ("Host", "maps.google.com");
      Holder.put ("Address_language", "ZH_CN");
      Holder.put ("Request_address", true);
      Holder.put ("Radio_type", "GSM");
 
      Holder.put ("Carrier", "HTC");
      Jsonobject tower = new Jsonobject (); Tower.put ("Mobile_country_code", cell.
      MCC); Tower.put ("Mobile_network_code", cell.
      MNC); Tower.put ("cell_id", CEll.
      CID); Tower.put ("Location_area_code", cell.
 
      LAC);
      Jsonarray Towerarray = new Jsonarray ();
      Towerarray.put (tower);
 
      Holder.put ("Cell_towers", Towerarray);
      stringentity query = new stringentity (holder.tostring ());
 
      post.setentity (query);
      /** issue the post data and obtain the return data */httpresponse response = Client.execute (POST);
      httpentity entity = response.getentity ();
      BufferedReader buffreader = new BufferedReader (New InputStreamReader (Entity.getcontent ()));
      StringBuffer Strbuff = new StringBuffer ();
      String result = null;
      while (result = Buffreader.readline ())!= null) {strbuff.append (result);
      /** parse the returned JSON data to obtain latitude and longitude * * * jsonobject JSON = new Jsonobject (strbuff.tostring ());
 
      Jsonobject subjosn = new Jsonobject (json.getstring ("location"));
      Itude.latitude = subjosn.getstring ("latitude");
       
      Itude.longitude = subjosn.getstring ("longitude"); LOG.I ("Itude", Itude.latitude +Itude.longitude);
      catch (Exception e) {log.e (E.getmessage (), e.tostring ());
    throw new Exception ("Get latitude and longitude error:" +e.getmessage ());
      } finally{Post.abort ();
    client = null;
  return itude;
    /** * Access to geographic location * * @throws Exception * * Private String getLocation (Situde itude) throws Exception {
 
    String resultstring = ""; /** here The Get method is used to add parameters directly to the URL/String urlstring = String.Format ("http://maps.google.cn/maps/geo?key=abcdefg&amp;q=%s,%
    S ", Itude.latitude, Itude.longitude);
 
    LOG.I ("URL", urlstring);
    /** New HttpClient * * httpclient client = new Defaulthttpclient ();
    /** using Get method * * HttpGet get = new HttpGet (urlstring);
      Try {/** initiates a GET request and obtains the return data */httpresponse response = Client.execute (gets);
      httpentity entity = response.getentity ();
      BufferedReader buffreader = new BufferedReader (New InputStreamReader (Entity.getcontent ())); StringBuffer Strbuff = new StringbuffeR ();
      String result = null;
      while (result = Buffreader.readline ())!= null) {strbuff.append (result);
 
      } resultstring = Strbuff.tostring (); /** parse JSON data, get Physical Address */if (resultstring!= null &amp;&amp; resultstring.length () &gt; 0) {jsonobject jsonob
        ject = new Jsonobject (resultstring);
        Jsonarray Jsonarray = new Jsonarray (Jsonobject.get ("Placemark"). toString ());
        resultstring = ""; for (int i = 0; i &lt; jsonarray.length (); i++) {resultstring = Jsonarray.getjsonobject (i). getString ("Address")
        ;
    (Exception e) {throw new Exception ("Get the Physical location error:" + e.getmessage ());
      finally {get.abort ();
    client = null;
  return resultstring; /** Display result */private void Showresult (Scell cell, String location) {TextView Celltext = (TextView) Findviewby
    Id (R.id.celltext);
       Celltext.settext (String.Format ("Base station information: mcc:%d, mnc:%d, lac:%d, cid:%d", Cell. MCC, Cell. MNC, Cell. LAC, Cell.
 
    CID));
    TextView Locationtext = (TextView) Findviewbyid (R.id.lacationtext);
  Locationtext.settext ("Physical Location:" + location);
 }
}

We connect the phone to run the program on the phone to see.

No surprises. The program runs and automatically jumps to the main interface. Click "Click Me" and make a mistake!

The detailed error message is: Neither user 10078 nor current process has android.permission.ACCESS_COARSE_LOCATION.

The original is not authorized, after the study, we know that Android in the application of the security of a kung fu, to use some special features must first report, install the application when listed to the user to see, must get the user's permission. Here we use the function of acquiring the base station information, which involves the user's privacy, so we must make a statement.

Open the Androidmanifest.xml configuration file and add the appropriate configuration information inside:

<uses-permission android:name= "Android.permission.ACCESS_FINE_LOCATION" ></uses-permission>

We continue to add the rights to the network connection:

<uses-permission android:name= "Android.permission.INTERNET" ></uses-permission>

Then compile the run to see (click "Click Me" after the program will be stuck, wait for some time to respond, depending on the network situation):

It worked!

There may be some students or errors, no success:

█ hint "www.google.com ..." What's wrong

Make sure your phone has access to the Internet and that the API to call Google must be networked.

█ the base station information is not available

Are you sure you tested it on the phone? The simulator is not going to work. or the CMDA network that your phone uses? This example only supports GSM network ...

█ not get latitude and longitude

It is likely that you won the lottery, your base station has not been included in Google's database ... (Say I have met before, how to search is to find out the latitude and longitude, return data is empty)

The geographic address █ obtained is incorrect

This may be a program error, maybe Google went wrong?

In fact, the data returned by the Google Map API also contains a lot of other information, we can use to develop some more interesting features, such as the production of our own map software, footprint software, and so give full play to your creativity:

Viii. Summary

This program basically achieved base station positioning function, but there are many problems, such as: Click the button after the interface will be stuck (access to the network blocked process), no further processing of exceptions, incompatible CMDA network.

In addition, the accuracy of the program is not enough, the location is actually the physical location of the base station, and the location of the person is still a certain gap. In the city, the general use of concentrated small power base station, the accuracy is generally within hundreds of meters, while in the suburbs often for high-power base station, density is very small, precision is generally more than thousands of meters.

To achieve higher accuracy needs to be achieved through a number of other algorithms, if we are interested, we can study together, and then write a special note.

It can be seen that there is a big difference between writing a program and doing a real product.

End
This section basically realizes the simplest base station localization, just as the study example, far does not reach the product request, please everybody forgive me.

We are more familiar with the Java code, before how to contact Java seems a bit difficult to find some of the students suggest a Java based book to see.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.