diff --git a/app/build.gradle b/app/build.gradle
index 0455fef..668a913 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -140,6 +140,7 @@ dependencies {
implementation 'me.zhanghai.android.materialratingbar:library:1.4.0'
implementation project(path: ':mylibrary')
+ implementation project(path: ':keeplibrary')
//高德地图
// implementation 'com.amap.api:3dmap:9.8.3'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6e674f1..8d8629e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -46,7 +46,7 @@
-
+
@@ -94,7 +94,13 @@
+
+
+
+
+// // 定义前台服务的通知点击事件
+//// ActivityUtils.startActivity(applicationContext,HomeActivity::class.java)
+// }
+//// 启动保活服务
+// KeepLive.startWork(this,
+// KeepLive.RunMode.ENERGY,
+// foregroundNotification, //你需要保活的服务,如socket连接、定时任务等,建议不用匿名内部类的方式在这里写
+// object : UpLocationService23() {
+// /**
+// * 运行中
+// * 由于服务可能会多次自动启动,该方法可能重复调用
+// */
+// override fun onWorking() {
+// // do something
+// }
+//
+// /**
+// * 服务终止
+// * 由于服务可能会被多次终止,该方法可能重复调用,需同onWorking配套使用,如注册和注销broadcast
+// */
+// override fun onStop() {
+// // do something
+// }
+// }
+// )
}
override fun attachBaseContext(base: Context) {
diff --git a/app/src/main/java/com/dahe/gldriver/service/MyNotification.kt b/app/src/main/java/com/dahe/gldriver/service/MyNotification.kt
new file mode 100644
index 0000000..b953c15
--- /dev/null
+++ b/app/src/main/java/com/dahe/gldriver/service/MyNotification.kt
@@ -0,0 +1,137 @@
+package com.dahe.gldriver.service
+
+import android.annotation.SuppressLint
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.app.Service
+import android.content.Context
+import android.content.Context.NOTIFICATION_SERVICE
+import android.content.Intent
+import android.graphics.Color
+import android.os.Build
+import androidx.core.app.NotificationCompat
+import com.dahe.gldriver.R
+import com.dahe.gldriver.ui.HomeActivity
+import com.dahe.gldriver.utils.OcrUtils
+import com.dahe.mylibrary.base.SingletonNoPHolder
+
+/**
+ * @ClassName MyNotification
+ * @Author john
+ * @Date 2024/4/1 08:37
+ * @Description TODO
+ */
+class MyNotification private constructor() {
+
+ companion object : SingletonNoPHolder(::MyNotification)
+
+ fun getNotification(context: Context): Notification {
+// return buildNotification(context)
+ return sendNotify(context)
+ }
+
+
+ /**
+ * 实现包装方法(参数按自己需求来)
+ * @param title 标题
+ * @param content 内容
+ * @param priorityType 通知级别:0为重要通知(有提示音),非0为普通通知(无提示音)
+ */
+
+
+}
+
+private var notificationManager: NotificationManager? = null
+var isCreateChannel = false
+fun buildNotification(ctx: Context): Notification {
+ var builder: Notification.Builder? = null
+ var notification: Notification? = null
+ if (Build.VERSION.SDK_INT >= 26) {
+ //Android O上对Notification进行了修改,如果设置的targetSDKVersion>=26建议使用此种方式创建通知栏
+ if (null == notificationManager) {
+ notificationManager =
+ ctx.getSystemService(Service.NOTIFICATION_SERVICE) as NotificationManager
+ }
+ val channelId = ctx.packageName
+ if (!isCreateChannel) {
+ val notificationChannel = NotificationChannel(
+ channelId,
+ "BackgroundLocation", NotificationManager.IMPORTANCE_DEFAULT
+ )
+ notificationChannel.enableLights(true) //是否在桌面icon右上角展示小圆点
+ notificationChannel.lightColor = Color.BLUE //小圆点颜色
+ notificationChannel.setShowBadge(true) //是否在久按桌面图标时显示此渠道的通知
+ notificationManager?.createNotificationChannel(notificationChannel)
+ isCreateChannel = true
+ }
+ builder = Notification.Builder(ctx, channelId)
+ } else {
+ builder = Notification.Builder(ctx)
+ }
+ builder.setSmallIcon(R.mipmap.app_icon)
+ .setContentTitle("大河好运司机端")
+ .setContentText("大河好运司机端为您提供服务")
+ .setWhen(System.currentTimeMillis())
+ notification = if (Build.VERSION.SDK_INT >= 16) {
+ builder.build()
+ } else {
+ return builder.notification
+ }
+ return notification
+}
+
+
+
+
+fun sendNotify( context: Context) : Notification{
+
+ var manager = context.getSystemService (NOTIFICATION_SERVICE) as NotificationManager
+
+ var wsschannel:NotificationChannel;// channel(安卓8.0及以上才用到)
+ var channel_id = "my_notification_important"; // channelId用于绑定builder配置
+ var priority = NotificationCompat.PRIORITY_LOW; // 通知级别
+
+ // 判断是否8.0及以上版本,并选择发送消息的级别
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+// if (priorityType == 0) {
+ wsschannel =
+ NotificationChannel ("my_notification_important", "重要通知", NotificationManager.IMPORTANCE_HIGH);
+ channel_id = "my_notification_important";
+// } else {
+// wsschannel =
+// NotificationChannel (NORMAL_CHANNEL_ID, "一般通知", NotificationManager.IMPORTANCE_LOW);
+// channel_id = NORMAL_CHANNEL_ID;
+// }
+ manager.createNotificationChannel(wsschannel);
+ }
+
+ // 通知级别
+// if (priorityType == 0) {
+// priority = NotificationCompat.PRIORITY_HIGH;
+// } else {
+// priority = NotificationCompat.PRIORITY_LOW;
+// }
+
+ // 点击意图
+ var intent = Intent(context, HomeActivity::class.java);
+ var pendingIntent = PendingIntent.getActivity (context, 0, intent, PendingIntent.FLAG_IMMUTABLE);
+
+ // 通知配置
+ var notification = NotificationCompat.Builder (context, channel_id)
+ .setContentTitle("大河好运司机端") // 标题
+ .setContentText("大河好运司机端为您提供服务") // 内容
+ .setSmallIcon(R.mipmap.app_icon) // 小图标
+ .setPriority(NotificationCompat.PRIORITY_HIGH) // 7.0 设置优先级
+ .setContentIntent(pendingIntent) // 跳转意图
+// .setAutoCancel(true) // 点击后自动销毁
+ .build();
+
+ // 给每个通知随机id
+// int id =(int)((Math.random() * 9 + 1) * (6));
+
+ // 生成通知
+ manager.notify(1, notification);
+ return notification
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/dahe/gldriver/service/UpLocationService2.kt b/app/src/main/java/com/dahe/gldriver/service/UpLocationService2.kt
new file mode 100644
index 0000000..7cdd9db
--- /dev/null
+++ b/app/src/main/java/com/dahe/gldriver/service/UpLocationService2.kt
@@ -0,0 +1,185 @@
+package com.dahe.gldriver.service
+
+import android.annotation.SuppressLint
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.app.Service
+import android.content.Context
+import android.content.Intent
+import android.graphics.Color
+import android.os.Build
+import android.os.Environment
+import android.os.Handler
+import android.os.IBinder
+import android.os.Message
+import android.util.Log
+import com.amap.api.location.AMapLocation
+import com.dahe.gldriver.R
+import com.dahe.gldriver.base.AppConfig
+import com.dahe.gldriver.bean.OrderDetailBean
+import com.dahe.gldriver.bean.UpLocation
+import com.dahe.gldriver.net.BaseObserver
+import com.dahe.gldriver.net.DataManager
+import com.dahe.gldriver.net.RxHttpCallBack
+import com.dahe.gldriver.ui.HomeActivity
+import com.dahe.gldriver.utils.GDLocationUtils
+import com.dahe.mylibrary.net.CommonResponseBean
+import com.dahe.mylibrary.utils.BaseSPUtils
+import com.dahe.mylibrary.utils.FileIOUtils
+import com.google.gson.Gson
+import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
+import io.reactivex.rxjava3.schedulers.Schedulers
+import java.text.DateFormat
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Timer
+import java.util.TimerTask
+
+
+/**
+ * @ClassName UpLocationService
+ * @Author john
+ * @Date 2024/3/28 09:08
+ * @Description TODO
+ */
+class UpLocationService2 : Service() {
+
+ private val hd = Handler { msg: Message ->
+ when (msg.what) {
+ 123 -> {
+ var orderString =
+ BaseSPUtils.get(application, AppConfig.NEED_UP_ORDER, "") as String
+ if (!orderString.isNullOrEmpty()) {
+ var order = Gson().fromJson(orderString, OrderDetailBean::class.java)
+ GDLocationUtils.instance.getLocation2(application) {
+ if (it.errorCode == 0 && it.latitude != 0.0) {
+ loadLocation(it, order)
+ }
+ }
+ } else {
+ GDLocationUtils.instance.stopLocation()
+ }
+
+ //获取文件输出路径
+// val path = Environment.getExternalStorageDirectory()
+// .toString() + "/crashinfo/"
+// val time: String = formatter.format(Date())
+// val time2: String = formatter2.format(Date())
+// val fileName = "crash-$time.txt"
+//
+// GDLocationUtils.instance.getLocation2(application) {
+// if (it.errorCode == 0 && it.latitude != 0.0) {
+// FileIOUtils.writeFileFromString(
+// path + fileName,
+// """当前时间:${time2},经纬度:${it.latitude}:${it.longitude}""",
+// true
+// )
+//
+// } else {
+// FileIOUtils.writeFileFromString(
+// path + fileName,
+// """当前时间:${time2},经纬度:${it.latitude}${it.errorInfo}""",
+// true
+// )
+// }
+// }
+
+ }
+ }
+ false
+ }
+
+ private val formatter: DateFormat = SimpleDateFormat("yyyy-MM-dd")
+ private val formatter2: DateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
+
+ override fun onBind(intent: Intent?): IBinder? {
+ return null
+ }
+
+ override fun onRebind(intent: Intent?) {
+ super.onRebind(intent)
+ }
+
+ private val timeSum = 1000 * 60 * 3
+
+ // private val timeSum = 3000
+ private var timer: Timer? = null
+ override fun onCreate() {
+ super.onCreate()
+
+ Log.e("开始循环上传,等待100ms", "-----")
+ timer = Timer()
+ timer?.schedule(object : TimerTask() {
+ override fun run() {
+ val msg = Message.obtain()
+ msg.what = 123
+ hd.sendMessage(msg)
+ }
+ }, 1000, timeSum.toLong())
+ }
+
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+
+// Log.d(TAG, "onStartCommand flags:$flags, startId:$startId [$this] ${Thread.currentThread()}")
+
+ val pendingIntent: PendingIntent =
+ Intent(this, HomeActivity::class.java).let { notificationIntent ->
+ PendingIntent.getActivity(this, 0, notificationIntent, 0)
+ }
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ val chanId = "f-channel"
+ val chan = NotificationChannel(
+ chanId, "前台服务channel",
+ NotificationManager.IMPORTANCE_NONE
+ )
+ chan.lightColor = Color.BLUE
+ chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
+ val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+ service.createNotificationChannel(chan)
+// Log.d(TAG, "服务调用startForeground")
+
+ val notification: Notification =
+ Notification.Builder(applicationContext, chanId)
+ .setContentTitle("大河好运司机端")
+ .setContentText("大河好运司机端为您提供服务")
+ .setSmallIcon(R.mipmap.app_icon)
+ .setContentIntent(pendingIntent)
+ .build()
+ startForeground(1, notification)
+ } else {
+// Log.d(TAG, "${Build.VERSION.SDK_INT} < O(API 26) ")
+ }
+ return START_STICKY
+ }
+
+ private fun loadLocation(loc: AMapLocation, order: OrderDetailBean) {
+ DataManager.getInstance().driverUploadLocus(
+ UpLocation(
+ loc.latitude,
+ loc.longitude,
+ order.orderId,
+ order.waybillId
+ )
+ )
+ .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
+ .subscribe(BaseObserver(application, object : RxHttpCallBack() {
+ override fun onSuccess(t: CommonResponseBean) {
+ super.onSuccess(t)
+ }
+ }))
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ if (timer != null) {
+ timer?.cancel()
+ timer = null
+ }
+ GDLocationUtils.instance.stopLocation()
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/dahe/gldriver/ui/waybill/activity/WaybillUpPicActivity.kt b/app/src/main/java/com/dahe/gldriver/ui/waybill/activity/WaybillUpPicActivity.kt
index 1eaa7e8..3f88487 100644
--- a/app/src/main/java/com/dahe/gldriver/ui/waybill/activity/WaybillUpPicActivity.kt
+++ b/app/src/main/java/com/dahe/gldriver/ui/waybill/activity/WaybillUpPicActivity.kt
@@ -14,6 +14,7 @@ import com.dahe.gldriver.net.DataManager
import com.dahe.gldriver.net.RxHttpCallBack
import com.dahe.gldriver.oss.OssServiceUtil
import com.dahe.gldriver.utils.GDLocationUtils
+import com.dahe.gldriver.utils.OrderUtils
import com.dahe.mylibrary.adapter.GridImageAdapter
import com.dahe.mylibrary.adapter.GridImageAdapter.OnItemClickListener
import com.dahe.mylibrary.base.BaseActivity
@@ -256,7 +257,10 @@ class WaybillUpPicActivity : BaseActivity() {
mContext,
WaybillSuccActivity::class.java,
intent.extras)
+ //装货成功-开启轨迹上传
+ OrderUtils.getInstance().upLocation(mContext)
} else {
+ OrderUtils.getInstance().stopUpLocation(mContext)
ActivityUtils.startActivity(
mContext,
WaybillSuccActivity::class.java,
diff --git a/app/src/main/java/com/dahe/gldriver/utils/GDLocationUtils.kt b/app/src/main/java/com/dahe/gldriver/utils/GDLocationUtils.kt
index e645923..9bbf063 100644
--- a/app/src/main/java/com/dahe/gldriver/utils/GDLocationUtils.kt
+++ b/app/src/main/java/com/dahe/gldriver/utils/GDLocationUtils.kt
@@ -1,10 +1,18 @@
package com.dahe.gldriver.utils
+import android.annotation.SuppressLint
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.Service
import android.content.Context
+import android.graphics.Color
+import android.os.Build
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
-
+import com.dahe.gldriver.R
+import com.dahe.gldriver.service.MyNotification
class GDLocationUtils private constructor(){
@@ -52,7 +60,8 @@ class GDLocationUtils private constructor(){
//设置是否允许模拟位置,默认为true,允许模拟位置
mLocationOption?.setMockEnable(true)
-
+ //启动后台定位,第一个参数为通知栏ID,建议整个APP使用一个
+// mLocationClient?.enableBackgroundLocation(1,buildNotification(ctx))
//给定位客户端对象设置定位参数
mLocationClient?.setLocationOption(mLocationOption);
if(null != mLocationClient){
@@ -62,8 +71,57 @@ class GDLocationUtils private constructor(){
mLocationClient?.startLocation()
}
}
+
+
+ /**
+ * 上传轨迹专用
+ * @param ctx Context
+ * @param mLocationListener AMapLocationListener
+ */
+ fun getLocation2(ctx : Context,mLocationListener : AMapLocationListener){
+ //初始化定位
+ mLocationClient = AMapLocationClient(ctx)
+ //设置定位回调监听
+ mLocationClient?.setLocationListener(mLocationListener)
+ //初始化AMapLocationClientOption对象
+ mLocationOption = AMapLocationClientOption()
+
+ /**
+ * 设置定位场景,目前支持三种场景(签到、出行、运动,默认无场景)
+ */
+ mLocationOption?.setLocationPurpose(AMapLocationClientOption.AMapLocationPurpose.SignIn)
+
+
+ //设置定位模式为AMapLocationMode.Hight_Accuracy,高精度模式。
+ mLocationOption?.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving)
+// mLocationOption?.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving)
+
+ //获取一次定位结果:
+ //该方法默认为false。
+ mLocationOption?.setOnceLocation(true)
+
+ //获取最近3s内精度最高的一次定位结果:
+//设置setOnceLocationLatest(boolean b)接口为true,启动定位时SDK会返回最近3s内精度最高的一次定位结果。如果设置其为true,setOnceLocation(boolean b)接口也会被设置为true,反之不会,默认为false。
+ mLocationOption?.setOnceLocationLatest(true)
+
+ //设置是否允许模拟位置,默认为true,允许模拟位置
+ mLocationOption?.setMockEnable(true)
+ //启动后台定位,第一个参数为通知栏ID,建议整个APP使用一个
+ mLocationClient?.enableBackgroundLocation(1,MyNotification.getInstance().getNotification(ctx))
+ //给定位客户端对象设置定位参数
+ mLocationClient?.setLocationOption(mLocationOption);
+ if(null != mLocationClient){
+ mLocationClient?.setLocationOption(mLocationOption);
+ //设置场景模式后最好调用一次stop,再调用start以保证场景模式生效
+ mLocationClient?.stopLocation()
+ mLocationClient?.startLocation()
+ }
+ }
+
+
fun stopLocation(){
if(null != mLocationClient){
+ mLocationClient?.disableBackgroundLocation(true)
mLocationClient?.stopLocation()
}
}
diff --git a/app/src/main/java/com/dahe/gldriver/utils/OrderUtils.kt b/app/src/main/java/com/dahe/gldriver/utils/OrderUtils.kt
index 59328e9..58b1027 100644
--- a/app/src/main/java/com/dahe/gldriver/utils/OrderUtils.kt
+++ b/app/src/main/java/com/dahe/gldriver/utils/OrderUtils.kt
@@ -2,6 +2,7 @@ package com.dahe.gldriver.utils
import android.content.Context
import android.content.Intent
+import android.os.Build
import android.os.Bundle
import com.dahe.gldriver.base.App
import com.dahe.gldriver.base.AppConfig
@@ -14,6 +15,7 @@ import com.dahe.gldriver.net.BaseObserver
import com.dahe.gldriver.net.DataManager
import com.dahe.gldriver.net.RxHttpCallBack
import com.dahe.gldriver.service.UpLocationService
+import com.dahe.gldriver.service.UpLocationService2
import com.dahe.gldriver.ui.waybill.activity.WaybillLoadActivity
import com.dahe.mylibrary.base.SingletonNoPHolder
import com.dahe.mylibrary.net.CommonResponseBean
@@ -164,23 +166,25 @@ class OrderUtils private constructor() {
super.onSuccess(t)
if (t.data != null) {
BaseSPUtils.put(context, NEED_UP_ORDER, Gson().toJson(t.data))
- context.startService(Intent(context, UpLocationService::class.java))
-// if (!Cactus.instance.isRunning(context)) {
-// Cactus.instance.addCallback {
-// context.startService(Intent(context, UpLocationService::class.java))
-// }.restart(context)
-// }else{
-// Cactus.instance.addCallback {
-// context.startService(Intent(context, UpLocationService::class.java))
-// }.restart(context)
-// }
-// OrderUtils.getInstance().upLocation("","",t.data.orderId,t.data.waybillId)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ context.startForegroundService(Intent(context, UpLocationService2::class.java))
+ }else{
+ context.startService(Intent(context, UpLocationService2::class.java))
+ }
} else {
- context.stopService(Intent(context, UpLocationService::class.java))
+ context.stopService(Intent(context, UpLocationService2::class.java))
BaseSPUtils.remove(context, NEED_UP_ORDER)
}
}
}))
}
+
+ /**
+ * 关闭上传运行中运单轨迹
+ * @param context Context
+ */
+ fun stopUpLocation(context: Context){
+ context.stopService(Intent(context, UpLocationService2::class.java))
+ }
}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 649748d..e04e5d9 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -22,3 +22,4 @@ dependencyResolutionManagement {
rootProject.name = "GLDriver"
include ':app'
include ':mylibrary'
+include ':keeplibrary'