OSMDroidOfflineDemo源码调试记录

news2024/11/19 15:20:46

文章目录

  • 源码下载
  • 环境配置
  • 尝试不同离线加载
  • 遇到的问题

尝试安卓端加载离线地图,下载了使用osmdroid的离线版项目源码,更改JDK环境、gradle环境,一顿操作下来,踉踉跄跄的把程序跑起来了,但是离线的地图一直加载不出来。给我整emo了,先记录分享出来,看有没有和我一样别的盆友,一起探讨下。
我尝试了4种办法,目前只有第4种方法,使用 OfflineTileProvider类,才加载出来,另外几个办法要么没有使用Provider直接给mapView设置 mapView.setTileSource(TileSourceFactory.MAPQUESTOSM);看这个常量也是https的地址;两个两次尝试的代码种分别用了 MapTileModuleProviderBase类结合 XYTileSource类MapTileModuleProviderBase类结合 自定义CustomTileSource类继承BitmapTileSourceBase类
在这里插入图片描述

源码下载

  • 项目的地址在这里:项目地址
  • 源码说明:原项目的gradle版本2.5,gradle的构建版本是3.1.2,目标sdk版本是28
    项目比较老,构建工具比较老,原项目配置下无法完成构建,我做了修改,在环境配置节
  • 使用的osmdroid安卓库是4.3implementation 'org.osmdroid:osmdroid-android:4.3'

环境配置

主要做了三处的修改

  1. 工程的build.gradle文件中仓库替换了国内的源
maven { url 'https://maven.aliyun.com/repository/google'}
maven { url 'https://maven.aliyun.com/repository/public'}
maven { url 'https://maven.aliyun.com/repository/jcenter'}
  1. 工程的build.gradle文件中更改了gradle构建版本
dependencies {
	classpath 'com.android.tools.build:gradle:7.4.2'
}
  1. 修改了gradle-wrapper.properties的distributionUrl
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip

尝试不同离线加载

