Android GoogleMap接入

首先你要下载官方demo这是必须的,然后开始配置你自己的项目吧
一、Google Map

接入sdk,别的不说,肯定是看看有没有文档和demo吧。

一.1、Google的文档和demo

Google Map Android 示例代码
注册和API秘钥

通过这Google的这两个,主要就说要我们做这么几件事
1、去 GitHub 上的 Google Maps repo 下载Google的地图demo
2、拿着你的SHA-1和包名去开始你的google地图之旅吧,(发包的时候debug和release的key不同生成的SHA-1也是不同的这点记得哈)
3、到Google Developers Console这里来,
3-1、创建你的项目。
3-2、创建凭据 (即生成API KEY)
3-3、创建凭据之后,编辑编辑,编辑凭据的时候即可添加我们想绑定包名和SHA-1.
(当然如果你还没注册那么就填一些信息,注册一下,然后还说送你300美金云端可以用的刀刀噢)

4、然后拿着Google的API KEY 往demo里面一填,demo就跑起来啦。
Android GoogleMap接入_第1张图片

1、转至 Google Developers Console。
2、Select a project, or create a new one.
3、Open the API Library in the Google Developers Console. If prompted, select a project or create a new one. Select the Enabled APIs link in the API section to see a list of all your enabled APIs. Make sure that the API is on the list of enabled APIs. If you have not enabled it, select the API from the list of APIs, then select the Enable API button for the API. 您需要的唯一 API 是 Google Maps Android API,但您也可以选择为相同项目启用其他 API。

2、创建凭据
Android GoogleMap接入_第2张图片

3、填入SHA-1和包名配置API

进入到凭据(Credentials),点击进入编辑

Android GoogleMap接入_第3张图片

拉到底部即可,选android,填写即可。
其实你要是测试阶段可以直接写上测试的SHA-1,这里也是测试图省事我debug和release都写上了

注意:Google说可能最长可能要5分钟才是生效哦。
Android GoogleMap接入_第4张图片

4、在清单文件写上的API KEY


5、请到你的API库启动你Map

如果按照上面的步骤整完,直接跑起来,而且之前你有没整过google的东西,那么应该会有如下提示:

Android GoogleMap接入_第5张图片

1、请确认 Map Api v2 开始开启
2、确保你的api key是存在的

其实在api key是存在的的前提下,问题就是我们在Google的控制器可以管理很多Google的库,每一个Google控制台新创建项目默认都是关闭没有开启api的,每一个都需要我们手动去开启。
显示为停用就是开启了。
Android GoogleMap接入_第6张图片

(有的人在网上提问说感觉什么配对了,但是地图就是死活显示不出来,很多时候就是因为这个api没有开启导致的。)
6、有的时候没有导入 google play-services

因为主module的gradle里面需要引入

ompile ‘com.google.android.gms:play-services-maps:9.8.0’

但是如果是新的环境或者说您之前接墙外的google server,那么应该是没有的,下载之。
Android GoogleMap接入_第7张图片
Android GoogleMap接入_第8张图片

跑起来了,该配的也配了。
接下来我们该处理界面的事情了!

谷歌地图使用起来大概分两种方式
1、以fragment的方式使用
2、以控件的方式,也就是原生的GoogleMap

一.1 以fragment的方式使用googleMap

亦可参见源例

Android GoogleMap接入_第9张图片

示例代码
SimpleFragmentModeActivity

public class SimpleFragmentModeActivity extends AppCompatActivity implements 

OnMapReadyCallback { @Override protected void onCreate(@Nullable Bundle savedInstanceState) 

{ super.onCreate(savedInstanceState); setContentView(R.layout.activity_fragment_mode); 

SupportMapFragment mapFragment = (SupportMapFragment) 

getSupportFragmentManager().findFragmentById(R.id.map); mapFragment.getMapAsync(this); } 

@Override public void onMapReady(GoogleMap googleMap) { double lat = 0.0; double lng = 0.0; 


LatLng appointLoc = new LatLng(lat, lng); // 移动地图到指定经度的位置 

googleMap.moveCamera(CameraUpdateFactory.newLatLng(appointLoc)); //添加标记到指定经纬度 

googleMap.addMarker(new MarkerOptions().position(new LatLng(lat, lng)).title("Marker") 

.icon(BitmapDescriptorFactory.fromResource(R.drawable.chat_loc_point))); 

/*// 点击标记点,默认点击弹出跳转google地图或导航选择,返回true则不弹出 

googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() { 

@Override public boolean onMarkerClick(Marker marker) { return true; } }); 

// 单击 googleMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() { 
@Override 

public void onMapClick(LatLng latLng) { } });

 // 不允许手势缩放 googleMap.getUiSettings().setZoomGesturesEnabled(false); 

//googleMap.getUiSettings().setMapToolbarEnabled(false); 禁用精简模式下右下角的工具栏   // 不允许拖动地图 
googleMap.getUiSettings().setScrollGesturesEnabled(false);
 // 设置缩放级别 
*/ }
 }

