自製導航
public class Map extends FragmentActivity implements LocationListener {
private LocationManager loctionManager;
private GoogleMap gMap;
private final LatLng destination = new LatLng(23.737958, 120.50840399999993);
private LatLng outset = null;
private MarkerOptions EndMarket, StartMarket;
private String bestProvider = LocationManager.GPS_PROVIDER;
private boolean getGPSService = true;
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
Uri uri = Uri.parse("geo:25.047192, 121.516981"); //經緯度
final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.map);
SupportMapFragment sFragment = (SupportMapFragment) this
.getSupportFragmentManager().findFragmentById(R.id.map);
gMap = sFragment.getMap();
// 設定地圖類型:Normal(典型);Hybrid(混合衛星照片及道路);Satellite(衛星);Terrain(地形);None(什麼都沒有);
gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
gMap.setTrafficEnabled(false);
gMap.setMyLocationEnabled(true);
EndMarket = new MarkerOptions();
StartMarket = new MarkerOptions();
updateView(locationServiceInitial());
}
/**
* 更新位置
*
* @param location
*/
public void updateView(Location location) {
if (location != null) {
outset = new LatLng(location.getLatitude(), location.getLongitude());
StartMarket.position(outset);
StartMarket.title("現在位置");
gMap.clear();
EndMarket.position(destination);
EndMarket.title("家");
gMap.addMarker(EndMarket);
gMap.addMarker(StartMarket);
gMap.moveCamera(CameraUpdateFactory.newLatLng(outset));
gMap.animateCamera(CameraUpdateFactory.zoomTo(15));
if (outset != null) {
// 取得URL到Google路線API
String url = getDirectionsUrl(outset, destination);
DownloadTask downloadTask = new DownloadTask();
// 開始下載從Google路線API的JSON數據
downloadTask.execute(url);
}
Toast.makeText(
Map.this,
"現在位置(" + location.getLatitude() + ","
+ location.getLongitude() + ")", Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(Map.this, "無法定位現在位置", Toast.LENGTH_SHORT).show();
}
}
/**
* 取得URL到Google路線API
*
* @param origin
* @param dest
* @return
*/
private String getDirectionsUrl(LatLng origin, LatLng dest) {
// 起點
String str_origin = "origin=" + origin.latitude + ","
+ origin.longitude;
// 終點
String str_dest = "destination=" + dest.latitude + "," + dest.longitude;
// 感應器啟用
String sensor = "sensor=false";
// 建立參數到Web Service
String parameters = str_origin + "&" + str_dest + "&" + sensor;
// 輸出格式
String output = "json";
// 構建URL到Web Service
String url = "https://maps.googleapis.com/maps/api/directions/"
+ output + "?" + parameters;
return url;
}
/**
* 解析JSON格式
*
* @author sakata
*
*/
public class ParserTask extends
AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {
// 解析在非UI thread中的數據
@Override
protected List<List<HashMap<String, String>>> doInBackground(
String... jsonData) {
JSONObject jObject;
List<List<HashMap<String, String>>> routes = null;
try {
jObject = new JSONObject(jsonData[0]);
DirectionsJSONParser parser = new DirectionsJSONParser();
// Starts parsing data
routes = parser.parse(jObject);
} catch (Exception e) {
e.printStackTrace();
}
return routes;
}
// 執行在UI thread,解析過程後
@Override
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = null;
PolylineOptions lineOptions = null;
// 通過所有的穿越路線
for (int i = 0; i < result.size(); i++) {
points = new ArrayList<LatLng>();
lineOptions = new PolylineOptions();
// 取第i個途徑
List<HashMap<String, String>> path = result.get(i);
// 在第i個途徑獲取所有的點
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
// 在路線LineOptions將所有的點
lineOptions.addAll(points);
lineOptions.width(5); // 導航路徑寬度
lineOptions.color(Color.BLUE); // 導航路徑顏色
}
// 在Google地圖繪製折線為第i個路徑
gMap.addPolyline(lineOptions);
}
}
/**
* 從傳遞的url獲取數據
*
* @author sakata
*
*/
public class DownloadTask extends AsyncTask<String, Void, String> {
/**
* 從URL下載JSON資料的方法
*
* @param strUrl
* @return
* @throws IOException
*/
private String downloadUrl(String strUrl) throws IOException {
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(strUrl);
// 創建一個http連接與URL進行溝通
urlConnection = (HttpURLConnection) url.openConnection();
// 連接URL
urlConnection.connect();
// 從URL讀取數據
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(
iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line);
}
data = sb.toString();
br.close();
} catch (Exception e) {
System.out.println("異常在下載時URL發生錯誤 " + e.toString());
} finally {
iStream.close();
urlConnection.disconnect();
}
return data;
}
// 在非UI thread下載數據
protected String doInBackground(String... url) {
// 從Web服務存儲數據
String data = "";
try {
// 從Web服務獲取數據
data = downloadUrl(url[0]);
} catch (Exception e) {
System.out.println("背景工作發生錯誤 " + e.toString());
}
return data;
}
// 執行在UI線程,執行後 doInBackground()
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
ParserTask parserTask = new ParserTask();
// 調用解析JSON數據的線程
parserTask.execute(result);
}
}
/**
* 鍵盤事件
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
loctionManager.removeUpdates((LocationListener) this);
gMap.clear();
Toast.makeText(Map.this, "結束", Toast.LENGTH_SHORT).show();
finish();
}
return super.onKeyDown(keyCode, event);
}
/**
* 位置改變
*/
@Override
public void onLocationChanged(Location location) {
updateView(location);
}
/**
* 停用
*/
@Override
public void onProviderDisabled(String provider) {
}
/**
* 啟用
*/
@Override
public void onProviderEnabled(String provider) {
}
/**
* 狀態改變
*/
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
/**
* 啟用定位模組,使用後記得關閉
*
* @return Location
*/
public Location locationServiceInitial() {
getGPSService = true;
loctionManager = (LocationManager) getSystemService(LOCATION_SERVICE); // 取得系統定位服務
Criteria criteria = new Criteria(); // 資訊提供者選取標準
bestProvider = loctionManager.getBestProvider(criteria, true);
Location location = loctionManager
.getLastKnownLocation(bestProvider); // 使用GPS定位座標
if (location != null) {
return location;
} else {
Toast.makeText(this, "無法定位座標", Toast.LENGTH_LONG).show();
return null;
}
}
@Override
protected void onResume() {
super.onResume();
if (getGPSService) {
updateView(locationServiceInitial());
// 服務提供者、更新頻率毫秒、最短距離、地點改變時呼叫物件
loctionManager.requestLocationUpdates(bestProvider, 1000, 1,
(LocationListener) this);
}
}
@Override
protected void onPause() {
super.onPause();
if (getGPSService) {
loctionManager.removeUpdates((LocationListener) this); // 離開頁面時停止更新
getGPSService = false;
}
}
}
取得定位座標
package tw.com.WeddingInvitation.Set;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.android.gms.maps.model.LatLng;
public class DirectionsJSONParser {
/**
* 接收一個JSONObject並返回一個列表的列表,包含經緯度
*
* @param jObject
* @return
*/
public List<List<HashMap<String, String>>> parse(JSONObject jObject) {
List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String, String>>>();
JSONArray jRoutes = null;
JSONArray jLegs = null;
JSONArray jSteps = null;
try {
jRoutes = jObject.getJSONArray("routes");
// 經過所有路由器
for (int i = 0; i < jRoutes.length(); i++) {
jLegs = ((JSONObject) jRoutes.get(i)).getJSONArray("legs");
ArrayList<HashMap<String, String>> path = new ArrayList<HashMap<String, String>>();
// 經過所有的路徑
for (int j = 0; j < jLegs.length(); j++) {
jSteps = ((JSONObject) jLegs.get(j)).getJSONArray("steps");
// 經過所有的步驟
for (int k = 0; k < jSteps.length(); k++) {
String polyline = "";
polyline = (String) ((JSONObject) ((JSONObject) jSteps
.get(k)).get("polyline")).get("points");
List<LatLng> list = decodePoly(polyline);
// 經過所有的點
for (int l = 0; l < list.size(); l++) {
HashMap<String, String> hm = new HashMap<String, String>();
hm.put("lat",
Double.toString(((LatLng) list.get(l)).latitude));
hm.put("lng",
Double.toString(((LatLng) list.get(l)).longitude));
path.add(hm);
}
}
routes.add(path);
}
}
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
}
return routes;
}
/**
* 解碼折線點的方法
*
* @param encoded
* @return
*/
private List<LatLng> decodePoly(String encoded) {
List<LatLng> poly = new ArrayList<LatLng>();
int index = 0, len = encoded.length();
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
LatLng p = new LatLng((((double) lat / 1E5)),
(((double) lng / 1E5)));
poly.add(p);
}
return poly;
}
}