32
build.gradle
@ -1,8 +1,21 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
maven { url 'https://maven.aliyun.com/repository/public/' }
|
||||
maven { url 'https://maven.aliyun.com/repository/google/' }
|
||||
maven { url 'https://maven.aliyun.com/repository/gradle-plugin/' }
|
||||
maven { url 'https://dl.bintray.com/ppartisan/maven/' }
|
||||
maven { url "https://clojars.org/repo/" }
|
||||
maven { url "https://jitpack.io" }
|
||||
mavenCentral()
|
||||
google()
|
||||
mavenLocal()
|
||||
// Nexus Maven 库地址
|
||||
// "WinBoll Release"
|
||||
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
|
||||
// "WinBoll Snapshot"
|
||||
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
|
||||
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.2.1'
|
||||
@ -13,11 +26,12 @@ buildscript {
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
// Nexus Maven 库地址
|
||||
// "WinBoll Release"
|
||||
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
|
||||
// "WinBoll Snapshot"
|
||||
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
|
||||
maven {
|
||||
url "https://mirrors.tencent.com/repository/maven/tencent_public/"
|
||||
}
|
||||
maven {
|
||||
url "https://mirrors.tencent.com/repository/maven/tencent_public_snapshots"
|
||||
}
|
||||
|
||||
maven { url 'https://maven.aliyun.com/repository/public/' }
|
||||
maven { url 'https://maven.aliyun.com/repository/google/' }
|
||||
@ -28,6 +42,12 @@ allprojects {
|
||||
mavenCentral()
|
||||
google()
|
||||
mavenLocal()
|
||||
// Nexus Maven 库地址
|
||||
// "WinBoll Release"
|
||||
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
|
||||
// "WinBoll Snapshot"
|
||||
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
|
||||
|
||||
}
|
||||
ext {
|
||||
// 定义全局变量,常用于版本管理
|
||||
|
@ -6,7 +6,7 @@
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx2048m
|
||||
org.gradle.jvmargs=-Xmx4096m
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
@ -18,7 +18,9 @@ android.useAndroidX=true
|
||||
# Automatically convert third-party libraries to use AndroidX
|
||||
android.enableJetifier=true
|
||||
|
||||
#org.gradle.caching=true
|
||||
org.gradle.caching=true
|
||||
|
||||
android.disableAutomaticComponentCreation=true
|
||||
|
||||
android.injected.testOnly=false
|
||||
|
||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https://services.gradle.org/distributions/gradle-7.5-all.zip
|
||||
distributionUrl = https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
BIN
positions/.DS_Store
vendored
Normal file
39
positions/README.md
Normal file
@ -0,0 +1,39 @@
|
||||
# Positions
|
||||
|
||||
#### 介绍
|
||||
位置应用,与卫星定位有关的应用。可以根据设定的位置与时间条件判断,来发送通知的应用。
|
||||
|
||||
#### 软件架构
|
||||
以腾讯位置服务SDK源码为基础。源码地址:https://lbs.qq.com/mobile/androidMapSDK/developerGuide/configuration
|
||||
适配安卓应用 [AIDE Pro] 的 Gradle 编译结构。
|
||||
也适配安卓应用 [AndroidIDE] 的 Gradle 编译结构。
|
||||
|
||||
|
||||
#### Gradle 编译说明
|
||||
调试版编译命令 :gradle assembleBetaDebug
|
||||
阶段版编译命令 :gradle assembleStageRelease
|
||||
|
||||
#### 使用说明
|
||||
|
||||
在安卓系统中需要设置两个权限允许。
|
||||
1.自启动权限允许。
|
||||
2.省电策略-无限制权限允许。
|
||||
|
||||
#### 参与贡献
|
||||
|
||||
1. Fork 本仓库
|
||||
2. 新建 Feat_xxx 分支
|
||||
3. 提交代码 : ZhanGSKen(ZhanGSKen@AliYun.Com)
|
||||
4. 新建 Pull Request
|
||||
|
||||
|
||||
#### 特技
|
||||
|
||||
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
|
||||
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
|
||||
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
|
||||
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
|
||||
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
|
||||
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
|
||||
#### 参考文档
|
0
positions/app_update_description.txt
Normal file
84
positions/build.gradle
Normal file
@ -0,0 +1,84 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply from: '../.winboll/winboll_app_build.gradle'
|
||||
apply from: '../.winboll/winboll_lint_build.gradle'
|
||||
|
||||
def genVersionName(def versionName){
|
||||
// 检查编译标志位配置
|
||||
assert (winbollBuildProps['stageCount'] != null)
|
||||
assert (winbollBuildProps['baseVersion'] != null)
|
||||
// 保存基础版本号
|
||||
winbollBuildProps.setProperty("baseVersion", "${versionName}");
|
||||
//保存编译标志配置
|
||||
FileOutputStream fos = new FileOutputStream(winbollBuildPropsFile)
|
||||
winbollBuildProps.store(fos, "${winbollBuildPropsDesc}");
|
||||
fos.close();
|
||||
|
||||
// 返回编译版本号
|
||||
return "${versionName}." + winbollBuildProps['stageCount']
|
||||
}
|
||||
|
||||
Properties properties = new Properties()
|
||||
File localFile = project.rootProject.file('local.properties')
|
||||
if (localFile.exists()) {
|
||||
InputStream inputStream = localFile.newDataInputStream()
|
||||
properties.load(inputStream)
|
||||
}
|
||||
|
||||
def mapsdkkey = properties.getProperty('mapsdk.key', "")
|
||||
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion "30.0.3"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "cc.winboll.studio.positions"
|
||||
minSdkVersion 26
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
// versionName 更新后需要手动设置
|
||||
// 项目模块目录的 build.gradle 文件的 stageCount=0
|
||||
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
|
||||
versionName "1.0"
|
||||
if(true) {
|
||||
versionName = genVersionName("${versionName}")
|
||||
}
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
manifestPlaceholders = ["TencentMapSDK_KEY": mapsdkkey]
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// 定位服务
|
||||
implementation 'com.google.android.gms:play-services-location:20.0.0'
|
||||
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'androidx.viewpager:viewpager:1.0.0'
|
||||
implementation 'androidx.fragment:fragment:1.0.0'
|
||||
implementation 'com.google.android.material:material:1.4.0'
|
||||
implementation 'pub.devrel:easypermissions:2.0.1'
|
||||
// 地图
|
||||
implementation 'com.tencent.map:tencent-map-vector-sdk:6.2.1.250120.3f971009.140342819'
|
||||
// 基础库
|
||||
implementation 'com.tencent.openmap:foundation:0.5.6.9be4e02'
|
||||
implementation 'com.tencent.map:sdk-utilities:1.0.9'
|
||||
implementation 'com.tencent.map.geolocation:TencentLocationSdk-openplatform:7.5.4.3'
|
||||
implementation 'com.google.code.gson:gson:2.8.5'
|
||||
|
||||
implementation 'io.github.medyo:android-about-page:2.0.0'
|
||||
implementation 'com.github.getActivity:ToastUtils:10.5'
|
||||
|
||||
implementation 'cc.winboll.studio:libapputils:9.3.2'
|
||||
implementation 'cc.winboll.studio:libappbase:1.5.6'
|
||||
}
|
8
positions/build.properties
Normal file
@ -0,0 +1,8 @@
|
||||
#Created by .winboll/winboll_app_build.gradle
|
||||
#Tue Feb 25 05:04:52 GMT 2025
|
||||
stageCount=0
|
||||
libraryProject=
|
||||
baseVersion=1.0
|
||||
publishVersion=1.0.0
|
||||
buildCount=184
|
||||
baseBetaVersion=1.0.1
|
41
positions/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
-dontwarn com.tencent.bugly.**
|
||||
-keep public class com.tencent.bugly.**{*;}
|
||||
|
||||
-dontwarn com.tencent.tmsqmsp.**
|
||||
-keep public class com.tencent.tmsqmsp.**{*;}
|
||||
|
||||
-dontwarn com.tencent.tmsbeacon.**
|
||||
-keep public class com.tencent.tmsbeacon.**{*;}
|
||||
|
||||
-dontwarn com.tencent.map.**
|
||||
-keep public class com.tencent.map.** {*;}
|
||||
|
||||
-dontwarn com.tencent.mapsdk.**
|
||||
-keep public class com.tencent.mapsdk.** {*;}
|
||||
|
||||
-dontwarn com.tencent.tencentmap.**
|
||||
-keep public class com.tencent.tencentmap.** {*;}
|
||||
|
||||
-dontwarn com.tencent.lbssearch.**
|
||||
-keep public class com.tencent.lbssearch.** {*;}
|
BIN
positions/src/.DS_Store
vendored
Normal file
13
positions/src/beta/AndroidManifest.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools" >
|
||||
|
||||
<application
|
||||
tools:replace="android:icon"
|
||||
android:icon="@drawable/ic_winbollbeta">
|
||||
|
||||
<!-- Put flavor specific code here -->
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
6
positions/src/beta/res/values/strings.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="app_name">Positions+</string>
|
||||
|
||||
</resources>
|
BIN
positions/src/main/.DS_Store
vendored
Normal file
741
positions/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,741 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="cc.winboll.studio.positions">
|
||||
|
||||
<!-- 拥有完全的网络访问权限 -->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
||||
<!-- 查看网络连接 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
|
||||
<!-- 查看WLAN连接 -->
|
||||
<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_EXTERNAL_STORAGE"/>
|
||||
|
||||
<!-- 读取手机状态和身份 -->
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
|
||||
<!-- 只能在前台获取精确的位置信息 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
|
||||
<!-- 只能在前台获取大概位置(基于网络) -->
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
|
||||
<!-- 连接WLAN网络和断开连接 -->
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
|
||||
|
||||
<!-- 更改网络连接性 -->
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/MyAppTheme"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
tools:ignore="AllowBackup,GoogleAppIndexingWarning"
|
||||
tools:targetApi="q">
|
||||
|
||||
<activity android:name=".MainSimpleActivity">
|
||||
|
||||
<intent-filter>
|
||||
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity android:name=".MainActivity2">
|
||||
|
||||
</activity>
|
||||
|
||||
<activity android:name="com.tencent.map.vector.demo.DemoMainActivity">
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.tencent.map.vector.demo.basic.MapViewActivity"
|
||||
android:description="@string/demo_description_show_map"
|
||||
android:label="@string/demo_label_show_map">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_basic"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".basic.SetMapTypeActivity"
|
||||
android:description="@string/demo_description_map_type"
|
||||
android:label="@string/demo_label_map_type">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_basic"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".basic.MapRenderLayerActivity"
|
||||
android:description="@string/demo_description_show_mapRenderLayer"
|
||||
android:label="@string/demo_label_show_mapRenderLayer">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_basic"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".location.LocationLayerActivity"
|
||||
android:description="@string/demo_description_show_location"
|
||||
android:label="@string/demo_label_show_location">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_location"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".location.LocationPointActivity"
|
||||
android:description="@string/demo_description_change_location_style"
|
||||
android:label="@string/demo_label_change_location_style">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_location"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".basic.IndoorMapActivity"
|
||||
android:description="@string/demo_description_indoor_map"
|
||||
android:label="@string/demo_label_indoor_map">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_basic"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".basic.OverseaMapActivity"
|
||||
android:description="@string/demo_description_oversea"
|
||||
android:label="@string/demo_label_oversea">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_basic"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".basic.MapStyleDemoActivity"
|
||||
android:description="@string/demo_description_style"
|
||||
android:label="@string/demo_label_style">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_basic"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".basic.UiSettingsActivity"
|
||||
android:description="@string/demo_description_ui"
|
||||
android:label="@string/demo_label_ui">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_interactive"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".gesture.GestureSettingsActivity"
|
||||
android:description="@string/demo_description_gesture"
|
||||
android:label="@string/demo_label_gesture">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_interactive"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".transaction.ZoomMapActivity"
|
||||
android:description="@string/demo_description_modify_zoom"
|
||||
android:label="@string/demo_label_modify_zoom">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_interactive"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".camera.MapCameraCenterActivity"
|
||||
android:description="@string/demo_description_modify_map_center"
|
||||
android:label="@string/demo_label_modify_map_center">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_interactive"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".camera.MapBoundActivity"
|
||||
android:description="@string/demo_description_map_bound"
|
||||
android:label="@string/demo_label_map_bound">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_interactive"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".poi.PoiClickActivity"
|
||||
android:description="@string/demo_description_click_poi"
|
||||
android:label="@string/demo_label_click_poi">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_interactive"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".transaction.AnimateCameraActivity"
|
||||
android:description="@string/demo_description_animate_camera"
|
||||
android:label="@string/demo_label_animate_camera">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_interactive"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".camera.MapAnchorZoomActivity"
|
||||
android:description="@string/demo_description_map_camera_anchor"
|
||||
android:label="@string/demo_label_map_camera_anchor">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_interactive"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".transaction.ScollMapActivity"
|
||||
android:description="@string/demo_description_camera_translation"
|
||||
android:label="@string/demo_label_camera_translation">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_transformation"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".transaction.RotateMapActivity"
|
||||
android:description="@string/demo_description_camera_rotation"
|
||||
android:label="@string/demo_label_camera_rotation">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_transformation"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".transaction.ZoomCalulateActivity"
|
||||
android:description="@string/demo_description_camera_include_points"
|
||||
android:label="@string/demo_label_camera_include_points">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_transformation"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".transaction.MoveCameraActivity"
|
||||
android:description="@string/demo_description_camera_change_listener"
|
||||
android:label="@string/demo_label_camera_change_listener">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_transformation"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".gesture.MapListenActivity"
|
||||
android:description="@string/demo_description_map_click_listener"
|
||||
android:label="@string/demo_label_map_click_listener">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_transformation"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".gesture.MapLongClickActivity"
|
||||
android:description="@string/demo_description_map_long_click_listener"
|
||||
android:label="@string/demo_label_map_long_click_listener">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_transformation"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".marker.SimpleMarkerActivity"
|
||||
android:description="@string/demo_description_simple_marker"
|
||||
android:label="@string/demo_label_simple_marker">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_marker"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".marker.MarkerCollisions"
|
||||
android:description="@string/demo_description_collisions_marker"
|
||||
android:label="@string/demo_label_collisions_marker">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_marker"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".marker.MarkerOptionsActivity"
|
||||
android:description="@string/demo_description_marker_options"
|
||||
android:label="@string/demo_label_marker_options">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_marker"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".marker.MarkerClickActivity"
|
||||
android:description="@string/demo_description_marker_click_listener"
|
||||
android:label="@string/demo_label_marker_click_listener">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_marker"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".marker.MarkerDragActivity"
|
||||
android:description="@string/demo_description_marker_drag_listener"
|
||||
android:label="@string/demo_label_marker_drag_listener">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_marker"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".marker.MarkerInfoWindowActivity"
|
||||
android:description="@string/demo_description_infowindow_click_listener"
|
||||
android:label="@string/demo_label_infowindow_click_listener">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_marker"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".marker.MarkerClusterActivity"
|
||||
android:description="@string/demo_description_marker_cluster"
|
||||
android:label="@string/demo_label_marker_cluster">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_marker"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".marker.MarkerAnimation"
|
||||
android:description="@string/demo_description_marker_animation"
|
||||
android:label="@string/demo_label_marker_animation">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_marker"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".heatoverlay.DrawHeatOverlayActivity"
|
||||
android:description="@string/demo_description_heat_map"
|
||||
android:label="@string/demo_label_heat_map">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".polygon.TileOverlayActivity"
|
||||
android:description="@string/demo_description_tileOverlay_map"
|
||||
android:label="@string/demo_label_tileOverlay_map">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".polyline.DrawLineActivity"
|
||||
android:description="@string/demo_description_polyline"
|
||||
android:label="@string/demo_label_polyline">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".polyline.MutablePolylineActivity"
|
||||
android:description="@string/demo_description_mutable_polyline"
|
||||
android:label="@string/demo_label_mutable_polyline">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".polygon.DrawPolygonActivity"
|
||||
android:description="@string/demo_description_polygon"
|
||||
android:label="@string/demo_label_polygon">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".circle.DrawCircleActivity"
|
||||
android:description="@string/demo_description_circle"
|
||||
android:label="@string/demo_label_circle">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".circle.ArcActivity"
|
||||
android:description="@string/demo_description_arc"
|
||||
android:label="@string/demo_label_arc">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".search.WalkingRouteActivity"
|
||||
android:description="@string/demo_description_walking_plan"
|
||||
android:label="@string/demo_label_walking_plan">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_route_plan"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".search.DrivingRouteActivity"
|
||||
android:description="@string/demo_description_driving_plan"
|
||||
android:label="@string/demo_label_driving_plan">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_route_plan"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".search.TransitRouteActivity"
|
||||
android:description="@string/demo_description_transit_plan"
|
||||
android:label="@string/demo_label_transit_plan">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_route_plan"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".search.TruckingRouteActivity"
|
||||
android:description="@string/demo_description_truking_plan"
|
||||
android:label="@string/demo_label_truking_plan">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_route_plan"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".search.SearchBasicActivity"
|
||||
android:description="@string/demo_description_basic_search"
|
||||
android:label="@string/demo_label_basic_search">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_search"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".search.GeoCoderActivity"
|
||||
android:description="@string/demo_description_geocoder"
|
||||
android:label="@string/demo_label_geocoder">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_search"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".search.DistrictActivity"
|
||||
android:description="@string/demo_description_district"
|
||||
android:label="@string/demo_label_district">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_search"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".polyline.LineTextActivity"
|
||||
android:description="@string/demo_description_line_text"
|
||||
android:label="@string/demo_label_line_text">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_special"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".utils.BitMapActivity"
|
||||
android:description="@string/demo_description_bitmap"
|
||||
android:enabled="false"
|
||||
android:label="@string/demo_label_bitmap">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_tools"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".utils.SnapshotActivity"
|
||||
android:description="@string/demo_description_map_snapshot"
|
||||
android:label="@string/demo_label_map_snapshot">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_tools"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".utils.CoordinateActivity"
|
||||
android:description="@string/demo_description_projection"
|
||||
android:label="@string/demo_label_projection">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_tools"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity android:name=".basic.SupportMapFragmentActivity"/>
|
||||
|
||||
<activity
|
||||
android:name=".marker.CustomRenderActivity"
|
||||
android:description="@string/demo_description_opengl"
|
||||
android:label="@string/demo_label_opengl">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".marker.GroundOverlayActivity"
|
||||
android:description="@string/demo_description_overlay"
|
||||
android:label="@string/demo_label_ground_overlay">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".marker.AoiLayerActivity"
|
||||
android:description="@string/demo_description_aoi"
|
||||
android:label="@string/demo_label_aoi">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".heatoverlay.VectorHeatMapActivity"
|
||||
android:description="@string/demo_description_vectorheatmap"
|
||||
android:label="@string/demo_label_vectorheatmap">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".heatoverlay.ArcLineLayerActivity"
|
||||
android:description="@string/demo_description_arcline"
|
||||
android:label="@string/demo_label_arcline_map">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".heatoverlay.HeatMapVectorOverlayActivity"
|
||||
android:description="@string/demo_description_3dheatmap"
|
||||
android:label="@string/demo_label_3d_heat_map">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".heatoverlay.AggregationOverlayActivity"
|
||||
android:description="@string/demo_description_AggregationOverlay"
|
||||
android:label="@string/demo_label_3d_aggregationOverlay_map">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".heatoverlay.ScatterPlotOverlayActivity"
|
||||
android:description="@string/demo_description_ScatterPlotOverlay"
|
||||
android:label="@string/demo_label_3d_scatterplotoverlay_map">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".heatoverlay.TrailOverlayActivity"
|
||||
android:description="@string/demo_description_TrailOverlay"
|
||||
android:label="@string/demo_label_3d_railoverltay_map">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".heatoverlay.GLModelActivity"
|
||||
android:description="@string/demo_description_glModel"
|
||||
android:label="@string/demo_label_glModel">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".basic.RecyclerListActivity"
|
||||
android:description="@string/demo_description_recycler_map"
|
||||
android:label="@string/demo_label_recycler_map">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_basic"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".smooth.SmoothMoveActivity"
|
||||
android:description="@string/demo_description_smooth_move"
|
||||
android:label="@string/demo_label_smooth_move">
|
||||
|
||||
<meta-data
|
||||
android:name="@string/demo_type"
|
||||
android:value="@string/demo_type_draw"/>
|
||||
|
||||
</activity>
|
||||
|
||||
<meta-data
|
||||
android:name="TencentMapSDK"
|
||||
android:value="SCYBZ-EC5Y4-XMHUI-FX2PU-ZYMMS-IBB7P"/>
|
||||
|
||||
<activity android:name="cc.winboll.studio.positions.activities.TestMapViewActivity"/>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
BIN
positions/src/main/assets/21.jpg
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
positions/src/main/assets/22.jpg
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
positions/src/main/assets/23.jpg
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
positions/src/main/assets/24.jpg
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
positions/src/main/assets/25.jpg
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
positions/src/main/assets/26.jpg
Normal file
After Width: | Height: | Size: 6.4 KiB |
50
positions/src/main/assets/arc.dat
Normal file
@ -0,0 +1,50 @@
|
||||
31.23037 121.4737 40.07733 116.60039 45.0
|
||||
30.5702 104.06476 40.07733 116.60039 45.0
|
||||
22.54286 114.05956 40.07733 116.60039 45.0
|
||||
23.12908 113.26436 40.07733 116.60039 45.0
|
||||
29.56471 106.55073 40.07733 116.60039 45.0
|
||||
30.27415 120.15515 40.07733 116.60039 45.0
|
||||
24.87966 102.83322 40.07733 116.60039 45.0
|
||||
34.32932 108.70929 40.07733 116.60039 45.0
|
||||
45.80216 126.5358 40.07733 116.60039 45.0
|
||||
28.22778 112.93886 40.07733 116.60039 45.0
|
||||
18.25248 109.51209 40.07733 116.60039 45.0
|
||||
43.82663 87.61688 40.07733 116.60039 45.0
|
||||
30.59276 114.30525 40.07733 116.60039 45.0
|
||||
22.27534 114.16546 40.07733 116.60039 45.0
|
||||
26.64702 106.63024 40.07733 116.60039 45.0
|
||||
24.47951 118.08948 40.07733 116.60039 45.0
|
||||
20.04422 110.19989 40.07733 116.60039 45.0
|
||||
28.68202 115.85794 40.07733 116.60039 45.0
|
||||
43.81602 125.32357 40.07733 116.60039 45.0
|
||||
36.06623 120.38299 40.07733 116.60039 45.0
|
||||
22.81673 108.3669 40.07733 116.60039 45.0
|
||||
26.07421 119.29647 40.07733 116.60039 45.0
|
||||
38.91369 121.61476 40.07733 116.60039 45.0
|
||||
41.80563 123.43236 40.07733 116.60039 45.0
|
||||
32.05838 118.79647 40.07733 116.60039 45.0
|
||||
36.06138 103.83417 40.07733 116.60039 45.0
|
||||
38.48644 106.23248 40.07733 116.60039 45.0
|
||||
27.99492 120.69939 40.07733 116.60039 45.0
|
||||
37.46353 121.44801 40.07733 116.60039 45.0
|
||||
22.27073 113.57668 40.07733 116.60039 45.0
|
||||
29.87386 121.55027 40.07733 116.60039 45.0
|
||||
31.82057 117.22901 40.07733 116.60039 45.0
|
||||
34.34127 108.93984 40.07733 116.60039 45.0
|
||||
49.21163 119.76584 40.07733 116.60039 45.0
|
||||
40.84149 111.75199 40.07733 116.60039 45.0
|
||||
37.87059 112.55067 40.07733 116.60039 45.0
|
||||
46.58758 125.10307 40.07733 116.60039 45.0
|
||||
25.27361 110.29002 40.07733 116.60039 45.0
|
||||
31.46751 104.6796 40.07733 116.60039 45.0
|
||||
24.87389 118.67587 40.07733 116.60039 45.0
|
||||
30.69186 111.28642 40.07733 116.60039 45.0
|
||||
23.54972 116.37271 40.07733 116.60039 45.0
|
||||
40.65781 109.84021 40.07733 116.60039 45.0
|
||||
37.51348 122.12171 40.07733 116.60039 45.0
|
||||
31.49099 120.31237 40.07733 116.60039 45.0
|
||||
22.18684 113.54294 40.07733 116.60039 45.0
|
||||
34.74725 113.62493 40.07733 116.60039 45.0
|
||||
34.61812 112.45361 40.07733 116.60039 45.0
|
||||
36.50204 102.104287 40.07733 116.60039 45.0
|
||||
24.954708 121.48068 40.07733 116.60039 45.0
|
10
positions/src/main/assets/arcDistricts.dat
Normal file
@ -0,0 +1,10 @@
|
||||
39.90469 116.40717 29.56471 106.55073 30.0
|
||||
39.90469 116.40717 39.53775 116.68376 30.0
|
||||
39.90469 116.40717 31.23037 121.4737 30.0
|
||||
39.90469 116.40717 23.12908 113.26436 30.0
|
||||
39.90469 116.40717 28.22778 112.93886 30.0
|
||||
29.56471 106.55073 39.90469 116.40717 60.0
|
||||
18.25248 109.51209 39.90469 116.40717 60.0
|
||||
31.23037 121.4737 39.90469 116.40717 60.0
|
||||
23.12908 113.26436 39.90469 116.40717 60.0
|
||||
39.53775 116.68376 39.90469 116.40717 60.0
|
25
positions/src/main/assets/cluster_new
Normal file
@ -0,0 +1,25 @@
|
||||
116.307621 39.984059
|
||||
116.304703 39.981954
|
||||
116.312256 39.984355
|
||||
116.315346 39.980442
|
||||
116.308994 39.981527
|
||||
116.310539 39.979751
|
||||
116.305776 39.977252
|
||||
116.316419 39.984026
|
||||
116.314874 39.976956
|
||||
116.311827 39.978501
|
||||
116.312814 39.980277
|
||||
116.369022 39.980236
|
||||
116.368486 39.980236
|
||||
116.367488 39.977161
|
||||
116.396713 39.915398
|
||||
116.455421 39.937645
|
||||
116.321182 39.896304
|
||||
121.452827 31.254487
|
||||
121.485443 31.225133
|
||||
121.442528 31.216912
|
||||
121.500893 31.251552
|
||||
121.455917 31.249204
|
||||
114.042892 22.546885
|
||||
113.999805 22.538086
|
||||
114.082031 22.538086
|
BIN
positions/src/main/assets/color_arrow_texture.png
Normal file
After Width: | Height: | Size: 781 B |
BIN
positions/src/main/assets/color_texture.png
Normal file
After Width: | Height: | Size: 712 B |
2000
positions/src/main/assets/data2k
Normal file
1000
positions/src/main/assets/datab
Normal file
9162
positions/src/main/assets/gltf-BrainStem/BrainStem.gltf
Normal file
BIN
positions/src/main/assets/gltf-BrainStem/BrainStem0.bin
Normal file
BIN
positions/src/main/assets/groundoverlay.jpg
Normal file
After Width: | Height: | Size: 71 KiB |
BIN
positions/src/main/assets/gugong.jpg
Normal file
After Width: | Height: | Size: 49 KiB |
11671
positions/src/main/assets/honeycomb.txt
Normal file
2
positions/src/main/assets/trailData.dat
Normal file
BIN
positions/src/main/java/.DS_Store
vendored
Normal file
29
positions/src/main/java/cc/winboll/studio/positions/App.java
Normal file
@ -0,0 +1,29 @@
|
||||
package cc.winboll.studio.positions;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@QQ.COM
|
||||
* @Date 2024/12/08 15:10:51
|
||||
* @Describe 全局应用类
|
||||
*/
|
||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
|
||||
|
||||
public class App extends GlobalApplication {
|
||||
|
||||
public static final String TAG = "App";
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
// 必须在调用基类前设置应用调试标志,
|
||||
// 这样可以预先设置日志与数据的存储根目录。
|
||||
setIsDebuging(this, BuildConfig.DEBUG);
|
||||
super.onCreate();
|
||||
// 设置 WinBoll 应用 UI 类型
|
||||
WinBollActivityManager.getInstance(this).setWinBollUI_TYPE(WinBollActivityManager.WinBollUI_TYPE.Aplication);
|
||||
|
||||
|
||||
LogUtils.d(TAG, "onCreate");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,394 @@
|
||||
package cc.winboll.studio.positions;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Toast;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.LogView;
|
||||
import cc.winboll.studio.libapputils.app.IWinBollActivity;
|
||||
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
|
||||
import cc.winboll.studio.libapputils.bean.APPInfo;
|
||||
import cc.winboll.studio.libapputils.view.YesNoAlertDialog;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.map.vector.demo.DemoMainActivity;
|
||||
import cc.winboll.studio.positions.activities.SettingsActivity;
|
||||
import cc.winboll.studio.positions.adapters.MyPagerAdapter;
|
||||
import cc.winboll.studio.positions.beans.MainServiceBean;
|
||||
import cc.winboll.studio.positions.services.MainService;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.tencent.map.vector.demo.AbsListActivity;
|
||||
import com.tencent.map.vector.demo.AbsActivity;
|
||||
|
||||
final public class MainSimpleActivity extends AbsActivity implements IWinBollActivity, ViewPager.OnPageChangeListener, View.OnClickListener {
|
||||
|
||||
public static final String TAG = "MainActivity";
|
||||
|
||||
public static final int REQUEST_HOME_ACTIVITY = 0;
|
||||
public static final int REQUEST_ABOUT_ACTIVITY = 1;
|
||||
|
||||
public static final String ACTION_SOS = "cc.winboll.studio.libappbase.WinBoll.ACTION_SOS";
|
||||
|
||||
LogView mLogView;
|
||||
Toolbar mToolbar;
|
||||
CheckBox cbMainService;
|
||||
MainServiceBean mMainServiceBean;
|
||||
ViewPager viewPager;
|
||||
private List<View> views; //用来存放放进ViewPager里面的布局
|
||||
//实例化存储imageView(导航原点)的集合
|
||||
ImageView[] imageViews;
|
||||
//MyPagerAdapter adapter;//适配器
|
||||
MyPagerAdapter pagerAdapter;
|
||||
LinearLayout linearLayout;//下标所在在LinearLayout布局里
|
||||
int currentPoint = 0;//当前被选中中页面的下标
|
||||
|
||||
private static final int DIALER_REQUEST_CODE = 1;
|
||||
|
||||
@Override
|
||||
public AppCompatActivity getActivity() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public APPInfo getAppInfo() {
|
||||
// String szBranchName = "contacts";
|
||||
//
|
||||
// APPInfo appInfo = AboutActivityFactory.buildDefaultAPPInfo();
|
||||
// appInfo.setAppName("Contacts");
|
||||
// appInfo.setAppIcon(cc.winboll.studio.libapputils.R.drawable.ic_winboll);
|
||||
// appInfo.setAppDescription("Contacts Description");
|
||||
// appInfo.setAppGitName("APP");
|
||||
// appInfo.setAppGitOwner("Studio");
|
||||
// appInfo.setAppGitAPPBranch(szBranchName);
|
||||
// appInfo.setAppGitAPPSubProjectFolder(szBranchName);
|
||||
// appInfo.setAppHomePage("https://www.winboll.cc/studio/details.php?app=Contacts");
|
||||
// appInfo.setAppAPKName("Contacts");
|
||||
// appInfo.setAppAPKFolderName("Contacts");
|
||||
// return appInfo;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
// 接收并处理 Intent 数据,函数 Intent 处理接收就直接返回
|
||||
//if (prosessIntents(getIntent())) return;
|
||||
// 以下正常创建主窗口
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
// 初始化工具栏
|
||||
mToolbar = findViewById(R.id.activitymainToolbar1);
|
||||
setSupportActionBar(mToolbar);
|
||||
if (isEnableDisplayHomeAsUp()) {
|
||||
// 显示后退按钮
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
getSupportActionBar().setSubtitle(getTag());
|
||||
|
||||
initData();
|
||||
initView();
|
||||
//initPoint();//调用初始化导航原点的方法
|
||||
viewPager.addOnPageChangeListener(this);//滑动事件
|
||||
|
||||
ViewPager viewPager = findViewById(R.id.activitymainViewPager1);
|
||||
MyPagerAdapter pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
|
||||
viewPager.setAdapter(pagerAdapter);
|
||||
TabLayout tabLayout = findViewById(R.id.activitymainTabLayout1);
|
||||
tabLayout.setupWithViewPager(viewPager);
|
||||
|
||||
// mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
|
||||
// if (mMainServiceBean == null) {
|
||||
// mMainServiceBean = new MainServiceBean();
|
||||
// }
|
||||
// cbMainService = findViewById(R.id.activitymainCheckBox1);
|
||||
// cbMainService.setChecked(mMainServiceBean.isEnable());
|
||||
// cbMainService.setOnClickListener(new View.OnClickListener(){
|
||||
// @Override
|
||||
// public void onClick(View view) {
|
||||
// if (cbMainService.isChecked()) {
|
||||
// MainService.startMainService(MainActivity.this);
|
||||
// } else {
|
||||
// MainService.stopMainService(MainActivity.this);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
MainService.startMainService(Main2Activity.this);
|
||||
}
|
||||
|
||||
//初始化view,即显示的图片
|
||||
void initView() {
|
||||
viewPager = findViewById(R.id.activitymainViewPager1);
|
||||
pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
|
||||
viewPager.setAdapter(pagerAdapter);
|
||||
//adapter = new MyPagerAdapter(views);
|
||||
//viewPager = findViewById(R.id.activitymainViewPager1);
|
||||
//viewPager.setAdapter(adapter);
|
||||
//linearLayout = findViewById(R.id.activitymainLinearLayout1);
|
||||
//initPoint();//初始化页面下方的点
|
||||
viewPager.setOnPageChangeListener(this);
|
||||
|
||||
}
|
||||
|
||||
//初始化所要显示的布局
|
||||
void initData() {
|
||||
ViewPager viewPager = findViewById(R.id.activitymainViewPager1);
|
||||
LayoutInflater inflater = LayoutInflater.from(getActivity());
|
||||
View view1 = inflater.inflate(R.layout.fragment_gms, viewPager, false);
|
||||
View view2 = inflater.inflate(R.layout.fragment_contacts, viewPager, false);
|
||||
View view3 = inflater.inflate(R.layout.fragment_log, viewPager, false);
|
||||
|
||||
views = new ArrayList<>();
|
||||
views.add(view1);
|
||||
views.add(view2);
|
||||
views.add(view3);
|
||||
}
|
||||
|
||||
// void initPoint() {
|
||||
// imageViews = new ImageView[5];//实例化5个图片
|
||||
// for (int i = 0; i < linearLayout.getChildCount(); i++) {
|
||||
// imageViews[i] = (ImageView) linearLayout.getChildAt(i);
|
||||
// imageViews[i].setImageResource(R.drawable.ic_launcher);
|
||||
// imageViews[i].setOnClickListener(this);//点击导航点,即可跳转
|
||||
// imageViews[i].setTag(i);//重复利用实例化的对象
|
||||
// }
|
||||
// currentPoint = 0;//默认第一个坐标
|
||||
// imageViews[currentPoint].setImageResource(R.drawable.ic_launcher);
|
||||
// }
|
||||
|
||||
//OnPageChangeListener接口要实现的三个方法
|
||||
/* onPageScrollStateChanged(int state)
|
||||
此方法是在状态改变的时候调用,其中state这个参数有三种状态:
|
||||
SCROLL_STATE_DRAGGING(1)表示用户手指“按在屏幕上并且开始拖动”的状态
|
||||
(手指按下但是还没有拖动的时候还不是这个状态,只有按下并且手指开始拖动后log才打出。)
|
||||
SCROLL_STATE_IDLE(0)滑动动画做完的状态。
|
||||
SCROLL_STATE_SETTLING(2)在“手指离开屏幕”的状态。*/
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
|
||||
}
|
||||
/* onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
|
||||
当页面在滑动的时候会调用此方法,在滑动被停止之前,此方法回一直得到调用。其中三个参数的含义分别为:
|
||||
|
||||
position :当前页面,即你点击滑动的页面(从A滑B,则是A页面的position。
|
||||
positionOffset:当前页面偏移的百分比
|
||||
positionOffsetPixels:当前页面偏移的像素位置*/
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
|
||||
}
|
||||
/* onPageSelected(int position)
|
||||
此方法是页面滑动完后得到调用,position是你当前选中的页面的Position(位置编号)
|
||||
(从A滑动到B,就是B的position)*/
|
||||
public void onPageSelected(int position) {
|
||||
|
||||
// ImageView preView = imageViews[currentPoint];
|
||||
// preView.setImageResource(R.drawable.ic_launcher);
|
||||
// ImageView currView = imageViews[position];
|
||||
// currView.setImageResource(R.drawable.ic_launcher);
|
||||
// currentPoint = position;
|
||||
}
|
||||
|
||||
//小圆点点击事件
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// TODO Auto-generated method stub
|
||||
//通过getTag(),可以判断是哪个控件
|
||||
// int i = (Integer) v.getTag();
|
||||
// viewPager.setCurrentItem(i);//直接跳转到某一个页面的情况
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostCreate(Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
//setSubTitle("");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
LogUtils.d(TAG, "onDestroy() SOS");
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 处理传入的 Intent 数据
|
||||
//
|
||||
// boolean prosessIntents(Intent intent) {
|
||||
// if (intent == null
|
||||
// || intent.getAction() == null
|
||||
// || intent.getAction().equals(""))
|
||||
// return false;
|
||||
//
|
||||
// if (intent.getAction().equals(StringToQrCodeView.ACTION_UNITTEST_QRCODE)) {
|
||||
// try {
|
||||
// WinBollActivity clazzActivity = UnitTestActivity.class.newInstance();
|
||||
// String tag = clazzActivity.getTag();
|
||||
// LogUtils.d(TAG, "String tag = clazzActivity.getTag(); tag " + tag);
|
||||
// Intent subIntent = new Intent(this, UnitTestActivity.class);
|
||||
// subIntent.setAction(intent.getAction());
|
||||
// File file = new File(getCacheDir(), UUID.randomUUID().toString());
|
||||
// //取出文件uri
|
||||
// Uri uri = intent.getData();
|
||||
// if (uri == null) {
|
||||
// uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
|
||||
// }
|
||||
// //获取文件真实地址
|
||||
// String szSrcPath = UriUtils.getFileFromUri(getApplication(), uri);
|
||||
// if (TextUtils.isEmpty(szSrcPath)) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// Files.copy(Paths.get(szSrcPath), Paths.get(file.getPath()));
|
||||
// //startWinBollActivity(subIntent, tag);
|
||||
// WinBollActivityManager.getInstance(this).startWinBollActivity(this, subIntent, UnitTestActivity.class);
|
||||
// } catch (IllegalAccessException | InstantiationException | IOException e) {
|
||||
// LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||
// // 函数处理异常返回失败
|
||||
// return false;
|
||||
// }
|
||||
// } else {
|
||||
// LogUtils.d(TAG, "prosessIntents|" + intent.getAction() + "|yet");
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar initToolBar() {
|
||||
return findViewById(R.id.activitymainToolbar1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAddWinBollToolBar() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnableDisplayHomeAsUp() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
exit();
|
||||
}
|
||||
|
||||
void exit() {
|
||||
YesNoAlertDialog.OnDialogResultListener listener = new YesNoAlertDialog.OnDialogResultListener(){
|
||||
|
||||
@Override
|
||||
public void onYes() {
|
||||
WinBollActivityManager.getInstance(getApplicationContext()).finishAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNo() {
|
||||
}
|
||||
};
|
||||
YesNoAlertDialog.show(this, "[ " + getString(R.string.app_name) + " ]", "Exit(Yes/No).\nIs close all activity?", listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.toolbar_main, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == R.id.item_settings) {
|
||||
Intent intent = new Intent(this, SettingsActivity.class);
|
||||
startActivity(intent);
|
||||
//WinBollActivityManager.getInstance(this).startWinBollActivity(this, CallActivity.class);
|
||||
} else if (item.getItemId() == R.id.item_demomain) {
|
||||
Intent intent = new Intent(this, com.tencent.map.vector.demo.DemoMainActivity.class);
|
||||
startActivity(intent);
|
||||
//WinBollActivityManager.getInstance(this).startWinBollActivity(this, CallActivity.class);
|
||||
}
|
||||
// } else
|
||||
// if (item.getItemId() == R.id.item_exit) {
|
||||
// exit();
|
||||
// return true;
|
||||
// }
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
/**
|
||||
* Android M 及以上检查是否是系统默认电话应用
|
||||
*/
|
||||
public boolean isDefaultPhoneCallApp() {
|
||||
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
TelecomManager manger = (TelecomManager) getSystemService(TELECOM_SERVICE);
|
||||
if (manger != null && manger.getDefaultDialerPackage() != null) {
|
||||
return manger.getDefaultDialerPackage().equals(getPackageName());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isServiceRunning(Class<?> serviceClass) {
|
||||
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||
if (manager == null) return false;
|
||||
|
||||
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(
|
||||
Integer.MAX_VALUE)) {
|
||||
if (serviceClass.getName().equals(service.service.getClassName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
// switch (resultCode) {
|
||||
// case REQUEST_HOME_ACTIVITY : {
|
||||
// LogUtils.d(TAG, "REQUEST_HOME_ACTIVITY");
|
||||
// break;
|
||||
// }
|
||||
// case REQUEST_ABOUT_ACTIVITY : {
|
||||
// LogUtils.d(TAG, "REQUEST_ABOUT_ACTIVITY");
|
||||
// break;
|
||||
// }
|
||||
// default : {
|
||||
// super.onActivityResult(requestCode, resultCode, data);
|
||||
// }
|
||||
// }
|
||||
if (requestCode == DIALER_REQUEST_CODE) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
Toast.makeText(Main2Activity.this, getString(R.string.app_name) + " 已成为默认电话应用",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,470 @@
|
||||
package cc.winboll.studio.positions;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/24 11:05:49
|
||||
*/
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Matrix;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.os.Looper;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import cc.winboll.studio.libappbase.LogView;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import cc.winboll.studio.positions.activities.SettingsActivity;
|
||||
import cc.winboll.studio.positions.activities.TestMapViewActivity;
|
||||
import cc.winboll.studio.positions.utils.LocationFileStorage;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.tencent.map.geolocation.TencentLocation;
|
||||
import com.tencent.map.geolocation.TencentLocationListener;
|
||||
import com.tencent.map.geolocation.TencentLocationManager;
|
||||
import com.tencent.map.geolocation.TencentLocationRequest;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdate;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.LocationSource;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMapInitializer;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TextureMapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptor;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.Marker;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.MyLocationStyle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import pub.devrel.easypermissions.EasyPermissions;
|
||||
import cc.winboll.studio.positions.beans.LocationJson;
|
||||
|
||||
public class MainSimpleActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks,LocationSource, TencentLocationListener {
|
||||
|
||||
public static final String TAG ="MainSimpleActivity";
|
||||
|
||||
private static final int PERMISSION_REQUEST_CODE = 1;
|
||||
|
||||
Toolbar mToolbar;
|
||||
private TextureMapView mapView;
|
||||
protected TencentMap tencentMap;
|
||||
TextView mtvInfo;
|
||||
private LocationSource.OnLocationChangedListener locationChangedListener;
|
||||
|
||||
private TencentLocationManager locationManager;
|
||||
private TencentLocationRequest locationRequest;
|
||||
private MyLocationStyle locationStyle;
|
||||
ArrayList<LocationJson> locationJsonList;
|
||||
LogView mLogView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main_simple);
|
||||
|
||||
locationJsonList = new ArrayList<LocationJson>();
|
||||
|
||||
// 初始化工具栏
|
||||
mToolbar = findViewById(R.id.activitymainToolbar1);
|
||||
setSupportActionBar(mToolbar);
|
||||
getSupportActionBar().setSubtitle(TAG);
|
||||
|
||||
mLogView = findViewById(R.id.logview);
|
||||
mLogView.start();
|
||||
|
||||
TencentMapInitializer.setAgreePrivacy(this, true);
|
||||
TencentMapInitializer.start(this);
|
||||
TencentLocationManager.setUserAgreePrivacy(true);
|
||||
|
||||
|
||||
mapView = findViewById(R.id.mapview);
|
||||
mapView.setOpaque(false);
|
||||
//创建tencentMap地图对象,可以完成对地图的几乎所有操作
|
||||
tencentMap = mapView.getMap();
|
||||
|
||||
FloatingActionButton fab = findViewById(R.id.fab);
|
||||
fab.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Snackbar.make(view, "点击了悬浮按钮", Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
|
||||
mtvInfo = findViewById(R.id.tv_info);
|
||||
|
||||
checkLocationPermission();
|
||||
|
||||
//设置显示定位的图标
|
||||
TencentLocationManager.setUserAgreePrivacy(true);
|
||||
//建立定位
|
||||
//initLocation();
|
||||
//对地图操作类进行操作
|
||||
CameraUpdate cameraSigma =
|
||||
CameraUpdateFactory.newCameraPosition(new CameraPosition(
|
||||
new LatLng(22.984066, 116.307548),
|
||||
15,
|
||||
0f,
|
||||
0f));
|
||||
//移动地图
|
||||
tencentMap.moveCamera(cameraSigma);
|
||||
|
||||
// 设置地图点击监听
|
||||
tencentMap.setOnMapClickListener(new TencentMap.OnMapClickListener(){
|
||||
|
||||
@Override
|
||||
public void onMapClick(com.tencent.tencentmap.mapsdk.maps.model.LatLng latLng) {
|
||||
//创建Marker对象之前,设置属性
|
||||
//LatLng position = new LatLng(40.011313,116.391907);
|
||||
BitmapDescriptor custom = BitmapDescriptorFactory.fromResource(R.drawable.marker);
|
||||
Location location = createLocationFromLatLng(latLng);
|
||||
addLocationJson(location);
|
||||
Marker mCustomMarker = tencentMap.addMarker(new MarkerOptions(latLng));
|
||||
|
||||
//创建Marker对象之后,修改属性
|
||||
// Animation animation = new AlphaAnimation(0.7f, 0f);
|
||||
// animation.setDuration(2000);
|
||||
// mCustomMarker.setAnimation(animation);
|
||||
// mCustomMarker.startAnimation();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
void loadLocations() {
|
||||
// 存储位置数据
|
||||
// Location location = new Location("gps");
|
||||
// location.setLatitude(22.984066);
|
||||
// location.setLongitude(116.307548);
|
||||
// location.setTime(System.currentTimeMillis());
|
||||
//
|
||||
// // 方式1:保存到文件
|
||||
// List<Location> locations = new ArrayList<>();
|
||||
// locations.add(location);
|
||||
// LocationFileStorage.saveToFile(this, locations);
|
||||
|
||||
// 读取数据
|
||||
locationJsonList = LocationFileStorage.loadFromFile(this);
|
||||
|
||||
for (LocationJson lj : locationJsonList) {
|
||||
tencentMap.addMarker(new MarkerOptions(toTencentLatLng(lj.toLocation())));
|
||||
//LogUtils.d("Location", "Lat: " + loc.getLatitude() + ", Lng: " + loc.getLongitude());
|
||||
}
|
||||
}
|
||||
|
||||
void addLocationJson(Location location) {
|
||||
// 存储位置数据
|
||||
// Location location = new Location("gps");
|
||||
// location.setLatitude(22.984066);
|
||||
// location.setLongitude(116.307548);
|
||||
// location.setTime(System.currentTimeMillis());
|
||||
|
||||
// 方式1:保存到文件
|
||||
//List<Location> locations = new ArrayList<>();
|
||||
locationJsonList.add(new LocationJson(location));
|
||||
LocationFileStorage.saveToFile(this, locationJsonList);
|
||||
|
||||
// 读取数据
|
||||
// List<Location> loaded = LocationFileStorage.loadFromFile(this);
|
||||
// for (Location loc : loaded) {
|
||||
// tencentMap.addMarker(new MarkerOptions(toTencentLatLng(loc)));
|
||||
// //LogUtils.d("Location", "Lat: " + loc.getLatitude() + ", Lng: " + loc.getLongitude());
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 创建Location对象方法
|
||||
private Location createLocationFromLatLng(LatLng latLng) {
|
||||
Location location = new Location("tencent_map_manual");
|
||||
|
||||
// 设置基础坐标
|
||||
location.setLatitude(latLng.getLatitude());
|
||||
location.setLongitude(latLng.getLongitude());
|
||||
|
||||
// 设置必要元数据
|
||||
location.setTime(System.currentTimeMillis());
|
||||
location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
|
||||
location.setAccuracy(5.0f); // 手动点击精度设为5米
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
|
||||
public LatLng toTencentLatLng(Location location) {
|
||||
return new LatLng(
|
||||
location.getLatitude(),
|
||||
location.getLongitude()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// 添加标记方法
|
||||
private void addMarker(LatLng latLng) {
|
||||
tencentMap.clearAllOverlays();
|
||||
MarkerOptions options = new MarkerOptions(latLng)
|
||||
.icon(BitmapDescriptorFactory.defaultMarker())
|
||||
.title("点击保存");
|
||||
tencentMap.addMarker(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostCreate(Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
// LatLng center = new LatLng(39.904556, 116.427242);
|
||||
// tencentMap.moveCamera(
|
||||
// CameraUpdateFactory.newLatLngZoom(center, 13f) // 注意 13 → 13f
|
||||
// );
|
||||
loadLocations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.toolbar_main, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == R.id.item_settings) {
|
||||
Intent intent = new Intent(this, SettingsActivity.class);
|
||||
startActivity(intent);
|
||||
//WinBollActivityManager.getInstance(this).startWinBollActivity(this, CallActivity.class);
|
||||
} else if (item.getItemId() == R.id.item_demomain) {
|
||||
Intent intent = new Intent(this, com.tencent.map.vector.demo.DemoMainActivity.class);
|
||||
startActivity(intent);
|
||||
//WinBollActivityManager.getInstance(this).startWinBollActivity(this, CallActivity.class);
|
||||
} else if (item.getItemId() == R.id.item_testmapview) {
|
||||
Intent intent = new Intent(this, TestMapViewActivity.class);
|
||||
startActivity(intent);
|
||||
//WinBollActivityManager.getInstance(this).startWinBollActivity(this, CallActivity.class);
|
||||
}
|
||||
// } else
|
||||
// if (item.getItemId() == R.id.item_exit) {
|
||||
// exit();
|
||||
// return true;
|
||||
// }
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* mapview的生命周期管理
|
||||
*/
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestart() {
|
||||
super.onRestart();
|
||||
mapView.onRestart();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 设置定位图标样式
|
||||
*/
|
||||
private void setLocMarkerStyle() {
|
||||
locationStyle = new MyLocationStyle();
|
||||
//创建图标
|
||||
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(getBitMap(R.drawable.marker));
|
||||
locationStyle.icon(bitmapDescriptor);
|
||||
//设置定位圆形区域的边框宽度
|
||||
locationStyle.strokeWidth(3);
|
||||
//设置圆区域的颜色
|
||||
locationStyle.fillColor(R.color.style);
|
||||
|
||||
tencentMap.setMyLocationStyle(locationStyle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Bitmap getBitMap(int resourceId) {
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resourceId);
|
||||
int width = bitmap.getWidth();
|
||||
int height = bitmap.getHeight();
|
||||
int newWidth = 55;
|
||||
int newHeight = 55;
|
||||
float widthScale = ((float)newWidth) / width;
|
||||
float heightScale = ((float)newHeight) / height;
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postScale(widthScale, heightScale);
|
||||
bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 定位的一些初始化设置
|
||||
*/
|
||||
private void initLocation() {
|
||||
//用于访问腾讯定位服务的类, 周期性向客户端提供位置更新
|
||||
locationManager = TencentLocationManager.getInstance(this);
|
||||
//设置坐标系
|
||||
locationManager.setCoordinateType(TencentLocationManager.COORDINATE_TYPE_GCJ02);
|
||||
//创建定位请求
|
||||
locationRequest = TencentLocationRequest.create();
|
||||
//设置定位周期(位置监听器回调周期)为3s
|
||||
locationRequest.setInterval(3000);
|
||||
|
||||
//地图上设置定位数据源
|
||||
tencentMap.setLocationSource(this);
|
||||
//设置当前位置可见
|
||||
tencentMap.setMyLocationEnabled(true);
|
||||
//设置定位图标样式
|
||||
setLocMarkerStyle();
|
||||
// locationStyle = locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
|
||||
tencentMap.setMyLocationStyle(locationStyle);
|
||||
}
|
||||
/**
|
||||
* 实现位置监听
|
||||
* @param tencentLocation
|
||||
* @param i
|
||||
* @param s
|
||||
*/
|
||||
@Override
|
||||
public void onLocationChanged(TencentLocation tencentLocation, int i, String s) {
|
||||
|
||||
if (i == TencentLocation.ERROR_OK && locationChangedListener != null) {
|
||||
final Location location = new Location(tencentLocation.getProvider());
|
||||
//设置经纬度以及精度
|
||||
location.setLatitude(tencentLocation.getLatitude());
|
||||
location.setLongitude(tencentLocation.getLongitude());
|
||||
location.setAccuracy(tencentLocation.getAccuracy());
|
||||
locationChangedListener.onLocationChanged(location);
|
||||
|
||||
//显示回调的实时位置信息
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Rules.getEffectInfo(location);
|
||||
// double distance = DistanceUtils.getDistance(
|
||||
// locationA.getLatitude(),
|
||||
// locationA.getLongitude(),
|
||||
// locationB.getLatitude(),
|
||||
// locationB.getLongitude()
|
||||
// );
|
||||
mtvInfo.setText(String.format("\n%f %f", location.getLatitude(), location.getLongitude()));
|
||||
//打印tencentLocation的json字符串
|
||||
// Toast.makeText(getApplicationContext(), new Gson().toJson(location), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusUpdate(String s, int i, String s1) {
|
||||
//GPS, WiFi, Radio 等状态发生变化
|
||||
Log.v("State changed", s + "===" + s1);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void activate(OnLocationChangedListener onLocationChangedListener) {
|
||||
locationChangedListener = onLocationChangedListener;
|
||||
|
||||
int err = locationManager.requestLocationUpdates(locationRequest, this, Looper.myLooper());
|
||||
switch (err) {
|
||||
case 1:
|
||||
Toast.makeText(this, "设备缺少使用腾讯定位服务需要的基本条件", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
case 2:
|
||||
Toast.makeText(this, "manifest 中配置的 key 不正确", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
case 3:
|
||||
Toast.makeText(this, "自动加载libtencentloc.so失败", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
locationManager.removeUpdates(this);
|
||||
locationManager = null;
|
||||
locationRequest = null;
|
||||
locationChangedListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
|
||||
Log.e("location quest: ", "success");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
|
||||
Log.e("location quest: ", "failed");
|
||||
}
|
||||
|
||||
private void checkLocationPermission() {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
|
||||
|| ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(this,
|
||||
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
|
||||
PERMISSION_REQUEST_CODE);
|
||||
} else {
|
||||
// 权限已授予,可进行定位操作
|
||||
//startLocationUpdates();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (requestCode == PERMISSION_REQUEST_CODE) {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
//startLocationUpdates();
|
||||
} else {
|
||||
// 用户拒绝了权限请求
|
||||
Toast.makeText(this, "请授予定位权限", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package cc.winboll.studio.positions.activities;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/22 02:01:44
|
||||
*/
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import cc.winboll.studio.positions.views.GridMapView;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View;
|
||||
|
||||
public class GridMapActivity extends AppCompatActivity {
|
||||
|
||||
GridMapView gridMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_gridmap);
|
||||
|
||||
// 初始化视图
|
||||
GridMapView mapView = (GridMapView) findViewById(R.id.map_view);
|
||||
|
||||
// 设置网格参数
|
||||
mapView.setGridParameters(10000f, 10000f, 10f);
|
||||
|
||||
// 初始化显示区域(中心点400,300,显示范围2000x200)
|
||||
mapView.initViewport(5000f, 5000f, 1000f, 1000f);
|
||||
|
||||
// 绘制图形
|
||||
mapView.drawPoint(5000f, 5000f, Color.RED, 8f);
|
||||
mapView.drawCircle(5000f, 5000f, 50f, Color.BLUE, 8f);
|
||||
mapView.drawLine(4975f, 4975f, 5025f, 5025f, Color.GREEN, 2f);
|
||||
}
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
package cc.winboll.studio.positions.activities;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/21 05:37:42
|
||||
*/
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.hjq.toast.ToastUtils;
|
||||
import java.lang.reflect.Field;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import cc.winboll.studio.libappbase.IWinBollActivity;
|
||||
import cc.winboll.studio.libappbase.bean.APPInfo;
|
||||
|
||||
public class SettingsActivity extends AppCompatActivity implements IWinBollActivity {
|
||||
|
||||
public static final String TAG = "SettingsActivity";
|
||||
|
||||
Toolbar mToolbar;
|
||||
|
||||
@Override
|
||||
public APPInfo getAppInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppCompatActivity getActivity() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar initToolBar() {
|
||||
return findViewById(R.id.activitymainToolbar1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAddWinBollToolBar() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnableDisplayHomeAsUp() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_settings);
|
||||
|
||||
// 初始化工具栏
|
||||
mToolbar = findViewById(R.id.activitymainToolbar1);
|
||||
setSupportActionBar(mToolbar);
|
||||
if (isEnableDisplayHomeAsUp()) {
|
||||
// 显示后退按钮
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
getSupportActionBar().setSubtitle(getTag());
|
||||
|
||||
}
|
||||
|
||||
public void onDefaultPhone(View view) {
|
||||
Intent intent = new Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS);
|
||||
startActivity(intent);
|
||||
}
|
||||
public void onCanDrawOverlays(View view) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
&& !Settings.canDrawOverlays(this)) {
|
||||
// 请求 悬浮框 权限
|
||||
askForDrawOverlay();
|
||||
} else {
|
||||
ToastUtils.show("悬浮窗已开启");
|
||||
}
|
||||
}
|
||||
|
||||
private void askForDrawOverlay() {
|
||||
AlertDialog alertDialog = new AlertDialog.Builder(this)
|
||||
.setTitle("允许显示悬浮框")
|
||||
.setMessage("为了使电话监听服务正常工作,请允许这项权限")
|
||||
.setPositiveButton("去设置", new DialogInterface.OnClickListener(){
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
openDrawOverlaySettings();
|
||||
dialog.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton("稍后再说", new DialogInterface.OnClickListener(){
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
})
|
||||
.create();
|
||||
|
||||
//noinspection ConstantConditions
|
||||
alertDialog.getWindow().setFlags(
|
||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
|
||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
|
||||
alertDialog.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转悬浮窗管理设置界面
|
||||
*/
|
||||
private void openDrawOverlaySettings() {
|
||||
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// Android M 以上引导用户去系统设置中打开允许悬浮窗
|
||||
// 使用反射是为了用尽可能少的代码保证在大部分机型上都可用
|
||||
try {
|
||||
Context context = this;
|
||||
Class clazz = Settings.class;
|
||||
Field field = clazz.getDeclaredField("ACTION_MANAGE_OVERLAY_PERMISSION");
|
||||
Intent intent = new Intent(field.get(null).toString());
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.setData(Uri.parse("package:" + context.getPackageName()));
|
||||
context.startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
Toast.makeText(this, "请在悬浮窗管理中打开权限", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package cc.winboll.studio.positions.activities;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/24 12:14:04
|
||||
*/
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.map.vector.demo.heatoverlay.ScatterPlotOverlayActivity;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMapOptions;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TextureMapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
|
||||
public class TestMapViewActivity extends AppCompatActivity {
|
||||
|
||||
public static final String TAG = "TestMapViewActivity";
|
||||
|
||||
/**
|
||||
* 由于SDK并没有提供用于MapView管理地图生命周期的Activity
|
||||
* 因此需要用户继承Activity后管理地图的生命周期,防止内存泄露
|
||||
*/
|
||||
|
||||
private TextureMapView mapView;
|
||||
protected TencentMap tencentMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_testmapview);
|
||||
|
||||
mapView = findViewById(R.id.mapview);
|
||||
mapView.setOpaque(false);
|
||||
//创建tencentMap地图对象,可以完成对地图的几乎所有操作
|
||||
tencentMap = mapView.getMap();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* mapview的生命周期管理
|
||||
*/
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestart() {
|
||||
super.onRestart();
|
||||
mapView.onRestart();
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package cc.winboll.studio.positions.adapters;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/20 13:33:04
|
||||
* @Describe MyPagerAdapter
|
||||
*/
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
import cc.winboll.studio.positions.fragments.GmsFragment;
|
||||
import cc.winboll.studio.positions.fragments.ContactsFragment;
|
||||
import cc.winboll.studio.positions.fragments.LogFragment;
|
||||
|
||||
public class MyPagerAdapter extends FragmentPagerAdapter {
|
||||
public static final String TAG = "MyPagerAdapter";
|
||||
|
||||
private static final int PAGE_COUNT = 3;
|
||||
|
||||
public MyPagerAdapter(@NonNull FragmentManager fm) {
|
||||
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
if(position == 1) {
|
||||
return ContactsFragment.newInstance(position);
|
||||
} else if(position == 2) {
|
||||
return LogFragment.newInstance(position);
|
||||
} else {
|
||||
return GmsFragment.newInstance(position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return PAGE_COUNT;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,141 @@
|
||||
package cc.winboll.studio.positions.beans;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/25 02:58:33
|
||||
* @Describe LocationJson
|
||||
*/
|
||||
|
||||
import android.util.JsonReader;
|
||||
import android.util.JsonWriter;
|
||||
import cc.winboll.studio.libappbase.BaseBean;
|
||||
import java.io.IOException;
|
||||
import android.location.Location;
|
||||
|
||||
public class LocationJson extends BaseBean {
|
||||
|
||||
public static final String TAG = "LocationJson";
|
||||
|
||||
private double latitude;
|
||||
private double longitude;
|
||||
private long timestamp;
|
||||
private double accuracy;
|
||||
private String provider;
|
||||
|
||||
public LocationJson() {
|
||||
this.latitude = 0.0f;
|
||||
this.longitude = 0.0f;
|
||||
this.timestamp = 0L;
|
||||
this.accuracy = 0.0f;
|
||||
this.provider = "";
|
||||
}
|
||||
|
||||
public LocationJson(Location location) {
|
||||
this.latitude = location.getLatitude();
|
||||
this.longitude = location.getLongitude();
|
||||
this.timestamp = location.getTime();
|
||||
this.accuracy = location.getAccuracy();
|
||||
this.provider = location.getProvider();
|
||||
}
|
||||
|
||||
public void setLatitude(double latitude) {
|
||||
this.latitude = latitude;
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
public void setLongitude(double longitude) {
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setAccuracy(double accuracy) {
|
||||
this.accuracy = accuracy;
|
||||
}
|
||||
|
||||
public double getAccuracy() {
|
||||
return accuracy;
|
||||
}
|
||||
|
||||
public void setProvider(String provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
public String getProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return LocationJson.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
|
||||
super.writeThisToJsonWriter(jsonWriter);
|
||||
jsonWriter.name("latitude").value(getLatitude());
|
||||
jsonWriter.name("longitude").value(getLongitude());
|
||||
jsonWriter.name("timestamp").value(getTimestamp());
|
||||
jsonWriter.name("accuracy").value(getAccuracy());
|
||||
jsonWriter.name("provider").value(getProvider());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
|
||||
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
|
||||
if (name.equals("latitude")) {
|
||||
setLatitude(jsonReader.nextDouble());
|
||||
} else if (name.equals("longitude")) {
|
||||
setLongitude(jsonReader.nextDouble());
|
||||
} else if (name.equals("timestamp")) {
|
||||
setTimestamp(jsonReader.nextLong());
|
||||
} else if (name.equals("accuracy")) {
|
||||
setAccuracy(jsonReader.nextDouble());
|
||||
} else if (name.equals("provider")) {
|
||||
setProvider(jsonReader.nextString());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException {
|
||||
jsonReader.beginObject();
|
||||
while (jsonReader.hasNext()) {
|
||||
String name = jsonReader.nextName();
|
||||
if (!initObjectsFromJsonReader(jsonReader, name)) {
|
||||
jsonReader.skipValue();
|
||||
}
|
||||
}
|
||||
// 结束 JSON 对象
|
||||
jsonReader.endObject();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Location toLocation() {
|
||||
Location location = new Location(getProvider());
|
||||
location.setLatitude(getLatitude());
|
||||
location.setLongitude(getLongitude());
|
||||
location.setTime(getTimestamp());
|
||||
location.setAccuracy((float)getAccuracy());
|
||||
return location;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package cc.winboll.studio.positions.beans;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/13 07:06:13
|
||||
*/
|
||||
import android.util.JsonReader;
|
||||
import android.util.JsonWriter;
|
||||
import cc.winboll.studio.libappbase.BaseBean;
|
||||
import java.io.IOException;
|
||||
|
||||
public class MainServiceBean extends BaseBean {
|
||||
|
||||
public static final String TAG = "MainServiceBean";
|
||||
|
||||
boolean isEnable;
|
||||
|
||||
public MainServiceBean() {
|
||||
this.isEnable = false;
|
||||
}
|
||||
|
||||
public void setIsEnable(boolean isEnable) {
|
||||
this.isEnable = isEnable;
|
||||
}
|
||||
|
||||
public boolean isEnable() {
|
||||
return isEnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return MainServiceBean.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
|
||||
super.writeThisToJsonWriter(jsonWriter);
|
||||
MainServiceBean bean = this;
|
||||
jsonWriter.name("isEnable").value(bean.isEnable());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
|
||||
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
|
||||
if (name.equals("isEnable")) {
|
||||
setIsEnable(jsonReader.nextBoolean());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException {
|
||||
jsonReader.beginObject();
|
||||
while (jsonReader.hasNext()) {
|
||||
String name = jsonReader.nextName();
|
||||
if (!initObjectsFromJsonReader(jsonReader, name)) {
|
||||
jsonReader.skipValue();
|
||||
}
|
||||
}
|
||||
// 结束 JSON 对象
|
||||
jsonReader.endObject();
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package cc.winboll.studio.positions.beans;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/25 01:21:17
|
||||
* @Describe 定位信息类
|
||||
*/
|
||||
public class RulsBean {
|
||||
|
||||
public static final String TAG = "LocationBean";
|
||||
|
||||
float latitude;
|
||||
float longitude;
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package cc.winboll.studio.positions.fragments;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/20 12:57:50
|
||||
* @Describe 联系人
|
||||
*/
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import cc.winboll.studio.positions.R;
|
||||
|
||||
public class ContactsFragment extends Fragment {
|
||||
|
||||
public static final String TAG = "ContactsFragment";
|
||||
|
||||
private static final String ARG_PAGE = "ARG_PAGE";
|
||||
private int mPage;
|
||||
|
||||
public static ContactsFragment newInstance(int page) {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_PAGE, page);
|
||||
ContactsFragment fragment = new ContactsFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getArguments()!= null) {
|
||||
mPage = getArguments().getInt(ARG_PAGE);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_contacts, container, false);
|
||||
TextView textView = view.findViewById(R.id.page_text);
|
||||
textView.setText("这是第 " + mPage + " 页");
|
||||
return view;
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
package cc.winboll.studio.positions.fragments;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/20 12:57:00
|
||||
* @Describe 拨号
|
||||
*/
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import cc.winboll.studio.libappbase.LogView;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.graphics.Color;
|
||||
import android.widget.TextView;
|
||||
import cc.winboll.studio.positions.views.GridMapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TextureMapView;
|
||||
|
||||
public class GmsFragment extends Fragment {
|
||||
|
||||
public static final String TAG = "GmsFragment";
|
||||
|
||||
private static final String ARG_PAGE = "ARG_PAGE";
|
||||
private int mPage;
|
||||
private TextureMapView mapView;
|
||||
protected TencentMap tencentMap;
|
||||
|
||||
public static GmsFragment newInstance(int page) {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_PAGE, page);
|
||||
GmsFragment fragment = new GmsFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getArguments()!= null) {
|
||||
mPage = getArguments().getInt(ARG_PAGE);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_gms, container, false);
|
||||
|
||||
// // 初始化视图
|
||||
// GridMapView mapView = (GridMapView) view.findViewById(R.id.map_view);
|
||||
//
|
||||
// // 设置网格参数
|
||||
// mapView.setGridParameters(10000f, 10000f, 10f);
|
||||
//
|
||||
// // 初始化显示区域(中心点400,300,显示范围2000x200)
|
||||
// mapView.initViewport(5000f, 5000f, 1000f, 1000f);
|
||||
//
|
||||
// // 绘制图形
|
||||
// mapView.drawPoint(5000f, 5000f, Color.RED, 8f);
|
||||
// mapView.drawCircle(5000f, 5000f, 50f, Color.BLUE, 8f);
|
||||
// mapView.drawLine(4975f, 4975f, 5025f, 5025f, Color.GREEN, 2f);
|
||||
|
||||
// 初始化地图视图
|
||||
mapView = view.findViewById(R.id.mapView);
|
||||
mapView.setOpaque(false);
|
||||
//创建tencentMap地图对象,可以完成对地图的几乎所有操作
|
||||
tencentMap = mapView.getMap();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* mapview的生命周期管理
|
||||
*/
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package cc.winboll.studio.positions.fragments;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/20 12:58:15
|
||||
* @Describe 应用日志
|
||||
*/
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import cc.winboll.studio.libappbase.LogView;
|
||||
|
||||
public class LogFragment extends Fragment {
|
||||
|
||||
public static final String TAG = "LogFragment";
|
||||
|
||||
private static final String ARG_PAGE = "ARG_PAGE";
|
||||
private int mPage;
|
||||
|
||||
public static LogFragment newInstance(int page) {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_PAGE, page);
|
||||
LogFragment fragment = new LogFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getArguments() != null) {
|
||||
mPage = getArguments().getInt(ARG_PAGE);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_log, container, false);
|
||||
LogView logView = view.findViewById(R.id.logview);
|
||||
logView.start();
|
||||
return view;
|
||||
}
|
||||
}
|
@ -0,0 +1,461 @@
|
||||
package cc.winboll.studio.positions.fragments;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/25 12:44:39
|
||||
* @Describe 腾讯地图服务视图
|
||||
*/
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Matrix;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.os.Looper;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import cc.winboll.studio.libappbase.LogView;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import cc.winboll.studio.positions.activities.SettingsActivity;
|
||||
import cc.winboll.studio.positions.activities.TestMapViewActivity;
|
||||
import cc.winboll.studio.positions.utils.LocationFileStorage;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.tencent.map.geolocation.TencentLocation;
|
||||
import com.tencent.map.geolocation.TencentLocationListener;
|
||||
import com.tencent.map.geolocation.TencentLocationManager;
|
||||
import com.tencent.map.geolocation.TencentLocationRequest;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdate;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.LocationSource;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMapInitializer;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TextureMapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptor;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.Marker;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.MyLocationStyle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import pub.devrel.easypermissions.EasyPermissions;
|
||||
import cc.winboll.studio.positions.beans.LocationJson;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import cc.winboll.studio.libappbase.LogView;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.graphics.Color;
|
||||
import android.widget.TextView;
|
||||
import cc.winboll.studio.positions.views.GridMapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TextureMapView;
|
||||
|
||||
public class TXMSFragment extends Fragment implements EasyPermissions.PermissionCallbacks,LocationSource, TencentLocationListener {
|
||||
|
||||
public static final String TAG = "TXMSFragment";
|
||||
|
||||
|
||||
private static final String ARG_PAGE = "ARG_PAGE";
|
||||
private int mPage;
|
||||
private TextureMapView mapView;
|
||||
protected TencentMap tencentMap;
|
||||
TextView mtvInfo;
|
||||
private LocationSource.OnLocationChangedListener locationChangedListener;
|
||||
|
||||
private TencentLocationManager locationManager;
|
||||
private TencentLocationRequest locationRequest;
|
||||
private MyLocationStyle locationStyle;
|
||||
ArrayList<LocationJson> locationJsonList;
|
||||
|
||||
public static TXMSFragment newInstance(int page) {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_PAGE, page);
|
||||
TXMSFragment fragment = new GmsFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getArguments()!= null) {
|
||||
mPage = getArguments().getInt(ARG_PAGE);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View viewRoot = inflater.inflate(R.layout.fragment_gms, container, false);
|
||||
locationJsonList = new ArrayList<LocationJson>();
|
||||
|
||||
mLogView = viewRoot.findViewById(R.id.logview);
|
||||
mLogView.start();
|
||||
|
||||
TencentMapInitializer.setAgreePrivacy(this, true);
|
||||
TencentMapInitializer.start(this);
|
||||
TencentLocationManager.setUserAgreePrivacy(true);
|
||||
|
||||
|
||||
mapView = viewRoot.findViewById(R.id.mapview);
|
||||
mapView.setOpaque(false);
|
||||
//创建tencentMap地图对象,可以完成对地图的几乎所有操作
|
||||
tencentMap = mapView.getMap();
|
||||
|
||||
FloatingActionButton fab = viewRoot.findViewById(R.id.fab);
|
||||
fab.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Snackbar.make(view, "点击了悬浮按钮", Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
|
||||
mtvInfo = viewRoot.findViewById(R.id.tv_info);
|
||||
|
||||
checkLocationPermission();
|
||||
|
||||
//设置显示定位的图标
|
||||
TencentLocationManager.setUserAgreePrivacy(true);
|
||||
//建立定位
|
||||
//initLocation();
|
||||
//对地图操作类进行操作
|
||||
CameraUpdate cameraSigma =
|
||||
CameraUpdateFactory.newCameraPosition(new CameraPosition(
|
||||
new LatLng(22.984066, 116.307548),
|
||||
15,
|
||||
0f,
|
||||
0f));
|
||||
//移动地图
|
||||
tencentMap.moveCamera(cameraSigma);
|
||||
|
||||
// 设置地图点击监听
|
||||
tencentMap.setOnMapClickListener(new TencentMap.OnMapClickListener(){
|
||||
|
||||
@Override
|
||||
public void onMapClick(com.tencent.tencentmap.mapsdk.maps.model.LatLng latLng) {
|
||||
//创建Marker对象之前,设置属性
|
||||
//LatLng position = new LatLng(40.011313,116.391907);
|
||||
BitmapDescriptor custom = BitmapDescriptorFactory.fromResource(R.drawable.marker);
|
||||
Location location = createLocationFromLatLng(latLng);
|
||||
addLocationJson(location);
|
||||
Marker mCustomMarker = tencentMap.addMarker(new MarkerOptions(latLng));
|
||||
|
||||
//创建Marker对象之后,修改属性
|
||||
// Animation animation = new AlphaAnimation(0.7f, 0f);
|
||||
// animation.setDuration(2000);
|
||||
// mCustomMarker.setAnimation(animation);
|
||||
// mCustomMarker.startAnimation();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return viewRoot;
|
||||
}
|
||||
|
||||
void loadLocations() {
|
||||
// 存储位置数据
|
||||
// Location location = new Location("gps");
|
||||
// location.setLatitude(22.984066);
|
||||
// location.setLongitude(116.307548);
|
||||
// location.setTime(System.currentTimeMillis());
|
||||
//
|
||||
// // 方式1:保存到文件
|
||||
// List<Location> locations = new ArrayList<>();
|
||||
// locations.add(location);
|
||||
// LocationFileStorage.saveToFile(this, locations);
|
||||
|
||||
// 读取数据
|
||||
locationJsonList = LocationFileStorage.loadFromFile(this);
|
||||
|
||||
for (LocationJson lj : locationJsonList) {
|
||||
tencentMap.addMarker(new MarkerOptions(toTencentLatLng(lj.toLocation())));
|
||||
//LogUtils.d("Location", "Lat: " + loc.getLatitude() + ", Lng: " + loc.getLongitude());
|
||||
}
|
||||
}
|
||||
|
||||
void addLocationJson(Location location) {
|
||||
// 存储位置数据
|
||||
// Location location = new Location("gps");
|
||||
// location.setLatitude(22.984066);
|
||||
// location.setLongitude(116.307548);
|
||||
// location.setTime(System.currentTimeMillis());
|
||||
|
||||
// 方式1:保存到文件
|
||||
//List<Location> locations = new ArrayList<>();
|
||||
locationJsonList.add(new LocationJson(location));
|
||||
LocationFileStorage.saveToFile(this, locationJsonList);
|
||||
|
||||
// 读取数据
|
||||
// List<Location> loaded = LocationFileStorage.loadFromFile(this);
|
||||
// for (Location loc : loaded) {
|
||||
// tencentMap.addMarker(new MarkerOptions(toTencentLatLng(loc)));
|
||||
// //LogUtils.d("Location", "Lat: " + loc.getLatitude() + ", Lng: " + loc.getLongitude());
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 创建Location对象方法
|
||||
private Location createLocationFromLatLng(LatLng latLng) {
|
||||
Location location = new Location("tencent_map_manual");
|
||||
|
||||
// 设置基础坐标
|
||||
location.setLatitude(latLng.getLatitude());
|
||||
location.setLongitude(latLng.getLongitude());
|
||||
|
||||
// 设置必要元数据
|
||||
location.setTime(System.currentTimeMillis());
|
||||
location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
|
||||
location.setAccuracy(5.0f); // 手动点击精度设为5米
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
|
||||
public LatLng toTencentLatLng(Location location) {
|
||||
return new LatLng(
|
||||
location.getLatitude(),
|
||||
location.getLongitude()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// 添加标记方法
|
||||
private void addMarker(LatLng latLng) {
|
||||
tencentMap.clearAllOverlays();
|
||||
MarkerOptions options = new MarkerOptions(latLng)
|
||||
.icon(BitmapDescriptorFactory.defaultMarker())
|
||||
.title("点击保存");
|
||||
tencentMap.addMarker(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* mapview的生命周期管理
|
||||
*/
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPostCreate(Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
// LatLng center = new LatLng(39.904556, 116.427242);
|
||||
// tencentMap.moveCamera(
|
||||
// CameraUpdateFactory.newLatLngZoom(center, 13f) // 注意 13 → 13f
|
||||
// );
|
||||
loadLocations();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置定位图标样式
|
||||
*/
|
||||
private void setLocMarkerStyle() {
|
||||
locationStyle = new MyLocationStyle();
|
||||
//创建图标
|
||||
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(getBitMap(R.drawable.marker));
|
||||
locationStyle.icon(bitmapDescriptor);
|
||||
//设置定位圆形区域的边框宽度
|
||||
locationStyle.strokeWidth(3);
|
||||
//设置圆区域的颜色
|
||||
locationStyle.fillColor(R.color.style);
|
||||
|
||||
tencentMap.setMyLocationStyle(locationStyle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Bitmap getBitMap(int resourceId) {
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resourceId);
|
||||
int width = bitmap.getWidth();
|
||||
int height = bitmap.getHeight();
|
||||
int newWidth = 55;
|
||||
int newHeight = 55;
|
||||
float widthScale = ((float)newWidth) / width;
|
||||
float heightScale = ((float)newHeight) / height;
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postScale(widthScale, heightScale);
|
||||
bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 定位的一些初始化设置
|
||||
*/
|
||||
private void initLocation() {
|
||||
//用于访问腾讯定位服务的类, 周期性向客户端提供位置更新
|
||||
locationManager = TencentLocationManager.getInstance(this);
|
||||
//设置坐标系
|
||||
locationManager.setCoordinateType(TencentLocationManager.COORDINATE_TYPE_GCJ02);
|
||||
//创建定位请求
|
||||
locationRequest = TencentLocationRequest.create();
|
||||
//设置定位周期(位置监听器回调周期)为3s
|
||||
locationRequest.setInterval(3000);
|
||||
|
||||
//地图上设置定位数据源
|
||||
tencentMap.setLocationSource(this);
|
||||
//设置当前位置可见
|
||||
tencentMap.setMyLocationEnabled(true);
|
||||
//设置定位图标样式
|
||||
setLocMarkerStyle();
|
||||
// locationStyle = locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
|
||||
tencentMap.setMyLocationStyle(locationStyle);
|
||||
}
|
||||
/**
|
||||
* 实现位置监听
|
||||
* @param tencentLocation
|
||||
* @param i
|
||||
* @param s
|
||||
*/
|
||||
@Override
|
||||
public void onLocationChanged(TencentLocation tencentLocation, int i, String s) {
|
||||
|
||||
if (i == TencentLocation.ERROR_OK && locationChangedListener != null) {
|
||||
final Location location = new Location(tencentLocation.getProvider());
|
||||
//设置经纬度以及精度
|
||||
location.setLatitude(tencentLocation.getLatitude());
|
||||
location.setLongitude(tencentLocation.getLongitude());
|
||||
location.setAccuracy(tencentLocation.getAccuracy());
|
||||
locationChangedListener.onLocationChanged(location);
|
||||
|
||||
//显示回调的实时位置信息
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Rules.getEffectInfo(location);
|
||||
// double distance = DistanceUtils.getDistance(
|
||||
// locationA.getLatitude(),
|
||||
// locationA.getLongitude(),
|
||||
// locationB.getLatitude(),
|
||||
// locationB.getLongitude()
|
||||
// );
|
||||
mtvInfo.setText(String.format("\n%f %f", location.getLatitude(), location.getLongitude()));
|
||||
//打印tencentLocation的json字符串
|
||||
// Toast.makeText(getApplicationContext(), new Gson().toJson(location), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusUpdate(String s, int i, String s1) {
|
||||
//GPS, WiFi, Radio 等状态发生变化
|
||||
Log.v("State changed", s + "===" + s1);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void activate(OnLocationChangedListener onLocationChangedListener) {
|
||||
locationChangedListener = onLocationChangedListener;
|
||||
|
||||
int err = locationManager.requestLocationUpdates(locationRequest, this, Looper.myLooper());
|
||||
switch (err) {
|
||||
case 1:
|
||||
Toast.makeText(this, "设备缺少使用腾讯定位服务需要的基本条件", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
case 2:
|
||||
Toast.makeText(this, "manifest 中配置的 key 不正确", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
case 3:
|
||||
Toast.makeText(this, "自动加载libtencentloc.so失败", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
locationManager.removeUpdates(this);
|
||||
locationManager = null;
|
||||
locationRequest = null;
|
||||
locationChangedListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
|
||||
Log.e("location quest: ", "success");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
|
||||
Log.e("location quest: ", "failed");
|
||||
}
|
||||
|
||||
private void checkLocationPermission() {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
|
||||
|| ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(this,
|
||||
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
|
||||
PERMISSION_REQUEST_CODE);
|
||||
} else {
|
||||
// 权限已授予,可进行定位操作
|
||||
//startLocationUpdates();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (requestCode == PERMISSION_REQUEST_CODE) {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
//startLocationUpdates();
|
||||
} else {
|
||||
// 用户拒绝了权限请求
|
||||
Toast.makeText(this, "请授予定位权限", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
package cc.winboll.studio.positions.gps;
|
||||
|
||||
|
@ -0,0 +1,38 @@
|
||||
package cc.winboll.studio.positions.handlers;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/14 03:51:40
|
||||
*/
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import cc.winboll.studio.positions.services.MainService;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class MainServiceHandler extends Handler {
|
||||
public static final String TAG = "MainServiceHandler";
|
||||
|
||||
public static final int MSG_REMINDTHREAD = 0;
|
||||
|
||||
WeakReference<MainService> serviceWeakReference;
|
||||
public MainServiceHandler(MainService service) {
|
||||
serviceWeakReference = new WeakReference<MainService>(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MSG_REMINDTHREAD: // 处理下载完成消息,更新UI
|
||||
{
|
||||
// 显示提醒消息
|
||||
//
|
||||
//LogUtils.d(TAG, "显示提醒消息");
|
||||
MainService mainService = serviceWeakReference.get();
|
||||
if (mainService != null) {
|
||||
mainService.appenMessage((String)msg.obj);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package cc.winboll.studio.positions.receivers;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/13 06:58:04
|
||||
* @Describe 主要广播接收器
|
||||
*/
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import cc.winboll.studio.positions.services.MainService;
|
||||
import com.hjq.toast.ToastUtils;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class MainReceiver extends BroadcastReceiver {
|
||||
|
||||
public static final String TAG = "MainReceiver";
|
||||
public static final String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
|
||||
WeakReference<MainService> mwrService;
|
||||
// 存储电量指示值,
|
||||
// 用于校验电量消息时的电量变化
|
||||
static volatile int _mnTheQuantityOfElectricityOld = -1;
|
||||
static volatile boolean _mIsCharging = false;
|
||||
|
||||
public MainReceiver(MainService service) {
|
||||
mwrService = new WeakReference<MainService>(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String szAction = intent.getAction();
|
||||
if (szAction.equals(ACTION_BOOT_COMPLETED)) {
|
||||
ToastUtils.show("ACTION_BOOT_COMPLETED");
|
||||
MainService.startMainService(context);
|
||||
} else {
|
||||
ToastUtils.show(szAction);
|
||||
}
|
||||
}
|
||||
|
||||
// 注册 Receiver
|
||||
//
|
||||
public void registerAction(Context context) {
|
||||
IntentFilter filter=new IntentFilter();
|
||||
filter.addAction(ACTION_BOOT_COMPLETED);
|
||||
//filter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
||||
context.registerReceiver(this, filter);
|
||||
}
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
package cc.winboll.studio.positions.services;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/14 03:38:31
|
||||
* @Describe 守护进程服务
|
||||
*/
|
||||
import android.app.Service;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import cc.winboll.studio.positions.beans.MainServiceBean;
|
||||
import cc.winboll.studio.positions.services.MainService;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.SOS;
|
||||
import cc.winboll.studio.libappbase.bean.APPSOSBean;
|
||||
|
||||
public class AssistantService extends Service {
|
||||
|
||||
public static final String TAG = "AssistantService";
|
||||
|
||||
MainServiceBean mMainServiceBean;
|
||||
MyServiceConnection mMyServiceConnection;
|
||||
MainService mMainService;
|
||||
boolean isBound = false;
|
||||
volatile boolean isThreadAlive = false;
|
||||
|
||||
public synchronized void setIsThreadAlive(boolean isThreadAlive) {
|
||||
LogUtils.d(TAG, "setIsThreadAlive(...)");
|
||||
LogUtils.d(TAG, String.format("isThreadAlive %s", isThreadAlive));
|
||||
this.isThreadAlive = isThreadAlive;
|
||||
}
|
||||
|
||||
public boolean isThreadAlive() {
|
||||
return isThreadAlive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return new MyBinder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
LogUtils.d(TAG, "onCreate");
|
||||
super.onCreate();
|
||||
|
||||
//mMyBinder = new MyBinder();
|
||||
if (mMyServiceConnection == null) {
|
||||
mMyServiceConnection = new MyServiceConnection();
|
||||
}
|
||||
// 设置运行参数
|
||||
setIsThreadAlive(false);
|
||||
assistantService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
LogUtils.d(TAG, "call onStartCommand(...)");
|
||||
assistantService();
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
//LogUtils.d(TAG, "onDestroy");
|
||||
setIsThreadAlive(false);
|
||||
// 解除绑定
|
||||
if (isBound) {
|
||||
unbindService(mMyServiceConnection);
|
||||
isBound = false;
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
// 运行服务内容
|
||||
//
|
||||
void assistantService() {
|
||||
LogUtils.d(TAG, "assistantService()");
|
||||
mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
|
||||
LogUtils.d(TAG, String.format("mMainServiceBean.isEnable() %s", mMainServiceBean.isEnable()));
|
||||
if (mMainServiceBean.isEnable()) {
|
||||
LogUtils.d(TAG, String.format("mIsThreadAlive %s", isThreadAlive()));
|
||||
if (isThreadAlive() == false) {
|
||||
// 设置运行状态
|
||||
setIsThreadAlive(true);
|
||||
// 唤醒和绑定主进程
|
||||
wakeupAndBindMain();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 唤醒和绑定主进程
|
||||
//
|
||||
void wakeupAndBindMain() {
|
||||
LogUtils.d(TAG, "wakeupAndBindMain()");
|
||||
// 绑定服务的Intent
|
||||
Intent intent = new Intent(this, MainService.class);
|
||||
startService(new Intent(this, MainService.class));
|
||||
bindService(intent, mMyServiceConnection, Context.BIND_IMPORTANT);
|
||||
|
||||
// startService(new Intent(this, MainService.class));
|
||||
// bindService(new Intent(AssistantService.this, MainService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
|
||||
}
|
||||
|
||||
// 主进程与守护进程连接时需要用到此类
|
||||
//
|
||||
class MyServiceConnection implements ServiceConnection {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
LogUtils.d(TAG, "onServiceConnected(...)");
|
||||
MainService.MyBinder binder = (MainService.MyBinder) service;
|
||||
mMainService = binder.getService();
|
||||
isBound = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
LogUtils.d(TAG, "onServiceDisconnected(...)");
|
||||
mMainServiceBean = MainServiceBean.loadBean(AssistantService.this, MainServiceBean.class);
|
||||
if (mMainServiceBean.isEnable()) {
|
||||
wakeupAndBindMain();
|
||||
}
|
||||
isBound = false;
|
||||
mMainService = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 用于返回服务实例的Binder
|
||||
public class MyBinder extends Binder {
|
||||
AssistantService getService() {
|
||||
LogUtils.d(TAG, "AssistantService MyBinder getService()");
|
||||
return AssistantService.this;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,228 @@
|
||||
package cc.winboll.studio.positions.services;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/13 06:56:41
|
||||
* @Describe 拨号主服务
|
||||
* 参考:
|
||||
* 进程保活-双进程守护的正确姿势
|
||||
* https://blog.csdn.net/sinat_35159441/article/details/75267380
|
||||
* Android Service之onStartCommand方法研究
|
||||
* https://blog.csdn.net/cyp331203/article/details/38920491
|
||||
*/
|
||||
import android.app.Service;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.SOS;
|
||||
import cc.winboll.studio.libappbase.bean.APPSOSBean;
|
||||
import cc.winboll.studio.positions.beans.MainServiceBean;
|
||||
import cc.winboll.studio.positions.handlers.MainServiceHandler;
|
||||
import cc.winboll.studio.positions.receivers.MainReceiver;
|
||||
import cc.winboll.studio.positions.services.MainService;
|
||||
import cc.winboll.studio.positions.threads.MainServiceThread;
|
||||
|
||||
public class MainService extends Service {
|
||||
|
||||
public static final String TAG = "MainService";
|
||||
|
||||
public static final int MSG_UPDATE_STATUS = 0;
|
||||
|
||||
static MainService _mControlCenterService;
|
||||
|
||||
volatile boolean isServiceRunning;
|
||||
|
||||
MainServiceBean mMainServiceBean;
|
||||
MainServiceThread mMainServiceThread;
|
||||
MainServiceHandler mMainServiceHandler;
|
||||
MyServiceConnection mMyServiceConnection;
|
||||
AssistantService mAssistantService;
|
||||
boolean isBound = false;
|
||||
MainReceiver mMainReceiver;
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return new MyBinder();
|
||||
}
|
||||
|
||||
public MainServiceThread getRemindThread() {
|
||||
return mMainServiceThread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
LogUtils.d(TAG, "onCreate()");
|
||||
_mControlCenterService = MainService.this;
|
||||
isServiceRunning = false;
|
||||
mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
|
||||
|
||||
if (mMyServiceConnection == null) {
|
||||
mMyServiceConnection = new MyServiceConnection();
|
||||
}
|
||||
mMainServiceHandler = new MainServiceHandler(this);
|
||||
|
||||
// 运行服务内容
|
||||
mainService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
LogUtils.d(TAG, "onStartCommand(...)");
|
||||
// 运行服务内容
|
||||
mainService();
|
||||
return (mMainServiceBean.isEnable()) ? START_STICKY : super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
|
||||
// 运行服务内容
|
||||
//
|
||||
void mainService() {
|
||||
LogUtils.d(TAG, "mainService()");
|
||||
mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
|
||||
if (mMainServiceBean.isEnable() && isServiceRunning == false) {
|
||||
LogUtils.d(TAG, "mainService() start running");
|
||||
isServiceRunning = true;
|
||||
// 唤醒守护进程
|
||||
wakeupAndBindAssistant();
|
||||
// 召唤 WinBoll APP 绑定本服务
|
||||
SOS.bindToAPPService(this, new APPSOSBean(getPackageName(), MainService.class.getName()));
|
||||
|
||||
if (mMainReceiver == null) {
|
||||
// 注册广播接收器
|
||||
mMainReceiver = new MainReceiver(this);
|
||||
mMainReceiver.registerAction(this);
|
||||
}
|
||||
|
||||
|
||||
MainServiceThread.getInstance(this, mMainServiceHandler).start();
|
||||
|
||||
LogUtils.i(TAG, "Main Service Is Start.");
|
||||
}
|
||||
}
|
||||
|
||||
// 唤醒和绑定守护进程
|
||||
//
|
||||
void wakeupAndBindAssistant() {
|
||||
LogUtils.d(TAG, "wakeupAndBindAssistant()");
|
||||
// if (ServiceUtils.isServiceAlive(getApplicationContext(), AssistantService.class.getName()) == false) {
|
||||
// startService(new Intent(MainService.this, AssistantService.class));
|
||||
// //LogUtils.d(TAG, "call wakeupAndBindAssistant() : Binding... AssistantService");
|
||||
// bindService(new Intent(MainService.this, AssistantService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
|
||||
// }
|
||||
Intent intent = new Intent(this, AssistantService.class);
|
||||
startService(intent);
|
||||
// 绑定服务的Intent
|
||||
//Intent intent = new Intent(this, AssistantService.class);
|
||||
bindService(intent, mMyServiceConnection, Context.BIND_IMPORTANT);
|
||||
|
||||
// Intent intent = new Intent(this, AssistantService.class);
|
||||
// startService(intent);
|
||||
// LogUtils.d(TAG, "startService(intent)");
|
||||
// bindService(new Intent(this, AssistantService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
//LogUtils.d(TAG, "onDestroy");
|
||||
mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
|
||||
//LogUtils.d(TAG, "onDestroy done");
|
||||
if (mMainServiceBean.isEnable() == false) {
|
||||
// 设置运行状态
|
||||
isServiceRunning = false;// 解除绑定
|
||||
if (isBound) {
|
||||
unbindService(mMyServiceConnection);
|
||||
isBound = false;
|
||||
}
|
||||
// 停止守护进程
|
||||
Intent intent = new Intent(this, AssistantService.class);
|
||||
stopService(intent);
|
||||
// 停止Receiver
|
||||
if (mMainReceiver != null) {
|
||||
unregisterReceiver(mMainReceiver);
|
||||
mMainReceiver = null;
|
||||
}
|
||||
// 停止前台通知栏
|
||||
stopForeground(true);
|
||||
|
||||
// 停止主要进程
|
||||
MainServiceThread.getInstance(this, mMainServiceHandler).setIsExit(true);
|
||||
}
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
// 主进程与守护进程连接时需要用到此类
|
||||
//
|
||||
private class MyServiceConnection implements ServiceConnection {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
LogUtils.d(TAG, "onServiceConnected(...)");
|
||||
AssistantService.MyBinder binder = (AssistantService.MyBinder) service;
|
||||
mAssistantService = binder.getService();
|
||||
isBound = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
LogUtils.d(TAG, "onServiceDisconnected(...)");
|
||||
if (mMainServiceBean.isEnable()) {
|
||||
// 唤醒守护进程
|
||||
wakeupAndBindAssistant();
|
||||
SOS.sosWinBollService(getApplicationContext(), new APPSOSBean(getPackageName(), MainService.class.getName()));
|
||||
}
|
||||
isBound = false;
|
||||
mAssistantService = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 用于返回服务实例的Binder
|
||||
public class MyBinder extends Binder {
|
||||
MainService getService() {
|
||||
LogUtils.d(TAG, "MainService MyBinder getService()");
|
||||
return MainService.this;
|
||||
}
|
||||
}
|
||||
|
||||
// //
|
||||
// // 启动服务
|
||||
// //
|
||||
// public static void startControlCenterService(Context context) {
|
||||
// Intent intent = new Intent(context, MainService.class);
|
||||
// context.startForegroundService(intent);
|
||||
// }
|
||||
//
|
||||
// //
|
||||
// // 停止服务
|
||||
// //
|
||||
// public static void stopControlCenterService(Context context) {
|
||||
// Intent intent = new Intent(context, MainService.class);
|
||||
// context.stopService(intent);
|
||||
// }
|
||||
|
||||
public void appenMessage(String message) {
|
||||
LogUtils.d(TAG, String.format("Message : %s", message));
|
||||
}
|
||||
|
||||
public static void stopMainService(Context context) {
|
||||
LogUtils.d(TAG, "stopMainService");
|
||||
MainServiceBean bean = new MainServiceBean();
|
||||
bean.setIsEnable(false);
|
||||
MainServiceBean.saveBean(context, bean);
|
||||
context.stopService(new Intent(context, MainService.class));
|
||||
}
|
||||
|
||||
public static void startMainService(Context context) {
|
||||
LogUtils.d(TAG, "startMainService");
|
||||
MainServiceBean bean = new MainServiceBean();
|
||||
bean.setIsEnable(true);
|
||||
MainServiceBean.saveBean(context, bean);
|
||||
context.startService(new Intent(context, MainService.class));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
package cc.winboll.studio.positions.tasks;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/25 01:15:08
|
||||
* @Describe 定位规则类
|
||||
*/
|
||||
import com.tencent.map.geolocation.TencentLocation;
|
||||
import android.location.Location;
|
||||
|
||||
public class Rules {
|
||||
|
||||
public static final String TAG = "Rules";
|
||||
|
||||
public static String getEffectInfo(Location locationA) {
|
||||
//Location locationB = new Location(22.0f, 111.0f);
|
||||
// 腾讯SDK返回的坐标点(注意坐标系需统一)
|
||||
//TencentLocation locationA = ...; // 第一个点
|
||||
//TencentLocation locationB = ...; // 第二个点
|
||||
|
||||
// float[] results = new float[1];
|
||||
// Location.distanceBetween(
|
||||
// locationA.getLatitude(), // 纬度
|
||||
// locationA.getLongitude(), // 经度
|
||||
// locationB.getLatitude(),
|
||||
// locationB.getLongitude(),
|
||||
// results
|
||||
// );
|
||||
//
|
||||
// return "两点距离:" + results[0] + "米";
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package cc.winboll.studio.positions.threads;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/14 03:46:44
|
||||
*/
|
||||
import android.content.Context;
|
||||
import cc.winboll.studio.positions.handlers.MainServiceHandler;
|
||||
import cc.winboll.studio.positions.services.MainService;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.SOS;
|
||||
import cc.winboll.studio.libappbase.bean.APPSOSBean;
|
||||
import com.hjq.toast.ToastUtils;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class MainServiceThread extends Thread {
|
||||
|
||||
public static final String TAG = "MainServiceThread";
|
||||
|
||||
volatile static MainServiceThread _MainServiceThread;
|
||||
// 控制线程是否退出的标志
|
||||
volatile boolean isExit = false;
|
||||
volatile boolean isStarted = false;
|
||||
Context mContext;
|
||||
// 服务Handler, 用于线程发送消息使用
|
||||
WeakReference<MainServiceHandler> mwrMainServiceHandler;
|
||||
|
||||
MainServiceThread(Context context, MainServiceHandler handler) {
|
||||
mContext = context;
|
||||
mwrMainServiceHandler = new WeakReference<MainServiceHandler>(handler);
|
||||
}
|
||||
|
||||
public void setIsExit(boolean isExit) {
|
||||
this.isExit = isExit;
|
||||
}
|
||||
|
||||
public boolean isExit() {
|
||||
return isExit;
|
||||
}
|
||||
|
||||
public void setIsStarted(boolean isStarted) {
|
||||
this.isStarted = isStarted;
|
||||
}
|
||||
|
||||
public boolean isStarted() {
|
||||
return isStarted;
|
||||
}
|
||||
|
||||
public static MainServiceThread getInstance(Context context, MainServiceHandler handler) {
|
||||
if (_MainServiceThread != null) {
|
||||
_MainServiceThread.setIsExit(true);
|
||||
}
|
||||
_MainServiceThread = new MainServiceThread(context, handler);
|
||||
return _MainServiceThread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (isStarted == false) {
|
||||
isStarted = true;
|
||||
LogUtils.d(TAG, "run()");
|
||||
|
||||
while (!isExit()) {
|
||||
//ToastUtils.show("run");
|
||||
//LogUtils.d(TAG, "run()");
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||
}
|
||||
}
|
||||
_MainServiceThread = null;
|
||||
LogUtils.d(TAG, "run() exit");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package cc.winboll.studio.positions.utils;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/25 03:02:17
|
||||
* @Describe LocationFileStorage
|
||||
*/
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.json.JSONArray;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.positions.beans.LocationJson;
|
||||
|
||||
public class LocationFileStorage {
|
||||
public static final String TAG = "LocationFileStorage";
|
||||
|
||||
private static final String FILE_NAME = "locations.json";
|
||||
|
||||
public static void saveToFile(Context context, ArrayList<LocationJson> locations) {
|
||||
try {
|
||||
LocationJson.saveBeanList(context, locations, LocationJson.class);
|
||||
} catch (Exception e) {
|
||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||
}
|
||||
}
|
||||
|
||||
public static ArrayList<LocationJson> loadFromFile(Context context) {
|
||||
ArrayList<LocationJson> result = new ArrayList<LocationJson>();
|
||||
try {
|
||||
LocationJson.loadBeanList(context, result, LocationJson.class);
|
||||
} catch (Exception e) {
|
||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,246 @@
|
||||
package cc.winboll.studio.positions.views;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/02/22 03:32:48
|
||||
* @Describe GridMapView
|
||||
*/
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PointF;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.View;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GridMapView extends View {
|
||||
// 网格参数
|
||||
private float gridTotalWidth = 1000f;
|
||||
private float gridTotalHeight = 1000f;
|
||||
private float gridSpacing = 50f;
|
||||
|
||||
// 视图变换参数
|
||||
private float offsetX = 0f;
|
||||
private float offsetY = 0f;
|
||||
private float scaleFactor = 1.0f;
|
||||
private final float minScale = 0.5f;
|
||||
private final float maxScale = 5.0f;
|
||||
|
||||
// 手势检测
|
||||
private final ScaleGestureDetector scaleDetector;
|
||||
private float lastTouchX;
|
||||
private float lastTouchY;
|
||||
|
||||
// 图形存储
|
||||
private final List<MapShape> shapes = new ArrayList<MapShape>();
|
||||
|
||||
public GridMapView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public GridMapView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
scaleDetector = new ScaleGestureDetector(context, new ScaleListener());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
canvas.save();
|
||||
canvas.translate(offsetX, offsetY);
|
||||
canvas.scale(scaleFactor, scaleFactor);
|
||||
|
||||
drawGrid(canvas);
|
||||
drawShapes(canvas);
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
private void drawGrid(Canvas canvas) {
|
||||
Paint gridPaint = new Paint();
|
||||
gridPaint.setColor(Color.LTGRAY);
|
||||
gridPaint.setStrokeWidth(1f / scaleFactor);
|
||||
|
||||
// 绘制垂直线
|
||||
for (float x = 0; x <= gridTotalWidth; x += gridSpacing) {
|
||||
canvas.drawLine(x, 0, x, gridTotalHeight, gridPaint);
|
||||
}
|
||||
|
||||
// 绘制水平线
|
||||
for (float y = 0; y <= gridTotalHeight; y += gridSpacing) {
|
||||
canvas.drawLine(0, y, gridTotalWidth, y, gridPaint);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawShapes(Canvas canvas) {
|
||||
for (MapShape shape : shapes) {
|
||||
shape.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
scaleDetector.onTouchEvent(event);
|
||||
|
||||
final int action = event.getAction();
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
if (!scaleDetector.isInProgress()) {
|
||||
lastTouchX = x;
|
||||
lastTouchY = y;
|
||||
}
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (!scaleDetector.isInProgress()) {
|
||||
final float dx = x - lastTouchX;
|
||||
final float dy = y - lastTouchY;
|
||||
|
||||
offsetX += dx;
|
||||
offsetY += dy;
|
||||
invalidate();
|
||||
|
||||
lastTouchX = x;
|
||||
lastTouchY = y;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 初始化视图显示区域
|
||||
public void initViewport(final float centerX, final float centerY,
|
||||
final float viewWidth, final float viewHeight) {
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
float viewportWidth = getWidth();
|
||||
float viewportHeight = getHeight();
|
||||
|
||||
float widthScale = viewportWidth / viewWidth;
|
||||
float heightScale = viewportHeight / viewHeight;
|
||||
scaleFactor = Math.min(widthScale, heightScale);
|
||||
|
||||
offsetX = viewportWidth/2 - centerX * scaleFactor;
|
||||
offsetY = viewportHeight/2 - centerY * scaleFactor;
|
||||
invalidate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 图形绘制方法
|
||||
public void drawPoint(float x, float y, int color, float size) {
|
||||
shapes.add(new MapShape(MapShape.TYPE_POINT, x, y, color, size));
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void drawCircle(float x, float y, float radius, int color, float strokeWidth) {
|
||||
MapShape shape = new MapShape(MapShape.TYPE_CIRCLE, x, y, color, radius);
|
||||
shape.setStrokeWidth(strokeWidth);
|
||||
shapes.add(shape);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void drawLine(float startX, float startY, float endX, float endY,
|
||||
int color, float strokeWidth) {
|
||||
MapShape shape = new MapShape(MapShape.TYPE_LINE, startX, startY, endX, endY, color);
|
||||
shape.setStrokeWidth(strokeWidth);
|
||||
shapes.add(shape);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
// 网格参数设置
|
||||
public void setGridParameters(float totalWidth, float totalHeight, float spacing) {
|
||||
gridTotalWidth = totalWidth;
|
||||
gridTotalHeight = totalHeight;
|
||||
gridSpacing = spacing;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
|
||||
@Override
|
||||
public boolean onScale(ScaleGestureDetector detector) {
|
||||
float newScale = scaleFactor * detector.getScaleFactor();
|
||||
newScale = Math.max(minScale, Math.min(newScale, maxScale));
|
||||
|
||||
float focusX = detector.getFocusX();
|
||||
float focusY = detector.getFocusY();
|
||||
|
||||
offsetX = focusX - ((focusX - offsetX) / scaleFactor * newScale);
|
||||
offsetY = focusY - ((focusY - offsetY) / scaleFactor * newScale);
|
||||
|
||||
scaleFactor = newScale;
|
||||
invalidate();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MapShape {
|
||||
static final int TYPE_POINT = 0;
|
||||
static final int TYPE_CIRCLE = 1;
|
||||
static final int TYPE_LINE = 2;
|
||||
|
||||
final int type;
|
||||
final PointF[] points;
|
||||
final int color;
|
||||
float radius;
|
||||
float strokeWidth = 2f;
|
||||
|
||||
MapShape(int type, float x, float y, int color, float size) {
|
||||
this.type = type;
|
||||
this.points = new PointF[]{new PointF(x, y)};
|
||||
this.color = color;
|
||||
this.radius = size;
|
||||
}
|
||||
|
||||
MapShape(int type, float x1, float y1, float x2, float y2, int color) {
|
||||
this.type = type;
|
||||
this.points = new PointF[]{
|
||||
new PointF(x1, y1),
|
||||
new PointF(x2, y2)
|
||||
};
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
MapShape setStrokeWidth(float width) {
|
||||
this.strokeWidth = width;
|
||||
return this;
|
||||
}
|
||||
|
||||
void draw(Canvas canvas) {
|
||||
Paint paint = new Paint();
|
||||
paint.setColor(color);
|
||||
|
||||
switch (type) {
|
||||
case TYPE_POINT:
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
canvas.drawCircle(points[0].x, points[0].y, radius, paint);
|
||||
break;
|
||||
|
||||
case TYPE_CIRCLE:
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
paint.setStrokeWidth(strokeWidth);
|
||||
canvas.drawCircle(points[0].x, points[0].y, radius, paint);
|
||||
break;
|
||||
|
||||
case TYPE_LINE:
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
paint.setStrokeWidth(strokeWidth);
|
||||
canvas.drawLine(
|
||||
points[0].x, points[0].y,
|
||||
points[1].x, points[1].y,
|
||||
paint
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
positions/src/main/java/com/.DS_Store
vendored
Normal file
BIN
positions/src/main/java/com/tencent/.DS_Store
vendored
Normal file
BIN
positions/src/main/java/com/tencent/map/.DS_Store
vendored
Normal file
BIN
positions/src/main/java/com/tencent/map/vector/.DS_Store
vendored
Normal file
BIN
positions/src/main/java/com/tencent/map/vector/demo/.DS_Store
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
package com.tencent.map.vector.demo;
|
||||
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import cc.winboll.studio.positions.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbsActivity extends AppCompatActivity {
|
||||
|
||||
private static final int PERMISSIONS_REQUEST_CODE = 0x99FF;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
requestPermission();
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
private void requestPermission() {
|
||||
String[] permissions = onRequestPermissions();
|
||||
if (permissions != null) {
|
||||
List<String> deniedPermissions = new ArrayList<>();
|
||||
for (String permission : permissions) {
|
||||
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
|
||||
deniedPermissions.add(permission);
|
||||
}
|
||||
}
|
||||
|
||||
if (deniedPermissions.size() > 0) {
|
||||
requestPermissions(deniedPermissions.toArray(new String[0]), PERMISSIONS_REQUEST_CODE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected String[] onRequestPermissions() {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.tencent.map.vector.demo;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.map.geolocation.TencentLocationManager;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMapInitializer;
|
||||
|
||||
public abstract class AbsListActivity extends AbsActivity {
|
||||
|
||||
protected int getLayoutId() {
|
||||
return R.layout.activity_recycler_container;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(getLayoutId());
|
||||
TencentMapInitializer.setAgreePrivacy(this, true);
|
||||
TencentMapInitializer.start(this);
|
||||
TencentLocationManager.setUserAgreePrivacy(true);
|
||||
final String PRIVACY_URL = "https://privacy.qq.com/document/preview/a10a8634f237464da9a95f4f07e73e40";
|
||||
findViewById(R.id.tv_user).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(PRIVACY_URL)));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.tencent.map.vector.demo;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.SupportMapFragment;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
|
||||
public abstract class AbsMapActivity extends AbsActivity {
|
||||
|
||||
private TencentMap mTencentMap;
|
||||
|
||||
protected int getLayoutId() {
|
||||
return R.layout.activity_map_container;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(getLayoutId());
|
||||
|
||||
FragmentManager manager = getSupportFragmentManager();
|
||||
SupportMapFragment fragment = (SupportMapFragment) manager.findFragmentById(R.id.fragment_map);
|
||||
if (fragment != null) {
|
||||
mTencentMap = fragment.getMap();
|
||||
}
|
||||
|
||||
onCreate(savedInstanceState, mTencentMap);
|
||||
}
|
||||
|
||||
protected boolean checkMapInvalid() {
|
||||
return mTencentMap == null || mTencentMap.isDestroyed();
|
||||
}
|
||||
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState, TencentMap tencentMap) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
supportInvalidateOptionsMenu();
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
supportInvalidateOptionsMenu();
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
@ -0,0 +1,277 @@
|
||||
package com.tencent.map.vector.demo;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.ListAdapter;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import cc.winboll.studio.positions.R;
|
||||
|
||||
public class DemoMainActivity extends AbsListActivity {
|
||||
|
||||
private static final String DEMO_TYPE = "DEMO_TYPE";
|
||||
|
||||
private static List<DemoInfo> mDemoTypes;
|
||||
private static Map<String, List<DemoInfo>> mDemoMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getDemos();
|
||||
setupViews(getIntent().getStringExtra(DEMO_TYPE));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] onRequestPermissions() {
|
||||
return new String[]{
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
Manifest.permission.READ_PHONE_STATE
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
return R.layout.activity_demomain;
|
||||
}
|
||||
|
||||
private void setupViews(String type) {
|
||||
RecyclerView recyclerView = findViewById(R.id.layout_recycle_container);
|
||||
if (recyclerView != null) {
|
||||
RecyclerView.LayoutManager layoutManager =
|
||||
new LinearLayoutManager(getApplicationContext());
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.addItemDecoration(new DividerItemDecoration(
|
||||
getApplicationContext(), DividerItemDecoration.VERTICAL));
|
||||
|
||||
DemoActivityAdapter activityAdapter = new DemoActivityAdapter(type);
|
||||
recyclerView.setAdapter(activityAdapter);
|
||||
}
|
||||
}
|
||||
|
||||
private void getDemos() {
|
||||
if (mDemoMap != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mDemoMap = new HashMap<>(16);
|
||||
mDemoTypes = new ArrayList<>(16);
|
||||
|
||||
ActivityInfo[] activityIfs = new ActivityInfo[0];
|
||||
try {
|
||||
activityIfs = getPackageManager().getPackageInfo(getPackageName(),
|
||||
PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA).activities;
|
||||
} catch (PackageManager.NameNotFoundException pE) {
|
||||
pE.printStackTrace();
|
||||
}
|
||||
|
||||
for (ActivityInfo activityInfo : activityIfs) {
|
||||
if (activityInfo.metaData != null) {
|
||||
String demoType = activityInfo.metaData.getString(
|
||||
getResources().getString(R.string.demo_type));
|
||||
List<DemoInfo> items = mDemoMap.get(demoType);
|
||||
if (items == null) {
|
||||
items = new ArrayList<>();
|
||||
mDemoMap.put(demoType, items);
|
||||
mDemoTypes.add(new DemoInfo(
|
||||
DemoMainActivity.class.getName(),
|
||||
demoType,
|
||||
""));
|
||||
}
|
||||
|
||||
items.add(new DemoInfo(
|
||||
activityInfo.name,
|
||||
getString(activityInfo.labelRes),
|
||||
getString(activityInfo.descriptionRes)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class DemoInfo {
|
||||
private String name;
|
||||
private String label;
|
||||
private String description;
|
||||
|
||||
public DemoInfo(String name, String label, String description) {
|
||||
this.name = name;
|
||||
this.label = label;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof DemoInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DemoInfo info = (DemoInfo) obj;
|
||||
|
||||
if (!Objects.equals(this.name, info.name)) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(this.label, info.label)) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(this.description, info.description)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = name != null ? name.hashCode() : 0;
|
||||
hash = 31 * hash + (label != null ? label.hashCode() : 0);
|
||||
hash = 31 * hash + (description != null ? description.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
private class DemoActivityAdapter extends ListAdapter<DemoInfo, DemoInfoHolder> {
|
||||
|
||||
private int mType;
|
||||
|
||||
DemoActivityAdapter(String type) {
|
||||
super(new DiffUtil.ItemCallback<DemoInfo>() {
|
||||
@Override
|
||||
public boolean areItemsTheSame(@NonNull DemoInfo oldItem, @NonNull DemoInfo newItem) {
|
||||
return oldItem.name.equals(newItem.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(@NonNull DemoInfo oldItem, @NonNull DemoInfo newItem) {
|
||||
return oldItem.equals(newItem);
|
||||
}
|
||||
});
|
||||
if (TextUtils.isEmpty(type)) {
|
||||
mType = DemoInfoHolder.ITEM_TYPE_GROUP;
|
||||
submitList(mDemoTypes);
|
||||
} else {
|
||||
mType = DemoInfoHolder.ITEM_TYPE_ENTRY;
|
||||
submitList(mDemoMap.get(type));
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DemoInfoHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
return new DemoInfoHolder(DemoMainActivity.this, parent, viewType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull DemoInfoHolder holder, int position) {
|
||||
holder.bindView(getItem(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return mType;
|
||||
}
|
||||
}
|
||||
|
||||
static class DemoInfoHolder<T extends DemoInfo> extends RecyclerView.ViewHolder {
|
||||
|
||||
private static final int ITEM_TYPE_GROUP = 0;
|
||||
private static final int ITEM_TYPE_ENTRY = 1;
|
||||
|
||||
private int mViewType;
|
||||
|
||||
private TextView mTitle;
|
||||
private TextView mSubTitle;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
DemoInfoHolder(Context context, ViewGroup pParent, int pViewType) {
|
||||
super(LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_2, pParent, false));
|
||||
mViewType = pViewType;
|
||||
mContext = context;
|
||||
|
||||
mTitle = itemView.findViewById(android.R.id.text1);
|
||||
mTitle.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
|
||||
|
||||
mSubTitle = itemView.findViewById(android.R.id.text2);
|
||||
mSubTitle.setTextColor(Color.GRAY);
|
||||
|
||||
}
|
||||
|
||||
void bindView(T pItem) {
|
||||
if (mViewType == ITEM_TYPE_GROUP) {
|
||||
setupItemGroup(pItem);
|
||||
} else if (mViewType == ITEM_TYPE_ENTRY) {
|
||||
setupItemEntry(pItem);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupItemGroup(final T pItem) {
|
||||
mTitle.setText(pItem.getLabel());
|
||||
mSubTitle.setVisibility(View.GONE);
|
||||
|
||||
itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
try {
|
||||
Intent intent = new Intent(mContext, Class.forName(pItem.getName()));
|
||||
intent.putExtra(DEMO_TYPE, pItem.getLabel());
|
||||
mContext.startActivity(intent);
|
||||
} catch (ClassNotFoundException pE) {
|
||||
pE.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setupItemEntry(final T pItem) {
|
||||
mTitle.setText(pItem.getLabel());
|
||||
mSubTitle.setText(pItem.getDescription());
|
||||
|
||||
itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
try {
|
||||
Intent intent = new Intent(mContext, Class.forName(pItem.getName()));
|
||||
mContext.startActivity(intent);
|
||||
} catch (ClassNotFoundException pE) {
|
||||
pE.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,544 @@
|
||||
package com.tencent.map.vector.demo.basic;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.TextPaint;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class IndoorFloorView extends ScrollView {
|
||||
public static final String TAG = IndoorFloorView.class
|
||||
.getSimpleName();
|
||||
|
||||
private Context context;
|
||||
|
||||
private LinearLayout views;
|
||||
|
||||
private int itemHeight = 0;
|
||||
private List<String> items;
|
||||
|
||||
private int scrollDirection = -1;
|
||||
private static final int SCROLL_DIRECTION_UP = 0;
|
||||
private static final int SCROLL_DIRECTION_DOWN = 1;
|
||||
|
||||
private int viewWidth;
|
||||
|
||||
private Bitmap selectBitmap = null;
|
||||
//背景色
|
||||
private int backGroundColor = Color.parseColor("#00000000");
|
||||
//边框色
|
||||
private int strokeColor = Color.parseColor("#00000000");
|
||||
private int strokeWidth = 0; // 边框宽度
|
||||
|
||||
private int offset = 1; // 偏移量在最前面和最后面补全
|
||||
private int displayItemCount; // 每页显示的数
|
||||
int selectedIndex = 1;
|
||||
|
||||
private int initialY;
|
||||
|
||||
private Runnable scrollerTask;
|
||||
private int newCheck = 50;
|
||||
|
||||
public IndoorFloorView(Context context) {
|
||||
super(context);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public IndoorFloorView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public IndoorFloorView(Context context, AttributeSet attrs,
|
||||
int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改偏移量,即当第一个显示在中间是上面有几个空白<br>
|
||||
* 也会影响整体显示,如设置1,上下各偏移1,总共显3个;设置2总共显示5个;
|
||||
*
|
||||
* @param offset
|
||||
*/
|
||||
public void setOffset(int offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
this.context = context;
|
||||
|
||||
this.setVerticalScrollBarEnabled(false);
|
||||
|
||||
selectBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.radius);
|
||||
|
||||
views = new LinearLayout(context);
|
||||
views.setOrientation(LinearLayout.VERTICAL);
|
||||
this.addView(views);
|
||||
scrollerTask = new Runnable() {
|
||||
|
||||
public void run() {
|
||||
|
||||
int newY = getScrollY();
|
||||
if (initialY - newY == 0) { // stopped
|
||||
final int remainder = initialY % itemHeight;
|
||||
final int divided = initialY / itemHeight;
|
||||
if (remainder == 0) {
|
||||
selectedIndex = divided + offset;
|
||||
|
||||
onSeletedCallBack();
|
||||
} else {
|
||||
if (remainder > itemHeight / 2) {
|
||||
IndoorFloorView.this.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
IndoorFloorView.this.smoothScrollTo(
|
||||
0, initialY - remainder
|
||||
+ itemHeight);
|
||||
selectedIndex = divided + offset + 1;
|
||||
onSeletedCallBack();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
IndoorFloorView.this.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
IndoorFloorView.this.smoothScrollTo(
|
||||
0, initialY - remainder);
|
||||
selectedIndex = divided + offset;
|
||||
onSeletedCallBack();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
initialY = getScrollY();
|
||||
IndoorFloorView.this.postDelayed(scrollerTask,
|
||||
newCheck);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public void startScrollerTask() {
|
||||
|
||||
initialY = getScrollY();
|
||||
this.postDelayed(scrollerTask, newCheck);
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
if(items==null||items.size()==0){
|
||||
return;
|
||||
}
|
||||
|
||||
views.removeAllViews();
|
||||
displayItemCount = offset * 2 + 1;
|
||||
|
||||
for (int i=items.size()-1;i>=0;i--) {
|
||||
views.addView(createView(items.get(i)));
|
||||
}
|
||||
|
||||
refreshItemView(0);
|
||||
}
|
||||
|
||||
private TextView createView(String item) {
|
||||
TextView tv = new TextView(context);
|
||||
tv.setLayoutParams(new LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
tv.setSingleLine(true);
|
||||
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
|
||||
tv.setText(item);
|
||||
tv.setGravity(Gravity.CENTER);
|
||||
TextPaint tp = tv.getPaint();
|
||||
tp.setFakeBoldText(true);
|
||||
int padding_h = dip2px(context, 8);
|
||||
int padding_v = dip2px(context, 6);
|
||||
tv.setPadding(padding_h, padding_v, padding_h, padding_v);
|
||||
if (0 == itemHeight) {
|
||||
itemHeight = getViewMeasuredHeight(tv);
|
||||
views.setLayoutParams(new LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, itemHeight
|
||||
* displayItemCount));
|
||||
this.setLayoutParams(new LinearLayout.LayoutParams(
|
||||
LayoutParams.WRAP_CONTENT, itemHeight * displayItemCount));
|
||||
}
|
||||
return tv;
|
||||
}
|
||||
|
||||
private void refreshItemView(int y) {
|
||||
int position = y / itemHeight + offset;
|
||||
int remainder = y % itemHeight;
|
||||
int divided = y / itemHeight;
|
||||
|
||||
if (remainder == 0) {
|
||||
position = divided + offset;
|
||||
} else {
|
||||
if (remainder > itemHeight / 2) {
|
||||
position = divided + offset + 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int childSize = views.getChildCount();
|
||||
for (int i = 0; i < childSize; i++) {
|
||||
TextView itemView = (TextView) views.getChildAt(i);
|
||||
if (null == itemView) {
|
||||
return;
|
||||
}
|
||||
if (position == i) {
|
||||
itemView.setTextColor(Color.parseColor("#0079ff"));
|
||||
} else {
|
||||
itemView.setTextColor(Color.parseColor("#ccebfc"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置显示的内容
|
||||
*
|
||||
* @param list
|
||||
*/
|
||||
public void setItems(List<String> list) {
|
||||
if (null == items) {
|
||||
items = new ArrayList<String>();
|
||||
}
|
||||
items.clear();
|
||||
items.addAll(list);
|
||||
|
||||
// 前面和后面补
|
||||
for (int i = 0; i < offset; i++) {
|
||||
items.add(0, "");
|
||||
items.add("");
|
||||
}
|
||||
|
||||
initData();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置显示的内容
|
||||
*
|
||||
* @param strs
|
||||
*/
|
||||
public void setItems(String[] strs) {
|
||||
if (null == items) {
|
||||
items = new ArrayList<String>();
|
||||
}
|
||||
|
||||
items.clear();
|
||||
for (int i = 0; i < strs.length; i++)
|
||||
items.add(strs[i]);
|
||||
|
||||
// 前面和后面补
|
||||
for (int i = 0; i < offset; i++) {
|
||||
items.add(0, "");
|
||||
items.add("");
|
||||
}
|
||||
|
||||
initData();
|
||||
|
||||
}
|
||||
|
||||
public void setBackgroundColor(int color) {
|
||||
this.backGroundColor = color;
|
||||
}
|
||||
|
||||
public void setStrokeColor(int color) {
|
||||
this.strokeColor = color;
|
||||
}
|
||||
|
||||
public void setStrokeWidth(int width) {
|
||||
this.strokeWidth = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置选中状图片
|
||||
*
|
||||
* @param bitmap
|
||||
*/
|
||||
public void setIndoorSelectBitmap(Bitmap bitmap) {
|
||||
this.selectBitmap = bitmap;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (selectBitmap != null && !selectBitmap.isRecycled()) {
|
||||
selectBitmap.recycle();
|
||||
selectBitmap = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackgroundDrawable(Drawable background) {
|
||||
if (viewWidth == 0) {
|
||||
viewWidth = ((Activity) context).getWindowManager()
|
||||
.getDefaultDisplay().getWidth();
|
||||
}
|
||||
|
||||
background = new Drawable() {
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
|
||||
try {
|
||||
drawBg(canvas);
|
||||
drawCenterLine(canvas);
|
||||
drawStroke(canvas);
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void drawBg(Canvas canvas) {
|
||||
canvas.drawColor(backGroundColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param canvas
|
||||
*/
|
||||
private void drawCenterLine(Canvas canvas) {
|
||||
final Paint paint = new Paint();
|
||||
Rect src = new Rect();// 图片 >>原矩
|
||||
Rect dst = new Rect();// 屏幕 >>目标矩形
|
||||
//133 122
|
||||
Log.d("IndoorFloorView", "drawCenterLine: "+selectBitmap.getWidth()+"\n"+selectBitmap.getHeight());
|
||||
src.left = 0;
|
||||
src.top = 0;
|
||||
src.right = 0 + selectBitmap.getWidth();
|
||||
src.bottom = 0 + selectBitmap.getHeight();
|
||||
|
||||
dst.left = 0;
|
||||
dst.top = obtainSelectedAreaBorder()[0];
|
||||
dst.right = 0 + viewWidth;
|
||||
dst.bottom = obtainSelectedAreaBorder()[1];
|
||||
canvas.drawBitmap(selectBitmap, src, dst, paint);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param canvas
|
||||
*/
|
||||
private void drawStroke(Canvas canvas) {
|
||||
final Paint mPaint = new Paint();
|
||||
Rect rect = canvas.getClipBounds();
|
||||
mPaint.setColor(strokeColor);
|
||||
mPaint.setStyle(Paint.Style.STROKE);
|
||||
mPaint.setStrokeWidth(strokeWidth);
|
||||
canvas.drawRect(rect, mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
super.setBackgroundDrawable(background);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取选中区域的边
|
||||
*/
|
||||
private int[] obtainSelectedAreaBorder() {
|
||||
int[] selectedAreaBorder = null;
|
||||
if (null == selectedAreaBorder) {
|
||||
selectedAreaBorder = new int[2];
|
||||
selectedAreaBorder[0] = itemHeight * offset;
|
||||
selectedAreaBorder[1] = itemHeight * (offset + 1);
|
||||
}
|
||||
return selectedAreaBorder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
viewWidth = w;
|
||||
setBackgroundDrawable(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
|
||||
super.onScrollChanged(l, t, oldl, oldt);
|
||||
refreshItemView(t);
|
||||
if (t > oldt) {
|
||||
scrollDirection = SCROLL_DIRECTION_DOWN;
|
||||
} else {
|
||||
scrollDirection = SCROLL_DIRECTION_UP;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 选中回调
|
||||
*/
|
||||
private void onSeletedCallBack() {
|
||||
if (null != onIndoorFloorSwtichListener) {
|
||||
try {
|
||||
onIndoorFloorSwtichListener.onSelected(getSeletedIndex());
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setSeletion(String selectValue) {
|
||||
if(items==null||items.size()==0){
|
||||
return;
|
||||
}
|
||||
int position = items.indexOf(selectValue);
|
||||
final int p = items.size()-offset-1-position;
|
||||
selectedIndex = p + offset;
|
||||
this.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
IndoorFloorView.this.smoothScrollTo(0, p * itemHeight);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public String getSeletedItem() {
|
||||
return items.get(selectedIndex);
|
||||
}
|
||||
|
||||
public int getSeletedIndex() {
|
||||
if(items==null||items.size()==0){
|
||||
return 0;
|
||||
}
|
||||
int result = items.size()-1-selectedIndex - offset;
|
||||
return Math.min(items.size() - 2 * offset, Math.max(0, result));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fling(int velocityY) {
|
||||
super.fling(velocityY / 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_UP) {
|
||||
|
||||
startScrollerTask();
|
||||
}
|
||||
return super.onTouchEvent(ev);
|
||||
}
|
||||
|
||||
private OnIndoorFloorListener onIndoorFloorSwtichListener;
|
||||
|
||||
public OnIndoorFloorListener getOnIndoorFloorListener() {
|
||||
return onIndoorFloorSwtichListener;
|
||||
}
|
||||
|
||||
public void setOnIndoorFloorListener(
|
||||
OnIndoorFloorListener onIndoorFloorSwtichListener) {
|
||||
this.onIndoorFloorSwtichListener = onIndoorFloorSwtichListener;
|
||||
}
|
||||
|
||||
public static abstract interface OnIndoorFloorListener {
|
||||
public abstract void onSelected(int selectedIndex);
|
||||
}
|
||||
|
||||
// utils
|
||||
public static int dip2px(Context context, float dpValue) {
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (dpValue * scale + 0.5f);
|
||||
}
|
||||
|
||||
public static int px2dip(Context context, float pxValue) {
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (pxValue / scale + 0.5f);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取控件的高度,如果获取的高度为0,则重新计算尺寸后再返回高度
|
||||
*
|
||||
* @param view
|
||||
* @return
|
||||
*/
|
||||
public static int getViewMeasuredHeight(View view) {
|
||||
calcViewMeasure(view);
|
||||
return view.getMeasuredHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取控件的宽度,如果获取的宽度为0,则重新计算尺寸后再返回宽度
|
||||
*
|
||||
* @param view
|
||||
* @return
|
||||
*/
|
||||
public static int getViewMeasuredWidth(View view) {
|
||||
calcViewMeasure(view);
|
||||
return view.getMeasuredWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* 测量控件的尺寸
|
||||
*
|
||||
* @param view
|
||||
*/
|
||||
public static void calcViewMeasure(View view) {
|
||||
|
||||
int width = MeasureSpec.makeMeasureSpec(0,
|
||||
MeasureSpec.UNSPECIFIED);
|
||||
int expandSpec = MeasureSpec.makeMeasureSpec(
|
||||
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
|
||||
view.measure(width, expandSpec);
|
||||
}
|
||||
|
||||
public void setVisible(boolean isEnable) {
|
||||
if (isEnable) {
|
||||
if(!isVisible()) {
|
||||
setVisibility(VISIBLE);
|
||||
}
|
||||
} else {
|
||||
if(isVisible())
|
||||
setVisibility(GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return getVisibility() == VISIBLE ? true : false;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
package com.tencent.map.vector.demo.basic;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdate;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.UiSettings;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.IndoorBuilding;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.IndoorInfo;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.IndoorLevel;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.MapPoi;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.Marker;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions;
|
||||
import com.tencent.tencentmap.mapsdk.vector.utils.clustering.ClusterItem;
|
||||
import com.tencent.tencentmap.mapsdk.vector.utils.clustering.ClusterManager;
|
||||
import com.tencent.tencentmap.mapsdk.vector.utils.clustering.algo.NonHierarchicalDistanceBasedAlgorithm;
|
||||
import com.tencent.tencentmap.mapsdk.vector.utils.clustering.view.DefaultClusterRenderer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class IndoorMapActivity extends AppCompatActivity implements TencentMap.OnIndoorStateChangeListener {
|
||||
|
||||
private static final String TAG = "IndoorMapActivity";
|
||||
private MapView mapView;
|
||||
private TencentMap tencentMap;
|
||||
private IndoorFloorView indoorFloorView;
|
||||
private UiSettings uiSettings;
|
||||
private Handler handler = new Handler();
|
||||
private String floorName;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_indoor);
|
||||
mapView = findViewById(R.id.mapView);
|
||||
indoorFloorView = findViewById(R.id.indoor_floor);
|
||||
if (tencentMap == null) {
|
||||
tencentMap = mapView.getMap();
|
||||
}
|
||||
//欧美汇室内地图,需Key开通室内地图权限
|
||||
CameraUpdate camera =
|
||||
CameraUpdateFactory.newCameraPosition(new CameraPosition(
|
||||
new LatLng(39.979382, 116.314106),
|
||||
18,
|
||||
0f,
|
||||
0f));
|
||||
tencentMap.moveCamera(camera);
|
||||
final ArrayList<MarkerCluster> markerClusters = new ArrayList<>();
|
||||
|
||||
uiSettings = tencentMap.getUiSettings();
|
||||
tencentMap.setIndoorEnabled(true);
|
||||
//设置室内蒙层颜色 sdk版本4.3.5新增接口
|
||||
tencentMap.setIndoorMaskColor(R.color.color_C71585);
|
||||
//设置室内图状态变化监听
|
||||
tencentMap.setOnIndoorStateChangeListener(this);
|
||||
tencentMap.setMapType(TencentMap.MAP_TYPE_DARK);
|
||||
//设置是否隐藏楼层控件
|
||||
uiSettings.setIndoorLevelPickerEnabled(false);
|
||||
indoorFloorView.setOnIndoorFloorListener(new MyIndoorViewAdapter());
|
||||
ClusterManager<MarkerCluster> markerClusterClusterManager = new ClusterManager<MarkerCluster>(this, tencentMap);
|
||||
NonHierarchicalDistanceBasedAlgorithm<MarkerCluster> nba = new NonHierarchicalDistanceBasedAlgorithm<>(this);
|
||||
nba.setMaxDistanceAtZoom(15);
|
||||
markerClusterClusterManager.setAlgorithm(nba);
|
||||
DefaultClusterRenderer<MarkerCluster> renderer = new DefaultClusterRenderer<>(this, tencentMap, markerClusterClusterManager);
|
||||
renderer.setMinClusterSize(2);
|
||||
renderer.setBuckets(new int[]{5, 10, 20});
|
||||
markerClusterClusterManager.setRenderer(renderer);
|
||||
//添加室内图marker
|
||||
tencentMap.setOnMapPoiClickListener(new TencentMap.OnMapPoiClickListener() {
|
||||
@Override
|
||||
public void onClicked(MapPoi mapPoi) {
|
||||
LatLng position = mapPoi.getPosition();
|
||||
MarkerOptions markerOptions = new MarkerOptions().position(position).title(mapPoi.name).infoWindowEnable(true);
|
||||
if (!TextUtils.isEmpty("F3")) {
|
||||
markerOptions.indoorInfo(new IndoorInfo("11000023805", "F3"));
|
||||
|
||||
}
|
||||
Marker marker = tencentMap.addMarker(markerOptions);
|
||||
LatLng position1 = mapPoi.getPosition();
|
||||
markerClusters.add(new MarkerCluster(position1.getLatitude(), position1.getLongitude()));
|
||||
|
||||
}
|
||||
});
|
||||
tencentMap.setOnCameraChangeListener(markerClusterClusterManager);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onIndoorBuildingFocused() {
|
||||
Log.d(TAG, "onIndoorBuildingFocused: 室内图场景激活回调");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onIndoorLevelActivated(final IndoorBuilding indoorBuilding) {
|
||||
if (indoorBuilding != null) {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
indoorFloorView.setVisible(true);
|
||||
if (mIndoorBuilding == null || !mIndoorBuilding.getBuidlingId().equals(indoorBuilding.getBuidlingId())) {
|
||||
List<IndoorLevel> levels = indoorBuilding.getLevels();
|
||||
String[] activedIndoorFloorNames1 = tencentMap.getActivedIndoorFloorNames();
|
||||
indoorFloorView.setItems(activedIndoorFloorNames1);
|
||||
for (int i = 0; i < levels.size(); i++) {
|
||||
floorName = levels.get(i).getName();
|
||||
indoorFloorView.setSeletion(floorName);
|
||||
}
|
||||
}
|
||||
mIndoorBuilding = indoorBuilding;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
indoorFloorView.setVisible(false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onIndoorBuildingDeactivated() {
|
||||
Log.d(TAG, "onIndoorBuildingDeactivated: 当前室内图处于无效状态");
|
||||
return false;
|
||||
}
|
||||
|
||||
IndoorBuilding mIndoorBuilding = null;
|
||||
|
||||
private class MyIndoorViewAdapter implements IndoorFloorView.OnIndoorFloorListener {
|
||||
|
||||
@Override
|
||||
public void onSelected(int selectedIndex) {
|
||||
if (mIndoorBuilding != null) {
|
||||
|
||||
List<IndoorLevel> levels = mIndoorBuilding.getLevels();
|
||||
String activedIndoorFloorName = tencentMap.getActivedIndoorFloorNames()[selectedIndex];
|
||||
String name = levels.get(selectedIndex).getName();
|
||||
name = activedIndoorFloorName;
|
||||
String buidlingId = mIndoorBuilding.getBuidlingId();
|
||||
tencentMap.setIndoorFloor(buidlingId, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MarkerCluster implements ClusterItem {
|
||||
|
||||
private final LatLng latLng;
|
||||
|
||||
public MarkerCluster(double lat, double longitude) {
|
||||
latLng = new LatLng(lat, longitude);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LatLng getPosition() {
|
||||
|
||||
return latLng;
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package com.tencent.map.vector.demo.basic;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.TextureView;
|
||||
import android.view.View;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapRenderLayer;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMapOptions;
|
||||
import com.tencent.tencentmap.mapsdk.maps.UiSettings;
|
||||
|
||||
public class MapRenderLayerActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener {
|
||||
|
||||
private TextureView textureView;
|
||||
private MapRenderLayer mapRenderLayer;
|
||||
private TencentMap tencentMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_map_render_layer);
|
||||
textureView = findViewById(R.id.textureView);
|
||||
textureView.setOpaque(false);
|
||||
textureView.setSurfaceTextureListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
||||
TencentMapOptions mapOptions = new TencentMapOptions();
|
||||
// mapOptions.setMapKey("");
|
||||
mapOptions.setExtSurface(surface);
|
||||
mapOptions.setExtSurfaceDimension(width, height);
|
||||
mapRenderLayer = new MapRenderLayer(this, mapOptions);
|
||||
// mapRenderLayer.onResume();
|
||||
textureView.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
mapRenderLayer.onTouchEvent(event);
|
||||
mapRenderLayer.dispatchTouchEvent(event);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
tencentMap = mapRenderLayer.getMap();
|
||||
tencentMap.setMapStyle(3);
|
||||
UiSettings uiSettings = tencentMap.getUiSettings();
|
||||
uiSettings.setAllGesturesEnabled(true);
|
||||
tencentMap.moveCamera(CameraUpdateFactory.zoomTo(8));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
|
||||
if (mapRenderLayer != null) {
|
||||
mapRenderLayer.onSurfaceChanged(surface, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
|
||||
if (mapRenderLayer != null) {
|
||||
mapRenderLayer.onDestroy();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
|
||||
if (mapRenderLayer != null) {
|
||||
mapRenderLayer.onStart();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (mapRenderLayer != null) {
|
||||
mapRenderLayer.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestart() {
|
||||
super.onRestart();
|
||||
if (mapRenderLayer != null) {
|
||||
mapRenderLayer.onRestart();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
if (mapRenderLayer != null) {
|
||||
mapRenderLayer.onStop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mapRenderLayer != null) {
|
||||
mapRenderLayer.onDestroy();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.tencent.map.vector.demo.basic;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdate;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
|
||||
/**
|
||||
* Demonstrates the different base layers of a map.
|
||||
*/
|
||||
@SuppressLint("NewApi")
|
||||
public class MapStyleDemoActivity extends FragmentActivity implements TencentMap.OnCameraChangeListener {
|
||||
private MapView mMapView;
|
||||
private TextView mTextView;
|
||||
private TencentMap mTencentMap;
|
||||
private Switch mSwitch;
|
||||
private Spinner mSpinner;
|
||||
|
||||
private String[] styles = new String[]{"style1", "style2", "style3", "style4", "style5",
|
||||
"normal", "traffic_navi", "traffic_navi_night", "satellite", "night", "navi", "night", "eagle_day", "eagle_night"};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_map_style);
|
||||
mMapView = findViewById(R.id.map_view);
|
||||
mTextView = findViewById(R.id.tv_level);
|
||||
mSwitch=findViewById(R.id.switch_open);
|
||||
mTencentMap = mMapView.getMap();
|
||||
CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(new CameraPosition(new LatLng(39.901268, 116.403854), 11f, 0f, 0f));
|
||||
mTencentMap.moveCamera(cameraUpdate);
|
||||
//mTencentMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(39.901268, 116.403854))); //移动地图
|
||||
mTencentMap.setOnCameraChangeListener(this);
|
||||
mSpinner = findViewById(R.id.sp_style);
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_dropdown_item, styles);
|
||||
mSpinner.setAdapter(adapter);
|
||||
mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (position < 5) {
|
||||
mTencentMap.setMapStyle(position + 1);
|
||||
}
|
||||
switch (position) {
|
||||
case 5:
|
||||
mTencentMap.setMapStyle(TencentMap.MAP_TYPE_NORMAL);
|
||||
break;
|
||||
case 6:
|
||||
mTencentMap.setMapStyle(TencentMap.MAP_TYPE_TRAFFIC_NAVI);
|
||||
break;
|
||||
case 7:
|
||||
mTencentMap.setMapStyle(TencentMap.MAP_TYPE_TRAFFIC_NIGHT);
|
||||
break;
|
||||
case 8:
|
||||
mTencentMap.setMapStyle(TencentMap.MAP_TYPE_SATELLITE);
|
||||
break;
|
||||
case 9:
|
||||
mTencentMap.setMapStyle(TencentMap.MAP_TYPE_NIGHT);
|
||||
break;
|
||||
case 10:
|
||||
mTencentMap.setMapStyle(TencentMap.MAP_TYPE_NAVI);
|
||||
break;
|
||||
case 11:
|
||||
mTencentMap.setMapStyle(13 + 1000);
|
||||
break;
|
||||
case 12:
|
||||
mTencentMap.setMapStyle(14 + 1000);
|
||||
break;
|
||||
case 13:
|
||||
mTencentMap.setMapStyle(15 + 1000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
RadioGroup rg = findViewById(R.id.rg_map_type);
|
||||
rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(RadioGroup group, int checkedId) {
|
||||
switch (checkedId) {
|
||||
case R.id.rb_normal_type:
|
||||
if (mTencentMap != null) {
|
||||
mTencentMap.setMapType(TencentMap.MAP_TYPE_NORMAL);
|
||||
}
|
||||
break;
|
||||
case R.id.rb_dark_type:
|
||||
if (mTencentMap != null) {
|
||||
mTencentMap.setMapType(TencentMap.MAP_TYPE_DARK);
|
||||
}
|
||||
break;
|
||||
case R.id.rb_sagellite_type:
|
||||
if (mTencentMap != null) {
|
||||
mTencentMap.setMapType(TencentMap.MAP_TYPE_SATELLITE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
mTencentMap.getUiSettings().setCompassEnabled(true);
|
||||
mTencentMap.getUiSettings().setMyLocationButtonEnabled(true);
|
||||
mSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
PorterDuff.Mode buttonTintMode = compoundButton.getButtonTintMode();
|
||||
if(b){
|
||||
mTencentMap.setBuildingEnable(true);
|
||||
}else{
|
||||
mTencentMap.setBuildingEnable(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mMapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mMapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mMapView.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mMapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mMapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraChange(CameraPosition cameraPosition) {
|
||||
Log.i("TAG","地图滑动了");
|
||||
mTextView.setText("当前缩放级别为:" + cameraPosition.zoom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraChangeFinished(CameraPosition cameraPosition) {
|
||||
Log.i("TAG","地图滑动了");
|
||||
mTextView.setText("当前缩放级别为:" + cameraPosition.zoom);
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package com.tencent.map.vector.demo.basic;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.map.vector.demo.heatoverlay.ScatterPlotOverlayActivity;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMapOptions;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TextureMapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
|
||||
public class MapViewActivity extends AppCompatActivity {
|
||||
|
||||
/**
|
||||
* 由于SDK并没有提供用于MapView管理地图生命周期的Activity
|
||||
* 因此需要用户继承Activity后管理地图的生命周期,防止内存泄露
|
||||
*/
|
||||
|
||||
private TextureMapView mapView;
|
||||
protected TencentMap tencentMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_map_view);
|
||||
|
||||
mapView = findViewById(R.id.mapview);
|
||||
mapView.setOpaque(false);
|
||||
//创建tencentMap地图对象,可以完成对地图的几乎所有操作
|
||||
tencentMap = mapView.getMap();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* mapview的生命周期管理
|
||||
*/
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestart() {
|
||||
super.onRestart();
|
||||
mapView.onRestart();
|
||||
}
|
||||
}
|
@ -0,0 +1,559 @@
|
||||
//package com.tencent.map.vector.demo.basic;
|
||||
//
|
||||
//import androidx.annotation.NonNull;
|
||||
//import androidx.annotation.Nullable;
|
||||
//import androidx.appcompat.app.AppCompatActivity;
|
||||
//import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
//import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
//import androidx.recyclerview.widget.RecyclerView;
|
||||
//
|
||||
//import android.content.BroadcastReceiver;
|
||||
//import android.content.Context;
|
||||
//import android.content.Intent;
|
||||
//import android.content.IntentFilter;
|
||||
//import android.net.ConnectivityManager;
|
||||
//import android.net.NetworkInfo;
|
||||
//import android.os.Build;
|
||||
//import android.os.Bundle;
|
||||
//import android.os.Handler;
|
||||
//import android.os.Message;
|
||||
//import android.util.Log;
|
||||
//import android.view.LayoutInflater;
|
||||
//import android.view.Menu;
|
||||
//import android.view.MenuItem;
|
||||
//import android.view.View;
|
||||
//import android.view.ViewGroup;
|
||||
//import android.widget.Button;
|
||||
//import android.widget.LinearLayout;
|
||||
//import android.widget.TextView;
|
||||
//import android.widget.Toast;
|
||||
//
|
||||
//import com.tencent.map.sdk.comps.offlinemap.OfflineItem;
|
||||
//import com.tencent.map.sdk.comps.offlinemap.OfflineItemController;
|
||||
//import com.tencent.map.sdk.comps.offlinemap.OfflineMapComponent;
|
||||
//import com.tencent.map.sdk.comps.offlinemap.OfflineMapSyncedListener;
|
||||
//import com.tencent.map.sdk.comps.offlinemap.OfflineStatus;
|
||||
//import com.tencent.map.sdk.comps.offlinemap.OfflineStatusChangedListener;
|
||||
//import cc.winboll.studio.positions.R;
|
||||
//import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
//import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
//import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
//import com.tencent.tencentmap.mapsdk.maps.TencentMapOptions;
|
||||
//import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
//import com.tencent.tencentmap.mapsdk.maps.model.LatLngBounds;
|
||||
//import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions;
|
||||
//
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.List;
|
||||
//
|
||||
//
|
||||
///**
|
||||
// * 离线地图下载、取消下载、删除
|
||||
// */
|
||||
//public class OfflineMapActivity extends AppCompatActivity {
|
||||
// private static final String TAG = "OfflineMapActivity";
|
||||
// private Button btnGoWork;
|
||||
// private Button btnZoomIn;
|
||||
// private Button btnZoomOut;
|
||||
// private Button btnReboot;
|
||||
// private Button btnSync;
|
||||
// private Button btnRefresh;
|
||||
// private MapView mapView;
|
||||
// private RecyclerView offlineItemRecycleView;
|
||||
//
|
||||
// private TencentMap map;
|
||||
// private OfflineMapComponent offlineComp;
|
||||
//
|
||||
// private OfflineAdapter offlineAdapter;
|
||||
//
|
||||
// private List<OfflineItem> offlineItems = new ArrayList<>();
|
||||
//
|
||||
// private IntentFilter intentFilter;
|
||||
// private NetworkChangeReceiver networkChangeReceiver;
|
||||
// private ConnectivityManager connectivityManager;
|
||||
// private TextView tvParmes;
|
||||
//
|
||||
// @Override
|
||||
// protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
// super.onCreate(savedInstanceState);
|
||||
// setContentView(R.layout.activity_offline_map);
|
||||
// btnGoWork = findViewById(R.id.btn_go_work);
|
||||
// btnZoomIn = findViewById(R.id.btn_zoom_in);
|
||||
// btnZoomOut = findViewById(R.id.btn_zoom_out);
|
||||
// btnReboot = findViewById(R.id.btn_reboot_map);
|
||||
// btnSync = findViewById(R.id.btn_sync);
|
||||
// btnRefresh = findViewById(R.id.btn_refresh);
|
||||
// mapView = findViewById(R.id.map_view);
|
||||
// tvParmes = findViewById(R.id.tv_parmes);
|
||||
// offlineItemRecycleView = findViewById(R.id.offline_item_list);
|
||||
// connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
//
|
||||
// initMap();
|
||||
// //重置地图
|
||||
// btnReboot.setOnClickListener(new View.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(View v) {
|
||||
// if (map != null) {
|
||||
// mapView.onPause();
|
||||
// mapView.onStop();
|
||||
// mapView.onDestroy();
|
||||
// map = null;
|
||||
// initMap();
|
||||
// mapView.onStart();
|
||||
// mapView.onResume();
|
||||
// tvParmes.setText("重置地图");
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// offlineAdapter = new OfflineAdapter(offlineItems);
|
||||
// offlineItemRecycleView.setLayoutManager(new LinearLayoutManager(this));
|
||||
// offlineItemRecycleView.setAdapter(offlineAdapter);
|
||||
// offlineItemRecycleView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
|
||||
// intentFilter = new IntentFilter();
|
||||
// intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
|
||||
// networkChangeReceiver = new NetworkChangeReceiver();
|
||||
// }
|
||||
//
|
||||
// private void initMap() {
|
||||
// // 设置离线地图
|
||||
// TencentMapOptions options = new TencentMapOptions();
|
||||
// options.setOfflineMapEnable(true);
|
||||
//
|
||||
// map = mapView.getMap(options);
|
||||
//
|
||||
// map.addOnMapLoadedCallback(new TencentMap.OnMapLoadedCallback() {
|
||||
// @Override
|
||||
// public void onMapLoaded() {
|
||||
// Toast.makeText(OfflineMapActivity.this, "地图加载完成", Toast.LENGTH_SHORT).show();
|
||||
// }
|
||||
// });
|
||||
// //获取离线地图的城市列表
|
||||
// offlineComp = map.getMapComponent(OfflineMapComponent.class);
|
||||
//
|
||||
// Log.d(TAG, "Offline enable:" + offlineComp.isOfflineMapEnable());
|
||||
//
|
||||
// // 回公司按钮
|
||||
// btnGoWork.setOnClickListener(new View.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(View view) {
|
||||
// List<LatLng> latLngs = new ArrayList<>();
|
||||
// latLngs.add(new LatLng(40.042893, 116.269673));
|
||||
// latLngs.add(new LatLng(40.038951, 116.275241));
|
||||
// LatLng center = new LatLng(40.040429, 116.273525);
|
||||
// map.addMarker(new MarkerOptions(center)
|
||||
// .anchor(0.5f, 1));
|
||||
// map.moveCamera(CameraUpdateFactory.newLatLngBoundsWithMapCenter(
|
||||
// new LatLngBounds.Builder()
|
||||
// .include(latLngs)
|
||||
// .build(),
|
||||
// center,
|
||||
// 100));
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// // 地图放大按钮
|
||||
// btnZoomIn.setOnClickListener(new View.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(View view) {
|
||||
// map.moveCamera(CameraUpdateFactory.zoomIn());
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// // 地图缩小按钮
|
||||
// btnZoomOut.setOnClickListener(new View.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(View view) {
|
||||
// map.moveCamera(CameraUpdateFactory.zoomOut());
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// // 同步离线地图信息按钮
|
||||
// btnSync.setOnClickListener(new View.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(View view) {
|
||||
// syncData();
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// // 刷新离线地图列表按钮
|
||||
// btnRefresh.setOnClickListener(new View.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(View view) {
|
||||
// offlineItemRecycleView.setVisibility(View.VISIBLE);
|
||||
// refreshOfflineList();
|
||||
// }
|
||||
// });
|
||||
// map.moveCamera(CameraUpdateFactory.zoomTo(5)); // 设置缩放级别,显示全国概略图.
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void onStart() {
|
||||
// super.onStart();
|
||||
// mapView.onStart();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void onResume() {
|
||||
// super.onResume();
|
||||
// mapView.onResume();
|
||||
// registerReceiver(networkChangeReceiver, intentFilter);
|
||||
//
|
||||
//// offlineItems.addAll(offlineComp.getOfflineItemList());
|
||||
//// tryToOpenOffline();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void onPause() {
|
||||
// super.onPause();
|
||||
// mapView.onPause();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void onStop() {
|
||||
// super.onStop();
|
||||
// mapView.onStop();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void onDestroy() {
|
||||
// super.onDestroy();
|
||||
// mapView.onDestroy();
|
||||
// }
|
||||
//
|
||||
// private class OfflineAdapter extends RecyclerView.Adapter<OfflineAdapter.OfflineViewHolder> {
|
||||
//
|
||||
// List<OfflineItem> offlineItems;
|
||||
//
|
||||
// OfflineAdapter(List<OfflineItem> offlineItems) {
|
||||
// this.offlineItems = offlineItems;
|
||||
// }
|
||||
//
|
||||
// @NonNull
|
||||
// @Override
|
||||
// public OfflineViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
// View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_offline
|
||||
// , parent, false);
|
||||
// return new OfflineViewHolder(view);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onBindViewHolder(@NonNull OfflineViewHolder holder, int position) {
|
||||
// final OfflineItem offlineItem = offlineItems.get(position);
|
||||
//
|
||||
// final OfflineItemController cityController =
|
||||
// offlineComp.getOfflineItemController(offlineItem, statusChangedListener);
|
||||
// if (cityController == null) {
|
||||
// holder.tvTitle.setText("【controller is null】" + offlineItem.toString());
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// holder.tvTitle.setText(offlineItem.toString());
|
||||
//
|
||||
// holder.btnSwitch.setOnClickListener(new View.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(View v) {
|
||||
// boolean isClosed = cityController.close();
|
||||
// if (isClosed) {
|
||||
// // toast("已关闭【" + offlineItem.getName() + "】的离线地图");
|
||||
// tvParmes.setText("已关闭【" + offlineItem.getName() + "】的离线地图");
|
||||
//
|
||||
// }
|
||||
// Log.d(TAG, offlineItem.getName() + " close offline:" + isClosed);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// holder.btnDownload.setOnClickListener(new View.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(View v) {
|
||||
// downloadOffline(offlineItem);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// holder.btnDelete.setOnClickListener(new View.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(View v) {
|
||||
// boolean isDeleted = cityController.removeCache();
|
||||
// if (isDeleted) {
|
||||
// // toast("缓存移除成功");
|
||||
// tvParmes.setText("缓存移除成功");
|
||||
// } else {
|
||||
// // toast("缓存移除失败");
|
||||
// tvParmes.setText("缓存移除失败");
|
||||
// }
|
||||
// Log.d(TAG, offlineItem.getName() + " remove cache:" + isDeleted);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public int getItemCount() {
|
||||
// return offlineItems.size();
|
||||
// }
|
||||
//
|
||||
// class OfflineViewHolder extends RecyclerView.ViewHolder {
|
||||
//
|
||||
// TextView tvTitle;
|
||||
// Button btnSwitch;
|
||||
// Button btnDownload;
|
||||
// Button btnDelete;
|
||||
//
|
||||
// public OfflineViewHolder(@NonNull View itemView) {
|
||||
// super(itemView);
|
||||
// tvTitle = itemView.findViewById(R.id.tv_offline_title);
|
||||
// btnSwitch = itemView.findViewById(R.id.btn_switch_offline);
|
||||
// btnDownload = itemView.findViewById(R.id.btn_download_offline);
|
||||
// btnDelete = itemView.findViewById(R.id.btn_delete_offline);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// OfflineStatusChangedListener statusChangedListener = new OfflineStatusChangedListener() {
|
||||
// @Override
|
||||
// public void onStatusChanged(OfflineItem offlineItem, OfflineStatus offlineStatus) {
|
||||
// Log.d(TAG, offlineItem.getName() + " onStatusChanged: " + offlineStatus);
|
||||
// final Message msg = new Message();
|
||||
// msg.obj = offlineItem;
|
||||
// switch (offlineStatus) {
|
||||
// case OPEN: //开始离线
|
||||
// new Thread(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// msg.what = STATE_OPEN;
|
||||
// mHandler.sendMessage(msg);
|
||||
// }
|
||||
// }).start();
|
||||
// break;
|
||||
// case CLOSE: //关闭离线
|
||||
// break;
|
||||
// case COMPLETED: //完成下载
|
||||
// new Thread(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// msg.what = STATE_COMPLETED;
|
||||
// mHandler.sendMessage(msg);
|
||||
// }
|
||||
// }).start();
|
||||
// if (offlineItem.getPercentage() == 100 && offlineItem.getPinyin().equals("china2")) {
|
||||
// OfflineItemController cityController = offlineComp.getOfflineItemController(offlineItem,
|
||||
// statusChangedListener);
|
||||
// cityController.open();
|
||||
// map.moveCamera(CameraUpdateFactory.zoomTo(5)); // 设置缩放级别,显示全国概略图.
|
||||
// } else if (offlineItem.getPercentage() == 100 && offlineItem.getPinyin().equals("beijingshi")) {
|
||||
// OfflineItemController cityController = offlineComp.getOfflineItemController(offlineItem,
|
||||
// statusChangedListener);
|
||||
// cityController.open();
|
||||
// map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(39.909018, 116.397427), 16));
|
||||
// } else if (offlineItem.getPercentage() == 100 && offlineItem.getPinyin().equals("shanghaishi")) {
|
||||
// OfflineItemController cityController = offlineComp.getOfflineItemController(offlineItem,
|
||||
// statusChangedListener);
|
||||
// cityController.open();
|
||||
// map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(31.230378, 121.473658), 16));
|
||||
// } else if (offlineItem.getPercentage() == 100 && offlineItem.getPinyin().equals("tianjinshi")) {
|
||||
// OfflineItemController cityController = offlineComp.getOfflineItemController(offlineItem,
|
||||
// statusChangedListener);
|
||||
// cityController.open();
|
||||
// map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(39.085294, 117.201538), 16));
|
||||
// } else {
|
||||
// toast("可参考demo自行移动视野范围");
|
||||
// }
|
||||
// break;
|
||||
// case CANCEL: //取消下载
|
||||
// toast("取消下载");
|
||||
// new Thread(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// msg.what = STATE_CANCEL;
|
||||
// mHandler.sendMessage(msg);
|
||||
// }
|
||||
// }).start();
|
||||
// break;
|
||||
// case DOWNLOADING: //下载中
|
||||
// new Thread(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// msg.what = STATE_DOWNLOAD;
|
||||
// mHandler.sendMessage(msg);
|
||||
// }
|
||||
// }).start();
|
||||
// break;
|
||||
// case ERROR: //离线错误
|
||||
// toast("离线错误");
|
||||
// break;
|
||||
// case READY: //准备下载
|
||||
// toast("准备下载");
|
||||
// break;
|
||||
// case START: //开始下载
|
||||
// msg.what = STATE_START;
|
||||
// mHandler.sendMessage(msg);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// private void refreshOfflineList() {
|
||||
// //获取离线地图列表
|
||||
// List<OfflineItem> offlineItems = offlineComp.getOfflineItemList();
|
||||
// Log.d(TAG, "Offline Items num:" + offlineItems.size());
|
||||
//// for (OfflineItem item : offlineItems) {
|
||||
//// Log.d(TAG, item.toString());
|
||||
//// }
|
||||
//
|
||||
// this.offlineItems.clear();
|
||||
// this.offlineItems.addAll(offlineItems);
|
||||
// offlineAdapter.notifyDataSetChanged();
|
||||
// toast("刷新离线地图列表");
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private void tryToOpenOffline() {
|
||||
// // 无网情况主动开启离线地图
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// if (connectivityManager.getActiveNetwork() == null) {
|
||||
// Log.d(TAG, "tryToOpenOffline: 无网络,尝试开启离线地图,item size:" + offlineItems.size());
|
||||
// for (OfflineItem item : offlineItems) {
|
||||
// if (item.getPercentage() == 100 && item.getPinyin().equals("beijingshi")) {
|
||||
// OfflineItemController cityController = offlineComp.getOfflineItemController(item,
|
||||
// statusChangedListener);
|
||||
// if (cityController == null) {
|
||||
// Log.d(TAG, item.getName() + "try: controller is null");
|
||||
// } else {
|
||||
// Log.d(TAG, item.getName() + "try: openOffline: " + cityController.open());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// toast("require API > M(23)");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void closeOffline() {
|
||||
// List<OfflineItem> items = offlineComp.getOfflineItemList();
|
||||
// Log.d(TAG, "closeOffline: ,item size:" + items.size());
|
||||
// for (OfflineItem item : items) {
|
||||
// if (item.getPercentage() == 100) {
|
||||
// OfflineItemController cityController = offlineComp.getOfflineItemController(item,
|
||||
// statusChangedListener);
|
||||
// if (cityController == null) {
|
||||
// Log.d(TAG, item.getName() + "close: controller is null");
|
||||
// } else {
|
||||
// Log.d(TAG, item.getName() + "close: close Offline: " + cityController.close());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private void syncData() {
|
||||
// //同步最新数据
|
||||
// offlineComp.syncLatestData(new OfflineMapSyncedListener() {
|
||||
// @Override
|
||||
// public void onSynced(boolean b) {
|
||||
// Log.d(TAG, "onSynced: " + b);
|
||||
// refreshOfflineList();
|
||||
// // tryToOpenOffline();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// private void downloadOffline(OfflineItem offlineItem) {
|
||||
// //获取某一Item的离线地图数据
|
||||
// OfflineItemController cityController = offlineComp.getOfflineItemController(offlineItem, statusChangedListener);
|
||||
// if (cityController == null) {
|
||||
// Toast.makeText(this, "cityController为NULL", Toast.LENGTH_SHORT).show();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// boolean needDownload = cityController.checkInvalidate();
|
||||
// Log.d(TAG, "need download:" + cityController.checkInvalidate());
|
||||
// if (needDownload) {
|
||||
// //执行下载
|
||||
// cityController.startDownload();
|
||||
// tvParmes.setText("开始下载【" + offlineItem.getName() + "】的离线地图");
|
||||
// } else {
|
||||
// //跳过更新,打开离线
|
||||
// boolean isOpened = cityController.open();
|
||||
// if (isOpened) {
|
||||
// tvParmes.setText("已开启【" + offlineItem.getName() + "】的离线地图");
|
||||
// }
|
||||
// Log.d(TAG, offlineItem.getName() + " open offline:" + isOpened);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private final class NetworkChangeReceiver extends BroadcastReceiver {
|
||||
// @Override
|
||||
// public void onReceive(Context context, Intent intent) {
|
||||
// NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
|
||||
// //获取离线那地图列表
|
||||
// List<OfflineItem> items = offlineComp.getOfflineItemList();
|
||||
// Log.d(TAG, "onReceive: 网络状态变化, offline item size:" + items.size());
|
||||
// if (networkInfo != null) {
|
||||
// Toast.makeText(context, "当前无网络连接", Toast.LENGTH_SHORT).show();
|
||||
// for (OfflineItem item : items) {
|
||||
// if (item.getPercentage() == 100) {
|
||||
// OfflineItemController cityController = offlineComp.getOfflineItemController(item,
|
||||
// statusChangedListener);
|
||||
// if (cityController == null) {
|
||||
// Log.d(TAG, item.getName() + " controller is null");
|
||||
// } else {
|
||||
// Log.d(TAG, item.getName() + " closeOffline: " + cityController.close());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// // 加载所有已下载的离线地图
|
||||
// items = offlineComp.getOfflineItemList();
|
||||
// for (OfflineItem item : items) {
|
||||
// if (item.getPercentage() == 100) {
|
||||
// OfflineItemController cityController = offlineComp.getOfflineItemController(item,
|
||||
// statusChangedListener);
|
||||
// if (cityController == null) {
|
||||
// Log.d(TAG, item.getName() + " controller is null");
|
||||
// } else {
|
||||
// Log.d(TAG, item.getName() + " openOffline: " + cityController.open());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private final int STATE_DOWNLOAD = 1;
|
||||
// private final int STATE_COMPLETED = 2;
|
||||
// private final int STATE_OPEN = 3;
|
||||
// private final int STATE_CANCEL = 4;
|
||||
// private final int STATE_START = 5;
|
||||
//
|
||||
// private Handler mHandler = new Handler() {
|
||||
// public void handleMessage(Message msg) {
|
||||
// OfflineItem item = (OfflineItem) msg.obj;
|
||||
// switch (msg.what) {
|
||||
// case STATE_DOWNLOAD:
|
||||
// if (item.getPercentage() % 10 == 0) {
|
||||
// tvParmes.setText("正在下载【" + item.getName() + "】离线地图:" + item.getPercentage() + "%");
|
||||
// Log.d("getPercentage", item.getPercentage() + "");
|
||||
// }
|
||||
// break;
|
||||
// case STATE_COMPLETED:
|
||||
// tvParmes.setText(item.getName() + "离线地图下载结束");
|
||||
// break;
|
||||
// case STATE_OPEN:
|
||||
// tvParmes.setText(item.getName() + "离线地图已开启 ");
|
||||
// break;
|
||||
// case STATE_CANCEL:
|
||||
// break;
|
||||
// case STATE_START:
|
||||
// tvParmes.setText(item.getName() + "离线地图开始下载,点击刷新列表查看进度");
|
||||
// break;
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// private void toast(String msg) {
|
||||
// Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
|
||||
// }
|
||||
//
|
||||
//}
|
@ -0,0 +1,91 @@
|
||||
package com.tencent.map.vector.demo.basic;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdate;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMapContext;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.Language;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.OverSeaTileProvider;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Locale;
|
||||
|
||||
public class OverseaMapActivity extends SupportMapFragmentActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
//纽约时代广场海外地图,需Key开通海外位置服务权限
|
||||
CameraUpdate cameraSigma =
|
||||
CameraUpdateFactory.newCameraPosition(new CameraPosition(
|
||||
new LatLng(40.75797, -73.985542),
|
||||
11,
|
||||
0f,
|
||||
0f));
|
||||
//移动地图
|
||||
tencentMap.moveCamera(cameraSigma);
|
||||
//设置自定义海外图源
|
||||
tencentMap.setOverSeaTileProvider(new CustomOverSeaTileProvider(tencentMap.getMapContext()));
|
||||
}
|
||||
|
||||
class CustomOverSeaTileProvider extends OverSeaTileProvider {
|
||||
boolean mIsZhLanguage;
|
||||
boolean mIsNight;
|
||||
|
||||
/**
|
||||
* 创建海外图源供应
|
||||
*/
|
||||
public CustomOverSeaTileProvider(TencentMapContext context){
|
||||
//设置名称和版本号
|
||||
super("custom", 1, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getTileUrl(int x, int y, int zoom) {
|
||||
String url = "https://xxxx.com/x=%d&y=%d&z=%d&s=%s&l=&s";
|
||||
String formatUrl = String.format(Locale.ENGLISH, url, x, y, zoom, mIsNight ? "dark" : "day", mIsZhLanguage ? "zh" : "en");
|
||||
try {
|
||||
return new URL(formatUrl);
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDayNightChange(boolean dayNight) {
|
||||
mIsNight = dayNight;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onLanguageChange(Language language) {
|
||||
mIsZhLanguage = (language == Language.zh);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap getLogo(boolean isNight) {
|
||||
AssetManager assetManager = getAssets();
|
||||
Bitmap iBitmap = null;
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = assetManager.open("logo.png");
|
||||
iBitmap = BitmapFactory.decodeStream(is);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
} catch (OutOfMemoryError ignored) {
|
||||
} finally {
|
||||
// IO.safeClose(is);
|
||||
}
|
||||
return iBitmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,135 @@
|
||||
package com.tencent.map.vector.demo.basic;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMapOptions;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class RecyclerListActivity extends FragmentActivity {
|
||||
|
||||
private static final String TAG = "RecyclerListActivity";
|
||||
|
||||
RecyclerView recyclerView;
|
||||
private MapViewAdapter mapViewAdapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_recycler_list);
|
||||
recyclerView = findViewById(R.id.rv_container);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
|
||||
mapViewAdapter = new MapViewAdapter(this);
|
||||
recyclerView.setAdapter(mapViewAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (recyclerView != null) {
|
||||
recyclerView.setAdapter(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MapViewHolder extends RecyclerView.ViewHolder {
|
||||
MapView mMapView;
|
||||
|
||||
public MapViewHolder(@NonNull View itemView, MapView mapView) {
|
||||
super(itemView);
|
||||
mMapView = mapView;
|
||||
}
|
||||
|
||||
public void onRecycle() {
|
||||
if (mMapView != null) {
|
||||
mMapView.onPause();
|
||||
mMapView.onStop();
|
||||
}
|
||||
}
|
||||
|
||||
public void onBind() {
|
||||
if (mMapView != null) {
|
||||
mMapView.onResume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MapViewAdapter extends RecyclerView.Adapter<MapViewHolder> {
|
||||
private List<MapView> mMapViews;
|
||||
private static final int COUNT = 15;
|
||||
private Context mContext;
|
||||
|
||||
public MapViewAdapter(Context context) {
|
||||
mContext = context.getApplicationContext();
|
||||
mMapViews = new LinkedList<>();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MapViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, final int type) {
|
||||
|
||||
FrameLayout mapContainer = new FrameLayout(mContext);
|
||||
if (type == 1) {
|
||||
TencentMapOptions tencentMapOptions = new TencentMapOptions();
|
||||
tencentMapOptions.setDisallowInterceptTouchEvent(true);
|
||||
MapView mapView = new MapView(mContext, tencentMapOptions);
|
||||
mapView.setId(View.NO_ID);
|
||||
mapView.setLayoutParams(new FrameLayout.LayoutParams(1000, 700));
|
||||
mapContainer.addView(mapView);
|
||||
|
||||
|
||||
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
|
||||
lp.gravity = Gravity.CENTER;
|
||||
return new MapViewHolder(mapContainer, mapView);
|
||||
} else {
|
||||
return new MapViewHolder(mapContainer, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull MapViewHolder mapViewHolder, int i) {
|
||||
mapViewHolder.onBind();
|
||||
if (mapViewHolder.mMapView != null) {
|
||||
mMapViews.add(mapViewHolder.mMapView);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return COUNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
|
||||
if (position % 3 == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return super.getItemViewType(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewRecycled(@NonNull MapViewHolder holder) {
|
||||
|
||||
holder.onRecycle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
|
||||
for (MapView mapView : mMapViews) {
|
||||
mapView.onDestroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.tencent.map.vector.demo.basic;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.RadioGroup;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
|
||||
|
||||
public class SetMapTypeActivity extends SupportMapFragmentActivity implements RadioGroup.OnCheckedChangeListener {
|
||||
private RadioGroup radioGroup;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
initView();
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
radioGroup = findViewById(R.id.lay_map_type);
|
||||
radioGroup.setVisibility(View.VISIBLE);
|
||||
radioGroup.setOnCheckedChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(RadioGroup radioGroup, int i) {
|
||||
switch (i) {
|
||||
case R.id.btn_normal: //普通地图-默认地图类型
|
||||
tencentMap.setMapType(TencentMap.MAP_TYPE_NORMAL);
|
||||
break;
|
||||
case R.id.btn_satellite: //卫星地图
|
||||
tencentMap.setMapType(TencentMap.MAP_TYPE_SATELLITE);
|
||||
break;
|
||||
case R.id.btn_dark: //暗色地图
|
||||
tencentMap.setMapType(TencentMap.MAP_TYPE_DARK);
|
||||
break;
|
||||
case R.id.btn_traffic:
|
||||
tencentMap.setTrafficEnabled(true);
|
||||
break;
|
||||
case R.id.style_map:
|
||||
/*TencentMapOptions mapOptions = new TencentMapOptions();
|
||||
//将本地资源打包到apk的asset目录中
|
||||
mapOptions.setCustomAssetsPath("myMapStyle");
|
||||
//参数1对应的是“我的样式”中的序号
|
||||
tencentMap.setMapStyle(1);
|
||||
MapView mMapView = new MapView(SetMapTypeActivity.this, mapOptions);*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.tencent.map.vector.demo.basic;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdate;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.SupportMapFragment;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.UiSettings;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
|
||||
public class SupportMapFragmentActivity extends AppCompatActivity {
|
||||
|
||||
/**
|
||||
* SDK提供了SupportMapFragment这个类来加载地图,这个类的方便之处就在于不用手动管理内存
|
||||
*/
|
||||
|
||||
private FragmentManager fm;
|
||||
protected TencentMap tencentMap;
|
||||
private SupportMapFragment supportMapFragment;
|
||||
protected UiSettings mapUiSettings;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_support_map_fragment);
|
||||
|
||||
//创建tencentMap地图对象,可以完成对地图的几乎所有操作
|
||||
fm = getSupportFragmentManager();
|
||||
supportMapFragment = (SupportMapFragment) fm.findFragmentById(R.id.map_frag);
|
||||
tencentMap = supportMapFragment.getMap();
|
||||
mapUiSettings = tencentMap.getUiSettings();
|
||||
//对地图操作类进行操作
|
||||
CameraUpdate cameraSigma =
|
||||
CameraUpdateFactory.newCameraPosition(new CameraPosition(
|
||||
new LatLng(39.984066, 116.307548),
|
||||
15,
|
||||
0f,
|
||||
0f));
|
||||
//移动地图
|
||||
tencentMap.moveCamera(cameraSigma);
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package com.tencent.map.vector.demo.basic;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.Switch;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMapOptions;
|
||||
|
||||
public class UiSettingsActivity extends SupportMapFragmentActivity {
|
||||
|
||||
|
||||
private Switch logoControl;
|
||||
private Switch compassControl;
|
||||
private Switch scaleViewControl;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
initView();
|
||||
}
|
||||
private void initView(){
|
||||
|
||||
logoControl = findViewById(R.id.switch_logo);
|
||||
compassControl = findViewById(R.id.switch_compass);
|
||||
scaleViewControl = findViewById(R.id.switch_scale_view);
|
||||
logoControl.setVisibility(View.VISIBLE);
|
||||
logoControl.setText("logo位置");
|
||||
compassControl.setVisibility(View.VISIBLE);
|
||||
compassControl.setText("指南针");
|
||||
scaleViewControl.setVisibility(View.VISIBLE);
|
||||
scaleViewControl.setText("比例尺");
|
||||
|
||||
//打开缩放
|
||||
mapUiSettings.setZoomControlsEnabled(true);
|
||||
//打开位置标志
|
||||
mapUiSettings.setMyLocationButtonEnabled(true);
|
||||
|
||||
|
||||
logoControl.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
if (b){
|
||||
//logo左下角
|
||||
mapUiSettings.setLogoPosition(TencentMapOptions.LOGO_POSITION_BOTTOM_LEFT);
|
||||
}else{
|
||||
//logo右上角
|
||||
mapUiSettings.setLogoPosition(TencentMapOptions.LOGO_POSITION_TOP_RIGHT);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
compassControl.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
if (b){
|
||||
//显示指南针
|
||||
mapUiSettings.setCompassEnabled(true);
|
||||
}else{
|
||||
//隐藏指南针
|
||||
mapUiSettings.setCompassEnabled(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
scaleViewControl.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
if (b){
|
||||
//打开比例尺
|
||||
mapUiSettings.setScaleViewEnabled(true);
|
||||
}else{
|
||||
//关闭比例尺
|
||||
mapUiSettings.setScaleViewEnabled(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.tencent.map.vector.demo.camera;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.tencent.map.vector.demo.basic.SupportMapFragmentActivity;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdate;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.Projection;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLngBounds;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.Marker;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.RestrictBoundsFitMode;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.VisibleRegion;
|
||||
|
||||
public class MapAnchorZoomActivity extends SupportMapFragmentActivity {
|
||||
private Marker marker;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
LatLng latLng = new LatLng(39.984108,116.307557);
|
||||
|
||||
CameraUpdate cameraSigma =
|
||||
CameraUpdateFactory.newCameraPosition(new CameraPosition(
|
||||
latLng,
|
||||
15,
|
||||
0f,
|
||||
0f));
|
||||
//移动地图
|
||||
tencentMap.moveCamera(cameraSigma);
|
||||
Projection projection = tencentMap.getProjection();
|
||||
|
||||
VisibleRegion region = projection.getVisibleRegion();
|
||||
|
||||
tencentMap.setRestrictBounds(new LatLngBounds(region.farRight, region.nearLeft), RestrictBoundsFitMode.FIT_HEIGHT);
|
||||
tencentMap.setRestrictBounds(new LatLngBounds(region.farRight, region.nearLeft), RestrictBoundsFitMode.FIT_WIDTH);
|
||||
setMarker(latLng);
|
||||
}
|
||||
/**
|
||||
* 设置标注
|
||||
*/
|
||||
private void setMarker(LatLng latLng){
|
||||
|
||||
MarkerOptions options = new MarkerOptions().position(latLng);
|
||||
|
||||
//设置infowindow
|
||||
options.title("锚点");
|
||||
marker = tencentMap.addMarker(options);
|
||||
marker.setInfoWindowEnable(true);
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.tencent.map.vector.demo.camera;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.RadioGroup;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.map.vector.demo.basic.SupportMapFragmentActivity;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLngBounds;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.RestrictBoundsFitMode;
|
||||
|
||||
public class MapBoundActivity extends SupportMapFragmentActivity {
|
||||
private RadioGroup radioGroup;
|
||||
private CheckBox fitHeight;
|
||||
private CheckBox fitWidth;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
final LatLng northeastLatLng = new LatLng(39.984066, 116.307548);
|
||||
final LatLng southwestLatLng = new LatLng(39.974066, 116.297548);
|
||||
radioGroup = findViewById(R.id.lay_map_bound);
|
||||
radioGroup.setVisibility(View.VISIBLE);
|
||||
fitWidth = findViewById(R.id.btn_fit_width);
|
||||
fitWidth.setText("适应宽度");
|
||||
fitHeight = findViewById(R.id.btn_fit_height);
|
||||
fitHeight.setText("适应高度");
|
||||
fitHeight.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
if (b){
|
||||
tencentMap.setRestrictBounds(new LatLngBounds(northeastLatLng, southwestLatLng), RestrictBoundsFitMode.FIT_HEIGHT);
|
||||
}else{
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
fitWidth.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
if (b){
|
||||
tencentMap.setRestrictBounds(new LatLngBounds(northeastLatLng, southwestLatLng), RestrictBoundsFitMode.FIT_WIDTH);
|
||||
}else{
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.tencent.map.vector.demo.camera;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.map.vector.demo.basic.SupportMapFragmentActivity;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
|
||||
public class MapCameraCenterActivity extends SupportMapFragmentActivity implements TencentMap.OnCameraChangeListener, TencentMap.OnMapClickListener {
|
||||
private TextView textView;
|
||||
private String info;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
textView = findViewById(R.id.tv_info);
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
tencentMap.setOnCameraChangeListener(this);
|
||||
tencentMap.setOnMapClickListener(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 地图视图改变回调
|
||||
* @param cameraPosition
|
||||
*/
|
||||
@Override
|
||||
public void onCameraChange(CameraPosition cameraPosition) {
|
||||
//获取当前地图视图信息
|
||||
info = "经纬度:"+cameraPosition.target.latitude+","+cameraPosition.target.longitude+";zoom:"+cameraPosition.zoom;
|
||||
textView.setText(info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraChangeFinished(CameraPosition cameraPosition) {
|
||||
//获取当前地图视图信息
|
||||
info = "经纬度:"+cameraPosition.target.latitude+","+cameraPosition.target.longitude+";zoom:"+cameraPosition.zoom;
|
||||
Toast.makeText(MapCameraCenterActivity.this,info,Toast.LENGTH_SHORT).show();
|
||||
textView.setText(info);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapClick(LatLng latLng) {
|
||||
tencentMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(latLng,15f, 0, 0)));
|
||||
}
|
||||
}
|
@ -0,0 +1,126 @@
|
||||
package com.tencent.map.vector.demo.circle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdate;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.Arc;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.ArcOptions;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptor;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.Marker;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.MarkerCollisionItem;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions;
|
||||
|
||||
public class ArcActivity extends AppCompatActivity {
|
||||
|
||||
private MapView mapView;
|
||||
private TencentMap tencentMap;
|
||||
private boolean mMarkerAdded;
|
||||
private Arc arc;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_arc);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mapView = findViewById(R.id.mapView);
|
||||
tencentMap = mapView.getMap();
|
||||
CameraUpdate cameraSigma =
|
||||
CameraUpdateFactory.newCameraPosition(new CameraPosition(
|
||||
new LatLng(32.059352, 118.796623),
|
||||
5,
|
||||
0f,
|
||||
0f));
|
||||
//移动地图
|
||||
tencentMap.moveCamera(cameraSigma);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.markercol, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
menu.findItem(R.id.menu_open_collisionsmap).setVisible(!mMarkerAdded);
|
||||
menu.findItem(R.id.menu_close_collisionsmap).setVisible(mMarkerAdded);
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_open_collisionsmap:
|
||||
mMarkerAdded = true;
|
||||
LatLng startLat = new LatLng(39.89491, 116.322056);
|
||||
LatLng endtLat = new LatLng(22.547, 114.085947);
|
||||
LatLng passLat = new LatLng(32.059352, 118.796623);
|
||||
ArcOptions arcOptions = new ArcOptions();
|
||||
arcOptions.points(startLat, endtLat);
|
||||
arcOptions.pass(passLat);
|
||||
//设置起点到终点,与起点外切线逆时针旋转的夹角角度
|
||||
arcOptions.angle(30);
|
||||
//设置线宽,默认5
|
||||
arcOptions.width(2);
|
||||
//设置线颜色,默认黑色
|
||||
arcOptions.color(Color.BLUE);
|
||||
arc = tencentMap.addArc(arcOptions);
|
||||
break;
|
||||
case R.id.menu_close_collisionsmap:
|
||||
mMarkerAdded = false;
|
||||
arc.remove();
|
||||
break;
|
||||
}
|
||||
|
||||
supportInvalidateOptionsMenu();
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.tencent.map.vector.demo.circle;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.tencent.map.vector.demo.basic.SupportMapFragmentActivity;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.Circle;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CircleOptions;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
|
||||
public class CircleOptionsActivity extends SupportMapFragmentActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Circle circle = tencentMap.addCircle(circleOptions);
|
||||
Circle newCircle = tencentMap.addCircle(newCircleOptions);
|
||||
newCircle.setCenter(new LatLng(39.98408, 116.30701)); //重新设置圆心
|
||||
newCircle.setOptions(newCircleOptions); //重新设置圆形属性
|
||||
}
|
||||
|
||||
/**
|
||||
* 圆形选项
|
||||
*/
|
||||
private CircleOptions circleOptions = new CircleOptions() //圆形选项
|
||||
.center(new LatLng(39.9849, 116.3977)) //圆心位置
|
||||
.clickable(true) //支持点击
|
||||
.fillColor((128 << 24) + (100 << 16) + (50 << 8) + 120) //设置填充颜色RGBA
|
||||
.radius(110d) //设置半径
|
||||
.visible(true) //设置是否可见
|
||||
.zIndex(1) //设置堆叠顺序,越大优先级越高
|
||||
.strokeWidth(1) //描边宽度
|
||||
.strokeColor((128 << 24) + (128 << 16) + (128 << 8) + 128); //描边颜色
|
||||
|
||||
|
||||
private CircleOptions newCircleOptions = new CircleOptions().center(new LatLng(39.121, 116.454)).radius(90d).fillColor(0xff00ff00);
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.tencent.map.vector.demo.circle;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.map.vector.demo.basic.SupportMapFragmentActivity;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.Circle;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CircleOptions;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
|
||||
public class DrawCircleActivity extends SupportMapFragmentActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
LatLng latLng = new LatLng(39.984059,116.307771);
|
||||
Circle circle = tencentMap.addCircle(new CircleOptions().
|
||||
center(latLng).
|
||||
radius(100d).
|
||||
fillColor(getResources().getColor(R.color.style)).
|
||||
strokeColor(getResources().getColor(R.color.colorPrimary)).
|
||||
strokeWidth(1));
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package com.tencent.map.vector.demo.gesture;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.RadioGroup;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.map.vector.demo.basic.SupportMapFragmentActivity;
|
||||
|
||||
public class GestureSettingsActivity extends SupportMapFragmentActivity {
|
||||
|
||||
private CheckBox scrollBox;
|
||||
private CheckBox zoomBox;
|
||||
private CheckBox rotateBox;
|
||||
private CheckBox tiltBox;
|
||||
private RadioGroup radioGroup;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
radioGroup = findViewById(R.id.lay_checkbox);
|
||||
radioGroup.setVisibility(View.VISIBLE);
|
||||
initView();
|
||||
}
|
||||
|
||||
private void initView(){
|
||||
scrollBox = findViewById(R.id.btn_scroll);
|
||||
zoomBox = findViewById(R.id.btn_zoom);
|
||||
rotateBox = findViewById(R.id.btn_rotate);
|
||||
tiltBox = findViewById(R.id.btn_slope);
|
||||
|
||||
|
||||
scrollBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
if (b){
|
||||
mapUiSettings.setScrollGesturesEnabled(true);
|
||||
}else{
|
||||
mapUiSettings.setScrollGesturesEnabled(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
zoomBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
if (b){
|
||||
mapUiSettings.setZoomGesturesEnabled(true);
|
||||
}else{
|
||||
mapUiSettings.setZoomGesturesEnabled(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
rotateBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
if (b){
|
||||
mapUiSettings.setRotateGesturesEnabled(true);
|
||||
}else{
|
||||
mapUiSettings.setRotateGesturesEnabled(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
tiltBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
if (b){
|
||||
mapUiSettings.setTiltGesturesEnabled(true);
|
||||
}else{
|
||||
mapUiSettings.setTiltGesturesEnabled(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package com.tencent.map.vector.demo.gesture;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.map.vector.demo.basic.SupportMapFragmentActivity;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.TencentMapGestureListener;
|
||||
|
||||
public class MapGestureListenActivity extends SupportMapFragmentActivity implements TencentMapGestureListener {
|
||||
|
||||
private TextView textView;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
textView = findViewById(R.id.tv_info);
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
tencentMap.setTencentMapGestureListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDoubleTap(float v, float v1) {
|
||||
textView.setText("单指双击");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTap(float v, float v1) {
|
||||
textView.setText("单指单击");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onFling(float v, float v1) {
|
||||
textView.setText("单指惯性滑动");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(float v, float v1) {
|
||||
textView.setText("单指滑动");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongPress(float v, float v1) {
|
||||
textView.setText("长按");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDown(float v, float v1) {
|
||||
textView.setText("单指按下");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onUp(float v, float v1) {
|
||||
textView.setText("单指抬起");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTwoFingerMoveAgainst(TwoFingerMoveAgainstStatus twoFingerMoveAgainstStatus, CameraPosition cameraPosition) {
|
||||
textView.setText("双指捏合");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapStable() {
|
||||
textView.setText("地图稳定");
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapStableBy(CameraPosition.Trigger trigger) {
|
||||
textView.setText("地图稳定 by " + trigger.name());
|
||||
return;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.tencent.map.vector.demo.gesture;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.map.vector.demo.basic.SupportMapFragmentActivity;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
|
||||
public class MapListenActivity extends SupportMapFragmentActivity implements TencentMap.OnMapClickListener {
|
||||
private TextView textView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
textView = findViewById(R.id.tv_info);
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
tencentMap.setOnMapClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapClick(LatLng latLng) {
|
||||
String info = "经纬度:" + latLng.latitude + "," + latLng.longitude;
|
||||
Toast.makeText(MapListenActivity.this, info, Toast.LENGTH_SHORT).show();
|
||||
textView.setText(info);
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.tencent.map.vector.demo.gesture;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Matrix;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.map.vector.demo.basic.SupportMapFragmentActivity;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptor;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions;
|
||||
|
||||
public class MapLongClickActivity extends SupportMapFragmentActivity implements TencentMap.OnMapLongClickListener {
|
||||
private TextView textView;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
textView = findViewById(R.id.tv_info);
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
tencentMap.setOnMapLongClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapLongClick(LatLng latLng) {
|
||||
String info = "经纬度:"+latLng.latitude+","+latLng.longitude;
|
||||
textView.setText(info);
|
||||
setMarker(latLng);
|
||||
}
|
||||
|
||||
/**
|
||||
* 长按添加标注
|
||||
*/
|
||||
private void setMarker(LatLng latLng){
|
||||
|
||||
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(getBitMap(R.drawable.marker));
|
||||
MarkerOptions options = new MarkerOptions().position(latLng).icon(bitmapDescriptor);
|
||||
tencentMap.clear();
|
||||
tencentMap.addMarker(options);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private Bitmap getBitMap(int resourceId){
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resourceId);
|
||||
int width = bitmap.getWidth();
|
||||
int height = bitmap.getHeight();
|
||||
int newWidth = 100;
|
||||
int newHeight = 100;
|
||||
float widthScale = ((float)newWidth)/width;
|
||||
float heightScale = ((float)newHeight)/height;
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postScale(widthScale, heightScale);
|
||||
bitmap = Bitmap.createBitmap(bitmap,0,0,width,height,matrix,true);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,197 @@
|
||||
package com.tencent.map.vector.demo.heatoverlay;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.Switch;
|
||||
|
||||
import com.tencent.map.sdk.utilities.visualization.aggregation.AggregationOverlay;
|
||||
import com.tencent.map.sdk.utilities.visualization.aggregation.AggregationOverlayProvider;
|
||||
import com.tencent.map.sdk.utilities.visualization.aggregation.HoneyCombVectorOverlayProvider;
|
||||
import com.tencent.map.sdk.utilities.visualization.datamodels.WeightedLatLng;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class AggregationOverlayActivity extends AppCompatActivity {
|
||||
private MapView mMapView;
|
||||
private TencentMap mTencentMap;
|
||||
private AggregationOverlay aggregationOverlay;
|
||||
private AggregationOverlayProvider aggregationOverlayProvider;
|
||||
private Switch btnSwitch3D;
|
||||
|
||||
boolean mIsSelected;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_aggregation_overlay_design);
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.vectorheatmap, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
menu.findItem(R.id.menu_open_vectorheatmap).setVisible(!mIsSelected);
|
||||
menu.findItem(R.id.menu_close_vectorheatmap).setVisible(mIsSelected);
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_open_vectorheatmap:
|
||||
addAggregation();
|
||||
break;
|
||||
case R.id.menu_close_vectorheatmap:
|
||||
mIsSelected = false;
|
||||
if (aggregationOverlay != null) {
|
||||
aggregationOverlay.remove();
|
||||
aggregationOverlay = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
supportInvalidateOptionsMenu();
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mMapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mMapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mMapView.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mMapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mMapView.onStop();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mMapView = findViewById(R.id.mapView);
|
||||
mTencentMap = mMapView.getMap();
|
||||
mTencentMap.setMapStyle(3);
|
||||
mTencentMap.moveCamera(CameraUpdateFactory.zoomTo(10f));
|
||||
btnSwitch3D = (Switch) findViewById(R.id.btn_switch_3D);
|
||||
bindListener();
|
||||
}
|
||||
|
||||
|
||||
private void bindListener() {
|
||||
|
||||
CompoundButton.OnCheckedChangeListener onCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
switch (compoundButton.getId()) {
|
||||
case R.id.btn_switch_3D:
|
||||
if (aggregationOverlay != null) {
|
||||
if (compoundButton.isChecked()) {
|
||||
aggregationOverlayProvider.enable3D(true);
|
||||
aggregationOverlayProvider.enable3D(true).setAnimateDuration(3000);
|
||||
} else {
|
||||
aggregationOverlayProvider.enable3D(false);
|
||||
}
|
||||
mTencentMap.updateVectorOverlay(aggregationOverlay, aggregationOverlayProvider);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
btnSwitch3D.setOnCheckedChangeListener(onCheckedChangeListener);
|
||||
|
||||
}
|
||||
|
||||
protected void addAggregation() {
|
||||
mIsSelected = true;
|
||||
if (aggregationOverlay != null) {
|
||||
return;
|
||||
}
|
||||
// mTencentMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(new LatLng(39.961629, 116.355343), 12, 0, 0)));
|
||||
mTencentMap.setBuildingEnable(false);
|
||||
mTencentMap.setPoisEnabled(false);
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
ArrayList<WeightedLatLng> nodes = new ArrayList<WeightedLatLng>();
|
||||
br = new BufferedReader(new InputStreamReader(getResources().getAssets().open("data2k")));
|
||||
String line = null;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] lines = line.split("\t");
|
||||
if (lines.length == 3) {
|
||||
double value = Double.parseDouble(lines[2]);
|
||||
LatLng latLng = new LatLng((Double.parseDouble(lines[1])), (Double.parseDouble(lines[0])));
|
||||
nodes.add(new WeightedLatLng(latLng, value));
|
||||
}
|
||||
}
|
||||
|
||||
int[] colors = {
|
||||
Color.argb(255, 0x01, 0x2C, 0x4B),
|
||||
Color.argb(255, 0x17, 0x3E, 0x59),
|
||||
Color.argb(255, 0x3A, 0x73, 0x78),
|
||||
Color.argb(255, 0x98, 0xCD, 0x9A),
|
||||
Color.argb(255, 0xF6, 0xFB, 0xB6)
|
||||
};
|
||||
double[] startPoints = {0.f, 0.1f, 0.15f, 0.3f, 0.5f};
|
||||
|
||||
|
||||
aggregationOverlayProvider = new HoneyCombVectorOverlayProvider()
|
||||
.nodes(nodes.toArray(new WeightedLatLng[0]))
|
||||
.setHeightRange(0, 4000);
|
||||
aggregationOverlayProvider.colors(colors, startPoints);
|
||||
aggregationOverlay = mTencentMap.addVectorOverlay(aggregationOverlayProvider);
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
package com.tencent.map.vector.demo.heatoverlay;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.Switch;
|
||||
|
||||
import com.tencent.map.sdk.utilities.visualization.datamodels.FromToLatLng;
|
||||
import com.tencent.map.sdk.utilities.visualization.od.ArcLineOverlay;
|
||||
import com.tencent.map.sdk.utilities.visualization.od.ArcLineOverlayProvider;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.VectorOverlay;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ArcLineLayerActivity extends AppCompatActivity {
|
||||
private MapView mMapView;
|
||||
private TencentMap mTencentMap;
|
||||
private VectorOverlay vectorOverlay;
|
||||
private ArcLineOverlayProvider options;
|
||||
private Switch btnSwitch3D;
|
||||
boolean mIsSelected;
|
||||
private Switch btnani3D;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_arc_line_layer_design);
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.vectorheatmap, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
menu.findItem(R.id.menu_open_vectorheatmap).setVisible(!mIsSelected);
|
||||
menu.findItem(R.id.menu_close_vectorheatmap).setVisible(mIsSelected);
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_open_vectorheatmap:
|
||||
btnSwitch3D.setVisibility(View.VISIBLE);
|
||||
addArcLineLayer();
|
||||
break;
|
||||
case R.id.menu_close_vectorheatmap:
|
||||
mIsSelected = false;
|
||||
if (vectorOverlay != null) {
|
||||
vectorOverlay.remove();
|
||||
vectorOverlay = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
supportInvalidateOptionsMenu();
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mMapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mMapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mMapView.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mMapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mMapView.onStop();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mMapView = findViewById(R.id.mapView);
|
||||
mTencentMap = mMapView.getMap();
|
||||
mTencentMap.moveCamera(CameraUpdateFactory.zoomTo(5f));
|
||||
btnSwitch3D = (Switch) findViewById(R.id.btn_switch_3D);
|
||||
bindListener();
|
||||
|
||||
}
|
||||
|
||||
private void bindListener() {
|
||||
CompoundButton.OnCheckedChangeListener onCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
switch (compoundButton.getId()) {
|
||||
case R.id.btn_switch_3D:
|
||||
if (vectorOverlay != null) {
|
||||
if (compoundButton.isChecked()) {
|
||||
options.enable3D(true);
|
||||
} else {
|
||||
options.enable3D(false);
|
||||
}
|
||||
|
||||
mTencentMap.updateVectorOverlay(vectorOverlay, options);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
btnSwitch3D.setOnCheckedChangeListener(onCheckedChangeListener);
|
||||
}
|
||||
|
||||
private void addArcLineLayer() {
|
||||
mIsSelected = true;
|
||||
if (vectorOverlay == null) {
|
||||
// mTencentMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(new LatLng(39.9229731, 116.422880668), 8, 0f, 0f)));
|
||||
mTencentMap.setMapStyle(3);
|
||||
|
||||
int color = Color.argb(255, 0, 255, 170);
|
||||
BufferedReader br = null;
|
||||
final ArrayList<FromToLatLng> nodes = new ArrayList<FromToLatLng>();
|
||||
try {
|
||||
br = new BufferedReader(new InputStreamReader(getResources().getAssets().open("arc.dat")));
|
||||
String line = null;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] lines = line.split(" ");
|
||||
if (lines.length == 5) {
|
||||
double arc = Double.parseDouble(lines[4]);
|
||||
LatLng startLatLng = new LatLng((Double.parseDouble(lines[0])), (Double.parseDouble(lines[1])));
|
||||
LatLng endLatLng = new LatLng((Double.parseDouble(lines[2])), (Double.parseDouble(lines[3])));
|
||||
nodes.add(new FromToLatLng(startLatLng, endLatLng));
|
||||
//nodes.add(new FromToLatLng(startLatLng, endLatLng, arc));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
int[] colors = {
|
||||
Color.argb(255, 0, 0xd4, 0xff),
|
||||
Color.argb((int) (255 * 0.3), 0, 0xd4, 0xff),
|
||||
Color.argb(255, 0, 0xd4, 0xff)
|
||||
};
|
||||
options = new ArcLineOverlayProvider().data(nodes).opacity(2f).width(4).gradient(colors).setAnimateDuration(3000).setHighlightDuration(200).animateColor(Color.argb(255, 0xff, 0xff, 0xff));
|
||||
vectorOverlay = mTencentMap.addVectorOverlay(options);
|
||||
mTencentMap.setPoisEnabled(false);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,126 @@
|
||||
package com.tencent.map.vector.demo.heatoverlay;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.map.vector.demo.basic.SupportMapFragmentActivity;
|
||||
import com.tencent.map.sdk.utilities.heatmap.Gradient;
|
||||
import com.tencent.map.sdk.utilities.heatmap.HeatMapTileProvider;
|
||||
import com.tencent.map.sdk.utilities.heatmap.WeightedLatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.TileOverlay;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.TileOverlayOptions;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class DrawHeatOverlayActivity extends SupportMapFragmentActivity implements HeatMapTileProvider.OnHeatMapReadyListener{
|
||||
|
||||
private TileOverlay mHeatmapTileOverlay;
|
||||
private HeatMapTileProvider mProvider;
|
||||
//热力图半径
|
||||
private static final int ALT_HEATMAP_RADIUS = HeatMapTileProvider.DEFAULT_RADIUS;
|
||||
//热力图透明度
|
||||
private static final double ALT_HEATMAP_OPACITY = HeatMapTileProvider.DEFAULT_OPACITY;
|
||||
//热力图渐变方案
|
||||
public static final Gradient ALT_HEATMAP_GRADIENT = HeatMapTileProvider.DEFAULT_GRADIENT;
|
||||
|
||||
private static final int[] CUSTOM_GRADIENT_COLORS = {
|
||||
Color.argb(0,0, 225, 225),
|
||||
Color.rgb(102, 125, 200),
|
||||
Color.rgb(255, 0, 0)
|
||||
};
|
||||
|
||||
private static final float[] CUSTOM_GRADIENT_START_POINTS = {
|
||||
0.0f, 0.2f, 1f
|
||||
};
|
||||
|
||||
public static final Gradient CUSTOM_HEATMAP_GRADIENT = new Gradient(CUSTOM_GRADIENT_COLORS,
|
||||
CUSTOM_GRADIENT_START_POINTS);
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setUpMap();
|
||||
Button first = findViewById(R.id.btn_bottom);
|
||||
first.setVisibility(View.VISIBLE);
|
||||
first.setText("自定义热力图");
|
||||
first.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mProvider.setHeatTileGenerator(new HeatMapTileProvider.HeatTileGenerator() {
|
||||
@Override
|
||||
public double[] generateKernel(int radius) {
|
||||
double[] kernel = new double[radius * 2 + 1];
|
||||
for (int i = -radius; i <= radius; i++) {
|
||||
kernel[i + radius] = Math.exp(-i * i / (2 * (radius / 2f) * (radius / 2f)));
|
||||
}
|
||||
return kernel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] generateColorMap(double opacity) {
|
||||
return CUSTOM_HEATMAP_GRADIENT.generateColorMap(opacity);
|
||||
}
|
||||
});
|
||||
mHeatmapTileOverlay.clearTileCache();
|
||||
mHeatmapTileOverlay.reload();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
private void setUpMap() {
|
||||
tencentMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
|
||||
new com.tencent.tencentmap.mapsdk.maps.model.LatLng(39.917128, 116.399266),
|
||||
7.946870f));
|
||||
initHeatMap();
|
||||
}
|
||||
private void initHeatMap() {
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
ArrayList<WeightedLatLng> nodes = new ArrayList<>();
|
||||
br = new BufferedReader(new InputStreamReader(
|
||||
getResources().getAssets().open("data2k")));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] lines = line.split("\t");
|
||||
if (lines.length == 3) {
|
||||
double value = Double.parseDouble(lines[2]);
|
||||
LatLng latLng = new LatLng((Double.parseDouble(lines[1])),
|
||||
(Double.parseDouble(lines[0])));
|
||||
nodes.add(new WeightedLatLng(latLng, value));
|
||||
}
|
||||
}
|
||||
|
||||
mProvider = new HeatMapTileProvider.Builder()
|
||||
.weightedData(nodes)
|
||||
.gradient(ALT_HEATMAP_GRADIENT)
|
||||
.opacity(ALT_HEATMAP_OPACITY)
|
||||
.radius(ALT_HEATMAP_RADIUS)
|
||||
.readyListener(this)
|
||||
.build(tencentMap);
|
||||
mHeatmapTileOverlay = tencentMap.addTileOverlay(new TileOverlayOptions().tileProvider(mProvider));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHeatMapReady() {
|
||||
mHeatmapTileOverlay.clearTileCache();
|
||||
mHeatmapTileOverlay.reload();
|
||||
}
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
package com.tencent.map.vector.demo.heatoverlay;
|
||||
|
||||
import com.tencent.map.vector.demo.basic.SupportMapFragmentActivity;
|
||||
|
||||
public class DrawOldVersionHeatOverlayActivity extends SupportMapFragmentActivity {
|
||||
|
||||
|
||||
// private HeatOverlay heatOverlay;
|
||||
// private HeatOverlay newHeatOverlay;
|
||||
//
|
||||
// @Override
|
||||
// protected void onCreate(Bundle savedInstanceState) {
|
||||
// super.onCreate(savedInstanceState);
|
||||
// HeatOverlayOptions options = setHeatMap(getHeatDataNodes()); //热力图选项
|
||||
// HeatOverlayOptions newOptions = setHeatMap(transferHeatNodes(getHeatDataNodes())); //新的热力图选项
|
||||
//
|
||||
//
|
||||
// heatOverlay = tencentMap.addHeatOverlay(options); //绘制热力图
|
||||
// heatOverlay.remove(); //移除热力图
|
||||
//
|
||||
// newHeatOverlay = tencentMap.addHeatOverlay(newOptions); //绘制转换过坐标的热力图
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * 设置热力图Options
|
||||
// *
|
||||
// */
|
||||
// private HeatOverlayOptions setHeatMap(ArrayList<HeatDataNode> nodes){
|
||||
// //配置热力图参数
|
||||
// HeatOverlayOptions heatOverlayOptions = new HeatOverlayOptions();
|
||||
// heatOverlayOptions.nodes(nodes)
|
||||
// .radius(18)// 半径,单位是像素,这个数值越大运算量越大,默认值为18,建议设置在18-30之间)
|
||||
// .colorMapper(new ColorMapper())
|
||||
// .onHeatMapReadyListener(()->{
|
||||
// runOnUiThread(()-> {
|
||||
// Toast.makeText(getApplicationContext(),
|
||||
// "热力图数据准备完毕", Toast.LENGTH_SHORT).show();
|
||||
// });
|
||||
// });
|
||||
// return heatOverlayOptions;
|
||||
//
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 配色方案
|
||||
// */
|
||||
// class ColorMapper implements HeatOverlayOptions.IColorMapper {
|
||||
//
|
||||
// @Override
|
||||
// public int colorForValue(double arg0) {
|
||||
// // TODO Auto-generated method stub
|
||||
// int alpha, red, green, blue;
|
||||
// if (arg0 > 1) {
|
||||
// arg0 = 1;
|
||||
// }
|
||||
// arg0 = Math.sqrt(arg0);
|
||||
// float a = 20000;
|
||||
// red = 255;
|
||||
// green = 119;
|
||||
// blue = 3;
|
||||
// if (arg0 > 0.7) {
|
||||
// green = 78;
|
||||
// blue = 1;
|
||||
// }
|
||||
// if (arg0 > 0.6) {
|
||||
// alpha = (int) (a * Math.pow(arg0 - 0.7, 3) + 240);
|
||||
// } else if (arg0 > 0.4) {
|
||||
// alpha = (int) (a * Math.pow(arg0 - 0.5, 3) + 200);
|
||||
// } else if (arg0 > 0.2) {
|
||||
// alpha = (int) (a * Math.pow(arg0 - 0.3, 3) + 160);
|
||||
// } else {
|
||||
// alpha = (int) (700 * arg0);
|
||||
// }
|
||||
// if (alpha > 255) {
|
||||
// alpha = 255;
|
||||
// }
|
||||
// return Color.argb(alpha, red, green, blue);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * 准备热力图数据
|
||||
// * @return
|
||||
// */
|
||||
// private ArrayList<HeatDataNode> getHeatDataNodes(){
|
||||
// //HeatDataNode 是热力图热点,包括热点位置和热度值(HeatOverlay会根据传入的全部节点的热度值范围计算最终的颜色表现)
|
||||
// ArrayList<HeatDataNode> nodes = new ArrayList<>();
|
||||
// nodes.add(new HeatDataNode(new LatLng(39.984108,116.307557), 86));
|
||||
// nodes.add(new HeatDataNode(new LatLng(39.984208,116.307457), 44));
|
||||
// nodes.add(new HeatDataNode(new LatLng(39.983208,116.307457), 64));
|
||||
// nodes.add(new HeatDataNode(new LatLng(39.983208,116.317457), 54));
|
||||
// nodes.add(new HeatDataNode(new LatLng(39.684308,116.317457), 34));
|
||||
// nodes.add(new HeatDataNode(new LatLng(39.684108,116.307457), 24));
|
||||
// nodes.add(new HeatDataNode(new LatLng(39.984408,116.327457), 44));
|
||||
// nodes.add(new HeatDataNode(new LatLng(39.984508,116.307457), 54));
|
||||
// nodes.add(new HeatDataNode(new LatLng(39.984208,116.307457), 14));
|
||||
// nodes.add(new HeatDataNode(new LatLng(39.984298,116.307457), 64));
|
||||
// nodes.add(new HeatDataNode(new LatLng(39.984208,116.327457), 74));
|
||||
// nodes.add(new HeatDataNode(new LatLng(39.984108,116.317457), 84));
|
||||
// nodes.add(new HeatDataNode(new LatLng(39.983208,116.297457), 65));
|
||||
// nodes.add(new HeatDataNode(new LatLng(39.982208,116.307457), 54));
|
||||
// nodes.add(new HeatDataNode(new LatLng(39.985208,116.297457), 69));
|
||||
// return nodes;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private ArrayList<HeatDataNode> transferHeatNodes(ArrayList<HeatDataNode> nodes){
|
||||
// ArrayList<HeatDataNode> newNodes = new ArrayList<HeatDataNode>();
|
||||
// for (HeatDataNode node: nodes){
|
||||
// newNodes.add(new HeatDataNode(new LatLng(node.getPoint().getLatitude() + 0.01, node.getPoint().getLongitude() - 0.01), Math.floor(node.getValue() + Math.random())));
|
||||
//
|
||||
// }
|
||||
// return newNodes;
|
||||
// }
|
||||
}
|
@ -0,0 +1,166 @@
|
||||
package com.tencent.map.vector.demo.heatoverlay;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import com.tencent.map.sdk.utilities.visualization.glmodel.GLModelOverlay;
|
||||
import com.tencent.map.sdk.utilities.visualization.glmodel.GLModelOverlayProvider;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMapOptions;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.GeneralTranslateAnimator;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.IAnimatorModel;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLngBounds;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.Polyline;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.PolylineOptions;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.tencent.map.sdk.utilities.visualization.glmodel.GLModelOverlayProvider.CoordType.GeoGraphicType;
|
||||
import static com.tencent.map.sdk.utilities.visualization.glmodel.GLModelOverlayProvider.CoordType.PixelType;
|
||||
|
||||
public class GLModelActivity extends AppCompatActivity {
|
||||
|
||||
/**
|
||||
* 和其他覆盖物相同三维模型图也可控制图层的Level和zIndex
|
||||
* 可通过 GLModelOverlayProvider的displayLevel和zIndex进行设置
|
||||
* displayLevel - 默认层级为POI之下 OverlayLevel.OverlayLevelAboveBuildings
|
||||
* 相同Level内的显示层级关系通过zIndex(int)来控制,zIndex越大越靠上显示。 Level优先级高于zIndex displayLevel必须为如下值之一,否则不生效
|
||||
*/
|
||||
|
||||
private MapView mapView;
|
||||
protected TencentMap tencentMap;
|
||||
private String mResourcePath;
|
||||
private GLModelOverlay vectorOverlay;
|
||||
private final String mLine = "39.98409,116.30804,39.98409,116.3081,39.98409,116.3081,39.98397,116.30809,39.9823,116.30809,39.9811,116.30817,39.9811,116.30817,39.97918,116.308266,39.97918,116.308266,39.9791,116.30827,39.9791,116.30827,39.979008,116.3083,39.978756,116.3084,39.978386,116.3086,39.977867,116.30884,39.977547,116.308914,39.976845,116.308914,39.975826,116.308945,39.975826,116.308945,39.975666,116.30901,39.975716,116.310486,39.975716,116.310486,39.975754,116.31129,39.975754,116.31129,39.975784,116.31241,39.975822,116.31327,39.97581,116.31352,39.97588,116.31591,39.97588,116.31591,39.97591,116.31735,39.97591,116.31735,39.97593,116.31815,39.975967,116.31879,39.975986,116.32034,39.976055,116.32211,39.976086,116.323395,39.976105,116.32514,39.976173,116.32631,39.976254,116.32811,39.976265,116.3288,39.976345,116.33123,39.976357,116.33198,39.976418,116.33346,39.976418,116.33346,39.97653,116.333755,39.97653,116.333755,39.978157,116.333664,39.978157,116.333664,39.978195,116.33509,39.978195,116.33509,39.978226,116.33625,39.978226,116.33625,39.97823,116.33656,39.97823,116.33656,39.978256,116.33791,39.978256,116.33791,39.978016,116.33789,39.977047,116.33791,39.977047,116.33791,39.97706,116.33768,39.97706,116.33768,39.976967,116.33706,39.976967,116.33697";
|
||||
private LatLng[] mCarLatLngArray;
|
||||
private GeneralTranslateAnimator animator;
|
||||
private Polyline polyline;
|
||||
private Spinner mSpinner;
|
||||
private String[] glmodelAnimator = new String[]{"开启平滑移动", "开启骨骼动画", "关闭骨骼动画"};
|
||||
private GLModelOverlayProvider provider;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_g_l_model);
|
||||
mapView = findViewById(R.id.mapView);
|
||||
tencentMap = this.mapView.getMap();
|
||||
String[] linePointsStr = mLine.split(",");
|
||||
mCarLatLngArray = new LatLng[linePointsStr.length / 4];
|
||||
|
||||
for (int i = 0; i < mCarLatLngArray.length; i++) {
|
||||
double latitude = Double.parseDouble(linePointsStr[i * 4]);
|
||||
double longitude = Double.parseDouble(linePointsStr[i * 4 + 1]);
|
||||
mCarLatLngArray[i] = new LatLng(latitude, longitude);
|
||||
}
|
||||
polyline = tencentMap.addPolyline(new PolylineOptions().add(mCarLatLngArray).color(R.color.colorAccent).arrow(true));
|
||||
tencentMap.animateCamera(CameraUpdateFactory.newLatLngBounds(LatLngBounds.builder().include(Arrays.asList(mCarLatLngArray)).build(), 50));
|
||||
creatglmode();
|
||||
init();
|
||||
}
|
||||
|
||||
private void creatglmode() {
|
||||
//gltf格式三维模型文件在assets内
|
||||
String file = "BrainStem.gltf";
|
||||
String SKELETON_PATH = "gltf-BrainStem";
|
||||
//获取外部存储
|
||||
mResourcePath = getExternalFilesDir(null).getAbsolutePath() + File.separator + SKELETON_PATH;
|
||||
provider = new GLModelOverlayProvider(
|
||||
mResourcePath + File.separator + file,
|
||||
new LatLng(39.98409, 116.30804)).coordType(PixelType)
|
||||
.pixelBounds(400, 1200).rotationX(90).rotationY(0).rotationZ(0).setClickEnable(true);
|
||||
vectorOverlay = tencentMap.addVectorOverlay(provider);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mSpinner = findViewById(R.id.sp_glmode);
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_dropdown_item, glmodelAnimator);
|
||||
mSpinner.setAdapter(adapter);
|
||||
mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
switch (position) {
|
||||
//开启骨骼动画
|
||||
case 0:
|
||||
animator = new GeneralTranslateAnimator.Builder(vectorOverlay, 6000,
|
||||
mCarLatLngArray).rotateEnabled(true).initRotate(180).modelType(GeneralTranslateAnimator.ModelType.MODEL_OVERLAY).build();
|
||||
animator.startAnimation();
|
||||
animator.addAnimatorEndListener(new IAnimatorModel.IAnimatorEndListener() {
|
||||
@Override
|
||||
public void onAnimatorEnd() {
|
||||
Log.i("TransformActivity", "onAnimatorEnd");
|
||||
}
|
||||
});
|
||||
break;
|
||||
//停止骨骼动画
|
||||
case 1:
|
||||
vectorOverlay.playSkeletonAnimation(0, 1, true);
|
||||
break;
|
||||
//模型平移
|
||||
case 2:
|
||||
vectorOverlay.stopSkeletonAnimation();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* mapview的生命周期管理
|
||||
*/
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
vectorOverlay.remove();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestart() {
|
||||
super.onRestart();
|
||||
mapView.onRestart();
|
||||
}
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
package com.tencent.map.vector.demo.heatoverlay;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.tencent.map.sdk.utilities.visualization.datamodels.WeightedLatLng;
|
||||
import com.tencent.map.sdk.utilities.visualization.heatmap.GradientVectorOverlay;
|
||||
import com.tencent.map.sdk.utilities.visualization.heatmap.GradientVectorOverlayProvider;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdate;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class HeatMapVectorOverlayActivity extends AppCompatActivity {
|
||||
private MapView mMapView;
|
||||
private TencentMap mTencentMap;
|
||||
private GradientVectorOverlay heatTileOverlay;
|
||||
private GradientVectorOverlayProvider heatMapTileProvider;
|
||||
boolean mIsSelected;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_heat_map_vector_overlay_design);
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.vectorheatmap, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
menu.findItem(R.id.menu_open_vectorheatmap).setVisible(!mIsSelected);
|
||||
menu.findItem(R.id.menu_close_vectorheatmap).setVisible(mIsSelected);
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_open_vectorheatmap:
|
||||
addHeatMap();
|
||||
break;
|
||||
case R.id.menu_close_vectorheatmap:
|
||||
mIsSelected = false;
|
||||
if (heatTileOverlay != null) {
|
||||
heatTileOverlay.remove();
|
||||
heatTileOverlay = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
supportInvalidateOptionsMenu();
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mMapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mMapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mMapView.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mMapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mMapView.onStop();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mMapView = findViewById(R.id.mapView);
|
||||
mTencentMap = mMapView.getMap();
|
||||
mTencentMap.setMapStyle(3);
|
||||
CameraUpdate cameraSigma =
|
||||
CameraUpdateFactory.newCameraPosition(new CameraPosition(
|
||||
new LatLng(31.085414, 111.024319),
|
||||
4,
|
||||
20f,
|
||||
1f));
|
||||
mTencentMap.moveCamera(cameraSigma);
|
||||
}
|
||||
|
||||
|
||||
private void addHeatMap() {
|
||||
mIsSelected = true;
|
||||
if (heatTileOverlay != null) {
|
||||
return;
|
||||
}
|
||||
mTencentMap.setBuildingEnable(false);
|
||||
mTencentMap.setPoisEnabled(false);
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
ArrayList<WeightedLatLng> nodes = new ArrayList<WeightedLatLng>();
|
||||
br = new BufferedReader(new InputStreamReader(getResources().getAssets().open("data2k")));
|
||||
String line = null;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] lines = line.split("\t");
|
||||
if (lines.length == 3) {
|
||||
double value = Double.parseDouble(lines[2]);
|
||||
LatLng latLng = new LatLng((Double.parseDouble(lines[1])), (Double.parseDouble(lines[0])));
|
||||
nodes.add(new WeightedLatLng(latLng, value));
|
||||
}
|
||||
}
|
||||
|
||||
// 通用配色1
|
||||
int[] colors = {
|
||||
Color.argb(255, 77, 111, 255),
|
||||
Color.argb(255, 0, 238, 227),
|
||||
Color.argb(255, 113, 236, 80),
|
||||
Color.argb(255, 255, 176, 0),
|
||||
Color.argb(255, 255, 72, 0)
|
||||
};
|
||||
float[] startPoints = {0.1f, 0.185f, 0.3571f, 0.6142f, 1f};
|
||||
|
||||
|
||||
heatMapTileProvider = new GradientVectorOverlayProvider()
|
||||
.weightedData(nodes).enable3D(true)
|
||||
.radius(56).setMaxHeight(500).setAnimateDuration(3000);
|
||||
heatMapTileProvider.opacity(0.95f);
|
||||
heatMapTileProvider.gradient(colors, startPoints);
|
||||
heatTileOverlay = mTencentMap.addVectorOverlay(heatMapTileProvider);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,180 @@
|
||||
package com.tencent.map.vector.demo.heatoverlay;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Switch;
|
||||
|
||||
import com.tencent.map.sdk.utilities.visualization.datamodels.ScatterLatLng;
|
||||
import com.tencent.map.sdk.utilities.visualization.scatterplot.BitmapScatterPlotOverlayProvider;
|
||||
import com.tencent.map.sdk.utilities.visualization.scatterplot.DotScatterPlotOverlayProvider;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptor;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.VectorOverlay;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
public class ScatterPlotOverlayActivity extends AppCompatActivity {
|
||||
private MapView mMapView;
|
||||
private TencentMap mTencentMap;
|
||||
private VectorOverlay vectorOverlay;
|
||||
boolean mIsSelected;
|
||||
private DotScatterPlotOverlayProvider dotScatterPlotOverlayProvider;
|
||||
private BitmapScatterPlotOverlayProvider provider;
|
||||
private String[] styles = new String[]{"添加点散点", "添加图片散点"};
|
||||
private Spinner mSpinner;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_scatter_plot_overlay);
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mMapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mMapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mMapView.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mMapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mMapView.onStop();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mMapView = findViewById(R.id.mapView);
|
||||
mTencentMap = mMapView.getMap();
|
||||
mTencentMap.moveCamera(CameraUpdateFactory.zoomTo(5f));
|
||||
mTencentMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(new LatLng(40.040219, 116.273348), 20, 0, 0)));
|
||||
mSpinner = findViewById(R.id.sp_style);
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_dropdown_item, styles);
|
||||
mSpinner.setAdapter(adapter);
|
||||
mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
if (vectorOverlay != null) {
|
||||
vectorOverlay.remove();
|
||||
vectorOverlay = null;
|
||||
}
|
||||
addDotVectorOverlay();
|
||||
mTencentMap.updateVectorOverlay(vectorOverlay, dotScatterPlotOverlayProvider);
|
||||
break;
|
||||
case 1:
|
||||
if (vectorOverlay != null) {
|
||||
vectorOverlay.remove();
|
||||
vectorOverlay = null;
|
||||
}
|
||||
addBitmapVectorOverlay();
|
||||
mTencentMap.updateVectorOverlay(vectorOverlay, provider);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void addDotVectorOverlay() {
|
||||
mIsSelected = true;
|
||||
if (vectorOverlay == null) {
|
||||
BufferedReader br = null;
|
||||
final ArrayList<ScatterLatLng> nodes = new ArrayList<ScatterLatLng>();
|
||||
double lat = 40.040219;
|
||||
double lng = 116.273348;
|
||||
double value = 100;
|
||||
Random r = new Random();
|
||||
for (int i = 0; i < 2000; i++) {
|
||||
double a = r.nextInt(10) * 1E-5;
|
||||
double b = r.nextInt(10) * 1E-5;
|
||||
LatLng latLng = new LatLng(lat + a, lng + b);
|
||||
nodes.add(new ScatterLatLng(latLng, value));
|
||||
}
|
||||
int[] colors = {
|
||||
Color.argb(255, 0, 0xd4, 0xff),
|
||||
Color.argb((int) (255 * 0.3), 0, 0xd4, 0xff),
|
||||
Color.argb(255, 0, 0xd4, 0xff)
|
||||
};
|
||||
|
||||
dotScatterPlotOverlayProvider = new DotScatterPlotOverlayProvider().data(nodes).opacity(2f).radius(2).animate(true).colors(colors);
|
||||
|
||||
vectorOverlay = mTencentMap.addVectorOverlay(dotScatterPlotOverlayProvider);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addBitmapVectorOverlay() {
|
||||
mIsSelected = true;
|
||||
if (vectorOverlay == null) {
|
||||
final ArrayList<ScatterLatLng> nodes = new ArrayList<ScatterLatLng>();
|
||||
double lat = 40.040219;
|
||||
double lng = 116.273348;
|
||||
double value = 10;
|
||||
Random r = new Random();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
double a = r.nextInt(10) * 1E-5;
|
||||
double b = r.nextInt(10) * 1E-5;
|
||||
LatLng latLng = new LatLng(lat + a, lng + b);
|
||||
nodes.add(new ScatterLatLng(latLng, value));
|
||||
}
|
||||
BitmapDescriptor[] bitmaps = {
|
||||
BitmapDescriptorFactory.fromAsset("21.jpg"),
|
||||
BitmapDescriptorFactory.fromAsset("22.jpg"),
|
||||
BitmapDescriptorFactory.fromAsset("23.jpg"),
|
||||
BitmapDescriptorFactory.fromAsset("24.jpg"),
|
||||
BitmapDescriptorFactory.fromAsset("25.jpg"),
|
||||
BitmapDescriptorFactory.fromAsset("26.jpg"),
|
||||
};
|
||||
provider = new BitmapScatterPlotOverlayProvider().data(nodes).bitmaps(bitmaps).opacity(2f).scale(20, 10);
|
||||
vectorOverlay = mTencentMap.addVectorOverlay(provider);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
package com.tencent.map.vector.demo.heatoverlay;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.tencent.map.sdk.utilities.visualization.datamodels.TimeLatLng;
|
||||
import com.tencent.map.sdk.utilities.visualization.datamodels.TrailLatLng;
|
||||
import com.tencent.map.sdk.utilities.visualization.trails.TrailOverlayProvider;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.VectorOverlay;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TrailOverlayActivity extends AppCompatActivity {
|
||||
private MapView mMapView;
|
||||
private TencentMap mTencentMap;
|
||||
private VectorOverlay vectorOverlay;
|
||||
boolean mIsSelected;
|
||||
private TrailOverlayProvider trailOverlayProvider;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_trail_overlay);
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.vectorheatmap, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
menu.findItem(R.id.menu_open_vectorheatmap).setVisible(!mIsSelected);
|
||||
menu.findItem(R.id.menu_close_vectorheatmap).setVisible(mIsSelected);
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_open_vectorheatmap:
|
||||
addArcLineLayer();
|
||||
break;
|
||||
case R.id.menu_close_vectorheatmap:
|
||||
mIsSelected = false;
|
||||
if (vectorOverlay != null) {
|
||||
vectorOverlay.remove();
|
||||
vectorOverlay = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
supportInvalidateOptionsMenu();
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mMapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mMapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mMapView.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mMapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mMapView.onStop();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mMapView = findViewById(R.id.mapView);
|
||||
mTencentMap = mMapView.getMap();
|
||||
mTencentMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(39.942117, 116.33668), 11));
|
||||
}
|
||||
|
||||
private void addArcLineLayer() {
|
||||
mIsSelected = true;
|
||||
if (vectorOverlay == null) {
|
||||
|
||||
mTencentMap.setPoisEnabled(false);
|
||||
BufferedReader br = null;
|
||||
long currentTime = System.currentTimeMillis();
|
||||
List<TrailLatLng> startLats = new ArrayList<>();
|
||||
try {
|
||||
br = new BufferedReader(new InputStreamReader(getResources().getAssets().open("trailData.dat")));
|
||||
|
||||
String line = null;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] oneDot = line.split(",");
|
||||
TimeLatLng[] timeLatLngs = new TimeLatLng[oneDot.length];
|
||||
int i = 0;
|
||||
for (String timeLatLng : oneDot) {
|
||||
String[] values = timeLatLng.split("\t");
|
||||
LatLng latlng = new LatLng((Double.parseDouble(values[0])), (Double.parseDouble(values[1])));
|
||||
int timeStamp = Integer.parseInt(values[2]);
|
||||
timeLatLngs[i++] = new TimeLatLng(latlng, timeStamp);
|
||||
}
|
||||
TrailLatLng tmp = new TrailLatLng(timeLatLngs);
|
||||
startLats.add(tmp);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
int[] colors = {Color.argb(0xff, 0x00, 0x00, 0xff),
|
||||
Color.argb(0x00, 0xff, 0xff, 0x00)};
|
||||
|
||||
trailOverlayProvider = new TrailOverlayProvider().type(TrailOverlayProvider.TrailOverlayType.Trail).data(startLats).opacity(2f).width(10).gradient(colors).setHighlightDuration(8000).setAnimateStartTime(0, 25000);
|
||||
vectorOverlay = mTencentMap.addVectorOverlay(trailOverlayProvider);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
package com.tencent.map.vector.demo.heatoverlay;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ToggleButton;
|
||||
|
||||
import com.tencent.map.sdk.utilities.heatmap.WeightedLatLng;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.map.vector.demo.basic.SupportMapFragmentActivity;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.VectorHeatAggregationUnit;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.VectorHeatOverlay;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.VectorHeatOverlayOptions;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 蜂窝热力图
|
||||
*/
|
||||
public class VectorHeatMapActivity extends SupportMapFragmentActivity {
|
||||
|
||||
MapView mMapView;
|
||||
TencentMap mTencentMap;
|
||||
VectorHeatOverlay mOverlay;
|
||||
boolean mIsSelected;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_vector_heat_map);
|
||||
mMapView = findViewById(R.id.map_view);
|
||||
mTencentMap = mMapView.getMap();
|
||||
mTencentMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
|
||||
new LatLng(36.139985, 120.402243),
|
||||
11));
|
||||
|
||||
mTencentMap.setOnMapClickListener(new TencentMap.OnMapClickListener() {
|
||||
@Override
|
||||
public void onMapClick(LatLng latlng) {
|
||||
if (mOverlay == null) {
|
||||
return;
|
||||
}
|
||||
VectorHeatAggregationUnit unit = mOverlay.getUnit(latlng);
|
||||
if (unit == null) {
|
||||
Log.e("VectorHeatMapActivity", "no unit found");
|
||||
return;
|
||||
}
|
||||
Log.e("VectorHeatMapActivity", "unit center:" + unit.getCenter() +
|
||||
", intensity:" + unit.getIntensity() +
|
||||
", size:" + unit.getNodes().length);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.vectorheatmap, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
menu.findItem(R.id.menu_open_vectorheatmap).setVisible(!mIsSelected);
|
||||
menu.findItem(R.id.menu_close_vectorheatmap).setVisible(mIsSelected);
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_open_vectorheatmap:
|
||||
addVectorHeatMap();
|
||||
break;
|
||||
case R.id.menu_close_vectorheatmap:
|
||||
removeVectorHeatMap();
|
||||
break;
|
||||
}
|
||||
|
||||
supportInvalidateOptionsMenu();
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private ArrayList<WeightedLatLng> getHeatNodes() {
|
||||
BufferedReader br = null;
|
||||
ArrayList<WeightedLatLng> nodes = null;
|
||||
try {
|
||||
nodes = new ArrayList<>();
|
||||
br = new BufferedReader(new InputStreamReader(
|
||||
getResources().getAssets().open("honeycomb.txt")));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] lines = line.split("\t");
|
||||
if (lines.length == 3) {
|
||||
double value = Double.parseDouble(lines[2]);
|
||||
LatLng latLng = new LatLng((Double.parseDouble(lines[1])),
|
||||
(Double.parseDouble(lines[0])));
|
||||
nodes.add(new WeightedLatLng(latLng, 1));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (mMapView != null) {
|
||||
mMapView.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
if (mMapView != null) {
|
||||
mMapView.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
if (mMapView != null) {
|
||||
mMapView.onStop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mMapView != null) {
|
||||
mMapView.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
private void addVectorHeatMap() {
|
||||
mIsSelected = true;
|
||||
if (mOverlay != null) {
|
||||
return;
|
||||
}
|
||||
WeightedLatLng[] nodes = getHeatNodes().toArray(new WeightedLatLng[0]);
|
||||
VectorHeatOverlayOptions options = new VectorHeatOverlayOptions()
|
||||
.nodes(nodes)
|
||||
.size(2000)
|
||||
.gap(100)
|
||||
.colors(new int[]{0x45fa4b14, 0x99fa4b14, 0xd9fa4b14})
|
||||
.startPoints(new double[]{0, 0.6, 0.8});
|
||||
mOverlay = mTencentMap.addVectorHeatOverlay(options);
|
||||
}
|
||||
|
||||
public void removeVectorHeatMap() {
|
||||
mIsSelected = false;
|
||||
if (mOverlay == null) {
|
||||
return;
|
||||
}
|
||||
mOverlay.remove();
|
||||
mOverlay = null;
|
||||
}
|
||||
}
|
@ -0,0 +1,251 @@
|
||||
package com.tencent.map.vector.demo.location;
|
||||
|
||||
import android.Manifest;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Matrix;
|
||||
import android.location.Location;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.map.vector.demo.basic.SupportMapFragmentActivity;
|
||||
import com.google.gson.Gson;
|
||||
import com.tencent.map.geolocation.TencentLocation;
|
||||
import com.tencent.map.geolocation.TencentLocationListener;
|
||||
import com.tencent.map.geolocation.TencentLocationManager;
|
||||
import com.tencent.map.geolocation.TencentLocationRequest;
|
||||
import com.tencent.tencentmap.mapsdk.maps.LocationSource;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptor;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.MyLocationStyle;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import pub.devrel.easypermissions.EasyPermissions;
|
||||
|
||||
public class LocationLayerActivity extends SupportMapFragmentActivity implements EasyPermissions.PermissionCallbacks, LocationSource, TencentLocationListener, TencentMap.OnMapLongClickListener, RadioGroup.OnCheckedChangeListener {
|
||||
|
||||
private OnLocationChangedListener locationChangedListener;
|
||||
|
||||
private TencentLocationManager locationManager;
|
||||
private TencentLocationRequest locationRequest;
|
||||
private MyLocationStyle locationStyle;
|
||||
private RadioGroup radioGroup;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
|
||||
//定位需要申请的权限
|
||||
String[] perms = {
|
||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
||||
Manifest.permission.ACCESS_COARSE_LOCATION,
|
||||
Manifest.permission.READ_PHONE_STATE
|
||||
};
|
||||
|
||||
if (EasyPermissions.hasPermissions(this, perms)) {//检查是否获取该权限
|
||||
Log.i("location", "已获取权限");
|
||||
} else {
|
||||
EasyPermissions.requestPermissions(this, "必要的权限", 0, perms);
|
||||
}
|
||||
//设置显示定位的图标
|
||||
mapUiSettings.setMyLocationButtonEnabled(true);
|
||||
tencentMap.setOnMapLongClickListener(this);
|
||||
|
||||
radioGroup = findViewById(R.id.location_type);
|
||||
radioGroup.setVisibility(View.VISIBLE);
|
||||
radioGroup.setOnCheckedChangeListener(this);
|
||||
|
||||
//建立定位
|
||||
initLocation();
|
||||
//SDK版本4.3.5新增内置定位标点击回调监听
|
||||
tencentMap.setMyLocationClickListener(new TencentMap.OnMyLocationClickListener() {
|
||||
@Override
|
||||
public boolean onMyLocationClicked(LatLng latLng) {
|
||||
Toast.makeText(LocationLayerActivity.this, "内置定位标点击回调", Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 定位的一些初始化设置
|
||||
*/
|
||||
private void initLocation() {
|
||||
//用于访问腾讯定位服务的类, 周期性向客户端提供位置更新
|
||||
locationManager = TencentLocationManager.getInstance(this);
|
||||
//设置坐标系
|
||||
locationManager.setCoordinateType(TencentLocationManager.COORDINATE_TYPE_GCJ02);
|
||||
//创建定位请求
|
||||
locationRequest = TencentLocationRequest.create();
|
||||
//设置定位周期(位置监听器回调周期)为3s
|
||||
locationRequest.setInterval(3000);
|
||||
|
||||
//地图上设置定位数据源
|
||||
tencentMap.setLocationSource(this);
|
||||
//设置当前位置可见
|
||||
tencentMap.setMyLocationEnabled(true);
|
||||
//设置定位图标样式
|
||||
setLocMarkerStyle();
|
||||
tencentMap.setMyLocationStyle(locationStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置定位图标样式
|
||||
*/
|
||||
private void setLocMarkerStyle() {
|
||||
locationStyle = new MyLocationStyle();
|
||||
//创建图标
|
||||
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(getBitMap(R.drawable.location_icon));
|
||||
locationStyle.icon(bitmapDescriptor);
|
||||
//设置定位圆形区域的边框宽度
|
||||
locationStyle.strokeWidth(3);
|
||||
//设置圆区域的颜色
|
||||
locationStyle.fillColor(R.color.style);
|
||||
}
|
||||
|
||||
private Bitmap getBitMap(int resourceId) {
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resourceId);
|
||||
int width = bitmap.getWidth();
|
||||
int height = bitmap.getHeight();
|
||||
int newWidth = 55;
|
||||
int newHeight = 55;
|
||||
float widthScale = ((float) newWidth) / width;
|
||||
float heightScale = ((float) newHeight) / height;
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postScale(widthScale, heightScale);
|
||||
bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 实现位置监听
|
||||
*
|
||||
* @param tencentLocation
|
||||
* @param i
|
||||
* @param s
|
||||
*/
|
||||
@Override
|
||||
public void onLocationChanged(TencentLocation tencentLocation, int i, String s) {
|
||||
|
||||
if (i == TencentLocation.ERROR_OK && locationChangedListener != null) {
|
||||
Location location = new Location(tencentLocation.getProvider());
|
||||
//设置经纬度以及精度
|
||||
location.setLatitude(tencentLocation.getLatitude());
|
||||
location.setLongitude(tencentLocation.getLongitude());
|
||||
location.setAccuracy(tencentLocation.getAccuracy());
|
||||
locationChangedListener.onLocationChanged(location);
|
||||
|
||||
//显示回调的实时位置信息
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//打印tencentLocation的json字符串
|
||||
// Toast.makeText(getApplicationContext(), new Gson().toJson(location), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusUpdate(String s, int i, String s1) {
|
||||
//GPS, WiFi, Radio 等状态发生变化
|
||||
Log.v("State changed", s + "===" + s1);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void activate(OnLocationChangedListener onLocationChangedListener) {
|
||||
locationChangedListener = onLocationChangedListener;
|
||||
|
||||
int err = locationManager.requestLocationUpdates(locationRequest, this, Looper.myLooper());
|
||||
switch (err) {
|
||||
case 1:
|
||||
Toast.makeText(this, "设备缺少使用腾讯定位服务需要的基本条件", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
case 2:
|
||||
Toast.makeText(this, "manifest 中配置的 key 不正确", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
case 3:
|
||||
Toast.makeText(this, "自动加载libtencentloc.so失败", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
locationManager.removeUpdates(this);
|
||||
locationManager = null;
|
||||
locationRequest = null;
|
||||
locationChangedListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
|
||||
Log.e("location quest: ", "success");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
|
||||
Log.e("location quest: ", "failed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapLongClick(LatLng latLng) {
|
||||
Location location = new Location("LongPressLocationProvider");
|
||||
location.setLatitude(latLng.latitude);
|
||||
location.setLongitude(latLng.longitude);
|
||||
location.setAccuracy(20);
|
||||
locationChangedListener.onLocationChanged(location);
|
||||
Log.i("long click", new Gson().toJson(latLng));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(RadioGroup radioGroup, int i) {
|
||||
switch (i) {
|
||||
//连续定位,但不会移动到地图中心点,并且会跟随设备移动
|
||||
case R.id.btn_follow_no_center:
|
||||
|
||||
initLocation();
|
||||
locationStyle = locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER);
|
||||
tencentMap.setMyLocationStyle(locationStyle);
|
||||
break;
|
||||
//连续定位,且将视角移动到地图中心,定位点依照设备方向旋转,并且会跟随设备移动,默认是此种类型
|
||||
case R.id.btn_location_rotate:
|
||||
|
||||
initLocation();
|
||||
locationStyle = locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
|
||||
tencentMap.setMyLocationStyle(locationStyle);
|
||||
break;
|
||||
//连续定位,但不会移动到地图中心点,定位点依照设备方向旋转,并且跟随设备移动
|
||||
case R.id.btn_location_rotate_no_center:
|
||||
|
||||
initLocation();
|
||||
locationStyle = locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);
|
||||
tencentMap.setMyLocationStyle(locationStyle);
|
||||
break;
|
||||
//连续定位,但不会移动到地图中心点,地图依照设备方向旋转,并且会跟随设备移动
|
||||
case R.id.btn_map_rotate_no_center:
|
||||
|
||||
initLocation();
|
||||
locationStyle = locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE_NO_CENTER);
|
||||
tencentMap.setMyLocationStyle(locationStyle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,190 @@
|
||||
package com.tencent.map.vector.demo.location;
|
||||
|
||||
import android.Manifest;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Matrix;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.os.Looper;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.map.vector.demo.basic.SupportMapFragmentActivity;
|
||||
import com.tencent.map.geolocation.TencentLocation;
|
||||
import com.tencent.map.geolocation.TencentLocationListener;
|
||||
import com.tencent.map.geolocation.TencentLocationManager;
|
||||
import com.tencent.map.geolocation.TencentLocationRequest;
|
||||
import com.tencent.tencentmap.mapsdk.maps.LocationSource;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptor;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.MyLocationStyle;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import pub.devrel.easypermissions.EasyPermissions;
|
||||
|
||||
public class LocationPointActivity extends SupportMapFragmentActivity implements EasyPermissions.PermissionCallbacks,LocationSource, TencentLocationListener{
|
||||
private LocationSource.OnLocationChangedListener locationChangedListener;
|
||||
|
||||
private TencentLocationManager locationManager;
|
||||
private TencentLocationRequest locationRequest;
|
||||
private MyLocationStyle locationStyle;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
|
||||
//定位需要申请的权限
|
||||
String[] perms = {
|
||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
||||
Manifest.permission.ACCESS_COARSE_LOCATION,
|
||||
Manifest.permission.READ_PHONE_STATE
|
||||
};
|
||||
|
||||
if (EasyPermissions.hasPermissions(this, perms)) {//检查是否获取该权限
|
||||
Log.i("location", "已获取权限");
|
||||
} else {
|
||||
EasyPermissions.requestPermissions(this, "必要的权限", 0, perms);
|
||||
}
|
||||
//设置显示定位的图标
|
||||
TencentLocationManager.setUserAgreePrivacy(true);
|
||||
//建立定位
|
||||
initLocation();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置定位图标样式
|
||||
*/
|
||||
private void setLocMarkerStyle(){
|
||||
locationStyle = new MyLocationStyle();
|
||||
//创建图标
|
||||
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(getBitMap(R.drawable.marker));
|
||||
locationStyle.icon(bitmapDescriptor);
|
||||
//设置定位圆形区域的边框宽度
|
||||
locationStyle.strokeWidth(3);
|
||||
//设置圆区域的颜色
|
||||
locationStyle.fillColor(R.color.style);
|
||||
|
||||
tencentMap.setMyLocationStyle(locationStyle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Bitmap getBitMap(int resourceId){
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resourceId);
|
||||
int width = bitmap.getWidth();
|
||||
int height = bitmap.getHeight();
|
||||
int newWidth = 55;
|
||||
int newHeight = 55;
|
||||
float widthScale = ((float)newWidth)/width;
|
||||
float heightScale = ((float)newHeight)/height;
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postScale(widthScale, heightScale);
|
||||
bitmap = Bitmap.createBitmap(bitmap,0,0,width,height,matrix,true);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 定位的一些初始化设置
|
||||
*/
|
||||
private void initLocation(){
|
||||
//用于访问腾讯定位服务的类, 周期性向客户端提供位置更新
|
||||
locationManager = TencentLocationManager.getInstance(this);
|
||||
//设置坐标系
|
||||
locationManager.setCoordinateType(TencentLocationManager.COORDINATE_TYPE_GCJ02);
|
||||
//创建定位请求
|
||||
locationRequest = TencentLocationRequest.create();
|
||||
//设置定位周期(位置监听器回调周期)为3s
|
||||
locationRequest.setInterval(3000);
|
||||
|
||||
//地图上设置定位数据源
|
||||
tencentMap.setLocationSource(this);
|
||||
//设置当前位置可见
|
||||
tencentMap.setMyLocationEnabled(true);
|
||||
//设置定位图标样式
|
||||
setLocMarkerStyle();
|
||||
// locationStyle = locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
|
||||
tencentMap.setMyLocationStyle(locationStyle);
|
||||
}
|
||||
/**
|
||||
* 实现位置监听
|
||||
* @param tencentLocation
|
||||
* @param i
|
||||
* @param s
|
||||
*/
|
||||
@Override
|
||||
public void onLocationChanged(TencentLocation tencentLocation, int i, String s) {
|
||||
|
||||
if(i == TencentLocation.ERROR_OK && locationChangedListener != null){
|
||||
Location location = new Location(tencentLocation.getProvider());
|
||||
//设置经纬度以及精度
|
||||
location.setLatitude(tencentLocation.getLatitude());
|
||||
location.setLongitude(tencentLocation.getLongitude());
|
||||
location.setAccuracy(tencentLocation.getAccuracy());
|
||||
locationChangedListener.onLocationChanged(location);
|
||||
|
||||
//显示回调的实时位置信息
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//打印tencentLocation的json字符串
|
||||
// Toast.makeText(getApplicationContext(), new Gson().toJson(location), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusUpdate(String s, int i, String s1) {
|
||||
//GPS, WiFi, Radio 等状态发生变化
|
||||
Log.v("State changed", s +"===" + s1);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void activate(OnLocationChangedListener onLocationChangedListener) {
|
||||
locationChangedListener = onLocationChangedListener;
|
||||
|
||||
int err = locationManager.requestLocationUpdates(locationRequest, this, Looper.myLooper());
|
||||
switch (err) {
|
||||
case 1:
|
||||
Toast.makeText(this,"设备缺少使用腾讯定位服务需要的基本条件",Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
case 2:
|
||||
Toast.makeText(this,"manifest 中配置的 key 不正确",Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
case 3:
|
||||
Toast.makeText(this,"自动加载libtencentloc.so失败",Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
locationManager.removeUpdates(this);
|
||||
locationManager = null;
|
||||
locationRequest = null;
|
||||
locationChangedListener=null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
|
||||
Log.e("location quest: ","success");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
|
||||
Log.e("location quest: ","failed");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,151 @@
|
||||
package com.tencent.map.vector.demo.marker;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMapOptions;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.AoiLayer;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.AoiLayerOptions;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.MapPoi;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.SubPoi;
|
||||
|
||||
public class AoiLayerActivity extends AppCompatActivity implements AoiLayer.OnAoiLayerLoadListener {
|
||||
private MapView mMapView;
|
||||
private RelativeLayout mRelativeLayout;
|
||||
private TencentMap mTencentMap;
|
||||
private boolean mIsSelected;
|
||||
private AoiLayer mAoiLayer;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_aoi_layer);
|
||||
mRelativeLayout = findViewById(R.id.relativelayout);
|
||||
TencentMapOptions options = new TencentMapOptions();
|
||||
mMapView = new MapView(this, options);
|
||||
mRelativeLayout.addView(mMapView);
|
||||
mTencentMap = mMapView.getMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mMapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mMapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mMapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mMapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mMapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAoiLayerLoaded(boolean b, AoiLayer aoiLayer) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.marker_groundoverlay, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
menu.findItem(R.id.menu_add_groundoverlay).setVisible(!mIsSelected);
|
||||
menu.findItem(R.id.menu_remove_groundoverlay).setVisible(mIsSelected);
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_add_groundoverlay:
|
||||
addAOI();
|
||||
break;
|
||||
case R.id.menu_remove_groundoverlay:
|
||||
removeAOI();
|
||||
break;
|
||||
}
|
||||
|
||||
supportInvalidateOptionsMenu();
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加AOI面
|
||||
*/
|
||||
private void addAOI() {
|
||||
mIsSelected = true;
|
||||
//通过检索能力获取Poi的ID ,以北京大学为例
|
||||
String poiId = "11107399966856067949";
|
||||
//AOI面配置项
|
||||
AoiLayerOptions options = new AoiLayerOptions();
|
||||
//设置显示级别 有效范围是(0-20]
|
||||
options.setDisplayLevel(10, 20);
|
||||
|
||||
//添加一个Aoi面
|
||||
mAoiLayer = mTencentMap.addAoiLayer(poiId, options, new AoiLayer.OnAoiLayerLoadListener() {
|
||||
|
||||
@Override
|
||||
public void onAoiLayerLoaded(boolean b, AoiLayer aoiLayer) {
|
||||
if (b) {
|
||||
Toast.makeText(AoiLayerActivity.this, "添加[" + aoiLayer.name() + "]成功!", Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
Toast.makeText(AoiLayerActivity.this, "添加[" + aoiLayer.getId() + "]失败!", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//设置AOi面上的子POI点的点击回调
|
||||
mTencentMap.setOnMapPoiClickListener(new TencentMap.OnMapPoiClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClicked(MapPoi mapPoi) {
|
||||
if (mapPoi instanceof SubPoi) {
|
||||
Toast.makeText(AoiLayerActivity.this, "SubPoi[" + mapPoi.getName() + "]被点击!", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除AOI面
|
||||
*/
|
||||
private void removeAOI() {
|
||||
mIsSelected = false;
|
||||
if (mAoiLayer != null) {
|
||||
mAoiLayer.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,281 @@
|
||||
package com.tencent.map.vector.demo.marker;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.opengl.GLES20;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import cc.winboll.studio.positions.R;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
|
||||
import com.tencent.tencentmap.mapsdk.maps.CustomRender;
|
||||
import com.tencent.tencentmap.mapsdk.maps.MapView;
|
||||
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
|
||||
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
/**
|
||||
* OpenGL绘制
|
||||
*/
|
||||
public class CustomRenderActivity extends AppCompatActivity {
|
||||
|
||||
private static final String TAG = CustomRenderActivity.class.getSimpleName();
|
||||
|
||||
// 标识是否第一次绘制3D立方体
|
||||
private boolean mIsFirstDraw3DCube = true;
|
||||
|
||||
// 立方体8个顶点坐标
|
||||
private float[] mVertices = {
|
||||
-1, -1, -0,
|
||||
1, -1, -0,
|
||||
1, 1, -0,
|
||||
-1, 1, -0,
|
||||
-1, -1, 1,
|
||||
1, -1, 1,
|
||||
1, 1, 1,
|
||||
-1, 1, 1,
|
||||
};
|
||||
|
||||
// 3D立方体顶点绘制顺序列表
|
||||
private short[] mDrawIndices = {
|
||||
5, 4, 0, 1, 5, 0, 6, 5, 1, 2, 6, 1,
|
||||
7, 6, 2, 3, 7, 2, 4, 7, 3, 0, 4, 3,
|
||||
6, 7, 4, 5, 6, 4, 1, 0, 3, 2, 1, 3
|
||||
};
|
||||
|
||||
// 3D立方体8个顶点颜色值
|
||||
private float[] mVertexColors = {
|
||||
1f, 1f, 0f, 1f,
|
||||
0f, 1f, 1f, 1f,
|
||||
1f, 0f, 1f, 1f,
|
||||
0f, 0f, 0f, 1f,
|
||||
1f, 1f, 1f, 1f,
|
||||
1f, 0f, 0f, 1f,
|
||||
0f, 1f, 0f, 1f,
|
||||
0f, 0f, 1f, 1f
|
||||
};
|
||||
|
||||
// 立方体顶点坐标Buffer
|
||||
private FloatBuffer mVertexBuffer;
|
||||
|
||||
// 顶点绘制顺序Buffer
|
||||
private ShortBuffer mIndexBuffer;
|
||||
|
||||
// 立方体顶点颜色Buffer
|
||||
private FloatBuffer mColorBuffer;
|
||||
|
||||
// 3D立方体着色器
|
||||
private CubeShader mCubeShader;
|
||||
|
||||
private MapView mapView;
|
||||
|
||||
private TencentMap mMap;
|
||||
|
||||
private LatLng latlng = new LatLng(40.04199816,116.27479076);
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_custom_render);
|
||||
mapView = findViewById(R.id.map_view);
|
||||
mMap = mapView.getMap();
|
||||
mMap.addOnMapLoadedCallback(new TencentMap.OnMapLoadedCallback() {
|
||||
@Override
|
||||
public void onMapLoaded() {
|
||||
mMap.setCustomRender(new CubeRender());
|
||||
mMap.removeOnMapLoadedCallback(this);
|
||||
}
|
||||
});
|
||||
|
||||
mMap.moveCamera(CameraUpdateFactory.newCameraPosition(CameraPosition.builder()
|
||||
.target(latlng).zoom(16).tilt(45).build()));
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
// TODO Auto-generated method stub
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
// TODO Auto-generated method stub
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
private class CubeRender implements CustomRender {
|
||||
|
||||
private void initCubeData(float width, float height, float depth) {
|
||||
// 对标地图坐标
|
||||
initVertices(mVertices, width, height, depth);
|
||||
|
||||
// 立方体顶点数据Buffer
|
||||
mVertexBuffer = ByteBuffer.allocateDirect(mVertices.length * 4)
|
||||
.order(ByteOrder.nativeOrder())
|
||||
.asFloatBuffer();
|
||||
mVertexBuffer.put(mVertices).position(0);
|
||||
|
||||
// 立方体顶点绘制顺序Buffer
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(mDrawIndices.length * 4);
|
||||
byteBuffer.order(ByteOrder.nativeOrder());
|
||||
mIndexBuffer = byteBuffer.asShortBuffer();
|
||||
mIndexBuffer.put(mDrawIndices);
|
||||
mIndexBuffer.position(0);
|
||||
|
||||
// 立方体顶点颜色Buffer
|
||||
ByteBuffer byteBuffer1 = ByteBuffer.allocateDirect(mVertexColors.length * 4);
|
||||
byteBuffer1.order(ByteOrder.nativeOrder());
|
||||
mColorBuffer = byteBuffer1.asFloatBuffer();
|
||||
mColorBuffer.put(mVertexColors);
|
||||
mColorBuffer.position(0);
|
||||
}
|
||||
|
||||
private void initCubeShader() {
|
||||
mCubeShader = new CubeShader();
|
||||
mCubeShader.init();
|
||||
}
|
||||
|
||||
private void initVertices(float[] vertices, float width, float height, float depth) {
|
||||
for (int i = 0; i < vertices.length / 3; i++) {
|
||||
int m = i * 3;
|
||||
vertices[m] = vertices[m] * width;
|
||||
vertices[m + 1] = vertices[m + 1] * height;
|
||||
vertices[m + 2] = vertices[m + 2] * depth;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrawFrame() {
|
||||
drawCube();
|
||||
}
|
||||
|
||||
private void drawCube() {
|
||||
|
||||
if (mIsFirstDraw3DCube) {
|
||||
float cubeWidth = 0.2f * 10000 / 2;
|
||||
float cubeHeight = 0.2f * 10000 / 2;
|
||||
float cubeDepth = 0.4f * 10000 / 2;
|
||||
initCubeData(cubeWidth, cubeHeight, cubeDepth);
|
||||
initCubeShader();
|
||||
mIsFirstDraw3DCube = false;
|
||||
}
|
||||
|
||||
if (null == mCubeShader) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 绑定地图移动
|
||||
PointF p1f = mMap.getProjection().glVertexForCoordinate(latlng);
|
||||
float[] mvpMatrix = mMap.getProjection().glModelMatrix(p1f, 1);
|
||||
|
||||
// Step2 开始绘制设置
|
||||
GLES20.glUseProgram(mCubeShader.mProgram);
|
||||
checkGlError("glUseProgram");
|
||||
|
||||
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
|
||||
checkGlError("glEnable");
|
||||
|
||||
//对齐矩阵
|
||||
GLES20.glUniformMatrix4fv(mCubeShader.mMvpMatrix, 1, false, mvpMatrix, 0);
|
||||
checkGlError("glUniformMatrix4fv");
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
// 顶点指针
|
||||
GLES20.glEnableVertexAttribArray(mCubeShader.mVertex);
|
||||
checkGlError("glEnableVertexAttribArray");
|
||||
GLES20.glVertexAttribPointer(mCubeShader.mVertex, 3, GLES20.GL_FLOAT, false, 0, mVertexBuffer);
|
||||
checkGlError("glVertexAttribPointer");
|
||||
|
||||
// 颜色指针
|
||||
GLES20.glEnableVertexAttribArray(mCubeShader.mColor);
|
||||
checkGlError("glEnableVertexAttribArray");
|
||||
GLES20.glVertexAttribPointer(mCubeShader.mColor, 4, GLES20.GL_FLOAT, false, 0, mColorBuffer);
|
||||
checkGlError("glVertexAttribPointer");
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
// 开始画
|
||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, mDrawIndices.length, GLES20.GL_UNSIGNED_SHORT, mIndexBuffer);
|
||||
checkGlError("glDrawElements");
|
||||
|
||||
GLES20.glDisableVertexAttribArray(mCubeShader.mVertex);
|
||||
checkGlError("glDisableVertexAttribArray");
|
||||
|
||||
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
|
||||
checkGlError("glDisable");
|
||||
}
|
||||
}
|
||||
|
||||
private static class CubeShader {
|
||||
int mVertex;
|
||||
int mMvpMatrix;
|
||||
int mColor;
|
||||
int mProgram;
|
||||
|
||||
String vertexShader = "precision mediump float;\n" +
|
||||
" attribute vec3 mVertex;//顶点数组,三维坐标\n" +
|
||||
" attribute vec4 mColor;//颜色数组,三维坐标\n" +
|
||||
" uniform mat4 mMvpMatrix;//mvp矩阵\n" +
|
||||
" varying vec4 color;//\n" +
|
||||
" void main(){\n" +
|
||||
" gl_Position = mMvpMatrix * vec4(mVertex, 1.0);\n" +
|
||||
" color = mColor;\n" +
|
||||
" }";
|
||||
|
||||
String fragmentShader = "//有颜色 没有纹理\n" +
|
||||
" precision mediump float;\n" +
|
||||
" varying vec4 color;//\n" +
|
||||
" void main(){\n" +
|
||||
" gl_FragColor = color;\n" +
|
||||
" }";
|
||||
|
||||
public void init() {
|
||||
int vertexLocation = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
|
||||
GLES20.glShaderSource(vertexLocation, vertexShader);
|
||||
checkGlError("glShaderSource");
|
||||
GLES20.glCompileShader(vertexLocation);
|
||||
checkGlError("glCompileShader");
|
||||
int fragmentLocation = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
|
||||
GLES20.glShaderSource(fragmentLocation, fragmentShader);
|
||||
checkGlError("glShaderSource");
|
||||
GLES20.glCompileShader(fragmentLocation);
|
||||
checkGlError("glCompileShader");
|
||||
|
||||
mProgram = GLES20.glCreateProgram();
|
||||
GLES20.glAttachShader(mProgram, vertexLocation);
|
||||
GLES20.glAttachShader(mProgram, fragmentLocation);
|
||||
GLES20.glLinkProgram(mProgram);
|
||||
int[] linked = new int[1];
|
||||
GLES20.glGetProgramiv(mProgram, GLES20.GL_LINK_STATUS, linked, 0);
|
||||
checkGlError("glLinkProgram");
|
||||
if (linked[0] != GLES20.GL_TRUE) {
|
||||
Log.e(TAG, "Could not link program: ");
|
||||
Log.e(TAG, GLES20.glGetProgramInfoLog(mProgram));
|
||||
GLES20.glDeleteProgram(mProgram);
|
||||
mProgram = 0;
|
||||
}
|
||||
|
||||
|
||||
mVertex = GLES20.glGetAttribLocation(mProgram, "mVertex");
|
||||
mMvpMatrix = GLES20.glGetUniformLocation(mProgram, "mMvpMatrix");
|
||||
mColor = GLES20.glGetAttribLocation(mProgram, "mColor");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void checkGlError(String op) {
|
||||
int error;
|
||||
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
|
||||
Log.e(TAG, op + ": glError " + error);
|
||||
}
|
||||
}
|
||||
}
|