Android Service獲取當前位置(GPS+基站)

Ruthless發表於2013-06-21

需求詳情:
1)、Service中每隔1秒執行一次定位操作(GPS+基站)
2)、定位的結果實時顯示在介面上(要求得到經度、緯度)
技術支援:
1)、獲取經緯度
透過GPS+基站獲取經緯度,先透過GPS來獲取,如果為空改用基站進行獲取–>GPS+基站(基站獲取支援聯通、電信、移動)。
2)、實時獲取經緯度
為了達到實時獲取經緯度,需在後臺啟動獲取經緯度的Service,然後把經緯度資料透過廣播傳送出去,在需要的地方進行廣播註冊(比如在Activity中註冊廣播,顯示在介面中)–>涉及到Service+BroadcastReceiver+Activity+Thread等知識點。

備註:本文注重實踐,如有看不懂的,先去鞏固下知識點,可以去看看我前面寫的幾篇文章。

1、CellInfo實體類–>基站資訊

package com.ljq.activity;
 
/**
 * 基站資訊
 * 
 * @author jiqinlin
 * 
 */
public class CellInfo {
 /** 基站id,用來找到基站的位置 */
 private int cellId;
 /** 移動國家碼,共3位,中國為460,即imsi前3位 */
 private String mobileCountryCode="460";
 /** 行動網路碼,共2位,在中國,移動的程式碼為00和02,聯通的程式碼為01,電信的程式碼為03,即imsi第4~5位 */
 private String mobileNetworkCode="0";
 /** 地區區域碼 */
 private int locationAreaCode;
 /** 訊號型別[選 gsm|cdma|wcdma] */
 private String radioType="";
 
 public CellInfo() {
 }
 
 public int getCellId() {
  return cellId;
 }
 
 public void setCellId(int cellId) {
  this.cellId = cellId;
 }
 
 public String getMobileCountryCode() {
  return mobileCountryCode;
 }
 
 public void setMobileCountryCode(String mobileCountryCode) {
  this.mobileCountryCode = mobileCountryCode;
 }
 
 public String getMobileNetworkCode() {
  return mobileNetworkCode;
 }
 
 public void setMobileNetworkCode(String mobileNetworkCode) {
  this.mobileNetworkCode = mobileNetworkCode;
 }
 
 public int getLocationAreaCode() {
  return locationAreaCode;
 }
 
 public void setLocationAreaCode(int locationAreaCode) {
  this.locationAreaCode = locationAreaCode;
 }
 
 public String getRadioType() {
  return radioType;
 }
 
 public void setRadioType(String radioType) {
  this.radioType = radioType;
 }
 
}

2、Gps類–>Gps封裝類,用來獲取經緯度

package com.ljq.activity;
 
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
 
public class Gps{
 private Location location = null;
 private LocationManager locationManager = null;
 private Context context = null;
 
 /**
  * 初始化 
  * 
  * @param ctx
  */
 public Gps(Context ctx) {
  context=ctx;
  locationManager=(LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
  location = locationManager.getLastKnownLocation(getProvider());
  locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, locationListener);
 }
 
 
 // 獲取Location Provider
 private String getProvider() {
  // 構建位置查詢條件
  Criteria criteria = new Criteria();
  // 查詢精度:高
  criteria.setAccuracy(Criteria.ACCURACY_FINE);
  // 是否查詢海撥:否
  criteria.setAltitudeRequired(false);
  // 是否查詢方位角 : 否
  criteria.setBearingRequired(false);
  // 是否允許付費:是
  criteria.setCostAllowed(true);
  // 電量要求:低
  criteria.setPowerRequirement(Criteria.POWER_LOW);
  // 返回最合適的符合條件的provider,第2個引數為true說明 , 如果只有一個provider是有效的,則返回當前provider
  return locationManager.getBestProvider(criteria, true);
 }
 
