android基站定位程序獲取地理位置

在Android操作系統下,基站定位其實很簡單,先說一下實現流程:

調用SDK中的API(TelephonyManager)獲得MCC、MNC、LAC、CID等信息,然後通過google的API獲得所在位置的經緯度,最後再通過google map的API獲得實際的地理位置。(google真牛!)

有同學會問:MNC、MCC、LAC、CID都是些什麼東西?google又怎麼通過這些東西就獲得經緯度了呢?

我們一起來學習一下:

MCC,Mobile Country Code,移動國家代碼(中國的爲460);

MNC,Mobile Network Code,移動網絡號碼(中國移動爲00,中國聯通爲01);

LAC,Location Area Code,位置區域碼;

CID,Cell Identity,基站編號,是個16位的數據(範圍是0到65535)。

瞭解了這幾個名詞的意思,相信有些朋友已經知道後面的事了:google存儲了這些信息,直接查詢就能得到經緯度了。(至於google怎麼得到移動、聯通的基站信息,這就不得而知了,反正google免費提供接口,直接調用就是)

下面開始動手。

一、設置界面

我們在上一節的程序的基礎上進行開發,在DemoActivity的界面上實現這個功能。(沒有代碼的同學可點擊這裏下載,感謝yuejianjun同學的建議,以後我會在每一節的最後把例子打包提供下載)

首先我們將DemoActivity使用的佈局修改一下:

image

第1行爲TextView,顯示提示文字;第2行爲一個Button,觸發事件;第3行、第4行分別顯示基站信息和地理位置(現在爲空,看不到)。

layout/main.xml文件內容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://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="wrap_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" />
 
    <TextView
        android:id="@+id/cellText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="" />
 
    <TextView
        android:id="@+id/lacationText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="" />
 
</LinearLayout>

接下來我們打開DemoActivity.java編寫代碼。

二、爲按鈕綁定事件

我們在Activity創建時綁定事件,將以下代碼添加到setContentView(R.layout.main);後:

1
2
3
4
5
6
7
8
9
/** 爲按鈕綁定事件 */
Button btnGetLocation = (Button)findViewById(R.id.button1);
btnGetLocation.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
        onBtnClick();
    }
});

同時還需要在頭部import相關組件:

1
2
3
import android.view.View;
import android.widget.Button;
import android.view.View.OnClickListener;

我們來分析一下這段代碼:

首先我們通過findViewById(R.id.button1)找到按鈕這個對象,前面加(Button)表示顯示的轉換爲Button對象;

然後設置按鈕點擊事件的監聽器,參數爲OnClickListener對象,再重載這個類的onClick方法,調用onBtnClick方法(這個方法得由我們自己去寫,他在點擊按鈕時被調用)。

好了,調用方法寫好了,我們來寫實現(調用後需要做什麼事)。動手編碼之前先在腦中整理好思路,養成好習慣。

我們需要在DemoActivty類中添加如下私有方法:

  1. 我們需要剛剛提到的onBtnClick回調方法,被調用時實現取得基站信息、獲取經緯度、獲取地理位置、顯示的功能。但是很顯然,全部揉到一個方法裏面並不是個好主意,我們將它分割爲幾個方法;
  2. 添加獲取基站信息的方法getCellInfo,返回基站信息;
  3. 添加獲取經緯度的方法getItude,傳入基站信息,返回經緯度;
  4. 添加獲取地理位置的方法getLocation,傳入經緯度,返回地理位置;
  5. 添加顯示結果的方法showResult,傳入得到的信息在界面上顯示出來。

好了,先將方法添上,完整代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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;
 
public class DemoActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
         
        /** 爲按鈕綁定事件 */
        Button btnGetLocation = (Button)findViewById(R.id.button1);
        btnGetLocation.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                onBtnClick();
            }
        });
    }
     
    /** 基站信息結構體 */
    public class SCell{
        public int MCC;
        public int MNC;
        public int LAC;
        public int CID;
    }
     
    /** 經緯度信息結構體 */
    public class SItude{
        public String latitude;
        public String longitude;
    }
     
    /** 按鈕點擊回調函數 */
    private void onBtnClick(){
         
    }
     
    /** 獲取基站信息 */
    private SCell getCellInfo(){
 
    }
     
    /** 獲取經緯度 */
    private SItude getItude(SCell cell){
         
    }
     
    /** 獲取地理位置 */
    private String getLocation(SItude itude){
         
    }
     
    /** 顯示結果 */
    private void showResult(SCell cell, String location){
         
    }
}

