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

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.ParserConfigurationException;

import org.alternativevision.gpx.GPXParser;
import org.alternativevision.gpx.beans.GPX;
import org.apache.http.util.EncodingUtils;
import org.xml.sax.SAXException;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentUris;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.inputmethod.InputMethodManager;

 
import com.loopj.android.http.Base64;
import com.qiyou.mb.android.QiYouConstant;
import com.qiyou.mb.android.R;
import com.qiyou.mb.android.beans.Track;
import com.qiyou.mb.android.beans.basic.Track_bean;
import com.qiyou.mb.android.beans.basic.User_bean;
import com.qiyou.mb.android.beans.basic.Waypoint_bean;
import com.qiyou.mb.android.utils.enums.TrackType;
import com.qiyou.mb.android.utils.enums.wpFlag;
import com.qiyou.mb.android.utils.log.QLog;
import com.baidu.mapapi.model.LatLng;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
/**
 * @author mwang
 * 
 */
public class Utils {
	public static final String dTAG ="com.qiyou";
	public static final String TAG ="com.qiyou.Utils";
	
	/**
	 * 
	 */
	public Utils() {
		// TODO Auto-generated constructor stub
	}

	public static boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile("[0-9]*");
		return pattern.matcher(str).matches();
	}
	
	
	public static String getGPXformatedTime(Long time) 
	{
		
		if(time==0) return "";
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss");			
		return df.format(new Date(time)); 
	}
	 
	public static String getFormatedTime(Long time) 
	{
		
		if(time==0) return "";
		SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");			
		return df.format(new Date(time));
		 
	}
	
	public static String getFormatedTime(String format,Long time) 
	{
		
		if(time==0) return "";
		SimpleDateFormat df = new SimpleDateFormat(format);			
		return df.format(new Date(time));
		 
	}
	public static String getFormatedTime (Long time,String format) 
	{
		
		if(time==0) return "";
		SimpleDateFormat df = new SimpleDateFormat(format);			
		return df.format(new Date(time));
		 
	}
	
	public static String getFormatedTimeMonthDay(Long time) 
	{
		
		if(time==0) return "";
		SimpleDateFormat df = new SimpleDateFormat("MM/dd HH:mm");			
		return df.format(new Date(time));
		 
	}
	public static String getShortFormatedTime(Long time) 
	{
		
		if(time==0) return "";
		SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd");			
		return df.format(new Date(time));
		
		/*
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
	     
		Date dt =null;dt.getd getDateTimeInstance() 
		try {
			dt = df.parse(time.toString());
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return dt;
		*/

	}
	
	public static String getTimeCnt(Long time ){
	    return 	 getTimeCnt(  time,true);
	}
	
	public static String getTimeMS(Long time) 
	{
		// int hour =Integer.valueOf(String.valueOf(time/1000/60/60));
/*		 long hour = time/1000/60/60;
		 long minute = (time - hour*3600*1000)/1000/60;
		 long second = (time -hour*3600*1000 - minute*60*1000)/1000;
		 int ish =Integer.valueOf(String.valueOf(hour));
		 int ism =  Integer.valueOf(String.valueOf(minute));
		 int iss = Integer.valueOf(String.valueOf(second));
		 String sh = Integer.valueOf(String.valueOf(hour))>0 ? Integer.valueOf(String.valueOf(hour)).toString() :"00";
		 String sm =  Integer.valueOf(String.valueOf(minute))>0 ? Integer.valueOf(String.valueOf(minute)).toString() :"00";		
		 String ss =   Integer.valueOf(String.valueOf(second))>0 ? Integer.valueOf(String.valueOf(second)).toString() :"00";
		 if (10>ish && ish>0)sh ="0"+sh;
		 if (10>ism && ism>0)sm ="0"+sm;
		 if (10>iss && iss>0)ss ="0"+ss;*/
		
		 int ish = (int) (time/1000/60/60);
		 int ism = (int) ((time - ish*3600*1000)/1000/60);
		 int iss = (int) ((time -ish*3600*1000 - ism*60*1000)/1000);
//		 int ish =Integer.valueOf(String.valueOf(hour));
//		 int ism =  Integer.valueOf(String.valueOf(minute));
//		 int iss = Integer.valueOf(String.valueOf(second));
		 String sh =   String.valueOf( ish>0 ?ish :"00")  ;
		 String sm =   String.valueOf(ism>0 ? ism :"00")  ;		
		 String ss =   String.valueOf(iss>0 ?iss :"00"  ) ;
		 if (10>ish && ish>0)sh ="0"+sh;
		 if (10>ism && ism>0)sm ="0"+sm;
		 if (10>iss && iss>0)ss ="0"+ss;
		 
		 if(ish>0){
			 sm+=ish*60;
		 }
		 return   sm  +":"+ss;
	}
	
	//return xx小时xx分钟xx秒
	public static String getTimeCnt(Long time,boolean isIncludeSec) 
	{
		// int hour =Integer.valueOf(String.valueOf(time/1000/60/60));
/*		 long hour = time/1000/60/60;
		 long minute = (time - hour*3600*1000)/1000/60;
		 long second = (time -hour*3600*1000 - minute*60*1000)/1000;
		 int ish =Integer.valueOf(String.valueOf(hour));
		 int ism =  Integer.valueOf(String.valueOf(minute));
		 int iss = Integer.valueOf(String.valueOf(second));
		 String sh = Integer.valueOf(String.valueOf(hour))>0 ? Integer.valueOf(String.valueOf(hour)).toString() :"00";
		 String sm =  Integer.valueOf(String.valueOf(minute))>0 ? Integer.valueOf(String.valueOf(minute)).toString() :"00";		
		 String ss =   Integer.valueOf(String.valueOf(second))>0 ? Integer.valueOf(String.valueOf(second)).toString() :"00";
		 if (10>ish && ish>0)sh ="0"+sh;
		 if (10>ism && ism>0)sm ="0"+sm;
		 if (10>iss && iss>0)ss ="0"+ss;*/
		/*
		 int ish = (int) (time/1000/60/60);
		 int ism = (int) ((time - ish*3600*1000)/1000/60);
		 int iss = (int) ((time -ish*3600*1000 - ism*60*1000)/1000);
//		 int ish =Integer.valueOf(String.valueOf(hour));
//		 int ism =  Integer.valueOf(String.valueOf(minute));
//		 int iss = Integer.valueOf(String.valueOf(second));
		 String sh =   String.valueOf( ish>0 ?ish :"00")  ;
		 String sm =   String.valueOf(ism>0 ? ism :"00")  ;		
		 String ss =   String.valueOf(iss>0 ?iss :"00"  ) ;
		 if (10>ish && ish>0)sh ="0"+sh;
		 if (10>ism && ism>0)sm ="0"+sm;
		 if (10>iss && iss>0)ss ="0"+ss;
		 
		 if(!isIncludeSec)
			 return sh +":" + sm;
		 return sh +":" + sm  +":"+ss;
		 */
		 /*
		    Integer ss = 1000;  
		    Integer mi = ss * 60;  
		    Integer hh = mi * 60;  
		    Integer dd = hh * 24;  
		  
		    Long day = time / dd;  
		    Long hour = (ms - day * dd) / hh;  
		    Long minute = (ms - day * dd - hour * hh) / mi;  
		    Long second = (ms - day * dd - hour * hh - minute * mi) / ss;  
		    Long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;  
		 */
		 
		    Integer ss = 1000;  
		    Integer mi = ss * 60;  
		    Integer hh = mi * 60;   
		  
		    Long hour = time / hh;  
		    Long minute = (time  - hour * hh) / mi;  
		    Long second = (time  - hour * hh - minute * mi) / ss;  
//		    Long milliSecond = time  - hour * hh - minute * mi - second * ss;  
		     String sh =   String.valueOf( hour>0 ?hour :"00")  ;
			 String sm =   String.valueOf(minute>0 ? minute :"00")  ;		
			 String sss =   String.valueOf(second>0 ?second :"00"  ) ;
			 
		     if (10>hour && hour>0) sh ="0"+hour;
			 if (10>minute && minute>0)sm ="0"+sm;
			 if (10>second && second>0)sss ="0"+sss;
			 
			 if(!isIncludeSec)
				 return sh +":" + sm;
			 return sh +":" + sm  +":"+sss;
	}
	//return xx小时xx分钟xx秒
		public static String getTimeCnt4Read(Long time,boolean isIncludeSec) 
		{
			 int ish = (int) (time/1000/60/60);
			 int ism = (int) ((time - ish*3600*1000)/1000/60);
			 int iss = (int) ((time -ish*3600*1000 - ism*60*1000)/1000);
//			 int ish =Integer.valueOf(String.valueOf(hour));
//			 int ism =  Integer.valueOf(String.valueOf(minute));
//			 int iss = Integer.valueOf(String.valueOf(second));
			 String sh =   String.valueOf( ish>0 ?ish+"小时" :"")  ;
			 String sm =   String.valueOf(ism>0 ? ism +"分" :"") ;		
			 String ss =   String.valueOf(iss>0 ?iss +"秒":"钟"  ) ;
//			 if (10>ish && ish>0)sh ="0"+sh;
			 if (ish>0&& 10>ism && ism>0)sm ="0"+sm;
			 if (ism>0 && 10>iss && iss>0)ss ="0"+ss;
			 
			 if(!isIncludeSec)
				 return sh    + sm +(ish==0?(ism>0 ? "钟" :""):"");
			 
			 return sh  + sm +ss;
		}
		
		public static int getDayscnt(Long time ) 
		{ 
			 int days =(int) (time/1000/60/60/24);
			 if(days>0){
				 days++;
			 }
			 return days;
		}
		
	public static long getUTC(String bdTime) {
		Date dt = new Date(); // 2013-12-16 15:45:09
		//TODO check the hint To get local formatting use getDateInstance(), getDateTimeInstance(), or getTimeInstance(), or use new SimpleDateFormat(String template, Locale locale) with for example Locale.US for ASCII dates.
		SimpleDateFormat sdf = new SimpleDateFormat();

		try {
			dt = sdf.parse(bdTime);

		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return dt.getTime();

	}
    private static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;  
	  
/*   void bd_encrypt(double gg_lat, double gg_lon, double bd_lat, double bd_lon)  
	{  
	    double x = gg_lon, y = gg_lat;  
	    double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);  
	    double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);  
	    bd_lon = z * Math.cos(theta) + 0.0065;  
	    bd_lat = z * Math.sin(theta) + 0.006;  
	} 
	
   public static void bd_decrypt(double bd_lat, double bd_lon, double  gg_lat, double  gg_lon)  
	{  
	    double x = bd_lon - 0.0065, y = bd_lat - 0.006;  
	    double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);  
	    double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);  
	    gg_lon = z * Math.cos(theta);  
	    gg_lat = z * Math.sin(theta);  
	} 
   */
   public static double getggLat(double bd_lat, double bd_lon)  
	{  
	    double bdLat =getbdLat(bd_lat,bd_lon) ; 
//	    x=2*x1-x2; y=2*y1-y2;
	    return bd_lat*2-bdLat;
	     
	}  
   public static double getggLon(double bd_lat, double bd_lon)  
 	{  
 	    double bdLon =getbdLon(bd_lat,bd_lon) ; 
// 	    x=2*x1-x2; y=2*y1-y2;
 	    return bd_lon*2-bdLon;
 	     
 	}  
   
 /*  public static double getggLon(double bd_lat, double bd_lon)  
	{  
	    double x = bd_lon - 0.0065, y = bd_lat - 0.006;  
	    double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);  
	    double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);  
	    return z * Math.cos(theta); 
	      
	}  */
	 
	public static double getbdLat(double wg_lat, double wg_lon)  
	{   
	    double x = getCJLon(wg_lat,wg_lon), y =  getCJLat(wg_lat,wg_lon); 
	    double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);  
	    double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);  
	   return z * Math.sin(theta) + 0.006;  
	}
	
	public static double getbdLon(double wg_lat, double wg_lon)  
	{  
		  double x = getCJLon(wg_lat,wg_lon), y =  getCJLat(wg_lat,wg_lon); 
	    double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);  
	    double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);  
	   return z * Math.cos(theta) + 0.0065;  
	}
	
	
	
	
	
	/*
	 * get lat from WGS84 to GCJ-02
	 */
	public static double getCJLat(double wgLat, double wgLon)
	{
		if (outOfChina(wgLat, wgLon))
        {   
            return wgLat;
        }
        double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
        double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
        double radLat = wgLat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); 
        return  wgLat + dLat;
	}
	
	/*
	 * get lon from WGS84 to GCJ-02
	 */
	public static double getCJLon(double wgLat, double wgLon)
	{
		if (outOfChina(wgLat, wgLon))
        {   
            return wgLat;
        }
        double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
        double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
        double radLat = wgLat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); 
        return  wgLon + dLon; 
        
	}
	
	
	
	   static  double pi = 3.14159265358979324;
	   static  double a = 6378245.0;
	   static  double ee = 0.00669342162296594323;

	
	/*  public static void transform(double wgLat, double wgLon,   double mgLat,   double mgLon)
      {
          if (outOfChina(wgLat, wgLon))
          {
              mgLat = wgLat;
              mgLon = wgLon;
              return;
          }
          double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
          double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
          double radLat = wgLat / 180.0 * pi;
          double magic = Math.sin(radLat);
          magic = 1 - ee * magic * magic;
          double sqrtMagic = Math.sqrt(magic);
          dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
          dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
          mgLat = wgLat + dLat;
          mgLon = wgLon + dLon;
      }*/
	  
	  
	  static boolean outOfChina(double lat, double lon)
      {
          if (lon < 72.004 || lon > 137.8347)
              return true;
          if (lat < 0.8293 || lat > 55.8271)
              return true;
          return false;
      }

      static double transformLat(double x, double y)
      {
          double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
          ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
          ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
          ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
          return ret;
      }

      static double transformLon(double x, double y)
      {
          double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
          ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
          ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
          ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;
          return ret;
      }
	  
      
      public static String getDistanceRange(float range,float lat,float lon){
    	  
    	  if(range>0){
    		  return  getFormatedDistance(range);
    	  }else if(lat>0 && lon>0)
    		  return getFormatedDistance((float) getDistanceFromXtoY(lat,lon, QiYouConstant.PV_LAST_LAT, QiYouConstant.PV_LAST_LON));
    	  else return "";
    	  
      }
      
      public   static int get_updatedb_invterval(TrackType trackType)
	{
		int rt =0;
		switch(trackType)
		{
		case BIKE: {rt = QiYouConstant.MAX_TIME_UPDATE_DB;break;}  //TODO: read reference for types
		case MOTOR: {rt = QiYouConstant.MAX_TIME_UPDATE_DB;break;}
		case HIKE: {rt = QiYouConstant.MAX_TIME_UPDATE_DB;break;}
		case FLY: {rt = QiYouConstant.MAX_TIME_UPDATE_DB;break;}
		case DIVE: {rt = QiYouConstant.MAX_TIME_UPDATE_DB;break;}
		case OTHER: {rt = QiYouConstant.MAX_TIME_UPDATE_DB;break;}
		default:rt = QiYouConstant.MAX_TIME_UPDATE_DB; 
		}
		
		return rt;
	}
	  
      public  static	int get_updatedb_cachsize(TrackType trackType)
		{
			int rt =0;
			switch(trackType)
			{ 
			case BIKE: {rt = QiYouConstant.MAX_WPS_UPDATE_DB;break;}  //TODO: read reference for types
			case MOTOR: {rt = QiYouConstant.MAX_WPS_UPDATE_DB;break;}
			case HIKE: {rt = QiYouConstant.MAX_WPS_UPDATE_DB;break;}
			case FLY: {rt = QiYouConstant.MAX_WPS_UPDATE_DB;break;}
			case DIVE: {rt = QiYouConstant.MAX_WPS_UPDATE_DB;break;}
			case OTHER: {rt = QiYouConstant.MAX_WPS_UPDATE_DB;break;}
			default: rt = QiYouConstant.MAX_WPS_UPDATE_DB; 
			}
			
			return rt;
		}
	  
