2014-06-27 54 views
-1

我已經跟着教程創建簡單的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庫,但仍然失敗。任何人都可以幫助解決我的問題,請?非常感謝你

+0

的任何消息與自己的APIKEY改變APIKEY價值? – Henry

+0

是否有任何消息不能聯繫谷歌服務器或如此? – Lal

+0

亨利:我使用Android智能手機設備,所以,沒有logcat消息 @Lal:沒有消息,它只是顯示加(+)減( - )按鈕,地圖不會出現 –

回答

0

它看起來像你的證書或packageId sha1哈希是錯誤地設置在您的地圖的谷歌API控制檯。使用適當的sha1散列和正確的軟件包ID很重要。另請注意,您也可能想要添加調試證書

+0

我的android src項目文件夾有2包,那些是「com.tugas.akhir」和「com.tugas.akhir.googlemaps」,....當我創建Google Maps API密鑰時,我只提交「com.tugas.akhir」包,是否受到影響???請幫助 –

0

它可能與您的Android Manifest文件中提到的API密鑰有關。請確保它是使用正確的SHA-1鍵+在Android清單文件中提到的軟件包名稱生成的。

還要檢查位於服務選項卡中的Google API控制檯上是否已打開Goog​​le Maps Android API V2。

注意:生成新的API密鑰後,請在設備中卸載舊的應用程序,然後重新嘗試新安裝。

+0

我檢查了一段時間我的SHA1,它是由keytool jdk生成的,然後我提交到谷歌代碼以獲取Google Maps API密鑰。我已經開啓了我的Google Maps Android API V2,但是我的android文件夾項目有2個包,分別是「com.tugas.akhir」和「com.tugas.akhir」。googlemaps「,但是當我提交包&SHA1到谷歌代碼來獲取Google Maps API密鑰時,我只提交其中的一個,它是」com.tugas.akhir「,...是否受影響???請幫助 –

+0

您需要使用您的包名在Android清單文件中提到,但不是您的android文件夾項目,即com.tugas.akhir創建API密鑰 –

0

必須在logcat的清單文件中提到

<meta-data 
     android:name="com.google.android.maps.v2.API_KEY" 
     android:value="-------- MY GOOGLE API KEY -------------" />