/**
 * 
 */
package com.qiyou.mb.android;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;

import android.Manifest;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.Application;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Point;
import android.location.Location;
import android.location.LocationManager;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.support.v4.content.ContextCompat;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
  
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.model.inner.GeoPoint;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult.AddressComponent;
import com.facebook.android.crypto.keychain.SharedPrefsBackedKeyChain;
import com.facebook.crypto.Crypto;
import com.facebook.crypto.Entity;
import com.facebook.crypto.util.SystemNativeCryptoLibrary;
import com.google.gson.JsonSyntaxException;
import com.iflytek.speech.ErrorCode;
import com.iflytek.speech.ISpeechModule;
import com.iflytek.speech.InitListener;
import com.iflytek.speech.SpeechConstant;
import com.iflytek.speech.SpeechSynthesizer;
import com.iflytek.speech.SpeechUtility;
import com.iflytek.speech.SynthesizerListener;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import com.loopj.android.http.ResponseHandlerInterface;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.qiyou.mb.android.beans.Statistics;
import com.qiyou.mb.android.beans.Track;
import com.qiyou.mb.android.beans.User;
import com.qiyou.mb.android.beans.basic.GEOaddress;
import com.qiyou.mb.android.beans.basic.GEOs;
import com.qiyou.mb.android.beans.basic.GPItem;
import com.qiyou.mb.android.beans.basic.StatTrack;
import com.qiyou.mb.android.beans.basic.Statics_bean;
import com.qiyou.mb.android.beans.basic.TypeStatistics;
import com.qiyou.mb.android.beans.basic.User_bean;
import com.qiyou.mb.android.service.BDLocationSvc;
import com.qiyou.mb.android.service.LocationService2;
import com.qiyou.mb.android.service.QNaviSvc;
import com.qiyou.mb.android.service.TimtickService;
import com.qiyou.mb.android.service.TrackDbServiceBackground;
import com.qiyou.mb.android.service.TrackGEOService;
import com.qiyou.mb.android.service.TrackPlaybackService;
import com.qiyou.mb.android.service.sync;
import com.qiyou.mb.android.utils.FileUtil;
import com.qiyou.mb.android.utils.TrackCache;
import com.qiyou.mb.android.utils.Utils;
import com.qiyou.mb.android.utils.enums.TrackStatus;
import com.qiyou.mb.android.utils.enums.TrackType;
import com.qiyou.mb.android.utils.log.QLog;
import com.umeng.analytics.MobclickAgent;
import com.umeng.message.PushAgent;
import com.umeng.message.IUmengRegisterCallback;
import com.umeng.message.UTrack;
import com.umeng.message.ALIAS_TYPE;
//import com.qiyou.mb.android.service.TrackDbService;
 
 public class QiYouApplication extends Application {
 public static String TAG="com.qiyou.QiYouApplication";
 public static final String dTAG ="com.qiyou";
	  
 public User user=new User();	  
 private static QiYouApplication mInstance = null;
 public boolean m_bKeyRight = true;
 /*
  * when UI is active, send, else not send
  */
 public boolean canSendLocation2UI; 
 public boolean isUIactive;
 public String currentActiveFragment;
 public boolean isStaticsticsDone=true;
 // public HashMap<Integer,TypeStatistics> StatisticsTracks;
// public SparseArray<TypeStatistics> StatisticsTracks;
// public  List<CItem > typeUsedLst; 
 public boolean statTrackLoading=false;
 
 public Statistics mStatistics;
 
// public boolean isGetingStatistics=false;
// public ConcurrentHashMap<Integer,Track> tracks_cached;
// public  HashMap<Integer,Track> tracks_cached;
 public ConcurrentHashMap<Integer,String> tracks_json_cached;
 public ConcurrentHashMap<Integer,Location> location_cached;
 public GEOs geos = new GEOs(); 
 public Track currentTrack;
 public Track recordingTrack; 
 public Track gpxTrack;
// public Track naviTrack;
 public int naviTrackId;
 public boolean isNaving=false;
 public boolean isNavPaused=false;
 private ArrayList<Track> importedGpx; 
 public ArrayList<Location> toDecideLocations;
// public Track copyTrack; 
// private StatTrack statTrack; 
// public double sumDiff=0; //TODO: remove
// public double sumDiff2=0; //TODO: remove
 public Location lastSavedLocation; 
 public Location lastNaviLocation;
 public Location lastLocation;
 public Location lastBearLoc;
 public HashMap<Long,Float[]> bearLocs = new HashMap<Long,Float[]>();
 public HashMap<Long,Location> sumBearLocs = new HashMap<Long,Location>();
// public long lastBearLoc;
 public float sumBear;
 public float sumBear2;
 public int   cntBear;
 public int   cntBeared;
 public long lastSumbear;
 public float bearDist;
 public float targetBear;
// private int cntKm;
 public long timeKm;
 public long lastPaused;
 public long sumPaused;
 public long lastOfftime;
 
 //---share location
 public long lastSharedTime;

 public float rd =1000f; //used in route_fragment for checkWps
 
 public boolean isNewLogin=false;
public boolean isRouting;
 
 /*
  * offtime will be reset to 0 after each forceupdate
  */
 public long offtime;
 /*
  * total sum offtime since the time when lost gps, recorded in the waypoint. it will not be reset by forceupdate.
  */
 public long sumOfftimeWp;   
 public double sumDist;
 public double sumNavDist;
// public double sumDist2;
 public float SpDist;
 public float locDist;
// public float sumSpeed;
// public int spdCnt=0;
 public float lastEle=QiYouConstant.MAX_ELE;
 public ArrayList<Float>  eles =new  ArrayList<Float> ();
 /*
  * 坡度数据
  */
 public float maxEle = QiYouConstant.MAX_ELE*-1;
 public float minEle =QiYouConstant.MAX_ELE ;
 public float upDist;
 public float downDist;
 
 
 
 /*
  * when gps code start,wp count to skip for ele calculation.
  */
 public int skipCnt=0;
 public boolean plCanRecord= false;
 public boolean playBack= false;
 public boolean playBackStopped= false;
 public boolean playbackPaused= false;
 public int playBackTrackId =0;
 public int playProgressTarget =-1;
 
 
// public String userName;
 public boolean isOneRequestForceUpdate;
 public boolean isGPSstopped =false;
 public long minTime= 0;
 public long gpsStartTime;
 public long lastGpsStartTime;
 public long lastGpsStopTime;
 public long lastLocationTime;
 
 public int GPS_SPAN_FACTOR=1;
// public long lastGPStime; //last gps locaiton time that showing in updateUI function.
// public String City;
 SharedPreferences  pref;
 Editor  pe;
 Editor pEditor ;
 
/* MKSearch*/ GeoCoder mSearch ;
 
// public Point screenSize;
 
// public SensorManager sm = null;
// public Sensor mAccelerometer = null;

// public boolean isProcessingGEO =false; //last time receiving an new connected wifi network.
/*
  * 是不是正在记录骑行/运动轨迹数据
  */
 public static boolean isRecording =false; 
 private BMapManager mBMapManager = null;
public SharedPreferences settings  ;
 //preference
public long startTime;

public LocationManager lm;
PendingIntent locationListenerPendingIntent;
//PendingIntent netwrokLocationListenerPendingIntent;
//public MapView mMapview;
public LocationClient mLocClient;
public BDLocationListener bdListener;
private GEOaddress GEOinfo;
//TimeTickReceiver timeTickReceiver;
Intent timeTickIntent; 
private HttpClient mHttpClient = null;
private static final String CHARSET = HTTP.UTF_8;


private HashMap<Integer,ArrayList<String>> newCategoryList;
private HashMap<Integer,ArrayList<String>> delCategoryList;
private  ArrayList<String> queryCategoryList;

private TrackCache trackCache = new TrackCache();

//public long lastCheckNaviPoint=0;
//public boolean isWrongWayAlert;

private ConcurrentHashMap<String,Object> webObjcache;


	public QiYouApplication() {
		// TODO Auto-generated constructor stub
		
//		 initSdPath();
	}
	/*
	 * 
	 */
	@Override
	public final void onCreate()
	{  
		
		//TODO: as the Application.onCreate() called muiti times during the application running,
		//so need review the functions it espected to call for create only once.
		if(mInstance!=null){
			Log.d(dTAG, TAG+"The Application OnCreate was called already.");
//			Utils.logStackTrace(new Exception("The Application OnCreate was called already."),dTAG);
			return;
			}
//		 initSdPath(); why it is after the trackprovider?
		super.onCreate();
		startTime =System.currentTimeMillis();
		
//		Utils.logStackTrace(new Exception("The Application OnCreate."),dTAG);
//		Utils.logStackTrace(new Exception("Log.e test on onCreate(),Application Started.  time: " + startTime),dTAG);
//		Log.v(dTAG, TAG+" is developer model? " +QiYouConstant.DEVELOPER_MODE); 
		 initialApplication();
//		 QLog.getLogger().d(dTAG,TAG+" onCreate(),Application Started. cost time: " + (System.currentTimeMillis() - startTime));
		     
//		  getCurrentCity();
	}
	
  void initialApplication()
	{
	
		Intent locIntent = new Intent(QiYouConstant.ACTION_NEW_LOCATION_CHANGED);		    
		locationListenerPendingIntent = PendingIntent.getBroadcast(this, 0, locIntent, PendingIntent.FLAG_UPDATE_CURRENT); 
//	    GPSwarmup();  
		 
//		Intent networkLocIntent = new Intent(QiYouConstant.ACTION_NEW_COARSE_LOCATION);  
//		netwrokLocationListenerPendingIntent = PendingIntent.getBroadcast(this, 0, networkLocIntent, PendingIntent.FLAG_UPDATE_CURRENT);
		 
//	   tracks_cached = new ConcurrentHashMap<Integer,Track>();
	   settings = PreferenceManager.getDefaultSharedPreferences(this);
	   pEditor =settings.edit(); 
	   getPreferences();	
	   initClient(this);
	   setAuth();
	   QiYouConstant.NETWORK_CONNECTED =Utils.isNetworkConnected(this);   
	   initialShowingGpxs();
	   worksOnLine(0);	 
	   
		 setPreferences(false,true);
		 locationAm=(AlarmManager)getSystemService(ALARM_SERVICE);	 
		 lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);	 
		
		 
		   mInstance = this;
		   initEngineManager(this);
		   
		   pref = getSharedPreferences(QiYouConstant.SHARED_PREFERENCE_FILE, Context.MODE_PRIVATE); 
		   pe= pref.edit(); 
		   
		   
		   //check last track status
//		   QLog.getLogger().d(dTAG,TAG+"  start to check last track status,it may at Andorid's startup. " );
//		   Intent serviceIntent = new Intent(this, LocationService.class); 
//	       serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_BOOT, "True");
//	       this.startService(serviceIntent);  
	       
 			 if (QiYouConstant.DEVELOPER_MODE) {
//			      IStrictMode strictMode =  PlatformSpecificImplementationFactory.getStrictMode();
//			      if (strictMode != null)
//			    	  strictMode.enableStrictMode();
 			    }
 			 
// 		    timeTickReceiver =new TimeTickReceiver();
 			timeTickIntent = new Intent(this, TimtickService.class);	 
 			regTimeTick();
// 			sm = (SensorManager)getSystemService(SENSOR_SERVICE); 
// 			mAccelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
 			 initialSpeech();
 			 
 			initCryto();
 			
 			setPhoneId();
 			QLog.getLogger().d(dTAG, "mobileid is"+ getPhoneId());
 			getStaticsTracks();

			initialPushSDK();

	}

	 void initialPushSDK(){
		 PushAgent mPushAgent = PushAgent.getInstance(this);
//注册推送服务，每次调用register方法都会回调该接口
		 mPushAgent.register(new IUmengRegisterCallback() {

			 @Override
			 public void onSuccess(String deviceToken) {
				 //注册成功会返回device token
				 QLog.getLogger().d(dTAG, " deviceToken of push is "+ deviceToken);
			 }

			 @Override
			 public void onFailure(String s, String s1) {
				 QLog.getLogger().d(dTAG, " push agent regist failed ");
			 }
		 });

	 }
 public Crypto crypto;
 public Entity entity;
  private void initCryto(){
		  crypto = new Crypto(
		    	  new SharedPrefsBackedKeyChain(this),
		    	  new SystemNativeCryptoLibrary());
		  entity = new Entity("TEST");
  }
  
  
/*	private void initSdPath(){
		Utils.initSdPath(this);
	}*/
	public void initEngineManager(Context context) {
       /* if (getmBMapManager() == null) {
            setmBMapManager(new BMapManager(context));
        }

//        if (!getmBMapManager().init(QiYouConstant.BAIDU_API_KEY,new MyGeneralListener())) {
        if (!getmBMapManager().init(new MyGeneralListener())) { //v3.4.1
        	
            Toast.makeText(QiYouApplication.getInstance().getApplicationContext(), 
                    "BMapManager  初始化错误!", Toast.LENGTH_LONG).show();
        }*/
      /* if(mSearch ==null){
    	   mSearch= GeoCoder.newInstance();
    	   mSearch.setOnGetGeoCodeResultListener(new MySearchListener());
       }*/
		
		SDKInitializer.initialize(this);
		
		
		// 注册 SDK 广播监听者
				IntentFilter iFilter = new IntentFilter();
				iFilter.addAction(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_OK);
				iFilter.addAction(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR);
				iFilter.addAction(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR);
				mReceiver = new SDKReceiver();
				registerReceiver(mReceiver, iFilter);
				
	}
	
	public static QiYouApplication getInstance() {
		return mInstance;
	}
	
	
	public BMapManager getmBMapManager() {
		return mBMapManager;
	}
	public void setmBMapManager(BMapManager mBMapManager) {
		this.mBMapManager = mBMapManager;
	}

	/**
	 * 构造广播监听类，监听 SDK key 验证以及网络异常广播
	 */
	public class SDKReceiver extends BroadcastReceiver {
		public void onReceive(Context context, Intent intent) {
			String s = intent.getAction(); 
 			 
			if (s.equals(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR)) {
				QLog.getLogger().d(dTAG,"key 验证出错! 请在 AndroidManifest.xml 文件中检查 key 设置");
			} else if (s
                    .equals(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_OK)) {
				QLog.getLogger().d(dTAG,"key 验证成功! 功能可以正常使用");
			     
			}
			else if (s
					.equals(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR)) {
				QLog.getLogger().d(dTAG,"网络出错");
			}
		}
	}

    private SDKReceiver mReceiver; 
    
    public Track getCurrentTrack() {
    	if(null == currentTrack) currentTrack = new Track();
   	return currentTrack;
   }
    
    /*
     *set the gloable current track object, usually it is from db query.
     *put it into the track cache too.
     */
    public void setCurrentTrack(Track _currentTrack) {
    	setCurrentTrack(_currentTrack,false);
	}
    
    public void setCurrentTrack(Track _currentTrack,boolean isWebQuery) { 
    	currentTrack = _currentTrack;	 
    	if(_currentTrack==null)return;
		currentTrackId =isWebQuery?_currentTrack.getTrackBean().getSvrNumber():_currentTrack.getTrackBean().getTrackId();
	    //check if the track object has been in the cache,if yes, then update the cache, if not then add it into the cache.
		if(currentTrackId <=0) return; 
		 getTrackCache().put(currentTrackId,_currentTrack);
//		 getTrackCache().putIfAbsent(_currentTrack.getTrackBean().getTrackId(),_currentTrack);
//		 getTrackJsoncache().put(_currentTrack.getTrackBean().getTrackId(), _currentTrack.getJsonWps().toString());	
//		 if(tracks_cached.size()>10)
//		 {
////			 getTrackCache()
////			 getTrackJsoncache()
//			//TODO: remove old values for the size limit to save memory.
//		 } 
    }
    public long getGPS_REQUEST_SPAN(){
    	return GPS_SPAN_FACTOR*QiYouConstant.MAX_GPS_SPAN;
    }
    
    /*
     * is lost gps signal or not for a tracking record
     */
   public boolean isLostGps(){	   
//	   if(pref!=null){
//		   lastOfftime =lastOfftime>0?lastOfftime: pref.getLong(QiYouConstant.PK_LAST_OFFTIME, 0);
////		   lastLocationTime = lastLocationTime>0?lastLocationTime: pref.getLong("lastLocationTime", 0);
//	   } 
//	   lastLocationTime =lastLocation!=null?lastLocation.getTime():lastLocationTime;
	   lastLocationTime=lastLocationTime >0?lastLocationTime:
		   				lastLocation!=null?lastLocation.getTime():0;
	  
//		QLog.getLogger().dLog( TAG, "   isLostGps(), System.currentTimeMillis() - app.lastLocationTime:" + String.valueOf(System.currentTimeMillis() -  lastLocationTime  ) +
//			  ",MAX_GPS_OFF_TIME*3 is "+ QiYouConstant.MAX_GPS_OFF_TIME*3 +",lastOfftime:" +lastOfftime);
	  
   				
		   				
	   return  lastOfftime > 0 
			   ||  System.currentTimeMillis()-lastLocationTime > QiYouConstant.MAX_GPS_OFF_TIME*3; //no gps or speed is zeo for long time
   }

  public boolean isNotMoving(){
	  
	 /* if(lastSavedLocation!=null)
	  QLog.getLogger().dLog( TAG,"  check if it isNotMoving(), System.currentTimeMillis() - app.lastSavedLocation:" 
			  					+ String.valueOf(System.currentTimeMillis() -  lastSavedLocation.getTime()  ) +
			  ",get_updatedb_invterval is "+ Utils.get_updatedb_invterval(TrackType.valueOf(getLastTracktype()) ));*/
	 boolean isNotMoving =
			 lastSavedLocation!=null &&(System.currentTimeMillis() - lastSavedLocation.getTime())
    		>Utils.get_updatedb_invterval(TrackType.valueOf(getLastTracktype()))*2;
    		
     if(isNotMoving){
/*    	 if((GPS_SPAN_FACTOR+1)*QiYouConstant.MAX_GPS_SPAN<30*1000)  //gps interval should small than 1 minute. //changed to 20 seconds 2015.06.26
//    	 if((GPS_SPAN_FACTOR+1)*QiYouConstant.MAX_GPS_SPAN<10*1000) 
    		 GPS_SPAN_FACTOR++;*/
    	  // QLog.getLogger().dLog(dTAG, TAG + " >>>>>>>>>>>>>>>>>it is not moving...............................");

    	 GPS_SPAN_FACTOR++; 
    	 
    	 if(isLostGps()){
    		 
    		 if((GPS_SPAN_FACTOR+1)*QiYouConstant.MAX_GPS_SPAN>20*1000){    	 
    			 GPS_SPAN_FACTOR=1;
    		 }  
    		 
    	 }else{ 
    		 
    		 if((GPS_SPAN_FACTOR+1)*QiYouConstant.MAX_GPS_SPAN>8*1000){
        		 GPS_SPAN_FACTOR=1;
        	 }
    	 }
    	 /*
    	 if((GPS_SPAN_FACTOR+1)*QiYouConstant.MAX_GPS_SPAN>15*1000){
    		 GPS_SPAN_FACTOR=1;
    	 }*/
     }else{
    	 GPS_SPAN_FACTOR=1; 
     }
    	 
     // QLog.getLogger().dLog( TAG	, " TimtickService GPS_SPAN_FACTOR*gps_span is  "+GPS_SPAN_FACTOR*QiYouConstant.MAX_GPS_SPAN );

    return isNotMoving;
  
  }
   
   