/*      public static	int get_updatedb_wpsDistance(int trackType)
		{
			int rt =0;
			switch(trackType)
			{
			case 0: {rt = QiYouConstant.MIN_WPS_DISTANCE_FACTOR;break;}  //TODO: read reference for types
			case 1: {rt = QiYouConstant.MIN_WPS_DISTANCE_FACTOR;break;}
			case 2: {rt = QiYouConstant.MIN_WPS_DISTANCE_FACTOR;break;}
			}
			
			return rt;
		}
		*/
     public static	int get_updatedb_wpsElesumcnt(TrackType trackType)
		{
			int rt =0;
			switch(trackType)
			{ 
			case BIKE: {rt = QiYouConstant.MAX_WPS_EVERAGE_ELE_CNT;break;}  //TODO: read reference for types
			case MOTOR: {rt = QiYouConstant.MAX_WPS_EVERAGE_ELE_CNT;break;}
			case HIKE: {rt = QiYouConstant.MAX_WPS_EVERAGE_ELE_CNT;break;}
			case FLY: {rt = QiYouConstant.MAX_WPS_EVERAGE_ELE_CNT;break;}
			case DIVE: {rt = QiYouConstant.MAX_WPS_EVERAGE_ELE_CNT;break;}
			case OTHER: {rt = QiYouConstant.MAX_WPS_EVERAGE_ELE_CNT;break;}
			}
			
			return rt;
		}
	  
     public static float getDistance(Location loc1, Location loc2)
     {
    	 return (float)  getDistanceFromXtoY(loc1.getLatitude(),loc1.getLongitude(),loc2.getLatitude(),loc2.getLongitude());
//    	 return  (float) getDistance2(loc1,loc2);
     }
     
   
     public static double getDistanceFromXtoY(double lat_a, double lng_a,
    		   double lat_b, double lng_b){
    		
    	 
    	 if(lat_a<=0 || lat_b<=0 ||lng_a<=0 ||lng_b<=0)return 0;
    	 
    	 
    		  double pk = 180 / 3.14169;

    		  double a1 = lat_a / pk;
    		  double a2 = lng_a / pk;
    		  double b1 = lat_b / pk;
    		  double b2 = lng_b / pk;

    		  double t1 = Math.cos(a1) * Math.cos(a2) * Math.cos(b1) * Math.cos(b2);
    		  double t2 = Math.cos(a1) * Math.sin(a2) * Math.cos(b1) * Math.sin(b2);
    		  double t3 = Math.sin(a1) * Math.sin(b1);
    		  double tt = Math.acos(t1 + t2 + t3); 
    		  
    		  double rt =  6366000 * tt;
    		  
//    		  if(rt ==Double.NaN) {
    		  if(Double.isNaN(rt)) {
    			  
    			      QLog.getLogger().dLog("com.qiyou.utils", "getDistanceFromXtoY,Distance is NaN. return value: "+ rt);
	    			  rt =0.0;    			  
    			  }
    		  if(rt>0)
    		  return rt;
    		  else return 0;
    		  
    		}
    
     
     public static double getDistance2( Location currentLoc, Location lastLoc)
 	{
    	 
    	 double distance=0d;
 		if(currentLoc != null &&lastLoc!=null && currentLoc.getTime()>lastLoc.getTime()){ 
 			 
//  			double distanceTo = currentLoc.distanceTo(lastLoc);
 		
 	/*		double getDistance =getDistance(  currentLoc, lastLoc);
 			
// 			QLog.getLogger().dLog(dTAG," getDistance "+  getDistance ); 
// 			QLog.getLogger().dLog(dTAG," getDistance - distanceTo "+ ( getDistance - currentLoc.distanceTo(lastLoc)));
 			
 			if(getDistance >0 && currentLoc.hasAccuracy() && lastLoc.hasAltitude()){ 
 				double opposite =currentLoc.getAltitude() - lastLoc.getAltitude(); 
// 				distance2 = (float) Math.atan(((double)opposite/distance));
 				double gradient =Math.abs(opposite/getDistance*100);
// 				QLog.getLogger().dLog(dTAG," ele opposite  "+String.format("%.2f", opposite));
// 				QLog.getLogger().dLog(dTAG," location gradients  "+String.format("%.2f", gradient));
 				if(gradient<20){
 					distance=Math.sqrt(Math.pow(opposite, 2)+Math.pow(getDistance,2));
 					
// 					QLog.getLogger().dLog(dTAG," location distance before fix "+getDistance);
// 					QLog.getLogger().dLog(dTAG," location distance after  fix  "+distance); 
// 					QLog.getLogger().dLog(dTAG," location distance   delta  is "+(distance-getDistance));
 				}
 				else{
 					distance=getDistance; 
 				}
 				
 				
 			} */	
//  			distance2=distance3; 
 			distance =getDistance(  currentLoc, lastLoc);
 		}
 		return distance;
 	}
     
     public static double getDistance3( Location currentLoc, Location lastLoc)
 	{
    	 
    	 double distance=0d;
 		if(currentLoc != null &&lastLoc!=null && currentLoc.getTime()>lastLoc.getTime()){ 
 			 
//  			double distanceTo = currentLoc.distanceTo(lastLoc);
 		
 			double getDistance =getDistance(  currentLoc, lastLoc);
 			
// 			QLog.getLogger().dLog(dTAG," getDistance "+  getDistance ); 
// 			QLog.getLogger().dLog(dTAG," getDistance - distanceTo "+ ( getDistance - currentLoc.distanceTo(lastLoc)));
 			
 			if(getDistance >0 && currentLoc.hasAccuracy() && lastLoc.hasAltitude()){ 
 				double opposite =currentLoc.getAltitude() - lastLoc.getAltitude(); 
// 				distance2 = (float) Math.atan(((double)opposite/distance));
 				double gradient =Math.abs(opposite/getDistance*100);
// 				QLog.getLogger().dLog(dTAG," ele opposite  "+String.format("%.2f", opposite));
// 				QLog.getLogger().dLog(dTAG," location gradients  "+String.format("%.2f", gradient));
 				if(gradient<20){
 					distance=Math.sqrt(Math.pow(opposite, 2)+Math.pow(getDistance,2));
 					
// 					QLog.getLogger().dLog(dTAG," location distance before fix "+getDistance);
// 					QLog.getLogger().dLog(dTAG," location distance after  fix  "+distance); 
// 					QLog.getLogger().dLog(dTAG," location distance   delta  is "+(distance-getDistance));
 				}
 				else{
 					distance=getDistance; 
 				}
 				
 				
 			} 	
//  			distance2=distance3; 
 		}
 		return distance;
 	}
     
	/* public boolean isScreenOff(){
	        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
	        
	        return !(pm.isScreenOn());
	    }

	    public boolean appNotOnTop(){
	        ActivityManager manager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
	        List<RunningTaskInfo> runningTaskInfos = manager.getRunningTasks(100);
	        
	        if(runningTaskInfos.size() > 0){  

	            System.out.println("---------------包名-----------"+runningTaskInfos.get(0).topActivity.getPackageName());

	            //应用程序位于堆栈的顶层  

	            if("com.chexiaodi.android.cxd".equals(runningTaskInfos.get(0).topActivity.getPackageName())){  

	                return false;  

	            }  

	        }  

	        return true;
	    }*/
     
     public static String sqliteEscape(String keyWord){
    	    keyWord = keyWord.replace("/", "//");
    	    keyWord = keyWord.replace("'", "''");
    	    keyWord = keyWord.replace("[", "/[");
    	    keyWord = keyWord.replace("]", "/]");
    	    keyWord = keyWord.replace("%", "/%");
    	    keyWord = keyWord.replace("&","/&");
    	    keyWord = keyWord.replace("_", "/_");
    	    keyWord = keyWord.replace("(", "/(");
    	    keyWord = keyWord.replace(")", "/)");
    	    return keyWord;
    	}

     public static void logStackTrace(Exception e,String TAG){ 
    	 
    	  if(!QiYouConstant.LOG_LEVEL_DEBUG && !QiYouConstant.LOG_LEVEL_ERROR) return;
    	 
    	  StackTraceElement[] ste= e.getStackTrace();
    	  int stelength=ste.length;
    	  Log.e(TAG,e.toString());  
    	  Log.e(dTAG,e.toString());  
    	  String err_msg=""; 
//    	  String	mDestXmlFilename =  QiYouConstant.SD_PATH + "error" +Calendar.YEAR+  Calendar.DATE + Calendar.DAY_OF_MONTH +".log";
    	  String	mDestXmlFilename =  QiYouConstant.SD_PATH + "error" +
    			  						new SimpleDateFormat("yyyy-MM-dd", Locale.CHINESE) .format(Calendar.getInstance().getTime()) 
    			  						+".log";
		 File myFile = new File(mDestXmlFilename);
			try {
			   if(!myFile.exists()){
				   myFile.createNewFile();
			   }
				FileOutputStream fOut = new FileOutputStream(myFile,true);
//				BufferedOutputStream bos = new BufferedOutputStream(fOut);
				fOut.write((Utils.getFormatedTime(System.currentTimeMillis())+"\n").getBytes());
				
				fOut.write((e.toString()+"\n").getBytes());
			 
				  for(int i=0;i<stelength;i++){   
		    		  err_msg=ste[i].toString();    	   
		    		  err_msg="                  "+err_msg+"\n";
//		    		  bos.write(err_msg.getBytes());
		    		  fOut.write(err_msg.getBytes());
//		    	     System.out.println(err_msg);
		    		 Log.e(dTAG, err_msg.toString());    	  
		    	  }			    
//			    bos.close();
			    fOut.close();
    	  	} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
    	  
    	  
    	 } 
     
     
     
     public static void logDbugTrace(String dTAG,String info){ 
    	 
   	  if(!QiYouConstant.LOG_LEVEL_DEBUG && !QiYouConstant.LOG_LEVEL_ERROR) return; 
   	  
//   	  if(!dTAG.equalsIgnoreCase("com.qiyou.qnaviSvc"))return;
   	  
//   	  String	mDestXmlFilename =  QiYouConstant.SD_PATH + "error" +Calendar.YEAR+  Calendar.DATE + Calendar.DAY_OF_MONTH +".log";
   	  String	mDestXmlFilename =  QiYouConstant.SD_PATH + "dbug"  +
   			  						new SimpleDateFormat("yyyy-MM-dd", Locale.CHINESE) .format(Calendar.getInstance().getTime()) 
   			  						+".log";
		 File myFile = new File(mDestXmlFilename);
			try {
			   if(!myFile.exists()){
				   myFile.createNewFile();
			   }
				FileOutputStream fOut = new FileOutputStream(myFile,true);
//				BufferedOutputStream bos = new BufferedOutputStream(fOut);
//				fOut.write((Utils.getFormatedTime(System.currentTimeMillis())+"\n").getBytes());
				
				fOut.write((dTAG+"           "+ Utils.getFormatedTime(System.currentTimeMillis()) +"           "+info+"\n").getBytes()); 
//			    bos.close();
			    fOut.close();
   	  	} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
   	  
   	  
   	 } 
     
     public static double round(Double value, int scale) {
         double result = 0.0; 
         if (null != value) {
             result = new BigDecimal(String.valueOf(value)).setScale(scale,
                 RoundingMode.HALF_UP).doubleValue();
         }

         return result;
     }
     
     public static float roundF(Float value, int scale) {
         float result = 0f; 
         if (null != value) {
             result = new BigDecimal(String.valueOf(value)).setScale(scale,
                 RoundingMode.HALF_UP).floatValue();
         }

         return result;
     }
     
     
    
     
     public static boolean isNetworkConnected(Context context) { 
    	 if (context != null) { 
	    	 ConnectivityManager mConnectivityManager = (ConnectivityManager) context 
	    	 .getSystemService(Context.CONNECTIVITY_SERVICE); 
	    	 NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo(); 
	    	  if (mNetworkInfo != null) { 
	    		  QiYouConstant.NETWORK_CONNECTED = mNetworkInfo.isAvailable();
	    	   return QiYouConstant.NETWORK_CONNECTED ; 
	    	 } 
	    	 
    	 } 
    	 
    	 return false; 
    	 }    
     
     public static int getNetworkType(Context context) { 
    	 int nType = -1;
    	 if (context != null) {  
	    	 ConnectivityManager mConnectivityManager = 
	    			 (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
	    	 NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo(); 
	    	if(mNetworkInfo!=null){
	    		nType = mNetworkInfo.getType();  
		    	 if(nType==ConnectivityManager.TYPE_MOBILE){ 
			    	 return QiYouConstant.NETWORK_TYPE_MOBILE;
		    	 } 
		    	 else if(nType==ConnectivityManager.TYPE_WIFI){ 
		    		 return QiYouConstant.NETWORK_TYPE_WIFII;
		    	 }  
	    	} 
    	 } 
    	 
    	 return  nType; 
    	 } 
     
     public static String getFormatedDistance(float dist){
		if(dist>1000)
				return   String.format("%.1f",dist /1000.0   )+"公里"  ;// + "% %.2f 公里后%转", tb.getRoadWps().size()+1,wp.getWb().getBearDist() /1000.0, turn);
			else
	 			return String.format("%.0f",dist) +"米" ;
     }
     
     
     public static String getWeather(){
//    	 String weather="   苏州天气不错,晴转多云,19摄氏度,空气质量一级.\n";
    	 String weather="";
    	 return weather;
     }
     
   /*  public static String getDirection(float bearing){  
    	 
//    	 float bear = bearing/30; 
    	  int dir =(int)roundF(bearing/30,2);
    	  dir=dir==0?12:dir;
    	  return String.format("%s %s 点钟方向 ",getDirection(bearing),  dir  );
    	 
     
    } */
     
  public static String getBearMsg(float bearing,boolean fineData){  
    	 
//    	 float bear = bearing/30; 
    	  
//    	  return String.format("%.0f", bearing/30   );
	  if(bearing<0)bearing+=360;
	  bearing =Utils.roundF(bearing,1);
	  String rt ="";
	  String dir="";
    	  final String NORTH="北";
    	  final String SOUTH="南";
    	  final String WEST="西";
    	  final String EAST="东";
    	  final String Pian ="偏";
    	  final String Zheng ="正";
    	  
    	  final int iN=0;
    	  final int iE=3;
    	  final int iS=6;
    	  final int iW=9;
    	  
    	  final float cha=1.5f;
    	 
    	  float direction = roundF(bearing/30,2);
    	  float tf=direction+0.5f;
 
    	  int idir =(int)(roundF(tf ,0));
    	  if(idir>=12)idir=0;
    	  switch(idir){
	    	  case iN:{
	    		  rt=Zheng +NORTH;
	    		  return rt;
	    	  }
	    	  case iE:{
	    		  rt=Zheng +EAST;
	    		  return rt;
	    	  }
	    	  case iW:{
	    		  rt=Zheng +WEST;
	    		  return rt;
	    	  }
	    	  case iS:{
	    		  rt=Zheng +SOUTH;
	    		  return rt;
	    	  }
    	  }
    	  
    	    tf=direction-0.5f;
//    	  int idir =Integer.valueOf(String.format("%.0f",bearing/30));
    	   idir =(int)(roundF(tf ,0));
    	 
    	  switch(idir){
	    	  case iN:{
	    		  rt=Zheng +NORTH;
	    		  return rt;
	    	  }
	    	  case iE:{
	    		  rt=Zheng +EAST;
	    		  return rt;
	    	  }
	    	  case iW:{
	    		  rt=Zheng +WEST;
	    		  return rt;
	    	  }
	    	  case iS:{
	    		  rt=Zheng +SOUTH;
	    		  return rt;
	    	  }
    	  }
    	  
    	   tf=direction;
//     	  int idir =Integer.valueOf(String.format("%.0f",bearing/30));
     	   idir =(int)(roundF(tf ,0));
     	 
     	  switch(idir){
 	    	  case iN:{
 	    		  rt=Zheng +NORTH;
 	    		  return rt;
 	    	  }
 	    	  case iE:{
 	    		  rt=Zheng +EAST;
 	    		  return rt;
 	    	  }
 	    	  case iW:{
 	    		  rt=Zheng +WEST;
 	    		  return rt;
 	    	  }
 	    	  case iS:{
 	    		  rt=Zheng +SOUTH;
 	    		  return rt;
 	    	  }
     	  }
     	  
     	  
     	  float diff=0;
    	  if(direction<=12 && direction>12-cha){
    		  dir =NORTH;    		  
    		  if(direction<=cha)
    			  dir=dir+Pian+EAST;
    		  else
    			  dir=dir+Pian+WEST;
    		  diff=(direction-12)*30;
    	  }
    	  else  
    	  if(direction<=iN+cha && direction>iN){
    		  dir =NORTH; 
    		  if(direction<=cha)
    			  dir=dir+Pian+EAST;
    		  else
    			  dir=dir+Pian+WEST;
    		  diff=(direction-iN)*30;
    	  }
    	  else    		  
    	  if(direction<=iE+cha && direction>iE-cha){
    		  dir =EAST; 
    		  if(!fineData && direction ==iE+cha)
    			  return dir+SOUTH;
    		  else
    		  if(direction>iE)
    			  dir=dir+Pian+SOUTH;
    		  else
    			  dir=dir+Pian+NORTH;
    		  diff=(direction-iE)*30;
    	  }else
    		  if(direction<=iS+cha && direction>iS-cha){
        		  dir =SOUTH;  
        		  
        		  if(!fineData && direction ==iS+cha)
        			  return WEST+SOUTH;
        		  
        		  if(direction>iS)
        			  dir=dir+Pian+WEST;
        		  else
        			  dir=dir+Pian+EAST;
        		  diff=(direction-iS)*30;
        	  }else
        		  if(direction<=iW+cha && direction>iW-cha){
            		  dir =WEST;  
            		  if(!fineData && direction ==iW+cha)
            			  return WEST+NORTH;
            		  
            		  if(direction>iW)
            			  dir=dir+Pian+NORTH;
            		  else
            			  dir=dir+Pian+SOUTH;
            		  diff=(direction-iW)*30;
            	  }
    	  if(TextUtils.isEmpty(dir)){
//    		  Utils.logStackTrace(new Exception("NO Direction Found:"+bearing),dTAG);
    		  QLog.getLogger().d(String.valueOf(bearing), dTAG);
    	  }
    	  if(fineData)
    		  return String.format("%s%.0f度", dir,Math.abs(diff));	
    	  else
    		  return String.format("%s", dir);
    } 
     
    public static String getSdRootPath(Context context){
    	if(!Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED)){
    		return context.getCacheDir().getAbsolutePath();
//    		Log.e(dTAG, "Utils: "+ "SD卡不可用. sd status: " +Environment.getExternalStorageState());
//    		logStackTrace(new Exception("SD卡不可用. sd status: " +Environment.getExternalStorageState()),TAG);
//    		if(QiYouConstant.DEVELOPER_MODE)
//    			SDPATH="/qiyouapp";
    	    		 //return;
    	}else    	 
    		return Environment.getExternalStorageDirectory().toString();  
    }
  
  
    public static void initialSDPaths(){
    	QiYouConstant.MEDIA_PATH =QiYouConstant.SD_PATH+"medias/"; 
   
    	QiYouConstant.FOOTMARK_PATH =QiYouConstant.SD_PATH+"footmarks/";
    	QiYouConstant.PHOTO_CACHE_PATH =QiYouConstant.SD_PATH+"photoCache/";
    	QiYouConstant.EXP_PATH =QiYouConstant.SD_PATH+"exp/";
    	QiYouConstant.IMP_PATH =QiYouConstant.SD_PATH+"imp/";
    	QiYouConstant.CONTENT_SD_DIR=QiYouConstant.SD_PATH+"dbcontent/";
   
    	QiYouConstant.GPX_CACHE_PATH= QiYouConstant.SD_PATH + "gpxcache/";
    	QiYouConstant.ACT_CACHE_PATH= QiYouConstant.SD_PATH + "actcache/";
    }
  
     public static void initSdPath(Context context){
    	/* String SDPATH="";
    	if(!Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED)){
    		SDPATH=context.getCacheDir().getAbsolutePath();
//    		Log.e(dTAG, "Utils: "+ "SD卡不可用. sd status: " +Environment.getExternalStorageState());
//    		logStackTrace(new Exception("SD卡不可用. sd status: " +Environment.getExternalStorageState()),TAG);
//    		if(QiYouConstant.DEVELOPER_MODE)
//    			SDPATH="/qiyouapp";
    	    		 //return;
    	}else    	 
    		SDPATH=Environment.getExternalStorageDirectory().toString();    	*/	
    	 String SDPATH=getSdRootPath(context);
    	 SDPATH=SDPATH+"/"+QiYouConstant.APP_SD_DIR +"/";
    	 QLog.getLogger().d(dTAG, "Utils: "+ "App Path on SD:  "+ SDPATH);
//      判断SD卡上的文件夹是否存在：通过File对象的exists()方法。
       File file=new File(SDPATH);
        if(!file.exists()){ //在SD卡上创建目录：
        	file.mkdir();
        	QLog.getLogger().d(dTAG, "Utils: "+ "App Path created on SD as  "+ SDPATH);
            
        } 
        QiYouConstant.SD_PATH = SDPATH;
        initialSDPaths();
        file=new File(QiYouConstant.IMP_PATH);
        if(!file.exists()){ //在SD卡上创建目录：
        	file.mkdir();
        	QLog.getLogger().d(dTAG, "Utils: "+ "IMP_PATH created on SD as  "+ QiYouConstant.IMP_PATH);
            
        }  
        
        if(QiYouConstant.DEVELOPER_MODE){
        	QiYouConstant.CONTENT_SD_DIR=QiYouConstant.CONTENT_SD_DIR.substring(0,QiYouConstant.CONTENT_SD_DIR.length()-1)+"Dev"+File.separator;
	        	 file=new File(QiYouConstant.CONTENT_SD_DIR);        
	        if(!file.exists()){ //在SD卡上创建目录：
	        	file.mkdir();
	        	
	        	QLog.getLogger().d(dTAG, "Utils: "+ "CONTENT_SD_DIR created on SD as  "+ QiYouConstant.CONTENT_SD_DIR); 
	        } 
        }else{
		        	 
		        	/* QiYouConstant.CONTENT_SD_DIR =QiYouConstant.CONTENT_SD_DIR.substring(0,QiYouConstant.CONTENT_SD_DIR.length()-1)+"Dev"+File.separator;
		        	//temp codes to migrate dbcontent from sd to app data
		        	file=new File(QiYouConstant.CONTENT_SD_DIR);        
		 	        if(file.exists()){  
		 	        	try {
							FileUtil.copyDirectiory(QiYouConstant.CONTENT_SD_DIR, context.getDir("dbcontent", 0).getAbsolutePath());
							FileUtil.del(QiYouConstant.CONTENT_SD_DIR);
							FileUtil.del(QiYouConstant.CONTENT_SD_DIR);
						} catch (IOException e) {
							// TODO Auto-generated catch block
							Utils.logStackTrace(e, TAG);
						}
		 	        }
		 	        //---->
		 	         
		//        	file=new File(QiYouConstant.CONTENT_SD_DIR);
		            String DATABASE_NAME = "tracks.db"; 
		        	file = new File(QiYouConstant.SD_PATH + DATABASE_NAME);// 创建文件  
		        	 if(file.exists()){  
		  	        	// 					FileUtil.copyDirectiory(QiYouConstant.CONTENT_SD_DIR, context.getDir("dbcontent", 0).getAbsolutePath());
		// 					FileUtil.del(QiYouConstant.CONTENT_SD_DIR);
		// 					FileUtil.del(QiYouConstant.SD_PATH + DATABASE_NAME);
						file.delete();
		  	        } 
		          */
		        	 
		        	//below is to be kept 
		            QiYouConstant.CONTENT_SD_DIR =context.getDir("dbcontent", 0).getAbsolutePath();  
		          	QiYouConstant.CONTENT_SD_DIR+=File.separator; 
		        
        	}
        
        QiYouConstant.BEAR_TEXT =QiYouConstant.CONTENT_SD_DIR+ QiYouConstant.BEAR_TEXT;
        //create beartext file 
        file=new File(QiYouConstant.BEAR_TEXT);
//        file=new File(QiYouConstant.CONTENT_SD_DIR+"/a/test.txt");
        if(!file.exists()){
        	try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				Utils.logStackTrace(e, TAG);
				}
         }
        if(QiYouConstant.DEVELOPER_MODE){        
         QiYouConstant.STAT_TEXT =QiYouConstant.SD_PATH+ QiYouConstant.STAT_TEXT;
        }else {
        	QiYouConstant.STAT_TEXT =QiYouConstant.CONTENT_SD_DIR+ QiYouConstant.STAT_TEXT;         
         }
        //create STAT file 
        file=new File(QiYouConstant.STAT_TEXT);
