-package com.enqualcomm.support;\r
-\r
-import android.content.BroadcastReceiver;\r
-import android.content.Context;\r
-import android.content.IClipboard;\r
-import android.content.Intent;\r
-import android.content.IntentFilter;\r
-import android.os.Handler;\r
-import android.os.Message;\r
-import android.os.PowerManager;\r
-import android.os.SystemClock;\r
-\r
-import com.enqualcomm.support.adapter.BTHelper;\r
-import com.enqualcomm.support.utils.AlarmHelper;\r
-import com.enqualcomm.support.adapter.LBSHelper;\r
-import com.enqualcomm.support.utils.Connection;\r
-import com.enqualcomm.support.utils.IBeaconUtil;\r
-import com.enqualcomm.support.utils.Util;\r
-import com.ic.protocols.protocolAPIHelper;\r
-import com.enqualcomm.support.bean.ICLocation;\r
-import com.enqualcomm.support.bean.StringMessage;\r
-import com.enqualcomm.support.service.Deliver;\r
-import com.enqualcomm.support.utils.CellInfoUtil;\r
-import com.enqualcomm.support.utils.DeviceInfoUtil;\r
-import com.enqualcomm.support.utils.ICLogger;\r
-import com.enqualcomm.support.utils.NettyConnection;\r
-import com.enqualcomm.support.utils.SimSignalUtil;\r
-import com.enqualcomm.support.bean.Runtime;\r
-import com.enqualcomm.support.utils.TimeUtil;\r
-\r
-import java.util.ArrayList;\r
-import java.util.concurrent.ExecutorService;\r
-import java.util.concurrent.Executors;\r
-\r
-import rx.Single;\r
-import rx.android.schedulers.AndroidSchedulers;\r
-import rx.functions.Action1;\r
-\r
-import static com.enqualcomm.support.Config.GPSLocationTimeoutInSeconds;\r
-import static com.enqualcomm.support.Config.WiFiLocationTimeoutInSeconds;\r
-import static com.enqualcomm.support.Constants.ACTION_CHECK_LOCATION_RESULT;\r
-\r
-/***\r
- * 周期定位:按周期进行,如果正在定位,则skip此次定位。\r
- * 强制定位:随机根据指令执行,如果正在定位,强制停止当前定位,立即执行新的定位。\r
- * 1、模式1 WiFi+LBS定位、15分钟一次,WiFi扫描3次如果都没有结果,20秒内返回LBS定位\r
- * 2、模式2 WiFi+LBS模式,1小时1一次,WiFi扫描3次如果都没有结果,20秒内返回LBS定位\r
- * 3、模式3 GPS定位模式,1分钟一次定位,GPS常开,超时返回WiFi定位。GPS 15秒内信号很差的话会提前关闭,返回wifi+LBS定位。\r
- * 4、模式4 GPS定位模式,1分钟定位一次,GPS常开,超时返回WiFi定位,GPS 15秒内信号很差的话会提前关闭,返回wifi+LBS定位。5分钟后自动工作在模式1上。\r
- * 5、模式5、8 GPS定位模式,客户自定义定位时间, 1分钟以内含1分钟,GPS常开,超时返回WiFi+LBS定位,1分钟以上的,GPS超2分钟时会关闭,GPS 15秒内信号很差的话也会提前关闭,返回wifi+LBS定位。\r
- * 6、模式9 WiFi模式,客户自定义定位时间,WiFi扫描3次如果都没有结果,20秒内返回LBS定位\r
- * 7、即时定位返回当前模式的定位方式,会强制进行定位。\r
- * 8、每次切换定位模式,会执行一次强制定位。\r
- */\r
-public class LocationClient {\r
- private static final String TAG = LocationClient.class.getSimpleName();\r
- private static final long CHANGENETMODETIME = 43200000L;\r
- private static long startCheckTime=0L;\r
- private static final int CLOSE_AIRMODE = 0;\r
- \r
- private static final int IS_GPS = 0;\r
- \r
- private static final int IS_LBS = 2;\r
- \r
- private static final int IS_WIFI = 1;\r
- \r
- public static final String LOCATION_CYCLE = "location_cycle";\r
- \r
- public static final String LOCATION_MODE = "location_mode";\r
-\r
- private static final int MAX_SIZE = 50;\r
- \r
- private static final int OPEN_AIRMODE = 1;\r
- \r
- private static final int TIME_OUT = 30000;\r
-\r
- private static Connection connection;\r
-\r
- private static boolean isLocationCallBack = false;\r
-\r
- private static boolean linkOK = false;\r
- \r
-\r
- \r
- private static boolean mHasWifiResult = true;\r
-\r
-\r
- private static Runtime runtime;\r
- \r
-// private int H12StepCount;\r
- \r
- private boolean batteryLowNotification;\r
- \r
- private boolean batteryNotification;\r
- \r
- private String cdmaInfo;\r
- \r
- private ExecutorService executor = Executors.newCachedThreadPool();\r
- \r
- private GSensorListener gSensorListener;\r
- \r
- private boolean haveChanegTo4G;\r
- \r
- private long haveChanegTo4GTime;\r
- \r
- private String mCellInfo;\r
-\r
-\r
- private LBSHelper mLbsHelper;\r
- private static BTHelper btHelper=null;\r
-\r
- private int mPedometer2;\r
- \r
- private SimSignalUtil mSignalUtil;\r
-\r
- private NMEAListener nmeaListener;\r
-\r
- private boolean startSOSLocation=false;\r
- private boolean startNomalLocation=false;\r
-\r
- private int preLbsCid;\r
- \r
- int preNetworkTypeNomber;\r
- private boolean scanBLEOnly=false;\r
-\r
- //如果未扫到,重试扫描的次数。\r
- private int maxBLEScanTime=0;\r
- private int ScanBLERetryCount=maxBLEScanTime;\r
- private int OneBLEScanTimeOUT=15;\r
-\r
- private static LocationClient gLocationCline=null;\r
-// private BroadcastReceiver screenOnReceiver = new BroadcastReceiver() {\r
-// public void onReceive(Context param1Context, Intent param1Intent) {\r
-// if ("android.intent.action.SCREEN_ON".equals(param1Intent.getAction())) {\r
-// mSignalUtil.setAirMode("CloseAirplane");\r
-// }\r
-// }\r
-// };\r
- public static LocationClient getInstance(){\r
- return gLocationCline;\r
- }\r
- public LocationClient(Connection paramNettyConnection, Runtime paramRuntime) {\r
- connection = paramNettyConnection;\r
- runtime = paramRuntime;\r
- btHelper = BTHelper.CreateInstance(paramRuntime, new BTHelper.BTScanCallback() {\r
- @Override\r
- public void OnScanFinished(ArrayList<IBeaconUtil.iBeacon> btBeaconScanResult, ArrayList<String> btNewScanResult) {\r
- if (Config.BLEScanProtocol == 0) { //扫描并判定是否在区域内。\r
- if (btNewScanResult != null && btNewScanResult.size() > 0) {\r
- StringBuilder sb = new StringBuilder();\r
- sb.append("found bt mac ").append(btNewScanResult.size());\r
- sb.append(" bounding BeaconMacList ").append(runtime.bleInfo.btMacList.size());\r
- runtime.bleInfo.btScanResult.clear();\r
- for (String mac : runtime.bleInfo.btMacList) {\r
- sb.append(" ").append(mac);\r
- }\r
- ICLogger.i(sb.toString());\r
-\r
-\r
- boolean in_area = false;\r
- try {\r
- for (String mac : btNewScanResult) {\r
- ICLogger.i("bt mac " + mac.replace(":", "").toLowerCase() + " " + mac.toLowerCase());\r
- String tmp = mac.replace(":", "").toLowerCase();\r
- tmp = tmp.substring(0, tmp.indexOf(","));\r
- if (runtime.bleInfo.btMacList.contains(tmp)) {\r
- in_area = true;\r
- break;\r
- }\r
- }\r
- if (in_area == false && ScanBLERetryCount-- > 0) {\r
- //如果没有扫描到,且扫描次数没有超限,则重新扫描一次。注意要delay 5秒\r
- Util.mSleep(5000);\r
- //Do retry Scan\r
- ICLogger.i("BT BLE not found retry Scan " + ScanBLERetryCount);\r
- btHelper.scanBLE();\r
- return;\r
- } else {\r
- runtime.bleInfo.is_in_area = in_area;\r
- ScanBLERetryCount = maxBLEScanTime;\r
- }\r
-\r
- } catch (Exception e) {//如果出错,原来的状态不要变。防止误报,最多延迟一个周期报。\r
- e.printStackTrace();\r
- ICLogger.i(e.getMessage());\r
- }\r
-\r
-\r
- } else {\r
- runtime.bleInfo.is_in_area = false;\r
- ScanBLERetryCount = maxBLEScanTime;\r
- }\r
- ICLogger.i("Bt Dev Is in Area " + runtime.bleInfo.is_in_area);\r
-\r
- if (scanBLEOnly == true) {\r
- //只扫描蓝牙,不做定位\r
- if (runtime.bleInfo.is_in_area == false) {\r
- runtime.updateFZDDevStatusEscape(true);\r
- ICLogger.i("BT 不在区域内");\r
- if (runtime.bleInfo.last_is_in_area == true) {\r
- //只有上一次在区域内,这次出区域才需要报警\r
- ICLogger.i("BT 不在区域内,且上次在区域内,报警!");\r
- //如果需要报警定位,则强制进行sos定位,不能通过triggerSOS,因为函数中调用了BLEScan会造成循环调用\r
- StringMessage AL_CMD = protocolAPIHelper.getWarningMSG(runtime);\r
- DeliverMessage(AL_CMD);\r
- }\r
- } else {\r
- ICLogger.i("BT 在区域内!");\r
- runtime.updateFZDDevStatusEscape(false);\r
- if (runtime.bleInfo.last_is_in_area == false) {\r
- //上一次不在区域内,这次进区域要报警\r
- ICLogger.i("BT 进入区域内,且上次不在区域内,报警!");\r
- if(!Config.noBLE_RelaseEscapeAlarm) {\r
- //如果需要报警定位,则强制进行sos定位,不能通过triggerSOS,因为函数中调用了BLEScan会造成循环调用\r
- StringMessage AL_CMD = protocolAPIHelper.getWarningMSG(runtime);\r
- DeliverMessage(AL_CMD);\r
- }\r
- }\r
- }\r
- } else {\r
- //定位前的蓝牙扫描\r
- if (runtime.bleInfo.is_in_area == false) {\r
- ICLogger.i("BT 不在区域内,开启定位流程");\r
- runtime.updateFZDDevStatusEscape(true);\r
- if (runtime.bleInfo.last_is_in_area == true) {\r
- //只有上一次在区域内,这次出区域才需要报警\r
- ICLogger.i("BT 不在区域内,且上次在区域内,报警!");\r
-\r
- StringMessage AL_CMD = protocolAPIHelper.getWarningMSG(runtime);\r
- DeliverMessage(AL_CMD);\r
- runtime.setAlarmType(Runtime.AlarmType.ALARM_REMOVE_SOS);\r
- startSOSLocation = false; //如果已经报警,后面就不用再报了\r
- }\r
-\r
- if (startSOSLocation) {\r
- StringMessage AL_CMD = protocolAPIHelper.getWarningMSG(runtime);\r
- DeliverMessage(AL_CMD);\r
- runtime.setAlarmType(Runtime.AlarmType.ALARM_REMOVE_SOS);\r
- startSOSLocation = false;\r
- }\r
- if (startNomalLocation) {\r
- startLocationProcess(runtime.getLocationInstance().getWorkingMod());\r
- }\r
-\r
- } else {\r
- ICLogger.i("BT 在区域内,直接发送区域坐标即可!");\r
- runtime.updateFZDDevStatusEscape(false);\r
- if (runtime.bleInfo.last_is_in_area == false) {\r
- //上一次不在区域内,这次进区域要报警\r
- ICLogger.i("BT 进入区域内,且上次不在区域内,报警!");\r
-\r
- if(!Config.noBLE_RelaseEscapeAlarm) {\r
- //如果需要报警定位,则强制进行sos定位,不能通过triggerSOS,因为函数中调用了BLEScan会造成循环调用\r
- StringMessage AL_CMD = protocolAPIHelper.getWarningMSG(runtime);\r
- DeliverMessage(AL_CMD);\r
- runtime.setAlarmType(Runtime.AlarmType.ALARM_REMOVE_SOS);\r
- startSOSLocation = false;//如果已经报警,后面就不用再报了\r
- }\r
- }\r
-\r
- if (startSOSLocation) {\r
- StringMessage AP01_CMD = protocolAPIHelper.getWarningMSG(runtime);\r
- DeliverMessage(AP01_CMD);\r
- runtime.setAlarmType(Runtime.AlarmType.ALARM_REMOVE_SOS);\r
- startSOSLocation = false;\r
- }\r
- if (startNomalLocation) {\r
- //已经通过蓝牙定位,则清除 forceLocation=0\r
- forceLocation = 0;\r
- startNomalLocation = false; //蓝牙定位,直接发GPS坐标\r
- StringMessage AP01_CMD = protocolAPIHelper.getGPSLocationMSG(runtime);\r
- DeliverMessage(AP01_CMD);\r
- }\r
- }\r
- }\r
-\r
- //处理过此次数据后,把当前状态赋值给上次检测状态\r
- runtime.bleInfo.last_is_in_area = runtime.bleInfo.is_in_area;\r
- //扫描结束就清掉scanBLEOnly,保证下次不会被误操作。\r
- scanBLEOnly = false;\r
- } else {\r
- //Config.BLEScanProtocol == 1\r
- if (btBeaconScanResult != null && btBeaconScanResult.size() > 0) {\r
- StringBuilder sb = new StringBuilder();\r
- sb.append("found bt mac ").append(btBeaconScanResult.size());\r
- runtime.bleInfo.btScanResult.clear();\r
- for (IBeaconUtil.iBeacon beacon : btBeaconScanResult) {\r
- sb.append("\n").append(beacon.toString());\r
- if(runtime.bleInfo.btMajorList.contains(beacon.major)) {\r
- runtime.bleInfo.btScanResult.add(beacon.toString());\r
- sb.append("in list!");\r
- }else{\r
- sb.append("not in!");\r
- }\r
- }\r
- ICLogger.i(sb.toString());\r
- Deliver.sendLocationMSG(protocolAPIHelper.getBLEScanResult(runtime));\r
- } else {\r
- ICLogger.i("未搜到蓝牙设备!");\r
- }\r
- }\r
- }\r
- });\r
-\r
- btHelper.setBLEScanTimeout(OneBLEScanTimeOUT);\r
- gLocationCline = this;\r
- //GPS 监听管理初始化\r
- this.nmeaListener = new NMEAListener(paramRuntime.getContextProxy().getLocationManager(), paramRuntime);\r
- // 初始化同时开启计步(硬件计步器,比较省电,全程开启计步功能)\r
- this.gSensorListener = new GSensorListener(paramRuntime);\r
- }\r
-\r
- private LocationResponseUrl responseUrl=null;\r
- public void setLocationResponse(LocationResponseUrl lru){\r
- responseUrl=lru;\r
- }\r
- public interface LocationResponseUrl{\r
- abstract public void replyCallBack(String locationResponseUrl);\r
- };\r
-\r
- private void handler2GTo4G() {\r
- int networktype = this.mSignalUtil.getNetworkType();\r
- int singal = runtime.getSignalStrength();\r
- long currenttime = SystemClock.elapsedRealtime();\r
- StringBuilder stringBuilder = new StringBuilder();\r
- stringBuilder.append("networkType=");\r
- stringBuilder.append(networktype);\r
- stringBuilder.append("signalStrength=");\r
- stringBuilder.append(singal);\r
- stringBuilder.append("haveChanegTo4G=");\r
- stringBuilder.append(this.haveChanegTo4G);\r
- ICLogger.i(stringBuilder.toString());\r
- switch (networktype) {\r
- default:\r
- return;\r
- case SimSignalUtil.IS_4G:\r
- if (singal < -93) {\r
- this.mSignalUtil.changeNetWorkType("2G");\r
- this.haveChanegTo4GTime = currenttime;\r
- return;\r
- }\r
- return;\r
- case SimSignalUtil.IS_2G:\r
- case SimSignalUtil.IS_3G:\r
- break;\r
- }\r
- if (this.haveChanegTo4G || currenttime - this.haveChanegTo4GTime > 43200000L) {\r
- this.mSignalUtil.changeNetWorkType("4G");\r
- this.haveChanegTo4G = false;\r
- this.haveChanegTo4GTime = currenttime;\r
- }\r
- }\r
- //计算运动并发送数据\r
- public void updateStepCount() {\r
- this.gSensorListener.updateStepCount();\r
-\r
-// this.H12StepCount = DeviceInfoUtil.getStepCount((runtime.getContextProxy()).context);\r
-// if (i != 0 && Math.abs(this.H12StepCount - this.mPedometer2) > 1000) {\r
-//// connection.send(API.H12(runtime, this.H12StepCount));\r
-// ICLogger.i("StepCount 运动开始后 变化超过1000 ,则发送给服务器!");\r
-// }\r
-\r
- }\r
-\r
- private void performAlarm(PowerManager.WakeLock paramWakeLock) {\r
-// if (!runtime.isAirMode) {\r
- updateStepCount();//update StepCount\r
- // CellInfoUtil.triggerUpdateCellinfo(); //这个在locationClinet中也会执行更新\r
-// sendBatteryNotification();\r
-// }\r
- }\r
- public void triggerLocationProcess(){\r
- mhandler.sendEmptyMessage(msgWhat_StartLocationProcess);\r
- }\r
-\r
- public void triggerBLEProcess(){\r
- mhandler.sendEmptyMessage(msgWhat_StartBLEProcess);\r
- }\r
-\r
- public void triggerSOSLocationProcess(){\r
-\r
- mhandler.sendEmptyMessage(msgWhat_StartSOSLocationProcess);\r
-\r
- }\r
-\r
- private static int checktimes=0;\r
- private static boolean timeout=false;\r
- private static boolean isLocating=false;\r
- private static boolean isWifiScanning=false;\r
- LBSHelper.OnWiFiInfoListener wifiinfoListener=new LBSHelper.OnWiFiInfoListener() {\r
- public void getWifiInfoCallBack(String param1String) {\r
- ICLogger.i("get wifi scan Callback " + param1String);\r
- LocationClient.mHasWifiResult=true;\r
- runtime.setWifiinfo(param1String==null?"":param1String);\r
- isWifiScanning=false;\r
- }\r
- };\r
- public void startWifiScan(){\r
-\r
- if (isWifiScanning==false) {\r
- ICLogger.i("开启wifi扫描");\r
- isWifiScanning=true;\r
- runtime.setWifiinfo("");\r
- mHasWifiResult = false;\r
- this.mLbsHelper.setOnWiFiInfoListener(wifiinfoListener);\r
- this.mLbsHelper.getWifiInfo();\r
- }else{\r
- ICLogger.i("wifi扫描进行中,skip开启");\r
- }\r
- }\r
- public void startGpsLocate() {\r
-\r
- boolean FactryModeOpening=DeviceInfoUtil.isFactoryTestTopActivity(runtime.getContextProxy().context);\r
- boolean needReOpenGPS=runtime.getFactoryTestingStat();\r
-\r
- //防止与工厂测试冲突\r
- if (FactryModeOpening==false || needReOpenGPS==true) {\r
-\r
- if (needReOpenGPS==true) {\r
- ICLogger.i("工厂模式关闭了GPS,需要重新关闭GPS以同步状态!");\r
- //处理过后,要把状态设置为初始状态,防止每次都重启。\r
- runtime.setFactoryTestingStat(false);\r
- //如果发现需要重启GPS,为了状态正确,需要先停止GPS\r
- nmeaListener.stopListen();\r
- }\r
- ICLogger.i("开启GPS扫描!");\r
- if(Config.LOG_TOFILE) ICLogger.logToFile("GPS","开启GPS扫描!");\r
- if (!nmeaListener.isListening()) {\r
- runtime.getLocationInstance().setLocationStat(ICLocation.LOCATION_STAT.LOCATION_OPEN); //此处为了检测是否定位时可以正确识别状态,以防一直处于GPS定位成功状态\r
-// Single.just(null).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Object>() {\r
-// public void call(Object param1Object) {\r
-// nmeaListener.startListen();\r
-// }\r
-// });\r
- nmeaListener.startListen();\r
-\r
- } else {\r
- ICLogger.i("GPS is still listening, skip open it!");\r
- runtime.getLocationInstance().setLocationStat(ICLocation.LOCATION_STAT.LOCATION_OPEN); //此处为了检测是否定位时可以正确识别状态,以防一直处于GPS定位成功状态\r
- if (Config.LOG_TOFILE) ICLogger.logToFile("GPS", "GPS is still listening, skip open it!");\r
- }\r
- }else{\r
- ICLogger.i("工厂模式,skip 开启GPS扫描!");\r
- runtime.getLocationInstance().setLocationStat(ICLocation.LOCATION_STAT.LOCATION_OPEN); //此处为了检测是否定位时可以正确识别状态,以防一直处于GPS定位成功状态\r
- if(Config.LOG_TOFILE) ICLogger.logToFile("GPS","工厂模式,skip 开启GPS扫描!");\r
- }\r
- }\r
-\r
- public void clearGPSlocateStat(){\r
- ICLogger.i("clearGPSlocateStat");\r
- stopGpsLocate();\r
- runtime.getLocationInstance().setLocationStat( ICLocation.LOCATION_STAT.LOCATION_CLOSED);//此处为了检测是否定位时可以正确识别状态,以防一直处于GPS定位成功状态\r
- }\r
-\r
- public void startCheckResult(){\r
- checktimes=0;\r
- timeout=false;\r
- startCheckTime= System.currentTimeMillis();\r
- needCheckAgain=true;\r
- ICLogger.i("startCheckResult " );\r
-\r
- AlarmHelper.setRealTimeAlarmInSeconds(runtime.getContextProxy().context,1,ACTION_CHECK_LOCATION_RESULT);\r
-\r
- }\r
-\r
-\r
-\r
- private final static int msgWhat_WaitAndSendLocation=100;\r
- private final static int msgWhat_StartLocationProcess=0;\r
- private final static int msgWhat_StartBLEProcess=1;\r
- private final static int msgWhat_StartSOSLocationProcess=2;\r
- Handler mhandler=new Handler(){\r
-\r
- public void handleMessage(Message msg) {\r
- super.handleMessage(msg);\r
- if (msg.what == msgWhat_WaitAndSendLocation){\r
- Single.just(null).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Object>() {\r
- public void call(Object param1Object) { waitAndSendLocation(); }\r
- });\r
- }else if (msg.what == msgWhat_StartLocationProcess) {\r
- startNomalLocation=true;\r
- if (Config.BLEScanProtocol == 0 && runtime.bleInfo.btMacList.size() > 0) {\r
- if(scanBLEOnly && btHelper.isBtscanning()){\r
- //如果正在进行独立蓝牙扫描,则强制切换为正常扫描。\r
- scanBLEOnly=false;\r
- }else {\r
- //有蓝牙搜索要求则 先进行蓝牙扫描\r
- if (needLocation()) {\r
- btHelper.scanBLE();\r
- }\r
- }\r
- } else {\r
- //没有蓝牙搜索要求,就正常定位\r
- startLocationProcess(runtime.getLocationInstance().getWorkingMod());\r
- }\r
- }else if (msg.what == msgWhat_StartBLEProcess){\r
- if(Config.BLEScanProtocol==0) {\r
- if (runtime.bleInfo.btMacList.size() > 0) {\r
- //有蓝牙搜索要求则 先进行蓝牙扫描\r
- if (!btHelper.isBtscanning()) {\r
- scanBLEOnly = true;\r
- if (needLocationForBT()) {\r
- ICLogger.i("msgWhat_StartBLEProcess");\r
- btHelper.scanBLE();\r
- }\r
- } else {\r
- ICLogger.i("BT Scanning skip ScanBLE only!");\r
- }\r
- }\r
- }else{\r
- //有蓝牙搜索要求则 先进行蓝牙扫描\r
- if (!btHelper.isBtscanning()) {\r
- if (needLocationForBT()) {\r
- ICLogger.i("msgWhat_StartBLEProcess2");\r
- btHelper.scanBLE();\r
- }\r
- } else {\r
- ICLogger.i("BT Scanning skip ScanBLE only2!");\r
- }\r
- }\r
- }else if (msg.what == msgWhat_StartSOSLocationProcess){\r
-\r
- if (runtime !=null) {\r
- //更新lbs信息\r
- CellInfoUtil.getCellInfo(runtime.getContextProxy().getTelephonyManager(),runtime);\r
-\r
- if (Config.BLEScanProtocol==0 && runtime.bleInfo.btMacList.size() > 0) {\r
- startSOSLocation = true;//启动SOS定位,为了快速响应,只要wifi定位即可。\r
- if (scanBLEOnly && btHelper.isBtscanning()) {\r
- //如果正在进行独立蓝牙扫描,则强制切换为正常扫描。\r
- scanBLEOnly = false;\r
- } else {\r
- //SOS location 有蓝牙搜索要求则 先进行蓝牙扫描\r
- forceLocation = 1;\r
- if(!btHelper.isBtscanning())\r
- btHelper.scanBLE();\r
- }\r
- } else {\r
- Util.mSleep(1000);\r
- StringMessage waningmsg = protocolAPIHelper.getWarningMSG(runtime);\r
- DeliverMessage(waningmsg);\r
- }\r
- }\r
-\r
-\r
-//\r
-// startSOSLocation=true;//启动SOS定位,为了快速响应,只要wifi定位即可。\r
-// forceLocation=1;\r
-// if (runtime.bleInfo.btMacList.size() > 0) {\r
-// //有蓝牙搜索要求则 先进行蓝牙扫描\r
-// if (needLocationForBT())\r
-// btHelper.scanBLE();\r
-// } else {\r
-// startLocationProcess(ICLocation.NORMAL_MOD);\r
-// }\r
- }\r
- }\r
- };\r
-\r
-\r
- boolean wifi_ok=false,gps_ok=false,lbs_ok=false,gps_nosignal=false;\r
-\r
- private static boolean needCheckAgain=false;\r
- public void waitAndSendLocation(){\r
-\r
- this.mLbsHelper.getWifiResult();\r
-\r
- long timeCost=0L;\r
- wifi_ok=false;\r
- gps_ok=false;\r
- lbs_ok=false;\r
- gps_nosignal=false;\r
- checktimes++;\r
- int mode=runtime.getLocationInstance().getWorkingMod();\r
- if (runtime.getWifiInfo().length()>0 ) wifi_ok =true;\r
- if (runtime.getLocationInstance().getLocationStat() == ICLocation.LOCATION_STAT.LOCATION_FIXED) gps_ok=true;\r
- if (runtime.getLocationInstance().getLocationStat() == ICLocation.LOCATION_STAT.LOCATION_GPS_TIEMOUT) gps_nosignal=true;\r
- lbs_ok=( runtime.getLocationInstance().isDataChanged()==false\r
- ||(runtime.getLocationInstance().getMNC().equals("0")\r
- && runtime.getLocationInstance().getMCC().equals("0")\r
- && runtime.getLocationInstance().getGSMStationCID() ==0\r
- && runtime.getLocationInstance().getLAC()==0)) ?false:true;\r
-\r
- // ICLogger.i("getMNC "+runtime.getLocationInstance().getMNC()+" getMCC "+runtime.getLocationInstance().getMCC()+" getGSMStationCID " + runtime.getLocationInstance().getGSMStationCID()+ " getLAC "+runtime.getLocationInstance().getLAC()+" changed "+runtime.getLocationInstance().isDataChanged());\r
- ICLogger.i("waitAndSendLocation "+checktimes+", lbs="+lbs_ok+", wifi="+ wifi_ok+ ", gps="+gps_ok + ", mode="+mode);\r
- if(NoMoveAndNoGPSsignalSkipGpsFlag==true){\r
- ICLogger.i("NoMove And NoGPSsignal SkipGpsLocation!");\r
- mode=ICLocation.NORMAL_MOD;//如果没有移动且没有Gps信号,则采用Normal 模式进行wifi定位\r
- }\r
- switch(mode){\r
- case ICLocation.CUSTOM_MOD:\r
- case ICLocation.CUSTOM_MOD8_GPS:\r
- case ICLocation.EMERGNECY_MOD:\r
- case ICLocation.REALTIME_MOD:\r
-\r
-\r
- //GPS 优先的话多给些时间(10秒)\r
- if (checktimes> GPSLocationTimeoutInSeconds )\r
- {\r
- ICLogger.i("waitAndSendLocation "+checktimes+" timeout");\r
- timeout=true;\r
-\r
- }\r
- if (NoMoveTimeout==true && (timeout==true || gps_nosignal==true)){\r
- //没有移动,GPS超时或者没信号都会给 计数 加 1\r
- gpsTimeoutCountOnNoMove++;\r
- }\r
- timeCost=System.currentTimeMillis()-startCheckTime;\r
- if ((startCheckTime!=0L)&& (timeCost> 50*1000L)){\r
- //有时timer计数不准,则根据实际时间计算\r
- ICLogger.i("waitAndSendLocation "+timeCost+"> 50000ms timeout");\r
- //timeout=true;\r
- }\r
-\r
- // lbs only +timeout, lbs+wifi+gpsNosignal, libs+ , lbs+gps+wifi, Timeout can override wifi and gps\r
- if ((lbs_ok && timeout==true)\r
- ||( gps_ok )\r
- ||(lbs_ok && ( gps_ok || startSOSLocation==true ) )\r
- ||(lbs_ok && ( gps_ok || startSOSLocation==true ) && wifi_ok )\r
- ||(lbs_ok&&gps_nosignal&&wifi_ok)\r
- ){\r
- if (startSOSLocation==true){\r
- StringMessage AP10_CMD = protocolAPIHelper.getWarningMSG(runtime);\r
- DeliverMessage(AP10_CMD);\r
- runtime.setAlarmType(Runtime.AlarmType.ALARM_REMOVE_SOS);\r
- startSOSLocation=false;\r
- }\r
-\r
- if(startNomalLocation=true){\r
- startNomalLocation=false;\r
- if (gps_ok) {\r
- StringMessage AP01_CMD = protocolAPIHelper.getGPSLocationMSG(runtime);\r
- DeliverMessage(AP01_CMD);\r
- }else{\r
- StringMessage AP02_CMD = protocolAPIHelper.getLBSLocationMSG(runtime);\r
- DeliverMessage(AP02_CMD);\r
- }\r
-\r
- }\r
-\r
-\r
- stopCheckLocationResult();\r
-\r
- String locationtype="LBS";\r
- if (gps_ok ){\r
- locationtype="GPS";\r
- }else if (wifi_ok){\r
- locationtype="WiFi";\r
- }\r
-\r
- runtime.getLocationInstance().setLocationType(locationtype);\r
- runtime.getLocationInstance().setLocationTime(TimeUtil.getSystemTime3());\r
-\r
- String msg="Location Fixed Type "+runtime.getLocationInstance().getLocationType()+" at "+runtime.getLocationInstance().getLocationTime()+" timeout "+timeout;\r
- ICLogger.i(msg);\r
-\r
- if (responseUrl!=null){\r
- if(locationtype.equals("GPS")){\r
- responseUrl.replyCallBack(runtime.getLocationInstance().getLocation().latGPSStr+","+runtime.getLocationInstance().getLocation().lonGPSStr);\r
- }else{\r
- responseUrl.replyCallBack("Location Fixed Type "+locationtype);\r
- }\r
-\r
- }\r
- if (Config.LOG_TOFILE)\r
- ICLogger.logToFile("GPS",msg);\r
-\r
-\r
- }else if (timeout==true){\r
- //timeout + noLBS +noGPS\r
- ICLogger.i("timeout no location ");\r
- stopCheckLocationResult();\r
- if (Config.LOG_TOFILE)\r
- ICLogger.logToFile("GPS","timeout no location ");\r
- }\r
- break;\r
-\r
- case ICLocation.NORMAL_MOD:\r
- case ICLocation.LOWPOWER_MOD:\r
- case ICLocation.CUSTOM_MOD8_WIFI:\r
- default:\r
- //wifi优先的话给20秒时间\r
-\r
- if (checktimes> WiFiLocationTimeoutInSeconds )\r
- {\r
- ICLogger.i("waitAndSendLocation "+checktimes+" timeout");\r
- timeout=true;\r
- }\r
- timeCost=System.currentTimeMillis()-startCheckTime;\r
- if ((startCheckTime!=0L)&& (timeCost> 20*1000L)){\r
- //有时timer计数不准,则根据实际时间计算\r
- ICLogger.i("waitAndSendLocation "+timeCost+"> 20000ms timeout");\r
- // timeout=true;\r
- }\r
-\r
- if ((lbs_ok && timeout==true) ||(lbs_ok && wifi_ok )){\r
-\r
-\r
- if (startSOSLocation==true){\r
- StringMessage AP10_CMD = protocolAPIHelper.getWarningMSG(runtime);\r
- DeliverMessage(AP10_CMD);\r
- runtime.setAlarmType(Runtime.AlarmType.ALARM_REMOVE_SOS);\r
- startSOSLocation=false;\r
- }\r
- if(startNomalLocation=true){\r
- startNomalLocation=false;\r
- StringMessage AP02_CMD = protocolAPIHelper.getLBSLocationMSG(runtime);\r
- DeliverMessage(AP02_CMD);\r
- }\r
-\r
- stopCheckLocationResult();\r
-\r
- String locationtype="LBS";\r
- if (wifi_ok){\r
- locationtype="WiFi";\r
- }\r
- runtime.getLocationInstance().setLocationType(locationtype);\r
- runtime.getLocationInstance().setLocationTime(TimeUtil.getSystemTime3());\r
-\r
- String msg="Location Fixed Type "+runtime.getLocationInstance().getLocationType()+" at "+runtime.getLocationInstance().getLocationTime()+" timeout "+timeout;\r
- ICLogger.i(msg);\r
-\r
- if (responseUrl!=null){\r
- responseUrl.replyCallBack("Location Fixed Type "+locationtype);\r
- }\r
- if (Config.LOG_TOFILE)\r
- ICLogger.logToFile("GPS",msg);\r
-\r
-\r
- }else if (timeout==true){\r
- ICLogger.i("timeout no location ");\r
- stopCheckLocationResult();\r
- if (Config.LOG_TOFILE)\r
- ICLogger.logToFile("GPS","timeout no location ");\r
- }\r
- break;\r
- }\r
- ICLogger.i("needCheckAgain "+needCheckAgain);\r
- if(needCheckAgain) {\r
- AlarmHelper.setRealTimeAlarmInSeconds(runtime.getContextProxy().context, 1, ACTION_CHECK_LOCATION_RESULT);\r
- }\r
- }\r
-\r
- private void DeliverMessage(StringMessage msg){\r
-\r
-// if(Runtime.practising==true){\r
-// if(msg==null){\r
-// ICLogger.i("msg is null skip!");\r
-// }\r
-// ICLogger.i("自由锻炼中,定位缓存再发送!");\r
-// Runtime.healthInfo.setLocationData(msg.isFromCache());\r
-//\r
-// //因为心率和定位用时都比温度多,但是定位和心率不一定谁用时多,所以两个都需要检测是否结束\r
-// if(Runtime.healthInfo.check_info_item_finished()){\r
-// Runtime.healthInfo.appendBuffer(Runtime.healthInfo.getHealthInfoString());\r
-// Runtime.healthInfo.reset();\r
-// }\r
-// if(Runtime.healthInfo.getInfoCount()>=(30-1)){\r
-// //超过30次发送数据给服务器\r
-// ICLogger.i("发送数据给服务器 "+Runtime.healthInfo.getBufferData().length);\r
-// //发送过后重置\r
-// Runtime.healthInfo.resetBuffer();\r
-// }\r
-// }else {\r
- Deliver.sendLocationMSG(msg);\r
-// }\r
- }\r
- public void stopCheckLocationResult(){\r
- ICLogger.i("stopCheckLocationResult!");\r
-// if (mTimer!=null){\r
-// mTimer.shutdownNow();\r
-// Runnable tmp= mTimer.getQueue().poll();\r
-// while (tmp!=null){\r
-// mTimer.remove(tmp);\r
-// }\r
-// mTimer.setContinueExistingPeriodicTasksAfterShutdownPolicy(true);\r
-// mTimer.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);\r
-// mTimer.setRemoveOnCancelPolicy(true);\r
-// ICLogger.i("Wait for thread pool getContinueExistingPeriodicTasksAfterShutdownPolicy " +mTimer.getContinueExistingPeriodicTasksAfterShutdownPolicy()+\r
-// "\ngetExecuteExistingDelayedTasksAfterShutdownPolicy "+mTimer.getExecuteExistingDelayedTasksAfterShutdownPolicy()+\r
-// "\ngetRemoveOnCancelPolicy "+mTimer.getRemoveOnCancelPolicy());\r
-// while(!mTimer.isTerminated())\r
-// {\r
-// StringBuilder sb=new StringBuilder();\r
-// if (mTimer.isTerminated()) sb.append("+");\r
-// if (mTimer.isShutdown()) sb.append("*");\r
-// if (mTimer.isTerminating()) sb.append("-");\r
-// ICLogger.i(sb.toString());\r
-//\r
-// try {\r
-// Thread.sleep(500);\r
-// } catch (InterruptedException e) {\r
-// e.printStackTrace();\r
-// }\r
-// }\r
-// mTimer.purge();\r
-// mTimer=null;\r
-// }\r
-\r
- needCheckAgain=false;\r
- isLocating = false;\r
- startCheckTime=0L;\r
- isWifiScanning=false;\r
-// ICLogger.i(" stopCheckLocationResult Done ");\r
- }\r
-\r
-// public void EqcAlgorithmInterfaceMethod3() {\r
- public void stopGpsLocate() {\r
-\r
- boolean FactryModeOpening=DeviceInfoUtil.isFactoryTestTopActivity(runtime.getContextProxy().context);\r
- //防止与工厂测试冲突\r
- if (FactryModeOpening==false ) {\r
- ICLogger.i("stopGpsLocate");\r
- if(Config.LOG_TOFILE) ICLogger.logToFile("GPS","stopGpsLocate");\r
- nmeaListener.stopListen();\r
-// Single.just(null).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Object>() {\r
-// public void call(Object param1Object) {\r
-// nmeaListener.stopListen();\r
-// }\r
-// });\r
- }else{\r
- ICLogger.i("工厂模式 skip stopGpsLocate");\r
- runtime.getLocationInstance().setLocationStat(ICLocation.LOCATION_STAT.LOCATION_OPEN); //此处为了检测是否定位时可以正确识别状态,以防一直处于GPS定位成功状态\r
- if(Config.LOG_TOFILE) ICLogger.logToFile("GPS","工厂模式 skip stopGpsLocate");\r
- }\r
- }\r
- \r
-\r
-public void updateCellInfo() {\r
- CellInfoUtil.setCurrentAttachCellInfo(runtime);\r
- }\r
-\r
-\r
- public PowerManager.WakeLock getLocationWakeLock() {\r
- PowerManager.WakeLock wakeLock = ((PowerManager)(runtime.getContextProxy()).context.getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getSimpleName());\r
- wakeLock.acquire(1000L);\r
- return wakeLock;\r
- }\r
- \r
- public void onAlarm(PowerManager.WakeLock paramWakeLock) {\r
- //每分钟更新一次数据\r
- runtime.preCellInfo = runtime.getCurrentCellInfo();\r
- runtime.preCdmaInfo = runtime.getCdmaInfo();\r
- runtime.preTime = TimeUtil.getSystemTime(System.currentTimeMillis() - (CoreService.alarmCycle * 60 * 1000));\r
- StringBuilder stringBuilder = new StringBuilder();\r
- stringBuilder.append("runtime.preCellInfo=");\r
- stringBuilder.append(runtime.preCellInfo);\r
- ICLogger.i(stringBuilder.toString());\r
- performAlarm(paramWakeLock);\r
- }\r
-\r
-\r
- private static int gpsTimeoutCountOnNoMove=0;// 记录gps 无信号或者timeout的次数,超过5 就会停止使用gps定位,只要有一次 移动,或者设置为wifi定位,则清零。\r
- private static final int MaxGpsTimeoutCountOnNoMove=5;//不动的情况最大的gps搜不到星的次数。\r
- private static boolean skipMoveCheck=false;\r
-\r
-\r
- public static void setSkipMoveCheck(boolean _skipMoveCheck){\r
- skipMoveCheck=_skipMoveCheck;\r
- }\r
- public static boolean getSkipMoveCheck(){\r
- return skipMoveCheck;\r
- }\r
-\r
- private static boolean NoMoveAndNoGPSsignalSkipGpsFlag=false;\r
- private static boolean noMove=false;\r
- private static boolean NoMoveTimeout=false;\r
- private static boolean last_noMove=false;\r
- private static final int MaxNoMoveTimeout=3*60*1000; //3分钟\r
- private static long first_NoMove_timestamp=0;\r
- private static long first_NoMove_timestampForBT=0;\r
- private static boolean last_noMoveForBT=false;\r
-\r
- /***\r
- *noMove and timeout return true\r
- * else return false\r
- */\r
- private boolean checkNoMoveTimeoutForBT(){\r
- noMove= (( runtime.getTotalStepCount() - runtime.getLastStepCountForBT())<=0) ;\r
- runtime.updateFZDDevStatusMoving(!noMove); //设置当前运动状态\r
- ICLogger.i("BT checkNoMoveTimeout last_noMoveForBT "+last_noMoveForBT+" noMove "+noMove+ " lastStepCountForBT "+runtime.getLastStepCountForBT()+" StepCount "+runtime.getTotalStepCount());\r
- if (last_noMoveForBT==false&& noMove==true){\r
- first_NoMove_timestampForBT=System.currentTimeMillis();\r
- }else if (noMove==false){\r
- first_NoMove_timestampForBT=0;\r
- }\r
- last_noMoveForBT=noMove;\r
- //属于 判断是否 不动的状态超时\r
- if (noMove==true&& first_NoMove_timestampForBT>0.01 && System.currentTimeMillis()-first_NoMove_timestampForBT > MaxNoMoveTimeout){\r
- ICLogger.i("BT checkNoMoveTimeout true ");\r
- return true;\r
- }else{\r
- ICLogger.i("BT checkNoMoveTimeout false");\r
- return false;\r
- }\r
-\r
- }\r
-\r
- /***\r
- *noMove and timeout return true\r
- * else return false\r
- */\r
- private boolean checkNoMoveTimeout(){\r
- noMove=(runtime.getTotalStepCount() - runtime.getLastStepCount() <=0);\r
- runtime.updateFZDDevStatusMoving(!noMove); //设置当前运动状态\r
- ICLogger.i("checkNoMoveTimeout last_noMove "+last_noMove+" noMove "+noMove+ " lastStepCount "+runtime.getLastStepCount()+" StepCount "+runtime.getTotalStepCount());\r
- if (last_noMove==false&& noMove==true){\r
- first_NoMove_timestamp=System.currentTimeMillis();\r
- }else if (noMove==false){\r
- first_NoMove_timestamp=0;\r
- }\r
- last_noMove=noMove;\r
- //属于 判断是否 不动的状态超时\r
- if (noMove==true&& first_NoMove_timestamp>0.01 && System.currentTimeMillis()-first_NoMove_timestamp > MaxNoMoveTimeout){\r
- ICLogger.i(" checkNoMoveTimeout true ");\r
- return true;\r
- }else{\r
- ICLogger.i("checkNoMoveTimeout false");\r
- return false;\r
- }\r
-\r
- }\r
-\r
- private boolean needLocationForBT(){\r
- updateStepCount();//update StepCount,保证每次定位前,计步数据是最新的。防止丢数据。\r
- //如果没有动,且超时。则跳过定位\r
- NoMoveTimeout=checkNoMoveTimeoutForBT();\r
- ICLogger.i("BT NoMoveTimeout "+NoMoveTimeout+", forceLocation="+forceLocation+", Config.forceMoveCheck="+Config.forceMoveCheck+", skipMoveCheck="+skipMoveCheck);\r
-\r
- // 不强制定位 且 (WorkingMod 不是紧急模式 或者 强制进行移动检测),且 没有移动过\r
- if ( ( forceLocation != 1 ) &&\r
- (Config.forceMoveCheck==true) &&\r
- (NoMoveTimeout) && (skipMoveCheck ==false )){\r
- ICLogger.i("No Move ,skip BT location!");\r
-\r
- return false;\r
- }\r
- //以目前逻辑,每次检测必然跟随蓝牙扫描,因此可以在此直接更新上一次的计步次数,配合下次的运动检测\r
- runtime.setLastStepCountForBT(runtime.getTotalStepCount());\r
- return true;\r
- }\r
-\r
- private boolean needLocation(){\r
- updateStepCount();//update StepCount,保证每次定位前,计步数据是最新的。防止丢数据。\r
- //如果没有动,且超时。则跳过定位\r
- NoMoveTimeout=checkNoMoveTimeout();\r
- ICLogger.i(" NoMoveTimeout "+NoMoveTimeout+", forceLocation="+forceLocation+", Config.forceMoveCheck="+Config.forceMoveCheck+", skipMoveCheck="+skipMoveCheck);\r
-\r
- // 不强制定位 且 (WorkingMod 不是紧急模式 或者 强制进行移动检测),且 没有移动过\r
- if ( ( forceLocation != 1 ) &&\r
- (Config.forceMoveCheck==true) &&\r
- (NoMoveTimeout) && (skipMoveCheck ==false )){\r
- ICLogger.i("No Move ,skip BT location2!");\r
-\r
- return false;\r
- }\r
- //只做正常定位前是否运动的判断,给定位前蓝牙扫描专用的。和 NeedlocationFotBT 还不同。\r
- return true;\r
- }\r
- public void startLocationProcess(int mod){\r
- updateStepCount();//update StepCount,保证每次定位前,计步数据是最新的。防止丢数据。\r
- ICLogger.i("forceLocation="+forceLocation+", WorkingMod="+mod+", isLocating="+isLocating+", lastStep="+runtime.getLastStepCount()+", currentStep="+ runtime.getTotalStepCount());\r
- if (isLocating && 1!=forceLocation) { //如果是强制定位,则即使是正在定位,也要执行,因为有时模式变换的时候,需要取消上一次定位信息,马上新的模式定位。\r
- ICLogger.i("locating ,skip location!");\r
- return;\r
- }\r
- //如果没有动,且超时。则跳过定位\r
- NoMoveTimeout=checkNoMoveTimeout();\r
- // 不强制定位 且 (WorkingMod 不是紧急模式 或者 强制进行移动检测),且 没有移动过\r
- if ( ( forceLocation != 1 ) &&\r
- ((( mod == ICLocation.NORMAL_MOD ) || ( mod == ICLocation.LOWPOWER_MOD ) || (mod == ICLocation.CUSTOM_MOD8_WIFI ) ) || Config.forceMoveCheck==true) &&\r
- (NoMoveTimeout) && (skipMoveCheck ==false )){\r
- ICLogger.i("No Move ,skip location!");\r
- return ;\r
- }\r
-\r
- if (NoMoveTimeout){\r
-// 记录gps 无信号或者timeout的次数,超过5 就会停止使用gps定位,只要有一次 移动,或者设置为wifi定位,则清零。\r
- if (gpsTimeoutCountOnNoMove>= MaxGpsTimeoutCountOnNoMove){\r
- NoMoveAndNoGPSsignalSkipGpsFlag=true;\r
- }else{\r
- NoMoveAndNoGPSsignalSkipGpsFlag=false;\r
- }\r
-\r
- }else{\r
- NoMoveAndNoGPSsignalSkipGpsFlag=false;\r
- gpsTimeoutCountOnNoMove=0; //只要有一次 移动,则清零。\r
- }\r
-\r
- forceLocation=0;\r
- isLocating=true;\r
-\r
- //如果不动且超时,则意味着要进行定位,更新计步,配合下一次运动检查。\r
- runtime.setLastStepCount(runtime.getTotalStepCount());\r
- updateCellInfo();\r
- if(!Config.disableWiFiScan) startWifiScan();\r
- switch(mod){\r
- case ICLocation.CUSTOM_MOD:\r
- case ICLocation.CUSTOM_MOD8_GPS:\r
- if (NoMoveAndNoGPSsignalSkipGpsFlag==false) {\r
- if (runtime.getLocationInstance().getLocation_cycle() <= 60) {\r
- nmeaListener.setNoStop(true);\r
- } else {\r
- nmeaListener.setNoStop(false);\r
- }\r
- startGpsLocate();\r
- }else{\r
- clearGPSlocateStat(); //如果wifi优先,则确保gps关闭,防止切换回来gps状态错误,尤其是不NoStop模式下的gps切换回来有此风险。\r
- }\r
- break;\r
- case ICLocation.EMERGNECY_MOD:\r
- case ICLocation.REALTIME_MOD:\r
-\r
-\r
- if(NoMoveAndNoGPSsignalSkipGpsFlag==false) {\r
- nmeaListener.setNoStop(true);\r
-// nmeaListener.setNoStop(false);//保证从Custom切换回来的时候不至于不关闭gps\r
- startGpsLocate();\r
- }else{\r
- clearGPSlocateStat(); //确保gps关闭,防止切换回来gps状态错误,尤其是不NoStop模式下的gps切换回来有此风险。\r
- }\r
-\r
- break;\r
- case ICLocation.LOWPOWER_MOD:\r
- case ICLocation.NORMAL_MOD:\r
- case ICLocation.CUSTOM_MOD8_WIFI:\r
- default:\r
- gpsTimeoutCountOnNoMove=0; //只要有一次不是GPS定位,则清零。\r
- clearGPSlocateStat(); //如果wifi优先,则确保gps关闭,防止切换回来gps状态错误,尤其是不NoStop模式下的gps切换回来有此风险。\r
- break;\r
- }\r
- startCheckResult();\r
- }\r
-\r
- public static void setForceLocation(int _forcelocation){\r
- forceLocation=_forcelocation;\r
- }\r
- private static int forceLocation=0;\r
- public void onReceive(StringMessage paramStringMessage) {\r
-\r
- ICLogger.i("LocationClient onReceive " +paramStringMessage.cmd() );\r
-// Deliver.triggerSendThread();\r
- //响应定位指令\r
- if ("StartLocate".equals(paramStringMessage.cmd()) ){\r
- forceLocation=1;\r
- this.startLocationProcess(runtime.getLocationInstance().getWorkingMod());\r
- }else if ("setWorkMod".equals(paramStringMessage.cmd())) {\r
- //此处不负责给工作模式赋值,在API接收的位置能够直接拿到变量,可以直接赋值较方便。\r
- int mod = runtime.getLocationInstance().getWorkingMod();\r
- ICLogger.i("Set WorkMODE "+mod +" and reset Location AlarmCycle");\r
- CoreService.getInstance().setLocationAlarm(mod); //默认设置好Alarm后会触发一次定位,无需后面再触发定位了。\r
- forceLocation=1; //不管是什么模式,都强制定位一次,然后再说其他情况\r
-\r
- if(mod==ICLocation.EMERGNECY_MOD)\r
- CoreService.getInstance().setEmegencyLocationSTOPAlarm(5);//Emergency模式5分钟自动停止\r
-// this.startLocationProcess(mod);\r
-\r
- }\r
- }\r
- private static String ACTION_GPSCMD="com.enqualcomm.support.gps";\r
- public void registerBroadReceiver() {\r
-\r
- IntentFilter intentFilter = new IntentFilter();\r
- intentFilter.addAction(ACTION_GPSCMD);\r
- (this.runtime.getContextProxy()).context.registerReceiver(this.mLocationBroadcastReceiver, intentFilter);\r
- }\r
-\r
- public void unregisterBroadReceiver() {\r
- (this.runtime.getContextProxy()).context.unregisterReceiver(this.mLocationBroadcastReceiver);\r
- }\r
-\r
- private final BroadcastReceiver mLocationBroadcastReceiver = new BroadcastReceiver() {\r
- @Override\r
- public void onReceive(Context context, Intent intent) {\r
- String action = intent.getAction();\r
- if (ACTION_GPSCMD.equals(action)) { //此消息来自工厂测试工具,测试GPS时会发送。\r
- String status = intent.getStringExtra("status");\r
- if( status.equals("needReopen")){\r
- runtime.setFactoryTestingStat(true);\r
- }\r
- }\r
- }\r
- };\r
-\r
- public void init() {\r
-\r
- this.mSignalUtil = SimSignalUtil.getInstance((runtime.getContextProxy()).context);\r
-\r
- //获取LBS定位服务\r
- this.mLbsHelper = runtime.getLbsHelper();\r
-//\r
- StringBuilder stringBuilder = new StringBuilder();\r
- stringBuilder.append("LOCATION_MODE=");\r
- stringBuilder.append(runtime.getLocationInstance().getWorkingMod());\r
- stringBuilder.append("LOCATION_CYCLE=");\r
- stringBuilder.append(runtime.getLocationInstance().getLocation_cycle());\r
- ICLogger.i(stringBuilder.toString());\r
-\r
-\r
- /*注册 亮屏监控*/\r
-// IntentFilter intentFilter = new IntentFilter();\r
-// intentFilter.addAction("android.intent.action.SCREEN_ON");\r
-// (runtime.getContextProxy()).context.registerReceiver(this.screenOnReceiver, intentFilter);\r
-\r
- registerBroadReceiver();\r
-\r
-\r
- //暂时没有处理4G、2G切换问题\r
-// this.haveChanegTo4GTime = SystemClock.elapsedRealtime();\r
- }\r
- \r
- public void deinit() {\r
-\r
- ICLogger.i("GPS deinit!");\r
-// (runtime.getContextProxy()).context.unregisterReceiver(this.screenOnReceiver);\r
-// mLbsHelper.unRegisterWiFiBroadReceiver();\r
-// this.executor.execute(new Runnable() {\r
-// public void run() {\r
-// Deliver.saveQueue();\r
-// }\r
-// });\r
- stopGpsLocate();\r
- unregisterBroadReceiver();\r
- }\r
-\r
-\r
-\r
-\r
-\r
- private void notifiSetAirModeMethod() { (new Thread(new Runnable() {\r
- public void run() {\r
- SystemClock.sleep(3000L);\r
- boolean bool = mSignalUtil.IsAirModeOn();\r
- byte b = 1;\r
- if (bool != true)\r
- b = 0;\r
- StringBuilder stringBuilder = new StringBuilder();\r
- stringBuilder.append("AirMode==");\r
- stringBuilder.append(b);\r
- ICLogger.i(stringBuilder.toString());\r
-\r
- }\r
- })).start(); }\r
-\r
-\r
- // 飞行模式 1 开启 0 关闭\r
- public void setAirMode(int paramInt) {\r
- boolean isAirModeOn = this.mSignalUtil.IsAirModeOn();\r
- boolean isScreenOn = this.mSignalUtil.isScreenON(runtime.getContextProxy().context);\r
- switch (paramInt) {\r
-\r
- case 1:\r
- if (!isAirModeOn && !isScreenOn) {\r
- // this.mSignalUtil.setAirMode("OpenAirplane");\r
- runtime.isAirMode = true;\r
- notifiSetAirModeMethod();\r
-\r
- }\r
-\r
- break;\r
- case 0:\r
-\r
- if (isAirModeOn) {\r
- //this.mSignalUtil.setAirMode("CloseAirplane");\r
- runtime.isAirMode = false;\r
- notifiSetAirModeMethod();\r
- return;\r
- }\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- }\r
-\r
-}\r
-\r
+package com.enqualcomm.support;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.IClipboard;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.SystemClock;
+
+import com.enqualcomm.support.adapter.BTHelper;
+import com.enqualcomm.support.utils.AlarmHelper;
+import com.enqualcomm.support.adapter.LBSHelper;
+import com.enqualcomm.support.utils.Connection;
+import com.enqualcomm.support.utils.IBeaconUtil;
+import com.enqualcomm.support.utils.Util;
+import com.ic.protocols.protocolAPIHelper;
+import com.enqualcomm.support.bean.ICLocation;
+import com.enqualcomm.support.bean.StringMessage;
+import com.enqualcomm.support.service.Deliver;
+import com.enqualcomm.support.utils.CellInfoUtil;
+import com.enqualcomm.support.utils.DeviceInfoUtil;
+import com.enqualcomm.support.utils.ICLogger;
+import com.enqualcomm.support.utils.NettyConnection;
+import com.enqualcomm.support.utils.SimSignalUtil;
+import com.enqualcomm.support.bean.Runtime;
+import com.enqualcomm.support.utils.TimeUtil;
+
+import java.util.ArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import rx.Single;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.functions.Action1;
+
+import static com.enqualcomm.support.Config.GPSLocationTimeoutInSeconds;
+import static com.enqualcomm.support.Config.WiFiLocationTimeoutInSeconds;
+import static com.enqualcomm.support.Constants.ACTION_CHECK_LOCATION_RESULT;
+
+/***
+ * 周期定位:按周期进行,如果正在定位,则skip此次定位。
+ * 强制定位:随机根据指令执行,如果正在定位,强制停止当前定位,立即执行新的定位。
+ * 1、模式1 WiFi+LBS定位、15分钟一次,WiFi扫描3次如果都没有结果,20秒内返回LBS定位
+ * 2、模式2 WiFi+LBS模式,1小时1一次,WiFi扫描3次如果都没有结果,20秒内返回LBS定位
+ * 3、模式3 GPS定位模式,1分钟一次定位,GPS常开,超时返回WiFi定位。GPS 15秒内信号很差的话会提前关闭,返回wifi+LBS定位。
+ * 4、模式4 GPS定位模式,1分钟定位一次,GPS常开,超时返回WiFi定位,GPS 15秒内信号很差的话会提前关闭,返回wifi+LBS定位。5分钟后自动工作在模式1上。
+ * 5、模式5、8 GPS定位模式,客户自定义定位时间, 1分钟以内含1分钟,GPS常开,超时返回WiFi+LBS定位,1分钟以上的,GPS超2分钟时会关闭,GPS 15秒内信号很差的话也会提前关闭,返回wifi+LBS定位。
+ * 6、模式9 WiFi模式,客户自定义定位时间,WiFi扫描3次如果都没有结果,20秒内返回LBS定位
+ * 7、即时定位返回当前模式的定位方式,会强制进行定位。
+ * 8、每次切换定位模式,会执行一次强制定位。
+ */
+public class LocationClient {
+ private static final String TAG = LocationClient.class.getSimpleName();
+ private static final long CHANGENETMODETIME = 43200000L;
+ private static long startCheckTime=0L;
+ private static final int CLOSE_AIRMODE = 0;
+
+ private static final int IS_GPS = 0;
+
+ private static final int IS_LBS = 2;
+
+ private static final int IS_WIFI = 1;
+
+ public static final String LOCATION_CYCLE = "location_cycle";
+
+ public static final String LOCATION_MODE = "location_mode";
+
+ private static final int MAX_SIZE = 50;
+
+ private static final int OPEN_AIRMODE = 1;
+
+ private static final int TIME_OUT = 30000;
+
+ private static Connection connection;
+
+ private static boolean isLocationCallBack = false;
+
+ private static boolean linkOK = false;
+
+
+
+ private static boolean mHasWifiResult = true;
+
+
+ private static Runtime runtime;
+
+// private int H12StepCount;
+
+ private boolean batteryLowNotification;
+
+ private boolean batteryNotification;
+
+ private String cdmaInfo;
+
+ private ExecutorService executor = Executors.newCachedThreadPool();
+
+ private GSensorListener gSensorListener;
+
+ private boolean haveChanegTo4G;
+
+ private long haveChanegTo4GTime;
+
+ private String mCellInfo;
+
+
+ private LBSHelper mLbsHelper;
+ private static BTHelper btHelper=null;
+
+ private int mPedometer2;
+
+ private SimSignalUtil mSignalUtil;
+
+ private NMEAListener nmeaListener;
+
+ private boolean startSOSLocation=false;
+ private boolean startNomalLocation=false;
+
+ private int preLbsCid;
+
+ int preNetworkTypeNomber;
+ private boolean scanBLEOnly=false;
+
+ //如果未扫到,重试扫描的次数。
+ private int maxBLEScanTime=0;
+ private int ScanBLERetryCount=maxBLEScanTime;
+ private int OneBLEScanTimeOUT=15;
+
+ private static LocationClient gLocationCline=null;
+// private BroadcastReceiver screenOnReceiver = new BroadcastReceiver() {
+// public void onReceive(Context param1Context, Intent param1Intent) {
+// if ("android.intent.action.SCREEN_ON".equals(param1Intent.getAction())) {
+// mSignalUtil.setAirMode("CloseAirplane");
+// }
+// }
+// };
+ public static LocationClient getInstance(){
+ return gLocationCline;
+ }
+ public LocationClient(Connection paramNettyConnection, Runtime paramRuntime) {
+ connection = paramNettyConnection;
+ runtime = paramRuntime;
+ btHelper = BTHelper.CreateInstance(paramRuntime, new BTHelper.BTScanCallback() {
+ @Override
+ public void OnScanFinished(ArrayList<IBeaconUtil.iBeacon> btBeaconScanResult, ArrayList<String> btNewScanResult) {
+ if (Config.BLEScanProtocol == 0) { //扫描并判定是否在区域内。
+ if (btNewScanResult != null && btNewScanResult.size() > 0) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("found bt mac ").append(btNewScanResult.size());
+ sb.append(" bounding BeaconMacList ").append(runtime.bleInfo.btMacList.size());
+ runtime.bleInfo.btScanResult.clear();
+ for (String mac : runtime.bleInfo.btMacList) {
+ sb.append(" ").append(mac);
+ }
+ ICLogger.i(sb.toString());
+
+
+ boolean in_area = false;
+ try {
+ for (String mac : btNewScanResult) {
+ ICLogger.i("bt mac " + mac.replace(":", "").toLowerCase() + " " + mac.toLowerCase());
+ String tmp = mac.replace(":", "").toLowerCase();
+ tmp = tmp.substring(0, tmp.indexOf(","));
+ if (runtime.bleInfo.btMacList.contains(tmp)) {
+ in_area = true;
+ break;
+ }
+ }
+ if (in_area == false && ScanBLERetryCount-- > 0) {
+ //如果没有扫描到,且扫描次数没有超限,则重新扫描一次。注意要delay 5秒
+ Util.mSleep(5000);
+ //Do retry Scan
+ ICLogger.i("BT BLE not found retry Scan " + ScanBLERetryCount);
+ btHelper.scanBLE();
+ return;
+ } else {
+ runtime.bleInfo.is_in_area = in_area;
+ ScanBLERetryCount = maxBLEScanTime;
+ }
+
+ } catch (Exception e) {//如果出错,原来的状态不要变。防止误报,最多延迟一个周期报。
+ e.printStackTrace();
+ ICLogger.i(e.getMessage());
+ }
+
+
+ } else {
+ runtime.bleInfo.is_in_area = false;
+ ScanBLERetryCount = maxBLEScanTime;
+ }
+ ICLogger.i("Bt Dev Is in Area " + runtime.bleInfo.is_in_area);
+
+ if (scanBLEOnly == true) {
+ //只扫描蓝牙,不做定位
+ if (runtime.bleInfo.is_in_area == false) {
+ runtime.updateFZDDevStatusEscape(true);
+ ICLogger.i("BT 不在区域内");
+ if (runtime.bleInfo.last_is_in_area == true) {
+ //只有上一次在区域内,这次出区域才需要报警
+ ICLogger.i("BT 不在区域内,且上次在区域内,报警!");
+ //如果需要报警定位,则强制进行sos定位,不能通过triggerSOS,因为函数中调用了BLEScan会造成循环调用
+ StringMessage AL_CMD = protocolAPIHelper.getWarningMSG(runtime);
+ DeliverMessage(AL_CMD);
+ }
+ } else {
+ ICLogger.i("BT 在区域内!");
+ runtime.updateFZDDevStatusEscape(false);
+ if (runtime.bleInfo.last_is_in_area == false) {
+ //上一次不在区域内,这次进区域要报警
+ ICLogger.i("BT 进入区域内,且上次不在区域内,报警!");
+ if(!Config.noBLE_RelaseEscapeAlarm) {
+ //如果需要报警定位,则强制进行sos定位,不能通过triggerSOS,因为函数中调用了BLEScan会造成循环调用
+ StringMessage AL_CMD = protocolAPIHelper.getWarningMSG(runtime);
+ DeliverMessage(AL_CMD);
+ }
+ }
+ }
+ } else {
+ //定位前的蓝牙扫描
+ if (runtime.bleInfo.is_in_area == false) {
+ ICLogger.i("BT 不在区域内,开启定位流程");
+ runtime.updateFZDDevStatusEscape(true);
+ if (runtime.bleInfo.last_is_in_area == true) {
+ //只有上一次在区域内,这次出区域才需要报警
+ ICLogger.i("BT 不在区域内,且上次在区域内,报警!");
+
+ StringMessage AL_CMD = protocolAPIHelper.getWarningMSG(runtime);
+ DeliverMessage(AL_CMD);
+ runtime.setAlarmType(Runtime.AlarmType.ALARM_REMOVE_SOS);
+ startSOSLocation = false; //如果已经报警,后面就不用再报了
+ }
+
+ if (startSOSLocation) {
+ StringMessage AL_CMD = protocolAPIHelper.getWarningMSG(runtime);
+ DeliverMessage(AL_CMD);
+ runtime.setAlarmType(Runtime.AlarmType.ALARM_REMOVE_SOS);
+ startSOSLocation = false;
+ }
+ if (startNomalLocation) {
+ startLocationProcess(runtime.getLocationInstance().getWorkingMod());
+ }
+
+ } else {
+ ICLogger.i("BT 在区域内,直接发送区域坐标即可!");
+ runtime.updateFZDDevStatusEscape(false);
+ if (runtime.bleInfo.last_is_in_area == false) {
+ //上一次不在区域内,这次进区域要报警
+ ICLogger.i("BT 进入区域内,且上次不在区域内,报警!");
+
+ if(!Config.noBLE_RelaseEscapeAlarm) {
+ //如果需要报警定位,则强制进行sos定位,不能通过triggerSOS,因为函数中调用了BLEScan会造成循环调用
+ StringMessage AL_CMD = protocolAPIHelper.getWarningMSG(runtime);
+ DeliverMessage(AL_CMD);
+ runtime.setAlarmType(Runtime.AlarmType.ALARM_REMOVE_SOS);
+ startSOSLocation = false;//如果已经报警,后面就不用再报了
+ }
+ }
+
+ if (startSOSLocation) {
+ StringMessage AP01_CMD = protocolAPIHelper.getWarningMSG(runtime);
+ DeliverMessage(AP01_CMD);
+ runtime.setAlarmType(Runtime.AlarmType.ALARM_REMOVE_SOS);
+ startSOSLocation = false;
+ }
+ if (startNomalLocation) {
+ //已经通过蓝牙定位,则清除 forceLocation=0
+ forceLocation = 0;
+ startNomalLocation = false; //蓝牙定位,直接发GPS坐标
+ StringMessage AP01_CMD = protocolAPIHelper.getGPSLocationMSG(runtime);
+ DeliverMessage(AP01_CMD);
+ }
+ }
+ }
+
+ //处理过此次数据后,把当前状态赋值给上次检测状态
+ runtime.bleInfo.last_is_in_area = runtime.bleInfo.is_in_area;
+ //扫描结束就清掉scanBLEOnly,保证下次不会被误操作。
+ scanBLEOnly = false;
+ } else {
+ //Config.BLEScanProtocol == 1
+ if (btBeaconScanResult != null && btBeaconScanResult.size() > 0) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("found bt mac ").append(btBeaconScanResult.size());
+ runtime.bleInfo.btScanResult.clear();
+ for (IBeaconUtil.iBeacon beacon : btBeaconScanResult) {
+ sb.append("\n").append(beacon.toString());
+ if (runtime.bleInfo.btMajorList.size()>0) {
+ if (runtime.bleInfo.btMajorList.contains(String.valueOf(beacon.major))) {
+ runtime.bleInfo.btScanResult.add(beacon.toString());
+ sb.append(" in list!");
+ } else {
+ sb.append(" not in!");
+ }
+ }else{
+ runtime.bleInfo.btScanResult.add(beacon.toString());
+ }
+ }
+ ICLogger.i(sb.toString());
+ Deliver.sendLocationMSG(protocolAPIHelper.getBLEScanResult(runtime));
+ } else {
+ ICLogger.i("未搜到蓝牙设备!");
+ }
+ }
+ }
+ });
+
+ btHelper.setBLEScanTimeout(OneBLEScanTimeOUT);
+ gLocationCline = this;
+ //GPS 监听管理初始化
+ this.nmeaListener = new NMEAListener(paramRuntime.getContextProxy().getLocationManager(), paramRuntime);
+ // 初始化同时开启计步(硬件计步器,比较省电,全程开启计步功能)
+ this.gSensorListener = new GSensorListener(paramRuntime);
+ }
+
+ private LocationResponseUrl responseUrl=null;
+ public void setLocationResponse(LocationResponseUrl lru){
+ responseUrl=lru;
+ }
+ public interface LocationResponseUrl{
+ abstract public void replyCallBack(String locationResponseUrl);
+ };
+
+ private void handler2GTo4G() {
+ int networktype = this.mSignalUtil.getNetworkType();
+ int singal = runtime.getSignalStrength();
+ long currenttime = SystemClock.elapsedRealtime();
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append("networkType=");
+ stringBuilder.append(networktype);
+ stringBuilder.append("signalStrength=");
+ stringBuilder.append(singal);
+ stringBuilder.append("haveChanegTo4G=");
+ stringBuilder.append(this.haveChanegTo4G);
+ ICLogger.i(stringBuilder.toString());
+ switch (networktype) {
+ default:
+ return;
+ case SimSignalUtil.IS_4G:
+ if (singal < -93) {
+ this.mSignalUtil.changeNetWorkType("2G");
+ this.haveChanegTo4GTime = currenttime;
+ return;
+ }
+ return;
+ case SimSignalUtil.IS_2G:
+ case SimSignalUtil.IS_3G:
+ break;
+ }
+ if (this.haveChanegTo4G || currenttime - this.haveChanegTo4GTime > 43200000L) {
+ this.mSignalUtil.changeNetWorkType("4G");
+ this.haveChanegTo4G = false;
+ this.haveChanegTo4GTime = currenttime;
+ }
+ }
+ //计算运动并发送数据
+ public void updateStepCount() {
+ this.gSensorListener.updateStepCount();
+
+// this.H12StepCount = DeviceInfoUtil.getStepCount((runtime.getContextProxy()).context);
+// if (i != 0 && Math.abs(this.H12StepCount - this.mPedometer2) > 1000) {
+//// connection.send(API.H12(runtime, this.H12StepCount));
+// ICLogger.i("StepCount 运动开始后 变化超过1000 ,则发送给服务器!");
+// }
+
+ }
+
+ private void performAlarm(PowerManager.WakeLock paramWakeLock) {
+// if (!runtime.isAirMode) {
+ updateStepCount();//update StepCount
+ // CellInfoUtil.triggerUpdateCellinfo(); //这个在locationClinet中也会执行更新
+// sendBatteryNotification();
+// }
+ }
+ public void triggerLocationProcess(){
+ mhandler.sendEmptyMessage(msgWhat_StartLocationProcess);
+ }
+
+ public void triggerBLEProcess(){
+ mhandler.sendEmptyMessage(msgWhat_StartBLEProcess);
+ }
+
+ public void triggerSOSLocationProcess(){
+
+ mhandler.sendEmptyMessage(msgWhat_StartSOSLocationProcess);
+
+ }
+
+ private static int checktimes=0;
+ private static boolean timeout=false;
+ private static boolean isLocating=false;
+ private static boolean isWifiScanning=false;
+ LBSHelper.OnWiFiInfoListener wifiinfoListener=new LBSHelper.OnWiFiInfoListener() {
+ public void getWifiInfoCallBack(String param1String) {
+ ICLogger.i("get wifi scan Callback " + param1String);
+ LocationClient.mHasWifiResult=true;
+ runtime.setWifiinfo(param1String==null?"":param1String);
+ isWifiScanning=false;
+ }
+ };
+ public void startWifiScan(){
+
+ if (isWifiScanning==false) {
+ ICLogger.i("开启wifi扫描");
+ isWifiScanning=true;
+ runtime.setWifiinfo("");
+ mHasWifiResult = false;
+ this.mLbsHelper.setOnWiFiInfoListener(wifiinfoListener);
+ this.mLbsHelper.getWifiInfo();
+ }else{
+ ICLogger.i("wifi扫描进行中,skip开启");
+ }
+ }
+ public void startGpsLocate() {
+
+ boolean FactryModeOpening=DeviceInfoUtil.isFactoryTestTopActivity(runtime.getContextProxy().context);
+ boolean needReOpenGPS=runtime.getFactoryTestingStat();
+
+ //防止与工厂测试冲突
+ if (FactryModeOpening==false || needReOpenGPS==true) {
+
+ if (needReOpenGPS==true) {
+ ICLogger.i("工厂模式关闭了GPS,需要重新关闭GPS以同步状态!");
+ //处理过后,要把状态设置为初始状态,防止每次都重启。
+ runtime.setFactoryTestingStat(false);
+ //如果发现需要重启GPS,为了状态正确,需要先停止GPS
+ nmeaListener.stopListen();
+ }
+ ICLogger.i("开启GPS扫描!");
+ if(Config.LOG_TOFILE) ICLogger.logToFile("GPS","开启GPS扫描!");
+ if (!nmeaListener.isListening()) {
+ runtime.getLocationInstance().setLocationStat(ICLocation.LOCATION_STAT.LOCATION_OPEN); //此处为了检测是否定位时可以正确识别状态,以防一直处于GPS定位成功状态
+// Single.just(null).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Object>() {
+// public void call(Object param1Object) {
+// nmeaListener.startListen();
+// }
+// });
+ nmeaListener.startListen();
+
+ } else {
+ ICLogger.i("GPS is still listening, skip open it!");
+ runtime.getLocationInstance().setLocationStat(ICLocation.LOCATION_STAT.LOCATION_OPEN); //此处为了检测是否定位时可以正确识别状态,以防一直处于GPS定位成功状态
+ if (Config.LOG_TOFILE) ICLogger.logToFile("GPS", "GPS is still listening, skip open it!");
+ }
+ }else{
+ ICLogger.i("工厂模式,skip 开启GPS扫描!");
+ runtime.getLocationInstance().setLocationStat(ICLocation.LOCATION_STAT.LOCATION_OPEN); //此处为了检测是否定位时可以正确识别状态,以防一直处于GPS定位成功状态
+ if(Config.LOG_TOFILE) ICLogger.logToFile("GPS","工厂模式,skip 开启GPS扫描!");
+ }
+ }
+
+ public void clearGPSlocateStat(){
+ ICLogger.i("clearGPSlocateStat");
+ stopGpsLocate();
+ runtime.getLocationInstance().setLocationStat( ICLocation.LOCATION_STAT.LOCATION_CLOSED);//此处为了检测是否定位时可以正确识别状态,以防一直处于GPS定位成功状态
+ }
+
+ public void startCheckResult(){
+ checktimes=0;
+ timeout=false;
+ startCheckTime= System.currentTimeMillis();
+ needCheckAgain=true;
+ ICLogger.i("startCheckResult " );
+
+ AlarmHelper.setRealTimeAlarmInSeconds(runtime.getContextProxy().context,1,ACTION_CHECK_LOCATION_RESULT);
+
+ }
+
+
+
+ private final static int msgWhat_WaitAndSendLocation=100;
+ private final static int msgWhat_StartLocationProcess=0;
+ private final static int msgWhat_StartBLEProcess=1;
+ private final static int msgWhat_StartSOSLocationProcess=2;
+ Handler mhandler=new Handler(){
+
+ public void handleMessage(Message msg) {
+ super.handleMessage(msg);
+ if (msg.what == msgWhat_WaitAndSendLocation){
+ Single.just(null).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Object>() {
+ public void call(Object param1Object) { waitAndSendLocation(); }
+ });
+ }else if (msg.what == msgWhat_StartLocationProcess) {
+ startNomalLocation=true;
+ if (Config.BLEScanProtocol == 0 && runtime.bleInfo.btMacList.size() > 0) {
+ if(scanBLEOnly && btHelper.isBtscanning()){
+ //如果正在进行独立蓝牙扫描,则强制切换为正常扫描。
+ scanBLEOnly=false;
+ }else {
+ //有蓝牙搜索要求则 先进行蓝牙扫描
+ if (needLocation()) {
+ btHelper.scanBLE();
+ }
+ }
+ } else {
+ //没有蓝牙搜索要求,就正常定位
+ startLocationProcess(runtime.getLocationInstance().getWorkingMod());
+ }
+ }else if (msg.what == msgWhat_StartBLEProcess){
+ if(Config.BLEScanProtocol==0) {
+ if (runtime.bleInfo.btMacList.size() > 0) {
+ //有蓝牙搜索要求则 先进行蓝牙扫描
+ if (!btHelper.isBtscanning()) {
+ scanBLEOnly = true;
+ if (needLocationForBT()) {
+ ICLogger.i("msgWhat_StartBLEProcess");
+ btHelper.scanBLE();
+ }
+ } else {
+ ICLogger.i("BT Scanning skip ScanBLE only!");
+ }
+ }
+ }else{
+ //有蓝牙搜索要求则 先进行蓝牙扫描
+ if (!btHelper.isBtscanning()) {
+ if (needLocationForBT()) {
+ ICLogger.i("msgWhat_StartBLEProcess2");
+ btHelper.scanBLE();
+ }
+ } else {
+ ICLogger.i("BT Scanning skip ScanBLE only2!");
+ }
+ }
+ }else if (msg.what == msgWhat_StartSOSLocationProcess){
+
+ if (runtime !=null) {
+ //更新lbs信息
+ CellInfoUtil.getCellInfo(runtime.getContextProxy().getTelephonyManager(),runtime);
+
+ if (Config.BLEScanProtocol==0 && runtime.bleInfo.btMacList.size() > 0) {
+ startSOSLocation = true;//启动SOS定位,为了快速响应,只要wifi定位即可。
+ if (scanBLEOnly && btHelper.isBtscanning()) {
+ //如果正在进行独立蓝牙扫描,则强制切换为正常扫描。
+ scanBLEOnly = false;
+ } else {
+ //SOS location 有蓝牙搜索要求则 先进行蓝牙扫描
+ forceLocation = 1;
+ if(!btHelper.isBtscanning())
+ btHelper.scanBLE();
+ }
+ } else {
+ Util.mSleep(1000);
+ StringMessage waningmsg = protocolAPIHelper.getWarningMSG(runtime);
+ DeliverMessage(waningmsg);
+ }
+ }
+
+
+//
+// startSOSLocation=true;//启动SOS定位,为了快速响应,只要wifi定位即可。
+// forceLocation=1;
+// if (runtime.bleInfo.btMacList.size() > 0) {
+// //有蓝牙搜索要求则 先进行蓝牙扫描
+// if (needLocationForBT())
+// btHelper.scanBLE();
+// } else {
+// startLocationProcess(ICLocation.NORMAL_MOD);
+// }
+ }
+ }
+ };
+
+
+ boolean wifi_ok=false,gps_ok=false,lbs_ok=false,gps_nosignal=false;
+
+ private static boolean needCheckAgain=false;
+ public void waitAndSendLocation(){
+
+ this.mLbsHelper.getWifiResult();
+
+ long timeCost=0L;
+ wifi_ok=false;
+ gps_ok=false;
+ lbs_ok=false;
+ gps_nosignal=false;
+ checktimes++;
+ int mode=runtime.getLocationInstance().getWorkingMod();
+ if (runtime.getWifiInfo().length()>0 ) wifi_ok =true;
+ if (runtime.getLocationInstance().getLocationStat() == ICLocation.LOCATION_STAT.LOCATION_FIXED) gps_ok=true;
+ if (runtime.getLocationInstance().getLocationStat() == ICLocation.LOCATION_STAT.LOCATION_GPS_TIEMOUT) gps_nosignal=true;
+ lbs_ok=( runtime.getLocationInstance().isDataChanged()==false
+ ||(runtime.getLocationInstance().getMNC().equals("0")
+ && runtime.getLocationInstance().getMCC().equals("0")
+ && runtime.getLocationInstance().getGSMStationCID() ==0
+ && runtime.getLocationInstance().getLAC()==0)) ?false:true;
+
+ // ICLogger.i("getMNC "+runtime.getLocationInstance().getMNC()+" getMCC "+runtime.getLocationInstance().getMCC()+" getGSMStationCID " + runtime.getLocationInstance().getGSMStationCID()+ " getLAC "+runtime.getLocationInstance().getLAC()+" changed "+runtime.getLocationInstance().isDataChanged());
+ ICLogger.i("waitAndSendLocation "+checktimes+", lbs="+lbs_ok+", wifi="+ wifi_ok+ ", gps="+gps_ok + ", mode="+mode);
+ if(NoMoveAndNoGPSsignalSkipGpsFlag==true){
+ ICLogger.i("NoMove And NoGPSsignal SkipGpsLocation!");
+ mode=ICLocation.NORMAL_MOD;//如果没有移动且没有Gps信号,则采用Normal 模式进行wifi定位
+ }
+ switch(mode){
+ case ICLocation.CUSTOM_MOD:
+ case ICLocation.CUSTOM_MOD8_GPS:
+ case ICLocation.EMERGNECY_MOD:
+ case ICLocation.REALTIME_MOD:
+
+
+ //GPS 优先的话多给些时间(10秒)
+ if (checktimes> GPSLocationTimeoutInSeconds )
+ {
+ ICLogger.i("waitAndSendLocation "+checktimes+" timeout");
+ timeout=true;
+
+ }
+ if (NoMoveTimeout==true && (timeout==true || gps_nosignal==true)){
+ //没有移动,GPS超时或者没信号都会给 计数 加 1
+ gpsTimeoutCountOnNoMove++;
+ }
+ timeCost=System.currentTimeMillis()-startCheckTime;
+ if ((startCheckTime!=0L)&& (timeCost> 50*1000L)){
+ //有时timer计数不准,则根据实际时间计算
+ ICLogger.i("waitAndSendLocation "+timeCost+"> 50000ms timeout");
+ //timeout=true;
+ }
+
+ // lbs only +timeout, lbs+wifi+gpsNosignal, libs+ , lbs+gps+wifi, Timeout can override wifi and gps
+ if ((lbs_ok && timeout==true)
+ ||( gps_ok )
+ ||(lbs_ok && ( gps_ok || startSOSLocation==true ) )
+ ||(lbs_ok && ( gps_ok || startSOSLocation==true ) && wifi_ok )
+ ||(lbs_ok&&gps_nosignal&&wifi_ok)
+ ){
+ if (startSOSLocation==true){
+ StringMessage AP10_CMD = protocolAPIHelper.getWarningMSG(runtime);
+ DeliverMessage(AP10_CMD);
+ runtime.setAlarmType(Runtime.AlarmType.ALARM_REMOVE_SOS);
+ startSOSLocation=false;
+ }
+
+ if(startNomalLocation=true){
+ startNomalLocation=false;
+ if (gps_ok) {
+ StringMessage AP01_CMD = protocolAPIHelper.getGPSLocationMSG(runtime);
+ DeliverMessage(AP01_CMD);
+ }else{
+ StringMessage AP02_CMD = protocolAPIHelper.getLBSLocationMSG(runtime);
+ DeliverMessage(AP02_CMD);
+ }
+
+ }
+
+
+ stopCheckLocationResult();
+
+ String locationtype="LBS";
+ if (gps_ok ){
+ locationtype="GPS";
+ }else if (wifi_ok){
+ locationtype="WiFi";
+ }
+
+ runtime.getLocationInstance().setLocationType(locationtype);
+ runtime.getLocationInstance().setLocationTime(TimeUtil.getSystemTime3());
+
+ String msg="Location Fixed Type "+runtime.getLocationInstance().getLocationType()+" at "+runtime.getLocationInstance().getLocationTime()+" timeout "+timeout;
+ ICLogger.i(msg);
+
+ if (responseUrl!=null){
+ if(locationtype.equals("GPS")){
+ responseUrl.replyCallBack(runtime.getLocationInstance().getLocation().latGPSStr+","+runtime.getLocationInstance().getLocation().lonGPSStr);
+ }else{
+ responseUrl.replyCallBack("Location Fixed Type "+locationtype);
+ }
+
+ }
+ if (Config.LOG_TOFILE)
+ ICLogger.logToFile("GPS",msg);
+
+
+ }else if (timeout==true){
+ //timeout + noLBS +noGPS
+ ICLogger.i("timeout no location ");
+ stopCheckLocationResult();
+ if (Config.LOG_TOFILE)
+ ICLogger.logToFile("GPS","timeout no location ");
+ }
+ break;
+
+ case ICLocation.NORMAL_MOD:
+ case ICLocation.LOWPOWER_MOD:
+ case ICLocation.CUSTOM_MOD8_WIFI:
+ default:
+ //wifi优先的话给20秒时间
+
+ if (checktimes> WiFiLocationTimeoutInSeconds )
+ {
+ ICLogger.i("waitAndSendLocation "+checktimes+" timeout");
+ timeout=true;
+ }
+ timeCost=System.currentTimeMillis()-startCheckTime;
+ if ((startCheckTime!=0L)&& (timeCost> 20*1000L)){
+ //有时timer计数不准,则根据实际时间计算
+ ICLogger.i("waitAndSendLocation "+timeCost+"> 20000ms timeout");
+ // timeout=true;
+ }
+
+ if ((lbs_ok && timeout==true) ||(lbs_ok && wifi_ok )){
+
+
+ if (startSOSLocation==true){
+ StringMessage AP10_CMD = protocolAPIHelper.getWarningMSG(runtime);
+ DeliverMessage(AP10_CMD);
+ runtime.setAlarmType(Runtime.AlarmType.ALARM_REMOVE_SOS);
+ startSOSLocation=false;
+ }
+ if(startNomalLocation=true){
+ startNomalLocation=false;
+ StringMessage AP02_CMD = protocolAPIHelper.getLBSLocationMSG(runtime);
+ DeliverMessage(AP02_CMD);
+ }
+
+ stopCheckLocationResult();
+
+ String locationtype="LBS";
+ if (wifi_ok){
+ locationtype="WiFi";
+ }
+ runtime.getLocationInstance().setLocationType(locationtype);
+ runtime.getLocationInstance().setLocationTime(TimeUtil.getSystemTime3());
+
+ String msg="Location Fixed Type "+runtime.getLocationInstance().getLocationType()+" at "+runtime.getLocationInstance().getLocationTime()+" timeout "+timeout;
+ ICLogger.i(msg);
+
+ if (responseUrl!=null){
+ responseUrl.replyCallBack("Location Fixed Type "+locationtype);
+ }
+ if (Config.LOG_TOFILE)
+ ICLogger.logToFile("GPS",msg);
+
+
+ }else if (timeout==true){
+ ICLogger.i("timeout no location ");
+ stopCheckLocationResult();
+ if (Config.LOG_TOFILE)
+ ICLogger.logToFile("GPS","timeout no location ");
+ }
+ break;
+ }
+ ICLogger.i("needCheckAgain "+needCheckAgain);
+ if(needCheckAgain) {
+ AlarmHelper.setRealTimeAlarmInSeconds(runtime.getContextProxy().context, 1, ACTION_CHECK_LOCATION_RESULT);
+ }
+ }
+
+ private void DeliverMessage(StringMessage msg){
+
+// if(Runtime.practising==true){
+// if(msg==null){
+// ICLogger.i("msg is null skip!");
+// }
+// ICLogger.i("自由锻炼中,定位缓存再发送!");
+// Runtime.healthInfo.setLocationData(msg.isFromCache());
+//
+// //因为心率和定位用时都比温度多,但是定位和心率不一定谁用时多,所以两个都需要检测是否结束
+// if(Runtime.healthInfo.check_info_item_finished()){
+// Runtime.healthInfo.appendBuffer(Runtime.healthInfo.getHealthInfoString());
+// Runtime.healthInfo.reset();
+// }
+// if(Runtime.healthInfo.getInfoCount()>=(30-1)){
+// //超过30次发送数据给服务器
+// ICLogger.i("发送数据给服务器 "+Runtime.healthInfo.getBufferData().length);
+// //发送过后重置
+// Runtime.healthInfo.resetBuffer();
+// }
+// }else {
+ Deliver.sendLocationMSG(msg);
+// }
+ }
+ public void stopCheckLocationResult(){
+ ICLogger.i("stopCheckLocationResult!");
+// if (mTimer!=null){
+// mTimer.shutdownNow();
+// Runnable tmp= mTimer.getQueue().poll();
+// while (tmp!=null){
+// mTimer.remove(tmp);
+// }
+// mTimer.setContinueExistingPeriodicTasksAfterShutdownPolicy(true);
+// mTimer.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+// mTimer.setRemoveOnCancelPolicy(true);
+// ICLogger.i("Wait for thread pool getContinueExistingPeriodicTasksAfterShutdownPolicy " +mTimer.getContinueExistingPeriodicTasksAfterShutdownPolicy()+
+// "\ngetExecuteExistingDelayedTasksAfterShutdownPolicy "+mTimer.getExecuteExistingDelayedTasksAfterShutdownPolicy()+
+// "\ngetRemoveOnCancelPolicy "+mTimer.getRemoveOnCancelPolicy());
+// while(!mTimer.isTerminated())
+// {
+// StringBuilder sb=new StringBuilder();
+// if (mTimer.isTerminated()) sb.append("+");
+// if (mTimer.isShutdown()) sb.append("*");
+// if (mTimer.isTerminating()) sb.append("-");
+// ICLogger.i(sb.toString());
+//
+// try {
+// Thread.sleep(500);
+// } catch (InterruptedException e) {
+// e.printStackTrace();
+// }
+// }
+// mTimer.purge();
+// mTimer=null;
+// }
+
+ needCheckAgain=false;
+ isLocating = false;
+ startCheckTime=0L;
+ isWifiScanning=false;
+// ICLogger.i(" stopCheckLocationResult Done ");
+ }
+
+// public void EqcAlgorithmInterfaceMethod3() {
+ public void stopGpsLocate() {
+
+ boolean FactryModeOpening=DeviceInfoUtil.isFactoryTestTopActivity(runtime.getContextProxy().context);
+ //防止与工厂测试冲突
+ if (FactryModeOpening==false ) {
+ ICLogger.i("stopGpsLocate");
+ if(Config.LOG_TOFILE) ICLogger.logToFile("GPS","stopGpsLocate");
+ nmeaListener.stopListen();
+// Single.just(null).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Object>() {
+// public void call(Object param1Object) {
+// nmeaListener.stopListen();
+// }
+// });
+ }else{
+ ICLogger.i("工厂模式 skip stopGpsLocate");
+ runtime.getLocationInstance().setLocationStat(ICLocation.LOCATION_STAT.LOCATION_OPEN); //此处为了检测是否定位时可以正确识别状态,以防一直处于GPS定位成功状态
+ if(Config.LOG_TOFILE) ICLogger.logToFile("GPS","工厂模式 skip stopGpsLocate");
+ }
+ }
+
+
+public void updateCellInfo() {
+ CellInfoUtil.setCurrentAttachCellInfo(runtime);
+ }
+
+
+ public PowerManager.WakeLock getLocationWakeLock() {
+ PowerManager.WakeLock wakeLock = ((PowerManager)(runtime.getContextProxy()).context.getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getSimpleName());
+ wakeLock.acquire(1000L);
+ return wakeLock;
+ }
+
+ public void onAlarm(PowerManager.WakeLock paramWakeLock) {
+ //每分钟更新一次数据
+ runtime.preCellInfo = runtime.getCurrentCellInfo();
+ runtime.preCdmaInfo = runtime.getCdmaInfo();
+ runtime.preTime = TimeUtil.getSystemTime(System.currentTimeMillis() - (CoreService.alarmCycle * 60 * 1000));
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append("runtime.preCellInfo=");
+ stringBuilder.append(runtime.preCellInfo);
+ ICLogger.i(stringBuilder.toString());
+ performAlarm(paramWakeLock);
+ }
+
+
+ private static int gpsTimeoutCountOnNoMove=0;// 记录gps 无信号或者timeout的次数,超过5 就会停止使用gps定位,只要有一次 移动,或者设置为wifi定位,则清零。
+ private static final int MaxGpsTimeoutCountOnNoMove=5;//不动的情况最大的gps搜不到星的次数。
+ private static boolean skipMoveCheck=false;
+
+
+ public static void setSkipMoveCheck(boolean _skipMoveCheck){
+ skipMoveCheck=_skipMoveCheck;
+ }
+ public static boolean getSkipMoveCheck(){
+ return skipMoveCheck;
+ }
+
+ private static boolean NoMoveAndNoGPSsignalSkipGpsFlag=false;
+ private static boolean noMove=false;
+ private static boolean NoMoveTimeout=false;
+ private static boolean last_noMove=false;
+ private static final int MaxNoMoveTimeout=3*60*1000; //3分钟
+ private static long first_NoMove_timestamp=0;
+ private static long first_NoMove_timestampForBT=0;
+ private static boolean last_noMoveForBT=false;
+
+ /***
+ *noMove and timeout return true
+ * else return false
+ */
+ private boolean checkNoMoveTimeoutForBT(){
+ noMove= (( runtime.getTotalStepCount() - runtime.getLastStepCountForBT())<=0) ;
+ runtime.updateFZDDevStatusMoving(!noMove); //设置当前运动状态
+ ICLogger.i("BT checkNoMoveTimeout last_noMoveForBT "+last_noMoveForBT+" noMove "+noMove+ " lastStepCountForBT "+runtime.getLastStepCountForBT()+" StepCount "+runtime.getTotalStepCount());
+ if (last_noMoveForBT==false&& noMove==true){
+ first_NoMove_timestampForBT=System.currentTimeMillis();
+ }else if (noMove==false){
+ first_NoMove_timestampForBT=0;
+ }
+ last_noMoveForBT=noMove;
+ //属于 判断是否 不动的状态超时
+ if (noMove==true&& first_NoMove_timestampForBT>0.01 && System.currentTimeMillis()-first_NoMove_timestampForBT > MaxNoMoveTimeout){
+ ICLogger.i("BT checkNoMoveTimeout true ");
+ return true;
+ }else{
+ ICLogger.i("BT checkNoMoveTimeout false");
+ return false;
+ }
+
+ }
+
+ /***
+ *noMove and timeout return true
+ * else return false
+ */
+ private boolean checkNoMoveTimeout(){
+ noMove=(runtime.getTotalStepCount() - runtime.getLastStepCount() <=0);
+ runtime.updateFZDDevStatusMoving(!noMove); //设置当前运动状态
+ ICLogger.i("checkNoMoveTimeout last_noMove "+last_noMove+" noMove "+noMove+ " lastStepCount "+runtime.getLastStepCount()+" StepCount "+runtime.getTotalStepCount());
+ if (last_noMove==false&& noMove==true){
+ first_NoMove_timestamp=System.currentTimeMillis();
+ }else if (noMove==false){
+ first_NoMove_timestamp=0;
+ }
+ last_noMove=noMove;
+ //属于 判断是否 不动的状态超时
+ if (noMove==true&& first_NoMove_timestamp>0.01 && System.currentTimeMillis()-first_NoMove_timestamp > MaxNoMoveTimeout){
+ ICLogger.i(" checkNoMoveTimeout true ");
+ return true;
+ }else{
+ ICLogger.i("checkNoMoveTimeout false");
+ return false;
+ }
+
+ }
+
+ private boolean needLocationForBT(){
+ updateStepCount();//update StepCount,保证每次定位前,计步数据是最新的。防止丢数据。
+ //如果没有动,且超时。则跳过定位
+ NoMoveTimeout=checkNoMoveTimeoutForBT();
+ ICLogger.i("BT NoMoveTimeout "+NoMoveTimeout+", forceLocation="+forceLocation+", Config.forceMoveCheck="+Config.forceMoveCheck+", skipMoveCheck="+skipMoveCheck);
+
+ // 不强制定位 且 (WorkingMod 不是紧急模式 或者 强制进行移动检测),且 没有移动过
+ if ( ( forceLocation != 1 ) &&
+ (Config.forceMoveCheck==true) &&
+ (NoMoveTimeout) && (skipMoveCheck ==false )){
+ ICLogger.i("No Move ,skip BT location!");
+
+ return false;
+ }
+ //以目前逻辑,每次检测必然跟随蓝牙扫描,因此可以在此直接更新上一次的计步次数,配合下次的运动检测
+ runtime.setLastStepCountForBT(runtime.getTotalStepCount());
+ return true;
+ }
+
+ private boolean needLocation(){
+ updateStepCount();//update StepCount,保证每次定位前,计步数据是最新的。防止丢数据。
+ //如果没有动,且超时。则跳过定位
+ NoMoveTimeout=checkNoMoveTimeout();
+ ICLogger.i(" NoMoveTimeout "+NoMoveTimeout+", forceLocation="+forceLocation+", Config.forceMoveCheck="+Config.forceMoveCheck+", skipMoveCheck="+skipMoveCheck);
+
+ // 不强制定位 且 (WorkingMod 不是紧急模式 或者 强制进行移动检测),且 没有移动过
+ if ( ( forceLocation != 1 ) &&
+ (Config.forceMoveCheck==true) &&
+ (NoMoveTimeout) && (skipMoveCheck ==false )){
+ ICLogger.i("No Move ,skip BT location2!");
+
+ return false;
+ }
+ //只做正常定位前是否运动的判断,给定位前蓝牙扫描专用的。和 NeedlocationFotBT 还不同。
+ return true;
+ }
+ public void startLocationProcess(int mod){
+ updateStepCount();//update StepCount,保证每次定位前,计步数据是最新的。防止丢数据。
+ ICLogger.i("forceLocation="+forceLocation+", WorkingMod="+mod+", isLocating="+isLocating+", lastStep="+runtime.getLastStepCount()+", currentStep="+ runtime.getTotalStepCount());
+ if (isLocating && 1!=forceLocation) { //如果是强制定位,则即使是正在定位,也要执行,因为有时模式变换的时候,需要取消上一次定位信息,马上新的模式定位。
+ ICLogger.i("locating ,skip location!");
+ return;
+ }
+ //如果没有动,且超时。则跳过定位
+ NoMoveTimeout=checkNoMoveTimeout();
+ // 不强制定位 且 (WorkingMod 不是紧急模式 或者 强制进行移动检测),且 没有移动过
+ if ( ( forceLocation != 1 ) &&
+ ((( mod == ICLocation.NORMAL_MOD ) || ( mod == ICLocation.LOWPOWER_MOD ) || (mod == ICLocation.CUSTOM_MOD8_WIFI ) ) || Config.forceMoveCheck==true) &&
+ (NoMoveTimeout) && (skipMoveCheck ==false )){
+ ICLogger.i("No Move ,skip location!");
+ return ;
+ }
+
+ if (NoMoveTimeout){
+// 记录gps 无信号或者timeout的次数,超过5 就会停止使用gps定位,只要有一次 移动,或者设置为wifi定位,则清零。
+ if (gpsTimeoutCountOnNoMove>= MaxGpsTimeoutCountOnNoMove){
+ NoMoveAndNoGPSsignalSkipGpsFlag=true;
+ }else{
+ NoMoveAndNoGPSsignalSkipGpsFlag=false;
+ }
+
+ }else{
+ NoMoveAndNoGPSsignalSkipGpsFlag=false;
+ gpsTimeoutCountOnNoMove=0; //只要有一次 移动,则清零。
+ }
+
+ forceLocation=0;
+ isLocating=true;
+
+ //如果不动且超时,则意味着要进行定位,更新计步,配合下一次运动检查。
+ runtime.setLastStepCount(runtime.getTotalStepCount());
+ updateCellInfo();
+ if(!Config.disableWiFiScan) startWifiScan();
+ switch(mod){
+ case ICLocation.CUSTOM_MOD:
+ case ICLocation.CUSTOM_MOD8_GPS:
+ if (NoMoveAndNoGPSsignalSkipGpsFlag==false) {
+ if (runtime.getLocationInstance().getLocation_cycle() <= 60) {
+ nmeaListener.setNoStop(true);
+ } else {
+ nmeaListener.setNoStop(false);
+ }
+ startGpsLocate();
+ }else{
+ clearGPSlocateStat(); //如果wifi优先,则确保gps关闭,防止切换回来gps状态错误,尤其是不NoStop模式下的gps切换回来有此风险。
+ }
+ break;
+ case ICLocation.EMERGNECY_MOD:
+ case ICLocation.REALTIME_MOD:
+
+
+ if(NoMoveAndNoGPSsignalSkipGpsFlag==false) {
+ nmeaListener.setNoStop(true);
+// nmeaListener.setNoStop(false);//保证从Custom切换回来的时候不至于不关闭gps
+ startGpsLocate();
+ }else{
+ clearGPSlocateStat(); //确保gps关闭,防止切换回来gps状态错误,尤其是不NoStop模式下的gps切换回来有此风险。
+ }
+
+ break;
+ case ICLocation.LOWPOWER_MOD:
+ case ICLocation.NORMAL_MOD:
+ case ICLocation.CUSTOM_MOD8_WIFI:
+ default:
+ gpsTimeoutCountOnNoMove=0; //只要有一次不是GPS定位,则清零。
+ clearGPSlocateStat(); //如果wifi优先,则确保gps关闭,防止切换回来gps状态错误,尤其是不NoStop模式下的gps切换回来有此风险。
+ break;
+ }
+ startCheckResult();
+ }
+
+ public static void setForceLocation(int _forcelocation){
+ forceLocation=_forcelocation;
+ }
+ private static int forceLocation=0;
+ public void onReceive(StringMessage paramStringMessage) {
+
+ ICLogger.i("LocationClient onReceive " +paramStringMessage.cmd() );
+// Deliver.triggerSendThread();
+ //响应定位指令
+ if ("StartLocate".equals(paramStringMessage.cmd()) ){
+ forceLocation=1;
+ this.startLocationProcess(runtime.getLocationInstance().getWorkingMod());
+ }else if ("setWorkMod".equals(paramStringMessage.cmd())) {
+ //此处不负责给工作模式赋值,在API接收的位置能够直接拿到变量,可以直接赋值较方便。
+ int mod = runtime.getLocationInstance().getWorkingMod();
+ ICLogger.i("Set WorkMODE "+mod +" and reset Location AlarmCycle");
+ CoreService.getInstance().setLocationAlarm(mod); //默认设置好Alarm后会触发一次定位,无需后面再触发定位了。
+ forceLocation=1; //不管是什么模式,都强制定位一次,然后再说其他情况
+
+ if(mod==ICLocation.EMERGNECY_MOD)
+ CoreService.getInstance().setEmegencyLocationSTOPAlarm(5);//Emergency模式5分钟自动停止
+// this.startLocationProcess(mod);
+
+ }
+ }
+ private static String ACTION_GPSCMD="com.enqualcomm.support.gps";
+ public void registerBroadReceiver() {
+
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(ACTION_GPSCMD);
+ (this.runtime.getContextProxy()).context.registerReceiver(this.mLocationBroadcastReceiver, intentFilter);
+ }
+
+ public void unregisterBroadReceiver() {
+ (this.runtime.getContextProxy()).context.unregisterReceiver(this.mLocationBroadcastReceiver);
+ }
+
+ private final BroadcastReceiver mLocationBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (ACTION_GPSCMD.equals(action)) { //此消息来自工厂测试工具,测试GPS时会发送。
+ String status = intent.getStringExtra("status");
+ if( status.equals("needReopen")){
+ runtime.setFactoryTestingStat(true);
+ }
+ }
+ }
+ };
+
+ public void init() {
+
+ this.mSignalUtil = SimSignalUtil.getInstance((runtime.getContextProxy()).context);
+
+ //获取LBS定位服务
+ this.mLbsHelper = runtime.getLbsHelper();
+//
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append("LOCATION_MODE=");
+ stringBuilder.append(runtime.getLocationInstance().getWorkingMod());
+ stringBuilder.append("LOCATION_CYCLE=");
+ stringBuilder.append(runtime.getLocationInstance().getLocation_cycle());
+ ICLogger.i(stringBuilder.toString());
+
+
+ /*注册 亮屏监控*/
+// IntentFilter intentFilter = new IntentFilter();
+// intentFilter.addAction("android.intent.action.SCREEN_ON");
+// (runtime.getContextProxy()).context.registerReceiver(this.screenOnReceiver, intentFilter);
+
+ registerBroadReceiver();
+
+
+ //暂时没有处理4G、2G切换问题
+// this.haveChanegTo4GTime = SystemClock.elapsedRealtime();
+ }
+
+ public void deinit() {
+
+ ICLogger.i("GPS deinit!");
+// (runtime.getContextProxy()).context.unregisterReceiver(this.screenOnReceiver);
+// mLbsHelper.unRegisterWiFiBroadReceiver();
+// this.executor.execute(new Runnable() {
+// public void run() {
+// Deliver.saveQueue();
+// }
+// });
+ stopGpsLocate();
+ unregisterBroadReceiver();
+ }
+
+
+
+
+
+ private void notifiSetAirModeMethod() { (new Thread(new Runnable() {
+ public void run() {
+ SystemClock.sleep(3000L);
+ boolean bool = mSignalUtil.IsAirModeOn();
+ byte b = 1;
+ if (bool != true)
+ b = 0;
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append("AirMode==");
+ stringBuilder.append(b);
+ ICLogger.i(stringBuilder.toString());
+
+ }
+ })).start(); }
+
+
+ // 飞行模式 1 开启 0 关闭
+ public void setAirMode(int paramInt) {
+ boolean isAirModeOn = this.mSignalUtil.IsAirModeOn();
+ boolean isScreenOn = this.mSignalUtil.isScreenON(runtime.getContextProxy().context);
+ switch (paramInt) {
+
+ case 1:
+ if (!isAirModeOn && !isScreenOn) {
+ // this.mSignalUtil.setAirMode("OpenAirplane");
+ runtime.isAirMode = true;
+ notifiSetAirModeMethod();
+
+ }
+
+ break;
+ case 0:
+
+ if (isAirModeOn) {
+ //this.mSignalUtil.setAirMode("CloseAirplane");
+ runtime.isAirMode = false;
+ notifiSetAirModeMethod();
+ return;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ }
+
+}
+