//	public ConcurrentHashMap<Integer,Track> getTrackCache() {
//		if (tracks_cached == null) tracks_cached = new ConcurrentHashMap<Integer,Track>();
//		return tracks_cached;
//	}
	
	
	public TrackCache getTrackCache() {
		return trackCache;
}
  
	/*public void initMapview(Activity activity){
		mMapview =new MapView(activity);
		
	}*/
//	
//	public  HashMap<Integer,Track> getTrackCache() {
//		if (tracks_cached == null) tracks_cached = new  HashMap<Integer,Track>();
//		return tracks_cached;
//	}
	
	
	//  trackId,wpsJson 
	
	public ConcurrentHashMap<Integer,String> getTrackJsoncache() {
		if(tracks_json_cached == null) tracks_json_cached = new ConcurrentHashMap<Integer,String>();
		return tracks_json_cached;
	}
	public Track getRecordingTrack() {
		if(null == recordingTrack) recordingTrack = new Track();
		return recordingTrack;
	}
	
	public void setRecordingTrack(Track recordingTrack) {
		this.recordingTrack = recordingTrack;
	}
	
	public Track getGpxTrack() {
		if(null == gpxTrack){
			gpxTrack = new Track();
			gpxTrack.getTrackBean().setType(TrackType.GPX);
		}
		
		return gpxTrack;
	}
	
	public void setGpxTrack(Track track) {
		 gpxTrack = track;
	}   
	public ArrayList<Track> getImportedGpx() {
		if(importedGpx==null)importedGpx =new ArrayList<Track>();
		return importedGpx;
	}
	public void initialImportedGpx() {
		 importedGpx =new ArrayList<Track>(); 
	}
	
	public ArrayList<String>  getImportedGpxFileList(){

	 	 TypeStatistics st =  getTracksStat(TrackType.GPX.toInt(),0,0);
		 ArrayList<String> srcs = new ArrayList<String>(); 
		 ConcurrentHashMap<Integer, Statics_bean> sbs =st.getSbs(); 
		 for(Integer key :sbs.keySet()) {
			 if(!srcs.contains(sbs.get(key).getSrc()))
				 srcs.add(sbs.get(key).getSrc());
			 // QLog.getLogger().d(TAG," get imported SRC list:" +sbs.get(key).getSrc());
        }
		 return srcs;
	}
	
//	public boolean impGpx(String gpxfileName){
	 public boolean impGpx(){
		
/* 	 importedGpx =getImportedGpx();
//	 importedGpx =new ArrayList<Track>();// initial the imported list for each import. so that the list contains the latest imported gpx tracks.
	 importedGpx.add(Track.newInstance(gpxfileName));	*/
	 
	 if (importedGpx.size()==0) return false; 
	 
	 Intent serviceIntent = new Intent(this, TrackDbServiceBackground.class);
     serviceIntent.putExtra(QiYouConstant.NEW_GPX_TRACK,"");
     startService(serviceIntent);
     return true;
	}
     
     
//	public Track getCopyTrack() {
//		if(null == copyTrack) copyTrack = new Track();
//		return copyTrack;
//	}
//	public void setCopyTrack(Track copyTrack) {
//		this.copyTrack = copyTrack;
//	}
	public ConcurrentHashMap<Integer,Location> getLocationCached() {
		if(location_cached == null) location_cached = new ConcurrentHashMap<Integer,Location>();
		return location_cached;
	}
	public void setLocationCached(ConcurrentHashMap<Integer,Location> location_cached) {
		this.location_cached = location_cached;
	}
	  
	
	public void  GPSwarmup()
	{	
	     Intent testIntent = new Intent("testAction"); 
		 PendingIntent testpIntent = PendingIntent.getBroadcast(this, 0, testIntent, PendingIntent.FLAG_UPDATE_CURRENT); 
		 if(lm==null){
				lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);	 
			}
		//lm.requestSingleUpdate(LocationManager.GPS_PROVIDER, locationListenerPendingIntent) ;
		lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,0,   testpIntent);	
//		lm.requestSingleUpdate(LocationManager.GPS_PROVIDER, testpIntent);
//		lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000,0,   locationListenerPendingIntent);		
		lm.removeUpdates(testpIntent); 
//		QLog.getLogger().d(dTAG,TAG+" "+ "ggGPSwarmup."); 
		 
	}
	
	
	 
	public void startAndroidGPSRequest()
	{	 
/*		if(getRecordingTrack().getTrackBean().getStatus() == QiYouConstant.TRACK_STATUS_PAUSED) return;
		
		startNetworkLocationRequest(false);//先开启网络定位,收到gps信号后姜自动关闭网络定位
	   
//		if(!getGpsState(this));
//		{
//			//TODO: let user to toggle the GPS on.
//		}
		if(lm==null)lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
//		canRecord =true;
		lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, QiYouConstant.MAX_GPS_SPAN*GPS_SPAN_FACTOR,0,   locationListenerPendingIntent);
		isGPSstopped =false;
		lastGpsStopTime=0;
		lastGpsStartTime = System.currentTimeMillis();
		QLog.getLogger().d(dTAG,TAG+" TimtickService startAndroidGPSRequest"); */
		
		
		 if(getRecordingTrack().getTrackBean().getStatus() == TrackStatus.PAUSED) return;
		  String  key = QiYouConstant.EXTRA_KEY_START_GPS;		 
	       Intent serviceIntent = new Intent(this, TimtickService.class); 
	       serviceIntent.putExtra(key, true);
	       startService(serviceIntent);
	}
	

	public void stopAndroidGPSRequest(){
 
/*		if(lm!=null){
				lm.removeUpdates(locationListenerPendingIntent); 
//				 Log.i(dTAG,TAG + " stopped gps request ");	
			}
		isGPSstopped =true;
		lastGpsStartTime =0;
		lastGpsStopTime =System.currentTimeMillis();
//		this.canRecord =!this.playBack;
		if(!canRecord())cancelForceDbAlarm();
		  QLog.getLogger().d(dTAG,TAG+" TimtickService stopAndroidGPSRequest");
		  */
		
		  String  key = QiYouConstant.EXTRA_KEY_STOP_GPS;		 
	       Intent serviceIntent = new Intent(this, TimtickService.class); 
	       serviceIntent.putExtra(key, true);
	       startService(serviceIntent);
	}
	
	public boolean canRecord(){

		boolean canrec =this.getRecordingTrack().getTrackBean().getStatus() == TrackStatus.RECORDING;
		 canrec = canrec  ||  getRecordingTrack().getTrackBean().getStatus() == TrackStatus.PAUSED;
		 canrec =canrec && !playBack ;
		 canrec = canrec 
//				 && this.getRecordingTrack().getTrackBean().getType()!=QiYouConstant.TRACK_TYPE_COPY;
				 && getRecordingTrack().getTrackBean().getType()!=TrackType.COPY;
		 		 
//		 canrec = canrec  || QiYouConstant.PLAYBACK_CAN_RECORD;
//		 canrec = canrec  || QiYouConstant.DEVELOPER_MODE;
//		 canrec = canrec && isLastTrackExist();
		 return canrec;
	}
	
	public boolean canExit(){ 
		
	 return	recordingTrack ==null || recordingTrack.getTrackBean().getStatus()!= TrackStatus.RECORDING
			 ||recordingTrack.getTrackBean().getType() ==TrackType.COPY;
		 
	}

	 AlarmManager locationAm; 
	 PendingIntent amSender;
	public void forceDbUpdate(boolean isOneRequest){
		// Intent amIntent =new Intent( this,  LocationService.class);
		 Intent amIntent = new Intent(QiYouConstant.ACTION_NEW_FORCE_UPDATE);
//		 amIntent.setClassName("com.qiyou.mb.android.receivers", LocationChangesReceiver.class.getName());
	   // intent.setAction("repeating");  
		amIntent.putExtra(QiYouConstant.EXTRA_KEY_FORCE_UPDATE, true);
		amSender=PendingIntent.getBroadcast( this, 0,amIntent, PendingIntent.FLAG_UPDATE_CURRENT);
	     //开始时间
	    long firstime=SystemClock.elapsedRealtime();
	    
	   
//	    if(locationAm ==null)
//	    locationAm=(AlarmManager)getSystemService(ALARM_SERVICE);//60秒一个周期，不停的发送广播
//	    else  locationAm.cancel(amSender);
	    locationAm.cancel(amSender);
	   
//	     locationAm.setRepeating( AlarmManager.RTC_WAKEUP,System.currentTimeMillis()  +QiYouConstant.MAX_TIME_FORCE_UDATE, QiYouConstant.MAX_TIME_FORCE_UDATE, amSender);
//	    locationAm.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP , firstime+QiYouConstant.MAX_TIME_FORCE_UDATE, QiYouConstant.MAX_TIME_FORCE_UDATE, amSender);
	    locationAm.setRepeating(AlarmManager.RTC_WAKEUP , firstime+QiYouConstant.MAX_TIME_FORCE_UDATE, QiYouConstant.MAX_TIME_FORCE_UDATE, amSender);
//        locationAm.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP , firstime+5000, 30*1000, amSender);\
//	    QLog.getLogger().d(dTAG,TAG + String.format(" interval is %d, next time the forceupdate will be triggered is ",QiYouConstant.MAX_TIME_FORCE_UDATE)+ Utils.getTimeCnt((long) QiYouConstant.MAX_TIME_FORCE_UDATE  , true) );
	    // QLog.getLogger().dLog(TAG, " forceDbUpdate(), started, frequence is" +QiYouConstant.MAX_TIME_FORCE_UDATE);
//	    QLog.getLogger().d("Force_update", TAG +  " forceDbUpdate(), started.");
	    if(isOneRequest) {
	    	isOneRequestForceUpdate = isOneRequest;
	    	cancelForceDbAlarm();//locationAm.cancel(amSender);
	    }
	    
	 	}
	
	public void cancelForceDbAlarm()
	{
		if(locationAm!=null && amSender!=null)
			locationAm.cancel(amSender);
//		QLog.getLogger().d(dTAG,TAG+" "+ "cancelForceDbAlarm(), cancelled.");
		QLog.getLogger().dLog( TAG ,  " cancelForceDbAlarm(), cancelled.");
	}
	
      
		
      /* 
       *  
       * @param context 
       * @return true if enabled. 
       */   
//      private   boolean getGpsState(Context context) {    
//          return   lm.isProviderEnabled(LocationManager.GPS_PROVIDER);  
//      }  

      /** 
       * Toggles the state of GPS. 
       *  
       * @param context 
       */   
//      private void toggleGps(Context context) {  
//          ContentResolver resolver = context.getContentResolver();  
//          boolean enabled = getGpsState(context);  
//          Settings.Secure.putInt(resolver, LocationManager.GPS_PROVIDER,1  ) ;  
//      }
 
	public ArrayList<Float> getEles() {
		if(eles ==null) eles = new ArrayList<Float>();
		return eles;
	}
 
public void initialPlayBack(Integer trackId){ 
	playBack =true;
	playBackStopped =false; 
	 if(QiYouConstant.PLAYBACK_CAN_RECORD){
		 unregTimeTick(); 
		 stopAndroidGPSRequest(); 
	 }
	
	int currentId = currentTrack ==null?0:currentTrack.getTrackBean().getTrackId();
	
		if(currentId >0 && currentId != trackId){
				/*if( !tracks_cached.containsKey(trackId) ||
						tracks_cached.get(trackId).getTrackBean().getLastdbTime()
						< currentTrack.getTrackBean().getLastdbTime()
						){
						tracks_cached.put(currentId, currentTrack);
					}*/
			 Track tr=trackCache.get(Integer.valueOf(trackId));
			 if( tr==null||
					 tr.getTrackBean().getLastdbTime()
					< currentTrack.getTrackBean().getLastdbTime()
					){
				  trackCache.put(currentId, currentTrack);
				}
			
				this.currentTrack =null;  //current track is not the playback one, then set it to null.
				}
		 
		startPlayBackService(trackId);
		
	
	}
public void startPlayBackService(Integer trackId)
{ 
         Intent serviceIntent;
	     if(currentTrack == null){
	         serviceIntent = new Intent(this, TrackDbServiceBackground.class);	   
		 	 serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_GET_CURRENT_TRACK_BY_ID, trackId);	 	 	    	   
		 	 startService(serviceIntent);
	     }
	 	
	 	 serviceIntent = new Intent(this, TrackPlaybackService.class);	
		 serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_GET_CURRENT_TRACK_BY_ID, trackId);
		 startService(serviceIntent);
		 playBackTrackId =  trackId ;
		 // QLog.getLogger().d(dTAG,TAG+" "+ " playBackTrackId,trackId   "+ trackId );
}


public void getTrackById(Integer id){	
	 Intent  serviceIntent = new Intent(this, TrackDbServiceBackground.class);	   
 	 serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_GET_TRACK_BY_ID, id);	 	 	    	   
 	 startService(serviceIntent);
}

public void initialTrackParameters(){	 
	   
//    playBack=false;
//    QLog.getLogger().dLog(dTAG,TAG+" "+ "initialTrackParameters(), isPlayback: " +   playBack  ); 
    lastEle=88888f;
//    currentTrackId
    eles.clear();
    lastSharedTime =0;
    lastOfftime =0;
    lastPaused=0;
    sumDist=0;
    sumNavDist=0;
//    sumDist2=0;
    offtime=0;
    sumPaused=0;  
    sumOfftimeWp =0;
    minTime=0;
    locDist=0;
    SpDist=0; 
    lastLocation =null;
    lastBearLoc =null;
    lastSavedLocation=null;
    sumBear=0;
//    sumDiff2=0;
//    sumDiff=0;
    cntBear=0;
//    setCntKm(0);
    timeKm=0;
    bearDist=0;
    lastSumbear=0;
    lastGpsStartTime=0;
    lastGpsStopTime=0;
    bearLocs.clear();
    sumBearLocs.clear();
    targetBear=0f;
    cntBeared =0;
    getLocationCached().clear();
    lastLocationTime=0;
    gpsStartTime=0; 
    
    pe.putLong(QiYouConstant.PK_LONG_TRACK_MANULE_PAUSED, 0);  //总计手动暂停时长
    pe.putLong(QiYouConstant.PK_LONG_LAST_MANULE_PAUSED, 0);   //上次手动暂停时间戳
    pe.commit();
    toDecideLocations=null;
//    saveLocationParameters(true);  
    
    maxEle=QiYouConstant.MAX_ELE*-1;
    minEle=QiYouConstant.MAX_ELE ;
    upDist=0;
    downDist=0;
    
}
/*
 * isUpdate: true-->from pause to tracking
 */
public long getPausedTime(boolean isUpdate){
	if(isUpdate){
		updatePauseParameters();	
	}
	
	long sumPaused =pref.getLong(QiYouConstant.PK_LONG_TRACK_MANULE_PAUSED, 0);
//	QLog.getLogger().dLog(dTAG, TAG+" get totalTime,sumPaused: "+sumPaused+","+Utils.getFormatedTime(sumPaused)  ); 
	 
	
	return sumPaused;
	
}
/*
 * 
 * isNewPause
 * true: start new pause.
 * false: update pause starttime to now, and update the sum time of last paused period
 */
