关于使用google map实现周边搜索的功能_web google地图搜索定位开发-程序员宅基地

由于公司项目是针对美国市场,所以接入的是google定位

谷歌地图sdk不像高德地图或者百度地图那么好接入,一方面是纯英文,还有一方面国外文档习惯我们并不习惯,大多写得很简略

我的项目要实现附近宠物店的搜索和附近宠物医院的搜索,在接入谷歌地图用到了以下几个包:

"com.google.android.gms:play-services-maps:15.0.1"
"com.google.android.gms:play-services-location:15.0.1"
"com.google.android.gms:play-services-places:15.0.1"

此外还需要在清单文件中配置对应的

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="@string/google_maps_key"/>

注:在string.xml中的谷歌地图的key的名字必须是google_maps_key

下面实现的搜索的功能:本质上调用的http接口来实现,比较坑的一点是同一个key一天调用的次数最多150000次,如果用户量较大时,要专门交费调整限制次数

1.首先初始化

 

private GoogleApiClient mGoogleApiClient;

private void getLocationList() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    //创建GoogleAPIClient实例
    if (mGoogleApiClient == null) {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addApi(Places.GEO_DATA_API)
                .addApi(Places.PLACE_DETECTION_API)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

}

2.调用接口进行请求地址数据:

 private void getGoogleLocation() {
        String baseUrl = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=";
//            String realUrl=baseUrl+mLat+","+mLng+"&radius="
//                    +5000+"&type=pet_store"+"&language=zh-CN"+"&key="+"你自己在谷歌的对应的key";
        String realUrl = null;
//            realUrl = baseUrl + mLat + "," + mLng + "&radius="
//                    + 20000 +"&rankby=distance"+
//                    "&types=" + searchType + "&key=" + "你自己在谷歌的对应的key";
        realUrl = baseUrl + mLat + "," + mLng +"&rankby=distance"+
                "&types=" + searchType + "&key=" + "你自己在谷歌对应的key";
        Call<ResponseBody> ca = HBClient.getService(MineService.class).listGoogleLocations(realUrl);
        ca.enqueue(new RequestCallBack<ResponseBody>() {
            @Override
            public void onFailed(Call<ResponseBody> call, Response<ResponseBody> response) {
                super.onFailed(call, response);
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                super.onFailure(call, t);
            }

            @Override
            public void onSuccess(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    String json = response.body().string();
                    LogUtil.e("周边地址的json为" + json);
                    if (json != null && !json.equals("")) {
                        googleLocationBean = GsonUtils.jsonToBean(json, GoogleLocationBean.class);
                        if (googleLocationBean == null) {
                            LogUtil.e("解析周边地址json为空");
                            showEmpty();
                            nextPageToken = null;
                        } else {
                            if (googleLocationBean.getStatus().equals("OK")) {
                                List<GoogleLocationBean.GoogleLocationData> results = googleLocationBean.getResults();
                                nextPageToken = googleLocationBean.getNext_page_token();
                                showSuccess();
                                mAdapter.setNewData(results);
                                LogUtil.e("长度为" + results.size());
//                                    for (int i = 0; i < results.size(); i++) {
//                                    getGoogleDetail(results.get(i),results,i,hasMore);
//                                    }
//                                    getGooglePhotos(results.get(1).getReference());
                            } else {
                                nextPageToken = null;
                                showEmpty();
                            }
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

3.当请求返回的数据中有

nextPageToken字段不为空时,就有多页数据,请求下一页数据时需要将该字段携带去请求

4.请求下一页数据时:

private void getGoogleLocationMore() {
        String baseUrl = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?pagetoken=";
        String realUrl = null;
        realUrl = baseUrl + nextPageToken + "&key=" + "你对应的谷歌的key";
            nextPageToken = null;
        Call<ResponseBody> ca = HBClient.getService(MineService.class).listGoogleLocations(realUrl);
        ca.enqueue(new RequestCallBack<ResponseBody>() {
            @Override
            public void onFailed(Call<ResponseBody> call, Response<ResponseBody> response) {
                super.onFailed(call, response);
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                super.onFailure(call, t);
            }

            @Override
            public void onSuccess(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    String json = response.body().string();
                    LogUtil.e("周边地址的json为" + json);
                    if (json != null && !json.equals("")) {
                        googleLocationBean = GsonUtils.jsonToBean(json, GoogleLocationBean.class);
                        if (googleLocationBean == null) {
                            LogUtil.e("解析周边地址json为空");
                            mAdapter.loadMoreEnd();
                            nextPageToken = null;
                        } else {
                            if (googleLocationBean.getStatus().equals("OK")) {
                                List<GoogleLocationBean.GoogleLocationData> results = googleLocationBean.getResults();
                                mAdapter.addData(results);
                                mAdapter.loadMoreEnd();
                                nextPageToken = googleLocationBean.getNext_page_token();
                                LogUtil.e("长度为" + results.size());
//                                    for (int i = 0; i < results.size(); i++) {
//                                    getGoogleDetail(results.get(i),results,i,hasMore);
//                                    }
//                                    getGooglePhotos(results.get(1).getReference());
                            } else {
                                mAdapter.loadMoreEnd();
                            }
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

5.请求某个地点对应的照片时:

private void getGooglePhotos(String photoreference) {
    String baseUrlPhoto = "https://maps.googleapis.com/maps/api/place/photo?";
    String realUrlPhoto = baseUrlPhoto + "maxwidth=480&photoreference=" + photoreference
            + "&key=" + "你的谷歌对应的key";
    HBClient.getService(MineService.class).listGooglePhotos(realUrlPhoto).enqueue(new RequestCallBack<ResponseBody>() {
        @Override
        public void onFailed(Call<ResponseBody> call, Response<ResponseBody> response) {
            super.onFailed(call, response);
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            super.onFailure(call, t);
        }

        @Override
        public void onSuccess(Call<ResponseBody> call, Response<ResponseBody> response) {
            try {
                String json = response.body().string();
                LogUtil.e("图片json为" + json);
                if (json != null && !json.equals("")) {
                    GoogleLocationBean bean = GsonUtils.jsonToBean(json, GoogleLocationBean.class);
                    if (bean == null) {
                        LogUtil.e("解析周边地址图片json为空");
                    } else {
                        if (bean.getStatus().equals("OK")) {
                            List<GoogleLocationBean.GoogleLocationData> results = bean.getResults();
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });
}

6.上述请求对应地点照片采用的Places的web的api,也可以采用安卓的api,如下:

private void getPhoto(String placeId, GoogleApiClient mGoogleApiClient, ImageView imgLogo) {
    Places.GeoDataApi.getPlacePhotos(mGoogleApiClient, placeId)
            .setResultCallback(photos -> {
                if (!photos.getStatus().isSuccess()) {
                    return;
                }

                PlacePhotoMetadataBuffer photoMetadataBuffer = photos.getPhotoMetadata();
                if (photoMetadataBuffer.getCount() > 0) {
                    // Display the first bitmap in an ImageView in the size of the view
                    photoMetadataBuffer.get(0)
                            .getScaledPhoto(mGoogleApiClient, imgLogo.getWidth(),
                                    imgLogo.getHeight())
                            .setResultCallback(placePhotoResult -> {
                                LogUtil.e("请求图片回调-"+placePhotoResult.getStatus().isSuccess());
                                if (!placePhotoResult.getStatus().isSuccess()) {
                                    return;
                                }
                                imgLogo.setImageBitmap(placePhotoResult.getBitmap());

                            });
                }else {
                    LogUtil.e("查询到图片数量为0");
                }
                photoMetadataBuffer.release();
            });
}

 

7.关于谷歌地图的显示的补充:在Activity中实现OnMapReadyCallback接口

在onCreate方法中:注意

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // TODO: add setContentView(...) invocation
    ButterKnife.bind(this);
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}
    @Override
    public void onMapReady(GoogleMap googleMap) {
        LogUtil.e("googleMap");
        mMap = googleMap;
        mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
//        mMap.setOnMyLocationButtonClickListener(this);
//        mMap.setOnMarkerDragListener(this);
        UiSettings uiSettings = mMap.getUiSettings();
        uiSettings.setZoomControlsEnabled(true);
        uiSettings.setZoomGesturesEnabled(true);
        uiSettings.setCompassEnabled(true);
        uiSettings.setMyLocationButtonEnabled(true);//不显示定位按钮
//        enableMyLocation();
        // Add a marker in Sydney and move the camera
        LatLng sydney = new LatLng(item.getGeometry().getLocation().getLat(), item.getGeometry().getLocation().getLng());
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                MyApp.runOnUIThread(new Runnable() {
                    @Override
                    public void run() {
                        mMap.animateCamera(CameraUpdateFactory.
                                newLatLngZoom(new LatLng(item.getGeometry().getLocation().getLat(),
                                        item.getGeometry().getLocation().getLng()), 16));
                        Marker melbourne = mMap.addMarker(new MarkerOptions()
                                .position(sydney)
                                .title(item.getVicinity()));
                        melbourne.showInfoWindow();
                        CircleOptions circleOptions = new CircleOptions()
                                .center(sydney)
                                .radius(280); // In meters

                        Circle circle = mMap.addCircle(circleOptions);
                        circle.setFillColor(Color.argb(45, 0, 191, 255));
                        circle.setStrokeColor(Color.argb(65, 0, 191, 255));
                        circle.setStrokeWidth(6);
                    }
                });

            }
        }, 300);

    }
}

对应的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<com.zhy.autolayout.AutoLinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:fitsSystemWindows="true"
    android:clipToPadding="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<include layout="@layout/include_title"/>
        <fragment
            android:id="@+id/map"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            class="com.google.android.gms.maps.SupportMapFragment"/>
</com.zhy.autolayout.AutoLinearLayout>
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/U__F_O/article/details/81943842

智能推荐

14、详解java同步工具类CountDownLatch_java coundlash-程序员宅基地

文章浏览阅读2k次,点赞5次,收藏37次。这篇文章主要讲解java中一个比较常用的同步工具类CountDownLatch,不管是在工作还是面试中都比较常见。我们将通过案例来进行讲解分析。一、定义CountDownLatch的作用很简单,就是一个或者一组线程在开始执行操作之前,必须要等到其他线程执行完才可以。我们举一个例子来说明,在考试的时候,老师必须要等到所有人交了试卷才可以走。此时老师就相当于等待线程,而学生就好比是执行的线程。注..._java coundlash

顺序性容器(vector&list&deque)_vector list 赋值顺序-程序员宅基地

文章浏览阅读313次。引言(1)vector向量相当于一个数组 在内存中分配一块连续的内存空间进行存储。支持不指定vector大小的存储。STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capacity()函数返回的大小,当超过此分配的空间时再整体重新放分配一块内存存储,这给人以vector可以不指定vector即一个连续内存的大小的感觉。通常此默认的内存分配能完成大部分情况下的存_vector list 赋值顺序

cube/SSAS 数据级权限解决方案----不使用域身份验证-程序员宅基地

文章浏览阅读301次。一个多月没更新博客了,不是不想写而是真的没有什么高质量的文章与大家分享,最近在做一个集团公司的BI解决方案,客户提出了一个合理但是又比较棘手的一个问题,就是北京的经理和南京的经理都有权限访问公司内部的报表,但是需要对其进行透明化的权限区分,北京的区域经理不能浏览任何关于南京区域的销售信息。这个需求是很合理的,但是客户方不一定会在一个域中,也就是这个经理可能到美国到非洲(呵呵,当然这是比喻..._没有加域怎么连ssas

gradle下载的缓存路径-程序员宅基地

文章浏览阅读368次。为什么80%的码农都做不了架构师?>>> ..._download_jsc.gradle下载路径

如何在iPhone或iPad上安装iOS 11 Beta-程序员宅基地

文章浏览阅读2.6k次。The public beta of iOS 11 is now available for iPhones and iPads. Anyone who wants to play withiOS 11’s new featurescan install it today. However, we recommend backing up your device first so you ca..._ios11bate

UE4_UE5结合offline voice recognition插件做语音识别功能_ue5语音识别-程序员宅基地

文章浏览阅读6.2k次,点赞4次,收藏24次。市面上主流的语音识别大多是用科大讯飞的SDK,但是那个也不是完全免费使用的,于是我选择使用offline voice recognition的语音识别,购买插件终生使用。offline voice recognition插件在UE官方商城卖200多元。我将它需要的资源都打包成一个rar,分享给有需要的人。其中就有两个UE工程,一个是UE4.27版本的,另外一个是UE5的版本。并且也下载了两个中文的语言包,一个是简版,另外一个是完整版,对于 只是做简单的主意指令的只需要用简版的语言包即可,大大提升识别速度。第_ue5语音识别

随便推点

python求解整数规划_如何用python结合cplex求解混合整数规划问题-程序员宅基地

文章浏览阅读1.4k次。第一步:注册IBM id账号第二步:下载相关系统的CPLEX(windows/linux/mac)这里需要系统中安装有JAVA,选择 open with Java web start launcher (需要下载JAVA),打开后就开始进入下载页面。补充JAVA安装:备注:JAVA可以通过rpm包安装,或者是bin文件安装。Rpm安装可以直接双击就可以打开jnlp后缀的文件,bin文件安装的话,需..._cplex求解双目标混合整数规划模型

CentOS 7.X 源码编译安装MariaDB-10.2.X_group ‘mail’ not found-程序员宅基地

文章浏览阅读2.5k次。CentOS 7 编译安装MariaDB-10.2.XCentOS 7下mariadb-10.1.22 源码编译安装过程笔记,希望对大家有帮助。 下载文件https://mariadb.com/ 或 https://downloads.mariadb.org/mariadb/10.2.11/
源码包的下载下载链接: https://mirrors.tuna.tsinghua.edu.cn/m_group ‘mail’ not found

wps中的大客户版本_wps 大客户版-程序员宅基地

文章浏览阅读462次,点赞11次,收藏8次。网上的WPS各个版本基本都带有稻香插件,广告一堆堆,用户需要注册才能减少广告的显示,但依然时不时跳出来显示。其实WPS给大学做过一些版本,这种定制版本应用于大学院系的文档编写使用。最关键的是这个版本没有广告,没有稻香,没有推荐模板,只有纯净的WPS。界面虽然不华丽,风格还是很传统office2000风格,不是烦人的多标签页,也不会隐藏。工具栏不会藏着掖着直接横排展示所有图标,鼠标不用切换页,所有工具一目了然。这集美大学版本是办公软件的不二之选。_wps 大客户版

Android自动化页面测速在美团的实践-程序员宅基地

文章浏览阅读587次,点赞8次,收藏19次。我们都知道ViewPager的Tab切换是可以通过一个 OnPageChangeListener 对象进行监听的,所以我们可以为ViewPager添加一个自定义的Listener对象,在切换时记录一个时间,这样可以通过用这个时间减去页面创建后的时间得出这个多余的等待时间,上报时在总时间中减去即可。这里的 getConfigModel() 方法中,会使用页面的类名或者全路径类名,去初始化时解析的配置Map中进行id的匹配,如果匹配到说明页面需要测速,就会创建测速对象 PageObject 进行测速。

百度竞价悄然改版-程序员宅基地

文章浏览阅读42次。前段时间百度因为“魏则西事件”而被要求整改,百度的竞价排名也被推向了风口浪尖。最近有网友@闪电精灵SEO张扬爆料:百度竞价已改版,竞价显示4条,或许取消了右侧排名! 但是在经过风波之后,百度的确有了一些变化,最明显的变化就是对推广的网站的标注,之前的对百度推广只有推广两个字,现在是成了蓝色..._python 百度竞价排名

《剑指offer》学习笔记_面试题35_复杂链表的复制-程序员宅基地

文章浏览阅读334次。题目描述 请实现一个函数,复制一个复杂链表。在复杂链表中,每个节点除了一个next指针指向下一个节点,还有一个random指针指向链表中的任意节点或者为空。 思路 1.分治先复制当前的节点,然后递归的分别复制next或random。在复制next和random的过程中会重复复制相同节点,因此需要一个map来记录当前的复制情况。2.拆分法首先,将复制节点拼接到原始节点的...