首页 > 解决方案 > 为什么我的离线地图突然停止工作?

问题描述

我正在使用 osmdroid v6.0.1 来显示一些使用 MOBAC 生成的 4uMaps 瓦片。在我尝试添加 Mylocation 覆盖之前,我一直都在工作。从那时起,尽管(我认为)恢复到我的原始代码,但离线地图将无法使用,尽管使用 TileFactory.MAPNIK 可以。使用离线地图时,我得到的只是可怕的灰屏。我检查了我的权限并确认 (a) 我的应用程序可以读取 4uMaps.zip 文件,并且它包含一个名为 4uMaps 的文件夹,并且 (b) 我将地图中心设置为地图区域内的一个点。

我的清单文件是:-

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.corunna.osm">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"  />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
    android:allowBackup="true"
    android:icon="@mipmap/evcharger1"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/evcharger1"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

我的代码是:-

public class MainActivity extends Activity {
MapView map = null;
ArrayList<GeoPoint> waypoints = new ArrayList<GeoPoint>();
ArrayList<Marker> markers = new ArrayList<Marker>();
Context ctx;
IMapController mapController;

/** Base path for osmdroid files. Zip files are in this folder. */
public static File OSMDROID_PATH = new File(Environment.getExternalStorageDirectory(),"osmdroid");

/** Base path for tiles. */
public static File TILE_PATH_BASE = new File(OSMDROID_PATH, "tiles");

/** 600 Mb */
public static long TILE_MAX_CACHE_SIZE_BYTES = 600L * 1024 * 1024;

/** 500 Mb */
public static long TILE_TRIM_CACHE_SIZE_BYTES = 500L * 1024 * 1024;

@Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    /**************************************************************************
     *          Get Context and OSM User Agent
     **************************************************************************/

    ctx = getApplicationContext();
    Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx));

    /**************************************************************************
     *          Check Permissions
     **************************************************************************/

    if (ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        // Permission is not granted
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 2);
    }
    else {
        Log.e("OSMCH","Read External Storage allowed");

    }
    if (ContextCompat.checkSelfPermission(ctx, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        // Permission is not granted
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
    }
    else {
        Log.e("OSMCH","Write External Storage allowed");

    }

    if (ContextCompat.checkSelfPermission(ctx, Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        // Permission is not granted
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 3);
    }
    else {
        Log.e("OSMCH","Coarse Location allowed");

    }

    if (ContextCompat.checkSelfPermission(ctx, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        // Permission is not granted
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 4);
    }
    else {
        Log.e("OSMCH","Fine Location allowed");

    }

    /**************************************************************************
     *          Initialise maps
     **************************************************************************/

    setContentView(R.layout.activity_main);
    map = (MapView) findViewById(R.id.map);

    File umaps = new File(OSMDROID_PATH,"4uMaps.zip");
    Log.e("OSMCH","4uMaps read status = " + umaps.canRead());

    map.setUseDataConnection(false); //optional, but a good way to prevent loading from the network and test your zip loading.
    map.setTileSource(new XYTileSource("4uMaps", 0, 18, 256, ".jpg", new String[]{"http://tileserver.4umaps.eu/"}));
   //map.setTileSource(TileSourceFactory.MAPNIK);

    mapController = map.getController();
    mapController.setZoom(8);
    mapController.setCenter(new GeoPoint(54.280009, -2.103238));

    /**************************************************************************
     *      Allow Rotational Gestures so that user can more easily view route
     **************************************************************************/

    RotationGestureOverlay mRotationGestureOverlay = new RotationGestureOverlay(ctx, map);
    mRotationGestureOverlay.setEnabled(true);
    map.setMultiTouchControls(true);
    map.getOverlays().add(mRotationGestureOverlay);
 }
}

日志结果是:-

2019-08-02 22:21:39.991 17401-17401/com.corunna.osm E/OSMCH: Read External 
Storage allowed
2019-08-02 22:21:39.992 17401-17401/com.corunna.osm E/OSMCH: Write External 
Storage allowed
2019-08-02 22:21:39.993 17401-17401/com.corunna.osm E/OSMCH: Coarse Location 
allowed
2019-08-02 22:21:39.994 17401-17401/com.corunna.osm E/OSMCH: Fine Location 
allowed
2019-08-02 22:21:40.093 17401-17401/com.corunna.osm E/OSMCH: 4uMaps read 
status = true

我在 /sdcard/osmdroid 中使用 4uMaps.zip 设置了 /sdcard/osmdroid/tiles 的目录结构。据我所知(我写了一个小文件) /sdcard/osmdroid/tiles 是可写的。

最后,我的 build.gradle 文件(未更改)是:-

apply plugin: 'com.android.application'

android {
compileSdkVersion 28
buildToolsVersion "29.0.0"
defaultConfig {
    applicationId "com.corunna.osm"
    minSdkVersion 24
    targetSdkVersion 28
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner 
"android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android- 
   optimize.txt'), 'proguard-rules.pro'
    }
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'org.osmdroid:osmdroid-android:6.1.0'
implementation 'com.github.MKergall:osmbonuspack:6.6.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso- 
   core:3.0.2'
}

我怀疑问题与我的 Manifest 文件有关,因为当我添加 ACCESS_FINE_LOCATION 时一切都出错了,但我尝试删除它没有效果。

有人可以看到我做错了什么吗?我应该强调它有效,但现在无效,我无法弄清楚发生了什么变化。

标签: androidosmdroid

解决方案


事实证明,默认的 osmdroid 源和 tile 目录并不像文档中所暗示的那样。这两个都需要明确设置使用: -

    Configuration.getInstance().setOsmdroidBasePath(OSMDROID_PATH);
    Configuration.getInstance().setOsmdroidTileCache(TILE_PATH_BASE);

作为初始配置的一部分,即在应用程序的顶部。


推荐阅读