 private LocationListener locationListener = new LocationListener() {
  // 位置發生改變後呼叫
  public void onLocationChanged(Location l) {
   if(l!=null){
    location=l;
   }
  }
 
  // provider 被使用者關閉後呼叫
  public void onProviderDisabled(String provider) {
   location=null;
  }
 
  // provider 被使用者開啟後呼叫
  public void onProviderEnabled(String provider) {
   Location l = locationManager.getLastKnownLocation(provider);
   if(l!=null){
    location=l;
   }
     
  }
 
  // provider 狀態變化時呼叫
  public void onStatusChanged(String provider, int status, Bundle extras) {
  }
 
 };
  
 public Location getLocation(){
  return location;
 }
  
 public void closeLocation(){
  if(locationManager!=null){
   if(locationListener!=null){
    locationManager.removeUpdates(locationListener);
    locationListener=null;
   }
   locationManager=null;
  }
 }
 
 
}

3、GpsService服務類

package com.ljq.activity;
 
import java.util.ArrayList;
 
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.os.IBinder;
import android.util.Log;
 
public class GpsService extends Service {
 ArrayList<CellInfo> cellIds = null;
 private Gps gps=null;
 private boolean threadDisable=false; 
 private final static String TAG=GpsService.class.getSimpleName();
 
 @Override
 public void onCreate() {
  super.onCreate();
   
  gps=new Gps(GpsService.this);
  cellIds=UtilTool.init(GpsService.this);
   
  new Thread(new Runnable(){
   @Override
   public void run() {
    while (!threadDisable) { 
     try {
      Thread.sleep(1000);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
      
     if(gps!=null){ //當結束服務時gps為空
      //獲取經緯度
      Location location=gps.getLocation();
      //如果gps無法獲取經緯度,改用基站定位獲取
      if(location==null){
       Log.v(TAG, "gps location null"); 
       //2.根據基站資訊獲取經緯度
       try {
        location = UtilTool.callGear(GpsService.this, cellIds);
       } catch (Exception e) {
        location=null;
        e.printStackTrace();
       }
       if(location==null){
        Log.v(TAG, "cell location null"); 
       }
      }
       
      //傳送廣播
      Intent intent=new Intent();
      intent.putExtra("lat", location==null?"":location.getLatitude()+""); 
      intent.putExtra("lon", location==null?"":location.getLongitude()+""); 
      intent.setAction("com.ljq.activity.GpsService"); 
      sendBroadcast(intent);
     }
 
    }
   }
  }).start();
   
 }
 
 @Override
 public void onDestroy() {
  threadDisable=true;
  if(cellIds!=null&&cellIds.size()>0){
   cellIds=null;
  }
  if(gps!=null){
   gps.closeLocation();
   gps=null;
  }
  super.onDestroy();
 }
 
 @Override
 public IBinder onBind(Intent arg0) {
  return null;
 }
 
 
}

4、GpsActivity–>在介面上實時顯示經緯度資料

package com.ljq.activity;
 
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;
 
public class GpsActivity extends Activity {
 private Double homeLat=26.0673834d; //宿舍緯度
 private Double homeLon=119.3119936d; //宿舍經度
 private EditText editText = null;
 private MyReceiver receiver=null; 
 private final static String TAG=GpsActivity.class.getSimpleName();
 
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
   
  editText=(EditText)findViewById(R.id.editText);
   
  //判斷GPS是否可用
  Log.i(TAG, UtilTool.isGpsEnabled((LocationManager)getSystemService(Context.LOCATION_SERVICE))+"");
  if(!UtilTool.isGpsEnabled((LocationManager)getSystemService(Context.LOCATION_SERVICE))){
   Toast.makeText(this, "GSP當前已禁用,請在您的系統設定螢幕啟動。", Toast.LENGTH_LONG).show();
   Intent callGPSSettingIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);  
   startActivity(callGPSSettingIntent);
            return;
  }   
   
  //啟動服務
  startService(new Intent(this, GpsService.class));
   
