我已經跟着教程創建簡單的Android的地圖,這裏是我的源代碼(MainActivity.java):谷歌地圖V2的Android犯規出現
package com.tugas.akhir;
import java.util.List;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import android.widget.ToggleButton;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.CancelableCallback;
import com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import com.tugas.akhir.R;
import com.tugas.akhir.googlemaps.GMapV2Direction;
import com.tugas.akhir.googlemaps.GetRotueListTask;
import com.tugas.akhir.googlemaps.GMapV2Direction.DirecitonReceivedListener;
import android.support.v4.app.FragmentActivity;
/**
*
* @author Omer F. KAPLAN
*
*/
public class MapActivity extends FragmentActivity
implements OnClickListener, OnInfoWindowClickListener,
DirecitonReceivedListener {
private GoogleMap mMap;
private Button btnDirection;
LatLng startPosition;
String startPositionTitle;
String startPositionSnippet;
LatLng destinationPosition;
String destinationPositionTitle;
String destinationPositionSnippet;
ToggleButton tbMode;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startPosition = new LatLng(41.036896, 28.985490);
startPositionTitle = "Taksim Square";
startPositionSnippet = "Istanbul/Turkey";
destinationPosition = new LatLng(41.005921, 28.977737);
destinationPositionTitle = "Sultanahmet Mosque, Istanbul";
destinationPositionSnippet = "Istanbul/Turkey";
btnDirection = (Button) findViewById(R.id.btnDirection);
btnDirection.setOnClickListener(this);
tbMode = (ToggleButton) findViewById(R.id.tbMode);
tbMode.setChecked(true);
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the
// map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.setMyLocationEnabled(true);
mMap.setIndoorEnabled(true);
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
mMap.getUiSettings().setCompassEnabled(true);
mMap.getUiSettings().setAllGesturesEnabled(true);
mMap.setOnInfoWindowClickListener(this);
}
public void clearMap() {
mMap.clear();
}
@Override
public void onClick(View v) {
if (v == btnDirection) {
clearMap();
MarkerOptions mDestination = new MarkerOptions()
.position(destinationPosition)
.title(destinationPositionTitle)
.snippet(destinationPositionSnippet)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.pin1));
MarkerOptions mStart = new MarkerOptions()
.position(startPosition)
.title(startPositionTitle)
.snippet(startPositionSnippet)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.pin2));
mMap.addMarker(mDestination);
mMap.addMarker(mStart);
if (tbMode.isChecked()) {
new GetRotueListTask(MapActivity.this, startPosition,
destinationPosition, GMapV2Direction.MODE_DRIVING, this)
.execute();
} else {
new GetRotueListTask(MapActivity.this, startPosition,
destinationPosition, GMapV2Direction.MODE_WALKING, this)
.execute();
}
}
}
@Override
public void OnDirectionListReceived(List<LatLng> mPointList) {
if (mPointList != null) {
PolylineOptions rectLine = new PolylineOptions().width(10).color(
Color.RED);
for (int i = 0; i < mPointList.size(); i++) {
rectLine.add(mPointList.get(i));
}
mMap.addPolyline(rectLine);
CameraPosition mCPFrom = new CameraPosition.Builder()
.target(startPosition).zoom(15.5f).bearing(0).tilt(25)
.build();
final CameraPosition mCPTo = new CameraPosition.Builder()
.target(destinationPosition).zoom(15.5f).bearing(0)
.tilt(50).build();
changeCamera(CameraUpdateFactory.newCameraPosition(mCPFrom),
new CancelableCallback() {
@Override
public void onFinish() {
changeCamera(CameraUpdateFactory
.newCameraPosition(mCPTo),
new CancelableCallback() {
@Override
public void onFinish() {
LatLngBounds bounds = new LatLngBounds.Builder()
.include(startPosition)
.include(
destinationPosition)
.build();
changeCamera(
CameraUpdateFactory
.newLatLngBounds(
bounds, 50),
null, false);
}
@Override
public void onCancel() {
}
}, false);
}
@Override
public void onCancel() {
}
}, true);
}
}
/**
* Change the camera position by moving or animating the camera depending on
* input parameter.
*/
private void changeCamera(CameraUpdate update, CancelableCallback callback,
boolean instant) {
if (instant) {
mMap.animateCamera(update, 1, callback);
} else {
mMap.animateCamera(update, 4000, callback);
}
}
@Override
public void onInfoWindowClick(Marker selectedMarker) {
if (selectedMarker.getTitle().equals(startPositionTitle)) {
Toast.makeText(this, "Marker Clicked: " + startPositionTitle,
Toast.LENGTH_LONG).show();
} else if (selectedMarker.getTitle().equals(destinationPositionTitle)) {
Toast.makeText(this, "Marker Clicked: " + destinationPositionTitle,
Toast.LENGTH_LONG).show();
}
selectedMarker.hideInfoWindow();
}
@Override
protected void onResume() {
super.onResume();
}
}
除了MainActivity.java,我寫下GetRotueListTask.java,這裏的源代碼:
package com.tugas.akhir.googlemaps;
import java.util.List;
import android.app.ProgressDialog;
import android.content.Context;
import android.net.ConnectivityManager;
import android.os.AsyncTask;
import android.widget.Toast;
import com.google.android.gms.maps.model.LatLng;
import com.tugas.akhir.googlemaps.GMapV2Direction.DirecitonReceivedListener;
public class GetRotueListTask extends AsyncTask<Void, Void, Void> {
private final Context mContext;
GMapV2Direction mGMDirection = new GMapV2Direction();
LatLng fromPosition;
LatLng toPosition;
List<LatLng> mPointList;
private ProgressDialog dialog;
private int mDirectionMode;
DirecitonReceivedListener mListener;
public GetRotueListTask(Context context, LatLng fromPosition,
LatLng toPosition, int mDirectionMode,
DirecitonReceivedListener mListener) {
this.mContext = context;
this.fromPosition = fromPosition;
this.toPosition = toPosition;
this.mDirectionMode = mDirectionMode;
this.mListener = mListener;
}
@Override
protected Void doInBackground(Void... params) {
mGMDirection.setParams(fromPosition, toPosition, mDirectionMode);
mPointList = mGMDirection.getPointList(this.mContext);
return null;
}
@Override
protected void onPostExecute(Void result) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if (mPointList != null) {
mListener.OnDirectionListReceived(mPointList);
} else {
Toast.makeText(this.mContext, "Error downloading direction!",
Toast.LENGTH_LONG).show();
}
}
@Override
protected void onPreExecute() {
ConnectivityManager conMgr = (ConnectivityManager) mContext
.getApplicationContext().getSystemService(
Context.CONNECTIVITY_SERVICE);
if (conMgr.getActiveNetworkInfo() != null
&& conMgr.getActiveNetworkInfo().isAvailable()
&& conMgr.getActiveNetworkInfo().isConnectedOrConnecting()) {
// Background: Connected to internet
dialog = new ProgressDialog(mContext);
dialog.setMessage("Downloading directions...");
dialog.show();
} else {
this.cancel(true);
Toast.makeText(mContext, "Not connected to internet!",
Toast.LENGTH_LONG).show();
}
}
@Override
protected void onCancelled() {
super.onCancelled();
}
}
,根據我的教程後,我寫GMapV2Direction.java:
package com.tugas.akhir.googlemaps;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import android.content.Context;
import android.util.Log;
import com.google.android.gms.maps.model.LatLng;
/**
* @author KAPLANDROID
*/
public class GMapV2Direction {
LatLng src, dest;
public List<LatLng> pointToDraw;
public static final int MODE_DRIVING = 1;
public static final int MODE_WALKING = 2;
public int mDirectionMode;
public void setParams(LatLng src, LatLng dest, int mMode) {
this.src = src;
this.dest = dest;
this.mDirectionMode = mMode;
}
public List<LatLng> getPointList(Context mContext) {
if (src != null || dest != null) {
// connect to map web service
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(makeUrl(src, dest));
HttpResponse response;
try {
response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = null;
is = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
String line = "0";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
reader.close();
String result = sb.toString();
JSONObject jsonObject = new JSONObject(result);
JSONArray routeArray = jsonObject.getJSONArray("routes");
JSONObject routes = routeArray.getJSONObject(0);
JSONObject overviewPolylines = routes
.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
pointToDraw = decodePoly(encodedString);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return pointToDraw;
} else {
throw new NullPointerException(
"Source or Destination coordinate is null. You must call \"setParams(LatLng,LatLng)\" method first!");
}
}
private List<LatLng> decodePoly(String poly) {
int len = poly.length();
int index = 0;
List<LatLng> decoded = new LinkedList<LatLng>();
int lat = 0;
int lng = 0;
while (index < len) {
int b;
int shift = 0;
int result = 0;
do {
b = poly.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 = poly.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
decoded.add(new LatLng((lat/1E5), (lng/1E5)));
}
return decoded;
}
private String makeUrl(LatLng src, LatLng dest) {
StringBuilder urlString = new StringBuilder();
urlString.append("http://maps.googleapis.com/maps/api/directions/json");
// from
urlString.append("?origin=");
urlString.append(Double.toString((double) src.latitude));
urlString.append(",");
urlString.append(Double.toString((double) src.longitude));
// to
urlString.append("&destination=");
urlString.append(Double.toString((double) dest.latitude));
urlString.append(",");
urlString.append(Double.toString((double) dest.longitude));
urlString.append("&sensor=false&units=metric");
if (mDirectionMode == MODE_DRIVING) {
urlString.append("&mode=driving");
} else if (mDirectionMode == MODE_WALKING) {
urlString.append("&mode=walking");
}
Log.d("Request URL", "URL=" + urlString.toString());
return urlString.toString();
}
public interface DirecitonReceivedListener {
public void OnDirectionListReceived(List<LatLng> mPointList);
}
}
然後我寫這樣的佈局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:orientation="vertical" >
<fragment
android:id="@+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="5dp"
class="com.google.android.gms.maps.SupportMapFragment"
/>
<ToggleButton
android:id="@+id/tbMode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/map"
android:layout_toRightOf="@+id/btnDirection"
android:textOff="Walking"
android:textOn="Driving" />
<Button
android:id="@+id/btnDirection"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/map"
android:layout_alignTop="@+id/map"
android:layout_marginLeft="62dp"
android:text="@string/getdirection" />
</RelativeLayout>
最後,我添加一些代碼來AndroidManifest爲波紋管所示:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tugas.akhir"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Requaired Permissions for Google Maps V2 - Start - Kaplandroid -->
<permission
android:name="com.tugas.akhir.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<!-- External storage for caching. -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="com.tugas.akhir.permission.MAPS_RECEIVE" />
<!-- Maps API needs OpenGL ES 2.0. -->
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<!-- Requaired Permissions for Google Maps V2 - End - Kaplandroid -->
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- API KEY for Google Maps V2 - Start - Kaplandroid -->
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="-------- MY GOOGLE API KEY -------------" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<!-- API KEY for Google Maps V2 - End - Kaplandroid -->
<activity
android:name="com.tugas.akhir.MapActivity"
android:label="@string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
後來我導出爲.apk文件,然後將其安裝到我的設備。但是,...當我打開它,它沒有顯示任何地圖,它只顯示加&減號按鈕,除了那些按鈕沒有什麼。我搜索了互聯網,它說,我的問題是把這個代碼我AndroidManifest:
<uses-permission android:name="android.permission.INTERNET" />
我已經把這些代碼,但它仍然犯規表現出任何地圖中,有些文章說,這個問題是參考谷歌播放庫。我已成功將我的項目引用到google-play-service庫,但仍然失敗。任何人都可以幫助解決我的問題,請?非常感謝你
的任何消息與自己的APIKEY改變APIKEY價值? – Henry
是否有任何消息不能聯繫谷歌服務器或如此? – Lal
亨利:我使用Android智能手機設備,所以,沒有logcat消息 @Lal:沒有消息,它只是顯示加(+)減( - )按鈕,地圖不會出現 –