public void updatePauseParameters(){
	
	if(recordingTrack.getTrackBean().getTrackId()==0)return;
//	QLog.getLogger().dLog(dTAG, TAG+" get totalTime,sumPaused: "+sumPaused+","+Utils.getFormatedTime(sumPaused)  );
	restartPause();
/*
	long lastPaused =pref.getLong(QiYouConstant.PK_LONG_LAST_MANULE_PAUSED, 0);//last time paused.
	
/*	if(isNewPause){
		pe.putLong(QiYouConstant.PK_LONG_LAST_MANULE_PAUSED, System.currentTimeMillis());   //上次手动暂停时间戳
		
	}else{
		 
//		if(lastPaused==0){
//			pe.putLong(QiYouConstant.PK_LONG_LAST_MANULE_PAUSED, System.currentTimeMillis());
//		}else{
//			long sumPaused=getPausedTime(false)+System.currentTimeMillis() -lastPaused;
//			pe.putLong(QiYouConstant.PK_LONG_TRACK_MANULE_PAUSED, sumPaused);
//		}
		
		if(lastPaused>0){ 
			long sumPaused=getPausedTime(false)+System.currentTimeMillis() -lastPaused;
			pe.putLong(QiYouConstant.PK_LONG_TRACK_MANULE_PAUSED, sumPaused);
		}
		pe.putLong(QiYouConstant.PK_LONG_LAST_MANULE_PAUSED, System.currentTimeMillis());
		
	}*/
	
	/*if(lastPaused>0){ 
		long sumPaused=getPausedTime(false)+System.currentTimeMillis() -lastPaused;
		pe.putLong(QiYouConstant.PK_LONG_TRACK_MANULE_PAUSED, sumPaused);
	}
	pe.putLong(QiYouConstant.PK_LONG_LAST_MANULE_PAUSED, System.currentTimeMillis());
	pe.commit();*/
}

/*
 * from a pause to a new pause.
 */
public void restartPause(){
//	getPausedTime(false);   
	long lastPaused =pref.getLong(QiYouConstant.PK_LONG_LAST_MANULE_PAUSED, 0);
	if(lastPaused>0){ 
		long sumPaused=getPausedTime(false)+System.currentTimeMillis() -lastPaused;
		pe.putLong(QiYouConstant.PK_LONG_TRACK_MANULE_PAUSED, sumPaused);
	}
	pe.putLong(QiYouConstant.PK_LONG_LAST_MANULE_PAUSED, System.currentTimeMillis());
	pe.commit();
	
}


public void continueTrack(TrackType trackType){
	new Thread(){
		
		@Override
		public void run() {
			
			 initialTrackParameters(); //lastLocation is going to be set null.
			 
			 if(recordingTrack.getTrackBean().getEndTime()>0){ //for recording UI total time,the time between last end and the continue time will be treated as Manual Pausing time.
				 pe.putLong(QiYouConstant.PK_LONG_LAST_MANULE_PAUSED,recordingTrack.getTrackBean().getEndTime());
				 pe.commit();
				 updatePauseParameters();				 
			 }
//			 setRecordingTrack(currentTrack);  
//			 recordingTrack.getTrackBean().setStatus(QiYouConstant.TRACK_STATUS_TRACKING);
			 updateTrackStatus(recordingTrack.getTrackBean().getTrackId(),QiYouConstant.TRACK_STATUS_TRACKING);
		//	 if(!playBack)this.canRecord=true;
			 if(!playBack)startAndroidGPSRequest();	
			 playBack=false; 
			 setLastRecordingIdStartTime();
			 
			 Location loc= lastLocation;	 
			     Intent broadcastIntent = new Intent();						
			     broadcastIntent.setAction(QiYouConstant.ACTION_NEW_LOCATION_GETBACK);  
			     broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); 
			     broadcastIntent.putExtra(QiYouConstant.NEW_LOCATION,  loc);  
		//	     broadcastIntent.putExtra(QiYouConstant.EXTRA_KEY_NO_LOCCATION_SIGNAL, true);    
			    sendBroadcast(broadcastIntent); 
				regTimeTick();
			   
			 //update the ui to reflect new track 
		
		}}.start(); 
		
}



public void initialNewTrack(final TrackType trackType){
	QiYouConstant.CAN_SPEAK = true;
new Thread(){
		
		@Override
		public void run() { 
			 setLastRecordingIdStartTime();		
			 initialTrackParameters(); //lastLocation is going to be set null.
//			 setRecordingTrack(new Track()); 
			 getRecordingTrack().startNewTrack(trackType);
		//	 if(!playBack)this.canRecord=true;
//			 if(!playBack)
			 startAndroidGPSRequest();	
			 playBack=trackType==TrackType.COPY; 
			 
			 
			 Location loc= lastLocation;	 
			     Intent broadcastIntent = new Intent();						
			     broadcastIntent.setAction(QiYouConstant.ACTION_NEW_LOCATION_GETBACK);  
			     broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); 
			     broadcastIntent.putExtra(QiYouConstant.NEW_LOCATION,  loc);  
		//	     broadcastIntent.putExtra(QiYouConstant.EXTRA_KEY_NO_LOCCATION_SIGNAL, true);    
			    sendBroadcast(broadcastIntent); 
//				regTimeTick();
			   
			 //update the ui to reflect new track 

		}}.start(); 	
 }

/*
 *read parameters that updated during the recording.
 * This is in case the application exits and recreating, unpredicted.
 */
public void initialLocationParameters()
{/*
	if(lastPaused > QiYouConstant.PV_LONG_LAST_START || lastOfftime >QiYouConstant.PV_LONG_LAST_START) return;
	  sumPaused = pref.getLong(QiYouConstant.PK_LONG_SUM_PAUSE, 0);
//	  sumOfftime = pref.getLong(QiYouConstant.PK_LONG_SUM_OFFTIME, 0);//offtime only apply to forceupdate. need not persist.
	  lastOfftime = pref.getLong(QiYouConstant.PK_LAST_OFFTIME, 0);
	  lastGpsStartTime =pref.getLong("lastGpsStartTime", 0);
	  lastGpsStopTime =pref.getLong("lastGpsStopTime", 0);
//	  gpsStartTime =pref.getLong("gpsStartTime", 0); 	
	  lastLocationTime =pref.getLong("lastLocationTime", 0);
	  lastPaused= pref.getLong(QiYouConstant.PK_LAST_PAUSED, 0);
	  sumDist= pref.getFloat(QiYouConstant.PK_LONG_SUMDIST, 0); 
	  sumOfftimeWp = pref.getLong(QiYouConstant.PK_LONG_SUM_OFFTIMEWP, 0); 
	  minTime = pref.getLong(QiYouConstant.PK_LONG_MINTIME, 0);
	  locDist= pref.getFloat(QiYouConstant.PK_FLOAT_LOCDIST, 0);
	  SpDist= pref.getFloat(QiYouConstant.PK_FLOAT_SPDIST, 0);
	  cntKm= pref.getInt("cntKm", 0);
	  sumBear= pref.getFloat("sumBear", 0);
	  sumBear2= pref.getFloat("sumBear2", 0);
	  cntBear= pref.getInt("cntBear", 0);
//      cntBeared= pref.getInt("cntBeared", 0);
	  targetBear= pref.getFloat("targetBear", 0);
		 
 
      
//	  QLog.getLogger().d(dTAG, "Read Location Parameters.");
//	  QLog.getLogger().d(TAG," read app.sumPause: "+ sumPaused );	
*/}
/*
 * persist the parameters that updated during the recording.
 * This is in case the application exits and recreating, unpredicted.
 */
/*
 * newTrack, indicate when it is a new track, clear all the parameters.
 */
public void saveLocationParameters(Boolean newTrack)
{ /*
	if(!newTrack)
	if( recordingTrack==null || recordingTrack.getTrackBean().getStatus()!=QiYouConstant.TRACK_STATUS_TRACKING
//		|| sumPaused+sumOfftime+sumOfftimeWp+lastOfftime+lastPaused+sumDist ==0
		) return;
 //
//	if(!newTrack|| recordingTrack==null || recordingTrack.getTrackBean().getStatus()!=QiYouConstant.TRACK_STATUS_TRACKING
////			|| sumPaused+sumOfftime+sumOfftimeWp+lastOfftime+lastPaused+sumDist ==0
//			) return;
//	QLog.getLogger().d(dTAG, TAG+" save app tracking paramentes: "+ sumPaused+sumOfftime+sumOfftimeWp+lastOfftime+lastPaused+sumDist );	
	
      pe.putLong(QiYouConstant.PK_LONG_SUM_PAUSE, sumPaused);
//      pe.putLong(QiYouConstant.PK_LONG_SUM_OFFTIME, offtime);  //offtime only apply to forceupdate. need not persist.
      pe.putLong(QiYouConstant.PK_LONG_SUM_OFFTIMEWP, sumOfftimeWp);
      pe.putLong(QiYouConstant.PK_LAST_OFFTIME, lastOfftime);
      pe.putLong(QiYouConstant.PK_LAST_PAUSED, lastPaused);
      pe.putFloat(QiYouConstant.PK_LONG_SUMDIST, sumDist); 
      pe.putLong(QiYouConstant.PK_LONG_MINTIME, minTime);
      pe.putFloat(QiYouConstant.PK_FLOAT_LOCDIST, locDist); 
      pe.putFloat(QiYouConstant.PK_FLOAT_SPDIST, SpDist); 
      pe.putInt("cntKm", cntKm);
      pe.putLong("lastGpsStartTime", lastGpsStartTime);
      pe.putLong("lastGpsStopTime", lastGpsStopTime); 
//      pe.putLong("gpsStartTime", gpsStartTime);
      if(lastLocation!=null)pe.putLong("lastLocationTime", lastLocation.getTime()); 
      pe.putFloat("sumBear", sumBear); 
      pe.putFloat("sumBear2", sumBear2);
      pe.putInt("cntBear", cntBear); 
      pe.putInt("cntBeared", cntBeared);
      pe.putFloat("targetBear", targetBear);
      
      pe.commit();
//      pe.apply();
     
//      QLog.getLogger().d(dTAG, "saved Location Parameters.");
	  */
}

public int getExistTrackingID(){
	return settings.getInt(QiYouConstant.PK_INT_LAST_UNFINISHED_TRACKID,-1);
}
public boolean isLastTrackExist(){
//	
// 	int id =getExistTrackingID();
// 	long lastStart =settings.getLong(QiYouConstant.PK_LONG_LAST_TRACK_START,0);
//	
//	QLog.getLogger().dLog(dTAG, String.format("%s,last track id is %s, last track time is %s",TAG, id,lastStart));
	
	return settings.getInt(QiYouConstant.PK_INT_LAST_UNFINISHED_TRACKID,-1)>0
			|| settings.getLong(QiYouConstant.PK_LONG_LAST_TRACK_START,0)> 0;
}
public boolean isRestoreLastTracking =false;
public void restoreLastTracking()
{
//	 ggGPSwarmup();
	final int id =settings.getInt(QiYouConstant.PK_INT_LAST_UNFINISHED_TRACKID,-1);
	QLog.getLogger().dLog(TAG, "restoreLastTracking(),start to restore track of id "+ id );
	if(id<=0 ){
		
		if(settings.getLong(QiYouConstant.PK_LONG_LAST_TRACK_START,0)>0){  //just start, not get gps yet,no trackId yet
//			this.initialNewTrack(QiYouConstant.TRACK_TYPE_BIKE);
			this.initialNewTrack(TrackType.BIKE);//track type may need to store in pref.//TODO:rewiew
			QLog.getLogger().dLog(TAG, "restoreLastTracking(),by initialNewTrack" );
		}
		return;	
	}else	
	if(currentTrack!=null && currentTrack.getTrackBean().getTrackId()==id){//TODO: review currentTrack....
		this.recordingTrack=currentTrack;
		QLog.getLogger().dLog(TAG,"restoreLastTracking(),set recordingTrack to currentTrack  "+ id +",track status is "+recordingTrack.getTrackBean().getStatus() );
		return;
	}
	
	
	QLog.getLogger().dLog(TAG, "restoreLastTracking(),2 start to restore track of id "+ id );
	if(id >0 ){		
		isRestoreLastTracking =true;
		getTrack(id) ;
		currentTrackId = -11;
		this.startAndroidGPSRequest();
		
		if(getExistNaviTrackID() ==id &&  isLastNaviExist() && !playBack){ //last recording track is in naving, restore navi too.			
			isRestoreNavi=true;
			isNaving=true;
			restoreNaviService(getExistNaviID());
		}
		
//		new Handler().post(new Runnable () {
//		        public void run() {
	   final Intent broadcastIntent = new Intent();						
        broadcastIntent.setAction(QiYouConstant.ACTION_NEW_LOCATION_GETBACK);  
        broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); 
//	    broadcastIntent.putExtra(QiYouConstant.EXTRA_KEY_NO_LOCCATION_SIGNAL, true);   
	    new Thread(){
	      @Override
		public void run() {
			        	  long topWaiting=0;
	//		        	while(currentTrackId==-11){	
			        		while(currentTrackId!=id){	
			    			try {
			    				Thread.sleep(50);
			    				topWaiting+=50;
			    				if(topWaiting>QiYouConstant.MAX_TIME_GET_TRACK_FROM_DB)
			    				{
			    					QLog.getLogger().dLog(TAG,  " restoreLastTracking(),Get track with id" + id +" over time limit, Waiting = "+topWaiting);
			    					break;
	//		    					  Toast toast=	Toast.makeText(this, "Get track with id" + id +" over time limit.", Toast.LENGTH_LONG );
	//		    				 	   toast.show(); 
			    				}
			    			} catch (InterruptedException e) {
			    				// TODO Auto-generated catch block
			    				Utils.logStackTrace(e, TAG);
			    				} 
			    		}
			        	
			        
			        		
			        	isRestoreLastTracking =false;
			        	
			        	if(currentTrackId ==id)	{
	//		        	 if(getRecordingTrack().getTrackBean().getStatus()==QiYouConstant.TRACK_STATUS_TRACKING && recordingTrack.getTrackBean().getTrackId()==0)	
			        		 if(recordingTrack.getTrackBean().getTrackId()==0)
			        		 {
			        			 recordingTrack= currentTrack;
			        			 forceDbUpdate(false);
			        			 
			        			 //send notice to UI.
			        			 sendBroadcast(broadcastIntent); 
			        			  
			        			 // QLog.getLogger().dLog(TAG ," restoreLastTracking(), id "+ id +" Restored, track Status is " +getRecordingTrack().getTrackBean().getStatus());
	//		        			 Log.d(dTAG,TAG+" Send restore track information to update UI.");
			        		 }
			        	}
			        	else{//failed to restore, check current recording track
	//		        			setRecordingTrack(new Track());
			        		if( recordingTrack ==null || recordingTrack.getTrackBean().getTrackId()==0)
	//		        			getRecordingTrack().startNewTrack(QiYouConstant.TRACK_TYPE_BIKE);
			        			getRecordingTrack().startNewTrack(TrackType.BIKE);//TODO: review  bike as default or use pref.
			        			QLog.getLogger().dLog(dTAG,TAG+" "+ "restoreLastTracking(), id "+ id +" not Restored, start new track");
			        		}
			        	
	
			        	if( recordingTrack!=null && TrackStatus.FINISHED  ==  recordingTrack.getTrackBean().getStatus()){
			        		recordingTrack.getTrackBean().setStatus(TrackStatus.RECORDING);
			        	}
			        	
			        	
			        	isRestoreLastTracking =false;
	//		    		}});
	      }}.start();
	//      }};       	
			 
		
//		 Toast toast=	Toast.makeText(this, " Incomplete track " + id +" Restored "+TAG, Toast.LENGTH_LONG );
//	 	 toast.show(); 
	}
	
	
}

public boolean isRestoreNavi;

 void restoreNaviService(final int naviId){
	 
	 final Intent serviceIntent = new Intent(this, QNaviSvc.class); 
		serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_START_NAVI, 0);
	    stopService(serviceIntent);
	   
