前言
闲着无聊,安装了Android Studio 回忆一下Android开发,当打开Android Studio时,那种熟悉的感觉又回来了。之前了解到 osmdroid 的功能很强大,于是就想尝试一下。希望本文可以给想学习的小白提供一些参考。
osmdroid简介
osmdroid 是(几乎)完全/免费的Android的MapView(v1 API)类的替代品。 它还包括一个模块化的图块提供程序系统,该系统提供对许多在线和离线图块源的支持,并通过内置的覆盖图(用于绘制图标,跟踪位置和绘制形状)来支持覆盖图。
实现效果图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JMS2fRWZ-1596354708682)(./images/osmdroid.png)]
实现步骤
-
使用 Android Studio 新建一个带 Basic Activity 的项目模板,点击 Next
-
设置项目名、包名、项目路径、开发语言、支持的最小SDK。然后点击 Finish
-
项目结构
-
添加阿里依赖仓库(顺便解决 gradle 构建缓慢的问题)
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { maven { url 'https://maven.aliyun.com/repository/public/' } mavenLocal() mavenCentral() google() jcenter() } dependencies { classpath "com.android.tools.build:gradle:4.0.1" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { maven { url 'https://maven.aliyun.com/repository/public/' } mavenLocal() mavenCentral() google() jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }
提 示 : \color{orange}{提示:} 提示: 添加 maven 配置后 点击 Sync Now 同步
-
添加 osmdroid 函数库
implementation 'org.osmdroid:osmdroid-android:6.1.8'
-
在 AndroidManifest.xml 中添加权限
<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" />
-
添加布局 (layout)
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" tools:context=".FirstFragment"> <org.osmdroid.views.MapView android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="fill_parent" tools:ignore="MissingConstraints" /> </androidx.constraintlayout.widget.ConstraintLayout>
-
修改 Activity
package com.example.myapplication; import android.Manifest; import android.content.Context; import android.content.pm.PackageManager; import android.os.Bundle; import android.preference.PreferenceManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.navigation.fragment.NavHostFragment; import org.osmdroid.api.IMapController; import org.osmdroid.config.Configuration; import org.osmdroid.tileprovider.tilesource.TileSourceFactory; import org.osmdroid.util.GeoPoint; import org.osmdroid.views.MapView; import java.util.ArrayList; public class FirstFragment extends Fragment { private final int REQUEST_PERMISSIONS_REQUEST_CODE = 1; private MapView map = null; @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_first, container, false); } @Override public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); //handle permissions first, before map is created. not depicted here //load/initialize the osmdroid configuration, this can be done Context ctx = getContext(); Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx)); //setting this before the layout is inflated is a good idea //it 'should' ensure that the map has a writable location for the map cache, even without permissions //if no tiles are displayed, you can try overriding the cache path using Configuration.getInstance().setCachePath //see also StorageUtils //note, the load method also sets the HTTP User Agent to your application's package name, abusing osm's //tile servers will get you banned based on this string //inflate and create the map setTargetFragment(this.getTargetFragment(), REQUEST_PERMISSIONS_REQUEST_CODE); map = (MapView) view.findViewById(R.id.map); map.setTileSource(TileSourceFactory.MAPNIK); map.setBuiltInZoomControls(true); map.setMultiTouchControls(true); IMapController mapController = map.getController(); mapController.setZoom(9.5); GeoPoint startPoint = new GeoPoint(48.8583, 2.2944); mapController.setCenter(startPoint); requestPermissionsIfNecessary(new String[] { // if you need to show the current location, uncomment the line below // Manifest.permission.ACCESS_FINE_LOCATION, // WRITE_EXTERNAL_STORAGE is required in order to show the map Manifest.permission.WRITE_EXTERNAL_STORAGE }); } @Override public void onResume() { super.onResume(); //this will refresh the osmdroid configuration on resuming. //if you make changes to the configuration, use //SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); //Configuration.getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(this)); map.onResume(); //needed for compass, my location overlays, v6.0.0 and up } @Override public void onPause() { super.onPause(); //this will refresh the osmdroid configuration on resuming. //if you make changes to the configuration, use //SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); //Configuration.getInstance().save(this, prefs); map.onPause(); //needed for compass, my location overlays, v6.0.0 and up } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { ArrayList<String> permissionsToRequest = new ArrayList<>(); for (int i = 0; i < grantResults.length; i++) { permissionsToRequest.add(permissions[i]); } if (permissionsToRequest.size() > 0) { ActivityCompat.requestPermissions( this.getActivity(), permissionsToRequest.toArray(new String[0]), REQUEST_PERMISSIONS_REQUEST_CODE); } } private void requestPermissionsIfNecessary(String[] permissions) { ArrayList<String> permissionsToRequest = new ArrayList<>(); for (String permission : permissions) { if (ContextCompat.checkSelfPermission(this.getActivity(), permission) != PackageManager.PERMISSION_GRANTED) { // Permission is not granted permissionsToRequest.add(permission); } } if (permissionsToRequest.size() > 0) { ActivityCompat.requestPermissions( this.getActivity(), permissionsToRequest.toArray(new String[0]), REQUEST_PERMISSIONS_REQUEST_CODE); } } }
源码包
参考文献
osmdroid github上的源码 点击这里获取源码
osmdroid gitee上的源码 点击这里快速获取源码
阿里云仓库