SuperMap iMobile+Android studio开发入门(二)——超图示例代码运行

发布于:2022-11-09 ⋅ 阅读:(808) ⋅ 点赞:(0)

背景:这里运行的是“产品入门”的“基于Android studio开发移动GIS程序”的“开发三维移动GIS程序”,本篇对超图帮助文档进行了完善,对于部分用户的闪退问题做出了解决,可以对照超图文档一起学习。

(一)创建工程

(1)在 Android Studio 起始页选择【Create new Project】。

(2)选择项目模板 根据项目实际情况选择对应的模板,点击【Next】。本向导中选择【Phone and Tablet】选项卡中的【Empty Activity】。

(3)配置项目:依次填写项目属性,其中Language 选择【Java】。填写完成后,点击【Finish】。

(二)使用 SuperMap iMobile

(1)添加库文件

库文件在产品包 libs 文件夹下,根据功能需要,从 libs 文件夹中选择需要的库文件拷贝到工程的 libs 文件夹下。这里用到“核心模块库文件 com.supermap.data_v1100.jar”和“三维显示模块库文件 com.supermaprealspace_v1100.jar”。

选中上步中添加的 jar 文件,右键-> add as library,如下图所示

 

(2)添加 so 依赖

将三维示例要用的的 libimb_v1100.so 文件放入工程的"libs\armeabi-v7a"文件夹中。

这里要注意的一个问题是导入so依赖包的时候,要带着文件夹“armeabi-v7a”一起导入,并且文件夹名称最好是不要改动,后面需要用到。

(这两步中为了省事我把整个libs文件夹替换了)

 在 Module 的 build.gradle 添加 jni 的 sourceSets 配置:jniLibs.srcDirs = ['libs'],在 defaultConfig 下 添加 ndk 设置:abiFilters 'armeabi-v7a'。参考代码如下:

android {
compileSdkVersion 28
buildToolsVersion "29.0.3" defaultConfig {
applicationId "com.example.supermapimobile2d" minSdkVersion 23
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
//手动添加
ndk {
abiFilters 'armeabi-v7a' }
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
'proguard-rules.pro'
}
}
//手动添加
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

这里我把文档里面的sdk29改成了28,后面帖子会说明原因。

(3)添加最低权限

双击“AndroidManifest.xml”,打开工程配置文件,在里面添加必备权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Android 6.0 系统在原有 AndroidManifest.xml 声明权限的基础上新增运行时权限动态检测,定位等权限 也包含在其中。

Android 6.0 系统默认为 targetSdkVersion 小于 23 的应用授予申请的所有权限,所以 App 设置的 targetSdkVersion 低于 23,运行时不会崩溃。

(4)添加activity配置

在“AndroidManifest.xml”中,承载 MapControl 的 Activity 项目中添加 Activity 配置,让地图界面 在横竖屏切换时不再重复调用 onCreate。代码如下: 

android:configChanges="keyboardHidden|orientation|screenSize"

(5)支持多格式屏幕配置

在 AndroidManifest.xml 的 manifest 节点下添加以下配置:

<supports-screens
android:largeScreens="true" 
android:resizeable="true" 
android:normalScreens="true" 
android:anyDensity="true"/>

(6)编写代码

在布局文件 activity_main.xml 中添加场景控件,代码如下:

<com.supermap.realspace.SceneControl
android:id="@+id/SceneControl" 
android:layout_width="match_parent" 
android:layout_height="match_parent"/>

并添加button按钮如下:

   <Button
       android:id="@+id/btn_open"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentBottom="true"
       android:layout_alignParentEnd="true"
       android:layout_marginBottom="22dp"
       android:layout_marginEnd="28dp"
       android:text="@string/打开离线场景"/>

在 MainActivity 中编写应用程序代码如下:

package com.example.supermapimobile3d;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.view.View.OnClickListener;
import android.view.View;
import com.supermap.data.Environment;
import com.supermap.data.Workspace;
import com.supermap.data.WorkspaceConnectionInfo;
import com.supermap.data.WorkspaceType;
import com.supermap.realspace.Scene;
import com.supermap.realspace.SceneControl;
public class MainActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String sdcard =
android.os.Environment.getExternalStorageDirectory().getAbsolutePath().toString();
Environment.setLicensePath(sdcard + "/SuperMap/license/");
Environment.initialization(this);
setContentView(R.layout.activity_main);
Button btnOpen = (Button)findViewById(R.id.btn_open);
btnOpen.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//打开工作空间
Workspace workspace = new Workspace();
WorkspaceConnectionInfo info = new WorkspaceConnectionInfo();
info.setServer(sdcard+"/SampleData/CBD_android/CBD_android.sxwu");
info.setType(WorkspaceType.SXWU);
workspace.open(info);
//场景显示控件与工作空间相关联
SceneControl sceneControl = (SceneControl)findViewById(R.id.SceneControl);
Scene scene = sceneControl.getScene();
scene.setWorkspace(workspace);
//打开场景
String sceneName = workspace.getScenes().get(0);
scene.open(sceneName);
}
});
}
}

ps:这里要注意两个点,在文档里没有特别说明,不过一般大家也都能够看的出来。

(使用真机模拟:手机用数据线连接电脑,调成“文件传输模式”,打开手机“开发者模式”,不同手机打开方法不同,可以自行百度打开。最后在开发者模式里面,打开usb调试。)

第一,许可位置。在手机根目录也就是内部存储下面新建文件夹SuperMap,在里面新建文件夹license,将申请的试用许可放在这里。(许可申请可以查看官方文档,很简单。)

第二,地图数据位置。可以看到代码里用的是(sdcard+"/SampleData/CBD_android/CBD_android.sxwu"),可以到超图给的示例数据与示例代码中找到这个地图数据(下载软件的时候会带的),我的在这个位置。把这个文件夹放到手机根目录的SampleData文件夹下面的CBD_android文件夹里面。(没有就新建,不然改路径名称也行,对应好就可以)。

(7)运行程序

这个时候就可以运行了,但是一般来说是会闪退的。超图的文档就给到这里,很不友好。原因是没有授予app访问手机文件的权限,自然也就获取不了工程许可以及地图数据。

解决办法1:

手动给app访问所有文件的权限。

解决办法2:

编写代码实现app运行弹窗选择权限。

代码如下:

   private void requestPermissions() { //Android6.0以上设备设置动态权限
    if (Build.VERSION.SDK_INT >= 23) {
        // 检查是否拥有权限
        String[] permissions = {
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.READ_PHONE_STATE,
                Manifest.permission.ACCESS_WIFI_STATE,
                Manifest.permission.ACCESS_NETWORK_STATE,
                Manifest.permission.CHANGE_WIFI_STATE,
        };

        String permission = null;
        int id = 0;
        boolean isBreak = false;
        int checkCallPhonePermission = 0;
        for (int i = 0; i < permissions.length; i++) {
            permission = permissions[i];
            checkCallPhonePermission = checkSelfPermission(permission);
            if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(permissions, id);
                isBreak = true;
                break;
            }
        }
    }

}

在oncreate里面调用一下requestPermissions();即可。

----------------------------------到这里应该就可以成功运行啦------------------------------------

本文含有隐藏内容,请 开通VIP 后查看