  //註冊廣播
  receiver=new MyReceiver();
  IntentFilter filter=new IntentFilter();
  filter.addAction("com.ljq.activity.GpsService");
  registerReceiver(receiver, filter);
 }
  
 //獲取廣播資料
 private class MyReceiver extends BroadcastReceiver{
  @Override
  public void onReceive(Context context, Intent intent) {
   Bundle bundle=intent.getExtras();      
   String lon=bundle.getString("lon");    
   String lat=bundle.getString("lat"); 
   if(lon!=null&&!"".equals(lon)&&lat!=null&&!"".equals(lat)){
    double distance=getDistance(Double.parseDouble(lat), 
      Double.parseDouble(lon), homeLat, homeLon);
    editText.setText("目前經緯度\n經度:"+lon+"\n緯度:"+lat+"\n離宿舍距離:"+java.lang.Math.abs(distance));
   }else{
    editText.setText("目前經緯度\n經度:"+lon+"\n緯度:"+lat);
   }
  }
 }
  
 @Override
 protected void onDestroy() {
  //登出服務
  unregisterReceiver(receiver);
  //結束服務,如果想讓服務一直執行就登出此句
  stopService(new Intent(this, GpsService.class));
  super.onDestroy();
 }
  
 /**
  * 把經緯度換算成距離
  * 
  * @param lat1 開始緯度
  * @param lon1 開始經度
  * @param lat2 結束緯度
  * @param lon2 結束經度
  * @return
  */
 private double getDistance(double lat1, double lon1, double lat2, double lon2) {
  float[] results = new float[1];
  Location.distanceBetween(lat1, lon1, lat2, lon2, results);
  return results[0];
 }  
}

5、UtilTool–>工具類

package com.ljq.activity;
 
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
 
import org.apache.http.client.ClientProtocolException;
import org.json.JSONException;
import org.json.JSONObject;
 
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.telephony.NeighboringCellInfo;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import android.util.Log;
import android.widget.Toast;
 