//        file=new File(QiYouConstant.CONTENT_SD_DIR+"/a/test.txt");
        if(!file.exists()){
        	try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				Utils.logStackTrace(e, TAG);
				}
         }
          
     }
     
     public static String getContentPah(int TrackId){
    		if(TrackId<=0)
    			return ""; 
    		return QiYouConstant.CONTENT_SD_DIR +  TrackId+".txt";
    	}
     
     public static String getBearContentPah(int TrackId){
    	 if(TrackId<=0)
 			return ""; 
 		return QiYouConstant.CONTENT_SD_DIR +  TrackId+"b.txt";
 	}  
     
     
     public static boolean isContentExist(String filePath){
    		if(TextUtils.isEmpty(filePath))
    			return false; 
    		  File file = new File(filePath); 
    		  return file.exists(); 
    		
    	}
     
     public static String readSDFile(String fileName) throws IOException {  
   	 
         File file = new File(fileName);
         
         if(!file.exists()) return null;

         FileInputStream fis = new FileInputStream(file);  

         int length = fis.available(); 

          byte [] buffer = new byte[length]; 
          fis.read(buffer);     

          String res = EncodingUtils.getString(buffer, "UTF-8"); 

          fis.close();     
          return res;  
   }  

   //写文件
   public static void  writeSDFile(String fileName, String write_str) throws IOException{  

       /*  File file = new File(fileName);  

         FileOutputStream fos = new FileOutputStream(file);  
        

         byte [] bytes = write_str.getBytes(); 

         fos.write(bytes); 
         

         fos.close(); */
	   writeSDFile(fileName,  write_str, false);
   }  
   
   
   
   //写文件
   public static void  writeSDFile(String fileName, String write_str,boolean isAppend) throws IOException{  

	   	if(TextUtils.isEmpty(write_str))return;
         File file = new File(fileName);  

         FileOutputStream fos = new FileOutputStream(file,isAppend);  
//         FileOutputStream fos1 = new FileOutputStream(file, isAppend) ;

         byte [] bytes = write_str.getBytes(); 

         fos.write(bytes); 
         

         fos.close(); 
   }  
   
   
  public static String getShortString(String str,int lng){
//		 String value =cursor.getString(6);
		 str =TextUtils.isEmpty(str)?str:str.length()>lng?str.substring(0,lng)+"...":str;
		 str =TextUtils.isEmpty(str)?str:"  "+str.replaceAll( "\\s", "" );
			 
//			if (str!=null) {
////				Pattern p = Pattern.compile("\\s*|\t|\r|\n");
////				Matcher m = p.matcher(str);
////				str = m.replaceAll("");
//				str.replaceAll( "\\s", "" );
//			}
		 return   str;
	 }
  
  public static boolean isLocOfGPS(Location loc){
	  if(loc==null)return false;
	  return loc.getProvider().equalsIgnoreCase(LocationManager.GPS_PROVIDER);
  }
  public static boolean isLocOfForceUpdate(Location loc){
	  if(loc==null)return false;
	  return loc.getProvider().equalsIgnoreCase(QiYouConstant.LOCATION_FORCE_UPDATE);
  } 
  public static boolean isLocOfMonitor(Location loc){
	  if(loc==null)return false;
	  return loc.getProvider().equalsIgnoreCase(QiYouConstant.LOCATION_MONITOR);
  } 
  
  public static boolean isLocOfBD(Location loc){
	  if(loc==null)return false;
	  return loc.getProvider().equalsIgnoreCase(QiYouConstant.LOCATION_BD_LOC);
  } 
  public static boolean isLocOfRD(Location loc){
	  if(loc==null)return false;
	  return loc.getProvider().equalsIgnoreCase(QiYouConstant.LOCATION_RD_LOC);
  } 
  
  public static boolean canUpdateOffmap(Context context){
	  
		getlastGeoRequestTime(context);
		
		QLog.getLogger().d(dTAG,TAG+" "+ "  System.currentTimeMillis()- QiYouConstant.LAST_OFFMAP_UPDATE : " + ( System.currentTimeMillis()- QiYouConstant.LAST_OFFMAP_UPDATE ));
		QLog.getLogger().d(dTAG,TAG+" "+ "                 QiYouConstant.OFFMAP_UPDATE_INTERVAL*1000*60  : " + (  QiYouConstant.OFFMAP_UPDATE_INTERVAL*1000*60));
	 	
        QLog.getLogger().d(dTAG,TAG+" "+ " QiYouConstant.CAN_OFFMAP_UPDATE: " + QiYouConstant.CAN_OFFMAP_UPDATE);
		return QiYouConstant.CAN_OFFMAP_UPDATE;
	}
  public static boolean canUpdateGEOfootmark(Context context){
	
	  if(QiYouConstant.IS_PROCESSING_GEO_FOOTMARK) return false;
	  
		getlastGeoRequestTime(context);
		
		QLog.getLogger().d(dTAG,TAG+" "+ "  System.currentTimeMillis()- QiYouConstant.LAST_GEO_UPDATE : " + ( System.currentTimeMillis()- QiYouConstant.LAST_GEO_UPDATE ));
		QLog.getLogger().d(dTAG,TAG+" "+ "                 QiYouConstant.GEO_UPDATE_INTERVAL*1000*60  : " + (  QiYouConstant.GEO_UPDATE_INTERVAL*1000*60));
	 	
		 QLog.getLogger().d(dTAG,TAG+" "+ " QiYouConstant.CAN_GEO_UPDATE: " + QiYouConstant.CAN_GEO_UPDATE);
		return QiYouConstant.CAN_GEO_UPDATE;
	}
	public static void getlastGeoRequestTime(Context context){  
		
	    SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
      
	    QiYouConstant.LAST_OFFMAP_UPDATE =settings.getLong(QiYouConstant.PK_LONG_LAST_OFFMAP_UPDATE, 0);  
      	QiYouConstant.CAN_OFFMAP_UPDATE = System.currentTimeMillis()- QiYouConstant.LAST_OFFMAP_UPDATE >  QiYouConstant.OFFMAP_UPDATE_INTERVAL*1000*60;
      	
        QiYouConstant.LAST_GEO_UPDATE =settings.getLong(QiYouConstant.PK_LONG_LAST_GEO_UPDATE, 0); 
      	QiYouConstant.CAN_GEO_UPDATE = System.currentTimeMillis()- QiYouConstant.LAST_GEO_UPDATE >  QiYouConstant.GEO_UPDATE_INTERVAL*1000*60;
       
//		QLog.getLogger().d(dTAG,TAG+" "+ " #@#$!#%#$%@###last time offMap requested: " + Utils.getFormatedTime(QiYouConstant.LAST_GEO_UPDATE) +", past time:" +
//				Utils.getTimeCnt(System.currentTimeMillis()-QiYouConstant.LAST_GEO_UPDATE,true) +
//				" ,times since last geo update:" + QiYouConstant.TIME_SINCE_LAST_GEO_UPDATE +", " 
//				+ (System.currentTimeMillis()-QiYouConstant.LAST_GEO_UPDATE)+","+System.currentTimeMillis()); 
		
		/*QLog.getLogger().d(dTAG,TAG+" "+ " #@#$!#%#$%@###last time offMap requested: " + Utils.getFormatedTime(QiYouConstant.LAST_OFFMAP_UPDATE) +", past time:" +
		Utils.getTimeCnt(System.currentTimeMillis()-QiYouConstant.LAST_OFFMAP_UPDATE,true) +
		" ,times since last offmap update:"  + (System.currentTimeMillis()-QiYouConstant.LAST_OFFMAP_UPDATE) ); 
		
		QLog.getLogger().d(dTAG,TAG+" "+ " #@#$!#%#$%@###last time geo requested: " + Utils.getFormatedTime(QiYouConstant.LAST_GEO_UPDATE) +", past time:" +
				Utils.getTimeCnt(System.currentTimeMillis()-QiYouConstant.LAST_GEO_UPDATE,true) +
				" ,times since last geo update:" + (System.currentTimeMillis()-QiYouConstant.LAST_GEO_UPDATE) ); */

	} 
