lmw
2024-05-28 524abed53193c67683a363ce0f12fe4aa98323a0
行程录音,接送机
1 文件已重命名
11个文件已修改
246 ■■■■■ 已修改文件
app/build.gradle 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/future/driver/base/BaseEvent.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/future/driver/base/MyApplication.kt 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/future/driver/netUtls/Api.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/future/driver/ui/UiUtil.kt 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/future/driver/ui/main/GetOrderFragment.kt 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/future/driver/ui/main/MainActivity.kt 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/future/driver/ui/main/OrderOverActivity.kt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/future/driver/ui/main/TripActivity.kt 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/future/driver/ui/to_city/TripCityActivity.kt 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/future/driver/utils/AudioRecordUtils.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/future/driver/utils/OSSUtil.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/build.gradle
@@ -24,8 +24,8 @@
        applicationId "com.future.driver"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 4
        versionName "3.0.1"
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        ndk {
@@ -35,7 +35,7 @@
        applicationVariants.all { variant ->
            // 更新至Android Studio 3.3 gradle 4.10.1
            variant.outputs.all {
                outputFileName = "fuban_driver-${defaultConfig.versionName}-${new Date().format("yyyy-MM-dd" , TimeZone.getTimeZone("GMT+08")) }.apk"
                outputFileName = "future_driver-${defaultConfig.versionName}-${new Date().format("yyyy-MM-dd" , TimeZone.getTimeZone("GMT+08")) }.apk"
            }
        }
        manifestPlaceholders = [
app/src/main/java/com/future/driver/base/BaseEvent.java
@@ -50,6 +50,9 @@
    public static final int FACE_SUC = 10030; // 人脸失败
    public static final int FACE_FAILED = 10031; // 人脸成功
    public static final int START_RECORD = 10032; //开始录音任务
    public static final int FINISH_RECORD = 10033; //结束录音任务
    private String msg;
    private int code;
app/src/main/java/com/future/driver/base/MyApplication.kt
@@ -141,7 +141,7 @@
                                    val act = activities[activities.size - 1]
//                                    MyApplication.getTTsManager().setVideoText("收到新的订单")
                                    when (orderSimpleData.orderType) {
                                        1,2 -> {
                                        1,2,7 -> {
                                            (act as MyBaseActivity).showOrder(
                                                orderSimpleData.orderId.toString(),
                                                orderSimpleData.orderType.toString(),
@@ -162,7 +162,7 @@
                                if (orderSimpleData.status == 2) {
                                    val act = activities[activities.size - 1]
                                    when (orderSimpleData.orderType) {
                                        1, 2 -> {
                                        1, 2,7 -> {
                                            (act as MyBaseActivity).toDorderAct(
                                                orderSimpleData.orderId.toString(),
                                                orderSimpleData.orderType.toString()
@@ -195,7 +195,7 @@
                                    )
                                val act = activities[activities.size - 1]
                                when (orderSimpleData.orderType) {
                                    1, 2 -> {
                                    1, 2 ,7-> {
                                        (act as MyBaseActivity).showOrder(
                                            orderSimpleData.orderId.toString(),
                                            orderSimpleData.orderType.toString(),
@@ -391,6 +391,11 @@
        var aMapLocation: AMapLocation? = null
        var currentOrderId: String = ""
        var currentOrderType: String = ""
        var recordOrderType = "" //当前录音的订单类型
        var recordOrderId = "" //当前录音的订单id
        var isRecording = false //当前是否在录音
        var orderStatueViews: MutableList<OrderStatueView> =
            mutableListOf()
        var testHeartNunm = 0
app/src/main/java/com/future/driver/netUtls/Api.java
@@ -79,6 +79,7 @@
    public static String queryCityOrderInfo = "api/orderCrossCity/queryOrderInfo"; //api/orderCrossCity/queryOrderInfo 获取订单跨城详情
    public static String setOrderCrossCitySort = "api/orderCrossCity/setOrderCrossCitySort"; ///api/orderCrossCity/setOrderCrossCitySort 修改订单顺序(跨城)
    public static String setEnd = "api/order/specail"; //改目的地
    public static String tape = "api/order/tape"; //提交录音
    /**
     * 消息
app/src/main/java/com/future/driver/ui/UiUtil.kt
@@ -22,6 +22,9 @@
            6 -> {
                return "包车"
            }
            7 -> {
                return "接送机/站"
            }
        }
        return ""
    }
app/src/main/java/com/future/driver/ui/main/GetOrderFragment.kt
@@ -117,7 +117,7 @@
            if (!data.remark.isNullOrEmpty()) {
                tv_remark.text = data.remark
            }
            if (orderType == "1") {
            if (orderType == "1"||orderType == "7") {
                tv_money.gone()
            }
            if (orderType == "5" || orderType == "4") {
@@ -204,7 +204,7 @@
                "2" -> {
                    this.startActivity<TripActivity>("orderId" to orderId, "orderType" to orderType)
                }
                "1" -> {
                "1","7" -> {
                    this.startActivity<TripActivity>("orderId" to orderId, "orderType" to orderType)
                }
                "3" -> {
app/src/main/java/com/future/driver/ui/main/MainActivity.kt
@@ -6,8 +6,8 @@
import android.os.Handler
import android.os.Looper
import android.provider.Settings
import android.util.Log
import android.widget.Toast
import androidx.core.app.ActivityCompat
import cn.sinata.rxnetty.NettyClient
import cn.sinata.xldutils.utils.*
import com.amap.api.location.AMapLocation
@@ -30,8 +30,10 @@
import com.future.driver.ui.main.event.MineEventActivity
import com.future.driver.ui.mine.MineActivity
import com.future.driver.ui.mine.MsgActivity
import com.future.driver.utils.AudioRecordUtils
import com.future.driver.utils.Cache.CacheKey
import com.future.driver.utils.DateUtil
import com.future.driver.utils.OSSUtil
import com.future.driver.utils.download.DownloadUtil
import com.google.gson.Gson
import com.lljjcoder.style.citylist.Toast.ToastUtils
@@ -42,8 +44,8 @@
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.toast
class MainActivity : MyBaseActivity(), AMapLocationListener {
class MainActivity : MyBaseActivity(), AMapLocationListener,
    AudioRecordUtils.OnAudioStatusUpdateListener {
    val mainFragment by lazy {
        MainFragment()
@@ -55,17 +57,28 @@
        setContentView(R.layout.activity_main)
    }
    private var recorder:AudioRecordUtils? = null  //录音器
    private val VOICE_LENGTH = 1000L*60*5 //实际5分钟一个片段
//    private val VOICE_LENGTH = 1000L*15 //测试15秒一个片段
    override fun initView() {
        MyApplication.canPlayVoice = true
//        var packageName = "com.android.providers.downloads";
//        var intent =  Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
//    intent.setData(Uri.parse("package:" + packageName));
//    startActivity(intent);
        if (CacheKey.getKeyStr(Const.REFUSE_LOCATION).isNotEmpty()&&!RxPermissions(this).isGranted(Manifest.permission.ACCESS_FINE_LOCATION)){
        if (CacheKey.getKeyStr(Const.REFUSE_LOCATION).isNotEmpty()&&!RxPermissions(this).isGranted(
                Manifest.permission.ACCESS_FINE_LOCATION
            )){
            toast("没有定位权限,您将无法收到新订单推送")
        }else{
            if (!RxPermissions(this).isGranted(Manifest.permission.ACCESS_FINE_LOCATION)){
                DialogUtil.getDelAndSureDialog(this,"去授权","否","《未来出行司机》需要获取您的当前位置信息,用于查询当前城市是否开通服务,我们会将您的位置实时上传至后端为您匹配和推送附近订单。如果拒绝定位权限,您将无法正常接单。",{
                DialogUtil.getDelAndSureDialog(
                    this,
                    "去授权",
                    "否",
                    "《未来出行司机》需要获取您的当前位置信息,用于查询当前城市是否开通服务,我们会将您的位置实时上传至后端为您匹配和推送附近订单。如果拒绝定位权限,您将无法正常接单。",
                    {
                }){
                    val subscribe =
                        RxPermissions(this).request(Manifest.permission.ACCESS_FINE_LOCATION).subscribe {
@@ -325,6 +338,13 @@
            BaseEvent.FACE_FAILED -> {
                tv_face.visible()
            }
            BaseEvent.START_RECORD -> {
                if (!MyApplication.isRecording)
                    startRecord()
            }
            BaseEvent.FINISH_RECORD -> {
                recorder?.stopRecord()
            }
        }
    }
@@ -335,6 +355,70 @@
        }
    }
    private fun startRecord(){
        if (recorder == null){
            recorder = AudioRecordUtils(getExternalFilesDir(null)?.path+"/")
            recorder?.setOnAudioStatusUpdateListener(this)
        }
        if (RxPermissions(this).isGranted(Manifest.permission.RECORD_AUDIO)&&RxPermissions(this).isGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)){
            Log.e("mmp","订单${MyApplication.recordOrderId} 开始录音...")
            recorder?.startRecord()
        }
        else
            toast("缺少录音相关权限")
    }
    private fun updateVoice(filePath: String) {
        val ossUtil = OSSUtil(this)
        ossUtil.uploadSingleWithSize(filePath, object : OSSUtil.OSSUploadCallBack() {
            override fun onFinishWithSize(url: String?, size: Long) {
                super.onFinishWithSize(url, size)
                Log.e("mmp","录音保存路径:${url},大小:${size/1024}kb")
                val mapByAny = getMapByAny()
                mapByAny["fileFormat"] = "caf"
                mapByAny["fileLink"] = url
                mapByAny["fileSize"] = size/1024
                mapByAny["orderId"] = MyApplication.recordOrderId
                mapByAny["orderType"] = MyApplication.recordOrderType
                callNet(false,Api.tape,mapByAny){
                }
            }
            override fun onFial(message: String?) {
                super.onFial(message)
                runOnUiThread {
                    Toast.makeText(this@MainActivity, "录音上传失败,请检查网络", Toast.LENGTH_SHORT).show()
                }
            }
        })
    }
    override fun onUpdate(db: Double, time: Long) {
        MyApplication.isRecording = true
        if (time >= VOICE_LENGTH) {
            Log.e("mmp","订单${MyApplication.recordOrderId} 录音片段完成")
            recorder?.stopRecord() //结束录音
        }
    }
    override fun onStop(filePath: String) {
        MyApplication.isRecording = false
        Thread {
            updateVoice(filePath)
        }.start()
        if (MyApplication.currentOrderId.isNotEmpty()){//行程未结束 继续录制下一段
            Log.e("mmp","订单${MyApplication.recordOrderId} 开始下一片段录音")
            recorder?.startRecord()
        }
    }
    override fun onStartPlay() {
    }
    override fun onFinishPlay() {
    }
    override fun onDestroy() {
        super.onDestroy()
        MyApplication.canPlayVoice = false
app/src/main/java/com/future/driver/ui/main/OrderOverActivity.kt
@@ -42,6 +42,7 @@
        ll_order_cancel.gone()
        MyApplication.currentOrderType = ""
        MyApplication.currentOrderId = ""
        EventBus.getDefault().post(BaseEvent(BaseEvent.FINISH_RECORD))
        ll_pay_result.gone()
        tv_show_pay_over.gone()
    }
app/src/main/java/com/future/driver/ui/main/TripActivity.kt
@@ -103,7 +103,7 @@
            override fun orderInfo(data: OrderSimpleData?) {
                data?.let {
                    when(it.orderType){
                        1,2,3 -> {
                        1, 2, 3,7 -> {
                            if (it.status == 10 || it.status == 12) {
                                Handler(Looper.getMainLooper()).post {
                                    toast("用户已取消订单")
@@ -259,7 +259,7 @@
                            toast("只能在预约时间的半小时内出行")
                            return@let
                        }
                        if (it.data.orderState == 4&& !rxPermissions.isGranted(Manifest.permission.RECORD_AUDIO)&& !rxPermissions.isGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)){
                        if (it.data.orderState == 4&& (!rxPermissions.isGranted(Manifest.permission.RECORD_AUDIO) || !rxPermissions.isGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE))){
                            DialogUtil.getDelAndSureDialog(this,"去授权","取消","根据平台规则,为了保证司乘安全,我们将会对行程进行录音,因此需要获取录音和文件存储权限",{
                            }){
                                rxPermissions.request(Manifest.permission.RECORD_AUDIO,Manifest.permission.WRITE_EXTERNAL_STORAGE).subscribe {
@@ -296,7 +296,7 @@
                            "2" -> {
                                showMoneyTypeDialog()
                            }
                            "1" -> {
                            "1","7" -> {
                                callStatue(6,{
                                    startActivity<MajorSureMoneyActivity>(
                                        "orderId" to orderId,
@@ -343,6 +343,7 @@
        onlySureDialog.setOnDismissListener {
            timer.cancel()
        }
        EventBus.getDefault().post(BaseEvent(BaseEvent.START_RECORD))
    }
    private fun callStatue(i: Int, click: () -> Unit, clickFail: () -> Unit) {
@@ -484,6 +485,8 @@
    private fun callOrder() {
        MyApplication.currentOrderId = orderId
        MyApplication.currentOrderType = orderType
        MyApplication.recordOrderId = orderId
        MyApplication.recordOrderType = orderType
        var map = getMapByAny()
        map["orderId"] = orderId
        map["orderType"] = orderType
@@ -506,7 +509,7 @@
                tv_end_address.text = it.data.endAddress
                tv_change_end.gone()
            }
            if (orderType == "1"){
            if (orderType == "1"||orderType == "7"){
                tv_red_money.gone()
            }
            tv_red_money.text = it.data.tipMoney.toString() + "元红包"
@@ -625,6 +628,9 @@
                changeCarFive(true)
                setTitleText("服务中")
                slide_btn.changeButtonText("送达该乘客")
                if (!MyApplication.isRecording){
                    EventBus.getDefault().post(BaseEvent(BaseEvent.START_RECORD))
                }
            }
        }
    }
@@ -726,8 +732,8 @@
                    if (byChangeEnd){
                        orderBean.data.orderState++
                        callStatue(orderBean.data.orderState,{
                            showStatueMapUI(orderBean)
                            showRecordDialog()
                            showStatueMapUI(orderBean)
                        }) {
                            orderBean.data.orderState--
                        }
app/src/main/java/com/future/driver/ui/to_city/TripCityActivity.kt
@@ -1,8 +1,10 @@
package com.future.driver.ui.to_city
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Handler
import android.os.Looper
import android.view.Gravity
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import cn.sinata.xldutils.utils.*
@@ -41,6 +43,7 @@
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_trip_city.*
import kotlinx.android.synthetic.main.dialog_select_pay_type.view.*
import kotlinx.android.synthetic.main.dialog_sure_and_del.view.*
import kotlinx.android.synthetic.main.item_city_over.*
import kotlinx.android.synthetic.main.item_city_over.view.*
import kotlinx.android.synthetic.main.item_map_market.view.*
@@ -95,6 +98,10 @@
        setTitleText("已完成")
        tv_Right.text = "申请改派"
        orderId = intent.getStringExtra("orderId")
        MyApplication.recordOrderId = orderId
        MyApplication.recordOrderType = orderType
        recycler_view_order_list.layoutManager = LinearLayoutManager(this)
        recycler_view_order_list.adapter = tripItemAdapter
        callOrder()
@@ -325,6 +332,7 @@
            iv_move.gone()
            iv_to_gd.gone()
            cl_over_view.visible()
            EventBus.getDefault().post(BaseEvent(BaseEvent.FINISH_RECORD))
            recycler_view_money.layoutManager = LinearLayoutManager(this)
            recycler_view_money.adapter = overAdapter
            orderBean?.let {
@@ -345,6 +353,27 @@
            }
        }
        return b
    }
    private fun showRecordDialog(){
        val onlySureDialog = DialogUtil.getOnlySureDialog(this, "即将开始行程,\n行程中平台自动开启录音") {}
        val view = DialogUtil.getView(onlySureDialog)
        view.tv_view_two_base.gravity = Gravity.CENTER
        view.view_hint_close_base.visibility = View.INVISIBLE
        view.tv_count_timer.visible()
        val timer = object: CountDownTimer(3000, 1000){
            override fun onTick(millisUntilFinished: Long) {
                view.tv_count_timer.text = "${(millisUntilFinished/1000)+1}S"
            }
            override fun onFinish() {
                view.tv_sure_base.callOnClick()
            }
        }.start()
        onlySureDialog.setOnDismissListener {
            timer.cancel()
        }
        EventBus.getDefault().post(BaseEvent(BaseEvent.START_RECORD))
    }
    private fun getAllByOrder(): String? {
@@ -734,6 +763,8 @@
                changeCarFive(true)
                setTitleText("服务中")
                slide_btn.changeButtonText("送达乘客$orderPosition")
                if (!MyApplication.isRecording)
                    EventBus.getDefault().post(BaseEvent(BaseEvent.START_RECORD))
            }
        }
    }
app/src/main/java/com/future/driver/utils/AudioRecordUtils.java
File was renamed from app/src/main/java/com/future/driver/utils/AudioRecoderUtils.java
@@ -13,7 +13,7 @@
import cn.sinata.xldutils.utils.TimeUtils;
public class AudioRecoderUtils {
public class AudioRecordUtils {
    //文件路径
    private String filePath;
@@ -22,7 +22,7 @@
    private MediaRecorder mMediaRecorder;
    private final String TAG = "fan";
    public static final int MAX_LENGTH = 1000 * 60;// 最大录音时长1000*60*10;
    public static final int MAX_LENGTH = 1000 * 600;// 最大录音时长十分钟,实际行程设置为5分钟上传一次
    private OnAudioStatusUpdateListener audioStatusUpdateListener;
    private MediaPlayer mMediaPlayer;
@@ -30,12 +30,12 @@
    /**
     * 文件存储默认sdcard/record
     */
    public AudioRecoderUtils() {
    public AudioRecordUtils() {
        //默认保存路径为/sdcard/record/下
        this(Environment.getExternalStorageDirectory() + "/record/");
    }
    public AudioRecoderUtils(String filePath) {
    public AudioRecordUtils(String filePath) {
        File path = new File(filePath);
        if (!path.exists())
@@ -105,7 +105,7 @@
            mMediaRecorder = null;
            audioStatusUpdateListener.onStop(filePath);
            filePath = "";
//            filePath = ""; //这行代码会引起连续录音文件为空的bug
        } catch (RuntimeException e) {
            if (mMediaRecorder != null) {
app/src/main/java/com/future/driver/utils/OSSUtil.java
@@ -15,6 +15,7 @@
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.future.driver.base.MyApplication;
import java.io.File;
import java.util.ArrayList;
@@ -122,6 +123,56 @@
        mTasks.add(task);
    }
    private void uploadVoice(final String url, final OSSUploadCallBack callBack) {
        String recordOrderId = MyApplication.Companion.getRecordOrderId();
        String recordOrderType = MyApplication.Companion.getRecordOrderType();
        final String objectKey = "driver/record/" +recordOrderType+"_"+recordOrderId+"_"+url.substring(url.lastIndexOf("/")+1);
        PutObjectRequest put = new PutObjectRequest(bucketName, objectKey, url);
        put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            long temp = 0;
            @Override
            public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                CURRENT_SIZE += currentSize - temp;
                temp = currentSize;
                callBack.onSizeProgress(CURRENT_SIZE, TOTAL_SIZE);
            }
        });
        OSSAsyncTask<PutObjectResult> task = mOss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                mActivity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        URLs.add(mOss.presignPublicObjectURL(bucketName, objectKey));
                        callBack.onFinishWithSize(URLs.get(0),CURRENT_SIZE);
                        mTasks.clear();
                    }
                });
            }
            @Override
            public void onFailure(PutObjectRequest request, ClientException
                    clientException, ServiceException serviceException) {
                // 请求异常
                if (clientException != null) {
                    clientException.printStackTrace();
                    // 本地异常如网络异常等
                    callBack.onFial("网络异常");
                }
                if (serviceException != null) {
                    serviceException.printStackTrace();
                    // 服务异常
                    callBack.onFial("服务器异常");
                }
            }
        });
        mTasks.add(task);
    }
    /**
     * 单文件上传
@@ -137,6 +188,17 @@
        }
        TOTAL_COUNT = single.size();
        upload(single, true, callBack);
    }
    /**
     * 单文件上传
     *
     * @param url      the url
     * @param callBack the call back
     */
    public void uploadSingleWithSize(String url, OSSUploadCallBack callBack) {
        uploadVoice(url,  callBack);
    }
    /**
@@ -158,6 +220,10 @@
        public void onFinish(String url) {
        }
        //单张上传成功
        public void onFinishWithSize(String url,Long size) {
        }
        //批量上传成功
        public void onFinish(ArrayList<String> urls) {