注意:

  • 本文在编译过程中所有准备的版本都是64位。
  • 本文是在一台新安装的Ubuntu系统上进行编译(可以是实体机或虚拟机)。
  • 本文gdal-2.1.4编译后的so文件必须运行在Android 5.0及以上,且CPU为ARM的Android设备上。
  • 如需运行在低版本的Android上,可降低gdal的版本。
  • 如需运行在CPU为x86的平台上,可设置编译采用x86。
  • 编译出的so文件支持中文的读写(恭喜我吧,成功找到了方法)。

一、准备工作

  • 1、Ubuntu 16.04 LTS

下载地址:
http://www.ubuntu.org.cn/download/desktop

  • 2、android-ndk-r14b

下载地址:
https://developer.android.com/ndk/downloads/index.html

  • 3、gdal-2.1.4

下载地址:
https://trac.osgeo.org/gdal/wiki/DownloadSource
备注:原本想用2.2.2版本的,但是在交叉编译时报一个to_string方法未公开的错,因此选择了2.1.4这个版本。

二、编译环境搭建

  • 1、安装 g++,swig, ant和openjdk
sudo apt-get updatesudo apt-get install g++sudo apt-get install swigsudo apt-get install antsudo apt-get install openjdk-8-jdk
  • 2、NDK环境搭建

将下载好的NDK解压到某个路径下,并配置环境变量。本文通过修改/etc/profile文件来进行配置。

打开配置文件(后面不会再重复这步操作):

sudo gedit /etc/profile

末尾添加环境变量(具体的路径自行调整):

export NDK_HOME = /home/asen/Android/android-ndk-r14bexport PATH = $NDK_HOME:$PATH

执行下面的命令让环境变量立即生效(后面不会再重复这步操作):

source /etc/profile

测试环境变量,如果NDK的版本信息,就说明是配置正确:

ndk-build -v
  • 3、交叉编译的环境搭建

注意:这个是编译的关键部分,如不配置交叉编译,后面的.a文件没法通过ndk-build。

新建如下Shell脚本,名为make_toolchain.sh:

#!/bin/bashexport NDK_HOME=/home/asen/Android/android-ndk-r14bplatform=android-21shmake=$NDK_HOME/build/tools/make-standalone-toolchain.sharchs=(    'arm'    'arm64'    'x86'    'x86_64'    'mips'    'mips64')toolchains=(    'arm-linux-androideabi-4.9'    'aarch64-linux-android-4.9'    'x86-4.9'    'x86_64-4.9'    'mipsel-linux-android-4.9'    'mips64el-linux-android-4.9')echo $NDK_HOMEnum=${#archs[@]}for ((i=0;i<$num;i++))do   sh $shmake --arch=${archs[i]} --platform=$platform --install-dir=$HOME/Android/android-toolchain/${archs[i]} --toolchain=${toolchains[i]}done

执行这个shell脚本,执行后会在$HOME/Android/android-toolchain路径下生成android-toolchain文件夹:

bash make_toolchain.sh

配置交叉编译的环境变量(此处先以arm进行编译,可自行更改为android-toolchain中的其他文件夹):

export TOOLCHAIN_HOME=/home/asen/Android/android-toolchain/armexport PATH=$TOOLCHAIN_HOME/bin:$PATHexport LIBS="-lstdc++ -liconv -lgnustl_shared"export CC=arm-linux-androideabi-gccexport CXX=arm-linux-androideabi-g++export CXXFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"export CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"export LDFLAGS="-march=armv7-a -Wl,--fix-cortex-a8"

此处需要重启电脑后生效,测试如下:

arm-linux-androideabi-gcc -v

gcc version 4.9 20140827 (prerelease) (GCC)
当显示gcc version 4.9.x 20150123 (prerelease) (GCC)版本时,则为正确(PS:因为本文下载的是这个版本),如果不是,请确认下系统中是否存在多个arm-linux-androideabi-gcc版本,可能会影响到后面的编译过程。

  • 4、将下载的gdal214.zip解压后待用

三、中文支持

此处需要修改gdal-2.1.4/ogr/ogrsf_frmts/shape/shape2ogr.cpp文件,这个问题我找了好多天了,网上没找到这方面的答案,最后只能去看源码。在此先为自己点个赞!
这可能不是最好的处理方式,如果谁发现了更好的解决方案的话,欢迎留言!

  • 1、修改SHPReadOGRFeature方法
    将方法中的
char *pszUTF8Field = CPLRecode( pszFieldVal, pszSHPEncoding, CPL_ENC_UTF8);

改成

char *pszUTF8Field = CPLRecode( pszFieldVal, CPL_ENC_UTF8, CPL_ENC_UTF8);
  • 2、修改SHPWriteOGRFeature方法
    将方法中的
pszEncoded = CPLRecode( pszStr, CPL_ENC_UTF8, pszSHPEncoding );

改成

pszEncoded = CPLRecode( pszStr, CPL_ENC_UTF8, CPL_ENC_UTF8 );

四、交叉编译

  • 1、执行.configure命令

进入gdal的解压路径下,打开Terminal,执行如下命令:

CFLAGS="-mthumb" CXXFLAGS="-mthumb" LIBS="-lsupc++ -lstdc++" ./configure --host=arm-linux-androideabi --prefix=/home/asen/gdal/Android --without-gif --with-threads --with-ogr --with-geos --with-libz=internal

可以增加 --without内容来减少部分不需要的驱动,如下:

CFLAGS="-mthumb" CXXFLAGS="-mthumb" LIBS="-lsupc++ -lstdc++" ./configure --prefix=/home/asen/gdal/Android --host=arm-linux-androideabi --with-unix-stdio-64=no --with-ogr --with-geos --with-hide-internal-symbols --with-libz=internal --with-threads --without-bsb --without-cfitsio --without-cryptopp --without-curl --without-dwgdirect --without-ecw --without-expat --without-fme --without-freexl --without-gif --without-gif --without-gnm --without-grass --without-grib --without-hdf4 --without-hdf5 --without-idb --without-ingres --without-jasper --without-jp2mrsid --without-jpeg --without-kakadu --without-libgrass --without-libkml --without-libtool --without-mrf --without-mrsid --without-mysql --without-netcdf --without-odbc --without-ogdi --without-openjpeg --without-pcidsk --without-pcraster --without-pcre --without-perl --without-pg --without-php --without-png --without-python --without-qhull --without-sde --without-sqlite3 --without-webp --without-xerces --without-xml2

具体--without的内容可参考官网地址:
https://trac.osgeo.org/gdal/wiki/BuildingOnUnixWithMinimizedDrivers

执行后,一定要在打印的内容中看到checking whether we are cross compiling... yes,才算成功。

  • 2、进行编译并安装,安装的路径在上面的--prefix=后面配置
makemake install
  • 3、生成java文件和需要的c、c++文件
cd swigmake ANDROID=yescd javamake ANDROID=yes

在编译java中的命令时,会出现如下错误:


报错内容.png
注释掉的部分.png

处理方法:删掉报错类中报错的地方,重新make ANDROID=yes。

五、编译Android能用的so文件

  • 1、新建jni文件夹

  • 2、拷贝源文件(注意:源文件的地址根据自己电脑的情况设置)

cd /home/asen/gdal/jni# copy library bin and wrappers:cp /home/asen/gdal/Android/lib/libgdal.a ./mkdir -p gdalcp -r /home/asen/gdal/Android/include gdal#copy wrapperscp /home/asen/gdal/gdal-2.1.4/swig/java/*_wrap.cpp ./cp /home/asen/gdal/gdal-2.1.4/swig/java/gdalconst_wrap.c ./# copy headerscp -r /home/asen/gdal/gdal-2.1.4/swig/java/org ../jniwrap/cp /home/asen/gdal/gdal-2.1.4/swig/java/gdal.jar ../jniwrap/

其中jniwrap为Java代码的源文件和jar包。

  • 3、创建Android.mk文件,并写入下面的内容
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := gdalLOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/gdal/includeLOCAL_SRC_FILES := libgdal.aLOCAL_EXPORT_LDLIBS := -lzinclude $(PREBUILT_STATIC_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := gdaljniLOCAL_SRC_FILES := gdal_wrap.cppLOCAL_STATIC_LIBRARIES := gdalinclude $(BUILD_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := gdalconstjniLOCAL_SRC_FILES := gdalconst_wrap.cLOCAL_STATIC_LIBRARIES := gdalinclude $(BUILD_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := ogrjniLOCAL_SRC_FILES := ogr_wrap.cppLOCAL_STATIC_LIBRARIES := gdalinclude $(BUILD_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := osrjniLOCAL_SRC_FILES := osr_wrap.cppLOCAL_STATIC_LIBRARIES := gdalinclude $(BUILD_SHARED_LIBRARY)
  • 4、创建Application.mk文件,并写入下面的内容
APP_STL := gnustl_staticAPP_CFLAGS := Android.mkAPP_ABI := armeabi-v7aAPP_PLATFORM := android-21
  • 5、进行编译
ndk-build
  • 6、编译成功

保存的路径在jni文件夹所在的路径。


编译成功.png

六、Android Studio测试

  • 1、新建Android项目,并拷贝编译好的文件
项目结构.png
  • 2、运行结果截图
运行结果.png
  • 3、QGIS中查看shp文件

首先需要将编码方式改成UTF-8。


QGIS中查看.png

七、Github地址

https://github.com/houlian0/GdalAndroid

参考文章

https://github.com/nutiteq/gdal/wiki/AndroidHowto

http://www.c2001.net/uploads/9/9/0/8/9908187/gdal.pdf

http://www.jianshu.com/p/07e3af759c86

http://www.jianshu.com/p/51c645543a02

更多相关文章

  1. android studio 的自动添加依赖过程简介(适用于android studio 任
  2. Android(安卓)文件IO操作
  3. Android(安卓)上的 Chrome 终于,即将,就要,支持文件上传(input type=
  4. Android(安卓)Studio apk打包,keystore.jks文件生成,根据keystore
  5. 【Android】Android中用代码复制文件的大小限制
  6. [Android]反编译查看、修改源码、逆向分析以及二次打包签名
  7. Android中如何通过文件路径判断是否是同一文件
  8. 修改Android中strings.xml文件, 动态改变数据
  9. Android(安卓)Studio官方文档之使用Lint提高你的代码质量篇

随机推荐

  1. android之view获取getWidth()和getHeight
  2. 〖Android〗Android(安卓)App项目资源字
  3. ANdroid之蓝牙
  4. Android应用程序请求SurfaceFlinger服务
  5. Android(安卓)Lollipop
  6. 浅谈android的selector,背景选择器
  7. 详解Android应用开发中Intent的作用及使
  8. 浅谈android的selector背景选择器(ListVie
  9. Android(安卓)6.0 MTP(一) 框架
  10. Android应用市场付费比例35% 天气应用最