OSMDroid - 地图不显示
OSMDroid - Map does not display
我正在尝试在我的应用程序中加载开放式街道地图。
我的代码如下:
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);
}
}
确保您正确启用了运行时权限。您将需要外部存储和互联网存储。同时检查您的清单权限
这其实是一个奇怪的情况。 osmdroid 在第一次启动时会检测地图切片缓存的最大可写存储位置。如果找到 none,它应该默认为应用程序提供存储。我认为这不会发生在你的情况下,因为你没有调用这个
Configuration.getInstance().load(context, PreferenceManager.getDefaultSharedPreferences(context));
它可能需要在文档中有更多可见性,但这将启动发现过程。这应该在创建地图视图之前完成。
在此行之前添加下行setContentView(R.layout.activity_osm);
IConfigurationProvider provider = Configuration.getInstance();
provider.setUserAgentValue(BuildConfig.APPLICATION_ID);
provider.setOsmdroidBasePath(getStorage());
provider.setOsmdroidTileCache(getStorage());
我已经在 OpenStreetMap
下在 kotlin 平台中实现了并且它有效。
添加下面的行 build.gradle(应用级别)
implementation 'org.osmdroid:osmdroid-android:6.0.0'
Create LocationFragment.kt and paste the below code.
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
}
}
Use the below code in 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>
@shane 接受的答案为我指明了正确的方向。但是,权限请求发生了变化:
如果从 29 之前的版本迁移,您还必须包括对外部存储的旧权限 <application android:requestLegacyExternalStorage="true" ...
我正在尝试在我的应用程序中加载开放式街道地图。
我的代码如下:
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);
}
}
确保您正确启用了运行时权限。您将需要外部存储和互联网存储。同时检查您的清单权限
这其实是一个奇怪的情况。 osmdroid 在第一次启动时会检测地图切片缓存的最大可写存储位置。如果找到 none,它应该默认为应用程序提供存储。我认为这不会发生在你的情况下,因为你没有调用这个
Configuration.getInstance().load(context, PreferenceManager.getDefaultSharedPreferences(context));
它可能需要在文档中有更多可见性,但这将启动发现过程。这应该在创建地图视图之前完成。
在此行之前添加下行setContentView(R.layout.activity_osm);
IConfigurationProvider provider = Configuration.getInstance();
provider.setUserAgentValue(BuildConfig.APPLICATION_ID);
provider.setOsmdroidBasePath(getStorage());
provider.setOsmdroidTileCache(getStorage());
我已经在 OpenStreetMap
下在 kotlin 平台中实现了并且它有效。
添加下面的行 build.gradle(应用级别)
implementation 'org.osmdroid:osmdroid-android:6.0.0'
Create LocationFragment.kt and paste the below code.
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
}
}
Use the below code in 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>
@shane 接受的答案为我指明了正确的方向。但是,权限请求发生了变化:
如果从 29 之前的版本迁移,您还必须包括对外部存储的旧权限 <application android:requestLegacyExternalStorage="true" ...