【百度地图篇】1.Flutter+百度Sdk实现地图功能 & 百度地图显示网格问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了【百度地图篇】1.Flutter+百度Sdk实现地图功能 & 百度地图显示网格问题相关的知识,希望对你有一定的参考价值。

参考技术A 我是初学者小白,所以很多看法不深,理解也不够透彻。但是很适合小白们一起从低角度往高处探索。文中有错误的,感谢指正,一起进步。

趁着假期做一个Flutter的地图功能,因为后端选用了百度地图,所以前端没得挑。找了遍插件,并没有现成可用的。(不过发现了百度官方也自开发Flutter插件,目前功能只有一个获取本地位置信息,后期会继续增加吧?很期待!)

参考帖子: https://blog.csdn.net/sjm19901003/article/details/53128375

这个实际上跟功能之间没太大关系,只是我按照个人摸索的过程来写。

当对一个“领域/知识块”完全不懂的时候,360°的方向都不确定的话。先了解基础概念,有利于你确定自己的摸索方向。

参考帖子: https://www.jianshu.com/p/742b15d38404

中间我跳过了几十,上百个帖子的摸索过程。这个才是关键能够真正做事的参考。

因为百度的sdk还算是很完善的,所以一旦出问题,都会有对应的报错提示。

我是使用flutter插件:permission_handler,来解决安卓的动态授权问题,用法简单而且设计合理。

这个错误直接来看,就是签名有问题。怎么查看SHA1码和包名,这里不多说,网上有极其多的方法,百度Sdk开发指南里也有。没那么复杂,也没那么麻烦。按照流程操作就是对的。
实在不放心?跟我一样,flutter打包后,把apk反过来解SHA1码不就行了?

参考帖子: https://www.daimajiaoliu.com/daima/4858f130f900409#heading-1

红色框框基本就是帖子讲解的那样。

蓝色框框见下图:release标签里好像是自己设置了。所以debug标签里面,箭头指向的位置,是我多设置的一个参数。

uid: -1 appid -1 msg: httpsPost failed,IOException:Unable to resolve host "api.map.baidu.com": No address associated with hostname

这一步我是哭笑不得,一开始老是和问题(2)混淆,导致浪费很多时间。仔细阅读后,发现是不能连接到“api.map.baidu.com”。

我打开模拟器的chrome浏览器,发现不能上网。查看手机的dns是10.0.2.3(默认的),和家里wifi不一样,所以不能上网也正常,之前居然没发现这个问题!!!

终端执行:adb shell  和  getprop,就可以查看所有的属性参数了。(window小伙伴自行百度,这个没多大差别。如果你有多个设备,记得自己选好设备。)

在里面找到这一项,就是你的dns参数。有些人是net.dns1,我的是net.eth0.dns1。这个没关系,只是等下指令 稍微改动 就行。

修改dns指令:setprop net.eth0.dns1 192.168.2.1

后面的192.168.2.1是我自己的dns,这个根据自己的情况来填写。不懂的百度下怎么查看自己的dns。

虽然提示设置失败,但是回到模拟器一看,地图已经显示出来了。

嘿嘿,在flutter设定多大的区域,地图就是多大的区域。用起来就很方便了。

过程十分痛苦,因为对flutter不是很熟悉,对android原生更是了解很少。所以自己就像突然不能讲话,被丢到一个陌生的环境,却要我去找一个人。所以细心很重要,一定要看清楚错误提示,不要错过每一个细节和可能性。

幸好最后解决了问题,开心~

其实如果你仔细阅读过百度官方的文档,会发现里面有关于 地图的生命周期管理 。然后在这里面没有提及到,这一点虽然没提,但不可或缺,小伙伴就自行思考吧。

最后还有一点,其实我的初衷是想实现一个百度地图的plugin,但是苦于能力有限,对Android的不熟悉,最后折戟。我不得已另起项目,然后重新实现地图sdk接入。经过这次对于这些有更多更全面的认知后,有空会再次研究flutter 插件的开发,共勉,奥利给!!!