尝试了四个项目,第一个和第二个日志里都有okhttp网络请求的报错,都会尝试去下载瓦片。
第四个尝试,有点特殊,他用到了OfflineTileProvider类,最后一个测试成功了。

  1. 尝试1:原项目,启动成功,无法加载离线的瓦片,源码项目参考Using OSMDroid for Offline mapping in Android, step-by-step
  • 说明:没有使用Provider直接给mapView设置 mapView.setTileSource(TileSourceFactory.MAPQUESTOSM);
  1. 尝试2:另外一个项目OSMOfflineMap-Android
  • 说明:用MapTileModuleProviderBase类结合 XYTileSource类,也是运行成功,没跑起来
  1. 尝试3:参考Android使用osmdroid加载在线地图,离线地图以及各种填坑姿势
  • 说明1:MapTileModuleProviderBase类结合 自定义CustomTileSource类继承BitmapTileSourceBase类
  • 说明2:用的osmdroid版本是implementation 'org.osmdroid:osmdroid-android:6.1.11'使用kotlin写,我用Java翻译了一下,也没有加载出地图瓦片
 public void mapViewOtherData0(MapView mapView){
        String strFilepath = copyAssetGetFilePath("tiles.zip");
        File exitFile =new File(strFilepath);
        if(!exitFile.exists()){
            System.out.println("文件不存在!");
        }else {
            try{
                // 获取解压后的文件夹名称
                String source = exitFile.getName().substring(0, exitFile.getName().lastIndexOf("."));
                // 创建归档文件对象数组
                IArchiveFile[] archives = new IArchiveFile[1];
                archives[0] =ArchiveFileFactory.getArchiveFile(exitFile);

                // 创建 CustomTileSource 对象
                CustomTileSource customTiles = new CustomTileSource(source , 1, 13, 256, ".png");
                // 创建一个大小为1的 MapTileModuleProviderBase 数组
                MapTileModuleProviderBase[] providers = new MapTileModuleProviderBase[1];

                providers[0] =new MapTileFileArchiveProvider(new SimpleRegisterReceiver(this),customTiles,archives);

                MapTileProviderArray tileProvider = new MapTileProviderArray(customTiles,new SimpleRegisterReceiver(this),providers);

                TilesOverlay tilesOverlay = new TilesOverlay(tileProvider,this);
                tilesOverlay.setLoadingBackgroundColor(Color.TRANSPARENT);

                mapView.getOverlayManager().add(tilesOverlay);

                IMapController mapViewController = mapView.getController();

                mapViewController.setZoom(10);
//        mapViewController.setCenter(BERLIN);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
private String copyAssetGetFilePath(String fileName) {
        try {
            File cacheDir = getApplicationContext().getCacheDir();
            if (!cacheDir.exists()) {
                cacheDir.mkdirs();
            }
            File outFile = new File(cacheDir, fileName);
            if (!outFile.exists()) {
                boolean res = outFile.createNewFile();
                if (!res) {
                    return null;
                }
            } else {
                if (outFile.length() > 10) {//表示已经写入一次
                    return outFile.getPath();
                }
            }
            InputStream is = getApplicationContext().getAssets().open(fileName);
            FileOutputStream fos = new FileOutputStream(outFile);
            byte[] buffer = new byte[1024];
            int byteCount;
            while ((byteCount = is.read(buffer)) != -1) {
                fos.write(buffer, 0, byteCount);
            }
            fos.flush();
            is.close();
            fos.close();
            return outFile.getPath();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

报错信息

E Please configure a relevant user agent; current value is: osmdroid
  1. 尝试4:android osmdroid 加载常用离线地图格式(开源的在线地图),这个博客使用的mbtiles,目前还在下载中,可用图新地球下载,也可以直接用tiles.zip,已测试
  • 说明:使用OfflineTileProvider类
public void mapViewOtherData(MapView mapView){
//        String strFilepath = Environment.getExternalStorageDirectory().getPath() + "/njmap_DarkBlue.mbtiles";
        String strFilepath = copyAssetGetFilePath("tiles.zip");
        File exitFile =new File(strFilepath);
//        File exitFile = new File(strFilepath);
        String fileName = "tiles.zip";
        if (!exitFile.exists()) {
            mapView.setTileSource(TileSourceFactory.MAPNIK);
        }else {
            fileName = fileName.substring(fileName.lastIndexOf(".") + 1);
            if (fileName.length() == 0)
                return;
            if (ArchiveFileFactory.isFileExtensionRegistered(fileName)) {
                try {
                    OfflineTileProvider tileProvider = new OfflineTileProvider((IRegisterReceiver) new SimpleRegisterReceiver(this), new File[] { exitFile });
                    mapView.setTileProvider(tileProvider);

                    String source = "";
                    IArchiveFile[] archives = tileProvider.getArchives();
                    if (archives.length > 0) {
                        Set<String> tileSources = archives[0].getTileSources();
                        if (!tileSources.isEmpty()) {
                            source = tileSources.iterator().next();
                            mapView.setTileSource(FileBasedTileSource.getSource(source));
                        } else {
                            mapView.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);
                        }

                    } else
                        mapView.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);
                    Toast.makeText(this,"Using " + exitFile.getAbsolutePath() + " "+ source, Toast.LENGTH_LONG).show();
                    mapView.invalidate();
                    return;
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                Toast.makeText(this,  " did not have any files I can open! Try using MOBAC", Toast.LENGTH_LONG).show();
            } else{
                Toast.makeText(this, " dir not found!", Toast.LENGTH_LONG).show();
            }
        }
    }

在这里插入图片描述

遇到的问题

android:exported needs to be explicitly specified for element <activity#com.example.android.osmdroidofflinedemo.MainActivity>. Apps targeting Android 12 and higher are required to specify an explicit value for `android:exported` when the corresponding component has an intent filter defined. See https://developer.android.com/guide/topics/manifest/activity-element#exported for details. 

办法在此:tools:node="merge"参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1955147.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

49.TFT_LCD液晶屏驱动设计与验证(2)

&#xff08;1&#xff09;Visio视图&#xff1a; &#xff08;2&#xff09;控制模块Verilog代码&#xff1a; module tft_ctrl(input clk_33M ,input reset_n ,input [23:0] data_in ,output [9:0] hang…

如何使用 SQLite ?

SQLite 是一个轻量级、嵌入式的关系型数据库管理系统&#xff08;RDBMS&#xff09;。它是一种 C 库&#xff0c;实现了自给自足、无服务器、零配置、事务性 SQL 数据库引擎。SQLite 的源代码是开放的&#xff0c;完全在公共领域。它被广泛用于各种应用程序&#xff0c;包括浏览…

Python | ValueError: could not convert string to float: ‘example’

Python | ValueError: could not convert string to float: ‘example’ 在Python编程中&#xff0c;类型转换是一个常见的操作。然而&#xff0c;当尝试将一个字符串转换为浮点数时&#xff0c;如果字符串的内容不是有效的浮点数表示&#xff0c;就会遇到“ValueError: could…

【python_将一个列表中的几个字典改成二维列表,并删除不需要的列】

def 将一个列表中的几个字典改成二维列表(original_list,headersToRemove_list):# 初始化一个列表用于存储遇到的键&#xff0c;保持顺序ordered_keys []# 遍历data中的每个字典&#xff0c;添加其键到ordered_keys&#xff0c;如果该键还未被添加for d in original_list:for …

SpringCloud之@FeignClient()注解的使用方式

FeignClient介绍 FeignClient 是 Spring Cloud 中用于声明一个 Feign 客户端的注解。由于SpringCloud采用分布式微服务架构&#xff0c;难免在各个子模块下存在模块方法互相调用的情况。比如订单服务要调用库存服务的方法&#xff0c;FeignClient()注解就是为了解决这个问题的…

Vim 文本编辑工具

Vim 基础命令 一、Vim 命令速查 Vim 是一款功能强大的文本编辑器&#xff0c;广泛应用于Linux系统中。以下是一些基础但非常有用的Vim命令&#xff0c;它们将帮助你更高效地使用Vim。 使用单个字母键通常需要进一步的输入以形成完整命令。特殊符号用来表示操作的位置。 命令…

Linux网络:传输层TCP协议(四)拥塞控制及延迟应答

目录 一、拥塞控制 二、延迟应答 一、拥塞控制 虽然 TCP 拥有滑动窗口这个大杀器机制来根据具体情况对发送的数据大小和速度进行实时控制, 能够高效并且可靠的发送大量的数据. 但是如果在双方建立好连接后的刚开始阶段就发送大量的数据。仍然可能引发一些问题. 因为同一个网…

【2024蓝桥杯/C++/A组/团建】

题目 代码 #include<bits/stdc.h> using namespace std;const int N 2e510;int a[N], b[N]; int ans; vector<int> Ga[N], Gb[N];void dfs(int ap, int af, int bp, int bf, int dep) {ans max(ans, dep);map<int, int> bk;for(auto ason : Ga[ap])if(aso…

免费【2024】springboot 程序设计基础视频学习系统的设计与实现

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

CSS:mix-blend-mode属性(设置元素的混合模式)

目录 一、mix-blend-mode属性介绍 二、mix-blend-mode常用属性值 三、mix-blend-mode属性应用 四、文字智能适配背景 1、原始样式 2、添加混合 3、实现代码 一、mix-blend-mode属性介绍 CSS中的【mix-blend-mode属性】描述了元素的内容应该与元素的直系父元素的内容和…

nodejs安装及环境配置轨道交通运维检测系统App-OA人事办公排班故障维修

✌网站介绍&#xff1a;✌10年项目辅导经验、专注于计算机技术领域学生项目实战辅导。 ✌服务范围&#xff1a;Java(SpringBoo/SSM)、Python、PHP、Nodejs、爬虫、数据可视化、小程序、安卓app、大数据等设计与开发。 ✌服务内容&#xff1a;免费功能设计、免费提供开题答辩P…

【前端 09】JavaScript中的对象与JSON

JavaScript中的对象与JSON 在JavaScript中&#xff0c;对象和JSON&#xff08;JavaScript Object Notation&#xff09;是两个紧密相连但又有区别的概念。它们都在数据处理和交换中扮演着重要角色。本文将详细讲解JavaScript中的自定义对象以及JSON对象的基本概念、格式、用法…

赵本山:我跟你找游大队去,王平:实话告诉你,我就是游队长——小品《卖梨》(下)的台词与解说

赵本山&#xff1a;我跟你找游大队去&#xff0c;王平&#xff1a;实话告诉你&#xff0c;我就是游队长 ——小品《卖梨》&#xff08;下&#xff09;的台词与解说 &#xff08;接上&#xff09; 王平&#xff08;饰演警察&#xff09;&#xff1a;你少废话 你赶紧给我挪地方…

视觉SLAM第二讲

SLAM分为定位和建图两个问题。 定位问题 定位问题是通过传感器观测数据直接或间接求解位置和姿态。 通常可以分为两类&#xff1a;基于已知地图的定位和基于未知地图的定位。 基于已知地图的定位 利用预先构建的地图&#xff0c;结合传感器数据进行全局定位。SLAM中的全局…

USB 2.0 协议专栏之 USB 2.0 连接与枚举(二)

前言&#xff1a;本篇博客为手把手教学的 USB 2.0 协议栈类精品博客&#xff0c;该专栏博客侧重针对 USB 2.0 协议进行讲解。本篇博客将针对 USB 2.0 中的连接与枚举进行教学&#xff0c;USB 的枚举过程是 USB 协议中至关重要的一环&#xff0c;也是嵌入式工程师必须掌握的内容…

杂谈(杂鱼谈论c语言)——2.大小端字节序

⼤⼩端字节序和字节序判断 当我们了解了整数在内存中存储后&#xff0c;我们调试看⼀个细节&#xff1a; #include <stdio.h> int main() {int a 0x11223344;return 0; } 调试的时候&#xff0c;我们可以看到在a中的 0x11223344 这个数字是按照字节为单位&#xff0c;…

【多模态大模型】 ALBEF in NeurIPS 2021

一、引言 论文&#xff1a; Align before Fuse: Vision and Language Representation Learning with Momentum Distillation 作者&#xff1a; Salesforce Research 代码&#xff1a; ALBEF 特点&#xff1a; 该方法使用ViT进行图像特征提取&#xff0c;提出将BERT分两部分&am…

解密阿里大神写的天书般的Tree工具类,轻松搞定树结构!

首发公众号&#xff1a;赵侠客 一、引言 最近公司新进了不少新人&#xff0c;包括一些来自阿里、网易等大型企业的资深工程师。我们组的一位新同事是阿里来的专家&#xff0c;我在CR&#xff08;Code Review, 简称CR&#xff09;时看到了他编写的一个关于树操作的工具类&#…

用qt调试can通信,波特率如何设置

硬件环境介绍&#xff1a; 1、usb转can通信模块型号为创芯科技的USB-CAN适配器&#xff0c;厂家提供的测试软件和demo程序&#xff0c;如下图所示&#xff1b; 2、下位单片机STM32&#xff0c;can通信参数如下图&#xff0c;该测试程序时单片机一直在发送数据&#xff1b; 测试…