This commit is contained in:
ZhanGSKen 2025-02-25 16:44:26 +08:00
commit c633e1663b
226 changed files with 40240 additions and 9 deletions

View File

@ -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 {
//

View File

@ -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

View File

@ -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

Binary file not shown.

39
positions/README.md Normal file
View 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/)
#### 参考文档

View File

84
positions/build.gradle Normal file
View 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'
}

View 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
View 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

Binary file not shown.

View 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>

View 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

Binary file not shown.

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

View 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

View 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

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

BIN
positions/src/main/java/.DS_Store vendored Normal file

Binary file not shown.

View 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");
}
}

View File

@ -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_DRAGGING1表示用户手指按在屏幕上并且开始拖动的状态
手指按下但是还没有拖动的时候还不是这个状态只有按下并且手指开始拖动后log才打出
SCROLL_STATE_IDLE0滑动动画做完的状态
SCROLL_STATE_SETTLING2手指离开屏幕的状态*/
@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();
}
}
}
}

View File

@ -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();
}
}
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}
}
}

View File

@ -0,0 +1,3 @@
package cc.winboll.studio.positions.gps;

View File

@ -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;
}
}
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}
}

View File

@ -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));
}
}

View File

@ -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 "";
}
}

View File

@ -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");
}
}
}

View File

@ -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;
}
}

View File

@ -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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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;
}
}

View File

@ -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)));
}
});
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}
});
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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();
// }
//
//}

View File

@ -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;
}
}
}

View File

@ -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();
}
}
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
});
}
}

View File

@ -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);
}
}

View File

@ -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{
}
}
});
}
}

View File

@ -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)));
}
}

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -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));
}
}

View File

@ -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);
}
}
});
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}

View File

@ -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;
// }
}

View File

@ -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();
}
}

View File

@ -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();
}
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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");
}
}

View File

@ -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();
}
}
}

View File

@ -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);
}
}
}

Some files were not shown because too many files have changed in this diff Show More