diff --git a/README.md b/README.md index 40f04a5..8d67513 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,11 @@ # 友盟+一键登录 友盟+上的appkey(用来唤醒),与阿里云购买appkey(同样可以唤醒前端sdk?)不同(后台需配置友盟+上的appkey,来获取token) + # 无法获取sha1失败 可通过gradle-app-android-signingReport获取 # gradle无法下载或者下载慢问题-替换阿里云或腾讯云镜像 添加maven { url 'https://maven.aliyun.com/repository/central' } maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' } -distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.2-bin.zip -distributionUrl=https\://emas-devops-cdn.aliyuncs.com/distributions/gradle-7.2-bin.zip \ No newline at end of file + distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.2-bin.zip + distributionUrl=https\://emas-devops-cdn.aliyuncs.com/distributions/gradle-7.2-bin.zip \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 03a6b71..6e674f1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -92,7 +92,9 @@ android:name="com.amap.api.v2.apikey" android:value="e0c32c80b14f78b770b3671add9c4515" /> - + + > + /** + * 司机轨迹上传 + * @param [Error type: Missed a type for a value parameter ] + * @return Observable> + */ + @POST(BASE_URL + "driver/driverWaybill/driverUploadLocus") + fun driverUploadLocus(@Body upLocation: UpLocation): Observable> + + /** * 司机接单 * */ @@ -487,8 +497,6 @@ interface Api { fun safeClassroomDetail(@Query("classroomId") problemId: String): Observable> - - /** * 获取APP最新版本信息 * @return Observable> diff --git a/app/src/main/java/com/dahe/gldriver/service/UpLocationService.kt b/app/src/main/java/com/dahe/gldriver/service/UpLocationService.kt new file mode 100644 index 0000000..b5c90aa --- /dev/null +++ b/app/src/main/java/com/dahe/gldriver/service/UpLocationService.kt @@ -0,0 +1,142 @@ +package com.dahe.gldriver.service + +import android.app.Service +import android.content.Intent +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.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.utils.GDLocationUtils +import com.dahe.mylibrary.net.CommonResponseBean +import com.dahe.mylibrary.utils.CrashHandler +import com.dahe.mylibrary.utils.CrashHandler2 +import com.dahe.mylibrary.utils.FileIOUtils +import com.dahe.mylibrary.utils.ToastUtils +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.schedulers.Schedulers +import java.io.File +import java.io.FileOutputStream +import java.io.PrintWriter +import java.io.StringWriter +import java.io.Writer +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 UpLocationService : Service() { + + private val hd = Handler { msg: Message -> + when (msg.what) { + 123 -> { + //获取文件输出路径 + 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.getLocation(application) { + if (it.getErrorCode() == 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 + ) + } + } + +// var orderString = BaseSPUtils.get(application,AppConfig.NEED_UP_ORDER,"") as String +// if (!orderString.isNullOrEmpty()){ +// var order = Gson().fromJson(orderString,OrderDetailBean::class.java) +// GDLocationUtils.instance.getLocation(application){ +// loadLocation(it,order) +// +// } +// }else{ +// +// } + } + } + 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 { + 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 + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/dahe/gldriver/ui/HomeActivity.kt b/app/src/main/java/com/dahe/gldriver/ui/HomeActivity.kt index 17d0ae2..002a15d 100644 --- a/app/src/main/java/com/dahe/gldriver/ui/HomeActivity.kt +++ b/app/src/main/java/com/dahe/gldriver/ui/HomeActivity.kt @@ -92,6 +92,7 @@ class HomeActivity : BaseActivity(), OnTabSelectListener, Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION, ) diff --git a/app/src/main/java/com/dahe/gldriver/ui/home/HomeFragment.kt b/app/src/main/java/com/dahe/gldriver/ui/home/HomeFragment.kt index 9a7ad31..721d13b 100644 --- a/app/src/main/java/com/dahe/gldriver/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/dahe/gldriver/ui/home/HomeFragment.kt @@ -1,11 +1,9 @@ package com.dahe.gldriver.ui.home import android.Manifest -import android.content.Intent import android.graphics.Color import android.os.Bundle import android.widget.LinearLayout -import android.widget.Toast import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.dahe.gldriver.R @@ -14,6 +12,7 @@ import com.dahe.gldriver.adapter.WaybillAdapter import com.dahe.gldriver.base.AppConfig import com.dahe.gldriver.base.WebActivity import com.dahe.gldriver.bean.GridBean +import com.dahe.gldriver.bean.OrderDetailBean import com.dahe.gldriver.databinding.FragmentHomeBinding import com.dahe.gldriver.net.BaseObserver import com.dahe.gldriver.net.DataManager @@ -159,6 +158,9 @@ class HomeFragment : BaseFragment(), RefreshCallBack { ) } })) + + //执行中运单轨迹上传 + OrderUtils.getInstance().upLocation(mContext) } private fun initRecy() { 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 ec8a21e..59328e9 100644 --- a/app/src/main/java/com/dahe/gldriver/utils/OrderUtils.kt +++ b/app/src/main/java/com/dahe/gldriver/utils/OrderUtils.kt @@ -1,17 +1,26 @@ package com.dahe.gldriver.utils import android.content.Context +import android.content.Intent import android.os.Bundle +import com.dahe.gldriver.base.App import com.dahe.gldriver.base.AppConfig +import com.dahe.gldriver.base.AppConfig.NEED_UP_ORDER import com.dahe.gldriver.bean.CarBean +import com.dahe.gldriver.bean.OrderDetailBean +import com.dahe.gldriver.bean.UpLocation import com.dahe.gldriver.callback.OnResultListener 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.ui.waybill.activity.WaybillLoadActivity import com.dahe.mylibrary.base.SingletonNoPHolder import com.dahe.mylibrary.net.CommonResponseBean import com.dahe.mylibrary.utils.ActivityUtils +import com.dahe.mylibrary.utils.BaseSPUtils +import com.google.gson.Gson +import com.gyf.cactus.Cactus import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.schedulers.Schedulers @@ -83,7 +92,7 @@ class OrderUtils private constructor() { * * 接单(包含选择车辆)->装货 * */ - fun goReceWaybill(context: Context, orderId: String,listener:OnResultListener) { + fun goReceWaybill(context: Context, orderId: String, listener: OnResultListener) { //选择车辆 DataManager.getInstance().carList() .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) @@ -95,7 +104,7 @@ class OrderUtils private constructor() { CommonPopUtils.getInstance() .showCarList(context, t.data) { //接单接口 - receivingOrders(context, orderId, it,listener) + receivingOrders(context, orderId, it, listener) } } else { //单量车,直接默认当前车辆 ,接单接口 @@ -141,4 +150,37 @@ class OrderUtils private constructor() { }) ) } + + + /** + * 上传运行中运单轨迹 + * @param context Context + */ + fun upLocation(context: Context) { + DataManager.getInstance().orderDetail("") + .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) + .subscribe(BaseObserver(context, object : RxHttpCallBack() { + override fun onSuccess(t: CommonResponseBean) { + 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) + } else { + context.stopService(Intent(context, UpLocationService::class.java)) + BaseSPUtils.remove(context, NEED_UP_ORDER) + } + } + })) + + } } \ No newline at end of file diff --git a/app/src/main/res/raw/main.mp3 b/app/src/main/res/raw/main.mp3 new file mode 100644 index 0000000..cec3fdd Binary files /dev/null and b/app/src/main/res/raw/main.mp3 differ diff --git a/mylibrary/build.gradle b/mylibrary/build.gradle index 4294ff8..7820254 100644 --- a/mylibrary/build.gradle +++ b/mylibrary/build.gradle @@ -91,7 +91,8 @@ dependencies { api 'com.github.jenly1314.AppUpdater:app-updater:1.2.0' api 'com.github.jenly1314.AppUpdater:app-dialog:1.2.0' -// api 'com.gyf.cactus:cactus:1.1.3-beta13' + api 'com.gyf.cactus:cactus:1.1.3-beta13' + diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/FileIOUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/FileIOUtils.java new file mode 100644 index 0000000..9e2c94a --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/FileIOUtils.java @@ -0,0 +1,238 @@ +package com.dahe.mylibrary.utils; + +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; + +/** + * @ClassName FileIOUtils + * @Author john + * @Date 2024/3/29 09:50 + * @Description TODO + */ +public class FileIOUtils { + + private FileIOUtils() { + throw new UnsupportedOperationException("u can't instantiate me..."); + } + + private static final String LINE_SEP = System.getProperty("line.separator"); + + /** + * 将输入流写入文件 + * + * @param filePath 路径 + * @param is 输入流 + * @return {@code true}: 写入成功
{@code false}: 写入失败 + */ + public static boolean writeFileFromIS(String filePath, final InputStream is) { + return writeFileFromIS(FileUtils.getFileByPath(filePath), is, false); + } + + /** + * 将输入流写入文件 + * + * @param filePath 路径 + * @param is 输入流 + * @param append 是否追加在文件末 + * @return {@code true}: 写入成功
{@code false}: 写入失败 + */ + public static boolean writeFileFromIS(String filePath, final InputStream is, boolean append) { + return writeFileFromIS(FileUtils.getFileByPath(filePath), is, append); + } + + /** + * 将输入流写入文件 + * + * @param file 文件 + * @param is 输入流 + * @return {@code true}: 写入成功
{@code false}: 写入失败 + */ + public static boolean writeFileFromIS(File file, final InputStream is) { + return writeFileFromIS(file, is, false); + } + + /** + * 将输入流写入文件 + * + * @param file 文件 + * @param is 输入流 + * @param append 是否追加在文件末 + * @return {@code true}: 写入成功
{@code false}: 写入失败 + */ + public static boolean writeFileFromIS(File file, final InputStream is, boolean append) { + if (!FileUtils.createOrExistsFile(file) || is == null) return false; + OutputStream os = null; + try { + os = new BufferedOutputStream(new FileOutputStream(file, append)); + byte data[] = new byte[1024]; + int len; + while ((len = is.read(data, 0, 1024)) != -1) { + os.write(data, 0, len); + } + return true; + } catch (IOException e) { + e.printStackTrace(); + return false; + } finally { + try { + is.close(); + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + } + + + /** + * 将字符串写入文件 + * + * @param filePath 文件路径 + * @param content 写入内容 + * @return {@code true}: 写入成功
{@code false}: 写入失败 + */ + public static boolean writeFileFromString(String filePath, String content) { + return writeFileFromString(FileUtils.getFileByPath(filePath), content, false); + } + + /** + * 将字符串写入文件 + * + * @param filePath 文件路径 + * @param content 写入内容 + * @param append 是否追加在文件末 + * @return {@code true}: 写入成功
{@code false}: 写入失败 + */ + public static boolean writeFileFromString(String filePath, String content, boolean append) { + return writeFileFromString(FileUtils.getFileByPath(filePath), content, append); + } + + /** + * 将字符串写入文件 + * + * @param file 文件 + * @param content 写入内容 + * @return {@code true}: 写入成功
{@code false}: 写入失败 + */ + public static boolean writeFileFromString(File file, String content) { + return writeFileFromString(file, content, false); + } + + /** + * 将字符串写入文件 + * + * @param file 文件 + * @param content 写入内容 + * @param append 是否追加在文件末 + * @return {@code true}: 写入成功
{@code false}: 写入失败 + */ + public static boolean writeFileFromString(File file, String content, boolean append) { + if (file == null || content == null) return false; + if (!FileUtils.createOrExistsFile(file)) return false; + BufferedWriter bw = null; + try { + bw = new BufferedWriter(new FileWriter(file, append)); + bw.write(content); + bw.newLine(); + return true; + } catch (IOException e) { + e.printStackTrace(); + return false; + } finally { + try { + bw.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + + /** + * 读取文件到字符串中 + * + * @param filePath 文件路径 + * @return 字符串 + */ + public static String readFile2String(String filePath) { + return readFile2String(FileUtils.getFileByPath(filePath), null); + } + + /** + * 读取文件到字符串中 + * + * @param filePath 文件路径 + * @param charsetName 编码格式 + * @return 字符串 + */ + public static String readFile2String(String filePath, String charsetName) { + return readFile2String(FileUtils.getFileByPath(filePath), charsetName); + } + + /** + * 读取文件到字符串中 + * + * @param file 文件 + * @return 字符串 + */ + public static String readFile2String(File file) { + return readFile2String(file, null); + } + + /** + * 读取文件到字符串中 + * + * @param file 文件 + * @param charsetName 编码格式 + * @return 字符串 + */ + public static String readFile2String(File file, String charsetName) { + if (!FileUtils.isFileExists(file)) return null; + BufferedReader reader = null; + try { + StringBuilder sb = new StringBuilder(); + if (isSpace(charsetName)) { + reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); + } else { + reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), charsetName)); + } + String line; + while ((line = reader.readLine()) != null) { + sb.append(line).append(LINE_SEP); + } + // delete the last line separator + return sb.delete(sb.length() - LINE_SEP.length(), sb.length()).toString(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } finally { + try { + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + + private static boolean isSpace(String s) { + if (s == null) return true; + for (int i = 0, len = s.length(); i < len; ++i) { + if (!Character.isWhitespace(s.charAt(i))) { + return false; + } + } + return true; + } + +}