現在在onBtnClick方法中編碼,依次調用後面幾個方法,代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/** 按鈕點擊回調函數 */
private void onBtnClick(){
    /** 彈出一個等待狀態的框 */
    ProgressDialog mProgressDialog = new ProgressDialog(this);
    mProgressDialog.setMessage("正在獲取中...");
    mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    mProgressDialog.show();
     
    try {
        /** 獲取基站數據 */
        SCell cell = getCellInfo();
         
        /** 根據基站數據獲取經緯度 */
        SItude itude = getItude(cell);
         
        /** 獲取地理位置 */
        String location = getLocation(itude);
         
        /** 顯示結果 */
        showResult(cell, location);
         
        /** 關閉對話框 */
        mProgressDialog.dismiss();
    }catch (Exception e) {
        /** 關閉對話框 */
        mProgressDialog.dismiss();
        /** 顯示錯誤 */
        TextView cellText = (TextView)findViewById(R.id.cellText);
        cellText.setText(e.getMessage());
    }
}

按鈕相關的工作就完成了,接下來編寫獲取基站信息的方法。

三、獲取基站信息

獲取基站信息我們需要調用SDK提供的API中的TelephonyManager,需要在文件頭部引入:

1
2
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;

完整代碼爲:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
 * 獲取基站信息
 *
 * @throws Exception
 */
private SCell getCellInfo() throws Exception {
    SCell cell = new SCell();
 
    /** 調用API獲取基站信息 */
    TelephonyManager mTelNet = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    GsmCellLocation location = (GsmCellLocation) mTelNet.getCellLocation();
    if (location == null)
        throw new Exception("獲取基站信息失敗");
 
    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();
 
    /** 將獲得的數據放到結構體中 */
    cell.MCC = mcc;
    cell.MNC = mnc;
    cell.LAC = lac;
    cell.CID = cid;
 
    return cell;
}

如果獲得的位置信息爲null將拋出錯誤,不再繼續執行。最後將獲取的基站信息封裝爲結構體返回。

四、獲取經緯度

在這一步,我們需要採用HTTP調用google的API以獲取基站所在的經緯度。

Android作爲一款互聯網手機,聯網的功能必不可少。Android提供了多個接口供我們使用,這裏我們使用DefaultHttpClient

完整的方法代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
 * 獲取經緯度
 *
 * @throws Exception
 */
private SItude getItude(SCell cell) throws Exception {
    SItude itude = new SItude();
 
    /** 採用Android默認的HttpClient */
    HttpClient client = new DefaultHttpClient();
    /** 採用POST方法 */
    HttpPost post = new HttpPost("http://www.google.com/loc/json");
    try {
        /** 構造POST的JSON數據 */
        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);
 
        /** 發出POST數據並獲取返回數據 */
        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);
        }
 
        /** 解析返回的JSON數據獲得經緯度 */
        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("獲取經緯度出現錯誤:"+e.getMessage());
    } finally{
        post.abort();
        client = null;
    }
     
    return itude;
}

代筆中關鍵的地方都作了註釋,同學們還有不理解的舉手哈。

在這裏採用POST方法將JSON數據發送到googleAPI,google返回JSON數據,我們得到數據後解析,得到經緯度信息。

關於google 基站信息API的官方說明>>請到這裏查看

五、獲取物理位置

得到經緯度後,我們將之轉換爲物理地址。

我們仍然使用DefaultHttpClient來調用google地圖的API,獲得物理信息,不過在這裏我們使用GET方法。

完整的方法代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**
 * 獲取地理位置
 *
 * @throws Exception
 */
