【问题标题】:OSMDroid - Map does not displayOSMDroid - 地图不显示
【发布时间】:2018-02-04 12:42:24
【问题描述】:

我正在尝试在我的应用中加载开放的街道地图。

我的代码如下:

import android.app.Activity;
import android.os.Bundle;

import org.osmdroid.config.Configuration;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.views.MapView;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;


public class OsmActivity extends Activity {
private MapView         mMapView;
private MapController   mMapController;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_osm);


    Configuration.getInstance().setUserAgentValue(getPackageName());

    mMapView = (MapView) findViewById(R.id.map);
    mMapView.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);
    mMapView.setBuiltInZoomControls(true);
    mMapController = (MapController) mMapView.getController();
    mMapController.setZoom(13);
    GeoPoint gPt = new GeoPoint(51500000, -150000);
    mMapController.setCenter(gPt);
}
}

我正在使用 osmdroid 5.6.5(通过 Maven)。

我根据 osmdroid 文档定义我的用户代理。

Configuration.getInstance().setUserAgentValue(getPackageName());

我有这些 API 设置:

android {
compileSdkVersion 26
defaultConfig {
    applicationId "com.loco_zero.locolizetestsosm"
    minSdkVersion 21
    targetSdkVersion 26
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

拥有这些权限:

<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.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

我有网格和缩放按钮,但地图不会显示。 我收到这些错误:

I/StorageUtils: /sdcard is NOT writable
I/StorageUtils: /storage/emulated/0 is NOT writable
I/OsmDroid: Using tile source: Mapnik
E/SQLiteLog: (14) cannot open file at line 31278 of [2ef4f3a5b1]
E/SQLiteLog: (14) os_unix.c:31278: (13) open(/storage/emulated/0/osmdroid/tiles/cache.db) - 
E/SQLiteDatabase: Failed to open database '/storage/emulated/0/osmdroid/tiles/cache.db'.
              android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database

D/OsmDroid: Unable to store cached tile from Mapnik /13/4090/2719, database not available.

我做错了什么? 我可以告诉 OSMDroid 使用 sdcard 文件夹以外的东西吗?

编辑

我添加了以下内容以在运行时获取权限,它成功了:

    if (Build.VERSION.SDK_INT >= 23) {
        if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            Log.v(TAG, "Permission is granted");
        } else {
            Log.v(TAG, "Permission is revoked");
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }
    }

【问题讨论】:

标签: java android storage openstreetmap osmdroid


【解决方案1】:

确保您正确启用了运行时权限。您将需要外部存储以及互联网存储。还要检查您的清单权限

【讨论】:

  • 如果从 29 之前的版本迁移,您必须包含对外部存储的旧权限&lt;application android:requestLegacyExternalStorage="true" ...
  • @tonygil 太完美了。工作正常。
【解决方案2】:

@shane 接受的答案为我指明了正确的方向。但是,权限请求发生了变化:

如果从 29 之前的版本迁移,您还必须包含对外部存储的旧权限&lt;application android:requestLegacyExternalStorage="true" ...

【讨论】:

    【解决方案3】:

    这实际上是一个奇怪的情况。 osmdroid 在第一次启动时检测地图切片缓存的最大可写存储位置。如果没有找到,它应该默认为应用程序提供存储。我认为您的情况没有发生这种情况,因为您没有调用它

    Configuration.getInstance().load(context, PreferenceManager.getDefaultSharedPreferences(context));

    它可能需要在文档中获得更多可见性,但这将启动发现过程。这应该在创建地图视图之前完成。

    【讨论】:

      【解决方案4】:

      在此行之前添加以下行setContentView(R.layout.activity_osm);

      IConfigurationProvider provider = Configuration.getInstance();
      provider.setUserAgentValue(BuildConfig.APPLICATION_ID);
      provider.setOsmdroidBasePath(getStorage());
      provider.setOsmdroidTileCache(getStorage());
      

      【讨论】:

        【解决方案5】:

        我已经在 kotlin 平台中实现了 OpenStreetMap 下面并且它可以工作。

        添加以下行 build.gradle(app level)

        implementation 'org.osmdroid:osmdroid-android:6.0.0'
        

        创建 LocationFragment.kt 并粘贴以下代码。

        import android.graphics.BitmapFactory
        import android.os.Bundle
        import android.preference.PreferenceManager
        import android.view.LayoutInflater
        import android.view.View
        import android.view.ViewGroup
        import com.app.base.BuildConfig
        import com.app.base.base_classes.BaseFragment
        import com.google.android.gms.maps.GoogleMap
        import org.osmdroid.api.IMapController
        import org.osmdroid.config.Configuration
        import org.osmdroid.tileprovider.tilesource.TileSourceFactory
        import org.osmdroid.views.MapView
        import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider
        import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
        
        //Replace BaseFragment() with Fragment() class
        class LocationFragment : BaseFragment() {
        
            override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        
                val view = inflater.inflate(com.app.base.R.layout.fragment_location, container, false)
                val ctx = activity!!.applicationContext
                Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx));
                Configuration.getInstance().setUserAgentValue(BuildConfig.APPLICATION_ID);
                val map = view.findViewById<MapView>(com.app.base.R.id.mapview)
                map.setUseDataConnection(true)
                //val map = view.findViewById(R.id.map) as MapView
                map.setTileSource(TileSourceFactory.MAPNIK)
                //map.setBuiltInZoomControls(true) //Map ZoomIn/ZoomOut Button Visibility
                map.setMultiTouchControls(true)
                val mapController: IMapController
                mapController = map.getController()
        
                //mapController.zoomTo(14, 1)
                mapController.setZoom(14)
        
                val mGpsMyLocationProvider = GpsMyLocationProvider(activity)
                val mLocationOverlay = MyLocationNewOverlay(mGpsMyLocationProvider, map)
                mLocationOverlay.enableMyLocation()
                mLocationOverlay.enableFollowLocation()
        
                val icon = BitmapFactory.decodeResource(resources, com.app.base.R.drawable.ic_menu_compass)
                mLocationOverlay.setPersonIcon(icon)
                map.getOverlays().add(mLocationOverlay)
        
                mLocationOverlay.runOnFirstFix {
                    map.getOverlays().clear()
                    map.getOverlays().add(mLocationOverlay)
                    mapController.animateTo(mLocationOverlay.myLocation)
                }
                return view
            }
        
        }
        

        在xml中使用下面的代码

        <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/colorWhite"
            tools:context="com.app.base.ui.location.LocationFragment">
        
            <org.osmdroid.views.MapView
                android:id="@+id/mapview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                />
        
        </FrameLayout>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-10-20
          • 1970-01-01
          • 2013-07-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多