//	    lastStartDialog=!isContinue; //start new navi should not show dialog
		
		final Handler  handler = new Handler(){ 
				@Override
				public void handleMessage(Message msg) {  
					if (msg.what==10) {  
						    naviTrackId=naviId; //TODO:this need current navi stopped.
							startService(serviceIntent); 
					}
				}};
		if(!TextUtils.isEmpty(isLastNaviWeb())){
			
			try {
				this.setCurrentTrack(Utils.getTrackFromWebCache(isLastNaviWeb()));
				getTrackCache().put(naviId,currentTrack);
			} catch (JsonSyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		
			 handler.sendEmptyMessage(10);
			return;
		}
		
		
		    new Thread(){
				
				@Override
				public void run() {
					
					
		        	
					while(isRestoreLastTracking){
					 try {
							Thread.sleep(100);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				
					getTrack(naviId) ;
					
					int topWaiting=0;
					while(currentTrackId!=naviId){	
		    			try {
		    				Thread.sleep(100);
		    				topWaiting+=100;
		    				if(topWaiting>QiYouConstant.MAX_TIME_GET_TRACK_FROM_DB)
		    				{
		    					QLog.getLogger().dLog(TAG,  " restoreNaviService(),Get track with id" + naviId +" over time limit, Waiting = "+topWaiting);
		    					break;
//		    					  Toast toast=	Toast.makeText(this, "Get track with id" + id +" over time limit.", Toast.LENGTH_LONG );
//		    				 	   toast.show(); 
		    				}
		    			} catch (InterruptedException e) {
		    				// TODO Auto-generated catch block
		    				Utils.logStackTrace(e, TAG);
		    				} 
		    		}
					 
					  if(currentTrackId==naviId)
						  handler.sendEmptyMessage(10);
			    	
			    		
				}}.start(); 
}


//TODO: try AsyncTask
public int currentTrackId =0;
public void getTrack(final int trackID){ 
	Intent serviceIntent = new Intent(this, TrackDbServiceBackground.class);	   
    serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_GET_CURRENT_TRACK_BY_ID, trackID);   
    startService(serviceIntent); 
//   QLog.getLogger().d(dTAG,TAG+" "+ "getTrack result。 currentTrackId==trackID ? "+ currentTrackId+ "=="+ trackID);
}

/*void showAnimate(long time,int trackID)
{   
    //TODO: SHOW ANIMATE GIF FOR WAITING 1 SEC.
	  long topWaiting=0;
	  while(topWaiting<=time &&  currentTrackId !=trackID)
	    {
	    	try {  
				Thread.sleep(50);
				topWaiting+=50;
				
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				Utils.logStackTrace(e, TAG);
			}
	    }
}*/
public void updateTrackStatus( int status){
	updateTrackStatus(0,  status);//0: update recordingTrack,else update current  track
}

public void updateTrackStatus(int id, int status)
{	 	
//	if(null != getCurrentTrack()) getTrackCache().put( getCurrentTrack().getTrackBean().getTrackId(),  getCurrentTrack());
//    setCurrentTrack( getRecordingTrack());
	QLog.getLogger().d(dTAG,TAG+"  start to update track " + id +" to status " + status);
	
		
//   if(id ==0 &&  recordingTrack!=null )//&&  recordingTrack.getTrackBean().getTrackId()>0)
	 if( recordingTrack!=null &&(id==0 || id ==recordingTrack.getTrackBean().getTrackId()) )//&&  recordingTrack.getTrackBean().getTrackId()>0)
	    recordingTrack.getTrackBean().setStatus(TrackStatus.valueOf(status)); 
   else if(id > 0 &&  currentTrack!=null && currentTrack.getTrackBean().getTrackId() ==id)
		currentTrack.getTrackBean().setStatus(TrackStatus.valueOf(status)); 
	else return;
	 
    if( this.getRecordingTrack().getTrackBean().getTrackId() == id){
    	setLastRecordingIdStartTime(); //id may eq -1, thats okay to persist the -1 as none recording track exist.
    }
    	

	this.forceDbUpdate(true);
	try{
		if(status == QiYouConstant.TRACK_STATUS_TRACKING){
//			setLastRecordingIdStartTime();
//				 canRecord=true;
//				if(isGPSstopped) startAndroidGPSRequest();  //TODO: review when to startgsprequest 
				startAndroidGPSRequest();
				regTimeTick();
			}
		
		else
		{ 
//			 canRecord =false;
			stopAndroidGPSRequest();
			unregTimeTick();
		}
		

		
	Intent serviceIntent = new Intent(this, TrackDbServiceBackground.class);	
	if(id ==0 || recordingTrack!=null && recordingTrack.getTrackBean().getTrackId()>0 ) 
		serviceIntent.putExtra(QiYouConstant.UPDATE_RECORDING_TRACK, recordingTrack.getTrackBean().getTrackId());
	else{  //finish recording.
		
//			if(System.currentTimeMillis()>currentTrack.getTrackBean().getEndTime()){
//				currentTrack.getTrackBean().setEndTime(System.currentTimeMillis());
//	   	  }
		serviceIntent.putExtra(QiYouConstant.EXTR_KEY_FINISH_RECORDING, currentTrack.getTrackBean().getTrackId());
	}
    startService(serviceIntent);
   
    
  //keep the lat lon as the last location.     
   
	}catch(Exception e)
	{
		Log.d(dTAG,TAG+" "+ "wrong on update the new track status to " + status);
		Utils.logStackTrace(e, dTAG);
	}
	
	  
}
public void getPreferences(){
	
	  readUser();
//		QiYouConstant.PV_USER_ID=settings.getInt(QiYouConstant.PK_INT_USER_ID, QiYouConstant.PV_USER_ID);
//		QiYouConstant.PV_USER_PASSWD=settings.getString(QiYouConstant.PK_STR_USER_PASSWD, QiYouConstant.PV_USER_PASSWD);
//		QiYouConstant.PV_USER_ACCOUNT = settings.getString(QiYouConstant.PK_STR_USER_ACCOUNT, QiYouConstant.PV_USER_ACCOUNT);
//		QiYouConstant.PV_USER_NAME = settings.getString(QiYouConstant.PK_STR_USER_NAME, QiYouConstant.PV_USER_NAME);
//		QiYouConstant.PV_USER_EMAIL=settings.getString(QiYouConstant.PK_STR_USER_EMAIL, QiYouConstant.PV_USER_EMAIL); 
	    QiYouConstant.PV_USER_WEIGHT = Float.valueOf(settings.getString(QiYouConstant.PK_FLOAT_USER_WEIGHT, "60"));
	   
	    
 		QLog.getLogger().d(dTAG, TAG+ " before prefloading QiYouConstant.PV_BL_PLAYBACK_PAUSE_WITH_UI: "+QiYouConstant.PV_BL_PLAYBACK_PAUSE_WITH_UI );

	    QiYouConstant.PV_BL_PLAYBACK_PAUSE_WITH_UI =  Boolean.valueOf(settings.getBoolean(QiYouConstant.PK_BL_PLAYBACK_RECORD_SCREEN_OFF,  QiYouConstant.PV_BL_PLAYBACK_PAUSE_WITH_UI));
 		QLog.getLogger().d(dTAG, TAG+ " prefloading QiYouConstant.PV_BL_PLAYBACK_PAUSE_WITH_UI: "+QiYouConstant.PV_BL_PLAYBACK_PAUSE_WITH_UI );
 		
	    QiYouConstant.PV_BL_SAVE_POWER =  Boolean.valueOf(settings.getBoolean(QiYouConstant.PK_BL_SAVE_POWER,  QiYouConstant.PV_BL_SAVE_POWER));
 		QLog.getLogger().d(dTAG, TAG+ " prefloading QiYouConstant.PV_BL_SAVE_POWER: "+QiYouConstant.PV_BL_SAVE_POWER );
 
 		QiYouConstant.PV_BL_SHARE_LOCATION =  Boolean.valueOf(settings.getBoolean(QiYouConstant.PK_BL_SHARE_LOCATION,  QiYouConstant.PV_BL_SHARE_LOCATION)); 
 
 		
		QiYouConstant.PV_STR_SHARE_MSG = settings.getString(QiYouConstant.PK_STR_SHARE_MSG, QiYouConstant.PV_STR_SHARE_MSG);
// 		QiYouConstant.PV_LG_SHARE_INTERVAL = settings.getLong(QiYouConstant.PK_LG_SHARE_INTERVAL, QiYouConstant.PV_LG_SHARE_INTERVAL);
		QiYouConstant.PV_LAST_BBS_CATE = settings.getString(QiYouConstant.PK_LAST_BBS_CATE, "");
		
//		QiYouConstant.BL_SPEAK_KM = settings.getBoolean(QiYouConstant.PK_BL_SPEAK_KM, true) ;		
		QiYouConstant.PV_APP_CNT =settings.getInt(QiYouConstant.PK_INT_APP_CNT, 0);
		QiYouConstant.PV_LONG_LAST_QUIT =settings.getLong(QiYouConstant.PK_LONG_LAST_QUIT, 0);
		QiYouConstant.PV_LONG_LAST_START =settings.getLong(QiYouConstant.PK_LONG_LAST_START, 0);
		
		QiYouConstant.MAX_WPS_EVERAGE_ELE_CNT =settings.getInt(QiYouConstant.PK_INT_MAX_WPS_EVERAGE_ELE_CNT, QiYouConstant.MAX_WPS_EVERAGE_ELE_CNT);
//		QiYouConstant.PLAYBACK_CAN_RECORD = settings.getBoolean(QiYouConstant.PK_BL_PLAYBACK_CAN_RECORD, false);
//		QiYouConstant.PLAYBACK_CAN_RECORD = new Boolean(settings.getBoolean(QiYouConstant.PK_BL_PLAYBACK_CAN_RECORD, false));
		QiYouConstant.WPS_SAVE_ALL = settings.getBoolean(QiYouConstant.PK_BL_WPS_SAVE_ALL, false) ;
//		QiYouConstant.WPS_SAVE_ALL = new Boolean(settings.getBoolean(QiYouConstant.PK_BL_WPS_SAVE_ALL, false));
		
//		QiYouConstant.PLAYBACK_CAN_RECORD = Boolean.valueOf(settings.getString(QiYouConstant.PK_BL_PLAYBACK_CAN_RECORD, "false"));
//	 	QiYouConstant.PLAYBACK_CAN_RECORD = (Boolean) settings.getAll().get(QiYouConstant.PK_BL_PLAYBACK_CAN_RECORD ); 
		
	
//		QiYouConstant.MAX_GPS_SPAN =settings.getInt(QiYouConstant.PK_INT_GPS_SPAN, QiYouConstant.MAX_GPS_SPAN );
		int span =Integer.valueOf(settings.getString(QiYouConstant.PK_INT_GPS_SPAN, String.valueOf(QiYouConstant.MAX_GPS_SPAN )));
		span =span >1000?span:2000;
		QiYouConstant.MAX_GPS_SPAN =span;
		
		int  speakModel =Integer.valueOf(settings.getString(QiYouConstant.PK_INT_SPORTS_SPEAK_MODEL, String.valueOf(QiYouConstant.PV_INT_SPORTS_SPEAK_MODEL )));
		QiYouConstant.PV_INT_SPORTS_SPEAK_MODEL=speakModel;
		
		speakModel =Integer.valueOf(settings.getString(QiYouConstant.PK_INT_NAVI_SPEAK_MODEL, String.valueOf(QiYouConstant.PV_INT_NAVI_SPEAK_MODEL )));
		QiYouConstant.PV_INT_NAVI_SPEAK_MODEL=speakModel;
		
		
//		QiYouConstant.PLAYBACK_TIME_INTERVAL =settings.getInt(QiYouConstant.PK_INT_PLAYBACK_TIME_INTERVAL, QiYouConstant.PLAYBACK_TIME_INTERVAL);	
//		QiYouConstant.PLAYBACK_TIME_INTERVAL = Integer.valueOf(settings.getString(QiYouConstant.PK_INT_PLAYBACK_TIME_INTERVAL, String.valueOf(QiYouConstant.PLAYBACK_TIME_INTERVAL )));
		QiYouConstant.PV_LAST_LAT = (settings.getFloat(QiYouConstant.PK_DOU_LAST_LAT,  QiYouConstant.PV_LAST_LAT));
		QiYouConstant.PV_LAST_LON = (settings.getFloat(QiYouConstant.PK_DOU_LAST_LON,  QiYouConstant.PV_LAST_LON));
		QiYouConstant.PV_LAST_CITY = (settings.getString(QiYouConstant.PK_STR_CITY,  QiYouConstant.PV_LAST_CITY));
		
		int intV=0;
		if(settings.contains(QiYouConstant.PK_INT_WPS_CNT_BEAR)){
			intV =Integer.valueOf(settings.getString(QiYouConstant.PK_INT_WPS_CNT_BEAR, String.valueOf(QiYouConstant.WPS_ROAD_BEAR_CNT )));
			intV =intV >1?intV:QiYouConstant.WPS_ROAD_BEAR_CNT;
			QiYouConstant.WPS_ROAD_BEAR_CNT =intV;
		}
		if(settings.contains(QiYouConstant.PK_INT_ANGLE_BEAR)){
			intV =Integer.valueOf(settings.getString(QiYouConstant.PK_INT_ANGLE_BEAR, String.valueOf(QiYouConstant.WPS_ROAD_BEARING )));
			intV =intV >10?intV:QiYouConstant.WPS_ROAD_BEARING;
			QiYouConstant.WPS_ROAD_BEARING =intV;
		}
		
		if(settings.contains(QiYouConstant.PK_INT_WPS_KEEP_PERCENT)){
			intV =Integer.valueOf(settings.getString(QiYouConstant.PK_INT_WPS_KEEP_PERCENT, String.valueOf(QiYouConstant.WPS_SAVE_PERCENT_FACTOR )));
			intV =intV >0?intV:QiYouConstant.WPS_ROAD_BEARING;
			QiYouConstant.WPS_SAVE_PERCENT_FACTOR =intV;
		}
	 
		QiYouConstant.PV_INT_SCREEN_WIDTH=settings.getInt(QiYouConstant.PK_INT_SCREEN_WIDTH, QiYouConstant.PV_INT_SCREEN_WIDTH);
		QiYouConstant.PV_INT_SCREEN_HEIGHT=settings.getInt(QiYouConstant.PK_INT_SCREEN_HEIGHT, QiYouConstant.PV_INT_SCREEN_HEIGHT);
		QiYouConstant.MAP_PIC_SIZE = QiYouConstant.PV_INT_SCREEN_WIDTH/20;//40;//PIC SHOW ON MAP
		QiYouConstant.SUBNAIL_PIC_SIZE = QiYouConstant.PV_INT_SCREEN_WIDTH/2;//400;//PIC SHOW ON MAP
		QiYouConstant.BL_ONE_SHOT_BEAR = Boolean.valueOf(settings.getBoolean(QiYouConstant.PK_BL_ONE_SHOT_BEAR, false));

	 
		QiYouConstant.PV_BL_NAVI_VIBRATOR_ON = Boolean.valueOf(settings.getBoolean(QiYouConstant.PK_BL_NAVI_VIBRATOR_ON, QiYouConstant.PV_BL_NAVI_VIBRATOR_ON));

		
//		QLog.getLogger().d(dTAG, TAG+ " prefloading QiYouConstant.WPS_ROAD_BEARING,QiYouConstant.WPS_ROAD_BEAR_CNT: "+ QiYouConstant.WPS_ROAD_BEARING+","+QiYouConstant.WPS_ROAD_BEAR_CNT);
//		QLog.getLogger().d(dTAG, TAG+ " prefloading QiYouConstant.WPS_SAVE_PERCENT_FACTOR: "+QiYouConstant.WPS_SAVE_PERCENT_FACTOR );

		
//		public static String PK_INT_WPS_CNT_BEAR ="PK_INT_WPS_CNT_BEAR"; 
//		public static String PK_INT_ANGLE_BEAR ="PK_INT_ANGLE_BEAR";  
//		public static int WPS_ROAD_BEARING =20; //how much bearing change can be take as a roadwp,35,2; 25,4;...30,4;35,3;20,4
//		public static int WPS_ROAD_BEAR_CNT =4; //at least how much continued bear points can be counted as a valid roadbear

   		QiYouConstant.PV_OPEN_ID = settings.getString(QiYouConstant.PK_ST_OPEN_ID, QiYouConstant.PV_OPEN_ID);
		QiYouConstant.PV_ACCESS_TOKEN = settings.getString(QiYouConstant.PK_STR_ACCESS_TOKEN, QiYouConstant.PV_ACCESS_TOKEN);
		QiYouConstant.PV_EXPIRES_IN=settings.getLong(QiYouConstant.PK_L_EXPIRES_IN, QiYouConstant.PV_EXPIRES_IN);  
//	    QLog.getLogger().d(dTAG, TAG+ String.format(" prefloading QiYouConstant.PV_INT_LIVE_SPAN :'%s'",
//				  settings.getInt(QiYouConstant.PK_INT_LIVE_SPAN,   QiYouConstant.PV_INT_LIVE_SPAN ))  );
		
		if(settings.contains(QiYouConstant.PK_INT_LIVE_SPAN)){
			QiYouConstant.PV_INT_LIVE_SPAN  = Integer.valueOf(settings.getString(QiYouConstant.PK_INT_LIVE_SPAN, String.valueOf(QiYouConstant.PV_INT_LIVE_SPAN ))); 
		}
		
//		QiYouConstant.PV_INT_LIVE_SPAN  = settings.getInt(QiYouConstant.PK_INT_LIVE_SPAN,  QiYouConstant.PV_INT_LIVE_SPAN  ) ; 
 	    QLog.getLogger().d(dTAG, TAG+ String.format(" prefloading QiYouConstant.PV_INT_LIVE_SPAN :'%s'",QiYouConstant.PV_INT_LIVE_SPAN) );
 		
 		
//		saveShareLocationOption();
	
}

public long getTokenExpiresIn(){
	return System.currentTimeMillis()-settings.getLong(QiYouConstant.PK_L_EXPIRES_IN, QiYouConstant.PV_EXPIRES_IN);
}
public void saveAuth20Token(){
	
 	pEditor.putString(QiYouConstant.PK_ST_OPEN_ID,  QiYouConstant.PV_OPEN_ID);//(QiYouConstant.PK_DOU_LAST_LAT, QiYouConstant.PV_LAST_LAT);
	pEditor.putString(QiYouConstant.PK_STR_ACCESS_TOKEN, QiYouConstant.PV_ACCESS_TOKEN); 
	pEditor.putLong(QiYouConstant.PK_L_EXPIRES_IN, QiYouConstant.PV_EXPIRES_IN); 
    pEditor.commit();
}
public void updateUserPref(){
	
	QiYouConstant.PV_ACCESS_TOKEN=user.getUserbean().getToken();
	QiYouConstant.PV_USER_ID=user.getUserbean().getId();
	QiYouConstant.PV_EXPIRES_IN=user.getUserbean().getQqExprires();
	pEditor.putString(QiYouConstant.PK_STR_USER, Utils.getGsonString(user.getUserbean()));
	pEditor.putString(QiYouConstant.PK_STR_ACCESS_TOKEN, QiYouConstant.PV_ACCESS_TOKEN);	
	pEditor.commit();
 
}

public void logout(){
	user = new User();
	updateUserPref();
	setAuth();
	
}

public void saveShareLocationOption(){
 	pEditor.putBoolean(QiYouConstant.PK_BL_SHARE_LOCATION,  QiYouConstant.PV_BL_SHARE_LOCATION);
	pEditor.putString( QiYouConstant.PK_INT_LIVE_SPAN,  String.valueOf(QiYouConstant.PV_INT_LIVE_SPAN));
	pEditor.putString(QiYouConstant.PK_STR_SHARE_MSG,  QiYouConstant.PV_STR_SHARE_MSG);

    pEditor.commit();
}

public void setlastLocation(float lat,float lon){
	QiYouConstant.PV_LAST_LAT =   lat ;
	QiYouConstant.PV_LAST_LON =   lon ;		 				  
	pEditor.putFloat(QiYouConstant.PK_DOU_LAST_LAT, QiYouConstant.PV_LAST_LAT);
	pEditor.putFloat(QiYouConstant.PK_DOU_LAST_LON, QiYouConstant.PV_LAST_LON); 
	if(this.getGEOinfo()!=null)
		pEditor.putString(QiYouConstant.PK_STR_CITY, getGEOinfo().getCity());
    pEditor.commit();
}
public void setScreenInfo(Point outSize){
	  QiYouConstant.PV_INT_SCREEN_WIDTH =outSize.x ;
	  QiYouConstant.PV_INT_SCREEN_HEIGHT=outSize.y;  
	  QiYouConstant.MAP_PIC_SIZE = QiYouConstant.PV_INT_SCREEN_WIDTH/20;//40;//PIC SHOW ON MAP
	  QiYouConstant.SUBNAIL_PIC_SIZE = QiYouConstant.PV_INT_SCREEN_WIDTH/2;//400;//PIC SHOW ON MAP
	pEditor.putInt(QiYouConstant.PK_INT_SCREEN_WIDTH, QiYouConstant.PV_INT_SCREEN_WIDTH);
	pEditor.putInt(QiYouConstant.PK_INT_SCREEN_HEIGHT, QiYouConstant.PV_INT_SCREEN_HEIGHT); 
    pEditor.commit();
}

//last time that geo has been done.
public void setlastGeoRequestTime(){
	QiYouConstant.LAST_GEO_UPDATE 		=System.currentTimeMillis();	  
	pEditor.putLong(QiYouConstant.PK_LONG_LAST_GEO_UPDATE,QiYouConstant.LAST_GEO_UPDATE);
 
    pEditor.commit();
}

//last time that offmap has been done.
public void setlastOffMapRequestTime(){
	QiYouConstant.LAST_OFFMAP_UPDATE 		=System.currentTimeMillis();	  
	pEditor.putLong(QiYouConstant.PK_LONG_LAST_OFFMAP_UPDATE,QiYouConstant.LAST_OFFMAP_UPDATE);
 
    pEditor.commit();
}
/* public void updateUserPref(int userId,String email,String account,String passwd,String title,int score,int paiming){
	 user.getUserbean().setId(userId);
	 user.getUserbean().setMail(email);
	 user.getUserbean().setUserName(account);
	 user.getUserbean().setPassword(passwd);
	 user.getUserbean().setScore(score);
	 user.getUserbean().setPaiming(paiming);
	 updateUserPref();
 }*/
 public void updateUserPref(User_bean ub){
	user.setUserbean(ub);
	 updateUserPref();
 }

public void readUser(){
	
	String u = settings.getString(QiYouConstant.PK_STR_USER, "");
	if(!TextUtils.isEmpty(u)){
		User_bean ub = (User_bean)Utils.getGsonObject(u, User_bean.class);
		user.setUserbean(ub);
	}
 	QiYouConstant.PV_USER_ID=user.getUserbean().getId();
// 	QiYouConstant.PV_USER_ACCOUNT =user.getUserbean().getAccount();
 	QiYouConstant.PK_STR_USER_NAME =user.getUserbean().getUserName();

 	
 	
//	QiYouConstant.PV_USER_PASSWD=settings.getString(QiYouConstant.PK_STR_USER_PASSWD, QiYouConstant.PV_USER_PASSWD);
//	QiYouConstant.PV_USER_ACCOUNT = settings.getString(QiYouConstant.PK_STR_USER_ACCOUNT, QiYouConstant.PV_USER_ACCOUNT);
//	QiYouConstant.PV_USER_EMAIL=settings.getString(QiYouConstant.PK_STR_USER_EMAIL, QiYouConstant.PV_USER_EMAIL); 
	
	/*user.getUserbean().setUserName(settings.getString(QiYouConstant.PK_STR_USER_NAME, QiYouConstant.PV_USER_NAME));
	user.getUserbean().setAccount(settings.getString(QiYouConstant.PK_STR_USER_ACCOUNT, QiYouConstant.PV_USER_ACCOUNT));
	user.getUserbean().setTitle(settings.getString(QiYouConstant.PK_STR_USER_TITLE, ""));
	user.getUserbean().setPassword(settings.getString(QiYouConstant.PK_STR_USER_PASSWD, ""));
	user.getUserbean().setId(settings.getInt(QiYouConstant.PK_INT_USER_ID, QiYouConstant.PV_USER_ID));
	user.getUserbean().setPaiming(settings.getInt(QiYouConstant.PK_STR_USER_PAIMING, 0));
	user.getUserbean().setScore(settings.getInt(QiYouConstant.PK_STR_USER_SCORE, 0));*/
	
}
//set gpx to show
public void setGpxShowingTracks(String trackId,Boolean isAdd){
	  
	String trackIds = settings.getString(QiYouConstant.PK_STRING_SHOWING_GPX,"");
	trackId=","+trackId+",";
	if(isAdd){
		trackIds+=trackId;
	}else{
		trackIds=trackIds.replace(trackId, "");
	}  
	pEditor.putString(QiYouConstant.PK_STRING_SHOWING_GPX,trackIds); 
    pEditor.commit();
}
//last time that offmap has been done.
public ArrayList<Integer> getGpxShowingTracks(){
	  
	 String trackIds = settings.getString(QiYouConstant.PK_STRING_SHOWING_GPX,"");
	 String[] ids =trackIds.split(",");
	 ArrayList<Integer>iids= new ArrayList<Integer>();
	 int iid;
	 for(String id:ids){
		 id =id.trim();
		 if(TextUtils.isEmpty(id))continue;
		 iid=Integer.valueOf(id);
		 if(iid>0 && !iids.contains(iid)){
			 iids.add(iid);
			 
		 }
	 }
	 return iids;
 
 }
public void initialShowingGpxs(){ 
	
	    if(getGpxShowingTracks().size()==0)return;
	    Intent serviceIntent = new Intent(this, TrackDbServiceBackground.class);	   
	    serviceIntent.putExtra(QiYouConstant.INITIAL_GPXS, 1);   
	    startService(serviceIntent); 
}






public long getLastStatSyncTime(){ 
	return settings.getLong(QiYouConstant.PK_INT_LAST_SYNC_TIME,0);
//	return TextUtils.isEmpty()  ;
} 

public void setLastStatSyncTime(long time){
	 pEditor.putLong(QiYouConstant.PK_INT_LAST_SYNC_TIME,time);	  
	 pEditor.commit();
}









public void setlastLocation(Location loc){
//    Editor pEditor = settings.edit();
    if( loc!=null) {
		QiYouConstant.PV_LAST_LAT =   (float) (lastLocation.getLatitude()) ;
		QiYouConstant.PV_LAST_LON =   (float) (lastLocation.getLongitude()) ;		 				  
		pEditor.putFloat(QiYouConstant.PK_DOU_LAST_LAT, QiYouConstant.PV_LAST_LAT);
		pEditor.putFloat(QiYouConstant.PK_DOU_LAST_LON, QiYouConstant.PV_LAST_LON); 
        pEditor.commit();
    }
}

public void setLastTracktype(){
	if(recordingTrack!=null 
//   		 &&	 QiYouConstant.TRACK_TYPE_COPY != recordingTrack.getTrackBean().getType()
   		 &&	TrackType.COPY != recordingTrack.getTrackBean().getType()
   		 &&	 recordingTrack.getTrackBean().getStatus()!=TrackStatus.FINISHED) {
   	  pEditor.putInt(QiYouConstant.PK_INT_LAST_TRACKTYPE,recordingTrack.getTrackBean().getType().toInt());
   	 pEditor.commit();
    }
}

public int getLastTracktype(){
 return settings.getInt(QiYouConstant.PK_INT_LAST_TRACKTYPE, 0);
}

public void setLastRecordingIdStartTime(){
//	 Editor pEditor = settings.edit(); 
	     if(recordingTrack!=null 
//	    		 &&	 QiYouConstant.TRACK_TYPE_COPY != recordingTrack.getTrackBean().getType()
	    		 &&	TrackType.COPY != recordingTrack.getTrackBean().getType()
	    		 &&	 recordingTrack.getTrackBean().getStatus()!=TrackStatus.FINISHED) {
	    	  pEditor.putInt(QiYouConstant.PK_INT_LAST_UNFINISHED_TRACKID,recordingTrack.getTrackBean().getTrackId());
	    	  if(isNaving)
	    		  pEditor.putInt(QiYouConstant.PK_INT_LAST_NAVI_TRACK,recordingTrack.getTrackBean().getTrackId());
	    	  
	    	  pEditor.putLong(QiYouConstant.PK_LONG_LAST_TRACK_START,System.currentTimeMillis());
	    	  pEditor.commit();
	     }
	      else{
	    	  clearLastRecordingIdStartTime();
	      }
	 
   // apply();
  
  //  pEditor.apply(); 
    //TODO: use apply on high plaform while commit on low platform.
    
}

public void clearLastRecordingIdStartTime(){
	 pEditor.putInt(QiYouConstant.PK_INT_LAST_UNFINISHED_TRACKID,-1);
	 pEditor.putLong(QiYouConstant.PK_LONG_LAST_TRACK_START,0);
	  if(isNaving)
		  pEditor.putInt(QiYouConstant.PK_INT_LAST_NAVI_TRACK,-1);
//	 pEditor.putInt(QiYouConstant.PK_INT_LAST_TRACKTYPE,0);
	 pEditor.commit();
}

public Map<String,Integer> tabSpIndex;

 public void setPreferences(boolean isExitApp,boolean isStartup){
	 
//	 Editor pEditor = settings.edit();
     if(isExitApp){
    	  pEditor.putLong(QiYouConstant.PK_LONG_LAST_QUIT, System.currentTimeMillis()); 
    	  pEditor.putInt(QiYouConstant.PK_INT_APP_CNT, ++QiYouConstant.PV_APP_CNT);
    	  if( tabSpIndex !=null && tabSpIndex.keySet().size()>0){
    		  QiYouConstant.PV_LAST_BBS_CATE =   Utils.getGsonString(tabSpIndex);
    		  pEditor.putString(QiYouConstant.PK_LAST_BBS_CATE, QiYouConstant.PV_LAST_BBS_CATE );
    	  }
    	  
    	  
//	     if(this.recordingTrack.getTrackBean().getStatus()!=QiYouConstant.TRACK_STATUS_FINISHED)
//	     {
//	    	  pEditor.putInt(QiYouConstant.PK_INT_LAST_UNFINISHED_TRACKID,recordingTrack.getTrackBean().getTrackId());
//	     }else
//    	   pEditor.putInt(QiYouConstant.PK_INT_LAST_UNFINISHED_TRACKID,-1);
     	
//    	  setLastRecordingIdStartTime();
    	 
     }else if (isStartup){    	 
	   
	     pEditor.putLong(QiYouConstant.PK_LONG_LAST_START, System.currentTimeMillis());
//	    Toast toast=	Toast.makeText(this,  " QY Application is on create.  "+TAG, Toast.LENGTH_LONG );
//		toast.show(); 
     } 
     
    
     
     pEditor.commit();// apply();
//   String a = "";
   //  pEditor.apply(); 
     //TODO: use apply on high plaform while commit on low platform.
     
}
 
 /*public void getTracks(String[] ids)
 {
	  Intent serviceIntent = new Intent(this, TrackDbServiceBackground.class);	   
	  serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_GET_CURRENT_TRACK_BY_IDS, ids);	 	 	    	   
	  startService(serviceIntent);
 }*/
 public HashMap<Integer,String[]> geoWps;
 public void updateGEOs(HashMap<Integer,String[]> geoWps){
	 if(geoWps==null||geoWps.size()==0)return;
	   Intent serviceIntent = new Intent(this, TrackDbServiceBackground.class);
	   this.geoWps= geoWps;
	   QLog.getLogger().d(dTAG, TAG+" app.geoWps.size():"+geoWps.size()  );
	   serviceIntent.putExtra( QiYouConstant.EXTRA_KEY_TRACK_GEOS, 1);	      
	   startService(serviceIntent);	
 }
 
 
 public void getStaticsTracks(int trackType)
 { 
	 if(statTrackLoading)return;
//	  statTrackLoading=true;
	  Intent serviceIntent = new Intent(this, TrackDbServiceBackground.class);	   
	  serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_GET_STSTICS_TRACKS, trackType);	  
	  startService(serviceIntent);
 }

 public void syncStatistics()
 { 
	  QLog.getLogger().d(dTAG, " begin to sync statistics..............");
	  Intent serviceIntent = new Intent(this, sync.class);	   
	  serviceIntent.putExtra(QiYouConstant.ACTION_SYNC_STATISTICS, 0);	  
	  startService(serviceIntent);
 }
 public void syncStatisticsBeforExit()
 { 
	  QLog.getLogger().d(dTAG, " begin to sync statistics before exit app..............");
	  Intent serviceIntent = new Intent(this, sync.class);	   
	  serviceIntent.putExtra(QiYouConstant.ACTION_SYNC_STATISTICS, 1);	  
	  startService(serviceIntent);
 }
 
 /*
  * get all tracks to the statisticTracks.
  */
 public void getStaticsTracks()
 {
//	  Intent serviceIntent = new Intent(this, TrackDbServiceBackground.class);	   
//	  serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_GET_STSTICS_TRACKS, -100);	  
//	  startService(serviceIntent); 	 
	 getStaticsTracks(-100);
	 statTrackLoading=true;
 }
 
 
 /*
  *  Application start 1 分钟内, 不做trackstatus, gps status ,forceupdate 开关 处理.
  */
 public boolean isAppLong()
 {
	return (System.currentTimeMillis() - startTime)/1000/60 >QiYouConstant.MAX_TRACK_RESTORE_TIME;
 }
 
 /*
  * Application may restart, for memory or other service process may need to create new Application instance.
  * this causes lost status of application members
  * use start time to judge need to cancel gps request and force_update
  */
 public void reviewTrackStatus(){

/*	  	 if (isAppLong()){
	  		 
		  if(!isGPSstopped){	    	
//	    	if((getRecordingTrack().getTrackBean().getStatus()!=QiYouConstant.TRACK_STATUS_TRACKING ||!canRecord) || playBack)  {
//	    		 QLog.getLogger().d(dTAG,TAG+" "+ "recordingTrackStatus: " +getRecordingTrack().getTrackBean().getStatus() +
//	    				 ",app.canRecord "+canRecord +",app.playBack " +playBack);
	    	 if(!isCanRecord()){ 
			     QLog.getLogger().d(dTAG,TAG+" Application start time since now(s): " +(System.currentTimeMillis() - startTime)/1000); 
	    		 stopAndroidGPSRequest();  
		    	 QLog.getLogger().d(dTAG,TAG+" GPS request is  cancelled. ");		    	 
		    } 
	    }else{  //GPS request is stopped, to check recording track status.This will be triggered by force update.
//	    	if(getRecordingTrack().getTrackBean().getStatus() == QiYouConstant.TRACK_STATUS_TRACKING && canRecord)
	    	{
	    		startAndroidGPSRequest();	    		
	    		QLog.getLogger().d(dTAG,TAG+" "+ "GPS request is  started by force-update. ");		    	 
	    	}
	    }
	 } */
	  /*	if (isAppLong()){
	  		if(isCanRecord()){ 
	  			if(isGPSstopped)
	  				startAndroidGPSRequest();	
	  		}else{
	  			if(!isGPSstopped)
	  				stopAndroidGPSRequest(); 
	  		}
	  	}*/
	  	 
	  	 
	    	
//	   canRecord =QiYouConstant.PLAYBACK_CAN_RECORD; 
//	   initialLocationParameters(); 
//	   QLog.getLogger().d(TAG," read app.sumofftime "+ sumOfftime );
// 	   QLog.getLogger().d(TAG," read app.sumPaused "+  sumPaused );
		
 }
 
  
 

 /*
  * stop all services/ activities
  * release all resource
  * 
  */
 public void ExitApp() 
 {
	   QLog.getLogger().d(dTAG,TAG+" ------------------------ExitApp called.------------------------");
	  // 取消监听 SDK 广播
	 try{
		 unregisterReceiver(mReceiver);	
	 }catch(Exception e){
		 Utils.logStackTrace(e, TAG);
	 }
	 forceDbUpdate(true);
//	 stopAndroidGPSRequest();
	 unregTimeTick();
	 setPreferences(true,false);
//	 Toast toast=	Toast.makeText(this,  " QY Application is Exiting..bye..  "+TAG, Toast.LENGTH_LONG );
//		toast.show(); 
	 stopNetworkLocationRequest();
//	 syncStatisticsBeforExit();
	 final long start = System.currentTimeMillis();
	
	 if (isStaticsticsDone) {
		isStaticsticsDone = false;
	}
	 syncStatisticsBeforExit();
	 MobclickAgent.onKillProcess(this); //用来保存统计数据。

	 final Handler  handler = new Handler(){ 
			@Override
			public void handleMessage(Message msg) {  
				if (msg.what==0) {  
					 QLog.getLogger().d(dTAG, TAG+" to exit app. sync cost(s) " + (System.currentTimeMillis() -start)/1000);
					 if(!isUIactive ){
						 
						 System.exit(0);	 
					 }
				}
			}};
			
	 new Thread(){

			@Override
			public void run() {
				//需要花时间计算的方法		
				int topWaiting=0;
				
			   
	        	while(!isStaticsticsDone
	        			 
	        			){ //||start,end, type){ 
	        	 try {
	 				Thread.sleep(500);
	 				topWaiting+=500;
	 				 QLog.getLogger().d(dTAG, TAG+"  Waiting: " + topWaiting);
	 				if(topWaiting>QiYouConstant.MAX_TIME_GET_TRACK_FROM_DB*10  )
	 				{ 
	 				 
	 					break;
	 				}
	 				 
	 			  } catch (InterruptedException e) {
	 				// TODO Auto-generated catch block
	 				Utils.logStackTrace(e, TAG);
	 				handler.sendEmptyMessage(0);
	 				}
		    	}
	        	 QLog.getLogger().d(dTAG, TAG+" get sync done topWaiting: " +topWaiting);
				//向handler发消息
				handler.sendEmptyMessage(0);
			}}.start(); 
			
//	 System.exit(0);
 }
 

  /*
   * when startup,check network status\
   * initialize httpClient
   * 1. update GEOs
   * 2. get the location info, which city located? 
   */
 public void worksOnLine(int trackId){
	 
	 mHttpClient = this.createHttpClient();	 
	 
	 int networkType =Utils.getNetworkType(this);
	 if(networkType==-1) return; //no active network
	 
	 if(trackId>0 || networkType == QiYouConstant.NETWORK_TYPE_WIFII && Utils.canUpdateGEOfootmark(this))
	 {
	 
//	  Intent serviceIntent = new Intent(this, OfflineMapService.class);
//       startService(serviceIntent);  
        
       Intent serviceIntent = new Intent(this, TrackGEOService.class);
 	  
 	   if(trackId>0)
 		   serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_GET_CURRENT_TRACK_BY_ID,trackId );  //update all tracks that KEY_TRACK_GEO_STATUS !=1 
 	   else
 		  serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_TRACK_GEOS,-1 );  //update all tracks that KEY_TRACK_GEO_STATUS !=1 
 	   
	   startService(serviceIntent);  