基于百度地图sdk的地图app开发——poi检索

这是基于百度地图sdk的地图app开发系列博客第五篇

代码仓库位置:https://github.com/YanhuiLu89/lmap.git

上一篇 基于百度地图sdk的地图app开发(四)——显示地图定位

下一篇 基于百度地图sdk的地图app开发(六)——路线规划

因为本人是做C++开发,android和java都不熟,这方面知识有说错或者不好的习惯,欢迎赐较。
 

官方参考文档POI检索

POI(Point of Interest),即“兴趣点”。在地理信息系统中,一个POI可以是一栋房子、一个景点、一个邮筒或者一个公交站等。

poi检索分为城市内关键字检索和周边检索,其实现方式差不多,这里只实现城市内关键字检索,周边检索略。

关键字检索适用于在某个城市内搜索某个名称相关的POI,例如:查找“北京市”的“小吃”。

1、在布局文件中添加输入框

在地图最上方(原先地图模式按钮的上方)添加EditText控件

添加后xml文件内容如下(注意:android:imeOptions="actionSearch"这个属性,这样设置键盘默认的换行键显示为搜索

    <EditText
        android:id="@+id/inputText"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="50dp"
        android:background="@android:drawable/editbox_dropdown_dark_frame"
        android:ems="10"
        android:hint="请输入要搜索的内容"
        android:imeOptions="actionSearch"
        android:inputType="text"
        android:textColor="@color/white"
        app:layout_anchorGravity="top" />

    <ImageButton
        android:id="@+id/mapTypeBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        app:layout_anchorGravity="top"
        app:srcCompat="@android:drawable/ic_dialog_map" />

效果图如下

 

2、 创建POI检索实例

在MainActivity增加PoiSearch成员变量

  private PoiSearch mPoiSearch=null;

在onCreate函数中创建poi检索实例

        //创建poi检索实例
        mPoiSearch = PoiSearch.newInstance();
        

3、  创建POI检索监听器接收检索结果

这里暂时空实现,后面步骤6,显示搜索结果时填到相应布局中

    //创建poi检索监听器
    OnGetPoiSearchResultListener poiSearchListener = new OnGetPoiSearchResultListener() {
        @Override
        public void onGetPoiResult(PoiResult poiResult) {

        }
        @Override
        public void onGetPoiDetailResult(PoiDetailSearchResult poiDetailSearchResult) {

        }
        @Override
        public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {

        }
        //废弃
        @Override
        public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {

        }
    };

4 设置检索监听器

        //设置监听器
        mPoiSearch.setOnGetPoiSearchResultListener(poiSearchListener);

5、 发起检索

在EditText控件的OnEditorActionListener监听器中调用searchInCity函数发起检索,代码如下

 //获得检索输入框控件
        mInputText=findViewById(R.id.inputText);
        mInputText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                boolean ret=false;
                if(actionId== EditorInfo.IME_ACTION_SEARCH)
                {
                    String city=mCurLocation.getCity();
                    String keyWord=v.getText().toString();
                    ret=mPoiSearch.searchInCity(new PoiCitySearchOption()
                            .city(city)
                            .keyword(keyWord)
                            .pageNum(0));
                    //搜索后隐藏键盘
                    InputMethodManager       imum=(InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
                    View view=getWindow().peekDecorView();
                    if(view!=null)
                    {
                        imum.hideSoftInputFromWindow(view.getWindowToken(),0);
                    }
                }
                return ret;
            }
        });

注意:如果mCurLocation.getCity()返回null,那是因为在配置定位设置时,少了一步,默认是不开启获取当前位置的,需要加下面一行代码(定位详细配置参考上一篇基于百度地图sdk的地图app开发(四)——显示地图定位 的第4部分“4 通过LocationClient发起定位”代码) 

        option.setIsNeedAddress(true);

6、 显示搜索结果

6.1 layout中添加显示搜索结果的布局文件poi_item.xml