public class UtilTool {
 public static boolean isGpsEnabled(LocationManager locationManager) {
  boolean isOpenGPS = locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER);
  boolean isOpenNetwork = locationManager.isProviderEnabled(android.location.LocationManager.NETWORK_PROVIDER);
  if (isOpenGPS || isOpenNetwork) {
   return true;
  }
  return false;
 } 
  
    /**
     * 根據基站資訊獲取經緯度 
     * 
     * 原理向http://www.google.com/loc/json傳送http的post請求,根據google返回的結果獲取經緯度
     * 
     * @param cellIds
     * @return
     * @throws Exception 
     */
    public static Location callGear(Context ctx, ArrayList<CellInfo> cellIds) throws Exception {
     String result="";
     JSONObject data=null;
     if (cellIds == null||cellIds.size()==0) {
      UtilTool.alert(ctx, "cell request param null");
      return null;
     };
      
  try {
   result = UtilTool.getResponseResult(ctx, "http://www.google.com/loc/json", cellIds);
    
   if(result.length() <= 1)
    return null;
   data = new JSONObject(result);
   data = (JSONObject) data.get("location");
 
   Location loc = new Location(LocationManager.NETWORK_PROVIDER);
   loc.setLatitude((Double) data.get("latitude"));
   loc.setLongitude((Double) data.get("longitude"));
   loc.setAccuracy(Float.parseFloat(data.get("accuracy").toString()));
   loc.setTime(UtilTool.getUTCTime());
   return loc;
  } catch (JSONException e) {
   return null;
  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
  } catch (ClientProtocolException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
  return null;
 }
 
    /**
     * 接收Google返回的資料格式
     * 
  * 出參:{"location":{"latitude":26.0673834,"longitude":119.3119936,
  *       "address":{"country":"中å½","country_code":"CN","region":"ç¦å»ºç","city":"ç¦å·å¸",
  *       "street":"äºä¸ä¸­è·¯","street_number":"128å·"},"accuracy":935.0},
  *       "access_token":"2:xiU8YrSifFHUAvRJ:aj9k70VJMRWo_9_G"}
  * 請求路徑:http://maps.google.cn/maps/geo?key=abcdefg&q=26.0673834,119.3119936
     * 
     * @param cellIds
     * @return
     * @throws UnsupportedEncodingException
     * @throws MalformedURLException
     * @throws IOException
     * @throws ProtocolException
     * @throws Exception
     */
 public static String getResponseResult(Context ctx,String path, ArrayList<CellInfo> cellInfos)
   throws UnsupportedEncodingException, MalformedURLException,
   IOException, ProtocolException, Exception {
  String result="";
  Log.i(ctx.getApplicationContext().getClass().getSimpleName(), 
    "in param: "+getRequestParams(cellInfos));
  InputStream inStream=UtilTool.sendPostRequest(path, 
    getRequestParams(cellInfos), "UTF-8");
  if(inStream!=null){
   byte[] datas=UtilTool.readInputStream(inStream);
   if(datas!=null&&datas.length>0){
    result=new String(datas, "UTF-8");
    //Log.i(ctx.getClass().getSimpleName(), "receive result:"+result);//伺服器返回的結果資訊
    Log.i(ctx.getApplicationContext().getClass().getSimpleName(), 
        "google cell receive data result:"+result);
   }else{
    Log.i(ctx.getApplicationContext().getClass().getSimpleName(), 
      "google cell receive data null");
   }
  }else{
   Log.i(ctx.getApplicationContext().getClass().getSimpleName(), 
       "google cell receive inStream null");
  }
  return result;
 }
     
  
 /**
  * 拼裝json請求引數,拼裝基站資訊
  * 
  * 入參:{'version': '1.1.0','host': 'maps.google.com','home_mobile_country_code': 460,
  *       'home_mobile_network_code': 14136,'radio_type': 'cdma','request_address': true,
  *       'address_language': 'zh_CN','cell_towers':[{'cell_id': '12835','location_area_code': 6,
  *       'mobile_country_code': 460,'mobile_network_code': 14136,'age': 0}]}
  * @param cellInfos
  * @return
  */
 public static String getRequestParams(List<CellInfo> cellInfos){
  StringBuffer sb=new StringBuffer("");
  sb.append("{");
  if(cellInfos!=null&&cellInfos.size()>0){
   sb.append("'version': '1.1.0',"); //google api 版本[必]
   sb.append("'host': 'maps.google.com',"); //伺服器域名[必]
   sb.append("'home_mobile_country_code': "+cellInfos.get(0).getMobileCountryCode()+","); //移動使用者所屬國家代號[選 中國460]
   sb.append("'home_mobile_network_code': "+cellInfos.get(0).getMobileNetworkCode()+","); //移動系統號碼[預設0]
   sb.append("'radio_type': '"+cellInfos.get(0).getRadioType()+"',"); //訊號型別[選 gsm|cdma|wcdma]
   sb.append("'request_address': true,"); //是否返回資料[必]
   sb.append("'address_language': 'zh_CN',"); //反饋資料語言[選 中國 zh_CN]
   sb.append("'cell_towers':["); //移動基站引數物件[必]
   for(CellInfo cellInfo:cellInfos){
    sb.append("{");
    sb.append("'cell_id': '"+cellInfo.getCellId()+"',"); //基站ID[必]
    sb.append("'location_area_code': "+cellInfo.getLocationAreaCode()+","); //地區區域碼[必]
    sb.append("'mobile_country_code': "+cellInfo.getMobileCountryCode()+","); 
    sb.append("'mobile_network_code': "+cellInfo.getMobileNetworkCode()+",");
    sb.append("'age': 0"); //使用好久的資料庫[選 預設0表示使用最新的資料庫]
    sb.append("},");
   }
   sb.deleteCharAt(sb.length()-1);
   sb.append("]");
  }
  sb.append("}");
  return sb.toString();
 }
     
 /**
  * 獲取UTC時間
  * 
  * UTC + 時區差 = 本地時間(北京為東八區)
  * 
  * @return
  */
 public static long getUTCTime() { 
     //取得本地時間
        Calendar cal = Calendar.getInstance(Locale.CHINA);
        //取得時間偏移量
        int zoneOffset = cal.get(java.util.Calendar.ZONE_OFFSET); 
        //取得夏令時差
        int dstOffset = cal.get(java.util.Calendar.DST_OFFSET); 
        //從本地時間裡扣除這些差量,即可以取得UTC時間
        cal.add(java.util.Calendar.MILLISECOND, -(zoneOffset + dstOffset)); 
        return cal.getTimeInMillis();
    }
 /**
  * 初始化,記得放在onCreate()方法裡初始化,獲取基站資訊
  * 
  * @return
  */
 public static ArrayList<CellInfo> init(Context ctx) {
  ArrayList<CellInfo> cellInfos = new ArrayList<CellInfo>();
   
  TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
  //網路制式
  int type = tm.getNetworkType();
      /**
     * 獲取SIM卡的IMSI碼
     * SIM卡唯一標識:IMSI 國際移動使用者識別碼(IMSI:International Mobile Subscriber Identification Number)是區別移動使用者的標誌,
     * 儲存在SIM卡中,可用於區別移動使用者的有效資訊。IMSI由MCC、MNC、MSIN組成,其中MCC為移動國家號碼,由3位數字組成,
     * 唯一地識別移動客戶所屬的國家,我國為460;MNC為網路id,由2位數字組成,
     * 用於識別移動客戶所歸屬的行動網路,中國移動為00,中國聯通為01,中國電信為03;MSIN為移動客戶識別碼,採用等長11位數字構成。
     * 唯一地識別國內GSM行動通訊網中移動客戶。所以要區分是移動還是聯通,只需取得SIM卡中的MNC欄位即可
   */
  String imsi = tm.getSubscriberId(); 
  alert(ctx, "imsi: "+imsi);
  //為了區分移動、聯通還是電信,推薦使用imsi來判斷(萬不得己的情況下用getNetworkType()判斷,比如imsi為空時)
  if(imsi!=null&&!"".equals(imsi)){ 
   alert(ctx, "imsi");
   if (imsi.startsWith("46000") || imsi.startsWith("46002")) {// 因為行動網路編號46000下的IMSI已經用完,所以虛擬了一個46002編號,134/159號段使用了此編號
    // 中國移動
    mobile(cellInfos, tm);
   } else if (imsi.startsWith("46001")) {
    // 中國聯通
    union(cellInfos, tm);
   } else if (imsi.startsWith("46003")) {
    // 中國電信
    cdma(cellInfos, tm);
   }   
  }else{
   alert(ctx, "type");
   // 在中國,聯通的3G為UMTS或HSDPA,電信的3G為EVDO
   // 在中國,移動的2G是EGDE,聯通的2G為GPRS,電信的2G為CDMA
   // String OperatorName = tm.getNetworkOperatorName(); 
    
   //中國電信 
   if (type == TelephonyManager.NETWORK_TYPE_EVDO_A 
     || type == TelephonyManager.NETWORK_TYPE_EVDO_0
     || type == TelephonyManager.NETWORK_TYPE_CDMA 
     || type ==TelephonyManager.NETWORK_TYPE_1xRTT){
    cdma(cellInfos, tm);
   }
   //移動(EDGE(2.75G)是GPRS(2.5G)的升級版,速度比GPRS要快。目前移動基本在國內升級普及EDGE,聯通則在大城市部署EDGE。)
   else if(type == TelephonyManager.NETWORK_TYPE_EDGE
     || type == TelephonyManager.NETWORK_TYPE_GPRS ){
    mobile(cellInfos, tm);
   }
   //聯通(EDGE(2.75G)是GPRS(2.5G)的升級版,速度比GPRS要快。目前移動基本在國內升級普及EDGE,聯通則在大城市部署EDGE。)
   else if(type == TelephonyManager.NETWORK_TYPE_GPRS
     ||type == TelephonyManager.NETWORK_TYPE_EDGE
     ||type == TelephonyManager.NETWORK_TYPE_UMTS
     ||type == TelephonyManager.NETWORK_TYPE_HSDPA){
    union(cellInfos, tm);
   }
  }
   
  return cellInfos;
 }
 
 
 /**
  * 電信
  * 
  * @param cellInfos
  * @param tm
  */
 private static void cdma(ArrayList<CellInfo> cellInfos, TelephonyManager tm) {
  CdmaCellLocation location = (CdmaCellLocation) tm.getCellLocation();
  CellInfo info = new CellInfo();
  info.setCellId(location.getBaseStationId());
  info.setLocationAreaCode(location.getNetworkId());
  info.setMobileNetworkCode(String.valueOf(location.getSystemId()));
  info.setMobileCountryCode(tm.getNetworkOperator().substring(0, 3));
  info.setRadioType("cdma");
  cellInfos.add(info);
   
  //前面獲取到的都是單個基站的資訊,接下來再獲取周圍鄰近基站資訊以輔助透過基站定位的精準性
  // 獲得鄰近基站資訊
  List<NeighboringCellInfo> list = tm.getNeighboringCellInfo();
  int size = list.size();
  for (int i = 0; i < size; i++) {
   CellInfo cell = new CellInfo();
   cell.setCellId(list.get(i).getCid());
   cell.setLocationAreaCode(location.getNetworkId());
   cell.setMobileNetworkCode(String.valueOf(location.getSystemId()));
   cell.setMobileCountryCode(tm.getNetworkOperator().substring(0, 3));
   cell.setRadioType("cdma");
   cellInfos.add(cell);
  }
 }
 
 
 /**
  * 移動
  * 
  * @param cellInfos
  * @param tm
  */
 private static void mobile(ArrayList<CellInfo> cellInfos,
   TelephonyManager tm) {
  GsmCellLocation location = (GsmCellLocation)tm.getCellLocation();  
  CellInfo info = new CellInfo();
  info.setCellId(location.getCid());
  info.setLocationAreaCode(location.getLac());
  info.setMobileNetworkCode(tm.getNetworkOperator().substring(3, 5));
  info.setMobileCountryCode(tm.getNetworkOperator().substring(0, 3));
  info.setRadioType("gsm");
  cellInfos.add(info);
   
  //前面獲取到的都是單個基站的資訊,接下來再獲取周圍鄰近基站資訊以輔助透過基站定位的精準性
  // 獲得鄰近基站資訊
  List<NeighboringCellInfo> list = tm.getNeighboringCellInfo();
  int size = list.size();
  for (int i = 0; i < size; i++) {
   CellInfo cell = new CellInfo();
   cell.setCellId(list.get(i).getCid());
   cell.setLocationAreaCode(location.getLac());
   cell.setMobileNetworkCode(tm.getNetworkOperator().substring(3, 5));
   cell.setMobileCountryCode(tm.getNetworkOperator().substring(0, 3));
   cell.setRadioType("gsm");
   cellInfos.add(cell);
  }
 }
 
 
 /**
  *  聯通
  *  
  * @param cellInfos
  * @param tm
  */
 private static void union(ArrayList<CellInfo> cellInfos, TelephonyManager tm) {
  GsmCellLocation location = (GsmCellLocation)tm.getCellLocation();  
  CellInfo info = new CellInfo();
  //經過測試,獲取聯通資料以下兩行必須去掉,否則會出現錯誤,錯誤型別為JSON Parsing Error
  //info.setMobileNetworkCode(tm.getNetworkOperator().substring(3, 5));  
  //info.setMobileCountryCode(tm.getNetworkOperator().substring(0, 3));
  info.setCellId(location.getCid());
  info.setLocationAreaCode(location.getLac());
  info.setMobileNetworkCode("");
  info.setMobileCountryCode("");
  info.setRadioType("gsm");
  cellInfos.add(info);
   
  //前面獲取到的都是單個基站的資訊,接下來再獲取周圍鄰近基站資訊以輔助透過基站定位的精準性
  // 獲得鄰近基站資訊
  List<NeighboringCellInfo> list = tm.getNeighboringCellInfo();
  int size = list.size();
  for (int i = 0; i < size; i++) {
   CellInfo cell = new CellInfo();
   cell.setCellId(list.get(i).getCid());
   cell.setLocationAreaCode(location.getLac());
   cell.setMobileNetworkCode("");
   cell.setMobileCountryCode("");
   cell.setRadioType("gsm");
   cellInfos.add(cell);
  }
 }
 /**
  * 提示
  * 
  * @param ctx
  * @param msg
  */
 public static void alert(Context ctx,String msg){
  Toast.makeText(ctx, msg, Toast.LENGTH_LONG).show();
 }
  
 /**
  * 傳送post請求,返回輸入流
  * 
  * @param path 訪問路徑
  * @param params json資料格式
  * @param encoding 編碼
  * @return
  * @throws UnsupportedEncodingException
  * @throws MalformedURLException
  * @throws IOException
  * @throws ProtocolException
  */
 public static InputStream sendPostRequest(String path, String params, String encoding)
 throws UnsupportedEncodingException, MalformedURLException,
 IOException, ProtocolException {
  byte[] data = params.getBytes(encoding);
  URL url = new URL(path);
  HttpURLConnection conn = (HttpURLConnection)url.openConnection();
  conn.setRequestMethod("POST");
  conn.setDoOutput(true);
  //application/x-javascript text/xml->xml資料 application/x-javascript->json物件 application/x-www-form-urlencoded->表單資料
  conn.setRequestProperty("Content-Type", "application/x-javascript; charset="+ encoding);
  conn.setRequestProperty("Content-Length", String.valueOf(data.length));
  conn.setConnectTimeout(5 * 1000);
  OutputStream outStream = conn.getOutputStream();
  outStream.write(data);
  outStream.flush();
  outStream.close();
  if(conn.getResponseCode()==200)
   return conn.getInputStream();
  return null;
 }
  
 /**
  * 傳送get請求
  * 
  * @param path 請求路徑
  * @return
  * @throws Exception
  */
 public static String sendGetRequest(String path) throws Exception {
  URL url = new URL(path);
  HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  conn.setConnectTimeout(5 * 1000);
  conn.setRequestMethod("GET");
  InputStream inStream = conn.getInputStream();
  byte[] data = readInputStream(inStream);
  String result = new String(data, "UTF-8");
  return result;
 }
  
 /**
  * 從輸入流中讀取資料
  * @param inStream
  * @return
  * @throws Exception
  */
 public static byte[] readInputStream(InputStream inStream) throws Exception{
  ByteArrayOutputStream outStream = new ByteArrayOutputStream();
  byte[] buffer = new byte[1024];
  int len = 0;
  while( (len = inStream.read(buffer)) !=-1 ){
   outStream.write(buffer, 0, len);
  }
  byte[] data = outStream.toByteArray();//網頁的二進位制資料
  outStream.close();
  inStream.close();
  return data;
 }
 
  
}

6、main.xml–>佈局檔案

<?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">
    <EditText android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:cursorVisible="false"
        android:editable="false"
        android:id="@+id/editText"/>
 
</LinearLayout>

7、清單檔案

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.ljq.activity" android:versionCode="1"
 android:versionName="1.0">
 <application android:icon="@drawable/icon"
  android:label="@string/app_name">
  <activity android:name=".GpsActivity"
   android:label="@string/app_name">
   <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category
     android:name="android.intent.category.LAUNCHER" />
   </intent-filter>
  </activity>
  <service android:label="GPS服務" android:name=".GpsService" />
 
 </application>
 <uses-sdk android:minSdkVersion="7" />
 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
</manifest>

效果如下:

相關文章