Merge branch 'main' of https://github.com/MADAO-LUV/ManGoWalk
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
plugins {
|
||||
alias(libs.plugins.androidApplication)
|
||||
alias(libs.plugins.jetbrainsKotlinAndroid)
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -18,6 +19,9 @@ android {
|
||||
//设置支持的SO库架构(开发者可以根据需要,选择一个或多个平台的so)
|
||||
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86","x86_64"
|
||||
}
|
||||
vectorDrawables {
|
||||
useSupportLibrary true
|
||||
}
|
||||
|
||||
}
|
||||
sourceSets {
|
||||
@@ -41,6 +45,18 @@ android {
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
compose true
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion '1.5.1'
|
||||
}
|
||||
packaging {
|
||||
resources {
|
||||
excludes += '/META-INF/{AL2.0,LGPL2.1}'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -66,11 +82,24 @@ dependencies {
|
||||
implementation libs.material
|
||||
implementation libs.activity
|
||||
implementation libs.constraintlayout
|
||||
implementation libs.filament.android
|
||||
implementation libs.lifecycle.runtime.ktx
|
||||
implementation libs.activity.compose
|
||||
implementation platform(libs.compose.bom)
|
||||
implementation libs.ui
|
||||
implementation libs.ui.graphics
|
||||
implementation libs.ui.tooling.preview
|
||||
implementation libs.material3
|
||||
// implementtation 'cn.shanyaliux.serialport:serialport:4.2.0'
|
||||
// implementation 'com.amap.api:3dmap-location-search:latest.integration'
|
||||
// implementation 'com.amap.api:3dmap:latest.integration'
|
||||
// implementation 'com.amap.api:location:6.4.9'
|
||||
// implementation 'com.amap.api:location:6.4.9
|
||||
|
||||
testImplementation libs.junit
|
||||
androidTestImplementation libs.ext.junit
|
||||
androidTestImplementation libs.espresso.core
|
||||
androidTestImplementation platform(libs.compose.bom)
|
||||
androidTestImplementation libs.ui.test.junit4
|
||||
debugImplementation libs.ui.tooling
|
||||
debugImplementation libs.ui.test.manifest
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
BIN
app/libs/Msc.jar
Normal file
BIN
app/libs/Msc.jar
Normal file
Binary file not shown.
BIN
app/libs/arm64-v8a/libAMapSDK_NAVI_v10_1_200.so
Normal file
BIN
app/libs/arm64-v8a/libAMapSDK_NAVI_v10_1_200.so
Normal file
Binary file not shown.
BIN
app/libs/arm64-v8a/libneonui_shared.so
Normal file
BIN
app/libs/arm64-v8a/libneonui_shared.so
Normal file
Binary file not shown.
BIN
app/libs/arm64-v8a/libneonuijni_public.so
Normal file
BIN
app/libs/arm64-v8a/libneonuijni_public.so
Normal file
Binary file not shown.
BIN
app/libs/armeabi-v7a/libAMapSDK_NAVI_v10_1_200.so
Normal file
BIN
app/libs/armeabi-v7a/libAMapSDK_NAVI_v10_1_200.so
Normal file
Binary file not shown.
BIN
app/libs/armeabi-v7a/libneonui_shared.so
Normal file
BIN
app/libs/armeabi-v7a/libneonui_shared.so
Normal file
Binary file not shown.
BIN
app/libs/armeabi-v7a/libneonuijni_public.so
Normal file
BIN
app/libs/armeabi-v7a/libneonuijni_public.so
Normal file
Binary file not shown.
@@ -1,10 +1,9 @@
|
||||
iid=11600
|
||||
sid=3528001
|
||||
bid=1350002
|
||||
version=13.08.0.10009081
|
||||
time=2025-03-17 18:00:51
|
||||
sid=3535967
|
||||
bid=1359895
|
||||
version=13.08.0.10009084
|
||||
time=2025-03-26 09:54:38
|
||||
FEATURE_LOCATION=1
|
||||
FEATURE_ROUTE_OVERLAY=1
|
||||
FEATURE_MVT=1
|
||||
FEATURE_3DTiles=1
|
||||
FEATURE_GLTF=1
|
||||
FEATURE_MVT=0
|
||||
FEATURE_3DTiles=0
|
||||
FEATURE_GLTF=0
|
||||
|
||||
@@ -12,16 +12,15 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <!-- 如果设置了target >= 28 如果需要启动后台定位则必须声明这个权限 -->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- 如果您的应用需要后台定位权限,且有可能运行在Android Q设备上,并且设置了target>28,必须增加这个权限声明 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <!-- 允许写设备缓存,用于问题排查 -->
|
||||
<!-- 读取电话状态权限 -->
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_SETTINGS"
|
||||
tools:ignore="ProtectedPermissions" /> <!-- 允许读设备等信息,用于问题排查 -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
<!-- 添加 BLE权限 -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 添加 BLE权限 -->
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
|
||||
<!-- 操纵蓝牙的开启-->
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <!-- 操纵蓝牙的开启 -->
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
||||
|
||||
@@ -40,6 +39,9 @@
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.ManGoWalking"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".GuideMap"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".RouteDetailActivity"
|
||||
android:exported="false" />
|
||||
@@ -49,7 +51,8 @@
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:hardwareAccelerated="true">
|
||||
android:hardwareAccelerated="true"
|
||||
android:launchMode="singleTop">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
|
||||
438
app/src/main/java/com/example/mangowalking/GuideMap.java
Normal file
438
app/src/main/java/com/example/mangowalking/GuideMap.java
Normal file
@@ -0,0 +1,438 @@
|
||||
package com.example.mangowalking;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.amap.api.location.AMapLocationClient;
|
||||
import com.amap.api.location.AMapLocationClientOption;
|
||||
import com.amap.api.location.AMapLocationListener;
|
||||
import com.amap.api.maps.AMapException;
|
||||
import com.amap.api.navi.AMapNavi;
|
||||
import com.amap.api.navi.AMapNaviListener;
|
||||
import com.amap.api.navi.AMapNaviView;
|
||||
import com.amap.api.navi.AMapNaviViewListener;
|
||||
import com.amap.api.navi.ParallelRoadListener;
|
||||
import com.amap.api.navi.enums.AMapNaviParallelRoadStatus;
|
||||
import com.amap.api.navi.enums.NaviType;
|
||||
import com.amap.api.navi.enums.TransportType;
|
||||
import com.amap.api.navi.model.*;
|
||||
import com.example.mangowalking.utils.TTSController;
|
||||
import com.google.android.filament.View;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GuideMap extends AppCompatActivity implements AMapNaviListener, AMapNaviViewListener, ParallelRoadListener {
|
||||
private static final String TAG = "GuideMap";
|
||||
private AMapNaviView mNaviView; // 对应DEMO mAMapNaviView;
|
||||
private AMapNavi mNavi; // mAMapNavi;
|
||||
|
||||
protected TTSController mTtsManager;
|
||||
private NaviLatLng mStartPoint; // 起点
|
||||
private NaviLatLng mEndPoint; // 终点
|
||||
private List<NaviLatLng> mWayPoints = new ArrayList<>(); // 途经点
|
||||
|
||||
protected final List<NaviLatLng> sList = new ArrayList<NaviLatLng>();
|
||||
protected final List<NaviLatLng> eList = new ArrayList<NaviLatLng>();
|
||||
protected List<NaviLatLng> mWayPointList = new ArrayList<NaviLatLng>();
|
||||
//与定位相关
|
||||
private AMapLocationClient mapLocationClient;
|
||||
private AMapLocationClientOption mLocationOption;
|
||||
private boolean isAutoStartLocation = false;
|
||||
|
||||
@SuppressLint("MissingInflatedId")
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
// mNavi.setIsNaviTravelView(true);
|
||||
setContentView(R.layout.activity_guide_map);
|
||||
// 1. 初始化导航组件
|
||||
mNaviView = findViewById(R.id.naviView);
|
||||
mNaviView.onCreate(savedInstanceState);
|
||||
try {
|
||||
mNavi = AMapNavi.getInstance(getApplicationContext());
|
||||
} catch (AMapException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// 2. 设置导航监听器
|
||||
mNavi.addAMapNaviListener(this);
|
||||
mNaviView.setAMapNaviViewListener(new AMapNaviViewListener() {
|
||||
@Override
|
||||
public void onNaviSetting() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviCancel() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNaviBackClick() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviMapMode(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviTurnClick() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNextRoadClick() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanViewButtonClick() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLockMap(boolean b) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviViewLoaded() {
|
||||
Log.d("wlx","导航页面加载成功");
|
||||
Log.d("wlx","请不要使用AMapNaviView.getMap().setOnMapLoadedListener();会overwrite导航SDK内部画线逻辑");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapTypeChanged(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviViewShowMode(int i) {
|
||||
|
||||
}
|
||||
// 处理导航视图事件...
|
||||
});
|
||||
mNaviView.setNaviMode(mNaviView.NORTH_UP_MODE);
|
||||
initLocation();
|
||||
// 3. 添加途经点(可选)
|
||||
// mWayPoints.add(new NaviLatLng(39.993706, 116.400865));
|
||||
//初始化定位
|
||||
// initLocation();
|
||||
}
|
||||
@Override
|
||||
public void onNaviSetting() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviCancel() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNaviBackClick() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviMapMode(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviTurnClick() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNextRoadClick() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanViewButtonClick() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLockMap(boolean b) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviViewLoaded() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapTypeChanged(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviViewShowMode(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyParallelRoad(AMapNaviParallelRoadStatus aMapNaviParallelRoadStatus) {
|
||||
if (aMapNaviParallelRoadStatus.getmElevatedRoadStatusFlag() == 1) {
|
||||
Toast.makeText(this, "当前在高架上", Toast.LENGTH_SHORT).show();
|
||||
Log.d("wlx", "当前在高架上");
|
||||
} else if (aMapNaviParallelRoadStatus.getmElevatedRoadStatusFlag() == 2) {
|
||||
Toast.makeText(this, "当前在高架下", Toast.LENGTH_SHORT).show();
|
||||
Log.d("wlx", "当前在高架下");
|
||||
}
|
||||
|
||||
if (aMapNaviParallelRoadStatus.getmParallelRoadStatusFlag() == 1) {
|
||||
Toast.makeText(this, "当前在主路", Toast.LENGTH_SHORT).show();
|
||||
Log.d("wlx", "当前在主路");
|
||||
} else if (aMapNaviParallelRoadStatus.getmParallelRoadStatusFlag() == 2) {
|
||||
Toast.makeText(this, "当前在辅路", Toast.LENGTH_SHORT).show();
|
||||
Log.d("wlx", "当前在辅路");
|
||||
}
|
||||
}
|
||||
|
||||
public enum NaviMode {WALK,BUS};
|
||||
private NaviMode currentNaviMode = NaviMode.WALK;
|
||||
|
||||
|
||||
|
||||
// 初始化定位配置
|
||||
private void initLocation() {
|
||||
try {
|
||||
mapLocationClient = new AMapLocationClient(getApplicationContext());
|
||||
mLocationOption = new AMapLocationClientOption();
|
||||
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
|
||||
mLocationOption.setInterval(2000);
|
||||
mapLocationClient.setLocationListener((AMapLocationListener) this);
|
||||
mapLocationClient.setLocationOption(mLocationOption);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mNaviView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mNaviView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mNaviView.onDestroy();
|
||||
//since 1.6.0 不再在naviview destroy的时候自动执行AMapNavi.stopNavi();请自行执行
|
||||
if (mNavi!=null){
|
||||
mNavi.stopNavi();
|
||||
mNavi.destroy();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onInitNaviFailure() {
|
||||
Toast.makeText(this, "init navi Failed", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitNaviSuccess() {
|
||||
//这里无需super 因为我是直接在父类上直接写
|
||||
mNavi.setTravelInfo(new AMapTravelInfo(TransportType.Walk));
|
||||
mNavi.calculateWalkRoute(new NaviLatLng(39.925846, 116.435765), new NaviLatLng(39.925846, 116.532765));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartNavi(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrafficStatusUpdate() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChange(AMapNaviLocation aMapNaviLocation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetNavigationText(int i, String s) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetNavigationText(String s) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEndEmulatorNavi() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onArriveDestination() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteFailure(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReCalculateRouteForYaw() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReCalculateRouteForTrafficJam() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onArrivedWayPoint(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGpsOpenStatus(boolean b) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviInfoUpdate(NaviInfo naviInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCameraInfo(AMapNaviCameraInfo[] aMapNaviCameraInfos) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateIntervalCameraInfo(AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo aMapNaviCameraInfo1, int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceAreaUpdate(AMapServiceAreaInfo[] aMapServiceAreaInfos) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showCross(AMapNaviCross aMapNaviCross) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideCross() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showModeCross(AMapModelCross aMapModelCross) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideModeCross() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showLaneInfo(AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showLaneInfo(AMapLaneInfo aMapLaneInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideLaneInfo() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteSuccess(int[] ints) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyParallelRoad(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayRing(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteSuccess(AMapCalcRouteResult aMapCalcRouteResult) {
|
||||
mNavi.startNavi(NaviType.GPS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteFailure(AMapCalcRouteResult aMapCalcRouteResult) {
|
||||
//路线计算失败
|
||||
Log.e("dm", "--------------------------------------------");
|
||||
Log.i("dm", "路线计算失败:错误码=" + aMapCalcRouteResult.getErrorCode() + ",Error Message= " + aMapCalcRouteResult.getErrorDescription());
|
||||
Log.i("dm", "错误码详细链接见:http://lbs.amap.com/api/android-navi-sdk/guide/tools/errorcode/");
|
||||
Log.e("dm", "--------------------------------------------");
|
||||
Toast.makeText(this, "errorInfo:" + aMapCalcRouteResult.getErrorDetail() + ", Message:" + aMapCalcRouteResult.getErrorDescription(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviRouteNotify(AMapNaviRouteNotifyData aMapNaviRouteNotifyData) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGpsSignalWeak(boolean b) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.example.mangowalking;
|
||||
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static com.example.mangowalking.utils.MapUtil.convertToLatLng;
|
||||
import static com.example.mangowalking.utils.MapUtil.convertToLatLonPoint;
|
||||
|
||||
@@ -31,6 +32,7 @@ import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
@@ -41,6 +43,7 @@ import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
@@ -56,6 +59,7 @@ import com.amap.api.maps.model.BitmapDescriptorFactory;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.maps.model.MarkerOptions;
|
||||
import com.amap.api.maps.model.MyLocationStyle;
|
||||
import com.amap.api.navi.AMapNavi;
|
||||
import com.amap.api.services.busline.BusLineItem;
|
||||
import com.amap.api.services.core.AMapException;
|
||||
import com.amap.api.services.core.LatLonPoint;
|
||||
@@ -151,6 +155,7 @@ public class RouteActivity extends AppCompatActivity implements
|
||||
|
||||
private BluetoothGattCharacteristic writeCharacteristic;
|
||||
|
||||
private ArrayList<LatLng> poiListForGuideMap = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -163,6 +168,7 @@ public class RouteActivity extends AppCompatActivity implements
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
||||
return insets;
|
||||
});
|
||||
|
||||
//添加蓝牙开启 蓝牙部分是成功开启了
|
||||
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
|
||||
Toast.makeText(RouteActivity.this, "没有蓝牙", Toast.LENGTH_SHORT).show();
|
||||
@@ -182,6 +188,8 @@ public class RouteActivity extends AppCompatActivity implements
|
||||
@SuppressLint("MissingPermission")
|
||||
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); //创建一个蓝牙启动的意图
|
||||
launcher.launch(enableBtIntent);//使用launcer启动这个意图就可以了。
|
||||
|
||||
|
||||
//此处可行
|
||||
//初始化定位
|
||||
initLocation();
|
||||
@@ -193,6 +201,7 @@ public class RouteActivity extends AppCompatActivity implements
|
||||
//初始化出行方式
|
||||
initTravelMode();
|
||||
|
||||
binding.buttonmy.setOnClickListener(v->startActivity(new Intent(this,GuideMap.class)));
|
||||
// 新加入的
|
||||
scanner = bluetoothAdapter.getBluetoothLeScanner();
|
||||
//不进行权限验证
|
||||
@@ -213,13 +222,31 @@ public class RouteActivity extends AppCompatActivity implements
|
||||
ScanFilter sn = new ScanFilter.Builder().setDeviceName("蓝牙设备的名称").setServiceUuid(ParcelUuid.fromString("0000FFE0-0000-1000-8000-00805F9B34FB")).build();
|
||||
List<ScanFilter> scanFilters = new ArrayList<>();
|
||||
scanFilters.add(sn);
|
||||
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_SCAN) != PERMISSION_GRANTED) {
|
||||
// TODO: Consider calling
|
||||
// ActivityCompat#requestPermissions
|
||||
return;
|
||||
}
|
||||
scanner.startScan(scanFilters, new ScanSettings.Builder().build(), callback);
|
||||
bluetoothGatt = device.connectGatt(this, false, gattCallback);
|
||||
|
||||
// Button btn_1 = findViewById(R.id.btn_ble);
|
||||
//
|
||||
// // 重写一个内部类
|
||||
// btn_1.setOnClickListener(new View.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(View v) {
|
||||
// Log.d("RouteActivity", "点击了跳转按钮");
|
||||
//// ArrayList<LatLng> poiList = new ArrayList<>();
|
||||
// //这只是一个意图
|
||||
// Intent intent = new Intent(RouteActivity.this,GuideMap.class);
|
||||
//// intent.putParcelableArrayListExtra("poi_list",poiList);
|
||||
// startActivity(intent);
|
||||
// }
|
||||
// });
|
||||
// RouteActivity.java 中修改点击事件
|
||||
|
||||
|
||||
}
|
||||
|
||||
BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
|
||||
@@ -228,7 +255,7 @@ public class RouteActivity extends AppCompatActivity implements
|
||||
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
|
||||
super.onConnectionStateChange(gatt, status, newState);
|
||||
if (newState == BluetoothProfile.STATE_CONNECTED) {
|
||||
if (ActivityCompat.checkSelfPermission(RouteActivity.this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (ActivityCompat.checkSelfPermission(RouteActivity.this, android.Manifest.permission.BLUETOOTH_CONNECT) != PERMISSION_GRANTED) {
|
||||
return;
|
||||
}
|
||||
gatt.discoverServices();
|
||||
@@ -300,7 +327,7 @@ public class RouteActivity extends AppCompatActivity implements
|
||||
// 假设写特征的 UUID 就是 READ_UUID(或者你需要再定义一个 WRITE_UUID)
|
||||
writeCharacteristic = service.getCharacteristic(UUID.fromString(READ_UUID));
|
||||
// 如果该特征需要先 enableNotification,也可在这里设置:
|
||||
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) != PERMISSION_GRANTED) {
|
||||
return;
|
||||
}
|
||||
gatt.setCharacteristicNotification(writeCharacteristic, true);
|
||||
@@ -327,7 +354,7 @@ public class RouteActivity extends AppCompatActivity implements
|
||||
writeCharacteristic.setValue(data);
|
||||
|
||||
// 3) 发写命令,异步执行
|
||||
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) != PERMISSION_GRANTED) {
|
||||
return;
|
||||
}
|
||||
boolean success = bluetoothGatt.writeCharacteristic(writeCharacteristic);
|
||||
@@ -400,7 +427,10 @@ public class RouteActivity extends AppCompatActivity implements
|
||||
mLocationClient.setLocationListener(this);
|
||||
mLocationOption = new AMapLocationClientOption();
|
||||
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
|
||||
mLocationOption.setOnceLocationLatest(true);
|
||||
// 设置定位间隔 2000ms更新一次
|
||||
mLocationOption.setInterval(2000);
|
||||
//
|
||||
mLocationOption.setOnceLocationLatest(false);
|
||||
mLocationOption.setNeedAddress(true);
|
||||
mLocationOption.setHttpTimeOut(20000);
|
||||
mLocationOption.setLocationCacheEnable(false);
|
||||
@@ -408,6 +438,8 @@ public class RouteActivity extends AppCompatActivity implements
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 初始化地图
|
||||
*
|
||||
@@ -571,7 +603,7 @@ public class RouteActivity extends AppCompatActivity implements
|
||||
binding.mapView.onDestroy();
|
||||
|
||||
if (bluetoothGatt != null) {
|
||||
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) != PERMISSION_GRANTED) {
|
||||
return;
|
||||
}
|
||||
bluetoothGatt.close();
|
||||
@@ -673,6 +705,8 @@ public class RouteActivity extends AppCompatActivity implements
|
||||
}
|
||||
}
|
||||
}
|
||||
poiListForGuideMap.clear();
|
||||
poiListForGuideMap.addAll(allPoiPoints);
|
||||
|
||||
// // 🧪 测试打印
|
||||
// for (LatLng p : poiList) {
|
||||
@@ -753,6 +787,8 @@ public class RouteActivity extends AppCompatActivity implements
|
||||
Log.d("POI_POINT", p.latitude + "," + p.longitude);
|
||||
}
|
||||
sendPoiList(poiList);
|
||||
poiListForGuideMap.clear();
|
||||
poiListForGuideMap.addAll(poiList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
11
app/src/main/java/com/example/mangowalking/ui/theme/Color.kt
Normal file
11
app/src/main/java/com/example/mangowalking/ui/theme/Color.kt
Normal file
@@ -0,0 +1,11 @@
|
||||
package com.example.mangowalking.ui.theme
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
val Purple80 = Color(0xFFD0BCFF)
|
||||
val PurpleGrey80 = Color(0xFFCCC2DC)
|
||||
val Pink80 = Color(0xFFEFB8C8)
|
||||
|
||||
val Purple40 = Color(0xFF6650a4)
|
||||
val PurpleGrey40 = Color(0xFF625b71)
|
||||
val Pink40 = Color(0xFF7D5260)
|
||||
70
app/src/main/java/com/example/mangowalking/ui/theme/Theme.kt
Normal file
70
app/src/main/java/com/example/mangowalking/ui/theme/Theme.kt
Normal file
@@ -0,0 +1,70 @@
|
||||
package com.example.mangowalking.ui.theme
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Build
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.material3.dynamicLightColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.core.view.WindowCompat
|
||||
|
||||
private val DarkColorScheme = darkColorScheme(
|
||||
primary = Purple80,
|
||||
secondary = PurpleGrey80,
|
||||
tertiary = Pink80
|
||||
)
|
||||
|
||||
private val LightColorScheme = lightColorScheme(
|
||||
primary = Purple40,
|
||||
secondary = PurpleGrey40,
|
||||
tertiary = Pink40
|
||||
|
||||
/* Other default colors to override
|
||||
background = Color(0xFFFFFBFE),
|
||||
surface = Color(0xFFFFFBFE),
|
||||
onPrimary = Color.White,
|
||||
onSecondary = Color.White,
|
||||
onTertiary = Color.White,
|
||||
onBackground = Color(0xFF1C1B1F),
|
||||
onSurface = Color(0xFF1C1B1F),
|
||||
*/
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun ManGoWalkingTheme(
|
||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||
// Dynamic color is available on Android 12+
|
||||
dynamicColor: Boolean = true,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val colorScheme = when {
|
||||
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
||||
val context = LocalContext.current
|
||||
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
|
||||
}
|
||||
|
||||
darkTheme -> DarkColorScheme
|
||||
else -> LightColorScheme
|
||||
}
|
||||
val view = LocalView.current
|
||||
if (!view.isInEditMode) {
|
||||
SideEffect {
|
||||
val window = (view.context as Activity).window
|
||||
window.statusBarColor = colorScheme.primary.toArgb()
|
||||
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme
|
||||
}
|
||||
}
|
||||
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme,
|
||||
typography = Typography,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
34
app/src/main/java/com/example/mangowalking/ui/theme/Type.kt
Normal file
34
app/src/main/java/com/example/mangowalking/ui/theme/Type.kt
Normal file
@@ -0,0 +1,34 @@
|
||||
package com.example.mangowalking.ui.theme
|
||||
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
// Set of Material typography styles to start with
|
||||
val Typography = Typography(
|
||||
bodyLarge = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 24.sp,
|
||||
letterSpacing = 0.5.sp
|
||||
)
|
||||
/* Other default text styles to override
|
||||
titleLarge = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 22.sp,
|
||||
lineHeight = 28.sp,
|
||||
letterSpacing = 0.sp
|
||||
),
|
||||
labelSmall = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 11.sp,
|
||||
lineHeight = 16.sp,
|
||||
letterSpacing = 0.5.sp
|
||||
)
|
||||
*/
|
||||
)
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.example.mangowalking.utils;
|
||||
|
||||
public interface ICallBack {
|
||||
void onCompleted(int code);
|
||||
}
|
||||
170
app/src/main/java/com/example/mangowalking/utils/IFlyTTS.java
Normal file
170
app/src/main/java/com/example/mangowalking/utils/IFlyTTS.java
Normal file
@@ -0,0 +1,170 @@
|
||||
package com.example.mangowalking.utils;
|
||||
|
||||
import static com.iflytek.cloud.SpeechSynthesizer.createSynthesizer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.iflytek.cloud.ErrorCode;
|
||||
import com.iflytek.cloud.InitListener;
|
||||
import com.iflytek.cloud.SpeechConstant;
|
||||
import com.iflytek.cloud.SpeechError;
|
||||
import com.iflytek.cloud.SpeechSynthesizer;
|
||||
import com.iflytek.cloud.SpeechUtility;
|
||||
import com.iflytek.cloud.SynthesizerListener;
|
||||
|
||||
public class IFlyTTS implements TTS, SynthesizerListener, AudioManager.OnAudioFocusChangeListener {
|
||||
private static IFlyTTS iflyTTS = null;
|
||||
Context mContext = null;
|
||||
private boolean isPlaying = false;
|
||||
private AudioManager mAm = null;
|
||||
ICallBack callBack = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 请务必替换为您自己申请的ID。
|
||||
*/
|
||||
private final String appId = "1342cc62"; //这个是我自己的ID
|
||||
|
||||
public static IFlyTTS getInstance(Context context) {
|
||||
if (iflyTTS == null) {
|
||||
iflyTTS = new IFlyTTS(context);
|
||||
}
|
||||
return iflyTTS;
|
||||
}
|
||||
|
||||
private IFlyTTS(Context context) {
|
||||
mContext = context;
|
||||
SpeechUtility.createUtility(mContext, SpeechConstant.APPID + "="
|
||||
+ appId);
|
||||
createSynthesizer();
|
||||
mAm = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
|
||||
}
|
||||
|
||||
private void createSynthesizer() {
|
||||
mTts = SpeechSynthesizer.createSynthesizer(mContext,
|
||||
new InitListener() {
|
||||
@Override
|
||||
public void onInit(int errorcode) {
|
||||
if (ErrorCode.SUCCESS == errorcode) {
|
||||
//初始化成功
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private SpeechSynthesizer mTts;
|
||||
@Override
|
||||
public void onAudioFocusChange(int focusChange) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
if (mTts!=null){
|
||||
//设置发音人
|
||||
mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");
|
||||
//设置语速,值范围:[0, 100],默认值:50
|
||||
mTts.setParameter(SpeechConstant.SPEED, "55");
|
||||
//设置音量
|
||||
mTts.setParameter(SpeechConstant.VOLUME, "tts_volume");
|
||||
//设置语调
|
||||
mTts.setParameter(SpeechConstant.PITCH, "tts_pitch");
|
||||
//设置与其他音频软件冲突的时候是否暂停其他音频
|
||||
mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "false");
|
||||
//女生仅vixy支持多音字播报
|
||||
mTts.setParameter(SpeechConstant.VOICE_NAME, "vixy");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playText(String playText) {
|
||||
//多音字处理举例
|
||||
if (playText != null && playText.contains("京藏")) {
|
||||
playText = playText.replace("京藏", "京藏[=zang4]");
|
||||
}
|
||||
if (playText != null && playText.length() > 0) {
|
||||
int result = mAm.requestAudioFocus(this,
|
||||
AudioManager.STREAM_MUSIC,
|
||||
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
|
||||
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
||||
int code = mTts.startSpeaking(playText, this);
|
||||
isPlaying = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopSpeak() {
|
||||
if(mTts != null){
|
||||
mTts.stopSpeaking();
|
||||
}
|
||||
isPlaying = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
stopSpeak();
|
||||
if(mTts != null){
|
||||
mTts.destroy();
|
||||
}
|
||||
iflyTTS = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlaying() {
|
||||
return isPlaying;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onSpeakBegin() {
|
||||
isPlaying = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBufferProgress(int i, int i1, int i2, String s) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpeakPaused() {
|
||||
isPlaying = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpeakResumed() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpeakProgress(int i, int i1, int i2) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompleted(SpeechError arg0) {
|
||||
isPlaying = false;
|
||||
if (mAm != null) {
|
||||
mAm.abandonAudioFocus(this);
|
||||
}
|
||||
if (callBack != null) {
|
||||
if (arg0 == null) {
|
||||
callBack.onCompleted(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(int i, int i1, int i2, Bundle bundle) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCallback(ICallBack callback) {
|
||||
callBack = callback;
|
||||
}
|
||||
}
|
||||
119
app/src/main/java/com/example/mangowalking/utils/SystemTTS.java
Normal file
119
app/src/main/java/com/example/mangowalking/utils/SystemTTS.java
Normal file
@@ -0,0 +1,119 @@
|
||||
package com.example.mangowalking.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.speech.tts.UtteranceProgressListener;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class SystemTTS extends UtteranceProgressListener implements TTS, TextToSpeech.OnUtteranceCompletedListener {
|
||||
|
||||
private Context mContext;
|
||||
private static SystemTTS singleton;
|
||||
private TextToSpeech textToSpeech; // 系统语音播报类
|
||||
private boolean isSuccess = true;
|
||||
|
||||
ICallBack callBack = null;
|
||||
|
||||
public static SystemTTS getInstance(Context context) {
|
||||
if (singleton == null) {
|
||||
synchronized (SystemTTS.class) {
|
||||
if (singleton == null) {
|
||||
singleton = new SystemTTS(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
return singleton;
|
||||
}
|
||||
|
||||
private SystemTTS(Context context) {
|
||||
this.mContext = context.getApplicationContext();
|
||||
textToSpeech = new TextToSpeech(mContext, new TextToSpeech.OnInitListener() {
|
||||
@Override
|
||||
public void onInit(int i) {
|
||||
//系统语音初始化成功
|
||||
if (i == TextToSpeech.SUCCESS) {
|
||||
int result = textToSpeech.setLanguage(Locale.CHINA);
|
||||
textToSpeech.setPitch(1.0f);// 设置音调,值越大声音越尖(女生),值越小则变成男声,1.0是常规
|
||||
textToSpeech.setSpeechRate(1.0f);
|
||||
textToSpeech.setOnUtteranceProgressListener(SystemTTS.this);
|
||||
textToSpeech.setOnUtteranceCompletedListener(SystemTTS.this);
|
||||
if (result == TextToSpeech.LANG_MISSING_DATA
|
||||
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
|
||||
//系统不支持中文播报
|
||||
isSuccess = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUtteranceCompleted(String utteranceId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(String utteranceId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDone(String utteranceId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String utteranceId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playText(String playText) {
|
||||
if(!isSuccess){
|
||||
return;
|
||||
}
|
||||
if(textToSpeech != null)
|
||||
{
|
||||
textToSpeech.speak(playText,
|
||||
TextToSpeech.QUEUE_ADD,null,null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopSpeak() {
|
||||
if(textToSpeech != null)
|
||||
{
|
||||
textToSpeech.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
stopSpeak();
|
||||
if(textToSpeech != null)
|
||||
{
|
||||
textToSpeech.shutdown();
|
||||
}
|
||||
singleton = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlaying() {
|
||||
return textToSpeech.isSpeaking();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setCallback(ICallBack callback) {
|
||||
callBack = callback;
|
||||
}
|
||||
}
|
||||
10
app/src/main/java/com/example/mangowalking/utils/TTS.java
Normal file
10
app/src/main/java/com/example/mangowalking/utils/TTS.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.example.mangowalking.utils;
|
||||
|
||||
public interface TTS {
|
||||
public void init();
|
||||
public void playText(String playText);
|
||||
public void stopSpeak();
|
||||
public void destroy();
|
||||
public boolean isPlaying();
|
||||
public void setCallback(ICallBack callback);
|
||||
}
|
||||
@@ -0,0 +1,321 @@
|
||||
package com.example.mangowalking.utils;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Message;
|
||||
import android.os.Handler;
|
||||
|
||||
import com.amap.api.navi.AMapNaviListener;
|
||||
import com.amap.api.navi.model.AMapCalcRouteResult;
|
||||
import com.amap.api.navi.model.AMapLaneInfo;
|
||||
import com.amap.api.navi.model.AMapModelCross;
|
||||
import com.amap.api.navi.model.AMapNaviCameraInfo;
|
||||
import com.amap.api.navi.model.AMapNaviCross;
|
||||
import com.amap.api.navi.model.AMapNaviLocation;
|
||||
import com.amap.api.navi.model.AMapNaviRouteNotifyData;
|
||||
import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo;
|
||||
import com.amap.api.navi.model.AMapServiceAreaInfo;
|
||||
import com.amap.api.navi.model.AimLessModeCongestionInfo;
|
||||
import com.amap.api.navi.model.AimLessModeStat;
|
||||
import com.amap.api.navi.model.NaviInfo;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.logging.LogRecord;
|
||||
|
||||
public class TTSController implements AMapNaviListener,ICallBack{
|
||||
|
||||
@Override
|
||||
public void onCompleted(int code) {
|
||||
if (handler != null) {
|
||||
handler.obtainMessage(1).sendToTarget();
|
||||
}
|
||||
}
|
||||
public static enum TTSType {
|
||||
/**
|
||||
* 讯飞语音
|
||||
*/
|
||||
IFLYTTS,
|
||||
/**
|
||||
* 系统语音
|
||||
*/
|
||||
SYSTEMTTS;
|
||||
}
|
||||
|
||||
public static TTSController ttsManager;
|
||||
private Context mContext;
|
||||
private TTS tts = null;
|
||||
private SystemTTS systemTTS;
|
||||
private IFlyTTS iflyTTS = null;
|
||||
private LinkedList<String> wordList = new LinkedList<String>();
|
||||
private final int TTS_PLAY = 1;
|
||||
private final int CHECK_TTS_PLAY = 2;
|
||||
|
||||
private Handler handler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
super.handleMessage(msg);
|
||||
switch (msg.what) {
|
||||
case TTS_PLAY:
|
||||
if (tts != null && wordList.size() > 0) {
|
||||
tts.playText(wordList.removeFirst());
|
||||
}
|
||||
break;
|
||||
case CHECK_TTS_PLAY:
|
||||
if (!tts.isPlaying()) {
|
||||
handler.obtainMessage(1).sendToTarget();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
public void setTTSType(TTSType type) {
|
||||
if (type == TTSType.SYSTEMTTS) {
|
||||
tts = systemTTS;
|
||||
} else {
|
||||
tts = iflyTTS;
|
||||
}
|
||||
tts.setCallback(this);
|
||||
}
|
||||
|
||||
private TTSController(Context context) {
|
||||
mContext = context.getApplicationContext();
|
||||
systemTTS = SystemTTS.getInstance(mContext);
|
||||
iflyTTS = IFlyTTS.getInstance(mContext);
|
||||
tts = iflyTTS;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
if (systemTTS != null) {
|
||||
systemTTS.init();
|
||||
}
|
||||
if (iflyTTS != null) {
|
||||
iflyTTS.init();
|
||||
}
|
||||
tts.setCallback(this);
|
||||
}
|
||||
|
||||
public static TTSController getInstance(Context context) {
|
||||
if (ttsManager == null) {
|
||||
ttsManager = new TTSController(context);
|
||||
}
|
||||
return ttsManager;
|
||||
}
|
||||
|
||||
public void stopSpeaking() {
|
||||
if (systemTTS != null) {
|
||||
systemTTS.stopSpeak();
|
||||
}
|
||||
if (iflyTTS != null) {
|
||||
iflyTTS.stopSpeak();
|
||||
}
|
||||
wordList.clear();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (systemTTS != null) {
|
||||
systemTTS.destroy();
|
||||
}
|
||||
if (iflyTTS != null) {
|
||||
iflyTTS.destroy();
|
||||
}
|
||||
ttsManager = null;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 以下都是导航相关接口
|
||||
****************************************************************************/
|
||||
|
||||
@Override
|
||||
public void onInitNaviFailure() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitNaviSuccess() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartNavi(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrafficStatusUpdate() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChange(AMapNaviLocation aMapNaviLocation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetNavigationText(int i, String s) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetNavigationText(String s) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEndEmulatorNavi() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onArriveDestination() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteFailure(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReCalculateRouteForYaw() {
|
||||
if (wordList != null) {
|
||||
wordList.addLast("路线重新规划");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReCalculateRouteForTrafficJam() {
|
||||
if (wordList != null) {
|
||||
wordList.addLast("前方路线拥堵,路线重新规划");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onArrivedWayPoint(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGpsOpenStatus(boolean b) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviInfoUpdate(NaviInfo naviInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCameraInfo(AMapNaviCameraInfo[] aMapNaviCameraInfos) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateIntervalCameraInfo(AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo aMapNaviCameraInfo1, int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceAreaUpdate(AMapServiceAreaInfo[] aMapServiceAreaInfos) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showCross(AMapNaviCross aMapNaviCross) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideCross() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showModeCross(AMapModelCross aMapModelCross) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideModeCross() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showLaneInfo(AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showLaneInfo(AMapLaneInfo aMapLaneInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideLaneInfo() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteSuccess(int[] ints) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyParallelRoad(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayRing(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteSuccess(AMapCalcRouteResult aMapCalcRouteResult) {
|
||||
if(wordList != null)
|
||||
{
|
||||
wordList.addLast("主人你好棒呀");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteFailure(AMapCalcRouteResult aMapCalcRouteResult) {
|
||||
if (wordList != null) {
|
||||
wordList.addLast("路线规划失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviRouteNotify(AMapNaviRouteNotifyData aMapNaviRouteNotifyData) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGpsSignalWeak(boolean b) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
BIN
app/src/main/res/drawable/ic_back.jpg
Normal file
BIN
app/src/main/res/drawable/ic_back.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/drawable/ic_move.png
Normal file
BIN
app/src/main/res/drawable/ic_move.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/drawable/ic_setting.jpg
Normal file
BIN
app/src/main/res/drawable/ic_setting.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
57
app/src/main/res/layout/activity_guide_map.xml
Normal file
57
app/src/main/res/layout/activity_guide_map.xml
Normal file
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- 高德导航视图(必须全屏显示) -->
|
||||
|
||||
<!-- 顶部状态栏 -->
|
||||
<com.amap.api.navi.AMapNaviView
|
||||
android:id="@+id/naviView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:background="#80000000"
|
||||
android:padding="8dp">
|
||||
<TextView
|
||||
android:id="@+id/tvRouteInfo"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="16sp"
|
||||
android:gravity="center"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 底部控制栏 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:orientation="horizontal"
|
||||
android:background="#80000000"
|
||||
android:padding="16dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnStartNavi"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="开始导航"
|
||||
android:textAllCaps="false"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnSwitchMode"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="切换模式"
|
||||
android:textAllCaps="false"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
@@ -27,6 +27,7 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_start"
|
||||
android:layout_width="wrap_content"
|
||||
@@ -106,7 +107,23 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/view2" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/view2" >
|
||||
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/buttonmy"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="20dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
app:hoveredFocusedTranslationZ="18dp"
|
||||
app:pressedTranslationZ="18dp"
|
||||
tools:ignore="MissingConstraints" />
|
||||
</com.amap.api.maps.MapView>
|
||||
|
||||
|
||||
<!--浮动按钮-->
|
||||
|
||||
<!--地图路线规划详情布局-->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
@@ -148,7 +165,7 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/tv_time" />
|
||||
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<resources>
|
||||
<string name="app_name">ManGoWalking</string>
|
||||
<string name="title_activity_base">BaseActivity</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user