public static boolean canProcessWifiConn(Context context){  
		
	    SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
      
	    QiYouConstant.LAST_WIFI_TIME =settings.getLong(QiYouConstant.PK_LONG_LAST_WIFI_TIME, 0);  
      	QiYouConstant.CAN_WIFI_PROCESS = System.currentTimeMillis()- QiYouConstant.LAST_WIFI_TIME >  QiYouConstant.WIFI_CONNECT_CHANGE_INTERVAL*1000*60;
      	
      	if(QiYouConstant.CAN_WIFI_PROCESS ){
      		Editor edit =settings.edit();
      		edit.putLong(QiYouConstant.PK_LONG_LAST_WIFI_TIME, System.currentTimeMillis());
      		edit.commit();
      	} 

		QLog.getLogger().d(dTAG,TAG+" "+ " #@#$!#%#$%@### can Wifi connection process? " +QiYouConstant.CAN_WIFI_PROCESS); 
      	
       return QiYouConstant.CAN_WIFI_PROCESS;
		

	} 
  
  public static long getMondayOfTheWeek(){
	  return getFirstDay(true);
  }
  public static long getFirstDayOfTheMonth(){
	  return getFirstDay(false);
  }
  
  static  long getFirstDay(boolean isWeek){
	  Calendar cal =Calendar.getInstance();        		 
		int year =cal.get(Calendar.YEAR);
		int month =cal.get(Calendar.MONTH);
		int day=1;
		if(isWeek)day = cal.get(Calendar.DAY_OF_MONTH) - cal.get(Calendar.DAY_OF_WEEK) +1 ; //Get date of Monday 
		cal.clear();
		cal.set(year, month, day);  
//		startDate = endDate - cal.get(Calendar.MONDAY)*missPerday;
		return cal.getTimeInMillis();
		
  }
  
 public static boolean canUpdateUI(Context context){
//	  SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); 
	    return  PreferenceManager.getDefaultSharedPreferences(context).getBoolean(QiYouConstant.PK_BL_CAN_UPDATE_UI, false); 
  }

 public static int daysBetween(long start,long end){
		return (int)(end -start)/(24*3600*1000);
//		Date startDt = new Date(start);
//		Date endDt = new Date(end);
//		return endDt.compareTo(startDt);
	}