// 	   getCurrentCity(); 
//	  startNetworkLocationRequest(true);
	 }
//	 startNetworkLocationRequest(true);
	 
 }

 
 
 
 
 public   boolean canUpdateOffmap( ){
	 return Utils.canUpdateOffmap(this);
 }
 
 
public boolean isOfflimeMapWorking =false;
public boolean isNetworkLocationRequestStarted =false;

/*
 * when activity is created, call this method with isOffMap=true to check and update the offline maps  .
 */
public void startNetworkLocationRequest(Boolean isOffMap){
 
//	if(( QiYouConstant.NETWORK_CONNECTED || Utils.isNetworkConnected(this)) _&& !isNetworkLocationRequestStarted){  
	if( Utils.isNetworkConnected(this) && !isNetworkLocationRequestStarted || this.isLocationFinding){  

//	if(  Utils.isNetworkConnected(this)){  
		
		
	/*	
		if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.CALL_PHONE)
                != PackageManager.PERMISSION_GRANTED)
        {

			ContextCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},    1           );
        }
		
		*/
		
		 
		 Intent serviceIntent = new Intent(this, BDLocationSvc.class);
		  if(isOffMap){ 
 			  serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_GET_CURRENT_CITY, "");
 			 QLog.getLogger().d(dTAG,TAG+" start to request offmap information from network " ); 
		  }
		  else{
			  serviceIntent.putExtra(LocationManager.KEY_LOCATION_CHANGED, "");
			  QLog.getLogger().d(dTAG,TAG+" start to request location information from network " ); 
		  }  
		  
		  if(isOffMap){ 
			   
			  if(/*this.mMapview ==null || */!Utils.canUpdateOffmap(this) )return;
 			  serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_NETWORK_LOCATION,QiYouConstant.EXTRA_KEY_GET_CURRENT_CITY);
 			  startService(serviceIntent); 
 			 // QLog.getLogger().d(dTAG,TAG+" start to request offmap information from network " ); 
		  }
		  else if( canRecord()||this.isRouting ||isLocationFinding){ //network location request.
			  serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_NETWORK_LOCATION,LocationManager.KEY_LOCATION_CHANGED);
 			 QLog.getLogger().d(dTAG,TAG+" start to request location information from network " ); 
			  startService(serviceIntent);  