内容如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/poiname"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="TextView"
        android:textColor="@color/white"
        android:textSize="24sp" />

    <TextView
        android:id="@+id/poiaddress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="TextView"
        android:textColor="@color/white"
        android:textSize="14sp" />
</LinearLayout>

6.2、 activity_main.xml中添加listView控件

代码如下

    <ListView
        android:id="@+id/searchResult"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="120dp"
        android:background="@color/material_on_background_emphasis_high_type"
        android:visibility="gone" />

6.3、 新建PoiAdapter适配器类

package com.example.lmap;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.baidu.mapapi.search.core.PoiInfo;

import java.util.List;

public class PoiAdapter extends ArrayAdapter<PoiInfo> {
    private int resourceId;
    public PoiAdapter(@NonNull Context context, int resource, @NonNull List<PoiInfo> objects) {
        super(context, resource, objects);
        resourceId=resource;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        PoiInfo poi=getItem(position);
        View view= LayoutInflater.from(getContext()).inflate(resourceId,null);
        TextView name=view.findViewById(R.id.poiname);
        TextView address=view.findViewById(R.id.poiaddress);
        name.setText(poi.name);
        address.setText(poi.address);
        return view;
    }
}

6.4、 在POI检索监听器往listView中填充内容

在步骤3中创建的POI检索监听器的onGetPoiResult函数中添加以下代码来显示搜索结果 

该部分除了要显示当前页搜索结果外,还在 listView的滚动监听函数中实现了,当滚动到底部时加载下一页搜索结果的功能

        public void onGetPoiResult(PoiResult poiResult) {
            //显示搜索结果
            List<PoiInfo> poiList=poiResult.getAllPoi();
            PoiAdapter adapter=new PoiAdapter(MainActivity.this,R.layout.poi_item,poiList);
            ListView listView=findViewById(R.id.searchResult);
            listView.setAdapter(adapter);
            listView.setVisibility(View.VISIBLE);
            
            //当滑动到底部时加载更多搜索结果
            listView.setOnScrollListener(new AbsListView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
                    if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
                        // 判断是否滚动到底部
                        if (view.getLastVisiblePosition() == view.getCount() - 1) {
                            //加载更多
                            int curPage=poiResult.getCurrentPageNum();
                            int totalPage=poiResult.getTotalPageNum();
                            if(curPage< totalPage)
                            {
                                poiResult.setCurrentPageNum(curPage+1);
                                String city=mCurLocation.getCity();
                                TextView textV=findViewById(R.id.inputText);
                                String keyWord=textV.getText().toString();
                                mPoiSearch.searchInCity(new PoiCitySearchOption()
                                        .city(city)
                                        .keyword(keyWord)
                                        .pageNum(curPage+1));
                            }
                        }
                    }
                }

最后搜索结果实现效果如下

7 、当点击搜索结果列表之外区域时隐藏结果列表

最后,重写dispatchTouchEvent函数,实现当点击索结果列表之外区域时隐藏结果列表
     @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
     if (ev.getAction() == MotionEvent.ACTION_DOWN) {
         ListView listView = findViewById(R.id.searchResult);
         int left = listView.getLeft(), top = listView.getTop(), right = left + listView.getWidth(), bottom = top + listView.getHeight();
         if (ev.getX() < left || ev.getX() > right || ev.getY() < top || ev.getY() > bottom)//点击搜索结果列表之外区域,隐藏搜索结果列表
             listView.setVisibility(View.GONE);
     }
     return super.dispatchTouchEvent(ev);
 }

 

 

以上是关于【百度地图篇】1.Flutter+百度Sdk实现地图功能 & 百度地图显示网格问题的主要内容,如果未能解决你的问题,请参考以下文章

Android 百度鹰眼轨迹SDK(v2.1.6)

基于百度地图sdk的地图app开发——路线规划

基于百度地图sdk的地图app开发——poi检索

基于百度地图sdk的地图app开发——路线规划

基于百度地图sdk的地图app开发——导航和模拟导航

基于百度地图sdk的地图app开发——导航和模拟导航