public static boolean isGpsEnabled(Context context) { 
	LocationManager locationManager =((LocationManager)context.getSystemService(Context.LOCATION_SERVICE)); 
	return locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER); 
	
}


public static boolean isGpsPermited(Context context){
	PackageManager pkm = context.getPackageManager();
	boolean has_permission = (PackageManager.PERMISSION_GRANTED
//	== pkm.checkPermission("android.permission.ACCESS_GPS", "com.qiyou.mb.android"));android.permission.WRITE_EXTERNAL_STORAGE
			== pkm.checkPermission("android.permission.ACCESS_FINE_LOCATION", "com.qiyou.mb.android"));//android.permission.WRITE_EXTERNAL_STORAGE

	return has_permission;
}


/*
@SuppressLint("NewApi")
public static void setTabhostStyle(TabHost tabhost,int height,int width){ 
	TabWidget  tabWidget = tabhost.getTabWidget();
	for (int i =0; i < tabWidget.getChildCount(); i++) {  
	    tabWidget.getChildAt(i).getLayoutParams().height = height; 
	    tabWidget.getChildAt(i).getLayoutParams().width = width;
	    TextView tv = (TextView) tabWidget.getChildAt(i).findViewById(android.R.id.title);
	//    tv.setTextSize(15);
	    tv.setTextColor( getResources().getColorStateList(android.R.color.darker_gray));
	   }
	tabhost.getTabWidget().setStripEnabled(false);
}*/
 

