自学内容网 自学内容网

Android Osmdroid + 天地图 (一)

前言

  Osmdroid是一款完全开源的地图基本操作SDK,我们可以通过这个SDK去加一些地图API,比如腾讯、百度、高德、Google等等。天地图API也是一个地图服务提供商,不过之前还是提供Android的地图SDK的,现在就只提供了API服务了,那么为什么我们会想到这个天地图API呢?因为贫穷,贫穷使我们相遇,如果你是个人项目不上架的那种我推荐你使用高德、百度、腾讯3家,但如果你要上架的话就涉及到一个可能会被宰的问题了,这3家商业授权都是5万一年,那不是开玩笑的,如果你的应用不是主导地图的话,完全犯不上去使用,下面我们进入正文去使用天地图API,效果图如下所示:

在这里插入图片描述

正文

  点击天地图API进入,之后完成注册登录及个人或企业开发者的认证工作,然后就到了喜闻乐见的创建Android项目的环节了。

一、配置build.gradle

在这里插入图片描述

这里我们就使用Empty Views Activity的模板,点击Next。

在这里插入图片描述

  修改一下项目名和包名,这个包名在下面的获取API Key要用到的,注意这里的构建配置语言也是Kotlin的,如果你不习惯,请改成Groovy,然后运行能看到Hello World!即可。

因为我们需要使用OsmdroidSDK库,所以我们现在app模块下的build.gradle.kts文件中导入如下代码:

implementation("org.osmdroid:osmdroid-android:6.1.20")

这个库在mavenCentral()下,然后再配置viewBinding,代码如下所示:

    buildFeatures {
        viewBinding = true
    }

上述代码配置如下图所示:

在这里插入图片描述

二、配置AndroidManifest.xml

  因为用到地图自然就涉及到定位,还有API的使用就涉及到网络,而网络从Android8.0之后就默认是https请求方式,如果需要http的话则配置一下,针对上述的3个要求,我们首先配置一下权限,在AndroidManifest.xml中增加如下代码:

<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

然后在res下的xml目录下创建一个network_security_config.xml文件里面代码如下所示:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

这个文件的配置内容就是允许http访问,我们需要在AndroidManifest.xml中的application标签中进行配置,如下所示:

android:networkSecurityConfig="@xml/network_security_config"

上述的配置如下图所示:

在这里插入图片描述

三、获取天地图的API Key

相信你已经完成了我前面讲到的工作了,那么进入控制台,点击创建新应用。

在这里插入图片描述

可以看到这里我们需要发布版SHA1、开发版SHA1包名,包名我们创建项目的时候就有了。

① 获取开发版SHA1

首先我们来说明一下开发版SHA1的获取方式,刚才我们运行过了,下面使用快捷键Win+R,输入cmd,进入命令窗口,输入

cd .android

回车,然后输入

keytool -list -v -keystore debug.keystore

回车,会让你输入密码,密码就是android,输入后回车就看到一大串信息,其中就有我们SHA1,注意我们使用的是debug.keystore,所以得到的就是开发版SHA1,这个值在不同的电脑上就不一样,请注意。

在这里插入图片描述

复制一下粘贴过去即可。

② 获取发布版SHA1

下面来获取发布版SHA1,这个稍微麻烦一点,我们需要先生成一个APK。

在这里插入图片描述

点击Build➡️Generate Signed App Bundle/ APK...

在这里插入图片描述
这里选择APK,点击Next。

在这里插入图片描述

点击Create new...

在这里插入图片描述

  可以参考我这个方式去设置,这里我的两个密码都是一样的,你可以不一样,前提是你记得住,需要注意是的这个jks文件生成的位置,我是直接生成到项目的目录下了,点击OK

在这里插入图片描述
勾选上Remeber passwords,点击Next

在这里插入图片描述

点击Create等待生成APK。

在这里插入图片描述

当你在AS的右下角看到这个弹窗时,表示生成APK成功了,切换到Project模式查看一下,如下图所示:

在这里插入图片描述

  下面就是正式获取发布版SHA1的过程了,本来上面这一大串我是不想写的,但是又考虑到是小白的话,就还是写了,点击AS底部的Terminal,打开后默认就是当前项目的目录,然后我们只要输入

keytool -list -v -keystore .\openMap.jks

keytool -list -v -keystore后面的是你的jks的文件路径,如果你不是我这么配置的请写自己的实际路径,然后回车,输入密码再回车即可看到发布版SHA1,如下图所示:

在这里插入图片描述