//			 if(QiYouConstant.DEVELOPER_MODE) Toast.makeText( this, "无gps信号,启动..网络定位....", Toast.LENGTH_SHORT).show(); 
		  }  
		  
	     
	     
                  
	}
	 
 
//	
//	
////	 	if(!isNetworkLocationRequestStarted){
//	 		if(lm==null){
//				lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);	 
//			}
//			lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000,0, netwrokLocationListenerPendingIntent);
//	 	  
//	 	
//	 	isNetworkLocationRequestStarted =true;
//		QLog.getLogger().d(dTAG, TAG+ " Network location service request started....");
		
 }
public void stopNetworkLocationRequest(){
	
	if( mLocClient==null) return;	 
	
	mLocClient.getLocOption().setScanSpan(1); //set it less than 1000, can stop its location request.
	isNetworkLocationRequestStarted=false;
	 // QLog.getLogger().d(dTAG,TAG+" network location request is going to be cancled.");
//	 if(QiYouConstant.DEVELOPER_MODE) Toast.makeText( this, "停止...网络定位.... 停止", Toast.LENGTH_SHORT).show(); 
//	if(isNetworkLocationRequestStarted){
//		 if(lm==null){
//			 lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
//		 }
//         lm.removeUpdates(netwrokLocationListenerPendingIntent);
//	} 
//	isNetworkLocationRequestStarted =false;
 }
 
 

/*public StatTrack getStatTrack() {
	if(statTrack==null)statTrack= new StatTrack();
 
		
	return statTrack;
}
public void setStatTrack(StatTrack statTrack) {
	this.statTrack = statTrack;
}*/

public GEOaddress getGEOinfo() {
	return GEOinfo;
}
public void setGEOinfo(GEOaddress gEOinfo) {
	GEOinfo = gEOinfo;
	this.setlastLocation((float)Utils.getggLat(gEOinfo.getLat() , gEOinfo.getLon()),(float)Utils.getggLon(gEOinfo.getLat(), gEOinfo.getLon()));
}
 
/*
boolean getBdGEOadress(double lat, double lon){
	
	if(mSearch ==null){
  	   mSearch= GeoCoder.newInstance();
  	   mSearch.setOnGetGeoCodeResultListener(new MySearchListener());
     }
	 
	  GEOadress=null;
	  isGEOerror=false;
//	 double blat = Utils.getbdLat(lat,  lon);
//     double blon = Utils.getbdLon(lat,  lon);  
    LatLng ptCenter = new LatLng( lat,  lon) ;
//    LatLng ptCenter = new LatLng(Utils.getbdLat(lat,  lon), Utils.getbdLon(lat,  lon));
    isGEOerror =mSearch.reverseGeoCode(new ReverseGeoCodeOption() .location(ptCenter));
    return isGEOerror;
    
  
}
 
  AddressComponent  GEOadress;
  ReverseGeoCodeResult addressResult;
 public boolean isGEOerror =false;
 class MySearchListener implements OnGetGeoCoderResultListener { 
 
		@Override
		public void onGetGeoCodeResult(GeoCodeResult result) {
			// TODO Auto-generated method stub
			  QLog.getLogger().d(dTAG,TAG+" ----------------- onGetGeoCodeResult  "  + result.getAddress());
		}

		@Override
		public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
			// TODO Auto-generated method stub
//			isGEOerror = error>0;
			
			GEOadress = result.getAddressDetail();		
			if(GEOadress!=null)
				City=GEOadress==null?"":GEOadress.city;
			addressResult =result;
			
			QLog.getLogger().d(dTAG,TAG+" ----------------- onGetReverseGeoCodeResult  "  + result.getAddress());
			
		}
		}
 */
 @Override
 public void onLowMemory() {
     // TODO Auto-generated method stub
     super.onLowMemory();
//     this.shutdownHttpClient(); //will cause android.os.NetworkOnMainThreadException
//     Utils.logStackTrace(new Exception(" Memory Low..........,allocated memory by M:"+ android.os.Debug.getNativeHeapAllocatedSize()/1000/1000),dTAG);
      QLog.getLogger().dLog(dTAG,TAG+"................. Memory Low..........,allocated memory by M:"+ android.os.Debug.getNativeHeapAllocatedSize()/1000/1000);
//     ImageLoader.getInstance().clearMemoryCache();
//     ImageLoader.getInstance().clearDiskCache();
//     initialImageLoader();
 }
 
 public void initialImageLoader(){
	 
	 File cacheDir=new File(QiYouConstant.PHOTO_CACHE_PATH);
	 if(!cacheDir.exists())cacheDir.mkdirs();
		DisplayImageOptions defaultOptions = new DisplayImageOptions
				.Builder()
//				.resetViewBeforeLoading()
				.showImageForEmptyUri(R.drawable.empty_photo) 
				.showImageOnFail(R.drawable.empty_photo) 
				.cacheInMemory(true)
//				.cacheOnDisc(true)
				.cacheOnDisk(true)				
				.bitmapConfig(Bitmap.Config.RGB_565) 
//				 .imageScaleType(ImageScaleType.EXACTLY)  //good
			    .imageScaleType(ImageScaleType.EXACTLY_STRETCHED) //better
				.build();
		ImageLoaderConfiguration config = new ImageLoaderConfiguration
				.Builder(getApplicationContext())
				.memoryCache(new WeakMemoryCache())
				.denyCacheImageMultipleSizesInMemory()
				 .diskCache(new UnlimitedDiscCache(cacheDir))
//				 .memoryCacheExtraOptions(480, 800) // default=device screen dimensions
 
//                 .diskCacheExtraOptions(480, 800, CompressFormat.JPEG, 75)

				.defaultDisplayImageOptions(defaultOptions)
				.tasksProcessingOrder(QueueProcessingType.FIFO)
				.memoryCacheSize(50 * 1024 * 1024)
				.diskCacheSize(100 * 1024 * 1024)//
//				.diskCacheFileCount(100)//缓存一百张图片
				.writeDebugLogs()
				.build();  
		ImageLoader.getInstance().init(config);
 }
 
 
 
 
 /* class mSensorListener implements SensorEventListener{

	@Override
	public void onSensorChanged(SensorEvent event) {
		// TODO Auto-generated method stub
		  if (event.sensor.getType() ==SensorManager.sen )  {
              oy=values[1];
              oz=values[2];
          }
          if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
              ax=values[0];
              ay=values[1];
          }   
		
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// TODO Auto-generated method stub
		
	}

	 
	 
 }
 */
 
 
 public static volatile PowerManager.WakeLock lockStatic=null;

 synchronized public static PowerManager.WakeLock getLock(Context context) {
   if (lockStatic == null) {
     PowerManager mgr=
         (PowerManager)context.getSystemService(Context.POWER_SERVICE);

     lockStatic=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
     lockStatic.setReferenceCounted(true);
   }

   return(lockStatic);
 }
 
 
 public void regTimeTick(){
//		IntentFilter javaFilter = new IntentFilter();  
//	    javaFilter.addAction("android.intent.action.TIME_TICK");  
//	    registerReceiver(timeTickReceiver, javaFilter);
//	 unregTimeTick();
	 if(this.isLastTrackExist() && !playBack){
//	 if(this.canRecord()){ 
		 forceDbUpdate(false);
		 if(timeTickIntent==null)
			 timeTickIntent = new Intent(this, TimtickService.class);	   
//	 	 serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_GET_CURRENT_TRACK_BY_ID, trackId);
		 
		 // QLog.getLogger().dLog(dTAG,TAG+"...startting service timeTickIntent TimtickService.....," );
		//  
	 	 startService(timeTickIntent);
	 }
	 
	}

 public void unregTimeTick(){
	 if(timeTickIntent==null)
		 timeTickIntent = new Intent(this, TimtickService.class);
	 this.stopService(timeTickIntent);
	 // // // QLog.getLogger().dLog(dTAG,TAG+"...stopped service timeTickIntent .....," );
 }
 
 
 
 
 
 

 public void initialStatistics(){ 
//	 testEnde();
	 StringBuffer statJson=new StringBuffer();
 /*		try { 
			
			statJson.append(Utils.readSDFile(QiYouConstant.STAT_TEXT));
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			Utils.logStackTrace(e, TAG);
		}*/
		 
	 
	
//		statJson.append(FileUtil.readFile(QiYouConstant.STAT_TEXT+"_en", crypto, entity)); 
		
	  
	  try {
		   // QLog.getLogger().d(dTAG, " begin to read Statistics from "+ QiYouConstant.STAT_TEXT+"_en ..........................................." );
		  
//			    FileUtil.decodeFile(QiYouConstant.STAT_TEXT+"_en", QiYouConstant.STAT_TEXT, crypto, entity);   
//			statJson.append(Utils.readSDFile(QiYouConstant.STAT_TEXT));
			statJson.append(FileUtil.readEncodedFile(QiYouConstant.STAT_TEXT, crypto, entity));
//			 // // QLog.getLogger().d(dTAG, " QiYouConstant.STAT_TEXT is: "+QiYouConstant.STAT_TEXT );
			 // QLog.getLogger().d(dTAG, "  statJsn is: "+statJson.toString() );
			  if(QiYouConstant.DEVELOPER_MODE)
				  Utils.writeSDFile(QiYouConstant.STAT_TEXT+"_de", statJson.toString());  
//		  	Utils.writeSDFile(QiYouConstant.STAT_TEXT+"_test_dd",FileUtil.readFile(QiYouConstant.STAT_TEXT+"_test", crypto, entity)); 
		  	
	        mStatistics= (Statistics)Utils.getGsonObject(statJson.toString(), Statistics.class) ;
	        
//	        // // // QLog.getLogger().d(dTAG, " read Statistics from "+ QiYouConstant.STAT_TEXT+"_en ........................................... done" );
		 
		 }catch( JsonSyntaxException je){
			 Utils.logStackTrace(je, TAG);
			 mStatistics=null;
			}  catch (IOException e) {
//			// TODO Auto-generated catch block
				e.printStackTrace();
		}  
	  
	  
	  mStatistics =mStatistics==null?new Statistics():mStatistics;
	  
	  HashMap<String,GPItem> deltaList=new HashMap<String,GPItem>();	
	  
	  if(mStatistics!=null && mStatistics.getGpList().size()>100){  //remove duplicated ones
		  int ikey=0;
		  GPItem item;
		  for(Integer key:mStatistics.getGpList().keySet()){
			  item =mStatistics.getGpList().get(key);
			  if(item!=null){
				  deltaList.put(item.getLat()+"_"+item.getLng(), item);
			  }
		  }
		   
		  mStatistics.getGpList().clear();
		  for(String key:deltaList.keySet()){
			  item =deltaList.get(key);
			  if(item!=null){
				  mStatistics.getGpList().put(ikey, item);
				  ikey++;
			  }
		  }
	  }
	  
	  
	  
 }
 
 public void writeStatiscs(){
	 try { 
//		 Gson gson = new Gson();  
		 
	     Utils.writeSDFile(QiYouConstant.STAT_TEXT+"_tmp",Utils.getGsonString(mStatistics)); 
		     FileUtil.encodeFile(QiYouConstant.STAT_TEXT, QiYouConstant.STAT_TEXT+"_tmp", crypto, entity);
		 
//		 FileUtil.decodeFile(QiYouConstant.STAT_TEXT+"_conseal_en", QiYouConstant.STAT_TEXT+"_conseal_plain", crypto, entity);
		 
	    
//	     FileUtil.writeFile(this.crypto,this.entity, QiYouConstant.STAT_TEXT+"_conseal",  gson.toJson(mStatistics) ); 
//	     FileUtil.writeFile(this.crypto,this.entity, QiYouConstant.STAT_TEXT+"_test", "a" );
//	     Utils.writeSDFile( QiYouConstant.STAT_TEXT+"_test_a","a" );		
//	     Utils.writeSDFile(QiYouConstant.STAT_TEXT+"_test_a_dd",FileUtil.readFile(QiYouConstant.STAT_TEXT+"_test", crypto, entity)); 
		} catch (IOException e) {
			// TODO Auto-generated catch block
			Utils.logStackTrace(e, TAG); 
		/*} catch (CryptoInitializationException e) {
			// TODO Auto-generated catch block
			Utils.logStackTrace(e, TAG); 
		} catch (KeyChainException e) {
			// TODO Auto-generated catch block
			Utils.logStackTrace(e, TAG);
			 */
		}
 }
 
 
 
 
 
