package com.jqyd.app; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.location.Location; import android.telephony.TelephonyManager; import android.telephony.cdma.CdmaCellLocation; import android.telephony.gsm.GsmCellLocation; import android.util.Log; import android.widget.Toast; import com.jqyd.app.GpsThread.IGPSLoc; import com.jqyd.model.LocationModule; import com.jqyd.pub.JqydDateUtil; import com.jqyd.shareInterface.Baidu_location; import com.jqyd.shareInterface.CheckState_interface; import com.jqyd.shareInterface.GpsService; import com.jqyd.shareInterface.Optsharepre_interface; import com.jqyd.shareInterface.SystemInfo; public class LocationUtils { Context context; private String log = "";// 记录日志 private ShareMethod shareMethod = null; private MyApp myApp; private Optsharepre_interface share_obj = null; ShareMethod share_loc = null; private static SharedPreferences loationSharedFile; private static final String SHARE_FILES = "LOCATION_FILES"; private TelephonyManager tm; private WriteFile wf; private static final String TAG = "LOCUTILS"; public LocationUtils(Context context) { super(); this.context = context; shareMethod = new ShareMethod(context); myApp = (MyApp) context.getApplicationContext(); share_obj = new Optsharepre_interface(context); share_loc = new ShareMethod(context); loationSharedFile = context.getSharedPreferences(SHARE_FILES, 0); wf = new WriteFile(context,TAG + JqydDateUtil.getDateDayOne(new Date())); tm = (TelephonyManager) context .getSystemService(Context.TELEPHONY_SERVICE); } public LocationModule takeCellInfos() { LocationModule loc = new LocationModule(); int cid = -1; int lac = -1; int type = tm.getNetworkType(); /** * 当前使用的网络类型: * 例如:NETWORK_TYPE_UNKNOWN 网络类型未知 0 NETWORK_TYPE_GPRS GPRS网络 1 NETWORK_TYPE_EDGE EDGE网络 2 NETWORK_TYPE_UMTS UMTS网络 3 NETWORK_TYPE_HSDPA HSDPA网络 8 NETWORK_TYPE_HSUPA HSUPA网络 9 NETWORK_TYPE_HSPA HSPA网络 10 NETWORK_TYPE_CDMA CDMA网络,IS95A 或 IS95B. 4 NETWORK_TYPE_EVDO_0 EVDO网络, revision 0. 5 NETWORK_TYPE_EVDO_A EVDO网络, revision A. 6 NETWORK_TYPE_1xRTT 1xRTT网络 7 */ // 在中国,联通的3G为UMTS或HSDPA,移动和联通的2G为GPRS或EGDE,电信的2G为CDMA,电信的3G为EVDO // G网 wf.writeToFile("当前网络类型:" + type); /** Network type is unknown NETWORK_TYPE_UNKNOWN = 0; Current network is GPRS NETWORK_TYPE_GPRS = 1; Current network is EDGE NETWORK_TYPE_EDGE = 2; Current network is UMTS NETWORK_TYPE_UMTS = 3; Current network is CDMA: Either IS95A or IS95B NETWORK_TYPE_CDMA = 4; Current network is EVDO revision 0 NETWORK_TYPE_EVDO_0 = 5; Current network is EVDO revision A NETWORK_TYPE_EVDO_A = 6; Current network is 1xRTT NETWORK_TYPE_1xRTT = 7; Current network is HSDPA NETWORK_TYPE_HSDPA = 8; Current network is HSUPA NETWORK_TYPE_HSUPA = 9; Current network is HSPA NETWORK_TYPE_HSPA = 10; Current network is iDen NETWORK_TYPE_IDEN = 11;综合数字增强网络(简称iDEN),是摩托罗拉发明的一种无线通信技术 Current network is EVDO revision B NETWORK_TYPE_EVDO_B = 12; Current network is LTE NETWORK_TYPE_LTE = 13; Current network is eHRPD NETWORK_TYPE_EHRPD = 14; Current network is HSPA+ TelephonyManager.NETWORK_TYPE_HSPAP = 15; */ // String a=android.os.Build.VERSION.RELEASE; //高版本系统兼容低版本软件,但低版本系统无法兼容只适用高版本的软件。 try { if (type == TelephonyManager.NETWORK_TYPE_UMTS || type == TelephonyManager.NETWORK_TYPE_HSDPA || type == TelephonyManager.NETWORK_TYPE_HSPAP//3.1版本以上才有 || type == TelephonyManager.NETWORK_TYPE_EDGE || type == TelephonyManager.NETWORK_TYPE_GPRS || type == TelephonyManager.NETWORK_TYPE_HSPA ||type==TelephonyManager.NETWORK_TYPE_LTE//3.0版本一上 || type == TelephonyManager.NETWORK_TYPE_HSUPA) { GsmCellLocation gcl = (GsmCellLocation) tm.getCellLocation(); try { cid = gcl.getCid();// 小区编号 lac = gcl.getLac();// 位置区域码 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); wf.writeToFile("G网获取小区编号或位置区域码出现错误!"); } Log.i(TAG, "------------G网cid--------------:" + cid); // 信号强度 // C网 } else if (type == TelephonyManager.NETWORK_TYPE_CDMA || type == TelephonyManager.NETWORK_TYPE_EVDO_0 || type == TelephonyManager.NETWORK_TYPE_EVDO_A ||type==TelephonyManager.NETWORK_TYPE_1xRTT ||type==TelephonyManager.NETWORK_TYPE_EHRPD //3.0版本一上 ||type==TelephonyManager.NETWORK_TYPE_EVDO_B //3.0版本一上 ) { // 参考地址:http://topic.csdn.net/u/20110110/23/c2f6524a-8746-4c1b-914e-57c7c9cced02.html CdmaCellLocation cdl = (CdmaCellLocation) tm.getCellLocation(); try { cid = cdl.getBaseStationId(); lac = cdl.getNetworkId(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); wf.writeToFile("C网获取小区编号或位置区域码出现错误!"); } // 信号强度 Log.i(TAG, "------------------C网cid-------------:" + cid); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); wf.writeToFile("------------读取小区编号时出现异常-------------"); } Log.i(TAG, "本机网络类型:" + type); wf.writeToFile("小区编号:" + cid+"位置区域码:"+lac); if(cid==lac){ cid=-1; } loc.setCell_id(cid + "");// 小区编号 loc.setLac(lac + "");// 位置区域码 String imsi = tm.getSubscriberId(); if(imsi==null||imsi.equals("")){ imsi="000000000000000"; } loc.setCcode(imsi.substring(0, 3));// 移动国家码 loc.setNcode(imsi.substring(3, 5));// 移动网络码 String operator = tm.getSimOperator(); if (operator != null&&!operator.equals("")) { if (operator.equals("46000") || operator.equals("46002")) { // 中国移动 operator = "3"; } else if (operator.equals("46001")) { // 中国联通 operator = "1"; } else if (operator.equals("46003")) { // 中国电信 operator = "2"; } } else { operator = "-1"; } loc.setYys(operator); return loc; } /** * * Description: 获取小区的位置信息 Title: getCellLocationData * * @param loc * 位置对象 * @param custId * 客户id int 0失败1成功 */ public int getCellLocationData(LocationModule loc, String custId) { int result = 0;// 默认失败 // 1、获取小区位置 int cellId = -1; int lac = 0; try { cellId = Integer.parseInt(loc.getCell_id()); lac = Integer.parseInt(loc.getLac()); } catch (NumberFormatException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } shareMethod.recordLog("当前网络基站编号:" + cellId + "客户编号:" + custId+"位置区域码:"+lac); String locInfo = share_loc.getCellInfo(cellId, custId, lac); if (!locInfo.equals("")) {// 小区位置获取成功 System.out .println("******************通过小区获取位置信息******************"); String longitude = locInfo.split("#")[1]; String latitude = locInfo.split("#")[2]; if (validateLonLat(longitude, latitude)) { try { loc.setLon(Double.valueOf(longitude).doubleValue()); loc.setLat(Double.valueOf(latitude).doubleValue()); loc.setRadius(locInfo.split("#")[4]); result = 1; } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); result = 0; } } } return result; } /** * * Description: 验证经纬度是否合法 Title: validateLonLat * * @param longitude * 经度 * @param latitude * 纬度 * @return boolean true数据没问题false数据为空 */ public boolean validateLonLat(String longitude, String latitude) { boolean b = true; if (longitude.equals("0") || latitude.equals("0") || longitude.equals("0.0") || latitude.equals("0.0") || "".equals(longitude) || "".equals(latitude) || longitude == null || latitude == null) { b = false; } return b; } /** * * Description: 获取百度的位置信息 Title: getBaiduLocationData * * @param loc * 位置对象 * @param baidu * 百度对象 * @return int 0失败 1成功 */ public int getBaiduLocationData(LocationModule loc, Baidu_location baidu) { int result = 0;// 默认失败 Log.d("location", "启动百度监听器,开始搜索位置……" + new SimpleDateFormat("yyyy-mm-dd HH:mm:ss") .format(new Date())); shareMethod.recordLog("启动百度监听器,开始搜索位置……"); if (baidu != null) { baidu.mLocationClient.start(); baidu.mLocationClient.requestLocation(); } String locInfo = ""; // 1、获取百度位置 for (int i = 0; i < 10; i++) { Log.d("location", "---------" + baidu); try { if (baidu != null && baidu.mLocationClient.isStarted()) { baidu.mLocationClient.requestLocation();// 定位 Log.d("location", "百度监听器已经注册并启动成功"); shareMethod.recordLog("百度监听器已经注册并启动成功"); locInfo = share_loc.getBaiduInfo(myApp, baidu); } } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); shareMethod.recordLog("请求百度获取位置出现异常"); } if (!locInfo.equals("")) {// 获取到位置跳出循环 Log.d("location", "获取到百度位置,跳出循环"); shareMethod.recordLog("获取到百度位置,跳出循环" + locInfo); break; } else {// 获取位置失败,休息1s中后继续判断 try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } if (!locInfo.equals("")) {// 百度获取位置成功 Log.d("location", "******************通过百度获取位置信息******************"); String longitude = locInfo.split("#")[1]; String latitude = locInfo.split("#")[2]; if (validateLonLat(longitude, latitude)) { try { loc.setLon(Double.valueOf(longitude).doubleValue()); loc.setLat(Double.valueOf(latitude).doubleValue()); loc.setRadius(locInfo.split("#")[4]); loc.setTime(0);// 百度返回的时间不准确,故采用服务器端时间 result = 1; } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); result = 0; } } } else { shareMethod.recordLog("百度定位,获取失败"); } return result; } /** * * Description: 获取GPS的位置信息 Title: getGPSLocationData * * @param loc * 位置对象 * @return int 0失败1成功-1GPS未打开 */ public int getGPSLocationData(LocationModule loc) { int result = -1;// -1:默认GPS没有开.1:成功。0:失败。2.获取位置错误。 String locInfo = ""; // 请求卫星 // 判断是否开启GPS int gps_flag = new CheckState_interface(context).checkGpState(); if (gps_flag == 0) {// GPS设备未打开 /* * Toast.makeText(context, "GPS模块不可用,请打开GPS功能!", Toast.LENGTH_LONG) * .show(); */ // 记录日志 log = "GPS模块未打开,获取位置失败!"; shareMethod.recordLog(log); return result; } else {// GPS设备已打开 shareMethod.recordLog("GPS设备已打开,启动GPS线程"); GpsThread gpsThread = new GpsThread(myApp, loationSharedFile); gpsThread.start(); // --------------------------------- for (int k = 0; k < 6; k++) { if (!locInfo.equals("") && !locInfo.equals("1")) { break; } else { try { Thread.sleep(10000);// 每次休眠10s,共60s } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } long gpsTimeTemp = 0; try { gpsTimeTemp = Long.parseLong(share_obj .getDataFromPres("gpsTimeTemp")); } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println("获取历史时间出现异常"); } int activeInt = loationSharedFile.getInt("active", -1); String lat = loationSharedFile.getString("lat", "-1"); String lon = loationSharedFile.getString("lon", "-1"); long time = loationSharedFile.getLong("time", 0); log = "《获取位置--卫星定位》*******************" + "当前时间:" + time + ",上次时间:" + gpsTimeTemp + ",获取位置信息:经度:" + lon + ",纬度:" + lat; shareMethod.recordLog("GPSlog:" + time + "," + lon + "," + lat + ",历史时间:" + gpsTimeTemp + " isActive:" + activeInt + "\n"); System.out.println(time + "," + lon + "," + lat + ",历史时间:" + gpsTimeTemp); if ((activeInt == 1) && (time != gpsTimeTemp)) {// 卫星获取成功,且当前卫星时间和上次卫星时间不相同 locInfo = "0#" + lon + "#" + lat + "#" + time; // 记录gps的时间变量参数 share_obj.editPres("gpsTimeTemp", String.valueOf(time)); } else { locInfo = "1";// 获取位置失败 } System.out.println("GPSlog:" + log); shareMethod.recordLog(log); } gpsThread.stopGspListener(); } if (!locInfo.equals("") && !locInfo.equals("1")) {// 卫星获取位置成功 System.out .println("******************通过卫星获取位置信息******************"); shareMethod.recordLog("get location from GPS " + locInfo); String longitude = locInfo.split("#")[1]; String latitude = locInfo.split("#")[2]; if (validateLonLat(longitude, latitude)) { try { loc.setLon(Double.valueOf(longitude).doubleValue()); loc.setLat(Double.valueOf(latitude).doubleValue()); loc.setTime(Long.parseLong(locInfo.split("#")[3])); loc.setRadius("0"); if(longitude.equals(latitude)){ result = 2;//获取经纬度错误 }else{ result = 1;// 获取成功 } } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); result = 0; } } } else { result = 0;// 获取失败 } return result; } public boolean getLocation(LocationModule loc, String tag, String cusId, Baidu_location baidu) { int dwMode = new Integer(share_obj.getDataFromPres("DWMODE")); if (tag.equals("onlyGps")) { dwMode = 2; } // if(tag.equals("baidu")){ // dwMode = 1; // } shareMethod.recordLog("getLocation dwMode:" + dwMode + "; tag:" + tag+";IMEI:"+tm.getDeviceId()); int dw_type = -1;// 0小区1卫星3百度-1定位失败 long serverTime = share_loc.getServerTime(); switch (dwMode) { case 1: // 网络优先 shareMethod.recordLog("网络优先定位模式"); int getLoc = 0; getLoc = getCellLocationData(loc, cusId); if (getLoc == 1) { loc.setDw_type(0); loc.setState(4);// 小区定位成功 loc.setTime(serverTime); return true; } else { getLoc = getBaiduLocationData(loc, baidu); if (getLoc == 1) { loc.setDw_type(3); loc.setState(2);// 百度定位成功 loc.setTime(serverTime); return true; } else { getLoc = getGPSLocationData(loc); if (getLoc == 1) { loc.setDw_type(1); loc.setState(1);// GPS定位成功 loc.setTime(serverTime); return true; } else { int state = checkState("gps"); loc.setDw_type(-1); loc.setState(state);// 0:GPS获取失败;-1:GPS未开启 loc.setTime(serverTime); return false; } } } case 2: // 仅用GPS shareMethod.recordLog("仅用GPS定位模式"); int hasGPSLoc = getGPSLocationData(loc); if (hasGPSLoc == 1) { loc.setDw_type(1); loc.setState(1);// GPS定位成功 loc.setTime(serverTime); return true; } else { loc.setDw_type(-1); loc.setState(hasGPSLoc);// 0:GPS获取失败;-1:GPS未开启。2:位置错误 loc.setTime(serverTime); return false; } case 3: // GPS优先 shareMethod.recordLog("GPS优先定位模式"); int hasLoc = 0; hasLoc = getGPSLocationData(loc); if (hasLoc == 1) { loc.setDw_type(1); loc.setState(1);// GPS定位成功 loc.setTime(serverTime); return true; } else { hasLoc = getCellLocationData(loc, cusId); if (hasLoc == 1) { loc.setDw_type(0); loc.setState(4);// 小区定位成功 loc.setTime(serverTime); return true; } else { hasLoc = getBaiduLocationData(loc, baidu); if (hasLoc == 1) { loc.setDw_type(3); loc.setState(2);// 百度定位成功 loc.setTime(serverTime); return true; } else { int state = checkState("baidu"); loc.setDw_type(-2);// 百度定位失败 loc.setState(state); loc.setTime(serverTime); return false; } } } default: return false; } } //判断定位是否存在误差 public boolean isError(LocationModule nowlocation,LocationModule lastlocation){ Double distance = GetDistance.getDistance(nowlocation.getLon(), nowlocation.getLat(), lastlocation.getLon(), lastlocation.getLat())/1000; //Double distance = GetDistance.getDistance(116.25254,40.205414,116.97326,39.15473)/1000; Double time = (double) ((nowlocation.getTime()-lastlocation.getTime())/(60*1000))+1.0; Double limit = time/60*350; Log.e("hasError",distance+","+time+","+limit+","); if(distance>limit){ return true; }else{ return false; } } private int checkState(String s){ int i = 0; String fail="0"; if(s.equals("gps")){ fail = "1"; }else{ fail = "0"; } CheckState_interface check = new CheckState_interface(context); int wifiAndGPRS = check.checkWifiAndGPRS(); int gpState = check.checkGpState(); switch (wifiAndGPRS) { case 1: if(1+gpState==2){ i=11;//wifi,gprs正常,gps打开 }else{ i=12;//gps关闭, } break; case 2: if(2+gpState==3){ i=13;//gps打开,wifi没联网,gprs正常联网 }else{ i=14;//gps关闭,wifi没联网,gprs正常联网 } break; case 3: if(3+gpState==4){ i=15;//gps打开,wifi正常,gprs没联网 }else{ i=16;//gps关闭,wifi正常,gprs没联网 } break; case 4: if(4+gpState==5){ i=17;//gps打开,wifi,gprs都没联网 }else{ i=18;// gps关闭,wifi,gprs都没联网 } break; default: break; } i = Integer.parseInt(i+fail); return i; } /** * * Description: TODO Title: getLocation * * @param loc * 位置对象 * @param tag * 标记 * @param custId * 客户Id * @param baidu * 定位对象 * @return boolean true位置获取成功false位置获取失败 */ public boolean getLocation11(LocationModule loc, String tag, String custId, Baidu_location baidu) { Log.d("location", baidu + ""); int result = 0; boolean b = false;// 默认没有获取到位置 String dwMode = share_obj.getDataFromPres("DWMODE"); // 获取服务器端时间 long serverTime = share_loc.getServerTime(); int dw_type = -1;// 0小区1卫星3百度-1定位失败 if (tag.equals("onlyGps")) { // 仅仅需要GPS获取位置 int res = this.getGPSLocationData(loc); switch (res) { case -1: // gps未开 result = -1; break; case 0: result = 0;// gps获取失败 break; case 1: result = 1;// gps获取成功 // 卫星位置获取成功 dw_type = 1; b = true; break; } } else { Log.d("location", dwMode); // GPS优先获取位置 if (dwMode.equals("3")) { int res = this.getGPSLocationData(loc); switch (res) { case -1: // gps未开 result = -1; break; case 0: result = 0;// gps获取失败 break; case 1: result = 1;// gps获取成功 // 卫星位置获取成功 dw_type = 1; b = true; break; } } // 网络优先,百度获取位置 或者(GPS优先,但是gps获取失败) if ((dwMode.equals("1") || result != 1) && !dwMode.equals("2")) { int k = this.getCellLocationData(loc, custId); Log.d("location", k + ""); if (k == 0) {// 小区获取失败 int res = this.getBaiduLocationData(loc, baidu); if (res == 1) { result = 2;// 百度获取位置成功 dw_type = 3; b = true; } else { result = 3;// 百度获取失败 } } else { dw_type = 0;// 小区获取位置成功 b = true; result = 4; } } Log.d("location", result + ""); // 仅仅GPS获取位置或者百度位置获取失败(排除GPS优先多次获取GPS位置的情况 if ((dwMode.equals("2") || result == 3) && !dwMode.equals("3")) { int res = this.getGPSLocationData(loc); Log.d("location", res + ""); switch (res) { case -1: // gps未开 result = -1; break; case 0: result = 0;// gps获取失败 break; case 1: result = 1;// gps获取成功 // 卫星位置获取成功 dw_type = 1; b = true; break; } } } Log.d("location", dw_type + ":" + result + ":" + serverTime + ""); loc.setDw_type(dw_type); loc.setState(result); loc.setTime(serverTime); return b; } }