下面回到天地图那个网页,此时我们已经填好了所有需要的值。

在这里插入图片描述

点击提交,就是提示创建成功,如果提示创建失败的话,你再点一次,有网络延迟的问题。创建成功就得到了我们访问天地图的Key了,如下图所示:

在这里插入图片描述

这个Key我们在项目中需要用到的,我们可以在com.llw.openmap下创建一个Config类,这里面配置这个Key,代码如下所示:

object Config {
    const val MAP_KEY = "f951c7d1b85975379f6ee20bb264abba"
}

四、请求权限

进入MainActivity,增加代码如下所示:

    // 定位权限
    private val permissions = arrayOf(
        android.Manifest.permission.ACCESS_FINE_LOCATION,
        android.Manifest.permission.ACCESS_COARSE_LOCATION,
        android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
        android.Manifest.permission.READ_EXTERNAL_STORAGE
    )

    // 权限申请
    private val permissionLauncher =
        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result ->
            if (!result.containsValue(false)) initMap() else requestPermission()
        }

首先我们定义了定位权限和权限请求返回,使用ActivityResult API的方式,然后我们需要写initMap()checkPermission()函数,代码如下所示:

    /**
     * 初始化地图
     */
    private fun initMap() {

    }

    /**
     * 检查权限
     */
    private fun checkPermission() {
        permissions.forEach { permission ->
            if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
                // 请求权限
                requestPermission()
                return
            }
        }
        // 初始化地图
        initMap()
    }

    /**
     * 请求权限
     */
    private fun requestPermission() {
        permissionLauncher.launch(permissions)
    }

最后我们在onResume()生命周期中检查权限,调用checkPermission(),代码如下所示:

    override fun onResume() {
        super.onResume()
        // 检查权限
        checkPermission()
    }

目前为止整个页面代码如下图所示:

在这里插入图片描述

  为什么我要贴图呢,因为是真的有人把代码写错位置,然后问我为什么报错?现在我们运行一下,你会发现弹窗请求权限,同意之后会看到都是格子,因为我们还没有加载地图API的,这里我们就要加载天地图。

五、显示地图

要显示地图就需要用到Osmdroid了,在Config中添加如下代码:

    // 默认GeoPoint
    val defaultGeoPoint = GeoPoint(39.909, 116.39742)
    /**
     * 天地图 有标注电子地图
     */
    var TDTCIA_W: OnlineTileSourceBase = object : XYTileSource(
        "Tian Di Tu CIA",
        0, 20, 256, "",
        arrayOf(
            "http://t0.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY",
            "http://t1.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY",
            "http://t2.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY",
            "http://t3.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY",
            "http://t4.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY",
            "http://t5.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY",
            "http://t6.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY",
            "http://t7.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY"
        )
    ) {
        override fun getTileURLString(pMapTileIndex: Long) =
            ("$baseUrl&X=${MapTileIndex.getX(pMapTileIndex)}&Y=${MapTileIndex.getY(pMapTileIndex)}&L=${MapTileIndex.getZoom(pMapTileIndex)}")
    }

添加了一个默认的经纬度坐标,然后通过Osmdroid去加载天地图的在线瓦片资源,然后回到MainActivity,这里首先我们用上ViewBinding,代码如下所示:

    private lateinit var binding: ActivityMainBinding

然后在onCreate中配置代码,如下所示:

binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

位置如下图所示:

在这里插入图片描述

下面进入initMap()中去配置地图,代码如下所示:

    private fun initMap() {
        binding.mapView.apply {
            setTileSource(Config.TDTCIA_W)  // 设置瓦片地图资源
            minZoomLevel = 5.0              // 最小缩放级别
            maxZoomLevel = 20.0             // 最大缩放级别
            isTilesScaledToDpi = true       // 图块是否缩放到 DPI
            // 设置默认的地图中心点
            controller.apply {
                setZoom(12.0)
                setCenter(Config.defaultGeoPoint)
            }
            zoomController.setVisibility(Visibility.NEVER)
            setMultiTouchControls(true)
            overlayManager.tilesOverlay.isEnabled = true
        }
    }

下面可以运行一下,我从头开始运行一下:

在这里插入图片描述

虽然可能效果不是特别好,但是起码是个地图啊,免费的你还要什么自行车。

六、源码

如果对你有所帮助的话,不妨欢迎StarFork

源码地址:OpenMap

APK下载地址:OpenMap1.0.apk


原文地址:https://blog.csdn.net/qq_38436214/article/details/143732139

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!