You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

咨询:osmdroid地图仅显空白网格,无外部存储权限如何解决?

解决osmdroid空白网格+无需外部存储权限的问题

嘿,我看了你遇到的问题——osmdroid只显示空白网格,而且设备不支持外部存储,想去掉SD卡权限对吧?咱们一步步来解决:

一、先搞定「无需外部存储权限」的配置

osmdroid确实默认会依赖外部存储,但完全可以把缓存路径移到应用内部存储,这样就不需要READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限了。

1. 修改Manifest权限

直接删掉这两个冗余权限:

<!-- 移除这两行权限声明 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

如果你的目标SDK是Android 10+,系统会因为Scoped Storage特性自动忽略这类权限请求,放心删掉就行。

2. 正确配置内部存储缓存路径

你代码里已经尝试设置缓存路径,但存在重复初始化Configuration的问题,顺序也有点混乱。正确的做法是:在初始化mapView之前,一次性完成Configuration配置,不要重复调用load方法。

修改后的初始化代码示例:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    // 第一步:优先配置osmdroid缓存到内部存储
    Context appContext = getApplicationContext();
    Configuration config = Configuration.getInstance();
    
    // 用应用专属的内部缓存目录(getCacheDir),无需权限
    File basePath = new File(getCacheDir(), "osmdroid");
    File tileCache = new File(basePath, "tiles");
    // 确保目录存在,避免初始化失败
    if (!tileCache.exists()) {
        tileCache.mkdirs();
    }
    
    config.setOsmdroidBasePath(basePath);
    config.setOsmdroidTileCache(tileCache);
    // 必须设置用户代理,否则多数瓦片服务器会拒绝请求
    config.setUserAgentValue(BuildConfig.APPLICATION_ID);
    
    // 仅加载一次配置
    config.load(appContext, PreferenceManager.getDefaultSharedPreferences(appContext));
    
    // 第二步:再初始化布局和mapView
    setContentView(R.layout.activity_directmap);
    ButterKnife.bind(this);
    
    mapView = findViewById(R.id.mapViewosm);
    mapView.setMultiTouchControls(true);
    mapView.setBuiltInZoomControls(true);
    
    // 以下是你的业务逻辑代码
    roadManager = new GraphHopperRoadManager(getString(R.string.apikey), true);
    manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
    Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
    route.setOnClickListener(this);
    startIcon = BitmapFactory.decodeResource(appContext.getResources(), R.drawable.ic_mark);
    
    lat = -5.402213;
    lng = 105.264113;
    setupOverlay();
    setupMap();
    addMarker();
}

二、解决空白网格的核心问题

你代码里有几个可能导致空白的细节问题,咱们逐个修正:

1. 避免重复设置TileSource

你在onCreate里先设置了MAPNIK瓦片源,又在setupMap里改成Bing源,这种重复操作可能导致初始化异常。建议统一在setupMap里配置瓦片源,同时确保API Key有效:

private void setupMap() {
    // 确认Bing Key是有效且绑定了正确包名的
    BingMapTileSource.setBingKey(getString(R.string.bingkey));
    BingMapTileSource bingMap = new BingMapTileSource(null);
    bingMap.setStyle(BingMapTileSource.IMAGERYSET_ROAD);
    
    // 添加覆盖层
    mapView.getOverlays().add(rotationGestureOverlay);
    mapView.getOverlays().add(compassOverlay);
    mapView.getOverlays().add(myLocationNewOverlay);
    mapView.getOverlays().add(roadNodeMarkers);
    
    // 统一设置瓦片源
    mapView.setTileSource(bingMap);
    mapView.setTilesScaledToDpi(true);
    mapView.setMinZoomLevel(1.0);
    mapView.setMaxZoomLevel(21.0);
    mapView.setMultiTouchControls(true);
    mapView.setUseDataConnection(true);
    mapView.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER);
    
    // 确保mapView初始化完成后再获取控制器
    IMapController mapController = mapView.getController();
    mapController.setZoom(15); // 先设置合理缩放级别,再移动位置
    mapController.animateTo(new GeoPoint(-5.402213, 105.264093));
    
    // 最后强制刷新地图
    mapView.invalidate();
}

2. 确保用户代理(User-Agent)正确设置

很多瓦片服务器(比如OSM、Bing)会拒绝无User-Agent的请求,所以config.setUserAgentValue(BuildConfig.APPLICATION_ID)必须放在初始化最前面,且只设置一次。

3. 排查网络与瓦片源有效性

  • 确认设备网络正常,无代理/防火墙阻挡瓦片请求;
  • 如果Bing瓦片仍无法加载,可以临时切换到OSM默认源测试:mapView.setTileSource(TileSourceFactory.MAPNIK),如果OSM能显示,说明是Bing API Key的问题,需要检查Key的有效性。

三、额外调试技巧

可以打开Logcat搜索osmdroid关键词,查看是否有瓦片加载失败的错误日志,这能帮你快速定位具体问题(比如网络错误、权限问题、路径不存在等)。

内容的提问来源于stack exchange,提问作者Ewa Saputra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:32:17