OSMDroidOfflineDemo源码调试记录

2 篇文章 0 订阅
1 篇文章 0 订阅


尝试安卓端加载离线地图,下载了使用osmdroid的离线版项目源码,更改JDK环境、gradle环境,一顿操作下来,踉踉跄跄的把程序跑起来了,但是离线的地图一直加载不出来。给我整emo了,先记录分享出来,看有没有和我一样别的盆友,一起探讨下。
我尝试了4种办法,目前只有第4种方法,使用 OfflineTileProvider类,才加载出来

源码下载

  • 项目的地址在这里:项目地址
  • 源码说明:原项目的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"参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值