private String getLocation(SItude itude) throws Exception {
    String resultString = "";
 
    /** 這裏採用get方法,直接將參數加到URL上 */
    String urlString = String.format("http://maps.google.cn/maps/geo?key=abcdefg&q=%s,%s", itude.latitude, itude.longitude);
    Log.i("URL", urlString);
 
    /** 新建HttpClient */
    HttpClient client = new DefaultHttpClient();
    /** 採用GET方法 */
    HttpGet get = new HttpGet(urlString);
    try {
        /** 發起GET請求並獲得返回數據 */
        HttpResponse response = client.execute(get);
        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();
 
        /** 解析JSON數據,獲得物理地址 */
        if (resultString != null && resultString.length() > 0) {
            JSONObject jsonobject = new JSONObject(resultString);
            JSONArray jsonArray = new JSONArray(jsonobject.get("Placemark").toString());
            resultString = "";
            for (int i = 0; i < jsonArray.length(); i++) {
                resultString = jsonArray.getJSONObject(i).getString("address");
            }
        }
    } catch (Exception e) {
        throw new Exception("獲取物理位置出現錯誤:" + e.getMessage());
    } finally {
        get.abort();
        client = null;
    }
 
    return resultString;
}

GET方法就比POST方法簡單多了,得到的數據同樣爲JSON格式,解析一下得到物理地址。

六、顯示結果

好了,我們已經得到我們想要的信息了,我們把它顯示出來,方法代碼如下:

1
2
3
4
5
6
7
8
9
/** 顯示結果 */
private void showResult(SCell cell, String location) {
    TextView cellText = (TextView) findViewById(R.id.cellText);
    cellText.setText(String.format("基站信息: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("物理位置:" + location);
}

七、運行程序

我們的編碼工作已經完成了。在上面的代碼中有些地方需要的引入代碼沒有提到,下面把完整的代碼貼出來:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
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;
 
public class DemoActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        /** 爲按鈕綁定事件 */
        Button btnGetLocation = (Button) findViewById(R.id.button1);
        btnGetLocation.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                onBtnClick();
            }
        });
    }
     
    /** 基站信息結構體 */
    public class SCell{
        public int MCC;
        public int MNC;
        public int LAC;
        public int CID;
    }
     
    /** 經緯度信息結構體 */
    public class SItude{
        public String latitude;
        public String longitude;
    }
     
    /** 按鈕點擊回調函數 */
    private void onBtnClick() {
        /** 彈出一個等待狀態的框 */
        ProgressDialog mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setMessage("正在獲取中...");
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        mProgressDialog.show();
 
        try {
            /** 獲取基站數據 */
            SCell cell = getCellInfo();
 
            /** 根據基站數據獲取經緯度 */
            SItude itude = getItude(cell);
 
            /** 獲取地理位置 */
            String location = getLocation(itude);
 
            /** 顯示結果 */
            showResult(cell, location);
 
            /** 關閉對話框 */
            mProgressDialog.dismiss();
        } catch (Exception e) {
            /** 關閉對話框 */
            mProgressDialog.dismiss();
            /** 顯示錯誤 */
            TextView cellText = (TextView) findViewById(R.id.cellText);
            cellText.setText(e.getMessage());
            Log.e("Error", e.getMessage());
        }
    }
     
    /**
     * 獲取基站信息
     *
     * @throws Exception
     */
    private SCell getCellInfo() throws Exception {
        SCell cell = new SCell();
 
        /** 調用API獲取基站信息 */
        TelephonyManager mTelNet = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        GsmCellLocation location = (GsmCellLocation) mTelNet.getCellLocation();
        if (location == null)
            throw new Exception("獲取基站信息失敗");
 
        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();
 
        /** 將獲得的數據放到結構體中 */
        cell.MCC = mcc;
        cell.MNC = mnc;
        cell.LAC = lac;
        cell.CID = cid;
 
        return cell;
    }
     
    /**
     * 獲取經緯度
     *
     * @throws Exception
     */
    private SItude getItude(SCell cell) throws Exception {
        SItude itude = new SItude();
 
        /** 採用Android默認的HttpClient */
        HttpClient client = new DefaultHttpClient();
        /** 採用POST方法 */
        HttpPost post = new HttpPost("http://www.google.com/loc/json");
        try {
            /** 構造POST的JSON數據 */
            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);
 
            /** 發出POST數據並獲取返回數據 */
            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);
            }
 
            /** 解析返回的JSON數據獲得經緯度 */
            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("獲取經緯度出現錯誤:"+e.getMessage());
        } finally{
            post.abort();
            client = null;
        }
         
        return itude;
    }
     
    /**
     * 獲取地理位置
     *
     * @throws Exception
     */
    private String getLocation(SItude itude) throws Exception {
        String resultString = "";
 
        /** 這裏採用get方法,直接將參數加到URL上 */
        String urlString = String.format("http://maps.google.cn/maps/geo?key=abcdefg&q=%s,%s", itude.latitude, itude.longitude);
        Log.i("URL", urlString);
 
        /** 新建HttpClient */
        HttpClient client = new DefaultHttpClient();
        /** 採用GET方法 */
        HttpGet get = new HttpGet(urlString);
        try {
            /** 發起GET請求並獲得返回數據 */
            HttpResponse response = client.execute(get);
            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();
 
            /** 解析JSON數據,獲得物理地址 */
            if (resultString != null && resultString.length() > 0) {
                JSONObject jsonobject = new JSONObject(resultString);
                JSONArray jsonArray = new JSONArray(jsonobject.get("Placemark").toString());
                resultString = "";
                for (int i = 0; i < jsonArray.length(); i++) {
                    resultString = jsonArray.getJSONObject(i).getString("address");
                }
            }
        } catch (Exception e) {
            throw new Exception("獲取物理位置出現錯誤:" + e.getMessage());
        } finally {
            get.abort();
            client = null;
        }
 
        return resultString;
    }
     
    /** 顯示結果 */
    private void showResult(SCell cell, String location) {
        TextView cellText = (TextView) findViewById(R.id.cellText);
        cellText.setText(String.format("基站信息: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("物理位置:" + location);
    }
}

我們連上手機在手機上運行程序看看。

不出意外的話程序運行起來了,自動跳轉到了主界面。點擊“Click Me”,出錯了!

image

詳細的錯誤信息爲:Neither user 10078 nor current process has android.permission.ACCESS_COARSE_LOCATION.

原來是沒有權限,經過前面的學習,我們知道Android在應用的安全上下了一番功夫,要用一些特殊功能必須先報告,安裝應用的時候列給用戶看,必須要得到用戶的允許。這裏我們用了獲取基站信息的功能,涉及到用戶的隱私了,所以我們必須申明一下。

打開AndroidManifest.xml配置文件,在裏面添加相應的配置信息:

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

我們繼續把網絡連接的權限申明也加上:

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

再編譯運行看看(點擊“Click Me”後程序會卡住,等待一段時間纔有反應,取決於網絡情況):

豌豆莢截圖201202021637

成功啦!

可能有的同學還是出現錯誤,沒有成功:

█ 提示“www.google.com…”什麼的錯誤

請確認你的手機能訪問互聯網,調用google的API是必須聯網的。

█ 提示獲取不到基站信息

你確定你是在手機上測試的嗎?模擬器可不行哦。或者你的手機使用的CMDA網絡?這個例子只支持GSM網絡…

█ 獲取不到經緯度

很有可能你中獎了,你所在的基站還沒納入google的數據庫…(話說我之前也遇到過,怎麼查就是查不出經緯度來,返回數據爲空)

█ 獲取到的地理地址不正確

這個可能程序出錯了,可能google出錯了?

其實google map API返回的數據中還包含了很多其他信息,我們可以用來開發一些更有趣的功能,如製作我們專屬的地圖軟件、足跡記錄軟件等,充分發揮你的創造力:)

八、總結

這個程序基本實現了基站定位功能,但還有很多問題,如:點擊了按鈕後界面會卡住(訪問網絡時阻塞了進程)、未對異常進一步處理、不兼容CMDA網絡等。

另外這個程序的精度也不夠,獲得的位置實際上是基站的物理位置,與人所在的位置還有一定差距。在城市裏面,一般採用密集型的小功率基站,精度一般在幾百米範圍內,而在郊區常爲大功率基站,密度很小,精度一般在幾千米以上。

想要取得更高的精度需要通過一些其他的算法來實現,如果大家有興趣的話我們可以一起來研究一下,再專門寫篇筆記。

可見寫一段程序和做一個實際的產品是有很大差別的。

九、程序代碼

這一節完整程序的請點擊這裏下載

結尾

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章