public   TypeStatistics getTracksStat(int trackType,long startDate,long endDate){
		
//		int totalChartSize=11;
		
//		 if(activity.app.statisticsTrack==null )
//		initialStatTracks();
		
		//startDate=0;, 	endDate 
	  TypeStatistics mTypeStatistics = new TypeStatistics();
		if( getStatisticsTrack(trackType)==null) return mTypeStatistics;//no records for selected type or date.
//		QLog.getLogger().d(dTAG, TAG+  " dddddddddddddddddddddd-------------------begin to get StatTrack. ------------of type-"+ trackType  );
		 	
	 
		
		 ConcurrentHashMap<Integer,Statics_bean> sbs = getStatisticsTrack(trackType).getSbs();
		 Statics_bean sb;
		 int sbCnt=0;
		 for(Integer key :sbs.keySet()){
			 sb=sbs.get(key); 
			 if(sb==null)continue;
			 
			 if( (
					startDate>0 && endDate >= startDate
					&&	
					(sb.getStartTime()>=startDate && sb.getStartTime()<=endDate
					 ||sb.getEndTime()>=startDate && sb.getEndTime()<=endDate
					)
					||(startDate == endDate && startDate==0)
				)
				&& sb.getType() == trackType )						
				 mTypeStatistics.getSbs().put(sb.getTrackid(), sb);
			} 
		
		StatTrack st = new StatTrack();			
		for(Integer key : mTypeStatistics.getSbs().keySet()){
		    sb=mTypeStatistics.getSbs().get(key);
//			st.seteDownDist(sb.geteDownDist() );
//			st.seteUpDist( sb.geteUpDist()+sb.geteDownDist());
			st.setUpDistE( sb.geteUpDist());
			st.setTopSpeed(sb.getTopSpeed() );		       
			st.setPause(sb.getPause() );
			st.setOffTime( sb.getOffTime()); 
			st.setDist(sb.getDist());	 
 		st.setMaxR( sb.getMaxR());
 		st.setSportTime( sb.getSportTime());
 		st.setAvSpeed(sb.getAvs());
 		st.setTavSpeed(sb.getTavs());
 		st.setBurn(sb.getBurn());
// 		st.setTotalTime(sb.getSportTime()+sb.getPause());
 		st.setTotalTime(sb.getTotalTime());
 		st.setUpDist(sb.getUpDist());
 		st.setDownDist(sb.getDownDist());
 		st.setMaxEle(sb.getMaxEle());
 		st.setMinEle(sb.getMinEle());
 		st.setMinTimeKm(sb.getKmTime());
// 		QLog.getLogger().d(dTAG, TAG+  "ddddddddddddddd getStatTracks------------------"  );
// 		
// 		QLog.getLogger().d(dTAG, TAG+  "ddddddddddddddd sb.getDistance()"+sb.getDistance()  );
// 		QLog.getLogger().d(dTAG, TAG+  "ddddddddddddddd sb.getSportTime()"+sb.getSportTime()  );
// 		QLog.getLogger().d(dTAG, TAG+  "ddddddddddddddd sb.getAVS()"+sb.getAVS()  );
// 		QLog.getLogger().d(dTAG, TAG+  "ddddddddddddddd sb.getPause()"+sb.getPause()  );
 		
		}
	
		mTypeStatistics.setStatTrack(st); 
//		QLog.getLogger().d(dTAG, TAG+  " dddddddddddddddddddddd-------------------Get StatTrack. -------------"  );
		
		 
		return mTypeStatistics;
	}
 
 
 
 
 
 
 
 
 
 
 
 public TypeStatistics getStatisticsTrack(int type){
	 TypeStatistics mTypeStatistics =new TypeStatistics();
//	 QLog.getLogger().d(dTAG,TAG+"-------...mStatistics==null .....,"+(mStatistics==null)+startTime );
	 if(mStatistics==null && !statTrackLoading) {
		 getStaticsTracks();
		
	 }else if(mStatistics!=null){
		 mTypeStatistics =mStatistics.getStatisticsTracks().get(Integer.valueOf(type));
//		 if(statTrack==null || mTypeStatistics.getSbs().keySet().size()==0){
		 if(mTypeStatistics==null || mTypeStatistics.getSbs().keySet().size()==0){
			 this.getStaticsTracks(type);
//			 return new TypeStatistics();
		 }
	 }	  
		 return mTypeStatistics;		 
 }
	public void updateStatistics(){
		
		 new Thread(){
				
				@Override
				public void run() { 
							
					QLog.getLogger().d(dTAG,  TAG+"  begin to  Merge Track statiscs: ------------------->");
//					if(!isUIactive ||
					if( 
							 recordingTrack==null				
							||recordingTrack.getTrackBean().getTrackId()==0
//							||isLostGps()
//							||System.currentTimeMillis()- recordingTrack.getTrackBean()
//									.getLastdbTime() >2* QiYouConstant.MAX_TIME_FORCE_UDATE				
							){
						QLog.getLogger().d(dTAG,  TAG+"  1 return not merge statiscs: ------------------->");
						return;
					}
					
					 if(mStatistics!=null && !statTrackLoading ) {
//							QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: ------------------->");
//							QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: Current  recordingTrack     tb.getLastdbTime():?" +  Utils.getFormatedTime( recordingTrack.getTrackBean().getLastdbTime()  ));
						 mStatistics.mergeTrack(recordingTrack);
//						 if( canSendLocation2UI)
							 writeStatiscs();
						 return;
					 }else{
						 // QLog.getLogger().d(dTAG,  TAG+"  mStatistics!=null ? "+(mStatistics!=null));
						 // QLog.getLogger().d(dTAG,  TAG+"  statTrackLoading ? "+statTrackLoading);
						 // QLog.getLogger().d(dTAG,  TAG+"  2 return not merge statiscs: ------------------->");
					 }
					

				}}.start();   
			
				
	
		
		/*Intent locIntent = new Intent(QiYouConstant.ACTION_NEW_WAYPOINTS_TO_SAVE); 
		locIntent.putExtra(QiYouConstant.EXTRA_KEY_FORCE_UPDATE_STAT,1);  
		sendBroadcast(locIntent);*/
		
		
	}
	
	public void updateUIstatus(boolean isShowing){
		canSendLocation2UI =isShowing;
		pEditor.putBoolean(QiYouConstant.PK_BL_CAN_UPDATE_UI,canSendLocation2UI);
		 
	    pEditor.commit();
	}

	 

	@Override
	public void onTerminate() {
		// TODO Auto-generated method stub
		super.onTerminate();
		this.shutdownHttpClient();
		mTts.stopSpeaking(mTtsListener);
//        // 閫?嚭鏃堕噴鏀捐繛鎺?
		mTts.destory();
		QLog.getLogger().dLog(TAG,   "  Application Terminited."  );
		
		
	}

 
	/**创建HttpClient实例
	 * @return
	 */
	private HttpClient createHttpClient(){
		HttpParams params = new BasicHttpParams();
		//设置基本参数
		HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
		HttpProtocolParams.setContentCharset(params, CHARSET);
		HttpProtocolParams.setUseExpectContinue(params, true);
		//超时设置
		/*从连接池中取连接的超时时间*/
		ConnManagerParams.setTimeout(params, 1000);
		/*连接超时*/
		HttpConnectionParams.setConnectionTimeout(params, 4000);
		/*请求超时*/
		HttpConnectionParams.setSoTimeout(params, 8000);
		//设置HttpClient支持HTTp和HTTPS两种模式
		SchemeRegistry schReg = new SchemeRegistry();
		schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
//		schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
//		schReg.register(new Scheme("https",  new EasySSLSocketFactory(), 443));  
		//使用线程安全的连接管理来创建HttpClient
		ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);
		HttpClient client = new DefaultHttpClient(conMgr, params);
		return client;
	}
	private void shutdownHttpClient(){
		if(mHttpClient != null && mHttpClient.getConnectionManager() != null){
			mHttpClient.getConnectionManager().shutdown();
		}
	}
	  
	
	public HttpClient getHttpClient(){
		if(mHttpClient==null)createHttpClient();
		return mHttpClient;
	}
	public HashMap<Integer,ArrayList<String>> getNewCategoryList() {
		if(newCategoryList==null)newCategoryList =new HashMap<Integer,ArrayList<String>>();
		return newCategoryList;
	}
	public void setNewCategoryList(HashMap<Integer,ArrayList<String>> newCategoryList) {
		this.newCategoryList = newCategoryList;
	}
	public HashMap<Integer,ArrayList<String>> getDelCategoryList() {
		if(delCategoryList==null)delCategoryList =new HashMap<Integer,ArrayList<String>>();
		return delCategoryList;
	}
	public void setDelCategoryList(HashMap<Integer,ArrayList<String>> delCategoryList) {
		this.delCategoryList = delCategoryList;
	}
	public boolean updateCates(String newCate){
		if(!TextUtils.isEmpty(newCate) && !mStatistics.getCategoryList().containsKey(newCate)){  
			 //add to newCateList for insert to db
				if( getNewCategoryList().get(0) ==null){
					 getNewCategoryList().put(0, new ArrayList<String>());
					 getNewCategoryList().get(0).add(newCate);
				}else if(! getNewCategoryList().get(0).contains(newCate))
					  getNewCategoryList().get(0).add(newCate);
				
				
				
				//add the new cate to the statics for catelist update ui
				ArrayList<Integer> ids=  mStatistics.getCategoryList().get(newCate);
				if(ids==null)ids =new ArrayList<Integer>();
				if(!ids.contains(0)){
					ids.add(0);
				}
				 mStatistics.getCategoryList().put(newCate, ids); 
		 }
		
		
		if(	    
				mStatistics.mergeCates(getNewCategoryList(), true) ||
				mStatistics.mergeCates(getDelCategoryList(), false)
		 ){
			
			Intent serviceIntent = new Intent(this, TrackDbServiceBackground.class);	   
		    serviceIntent.putExtra(QiYouConstant.UPDATE_CATE_TRACK , 1);   
		    startService(serviceIntent);
		    return true;
		}
		 return false;
	}
	 
	
	public void updateTrackSvrNos( HashMap<Integer,Integer> ids){  
		 Intent serviceIntent = new Intent(this, TrackDbServiceBackground.class);	   
		 serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_UPDATE_SVRNOS , ids) ;   
		 startService(serviceIntent);
	}
	
	/*
	 * update track md
	 */
	public void updateTrackMds( int trackId,String mds){  
		 Intent serviceIntent = new Intent(this, TrackDbServiceBackground.class);	   
		 serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_UPDATE_MEDIAS ,  mds) ;   
		 serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_ID , trackId) ;     
		 startService(serviceIntent);
	}
	
	public void updateTrackAvStatus(int trackId){
		    Intent serviceIntent = new Intent(this, TrackDbServiceBackground.class);	   
		    serviceIntent.putExtra(QiYouConstant.UPDATE_TRACK_AVSTATUS , trackId);   
		    startService(serviceIntent);
	}
	public void initialCates(){
 		return;
//		 QLog.getLogger().d(dTAG, " .................initialCates called");
		 
		/*String newCate="通勤";
		if(mStatistics.getCategoryList().containsKey(newCate)) return;
		updateCates(newCate);
		updateCates("拉练");
		updateCates("休闲");
		updateCates("越野");
		updateCates("竞赛"); */
//		updateCates("环湖");
	}
	public ArrayList<String> getQueryCategoryList() {
		if(queryCategoryList==null)queryCategoryList=new ArrayList<String>();
		return queryCategoryList;
	}
	public void setQueryCategoryList(ArrayList<String> queryCategoryList) {
		this.queryCategoryList = queryCategoryList;
	}
	
	
	private SpeechSynthesizer mTts;
	private Toast mToast;
	private void initialSpeech(){
//	 	请的应用的appid
    	SpeechUtility.getUtility(this.getApplicationContext()).setAppid("54769bf1");
	// 初始化合成对象
	 mTts = new SpeechSynthesizer(this, mTtsInitListener);
	 mToast = Toast.makeText(this,"",Toast.LENGTH_LONG); 		
}
	
	/**
     * 鍒濇湡鍖栫洃鍚?
     */
    private InitListener mTtsInitListener = new InitListener() {

		@Override
		public void onInit(ISpeechModule arg0, int code) {
			Log.d(TAG, "InitListener init() code = " + code);
        	if (code == ErrorCode.SUCCESS) {
        		setParam();
        	}
//        	mTts.startSpeaking("你",   mTtsListener);
//        	speech("你好");
		}
    };
        
    /**
     * 鍚堟垚鍥炶皟鐩戝惉銆?
     */
    private SynthesizerListener mTtsListener = new SynthesizerListener.Stub() {
        @Override
        public void onBufferProgress(int progress) throws RemoteException {
//        	 Log.d(TAG, "onBufferProgress :" + progress);
//        	 showTip("onBufferProgress :" + progress);
        }

        @Override
        public void onCompleted(int code) throws RemoteException {
//        	Log.d(TAG, "onCompleted code =" + code);
//            showTip("onCompleted code =" + code);
        }

        @Override
        public void onSpeakBegin() throws RemoteException {
//            Log.d(TAG, "onSpeakBegin");
//            showTip("onSpeakBegin");
        }

        @Override
        public void onSpeakPaused() throws RemoteException {
//        	 Log.d(TAG, "onSpeakPaused.");
//        	 showTip("onSpeakPaused.");
        }

        @Override
        public void onSpeakProgress(int progress) throws RemoteException {
//        	Log.d(TAG, "onSpeakProgress :" + progress);
//        	showTip("onSpeakProgress :" + progress);
        }

        @Override
        public void onSpeakResumed() throws RemoteException {
//        	Log.d(TAG, "onSpeakResumed.");
//        	showTip("onSpeakResumed");
        }
    };
    
  
	
    
//	private void showTip(final String str){
//	 
//				mToast.setText(str);
//				mToast.show(); 
//	}
    
    private int speekingLevel=0;
//	public void speech(final String text){
//		 speech(text,1);
		/* if(!QiYouConstant.CAN_SPEAK)return;
		 
		 new Thread(){
				
				@Override
				public void run() { 
							
					 while(mTts.isSpeaking()){
						 try {
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					 }
						mTts.startSpeaking(text,   mTtsListener);

				}}.start();  */
			
