package com.wistron.WiGallery.GEO; import java.util.ArrayList; import java.util.List; import java.util.Locale; import com.wistron.WiGallery.WiGalleryInterface.BatchProcessCallBack; import com.wistron.swpc.wicamera3dii.R; import Utilities.CSStaticData; import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.location.Address; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.util.Log; /** * Copyright (c) 2011 Wistron SWPC * All rights reserved. * @author Cocoonshu * @date 2012-02-29 11:21:49 * @purpose 可通过这个类,在Cache中查询GEO信息,也可以管理Cache * @detail 流程:在Cache中查不到则联网查询 */ public class GEOCacheHelper { private static final String TAG = "GEOCacheHelper"; public static final int EARTH_RADIUS_METERS = 6378137; //地球半径 public static final int LAT_MIN = -90; //最小纬度 public static final int LAT_MAX = 90; //最大纬度 public static final int LON_MIN = -180; //最小经度 public static final int LON_MAX = 180; //最大经度 private static final int MAX_COUNTRY_NAME_LENGTH = 8; //国家名称限制 private static final int MAX_LOCALITY_MILE_RANGE = 20; //地点范围限制 private static String UNKNOWN_LOCATION = "Unknown"; //默认未知地理位置字符串 private Context mContext = null; private GEODBAdapter mSqlReader = null; private Address mAddress = null; private String mLangeuage = ""; //默认:不带语言标签 public GEOCacheHelper(Context context) { mContext = context; mLangeuage = Locale.getDefault().getLanguage(); mSqlReader = new GEODBAdapter(mContext, mLangeuage); UNKNOWN_LOCATION = context.getResources().getString(R.string.no_location); if(UNKNOWN_LOCATION == null || UNKNOWN_LOCATION.equals("")){ UNKNOWN_LOCATION = "Unknown"; } } public void clearDataBase(){ if(mSqlReader != null){ mSqlReader.clearAll(); } } public void close(){ if(mSqlReader != null){ mSqlReader.close(); } System.gc(); } protected void closeDataBase(){ if(mSqlReader != null){ mSqlReader.close(); mSqlReader = null; } System.gc(); } /** * 获取定位字符串 * @param latitude * @param longitude * @return */ public String[] getLocationString(double latitude, double longitude){ String[] result = null; if(!Double.isNaN(latitude) && !Double.isNaN(longitude)){ try{ //先在数据库中查找 result = searchInLib(latitude, longitude, mLangeuage); result = checkEmpty(result); //如果数据库中没有找到结果,则在线查找 if(result == null || checkEmpty(result)[0].equals(UNKNOWN_LOCATION) || result.equals(UNKNOWN_LOCATION)){ result = searchOnInternet(latitude, longitude, mLangeuage); } }catch (SQLException e) { if(CSStaticData.DEBUG){ e.printStackTrace(); } result = null; }catch (ArrayIndexOutOfBoundsException e) { if(CSStaticData.DEBUG){ e.printStackTrace(); } result = null; }catch (Exception e) { if(CSStaticData.DEBUG){ e.printStackTrace(); } result = null; } }else{ result = null; } //检查位置字符串是否为空串 result = checkEmpty(result); return result; } public List<String[]> getLocationStringBatch(List<CoordinateMap> maps, BatchProcessCallBack callback){ int mapsSize = 0; boolean isNetWorkConnectable = true; //网络是否连通 String[] elemResult = null; CoordinateMap elem = null; List<String[]> result = new ArrayList<String[]>(); NetworkInfo networkInfo = null; ConnectivityManager connectivityManager = null; if(maps == null){ return null; } if(maps.size() == 0){ return result; } //判断网络状态 connectivityManager = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); networkInfo = connectivityManager.getActiveNetworkInfo(); if (networkInfo == null || !networkInfo.isConnected()) { isNetWorkConnectable = false; } //先在数据库中批量查询 mapsSize = maps.size(); for(int i = 0; i < mapsSize; i++){ elem = maps.get(i); if(elem != null){ if(!Double.isNaN(elem.getLatitude()) && !Double.isNaN(elem.getLongitude())){ try{ //先在数据库中查找 elemResult = searchInLib(elem.getLatitude(), elem.getLongitude(), mLangeuage); //如果数据库中没有找到结果,则在线查找 if(isNetWorkConnectable && (elemResult == null || checkEmpty(elemResult)[0].equals(UNKNOWN_LOCATION) || elemResult.equals(UNKNOWN_LOCATION))){ elemResult = searchOnInternet(elem.getLatitude(), elem.getLongitude(), mLangeuage); } }catch (SQLException e) { if(CSStaticData.DEBUG){ e.printStackTrace(); } elemResult = null; }catch (ArrayIndexOutOfBoundsException e) { if(CSStaticData.DEBUG){ e.printStackTrace(); } elemResult = null; }catch (Exception e) { elemResult = null; }finally{ //保持查询队列的连续性 //Do Nothing } }else{ elemResult = null; } //检查位置字符串是否为空串 elemResult = checkEmpty(elemResult); //添加查询结果 result.add(elemResult); }else{ result.add(null); } //调用回调 if(callback != null){ if(i == 0){ callback.startProcess(i, mapsSize); callback.inProcess(i, mapsSize); }else if(i == mapsSize - 1){ callback.endProcess(i, mapsSize); callback.inProcess(i, mapsSize); }else{ callback.inProcess(i, mapsSize); } } } return result; } /** * 在线搜索位置字符串 * @return */ protected String[] searchOnInternet(double latitude, double longitude, String langeuage){ String[] result = new String[4]; String defaultResult = ""; GEOAddress geoAddress = null; StringBuilder address = null; NetworkInfo networkInfo = null; ConnectivityManager connectivityManager = null; if(CSStaticData.DEBUG && false){ Log.w(TAG, "[searchOnInternet]联线搜索地理信息: GPS(" + latitude + ", " + longitude + ")"); } if(Double.isNaN(latitude) && Double.isNaN(longitude)){ return new String[]{defaultResult}; } //判断网络状态 connectivityManager = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); networkInfo = connectivityManager.getActiveNetworkInfo(); if (networkInfo == null || !networkInfo.isConnected()) { result = new String[]{defaultResult}; return result; } //连线查询 try { address = GEOCoder.getAddress(latitude, longitude, langeuage); result = GEOCoder.parserJSON(address.toString(), GEOCoder.PRECISION_ORG); if(result != null){ geoAddress = new GEOAddress(); geoAddress.setCountryName(result[0]); geoAddress.setLocality(result[1]); geoAddress.setAdminArea(result[2]); geoAddress.setSubAdminArea(result[3]); } } catch (IllegalArgumentException e) { if(CSStaticData.DEBUG){ e.printStackTrace(); } geoAddress = new GEOAddress(); } //插入数据库 if(result != null){ if(mSqlReader == null){ mSqlReader = new GEODBAdapter(mContext, mLangeuage); } // if(!mLangeuage.equals(address.getLocale().getLanguage())){ // //重开数据库 // closeDataBase(); // mLangeuage = address.getLocale().getLanguage(); // mSqlReader = new GEODBAdapter(mContext, mLangeuage); // } //执行插入事务 mSqlReader.insert(getUID(latitude, longitude), geoAddress, mLangeuage); mSqlReader.close(); } //过滤数据,检查位置字符串中有没有"null"标签 for(int i = 0; i < result.length; i++){ checkNull(result[i]); } return result; } /** * 在数据库中搜索位置字符串 * @param langeuage * @param uid * @return */ protected String[] searchInLib(double latitude, double longitude, String langeuage) throws SQLException{ String[] result = null; String defaultResult = ""; long uid = 0l; Cursor cursor = null; if(CSStaticData.DEBUG && false){ Log.w(TAG, "[searchInLib]本地搜索地理信息: GPS(" + latitude + ", " + longitude + ")"); } if(Double.isNaN(latitude) && Double.isNaN(longitude)){ return new String[]{defaultResult}; } //计算UID uid = getUID(latitude, longitude); if(mSqlReader == null){ mSqlReader = new GEODBAdapter(mContext, mLangeuage); } if(!mLangeuage.equals(langeuage)){ //重开数据库 closeDataBase(); mLangeuage = langeuage; mSqlReader = new GEODBAdapter(mContext, mLangeuage); } //执行查询事务 cursor = mSqlReader.select(uid, mLangeuage); //过滤数据 if(cursor != null && cursor.getCount() > 0){ //找到有效数据 if(!cursor.moveToFirst()){ do{ if(cursor.moveToNext()){ break; } }while(!cursor.isLast()); } //读取数据 result = new String[4]; result[0] = cursor.getString(1); result[1] = cursor.getString(2); result[2] = cursor.getString(3); result[3] = cursor.getString(4); }else{ result = new String[]{defaultResult}; } //关闭数据库 mSqlReader.close(); //检查位置字符串中有没有"null"标签 for(int i = 0; i < result.length; i++){ checkNull(result[i]); } return result; } /** * 获取由经纬度换算的UID * @param latitude * @param longitude * @return */ protected long getUID(double latitude, double longitude) { return (long) (((latitude + LAT_MAX) * 2 * LAT_MAX + (longitude + LON_MAX)) * EARTH_RADIUS_METERS); } /** * 防止从数据库中读取出null * @param locality * @return */ protected String checkNull(String locality) { if (locality == null) return ""; if (locality.equals("null")) return ""; return locality; } /** * 检查位置字符串是否为空串 * 空串则返回"Unknown", 否则返回原字符串 * @param locality * @return */ protected String[] checkEmpty(String[] locality) { boolean passable = false; if(locality != null){ for(int i = 0; i < locality.length; i++){ if(locality[i] != null && !locality[i].equals("")){ passable = true; break; } } } if(!passable){ return new String[]{UNKNOWN_LOCATION}; }else{ return locality; } } }