Google Maps V2 Android不会出现

时间:2014-06-27 20:11:18

标签: java android google-maps map

我按照教程创建简单的android地图,这是我的源代码(MainActivity.java):

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文件,然后将其安装到我的设备上。但是,......当我打开它时,它没有显示任何地图,它只显示加号&amp;减号按钮,除了那些按钮之外什么也没有。我搜索到互联网,它说我的问题是把这个代码放到我的AndroidManifest:

<uses-permission android:name="android.permission.INTERNET" />

我已经放了那个代码,但它仍然没有显示任何地图,有些文章说这个问题是参考谷歌播放库。我已成功将我的项目引用到google-play-service库,但它仍然失败了。任何人都可以帮助解决我的问题,请???非常感谢你

3 个答案:

答案 0 :(得分:0)

您的证书的sha1哈希值或您使用的packageId在您的地图的google api控制台中设置不正确。使用正确的sha1哈希和正确的包ID非常重要。另请注意,您可能还想添加调试证书

答案 1 :(得分:0)

Android Manifest文件中提到的API密钥可能有问题。确保它是使用正确的SHA-1密钥+在android清单文件中提到的包名称生成的。

还要检查位于服务标签中的Google API控制台是否已启用Google Maps Android API V2。

注意:生成新的API密钥后,请卸载设备中的旧应用,然后重新尝试安装。

答案 2 :(得分:0)

您必须使用Manifest文件

中提到的自己的APIKEY更改APIKEY值
    <meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value="-------- MY GOOGLE API KEY -------------" />