对应布局

    
    

使用步骤

第一步
布局为文件放上fragment,注意class=”com.google.android.gms.maps.SupportMapFragment”不可或缺

第二步
得到SupportMapFragment对象,调用getMapAsync异步读取地图

第三步,在getMapAsync的OnMapReadyCallback接口中的onMapReady方法中指定经纬度和marker。

默认效果

默认效果
1、可双指缩放
2、可单指移动
3、带有指南针的,
4、maker点是点击的,点击后弹出toolbar(此toolbar是地图的toobar,即跳转googlemap app或者导航)
5、双击放大

我们可以获取UiSettings或者利用googleMap对象直接设置。
代码的备注里面我也简单列举了一些,可以参见官网文档进行调整。

如果不需要这些东西,就要特别简单的地图,那么我们可以使用精简模式。

精简模式

如果我们不想要默认的效果,那么我们完全可以使用精简模式。

使用方式

1、fragment布局代码中 map:liteMode="true"
2、java代码里面配置 GoogleMapOptions options = new GoogleMapOptions().liteMode(true);

其他的使用方式请参考官网~~~

二 、2 MapView

MapView 是 Android View 类的一个子类, 用于在 Android View 中放置地图。 View 表示屏幕的某个矩形区域, 是 Android 应用和小工具的基本构建基块。 MapView 与 MapFragment 很相似,它也充当地图容器,通过 GoogleMap 对象公开核心地图功能。

在完全交互模式下使用该 API 时,MapView 类的用户必须将下列 Activity 生命周期方法转发给 MapView 类中的相应方法:onCreate()、onStart()、onResume()、onPause()、onStop()、onDestroy()、onSaveInstanceState() 和 onLowMemory()

例子
Android GoogleMap接入_第10张图片

SimpleMapActivity

public class MapActivity extends BaseActivity implements AdapterView.OnItemClickListener , BaiduMap.OnMapLoadedCallback{
    @BindView(R.id.img_face)
    ImageView imgFace;
    @BindView(R.id.bmapView)
    MapView bmapView;
    private String userKey;
    private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE = 1;
    /**
     * 百度地图对象
     */
    private BaiduMap mBaiduMap;
    /**
     * 定位
     */
    private LocationClient mLocClient;
    MyLocationListener myLocationListener = new MyLocationListener();
    private android.graphics.Point mCenterPoint = null;
    /**
     * 是否第一次定位
     */
    private boolean isFirstLoc = true;
    /**
     * 当前经纬度
     */
    private LatLng mLoactionLatLng;
    /**
     * 请求码
     */
    private final static int REQUEST_CODE = 0x123;
    private boolean isTouch = true;
    /**
     * 地理编码
     */
    private GeoCoder mSearch;
    //接受所有经纬对象
    List allList = new ArrayList<>();
    GoogleMapBean google;
    //infowind 显示的字段
    //类型
    private String maptype="";
    //区域
    private String mapquyu="";
    private int inttype=0;
    //价格
    private String mapprice="";

    //聚合管理器
    ClusterManager mClusterManager;