public static float getMets(TrackType trackType,float speed){ 
	switch(trackType)
	{
	case BIKE: {
		if(speed>28)
			return 11.94f;
		if(speed>27)
			return 11.42f;
		if(speed>26)
			return 10.9f;
		if(speed>25)
			return 10.42f;
		if(speed>24)
			return 9.9f;
		if(speed>23)
			return 9.28f;
		if(speed>22)
			return 8.6f;
		if(speed>21)
			return 8;
		if(speed >20)			
			return 7.5f;
		if(speed >19)			
			return 6.8f;
		if(speed >18)			
			return 6.2f;
		if(speed >16)			
			return 6;		
		return 4;  
		}  //TODO: read reference for types
	case MOTOR: {return 0;}
	case HIKE: { 
		 if(speed >20)			
			 return 25;
		 if(speed >16)			
			 return 20;
		 if(speed >12)			
			 return 15;
		 if(speed >8)			
		     return 10;
		 if(speed >5.5f)		
			 return 5.8f;
		 return 2;
	}
	case FLY: {
		
		 if(speed >20)			
			 return 25;
		 if(speed >16)			
			 return 20;
		 if(speed >12)			
			 return 15;
		 if(speed >8)			
		     return 10;
		 if(speed >5.5f)		
			 return 5.8f;
		 return 4;
		
		 }
	
	case DIVE: {
		if(speed >20)			
			 return 25;
		 if(speed >16)			
			 return 20;
		 if(speed >12)			
			 return 15;
		 if(speed >8)			
		     return 10;
		 if(speed >5.5f)		
			 return 5.8f;
		 return 2;
		 }
	case OTHER: {return 0;}
	case GPX:{
		if(speed>28)
			return 11.94f;
		if(speed>27)
			return 11.42f;
		if(speed>26)
			return 10.9f;
		if(speed>25)
			return 10.42f;
		if(speed>24)
			return 9.9f;
		if(speed>23)
			return 9.28f;
		if(speed>22)
			return 8.6f;
		if(speed>21)
			return 8;
		if(speed >20)			
			return 7.5f;
		if(speed >19)			
			return 6.8f;
		if(speed >18)			
			return 6.2f;
		if(speed >16)			
			return 6;		
		return 4;  
	}
	default:return 0 ; 
	}
	
	 
  }

public static void hideSoftKeyboard(Activity activity) {
	try{
	    InputMethodManager inputMethodManager = (InputMethodManager)  activity.getSystemService(Context.INPUT_METHOD_SERVICE);
	    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
	}catch(Exception e){
		logStackTrace(e, TAG);
	}
}
 

public static double getCalories(TrackType type,double speed,long sportTime,float upDist){
	
	float mets =Utils.getMets(type,(float)speed);
	float weight=QiYouConstant.PV_USER_WEIGHT;
	float hours =sportTime/(3600f*1000f);
	float calories =mets*weight*(hours);
	/*float eUp =tb.getEsumUp() ;
	float mgh =0;
	if(calories>0 && eUp>0){
		 mgh =weight*9.8f*eUp;
		 mgh =mgh/4.184f;
		
	}*/
//	calories +=mgh;
	calories =calories>0?calories:0;
	
	//客服重力做功
	float w =mets>0?QiYouConstant.PV_USER_WEIGHT*9.8f*upDist:0;
	
	//1焦耳(J)=0.2389卡(cal) 
	//w*0.2389f/1000; 为大卡？
	calories+=w*0.2389f/1000;
	
	calories =calories>0?calories:0;
	return calories;
}


