安卓调用百度地图网页版进行路径规划与导航,只需提供地名

在开发一个安卓应用,需要用到路径规划的功能,但是再次吐槽百度地图的SDK,总之我是折腾半天都总是bug,遂考虑直接内嵌网页。

百度地图的网页也有相应的api,可以用但是不好用,它必须获得经纬度才能准确定位好吗,而且不具备位置搜索功能,如果自动定位失败或者定位到重名的地方了,倒是可以直接在地图上找,但是让用户自己去世界上找自己的位置真的好吗…不去找截图了,想尝试的请自便,总之难用又难改。

那么我所用的,便是正儿八经的百度地图网页版了,没错就是那个官网。
电脑版长这样,当然app和这个没关系,只是给看看:
这里写图片描述

这个网站做的还是不错的,毕竟百度大厂,响应式布局还是做了的,下面就是我们的主角:手机版网页如下,不要注意浏览器插件啊喂,请记下这个URL,这就是我们需要用到的:

https://map.baidu.com/mobile/webapp/index/index/

这里写图片描述

说起来手机版和电脑版的网页,定位方式是不同的,电脑版网页可以根据ip定位个大概,但是手机版网页大概是想通过GPS定位了,然而室内搜不到信号这里写图片描述

这都不重要,下面说正经的
完整代码我放在最后面,这里先只放重点

首先当然是使用webView加载网站了
先说几点需要注意的:

  • 如果说提示说 http和https 不能混合加载,那么加入如下代码:
int version = Build.VERSION.SDK_INT;
if(version >= 21) {
     webView.getSettings().setMixedContentMode(android.webkit.WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);//允许混合加载http与https
}
webView.loadUrl("https://map.baidu.com/mobile/webapp/index/index/");

然后运行结果如下图:
这里写图片描述

进入该页面后,点击路线,然后用户自己输入起点和终点就可以开始导航了。这样似乎凑合了,但是肯定不完美啊,程序不就是用来方便用户的么,居然连自动输入都做不到吗?

答案当然是可以的,使用的方法嘛,js注入!所以这就是我研究这东西研究了两天的成果,核心只有可以缩成2行代码的三行代码喵喵喵这里写图片描述

经过漫长的实验,的确可以通过js中注入的方式点击那个路径键然后跳转到后一个页面,但是js往里面填入值就不行了,原因猜测是页面还没加载好就执行了js代码。
我原本的js代码是,事实是只执行了前两句。

var qq = $('#fis_elm_pager__qk_4 div div div ul li:nth-child(3) a');
     qq.click();

     $('#se-txt-start').val(start);

     $('#se-txt-end').val(end);

所以直接进入路径按键对应的链接了,之前总感觉其URL里会有BUG潜伏,但是此刻也别无他法了。
所以点击路径后的URL,我这儿如下,中间乱码是一些中文,会在第一个页面就定位了然后传到第二个页面,没发现有啥用,但是删了又不行。

https://map.baidu.com/mobile/webapp/index/index/qt=cur&wd=%E5%8C%97%E4%BA%AC%E5%B8%82&from=maponline&tn=m01&ie=utf-8=utf-8/tab=line/?fromhash=1

关于js注入的七七八八我就不在此赘述了,下面直接写核心方法吧。

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
....
    @Override
    public void onPageFinished(WebView view, String url) {
        String s = "$('#se-txt-start').val('长沙理工大学');$('#se-txt-end').val('湖南大学');";
        webView.loadUrl("javascript:" + s);
        super.onPageFinished(view, url);
    }

}

如果js代码运行有问题的,请检查以下几句代码,如果没有就加上:

webView.setWebChromeClient(new WebChromeClient());
        webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);//设置js可以直接打开窗口,如window.open(),默认为false
        webView.getSettings().setJavaScriptEnabled(true);//是否允许执行js,默认为false。设置true时,会提醒可能造成XSS漏洞

想要可运行程序:请点击这是GITHUB链接
下载党注意本软件并不是为了写出该demo而作的,目前还不完善,下载本DEMO请看准WebNav_1 这个分支下载(上述链接默认是这个,不要下master,那个是陈年老版本了)使用方法为:不要管别的,点击最下方的导航就可以进入该页面了。

嘿嘿附上最终运行截图,点击搜索即可导航,而且如果位置不是唯一确定的话,点击搜索会让你选择的
这里写图片描述

下面放上我这一整个activity的代码吧,没有xml布局,这个布局一整个就是一个webView,还是用代码加进去的,所以按理说改一下类名后复制到其他activity中也是可以正常用的。

package com.yinyoupoet.seekbyscan;

import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.io.IOException;
import java.io.InputStream;

public class NavigatorActivity extends AppCompatActivity {

    private WebView webView;
    private long exitTime = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_navigator);

        webView = new WebView(this);

        //webView.setWebChromeClient(new WebChromeClient());
        webView.setWebViewClient(new WebViewClient(){
            //解决显示与跳转问题
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if(url == null) return false;

                Log.d("MY_URL", url);
                try{
                    if(url.startsWith("baidumap://")){
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                        startActivity(intent);
                        return true;
                    }
                }catch (Exception e){
                    return false;
                }
                webView.loadUrl(url);
                return true;
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                //String s = "var qq = $('#fis_elm__4 div div div ul li:nth-child(3) a'); qq.click();$('#se-txt-start').val('长沙理工大学');$('#se-txt-end').val('湖南大学'); window.alert('js injection success');";
                String s = "$('#se-txt-start').val('长沙理工大学');$('#se-txt-end').val('湖南大学');";

                webView.loadUrl("javascript:" + s);
                super.onPageFinished(view, url);
            }
        });


        webView.setWebChromeClient(new WebChromeClient());
        webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);//设置js可以直接打开窗口,如window.open(),默认为false
        webView.getSettings().setJavaScriptEnabled(true);//是否允许执行js,默认为false。设置true时,会提醒可能造成XSS漏洞
        webView.getSettings().setSupportZoom(true);//是否可以缩放,默认true
        webView.getSettings().setBuiltInZoomControls(true);//是否显示缩放按钮,默认false
        webView.getSettings().setUseWideViewPort(true);//设置此属性,可任意比例缩放。大视图模式
        webView.getSettings().setLoadWithOverviewMode(true);//和setUseWideViewPort(true)一起解决网页自适应问题
        webView.getSettings().setAppCacheEnabled(true);//是否使用缓存
        webView.getSettings().setDomStorageEnabled(true);//DOM Storage
        int version = Build.VERSION.SDK_INT;
        if(version >= 21) {
            webView.getSettings().setMixedContentMode(android.webkit.WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);//允许混合加载http与https
        }
// displayWebview.getSettings().setUserAgentString("User-Agent:Android");//设置用户代理,一般不用

        //webView.setWebChromeClient(new WebChromeClient());

        webView.loadUrl("https://map.baidu.com/mobile/webapp/index/index/qt=cur&wd=%E5%8C%97%E4%BA%AC%E5%B8%82&from=maponline&tn=m01&ie=utf-8=utf-8/tab=line/?fromhash=1");
        setContentView(webView);
    }

}



欢迎大家加入QQ群一起交流讨论,「吟游」程序人生——YinyouPoet

posted @ 2018-02-04 22:31  _吟游诗人  阅读(677)  评论(0编辑  收藏  举报