Android开发:基站定位
目錄
- 單基站定位
- 多基站定位
?
單基站定位
?? 整個(gè)流程按照【Android開(kāi)發(fā)筆記】4.簡(jiǎn)單基站定位程序 學(xué)習(xí)
?
?? 遇到的問(wèn)題:
? ? 1. Google服務(wù)已無(wú)法使用
? ?? solution: 網(wǎng)頁(yè)查詢 http://www.cellid.cn/ ?? 開(kāi)放接口?http://www.cellocation.com/interfac/#cell (如何使用該接口獲取信息Java版
? ? 2. 當(dāng)遇到網(wǎng)頁(yè)請(qǐng)求時(shí),HttpResponse response = client.execute(get)無(wú)法執(zhí)行。后來(lái)發(fā)現(xiàn)與線程有關(guān),網(wǎng)絡(luò)請(qǐng)求會(huì)阻塞進(jìn)程
? ?? solution:Android 多線程:使用Thread和Handler
? ? 3. Handler處理Runnable發(fā)送的數(shù)據(jù)時(shí),無(wú)法更新UI
? ?? solution:cellText.setText(String.format("基站信息:mcc:%d, mnc:%d, lac:%d, cid:%d",?cell.MCC, cell.MNC, cell.LAC, cell.CID))不知道為什么引發(fā)了錯(cuò)誤,最后改成如下就可以了,怪不得搜不到資料
String cellInfo = "基站信息" + "MCC:" + cell.MCC + "MNC:" + cell.MNC + "LAC:" + cell.LAC + "CID:" + cell.CID; cellText.setText(cellInfo);? ? 4. APP異常閃退
? ?? solution : 問(wèn)題1在于錯(cuò)誤的把 cellText = findViewById(R.id.cellText) 直接寫(xiě)在類里面,而應(yīng)該是寫(xiě)在onCreate()里;問(wèn)題2在于Handler在switch (msg.what) {}部分需要放進(jìn)try catch里,原因就不知道了
? ? 5. 無(wú)法導(dǎo)入http相關(guān)包
? ?? solution:在該module的build.gradle里面,添加useLibrary 'org.apache.http.legacy'
?
? ? 其他
? ? android中幾種定位方式詳解
package com.example.basestationlocate;import androidx.appcompat.app.AppCompatActivity;import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Handler; 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.impl.client.DefaultHttpClient; import android.content.Context; 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; import android.widget.Toast; import android.os.Message;public class MainActivity extends AppCompatActivity {private static final int MSG_SUCCESS = 0;// 獲取成功的標(biāo)識(shí)private static final int MSG_FAILURE = 1;// 獲取失敗的標(biāo)識(shí)private Thread mThread;SCell cell = null;TextView cellText;TextView locationText;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);cellText = findViewById(R.id.cellText);locationText = findViewById(R.id.locationText);/** 為按鈕綁定事件 */Button btnGetLocation = findViewById(R.id.button1);btnGetLocation.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {if (mThread == null) {try {mThread = new Thread(runnable);mThread.start();} catch (Exception e) {Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();}} else {Toast.makeText(MainActivity.this, "已獲取基站定位", Toast.LENGTH_SHORT).show();}}});}/*** 基站信息結(jié)構(gòu)體*/public class SCell {public int MCC;public int MNC;public int LAC;public int CID;}/*** 經(jīng)緯度信息結(jié)構(gòu)體*/public class SItude {public String latitude = "none";public String longitude = "none";public String address = "none";public String radis = "none";}/*** 獲取基站信息** @throws Exception*/public SCell getCellInfo() {SCell cell = new SCell();/** 調(diào)用API獲取基站信息 */TelephonyManager mTelNet = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {Log.e("Error", "遇到權(quán)限問(wèn)題");}GsmCellLocation location = (GsmCellLocation) mTelNet.getCellLocation();if (location == null)Toast.makeText(MainActivity.this, "獲取基站信息失敗", Toast.LENGTH_SHORT).show();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();/** 將獲得的數(shù)據(jù)放到結(jié)構(gòu)體中 */cell.MCC = mcc;cell.MNC = mnc;cell.LAC = lac;cell.CID = cid;return cell;}/*** 獲取基站地理位置** @throws Exception*/public String getWebData(String domain) {String resultString = "";HttpClient client = new DefaultHttpClient();/** 采用GET方法 */HttpGet get = new HttpGet(domain);try {/** 發(fā)起GET請(qǐng)求并獲得返回?cái)?shù)據(jù) */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();} catch (Exception e) {//throw new Exception("獲取物理位置出現(xiàn)錯(cuò)誤:" + e.getMessage());e.printStackTrace();} finally {get.abort();client = null;}return resultString;}public SItude getLocation(String url){String resultString = "";SItude situde = new SItude();resultString = getWebData(url);/** 解析基站位置 */String errcode = "";String[] arr = resultString.split(",");errcode = arr[0];if (errcode.equals("0")) {situde.latitude = arr[1];situde.longitude = arr[2];situde.radis = arr[3];situde.address = arr[4].replace("\"", "");}return situde;}private Handler mHandler = new Handler() {@Override// 重寫(xiě)handleMessage()方法,此方法在UI線程運(yùn)行public void handleMessage(Message msg) {super.handleMessage(msg);try {switch (msg.what) {case MSG_SUCCESS:String cellInfo = "基站信息" + "\nMCC:" + cell.MCC + "\nMNC:" + cell.MNC + "\nLAC:" + cell.LAC + "\nCID:" + cell.CID;cellText.setText(cellInfo);SItude s = (SItude) msg.obj;String loc = "基站坐標(biāo)"+"\nlon:" + s.longitude + "\nlat:" + s.latitude + "\n地址:" + s.address;locationText.setText(loc);Toast.makeText(MainActivity.this, "解析基站位置成功", Toast.LENGTH_SHORT).show();break;case MSG_FAILURE:Toast.makeText(MainActivity.this, "網(wǎng)絡(luò)解析基站位置失敗", Toast.LENGTH_SHORT).show();break;}} catch (Exception e) {e.printStackTrace();}}};private Runnable runnable = new Runnable() {// 重寫(xiě)run()方法,此方法在新的線程中運(yùn)行@Overridepublic void run() {/** 獲取基站 */cell = getCellInfo();/** 查詢基站地理位置 */String url = "http://api.cellocation.com:81/cell/?mcc=" + cell.MCC + "&mnc=" + cell.MNC + "&lac=" + cell.LAC + "&ci=" + cell.CID + "&output=csv";SItude situde = new SItude();try {situde = getLocation(url);} catch (Exception e) {mHandler.obtainMessage(MSG_FAILURE).sendToTarget();e.printStackTrace();} finally {mHandler.obtainMessage(MSG_SUCCESS, situde).sendToTarget();}}};}?
多基站定位
? ? 原本根據(jù)該博主的內(nèi)容,使用以下代碼獲取周?chē)拘畔?/p> // 獲取鄰區(qū)基站信息List<NeighboringCellInfo> infos = mTelephonyManager.getNeighboringCellInfo();StringBuffer sb = new StringBuffer("總數(shù) : " + infos.size() + "\n");for (NeighboringCellInfo info1 : infos) { // 根據(jù)鄰區(qū)總數(shù)進(jìn)行循環(huán)sb.append(" LAC : " + info1.getLac()); // 取出當(dāng)前鄰區(qū)的LACsb.append(" CID : " + info1.getCid()); // 取出當(dāng)前鄰區(qū)的CIDsb.append(" BSSS : " + (-113 + 2 * info1.getRssi()) + "\n"); // 獲取鄰區(qū)基站信號(hào)強(qiáng)度}
? ? 但是?getNeighboringCellInfo()方法不知道為什么標(biāo)紅了,而且根據(jù)博主的說(shuō)法,getAllCellInfo()方法更好,所以改用該方法
? ? 在使用時(shí)發(fā)現(xiàn)了CellInfoCdma、CellInfoLte、CellInfoGsm等類型轉(zhuǎn)換失敗的錯(cuò)誤,結(jié)果發(fā)現(xiàn)手機(jī)改用不同的網(wǎng)絡(luò)類型會(huì)改變接收的基站類型(當(dāng)網(wǎng)絡(luò)類型選擇優(yōu)先4G網(wǎng)絡(luò)時(shí),只能接收CellInfoLte
? ? 本來(lái)想用4G實(shí)驗(yàn)的,但好像獲取不到lac,所以改用2G
? ? 基站信息查詢開(kāi)放接口也要改成http://api.cellocation.com:81/loc/?,注意子線程里不能修改UI
? ? 成功實(shí)現(xiàn)后也發(fā)現(xiàn)了一個(gè)問(wèn)題,2G的精度相比4G差得多,這與基站的建設(shè)有關(guān),畢竟現(xiàn)在應(yīng)該沒(méi)什么人用2G了...
? ? 發(fā)現(xiàn)Lac在CellInfoLte類里應(yīng)該是用Tac表示了,重新適配2 3 4G
public List<CellInfo> getCellInfo() {/** 調(diào)用API獲取基站信息 */TelephonyManager mTelNet = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {Log.e("Error", "遇到權(quán)限問(wèn)題");}// 獲取鄰區(qū)基站信息List<CellInfo> infoLists = mTelNet.getAllCellInfo();return infoLists;}private Runnable runnable = new Runnable() {// 重寫(xiě)run()方法,此方法在新的線程中運(yùn)行@Overridepublic void run() {/** 獲取基站 */List<CellInfo> cells = getCellInfo();String info = "";SItude situde = new SItude();try {for (CellInfo cellInfo : cells) {if (cellInfo instanceof CellInfoGsm) {CellInfoGsm cellInfoGsm = (CellInfoGsm) cellInfo;CellIdentityGsm cellIdentityGsm = cellInfoGsm.getCellIdentity();int cid = cellIdentityGsm.getCid();int mcc = cellIdentityGsm.getMcc();int mnc = cellIdentityGsm.getMnc();int lac = cellIdentityGsm.getLac();int bss = cellInfoGsm.getCellSignalStrength().getDbm();if(mcc == 460){String s = mcc + ","+ mnc + ","+ lac + ","+ cid + "," + bss + ";";info += s;}} else if (cellInfo instanceof CellInfoLte) {CellInfoLte cellInfoLte = (CellInfoLte) cellInfo;CellIdentityLte cellIdentityLte = cellInfoLte.getCellIdentity();int cid = cellIdentityLte.getCi();int mcc = cellIdentityLte.getMcc();int mnc = cellIdentityLte.getMnc();int bss = cellInfoLte.getCellSignalStrength().getDbm();int lac = cellIdentityLte.getTac();if(mcc == 460){String s = mcc + ","+ mnc + ","+ lac + ","+ cid + "," + bss + ";";info += s;}} else if (cellInfo instanceof CellInfoWcdma){CellInfoWcdma cellInfoWcdma = (CellInfoWcdma) cellInfo;CellIdentityWcdma cellIdentityWcdma = cellInfoWcdma.getCellIdentity();int cid = cellIdentityWcdma.getCid();int mcc = cellIdentityWcdma.getMcc();int mnc = cellIdentityWcdma.getMnc();int lac = cellIdentityWcdma.getLac();int bss = cellInfoWcdma.getCellSignalStrength().getDbm();if(mcc == 460){String s = mcc + ","+ mnc + ","+ lac + ","+ cid + "," + bss + ";";info += s;}}}info = info.substring(0,info.length()-1);String URL = "http://api.cellocation.com:81/loc/?cl="+ info + "&output=csv";situde = getLocation(URL);mHandler.obtainMessage(MSG_SUCCESS, situde).sendToTarget();} catch (Exception e) {errorText.setText(e.getMessage());mHandler.obtainMessage(MSG_FAILURE).sendToTarget();e.printStackTrace();}}}; }?
使用百度地圖Android SDK
? ? 申請(qǐng)密鑰、初始化地圖
? ? 查看我的密鑰
? ? 百度:Android 地圖SDK
?
? ? 只是想顯示個(gè)百度地圖,按照教程一步步做好了,結(jié)果APP打開(kāi)就閃退...
?
? ? 其他
? ? Android基站定位基本應(yīng)用
?
ArcGIS for Android : LocationDisplay
? ? ArcGIS for Android LocationDisplay自定義數(shù)據(jù)源
? ? LocationDisplay 自定義坐標(biāo)校正
? ? ArcGIS for Android 100.3.0(9):GPS定位
總結(jié)
以上是生活随笔為你收集整理的Android开发:基站定位的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 腾讯地图手把手教你实现微信小程序路线规划
- 下一篇: Android程序员简历