public static GPX pareseGpx(InputStream in){ 
	
	
	GPXParser gp =new GPXParser();
	try {
		return gp.parseGPX(in);
	} catch (ParserConfigurationException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SAXException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return null;
}


public static GPX pareseGpx(String gpxfileName){
	  
		 
		  QLog.getLogger().d(dTAG, " begin to parese GPX file "+gpxfileName);
		  
		  File file = new File(gpxfileName);
	       
	  if(!file.exists()) return  null;
	
	   FileInputStream fis = null;
		try {
			fis = new FileInputStream(file);
		} catch (FileNotFoundException e) {
			 
	//		e.printStackTrace();
			Utils.logStackTrace(e, TAG);
			
			return null;
		}  catch(Exception er){
	//		 QLog.getLogger().d(dTAG, " 读文件错误");
			 Utils.logStackTrace(er, TAG);
			 return null;
		}
	//   InputStream in = new BufferedInputStream(fis);
	//	GPX gpx ;
	//	gpx= Utils.pareseGpx(in);
		return pareseGpx(new BufferedInputStream(fis));
	//	activity.app.setGpxTrack(new Track(gpx));
	//	activity.app.getGpxTrack().getTrackBean().setSrc(gpxfileName);
	//	 Intent serviceIntent = new Intent(activity, TrackDbServiceBackground.class);
	//     serviceIntent.putExtra(QiYouConstant.NEW_GPX_TRACK,"");
	//     activity.startService(serviceIntent); 
		
  }

@TargetApi(Build.VERSION_CODES.KITKAT)
public static String getPath(final Context context, final Uri uri) {

    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) {
                return Environment.getExternalStorageDirectory() + "/" + split[1];
            }

            // TODO handle non-primary volumes
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {

            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

            return getDataColumn(context, contentUri, null, null);
        }
        // MediaProvider
        else if (isMediaDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            Uri contentUri = null;
            if ("image".equals(type)) {
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if ("video".equals(type)) {
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else if ("audio".equals(type)) {
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            }

            final String selection = "_id=?";
            final String[] selectionArgs = new String[] {
                    split[1]
            };

            return getDataColumn(context, contentUri, selection, selectionArgs);
        }
    }
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) {

        // Return the remote address
        if (isGooglePhotosUri(uri))
            return uri.getLastPathSegment();

        return getDataColumn(context, uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    }

    return null;
}

/**
 * Get the value of the data column for this Uri. This is useful for
 * MediaStore Uris, and other file-based ContentProviders.
 *
 * @param context The context.
 * @param uri The Uri to query.
 * @param selection (Optional) Filter used in the query.
 * @param selectionArgs (Optional) Selection arguments used in the query.
 * @return The value of the _data column, which is typically a file path.
 */
public static String getDataColumn(Context context, Uri uri, String selection,
        String[] selectionArgs) {

    Cursor cursor = null;
    final String column = "_data";
    final String[] projection = {
            column
    };

    try {
        cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                null);
        if (cursor != null && cursor.moveToFirst()) {
            final int index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}


/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is ExternalStorageProvider.
 */
public static boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is DownloadsProvider.
 */
public static boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is MediaProvider.
 */
public static boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is Google Photos.
 */
public static boolean isGooglePhotosUri(Uri uri) {
    return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}


/*public static LatLng getGeoPoint(double lat ,double lon){
//	double mLat =  Utils.getbdLat(lat,lon);
//	double mLon =  Utils.getbdLon(lat, lon); 
//	int lat = (int) (mLat*1E6);
//   	int lon = (int) (mLon*1E6);
//	int lat = (int) (tb.getStartWp().getWb().getLatitude()*1E6);
//   	int lon = (int) (tb.getStartWp().getWb().getLongitude()*1E6);  
  return new LatLng((int)(getbdLat(lat,lon)*1E6), (int)(getbdLon(lat,lon)*1E6));
}*/

public static LatLng getLatLng(double lat ,double lon){
 
  return new LatLng(getbdLat(lat,lon), getbdLon(lat,lon));
}

// 判断手机中是否安装了讯飞语音+
public static boolean checkSpeechServiceInstall(Context context){
	 String packageName = "com.iflytek.speechcloud";
	 List<PackageInfo> packages = context.getPackageManager().getInstalledPackages(0);
	 for(int i = 0; i < packages.size(); i++){
		 PackageInfo packageInfo = packages.get(i);
		 if(packageInfo.packageName.equals(packageName)){
			 return true;
		 }else{
			 continue;
		 }
	 }
	 return false;
}


/*public static String buildPathPoints(CopyOnWriteArrayList<Waypoint_bean> wps,Track track,boolean is4Baidu,int size)throws NullPointerException{
*/
public static String buildPathPoints( ArrayList<Waypoint_bean> wps,Track track,boolean is4Baidu,int size)throws NullPointerException{

	
	 
	if(wps.size()<2)return "";
    
	Waypoint_bean wb;
//    Waypoint_bean lastWb = null;
    Waypoint_bean lastWb4map = null; 
//    final int MAXLATLNGS=50-3; 
//    float trackDist =track.getLastWp().getWb().getSumDist();
    
    Waypoint_bean startwp =track.getStartWp()!=null?track.getStartWp().getWb():wps.get(0);
    Waypoint_bean endwp =track.getLastWp()!=null?track.getLastWp().getWb():wps.get(wps.size()-1);
    Waypoint_bean maxwp =track.getMaxDistWp()!=null?track.getMaxDistWp().getWb():wps.get(wps.size()-1);
    
    float trackDist =endwp.getSumDist();
    float stepValue =wps.size()>size &&trackDist>0 ?trackDist/size:0;  
    String  pathPoints="";
    float skipDist=0;
//     float skiptDist=0;
//     QLog.getLogger().d(dTAG, TAG+" wps.size() is " + wps.size() +"----------------------------");
//     QLog.getLogger().d(dTAG, TAG+" MAXLATLNGS is " + MAXLATLNGS );
//     QLog.getLogger().d(dTAG, TAG+" trackDist/MAXLATLNGS " + trackDist/MAXLATLNGS );
//     
//     QLog.getLogger().d(dTAG, TAG+" stepValue is " + stepValue);
     
	 for(int i=0;i<wps.size();i++) {
	    	  
			 wb = wps.get(i);
			 
			 if(wb==null)continue;
			 if(lastWb4map==null)
				 lastWb4map =wb; 
			 if(wb.getTime()<lastWb4map.getTime())continue;
		 
			 if(outOfChina(wb.getLatitude(), wb.getLongitude()))continue;

//			 if (TextUtils.isEmpty(pathPoints)||wb.getTime()>lastWb4map.getTime())  
//				 QLog.getLogger().d(dTAG, TAG+" No.i,lastwb.gettime():"+i+"," + Utils.getFormatedTime(lastWb4map.getTime()));
//				 QLog.getLogger().d(dTAG, TAG+" wb.getSumDist()-lastWb.getSumDist()" + (wb.getSumDist()-lastWb.getSumDist()));
//				 QLog.getLogger().d(dTAG, TAG+" skipDist" + skipDist);
//				 QLog.getLogger().d(dTAG, TAG+" wb.getSumDist()-lastWb.getSumDist()+skipDist" + (wb.getSumDist()-lastWb.getSumDist()+skipDist));
				 float f =wb.getSumDist()-lastWb4map.getSumDist()+skipDist;
//				 QLog.getLogger().d(dTAG, TAG+" current dist " + f +", stepvalue is "+ stepValue +" dist >stepvalue?"+(f>=stepValue));
				 if(TextUtils.isEmpty(pathPoints)
						 ||wps.size()<=size
						 ||f>=stepValue 
						 ||wb.getTime()==startwp.getTime()
						 ||wb.getTime()==endwp.getTime()
						 ||wb.getTime()==maxwp.getTime())   
						 /*||wb.getTime()==track.getStartWp().getWb().getTime()
						 ||wb.getTime()==track.getLastWp().getWb().getTime()
						 ||wb.getTime()==track.getMaxDistWp().getWb().getTime()) */{ 
					 
					 if(is4Baidu) 
						 pathPoints=pathPoints+ getbdLon(wb.getLatitude(), wb.getLongitude())+","+ getbdLat(wb.getLatitude(), wb.getLongitude())+";";
					 else
						 pathPoints=pathPoints+ wb.getLatitude() +","+ wb.getLongitude() +"|";

					  skipDist=0; 
				 }
				 else
					 skipDist +=wb.getSumDist()-lastWb4map.getSumDist();
				 
				 lastWb4map =wb;
			  
//				lastWb=wb;
//			 if(wb.getTime()<lastWb4map.getTime())continue;
			  
			 
//			  wb.setBearDist(wb.getBearDist()+skiptDist);  //丢弃重复geo点
//			   skiptDist=0;
			   
	 }
	 
	 return pathPoints.length()>0?pathPoints.substring(0,pathPoints.length()-1):"";
	}


public static  ArrayList<Waypoint_bean> zipPathPoints(  Track_bean track,int targetSizePerKm)throws NullPointerException{

	 QLog.getLogger().d(dTAG,   "zip wps, target size is "+ targetSizePerKm + ",current size is "+ track.getTrkseg().size() );
	 
//	 if  ( track.getDistance() < 1000 ) {
//		 return track.getTrkseg();
//	 }
//	 
//	 int targetSizePerKm = 10 ; // per km 10 wps
	 double trackSizePerKm = track.getDistance() < 1000 ? track.getTrkseg().size() :  track.getTrkseg().size()/(track.getDistance()/1000.0);

		if(trackSizePerKm <= targetSizePerKm ){
			
			return track.getTrkseg();
		}
	  
	 int targetSize =    (int) (track.getDistance()/1000.0  * targetSizePerKm) ;
	 
	 
	if(track.getTrkseg().size() < targetSize ){
		
		return track.getTrkseg();
	}
	
	ArrayList<Waypoint_bean> wps = track.getTrkseg();
	ArrayList<Waypoint_bean> returnWps = new ArrayList<Waypoint_bean>() ;
	Waypoint_bean wb;
//    Waypoint_bean lastWb = null;
    Waypoint_bean lastWb4map = null; 
//    final int MAXLATLNGS=50-3; 
//    float trackDist =track.getLastWp().getWb().getSumDist();
    
    Waypoint_bean startwp =track.getStartWp()!=null?track.getStartWp().getWb():wps.get(0);
    Waypoint_bean endwp =track.getLastWp()!=null?track.getLastWp().getWb():wps.get(wps.size()-1);
    Waypoint_bean maxwp =track.getMaxDistWp()!=null?track.getMaxDistWp().getWb():wps.get(wps.size()-1);
    
    float trackDist =endwp.getSumDist();
    float stepValue =wps.size()>targetSize &&trackDist>0 ?trackDist/targetSize:0;  
//    String  pathPoints="";
    float skipDist=0;
//     float skiptDist=0;
//     QLog.getLogger().d(dTAG, TAG+" wps.size() is " + wps.size() +"----------------------------");
//     QLog.getLogger().d(dTAG, TAG+" MAXLATLNGS is " + MAXLATLNGS );
//     QLog.getLogger().d(dTAG, TAG+" trackDist/MAXLATLNGS " + trackDist/MAXLATLNGS );
//     
//     QLog.getLogger().d(dTAG, TAG+" stepValue is " + stepValue);
     float lastSumdist = 0;
	 for(int i=0;i<wps.size();i++) {
	    	  
			 wb = wps.get(i);
			 
			 if(wb==null)continue;
			 if(lastWb4map==null)
				 lastWb4map =wb; 
			 if(wb.getTime()<lastWb4map.getTime())continue;
		 
			 if(outOfChina(wb.getLatitude(), wb.getLongitude()))continue;

//			 if (TextUtils.isEmpty(pathPoints)||wb.getTime()>lastWb4map.getTime())  
//				 QLog.getLogger().d(dTAG, TAG+" No.i,lastwb.gettime():"+i+"," + Utils.getFormatedTime(lastWb4map.getTime()));
//				 QLog.getLogger().d(dTAG, TAG+" wb.getSumDist()-lastWb.getSumDist()" + (wb.getSumDist()-lastWb.getSumDist()));
//				 QLog.getLogger().d(dTAG, TAG+" skipDist" + skipDist);
//				 QLog.getLogger().d(dTAG, TAG+" wb.getSumDist()-lastWb.getSumDist()+skipDist" + (wb.getSumDist()-lastWb.getSumDist()+skipDist));
				 float f =wb.getSumDist()-lastWb4map.getSumDist()+skipDist;
//				 QLog.getLogger().d(dTAG, TAG+" current dist " + f +", stepvalue is "+ stepValue +" dist >stepvalue?"+(f>=stepValue));
				 if(returnWps.isEmpty()
						 ||f>=stepValue 
						 ||wb.getTime()==startwp.getTime()
						 ||wb.getTime()==endwp.getTime()
						 ||wb.getTime()==maxwp.getTime()   
					 	 ||!wb.getMedias().isEmpty()	
					 	 ||wb.getTurnFlag()!=wpFlag.NORMAL
					 	 || wb.getKmflag() > 0
					 	 
						 /*||wb.getTime()==track.getStartWp().getWb().getTime()
						 ||wb.getTime()==track.getLastWp().getWb().getTime()
						 ||wb.getTime()==track.getMaxDistWp().getWb().getTime()) */){ 
					  wb.setDistance(wb.getSumDist() - lastSumdist);
					  returnWps.add(wb);
					  lastSumdist = wb.getSumDist();
					  skipDist=0; 
				 }
				 else{
					 skipDist +=wb.getSumDist()-lastWb4map.getSumDist();
					 QLog.getLogger().d(dTAG,   "zip wps, skipDist" + skipDist +" wb is skipt: "+ wb.getSumDist());
				 }
				 
				 lastWb4map =wb;
			  
//				lastWb=wb;
//			 if(wb.getTime()<lastWb4map.getTime())continue;
			  
			 
//			  wb.setBearDist(wb.getBearDist()+skiptDist);  //丢弃重复geo点
//			   skiptDist=0;
			   
	 }
	 QLog.getLogger().d(dTAG,   "zip wps, returnWps.size() "+returnWps.size()+", zip percent " +returnWps.size()*100/wps.size() );
	 return returnWps;
	}


 static String getBaiduStaticUrl( /*CopyOnWriteArrayList<Waypoint_bean>*/ ArrayList<Waypoint_bean> wpsIn,Track track,boolean is4Baidu,int size)throws NullPointerException{
	
	/* CopyOnWriteArrayList<Waypoint_bean> wps = new CopyOnWriteArrayList<Waypoint_bean>();*/
	  ArrayList<Waypoint_bean> wps = new  ArrayList<Waypoint_bean>();
		for(Waypoint_bean wb:wpsIn){
			if(wb!=null)
				wps.add(wb);
		}
		if(wps.size()==0)return"";
	Waypoint_bean startwp =/*track.getStartWp()!=null?track.getStartWp().getWb():*/wps.get(0);
	Waypoint_bean endwp =/*track.getLastWp()!=null?track.getLastWp().getWb():*/wps.get(wps.size()-1);
	int width ;
	int height ;
//	int scale=1;
//	String center="";
	String pathStyle ;
	String format;
//	String staticMapUrl;
	final int maxWidth=1024;
	String baiduUrl ="https://api.map.baidu.com/staticimage";
	QLog.getLogger().i(dTAG, "screen width * height:" +QiYouConstant.PV_INT_SCREEN_WIDTH+"*"+QiYouConstant.PV_INT_SCREEN_HEIGHT);
	width= QiYouConstant.PV_INT_SCREEN_WIDTH>0? QiYouConstant.PV_INT_SCREEN_WIDTH:720;
	 
// 	width= QiYouConstant.PV_INT_SCREEN_HEIGHT>0? QiYouConstant.PV_INT_SCREEN_HEIGHT:540;
     width =width/2;
     width=width>maxWidth?maxWidth:width;
//	height=width/3;
//    width =width/2;
//	height=height/2;
  	 height=width*QiYouConstant.PV_INT_SCREEN_WIDTH/QiYouConstant.PV_INT_SCREEN_HEIGHT;
//	  center="";
	  pathStyle="0xff0000,4,1";
	  
	  String startpoint=startwp==null?""
			  : getbdLon(startwp.getLatitude(), startwp.getLongitude())
			  	+","
			  	+ getbdLat(startwp.getLatitude(), startwp.getLongitude())
			  	; 
	  String endpoint=endwp==null?""
			  : getbdLon(endwp.getLatitude(), endwp.getLongitude())
			  	+","
			  	+ getbdLat(endwp.getLatitude(), endwp.getLongitude())
			  	;  
	  
	   format ="?"  
			+"width=%s&height=%s&paths=%s&pathStyles=%s" 
//            +"&copyright=1&scale=%s"
            +"&copyright=1"
			+"&markers=%s&markerStyles=-1,https://www.i7lv.net/icon_start.png|-1,https://www.i7lv.net/icon_end.png"
			; 
	  
		  
	 return baiduUrl+String.format(format, width,height,buildPathPoints(  wps, track,  is4Baidu,  size),pathStyle, startpoint +"|"+endpoint); 
}

public static String getBaiduStaticMapUrl(  Track track ){
	String url="";
	try{
	url= track.getTrackBean().getTrkseg().size()>2?Utils.getBaiduStaticUrl(track.getTrackBean().getTrkseg()
			 ,track
			 ,true
			 ,50-3):"";
	}catch(NullPointerException e){
		logStackTrace(e,dTAG);
	}
	 QLog.getLogger().d(dTAG, " displaying static image of " + url);
	return url;
}

 public static String getBaiduStaticUrlFromServer(int svrNo){
	 return QiYouConstant.BASE_STATIC_URL+svrNo;
 }
	
	private static Pattern pattern;
	private static Matcher matcher;
	//Email Pattern
	private static final String EMAIL_PATTERN = 
			"^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
			+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
	
	/**
	 * Validate Email with regular expression
	 * 
	 * @param email
	 * @return true for Valid Email and false for Invalid Email
	 */
	public static boolean validate(String email) {
		pattern = Pattern.compile(EMAIL_PATTERN);
		matcher = pattern.matcher(email);
		return matcher.matches();
	
	}
	/**
	 * Checks for Null String object
	 * 
	 * @param txt
	 * @return true for not null and false for null String object
	 */
	public static boolean isNotNull(String txt){
//		return txt!=null && txt.trim().length()>0 ? true: false;
		return TextUtils.isEmpty(txt);
	}
	
	static Gson gson=null;
	public static Gson getGson(){
		if(gson==null)
			gson= new Gson();
		return gson;
	}
	public static String getGsonString(Object obj){
		
		return getGson().toJson(obj).toString();
	}
	
	public static Object getGsonObject(String json ,Class<?> T)throws JsonSyntaxException {
//		QLog.getLogger().dLog(TAG,"json is:" + json);
		return getGson().fromJson(json, T);
	}
	
	    /*
		 * MD5加密
		 */
	    public static  String getMD5Str(String str) {     
	        MessageDigest messageDigest = null;     
	     
	        try {     
	            messageDigest = MessageDigest.getInstance("MD5");     
	     
	            messageDigest.reset();     
	     
	            messageDigest.update(str.getBytes("UTF-8"));     
	        } catch (NoSuchAlgorithmException e) {     
	        	e.printStackTrace();   
	        } catch (UnsupportedEncodingException e) {     
	            e.printStackTrace();     
	        }     
	     
	        byte[] byteArray = messageDigest.digest();     
	     
	        StringBuffer md5StrBuff = new StringBuffer();     
	        
	        for (int i = 0; i < byteArray.length; i++) {                 
	            if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)     
	                md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));     
	            else     
	                md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));     
	        }     
	      //16位加密，从第9位到25位
	        return md5StrBuff.substring(8, 24).toString().toUpperCase();    
	    } 
	    
	    
	/*   public static 	 CopyOnWriteArrayList<Waypoint_bean> getCleanWbs(CopyOnWriteArrayList<Waypoint_bean> owbs){
		   CopyOnWriteArrayList<Waypoint_bean>  wbs=new CopyOnWriteArrayList<Waypoint_bean>(); 
		 long lastTime=0;
		 for(Waypoint_bean wb:owbs){ 
			if(wb==null)continue;
			if( wb.getTurnFlag().toInt()>=wpFlag.CUST.toInt() || wb.getTime()>lastTime){ 
				 wbs.add(wb);
				 lastTime =wb.getTime();				 
			}
	       }
		 return wbs;
	   }*/
	   public static 	  ArrayList<Waypoint_bean> getCleanWbs( ArrayList<Waypoint_bean> owbs){
		   ArrayList<Waypoint_bean>  wbs=new  ArrayList<Waypoint_bean>(); 
		 long lastTime=0;
		 for(Waypoint_bean wb:owbs){ 
			if(wb==null)continue;
			if( wb.getTurnFlag().toInt()>=wpFlag.CUST.toInt() || wb.getTime()>lastTime){ 
				 wbs.add(wb);
				 lastTime =wb.getTime();				 
			}
	       }
		 return wbs;
	   }
	   public static int getAndroidSDKVersion() { 
		   int version = 0; 
		   try { 
		     version = Integer.valueOf(android.os.Build.VERSION.SDK); 
		   } catch (NumberFormatException e) { 
			   logStackTrace(e, TAG);
		   } 
		   return version; 
		}
	   
	   
	   public static Bitmap getBitmapFromView(View view ) {
//			int widthSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
// 			int heightSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
//			view.measure(widthSpec, heightSpec);
//			view.layout(0, 0, width, height);
 			 
			Bitmap bitmap = Bitmap.createBitmap(view.getWidth() , view.getHeight(), Bitmap.Config.ARGB_8888);
			Canvas canvas = new Canvas(bitmap);
			Drawable bgDrawable =view.getBackground();
			if (bgDrawable!=null) 
			    bgDrawable.draw(canvas);
			else 
// 				canvas.drawColor(R.color.ivory);//#FFFFF0
				canvas.drawColor(Color.parseColor("#FFFFFF") );
			
			view.draw(canvas);
//			canvas.drawBitmap(bitmap, 0,0, null);
			return bitmap;
		} 
	   
	   public static Bitmap convertViewToBitmap(View view){
		    view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
 		        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
		        view.buildDrawingCache();
		        Bitmap bitmap = view.getDrawingCache();

		 return bitmap;
		}
	   
	   
	   public static int getTrackType(){
		  
 	    		 return QiYouConstant.DEVELOPER_MODE?
 	    				 R.array.trackType:R.array.trackType;
// 	    				 R.array.trackType_develop_use:R.array.trackType;
	   }
	   
	   
	   public static  String getCacheFileName(String fileName)
		  {
		    File localFile = new File(QiYouConstant.GPX_CACHE_PATH);
		    if (!localFile.exists()) {
		      localFile.mkdirs();
		    }
		    return localFile.getAbsolutePath() + File.separator + fileName + ".txt";
		  }
		 

	   public static   Track getTrackFromWebCache(String paramString)  throws IOException,JsonSyntaxException{ 
		    String str = Utils.readSDFile(getCacheFileName(paramString));
		    QLog.getLogger().d(dTAG, TAG +"reading track from gpx cache" +getCacheFileName(paramString));
		    if (TextUtils.isEmpty(str)) {
		    	return null;
		    } 
		    QLog.getLogger().d(dTAG, TAG +"reading track from gpx cache ... success " +str);
		    return  new Track((Track_bean)Utils.getGsonObject(str, Track_bean.class)); 
		  }
		  
	   
	   public static String getProvince(String province){
		   
		   if(TextUtils.isEmpty(province))return "";
		   
		   if(province.startsWith("黑龙江"))return "黑龙江";
		   if(province.startsWith("新疆"))return "新疆";
		   if(province.startsWith("西藏"))return "西藏";
		   if(province.startsWith("广西"))return "广西";
		   if(province.startsWith("宁夏"))return "宁夏";
		   if(province.startsWith("西藏"))return "西藏";
		   return province.substring(0,3);
	   }
	   
   public static String getGeoDistrict(String geoIn,int length){
		   
	   	
		   if(TextUtils.isEmpty(geoIn))return geoIn;
		   int lng=length<geoIn.length()?length:geoIn.length();
		   return geoIn.substring(0,lng);
		   
		  
	   }
   
//   public static String getUserAlbum(int id){
//		return QiYouConstant.BASE_MD_URL + "upload/user/0/" +id + "/banner";
//   }
   
   public static String getUserAlbum(User_bean user  ){
	  
	   String thumbUrl= TextUtils.isEmpty(user.getAlbum())?user.getQqAbulmUrl() :Utils.getUserAlbum(user.getAlbum());
	 return  thumbUrl ;
   }
   
   public static String getUserAlbum(  String thumbUrl ){
		  
	 
	   if (TextUtils.isEmpty(thumbUrl)){
		   return "";
	   }
	   if (thumbUrl.contains("qq")){
		   return thumbUrl;
	   }
		return QiYouConstant.BASE_MD_URL + thumbUrl;
   }
   
   
   public static String encodeBase64(String str){
//	   Base64 b =  Base64.  
//       String credentials = new String(b.decode(base64Credentials), Charset.forName("UTF-8"));
	   
	   String enToStr = Base64.encodeToString(str.getBytes(), Base64.DEFAULT);
	   QLog.getLogger().d(dTAG,   "encodeToString >>> " + enToStr);
       return enToStr;
   }
	   
   
}