    @Override
    protected void initSetView(Bundle savedInstanceState) {
        setContentView(R.layout.activity_map);
        ButterKnife.bind(this);
        userKey = SharePreUtils.newInstance(mContext).getUserKey();
        //获取所有房源需求经纬和ID
        getAllRoom();
        //初始化地图
        initMapView();
        LatLng point = new LatLng(11.5448729, 104.8921668);
        //构建Marker图标
        BitmapDescriptor bitmap = BitmapDescriptorFactory
                .fromResource(R.mipmap.icon_map1);
        //构建MarkerOption,用于在地图上添加Marker
        OverlayOptions option = new MarkerOptions()
                .position(point)
                .icon(bitmap);
        //在地图上添加Marker,并显示
        mBaiduMap.addOverlay(option);
        mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(point));
    }

    private void getAllRoom() {
        OkGoUtils.newInstance().get("http://www.fs352.net:9098/mis/categories/map", "ch", userKey,
                SharePreUtils.newInstance(mContext).getUsertoken(), SharePreUtils.newInstance(mContext).getUserpublicKey(),
                new OkGoCallback() {
                    @Override
                    public void onSucceed(String data) {
                        google = JSONUtils.getObject(data, GoogleMapBean.class);
                        if (google.getStatus() == 200) {
                            DialogUtils.cancleLoading();
                            Message mess = new Message();
                            mess.what = 0;
                            handler.dispatchMessage(mess);
                        }
                    }

                    @Override
                    public void onCancel(String data) {

                    }
                }
        );
    }

    private void initMapView() {
        // 地图初始化
        mBaiduMap = bmapView.getMap();
        //监听点击事件

        // 设置为普通矢量图地图
        mClusterManager = new ClusterManager(MapActivity.this, mBaiduMap);
        mClusterManager.setRenderer(new DefaultClusterRenderer(MapActivity.this, mBaiduMap, mClusterManager));
        mBaiduMap.setOnMarkerClickListener(mClusterManager);
        mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
        bmapView.setPadding(10, 0, 0, 10);
        bmapView.showZoomControls(false);
        //不倾斜
        mBaiduMap.getUiSettings().setOverlookingGesturesEnabled(false);
        //不旋转
        mBaiduMap.getUiSettings().setRotateGesturesEnabled(false);
        //图标管理器 mMarkerManager = new MarkerManager(mBaiduMap);
        mBaiduMap.setOnMapStatusChangeListener(mClusterManager);
        mBaiduMap.setOnMapLoadedCallback(this);
        mBaiduMap.setMyLocationEnabled(true);
        // 设置缩放比例(500米)
        MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(15.0f);
        mBaiduMap.setMapStatus(msu);
        // 初始化当前 MapView 中心屏幕坐标
        mCenterPoint = mBaiduMap.getMapStatus().targetScreen;
        mLoactionLatLng = mBaiduMap.getMapStatus().target;
        // 地理编码
        mSearch = GeoCoder.newInstance();
        //定义Maker坐标点
        // 定位初始化
        mLocClient = new LocationClient(getApplicationContext());
        mLocClient.registerLocationListener(myLocationListener);
        // 可定位
        mBaiduMap.setMyLocationEnabled(true);
        mBaiduMap.setOnMapStatusChangeListener(mClusterManager);
        mBaiduMap.setOnMarkerClickListener(mClusterManager);
        initListeners();
        // mBaiduMap.setOnInfoWindowClickListener(mClusterManager);
    }

    private void initListeners() {
        //地图状态发生变化,主要是移动、放大、经纬度发生变化
        mClusterManager.setOnMapStatusChangeListener(new BaiduMap.OnMapStatusChangeListener() {
            //记住变化前的上一个状态
            private MapStatus mFrontMapStatus;
            @Override
            public void onMapStatusChangeStart(MapStatus mapStatus) {
                //隐藏InfoWindow
                mBaiduMap.hideInfoWindow();
                if (mFrontMapStatus == null) {
                    mFrontMapStatus = mapStatus;
                }
            }

            @Override
            public void onMapStatusChange(MapStatus mapStatus) {
                //隐藏InfoWindow
                mBaiduMap.hideInfoWindow();
            }

            @Override
            public void onMapStatusChangeFinish(MapStatus mapStatus) {
                //隐藏InfoWindow
                mBaiduMap.hideInfoWindow();
            }
        });
        //单个点击
        mClusterManager.setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener() {
            @Override
            public boolean onClusterItemClick(final BaiduCluster item) {
                InfoWindow mInfoWindow;
                IconClick(item);
                LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                View view = inflater.inflate(R.layout.map_item, null);
                LinearLayout callLay = (LinearLayout) view.findViewById(R.id.call_phone);
                LinearLayout seeMore = (LinearLayout) view.findViewById(R.id.see_more);
                TextView typeTv = (TextView) view.findViewById(R.id.map_type);
                TextView cityTv = (TextView) view.findViewById(R.id.map_city);
                TextView priceTv = (TextView) view.findViewById(R.id.map_price);
                if(item.type==1){
                    callLay.setVisibility(View.VISIBLE);
                    seeMore.setVisibility(View.GONE);
                }else if(item.type==0){
                    callLay.setVisibility(View.GONE);
                    seeMore.setVisibility(View.VISIBLE);
                }
                typeTv.setText(item.name);
                cityTv.setText(item.title);
                priceTv.setText("$" + item.price);
                //将marker所在的经纬度的信息转化成屏幕上的坐标
                final LatLng ll = item.getPosition();
                Point p = mBaiduMap.getProjection().toScreenLocation(ll);
                Log.e("456489412313", "--!" + p.x + " , " + p.y);
                p.y -= 47;
                LatLng llInfo = mBaiduMap.getProjection().fromScreenLocation(p);
                //为弹出的InfoWindow添加点击事件
                mInfoWindow = new InfoWindow(view,llInfo,-47);
                //显示InfoWindow
                mBaiduMap.showInfoWindow(mInfoWindow);
                view.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //if(item.type==1){
                        if(item.type==1){
                            // 检查是否获得了权限(Android6.0运行时权限)
                            if (ContextCompat.checkSelfPermission(MapActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
                                // 没有获得授权,申请授权
                                if (ActivityCompat.shouldShowRequestPermissionRationale(MapActivity.this, Manifest.permission.CALL_PHONE)) {
                                    // 返回值:
                                    //如果app之前请求过该权限,被用户拒绝, 这个方法就会返回true.
                                    //如果用户之前拒绝权限的时候勾选了对话框中”Don’t ask again”的选项,那么这个方法会返回false.
                                    //如果设备策略禁止应用拥有这条权限, 这个方法也返回false.
                                    // 弹窗需要解释为何需要该权限,再次请求授权
                                    Toast.makeText(MapActivity.this, "请授权!", Toast.LENGTH_LONG).show();
                                    // 帮跳转到该应用的设置界面,让用户手动授权
                                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                    Uri uri = Uri.fromParts("package", getPackageName(), null);
                                    intent.setData(uri);
                                    startActivity(intent);
                                } else {
                                    // 不需要解释为何需要该权限,直接请求授权
                                    ActivityCompat.requestPermissions(MapActivity.this, new String[]{Manifest.permission.CALL_PHONE}, MY_PERMISSIONS_REQUEST_CALL_PHONE);
                                }
                            } else {
                                // 已经获得授权,可以打电话
                                CallPhone();
                            }
                        }else {
                            Bundle bundle = new Bundle();
                            bundle.putString("details", item.categoryid);
                            openActivity(HomedetailsActivity.class, bundle);
                        }
                    }
                });
                //根据商家信息为详细信息布局设置信息
//                popupInfo(view, info);
                return true;
            }
        });
        //聚合的点击
        mClusterManager.setOnClusterClickListener(new ClusterManager.OnClusterClickListener() {
            @Override
            public boolean onClusterClick(Cluster cluster) {
                ClusterOnClick(cluster);
                return true;
            }
        });
    }

    private void CallPhone() {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_CALL);
        //url:统一资源定位符
        //uri:统一资源标示符(更广)
        intent.setData(Uri.parse("tel:" + "023727352"));
        //开启系统拨号器
        startActivity(intent);
    }

    private void IconClick(BaiduCluster item) {
    }
    /**
     * 聚合点击
     */
    private void ClusterOnClick(Cluster clusterBaiduItems) {
        if (mBaiduMap == null) {
            return;
        }
        if (clusterBaiduItems.getItems().size() > 0) {
            LatLngBounds.Builder builder = new LatLngBounds.Builder();
            for (BaiduCluster clusterBaiduItem : clusterBaiduItems.getItems()) {
                builder.include(clusterBaiduItem.getPosition());
            }
            mBaiduMap.animateMapStatus(MapStatusUpdateFactory
                    .newLatLngBounds(builder.build()));
        }
    }


    @Override
    protected void init() {

    }

    @Override
    protected void initView() {
    }

    @Override
    protected void initListener() {
        imgFace.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (userKey.equals("")) {
                    showToast("请登录");
                    openActivity(LoginActivity.class);
                    return;
                }
                Bundle bundle = new Bundle();
                bundle.putString("stye", "sell");
                finish();
                openActivity(UpRentRoomActivity.class);
            }
        });
    }
    @Override
    protected void initData() {

    }

    @Override
    public void onItemClick(AdapterView parent, View view, int position, long id) {

    }

    @Override
    public void onMapLoaded() {

    }

    /**
     * 定位SDK监听函数
     */
    public class MyLocationListener implements BDLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {
            // map view 销毁后不在处理新接收的位置
            if (location == null || bmapView == null) {
                return;
            }
            MyLocationData locData = new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                    .latitude(location.getLatitude())
                    .longitude(location.getLongitude()).build();
            mBaiduMap.setMyLocationData(locData);

            Double mLatitude = location.getLatitude();
            Double mLongitude = location.getLongitude();

            LatLng currentLatLng = new LatLng(mLatitude, mLongitude);
            mLoactionLatLng = new LatLng(mLatitude, mLongitude);

            // 是否第一次定位
            if (isFirstLoc) {
                isFirstLoc = false;
                // 实现动画跳转
                MapStatusUpdate u = MapStatusUpdateFactory
                        .newLatLng(currentLatLng);
                mBaiduMap.animateMapStatus(u);
                mSearch.reverseGeoCode((new ReverseGeoCodeOption())
                        .location(currentLatLng));
                return;
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        // 退出时销毁定位
        mLocClient.stop();
        // 关闭定位图层
        mBaiduMap.setMyLocationEnabled(false);
        if (bmapView != null) {
            bmapView.onDestroy();
            bmapView = null;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
        bmapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
        bmapView.onPause();
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    List  mClusterBaiduItems = new ArrayList<>();

                    allList = google.getData().getContent();
                    String price = "";
                    mClusterManager.clearItems();
                    for (GoogleMapBean.DataBean.ContentBean content : allList) {
                        if (content.isRequirement()) {
                            if (!content.getBudgetaryprice().equals("none")) {
                                price = content.getBudgetaryprice();
                            } else {
                                price = String.valueOf(content.getPrice());
                            }
                            maptype = mContext.getResources().getString(R.string.order);
                            inttype = 1;
                            mapprice = price;
                            mapquyu = content.getDistrict();
                            mClusterManager.addItem(new BaiduCluster(new LatLng(content.getLatitude(), content.getLongitude()),
                                    maptype, mapquyu, price,mapprice, inttype, R.mipmap.icon_map3)
                            );
                            mClusterBaiduItems.add(new BaiduCluster(new LatLng(content.getLatitude(), content.getLongitude()),
                                    maptype, mapquyu, price,mapprice, inttype, R.mipmap.icon_map3));
                            LogUtils.e(content.getCategoryid() + "***********");
                        } else {
                            if (content.getHouseType().equals("rent")) {
                                if (!content.getBudgetaryprice().equals("none")) {
                                    price = content.getBudgetaryprice();
                                } else {
                                    price = String.valueOf(content.getPrice());
                                }
                                maptype = mContext.getResources().getString(R.string.home_need1);
                                inttype = 0;
                                mapprice = price;
                                mapquyu = content.getDistrict();

                                mClusterManager.addItem(new BaiduCluster(new LatLng(content.getLatitude(), content.getLongitude()),
                                        maptype,mapquyu, mapprice, content.getCategoryid(), inttype, R.mipmap.icon_map1)
                                );
                                mClusterBaiduItems.add(new BaiduCluster(new LatLng(content.getLatitude(), content.getLongitude()),
                                        maptype, mapquyu, price,mapprice, inttype, R.mipmap.icon_map1));
                                LogUtils.e(content.getCategoryid() + "***********");
                            } else if (content.getHouseType().equals("sell")) {
                                if (!content.getBudgetaryprice().equals("none")) {
                                    price = content.getBudgetaryprice();
                                } else {
                                    price = String.valueOf(content.getPrice());
                                }
                                maptype = mContext.getResources().getString(R.string.home_need2);
                                inttype = 0;
                                mapprice = price;
                                mapquyu = content.getDistrict();
                                mClusterManager.addItem(new BaiduCluster(new LatLng(content.getLatitude(), content.getLongitude()),
                                        maptype, mapquyu, mapprice, content.getCategoryid(), inttype, R.mipmap.icon_map2)
                                );
                                mClusterBaiduItems.add(new BaiduCluster(new LatLng(content.getLatitude(), content.getLongitude()),
                                        maptype, mapquyu, price,mapprice, inttype, R.mipmap.icon_map2));
                                LogUtils.e(content.getCategoryid() + "***********");
                            }
                        }
                    }
                    mBaiduMap.clear();
                    //显示刷新按键
                    if (mClusterManager != null)
                        mClusterManager.cluster();
                    break;
            }
        }
    };

}

布局文件


    
    

最后把流程画下
Android GoogleMap接入_第11张图片

二、小细节

1、在google控制台创建项目默认是不开启包括地图在内的任何api的,请开启对应功能,不然无法显示地图,开启方法请看Android Google Map/谷歌地图 接入不完全指南 (一)。

2、android API23 以上请做好权限申请工作,避免因为权限问题导致的闪退。

你可能感兴趣的:(android)