|
|
@ -5,10 +5,15 @@ import android.app.NotificationManager |
|
|
import android.app.Service |
|
|
import android.app.Service |
|
|
import android.content.Context |
|
|
import android.content.Context |
|
|
import android.content.Intent |
|
|
import android.content.Intent |
|
|
|
|
|
import android.graphics.Bitmap |
|
|
|
|
|
import android.graphics.BitmapFactory |
|
|
import android.os.Build |
|
|
import android.os.Build |
|
|
import android.os.IBinder |
|
|
import android.os.IBinder |
|
|
|
|
|
import android.util.Base64 |
|
|
import android.util.Log |
|
|
import android.util.Log |
|
|
|
|
|
import android.widget.RemoteViews |
|
|
import androidx.core.app.NotificationCompat |
|
|
import androidx.core.app.NotificationCompat |
|
|
|
|
|
import androidx.core.content.ContextCompat |
|
|
import com.amap.api.navi.AMapNavi |
|
|
import com.amap.api.navi.AMapNavi |
|
|
import com.amap.api.navi.AMapNaviListener |
|
|
import com.amap.api.navi.AMapNaviListener |
|
|
import com.amap.api.navi.enums.NaviType |
|
|
import com.amap.api.navi.enums.NaviType |
|
|
@ -26,6 +31,7 @@ import com.amap.api.navi.model.AimLessModeCongestionInfo |
|
|
import com.amap.api.navi.model.AimLessModeStat |
|
|
import com.amap.api.navi.model.AimLessModeStat |
|
|
import com.amap.api.navi.model.NaviInfo |
|
|
import com.amap.api.navi.model.NaviInfo |
|
|
import com.amap.api.navi.model.NaviLatLng |
|
|
import com.amap.api.navi.model.NaviLatLng |
|
|
|
|
|
import java.io.ByteArrayOutputStream |
|
|
import java.io.FileNotFoundException |
|
|
import java.io.FileNotFoundException |
|
|
import java.util.concurrent.atomic.AtomicBoolean |
|
|
import java.util.concurrent.atomic.AtomicBoolean |
|
|
|
|
|
|
|
|
@ -61,6 +67,12 @@ class NavigationService: Service() { |
|
|
when (command) { |
|
|
when (command) { |
|
|
"start" -> { |
|
|
"start" -> { |
|
|
try { |
|
|
try { |
|
|
|
|
|
if (::aMapNavi.isInitialized) { |
|
|
|
|
|
Log.w(TAG, "已有导航进行中,先停止当前导航") |
|
|
|
|
|
aMapNavi.stopNavi() |
|
|
|
|
|
aMapNavi.removeAMapNaviListener(naviListener) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
startpos = intent.getStringExtra("startpos").toString() |
|
|
startpos = intent.getStringExtra("startpos").toString() |
|
|
endpos = intent.getStringExtra("endpos").toString() |
|
|
endpos = intent.getStringExtra("endpos").toString() |
|
|
naviType = intent.getStringExtra("naviType"); |
|
|
naviType = intent.getStringExtra("naviType"); |
|
|
@ -76,7 +88,7 @@ class NavigationService: Service() { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
"stop" -> { |
|
|
"stop" -> { |
|
|
aMapNavi.stopNavi(); |
|
|
stopNavigation(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
return START_STICKY |
|
|
return START_STICKY |
|
|
@ -107,6 +119,38 @@ class NavigationService: Service() { |
|
|
startForeground(NOTIFICATION_ID, notification) |
|
|
startForeground(NOTIFICATION_ID, notification) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private fun updateNotification(contentText: String, iconBitmap: Bitmap?) { |
|
|
|
|
|
val builder = NotificationCompat.Builder(this, CHANNEL_ID) |
|
|
|
|
|
.setContentTitle("导航进行中") |
|
|
|
|
|
.setContentText(contentText) |
|
|
|
|
|
.setSmallIcon(R.drawable.ic_navigation) // 通知栏图标(小) |
|
|
|
|
|
.setOnlyAlertOnce(true) |
|
|
|
|
|
.setOngoing(true) |
|
|
|
|
|
|
|
|
|
|
|
if (iconBitmap != null) { |
|
|
|
|
|
val tinted = tintBitmap(iconBitmap, ContextCompat.getColor(this, R.color.teal_200)) |
|
|
|
|
|
builder.setLargeIcon(tinted) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
val notification = builder.build() |
|
|
|
|
|
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager |
|
|
|
|
|
notificationManager.notify(NOTIFICATION_ID, notification) |
|
|
|
|
|
} |
|
|
|
|
|
private fun tintBitmap(source: Bitmap, tintColor: Int): Bitmap { |
|
|
|
|
|
val result = Bitmap.createBitmap(source.width, source.height, Bitmap.Config.ARGB_8888) |
|
|
|
|
|
val canvas = android.graphics.Canvas(result) |
|
|
|
|
|
val paint = android.graphics.Paint() |
|
|
|
|
|
paint.colorFilter = android.graphics.PorterDuffColorFilter(tintColor, android.graphics.PorterDuff.Mode.SRC_IN) |
|
|
|
|
|
canvas.drawBitmap(source, 0f, 0f, paint) |
|
|
|
|
|
return result |
|
|
|
|
|
} |
|
|
|
|
|
fun bitmapToBase64(bitmap: Bitmap?): String? { |
|
|
|
|
|
if (bitmap != null) return null; |
|
|
|
|
|
val outputStream = ByteArrayOutputStream() |
|
|
|
|
|
bitmap?.compress(Bitmap.CompressFormat.PNG, 100, outputStream) |
|
|
|
|
|
val byteArray = outputStream.toByteArray() |
|
|
|
|
|
return Base64.encodeToString(byteArray, Base64.NO_WRAP) |
|
|
|
|
|
} |
|
|
// 实现监听器,处理导航播报等 |
|
|
// 实现监听器,处理导航播报等 |
|
|
private val naviListener = object : AMapNaviListener { |
|
|
private val naviListener = object : AMapNaviListener { |
|
|
override fun onInitNaviFailure() { |
|
|
override fun onInitNaviFailure() { |
|
|
@ -162,12 +206,15 @@ class NavigationService: Service() { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
override fun onEndEmulatorNavi() { |
|
|
override fun onEndEmulatorNavi() { |
|
|
Log.e(TAG, "onEndEmulatorNavi! ") |
|
|
// Log.e(TAG, "onEndEmulatorNavi! ") |
|
|
|
|
|
Log.e(TAG, "onEndEmulatorNavi!") |
|
|
|
|
|
stopNavigation() |
|
|
// TODO("Not yet implemented") |
|
|
// TODO("Not yet implemented") |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
override fun onArriveDestination() { |
|
|
override fun onArriveDestination() { |
|
|
Log.e(TAG, "onArriveDestination! ") |
|
|
Log.e(TAG, "onArriveDestination!") |
|
|
|
|
|
stopNavigation() |
|
|
// TODO("Not yet implemented") |
|
|
// TODO("Not yet implemented") |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -200,9 +247,38 @@ class NavigationService: Service() { |
|
|
Log.e(TAG, "onGpsOpenStatus!") |
|
|
Log.e(TAG, "onGpsOpenStatus!") |
|
|
// TODO("Not yet implemented") |
|
|
// TODO("Not yet implemented") |
|
|
} |
|
|
} |
|
|
|
|
|
private var lastNotificationUpdateTime = 0L |
|
|
|
|
|
private val notificationUpdateInterval = 1000L // 1秒 |
|
|
|
|
|
override fun onNaviInfoUpdate(naviInfo: NaviInfo?) { |
|
|
|
|
|
if (naviInfo == null) return |
|
|
|
|
|
|
|
|
override fun onNaviInfoUpdate(p0: NaviInfo?) { |
|
|
val currentTime = System.currentTimeMillis() |
|
|
Log.e(TAG, "onNaviInfoUpdate! $p0") |
|
|
if (currentTime - lastNotificationUpdateTime < notificationUpdateInterval) { |
|
|
|
|
|
// 距离上次更新不足1秒,跳过这次更新 |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
val directionBitmap = naviInfo.iconBitmap |
|
|
|
|
|
val currentRoad = naviInfo.currentRoadName |
|
|
|
|
|
val nextRoad = naviInfo.nextRoadName |
|
|
|
|
|
val remainingDistance = naviInfo.getCurStepRetainDistance() |
|
|
|
|
|
val remainingTime = naviInfo.getPathRetainTime() |
|
|
|
|
|
val distanceText = if (remainingDistance < 1000) { |
|
|
|
|
|
"${remainingDistance} 米" |
|
|
|
|
|
} else { |
|
|
|
|
|
String.format("%.1f 千米", remainingDistance / 1000.0) |
|
|
|
|
|
} |
|
|
|
|
|
val contentText = "$distanceText \n进入:$nextRoad" |
|
|
|
|
|
val directionBitmapBase64 = bitmapToBase64(directionBitmap) |
|
|
|
|
|
val naviInfoMap: Map<String, Any> = mapOf( |
|
|
|
|
|
"currentRoad" to currentRoad, |
|
|
|
|
|
"nextRoad" to nextRoad, |
|
|
|
|
|
"distanceText" to distanceText, |
|
|
|
|
|
"directionIcon" to (directionBitmapBase64 ?: "") |
|
|
|
|
|
) |
|
|
|
|
|
NavigationServiceStarter.sendEvent("amap_update",naviInfoMap) |
|
|
|
|
|
updateNotification(contentText, directionBitmap) |
|
|
|
|
|
Log.e(TAG, "onNaviInfoUpdate! $contentText") |
|
|
|
|
|
// Log.e(TAG, "onNaviInfoUpdate! $p0") |
|
|
// TODO("Not yet implemented") |
|
|
// TODO("Not yet implemented") |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -263,7 +339,7 @@ class NavigationService: Service() { |
|
|
override fun onCalculateRouteSuccess(ids: IntArray?) { |
|
|
override fun onCalculateRouteSuccess(ids: IntArray?) { |
|
|
Log.e(TAG, "onCalculateRouteSuccess! $ids") |
|
|
Log.e(TAG, "onCalculateRouteSuccess! $ids") |
|
|
// AMapNavi.getInstance(this).startNavi(1); |
|
|
// AMapNavi.getInstance(this).startNavi(1); |
|
|
aMapNavi.startNavi(1) |
|
|
aMapNavi.startNavi(2) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
override fun onCalculateRouteSuccess(p0: AMapCalcRouteResult?) { |
|
|
override fun onCalculateRouteSuccess(p0: AMapCalcRouteResult?) { |
|
|
@ -312,5 +388,14 @@ class NavigationService: Service() { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private fun stopNavigation() { |
|
|
|
|
|
if (::aMapNavi.isInitialized) { |
|
|
|
|
|
aMapNavi.stopNavi() |
|
|
|
|
|
aMapNavi.removeAMapNaviListener(naviListener) |
|
|
|
|
|
} |
|
|
|
|
|
isRunning.set(false) |
|
|
|
|
|
stopSelf() |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
override fun onBind(intent: Intent?): IBinder? = null |
|
|
override fun onBind(intent: Intent?): IBinder? = null |
|
|
} |
|
|
} |