//	 }
	 
	 public void speech(final String text,final int level){
// 		 if(!QiYouConstant.CAN_SPEAK)return;
		 
		 new Thread(){
				
				@Override
				public void run() {  
					 while(mTts.isSpeaking() &&level <=speekingLevel){
						 try {
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					 }
					 speekingLevel =level;
					 mTts.startSpeaking(text,   mTtsListener); 

				}}.start();  
			
	 }
	 
	 
	 public void stopSpeech(){
		 
			{
//				mTts.pauseSpeaking(mTtsListener);
				mTts.stopSpeaking(mTtsListener);
			}
	 }
	 public void resumeSpeech(){
		 
			{
				mTts.resumeSpeaking(mTtsListener);
			}
	 }
	 public boolean isSpeaking(){
		 
			 return mTts.isSpeaking();
	 }
	 
	 private void setParam(){
		 
	    	// 设置引擎类型
	    	mTts.setParameter(SpeechConstant.ENGINE_TYPE, "local");
	    	// 设置发音人
	    	mTts.setParameter(SpeechSynthesizer.VOICE_NAME, "");  // 设置本地合成发音人 voicer为空，默认通过语音+界面指定发音人
	    	// 设置语速
	    	mTts.setParameter(SpeechSynthesizer.SPEED, "50");
	    	// 设置音调
	    	mTts.setParameter(SpeechSynthesizer.PITCH, "50");
	    	// 开始合成
	     
	    	
	    	// 停止
	    	mTts.stopSpeaking(mTtsListener);
	    	// 暂停播放
	    	mTts.pauseSpeaking(mTtsListener);
	    	// 恢复播放
	    	mTts.resumeSpeaking(mTtsListener);
		 
		}
	
	 
	 public void naviUI(Location loc,String msg){

		 if(! canSendLocation2UI)return;
		 
		 Intent broadcastIntent = new Intent();
			broadcastIntent.setAction(QiYouConstant.ACTION_NEW_LOCATION_GETBACK);
//			broadcastIntent.setFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
			broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); 
		    broadcastIntent.putExtra(QiYouConstant.NEW_NAVIFO_MSG,loc); 
		 sendBroadcast(broadcastIntent);
	 }
	 
	 public HttpResponse httpExecute(String mUrl){
 
 
		  return httpExecute(mUrl,this.getHttpClient()) ;
		 
	 }
	 
	 public HttpResponse httpExecute(String mUrl,HttpClient client){
		 
//		 mUrl="https://addons.mozilla.org/zh-CN/firefox/extensions/bookmarks/";
		    // QLog.getLogger().d(dTAG, "request http of url:" +mUrl);
		    URL url;
		    URI uri = null ;
			try {
				url = new URL(mUrl);
				uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				Utils.logStackTrace(e, dTAG); 
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				Utils.logStackTrace(e, dTAG);
				
			}
		   
		    
		    HttpGet httpget = new HttpGet(uri);
		    HttpResponse response;
			try {
				response = client.execute(httpget);
				  // QLog.getLogger().d(dTAG, " request http response status:" + response.getStatusLine().getStatusCode());
				return response;
			} catch (ClientProtocolException e) {
				// TODO Auto-generated catch block
				Utils.logStackTrace(e, dTAG); 
			} catch (IOException e) {
				// TODO Auto-generated catch block
				Utils.logStackTrace(e, dTAG); 
			} catch (Exception e) {
				// TODO Auto-generated catch block
				Utils.logStackTrace(e, dTAG); 
			} 
			
			/*catch(IllegalArgumentException e){
				Utils.logStackTrace(e, dTAG); 
			} catch(Exception e){
				Utils.logStackTrace(e, dTAG); 
			}*/
		    
		  return null ;
		 
	 }
	 
	 public HttpResponse httpsExecute(String mUrl){
		  return httpExecute(mUrl,sslClient(this.getHttpClient())) ;
		  
	 }
	 

	 public HttpClient sslClient(HttpClient client) {
		    try {
		        X509TrustManager tm = new X509TrustManager() { 
		            public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
		            }

		            public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
		            }

		            public X509Certificate[] getAcceptedIssuers() {
		                return null;
		            }
		        };
		        SSLContext ctx = SSLContext.getInstance("TLS");
		        ctx.init(null, new TrustManager[]{tm}, null);
		        SSLSocketFactory ssf = new MySSLSocketFactory(ctx);
		        ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
		        ClientConnectionManager ccm = client.getConnectionManager();
		        SchemeRegistry sr = ccm.getSchemeRegistry();
		        sr.register(new Scheme("https", ssf, 443));
		        return new DefaultHttpClient(ccm, client.getParams());
		    } catch (Exception ex) {
		        return null;
		    }
		}
	 
	 
	 public class MySSLSocketFactory extends SSLSocketFactory {
	     SSLContext sslContext = SSLContext.getInstance("TLS");

	     public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
	         super(truststore);

	         TrustManager tm = new X509TrustManager() {
	             public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
	             }

	             public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
	             }

	             public X509Certificate[] getAcceptedIssuers() {
	                 return null;
	             }
	         };

	         sslContext.init(null, new TrustManager[] { tm }, null);
	     }

	     public MySSLSocketFactory(SSLContext context) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException {
	        super(null);
	        sslContext = context;
	     }

	     @Override
	     public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
	         return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
	     }

	     @Override
	     public Socket createSocket() throws IOException {
	         return sslContext.getSocketFactory().createSocket();
	     }
	}
	 
	 
	 
	 
 
	 
	  
	 
	 
	  
	 /**
	  * km/h
	  * @return
	  */
	 public float getAVS(){
		 float avspeed =  mStatistics==null?0:mStatistics.getAVS();
		 avspeed =Float.isNaN(avspeed)||avspeed==0?15:avspeed;
		 return avspeed;
		 
	 }
	 /**
	  * m/s
	  * @return
	  */
	 public float getRAVS(){
		   float avSpeed=getAVS();///3600;	  e
		    avSpeed=avSpeed>0?avSpeed:20f;
			avSpeed=avSpeed>40 ?40 :avSpeed;
			avSpeed=avSpeed<18 ?18 :avSpeed; 
			avSpeed=avSpeed/3600*0.8f;
			return avSpeed;
	 }
	 
//	 private static final String BASE_URL = "http://office:8080/qiyouji/";

	  private static AsyncHttpClient client;// = new AsyncHttpClient();
	  
	  private static void initClient(Context context) {
	        if (client != null) {
	            return;
	        }
	        client = new AsyncHttpClient();
	       /* PersistentCookieStore cookieStore = new PersistentCookieStore(context);
	        client.setCookieStore(cookieStore);
	        */
	        
	       
	    }

	  public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
		  try{
//			  pirntCookies();
			  // QLog.getLogger().d(dTAG, "request url is:" +getAbsoluteUrl(url));
	      client.get(getAbsoluteUrl(url), params, responseHandler);
		  }catch(Exception er){
			  Utils.logStackTrace(er, TAG);
		  }
	  }
	  public static void requestWeb(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
		  try{
//			  pirntCookies();
			  // QLog.getLogger().d(dTAG, "request url is:" +getAbsoluteUrl(url));
	      client.get(getWebAbsoluteUrl(url), params, responseHandler);
		  }catch(Exception er){
			  Utils.logStackTrace(er, TAG);
		  }
	  }

	  
	  public static void get3dpart(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
		  try{
//			  pirntCookies();
			  // QLog.getLogger().d(dTAG, "request url is:" +getAbsoluteUrl(url));
	      client.get(url, params, responseHandler);
		  }catch(Exception er){
			  Utils.logStackTrace(er, TAG);
		  }
	  }

	  
	  public static void getEle(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
	      client.get( url, params, responseHandler);
	  }
	  
	  public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
		  pirntCookies();
	      client.post(getAbsoluteUrl(url), params, responseHandler);
	  }

	  public static void post (Context context, String url, HttpEntity entity, String contentType, 
			  ResponseHandlerInterface responseHandler){
		  pirntCookies();
		  client.post(context, getAbsoluteUrl(url),   entity,   contentType,  responseHandler);
	  }

	  public static  HttpContext getHttpContext(){
		  return client.getHttpContext();
	  }

	  private static String getAbsoluteUrl(String relativeUrl) {
	      return QiYouConstant.BASE_URL +"mb"+ relativeUrl;
	  }
	  
	  private static String getWebAbsoluteUrl(String relativeUrl) {
	      return QiYouConstant.BASE_URL +"/"+ relativeUrl;
	  }

	/*public static void setCookieStore(PersistentCookieStore myCookieStore) {
		// TODO Auto-generated method stub
		  
		client.setCookieStore(myCookieStore);
		
	}*/
	public void setAuth(){
		/*	PersistentCookieStore myCookieStore = new PersistentCookieStore(this);
			String name = "uk";  
	        String value = QiYouConstant.PV_ACCESS_TOKEN +"-c-d-x-"+QiYouConstant.PV_USER_ID;  
	        BasicClientCookie clientCookie = new BasicClientCookie(name, value);  
	        clientCookie.setComment("");  
	        clientCookie.setDomain("i7lv.com");  
//	        clientCookie.setExpiryDate("");  
	        clientCookie.setPath("//");
	        myCookieStore.clear();					// if it is okay?
			myCookieStore.addCookie(clientCookie);
			client.setCookieStore(myCookieStore);
			client.setBasicAuth(String.valueOf(QiYouConstant.PV_USER_ID), QiYouConstant.PV_ACCESS_TOKEN);
			
			for(Cookie c:myCookieStore.getCookies()){
				QLog.getLogger().d(dTAG,TAG+ " print cookies ~~ name:"+c.getName()+",value:"+c.getValue());
				QLog.getLogger().d(dTAG,TAG+ " print cookies ~~ domain:"+c.getDomain()+",path:"+c.getPath());
				QLog.getLogger().d(dTAG,TAG+ " print cookies ~~ ExpiryDate():"+c.getExpiryDate()+",ports:"+c.getPorts());
				QLog.getLogger().d(dTAG,TAG+ " print cookies ~~ version():"+c.getVersion() );
			}
			*/

		
			String token;// =Utils.encodeBase64(QiYouConstant.PV_ACCESS_TOKEN);
			token =QiYouConstant.PV_ACCESS_TOKEN;
			client.setBasicAuth(String.valueOf(QiYouConstant.PV_USER_ID), token);  
//			   QLog.getLogger().d(dTAG,TAG+ " Original token "+ QiYouConstant.PV_ACCESS_TOKEN );
//			QLog.getLogger().d(dTAG,TAG+ " encoded token   "+ Utils.encodeBase64(QiYouConstant.PV_USER_ID+":"+QiYouConstant.PV_ACCESS_TOKEN) );
	 }
	
	/*// 设置cookie
	public static void synCookies(Context context, String url) {  
	    CookieSyncManager.createInstance(context);  
	    CookieManager cookieManager = CookieManager.getInstance();  
	    cookieManager.setCookie(url, "uid=1243432");              
	    CookieSyncManager.getInstance().sync();  
	}

	// 清除cookie
	private void removeCookie(Context context) {
	    CookieSyncManager.createInstance(context);  
	    CookieManager cookieManager = CookieManager.getInstance(); 
	    cookieManager.removeAllCookie();
	    CookieSyncManager.getInstance().sync();  
	}*/

	
	 static void pirntCookies(){
//		  AsyncHttpClient client = new AsyncHttpClient(); 
			HttpContext httpContext =QiYouApplication.getHttpContext();// QiyouRestClient.getHttpContext();
			
			CookieStore cookies = (CookieStore) httpContext.getAttribute(ClientContext.COOKIE_STORE);//获取AsyncHttpClient中的CookieStore
			QLog.getLogger().d(dTAG," begin to print cookies...............................");
			if(cookies!=null){
				for(Cookie c:cookies.getCookies()){
					QLog.getLogger().d(dTAG,TAG+ " print cookies ~~ name:"+c.getName()+",value:"+c.getValue());
					QLog.getLogger().d(dTAG,TAG+ " print cookies ~~ domain:"+c.getDomain()+",path:"+c.getPath());
					QLog.getLogger().d(dTAG,TAG+ " print cookies ~~ ExpiryDate():"+c.getExpiryDate()+",ports:"+c.getPorts());
					QLog.getLogger().d(dTAG,TAG+ " print cookies ~~ version():"+c.getVersion() );
				}
			}else{
				QLog.getLogger().d(dTAG,"main  before~~,cookies is null");
			}
			QLog.getLogger().d(dTAG," print cookies end   ...............................");
/*			//save cookie
			 PersistentCookieStore myCookieStore = new PersistentCookieStore(context);
			 QiyouRestClient.setCookieStore(myCookieStore);
	        
			httpContext = QiyouRestClient.getHttpContext();
			cookies = (CookieStore) httpContext.getAttribute(ClientContext.COOKIE_STORE);
			if(cookies!=null){
				QLog.getLogger().d(dTAG, "main  after~~,cookies is not null");
				for(Cookie c:cookies.getCookies()){
					QLog.getLogger().d(dTAG,"main after ~~"+c.getName()+","+c.getValue());
				}
			}else{
				QLog.getLogger().d(dTAG, "main  after~~,cookies is null");
			}
			*/
	}
	
	/*
	 *  
	 */
	public boolean isShowSlidTabs(){
		 
		 return pref.getInt(QiYouConstant.PK_INT_TAB_SLICED, 0)<5;
 	}
 
	/*
	 * from a pause to a new pause.
	 */
	public void updateSlidTabs(){
		if(!isShowSlidTabs())return;
		pe.putInt(QiYouConstant.PK_INT_TAB_SLICED,pref.getInt(QiYouConstant.PK_INT_TAB_SLICED, 0)+1 );
		pe.commit();
		
	}


	public int getExistNaviID(){
		return settings.getInt(QiYouConstant.PK_INT_LAST_UNFINISHED_NAVID,-1);
	}
	public int getExistNaviTrackID(){
		return settings.getInt(QiYouConstant.PK_INT_LAST_NAVI_TRACK,-1); 
	}
	 
	public boolean isLastNaviExist(){ 
		return settings.getInt(QiYouConstant.PK_INT_LAST_UNFINISHED_NAVID,-1)>0 ;
	}
	public void setLastNavId(){
//		 Editor pEditor = settings.edit();
		if(this.playBack)return;
		
		     if(isNaving) {
		    	  pEditor.putInt(QiYouConstant.PK_INT_LAST_UNFINISHED_NAVID, naviTrackId);  
		    	  
		    	 if(getRecordingTrack().getTrackBean().getTrackId()>0)
		    	  pEditor.putInt(QiYouConstant.PK_INT_LAST_NAVI_TRACK, getRecordingTrack().getTrackBean().getTrackId());
		    	 
		    	 pEditor.commit();		    	 
		    	 }
		      else{
		    	  clearLastNavId();
		      }  
	}
	
	public void setLastNavWeb(String cache){
//		 Editor pEditor = settings.edit();
		if(this.playBack)return;
		
		     if(isNaving) {
		    	  pEditor.putString(QiYouConstant.PK_INT_LAST_UNFINISHED_NAV_WEB, cache);   
		    	 pEditor.commit();		    	 
		    	 }
		      else{
		    	  clearLastNavId();
		      }  
	}
	public String isLastNaviWeb(){ 
		return settings.getString(QiYouConstant.PK_INT_LAST_UNFINISHED_NAV_WEB,"");
//		return TextUtils.isEmpty()  ;
	}
	
	 
	public void clearLastNavId(){
//		 naviTrackId =-1;
		 pEditor.putInt(QiYouConstant.PK_INT_LAST_UNFINISHED_NAVID,-1); 
		 pEditor.putString(QiYouConstant.PK_INT_LAST_UNFINISHED_NAV_WEB,""); 
		 pEditor.commit();
	}
	
	
	
	
	public int getCntKm() {
//		return cntKm;\
		int km = (int) ((getRecordingTrack().getTrackBean().getDistance()+500)/1000);
		km=km>0?km:1;
		return km;
	}
	/*public void setCntKm(int cntKm) {
		this.cntKm = cntKm;
	}*/
	/*
	public boolean getCityGEO(double lat, double lon){
		
		  getBdGEOadress(lat,lon);
		   // QLog.getLogger().d(dTAG,TAG+ String.format("lat: %s; lon: %s", lat,lon));
		   int topWaiting=0; 
		    while( GEOadress==null && ! isGEOerror && Utils.getNetworkType(this)!=QiYouConstant.NETWORK_TYPE_OFF)
		     try {
				Thread.sleep(50);
				topWaiting+=50;
				QLog.getLogger().d(dTAG,TAG+"  getCityGEO waiting for  "+ topWaiting );
				if(topWaiting>QiYouConstant.MAX_TIME_GET_TRACK_FROM_DB/3 )
				{ 
					Log.e(dTAG,TAG+" 获取地址超时.");
					return false;
				   
				}
			  } catch (InterruptedException e) {
				// TODO Auto-generated catch block
				Utils.logStackTrace(e, TAG);
				} 
		    return true;
		   
	}*/
	
	
	   int getuniqueId(){ 
		    TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE); 
			String imei=tm.getDeviceId();
			return TextUtils.isEmpty(imei)?-1:imei.hashCode();
			/*String simSerialNumber=tm.getSimSerialNumber();
			String androidId = android.provider.Settings.Secure.getString(
			getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
			java.util.UUID deviceUuid =new java.util.UUID(androidId.hashCode(), ((long)imei.hashCode() << 32) | simSerialNumber.hashCode());
			String uniqueId    = deviceUuid.toString();*/ 
	}
		public void setPhoneId(){
			if(getPhoneId()==-1){
				pEditor.putInt(QiYouConstant.PK_INT_PHONEID,getuniqueId());		 
				pEditor.commit();
		    }
		}
		
		public int getPhoneId(){ 
			if( QiYouConstant.PV_INT_PHONEID==-1){
				QiYouConstant.PV_INT_PHONEID =settings.getInt(QiYouConstant.PK_INT_PHONEID,-1);
				if(QiYouConstant.PV_INT_PHONEID>0){
					QiYouConstant.PV_INT_PHONEID=QiYouConstant.PV_INT_PHONEID*-1;
					
				}
			}
			return QiYouConstant.PV_INT_PHONEID;
			  
	 	}
		public boolean isLocationFinding=false;
		public boolean canStopNetworkRequest(){
			return  playBack ||! canRecord() &&! isRouting &&!isLocationFinding;
		}
		
		
		
	public void sendSharedLocation(){
		
		Intent serviceIntent = new Intent(this, LocationService2.class); 
		serviceIntent.putExtra(QiYouConstant.EXTRA_KEY_UPLOAD_SHARED_LOCATION, 0);  
	    startService(serviceIntent); 
	    
	    QLog.getLogger().dLog(dTAG," send shared location service called.... ");
	}
		
		
	/*public boolean isAdmin(User_bean u){
		return QiYouConstant.DEVELOPER_MODE;
	}*/
		
	public boolean isAdmin(){
		return user.getUserbean().isPower();
	}
	public ConcurrentHashMap<String,Object> getWebObjcache() {
		if ( webObjcache == null){
			 webObjcache = new ConcurrentHashMap<String,Object>();
		}
		return webObjcache;
	}
	 
		
		
	
}
