Browse Source

迈冲rk3288串口地址、音量、亮度适配

ccc 1 month ago
parent
commit
b0ff8eb2ea

+ 12 - 1
app/src/main/java/com/sunzee/app/AppApplication.kt

@@ -14,11 +14,13 @@ import com.hjq.http.EasyConfig
 import com.hjq.http.config.IRequestHandler
 import com.hjq.http.request.HttpRequest
 import com.hjq.toast.Toaster
+import com.quyunshuo.module.home.service.ForceBackToAppService
 import com.quyunshuo.sbm10.base.BaseApplication
 import com.quyunshuo.sbm10.common.constant.Heartbeat
 import com.quyunshuo.sbm10.common.util.XLogUtil
 import com.quyunshuo.module.home.service.GlobalService
 import com.quyunshuo.module.home.service.MqService
+import com.quyunshuo.sbm10.common.constant.MMKVName
 import dagger.hilt.android.HiltAndroidApp
 import okhttp3.OkHttpClient
 import okhttp3.Response
@@ -62,6 +64,14 @@ class AppApplication : BaseApplication() {
             } else {
                 startService(intent)
             }
+            val forceBackToAppIntent = Intent(this, ForceBackToAppService::class.java)
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                Log.d(TAG, "onCreate: forceBackToAppIntent1")
+                startForegroundService(forceBackToAppIntent)
+            } else {
+                Log.d(TAG, "onCreate: forceBackToAppIntent2")
+                startService(forceBackToAppIntent)
+            }
             //开启MQ
             startService(Intent(this, MqService::class.java))
         }
@@ -105,7 +115,8 @@ class AppApplication : BaseApplication() {
 //        Log.d(TAG, "connectDevice 串口打开成功: ")
 
         //对单片机进行连接
-        val device: VboxSerialPortDevice = VboxSerialPortDevice("dev/ttyS7", "115200")
+        val device = VboxSerialPortDevice("dev/"+MMKVName.PLC_PATH, "115200")
+        Log.d(TAG, "connectDevice: "+Build.MODEL)
         try {
             VboxSerialPortManager.getInstance().open(device)
         } catch (e: Exception) {

+ 2 - 2
buildSrc/src/main/kotlin/com/quyunshuo/sbm10/buildsrc/ProjectBuildConfig.kt

@@ -11,8 +11,8 @@ object ProjectBuildConfig {
     const val applicationId = "com.quyunshuo.sbm10"
     const val minSdkVersion = 21
     const val targetSdkVersion = 29
-    const val versionCode = 10
-    const val versionName = "1.0.10"
+    const val versionCode = 11
+    const val versionName = "1.0.11"
     const val isAppMode = false
     /**
      * 项目当前的版本状态

+ 16 - 1
lib_base/src/main/AndroidManifest.xml

@@ -1 +1,16 @@
-<manifest />
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+    <!-- android:theme="@style/SplashTeme"-->
+    <application>
+        <provider
+            android:name="androidx.core.content.FileProvider"
+            android:authorities="${applicationId}.fileprovider"
+            android:exported="false"
+            android:grantUriPermissions="true">
+            <meta-data
+                android:name="android.support.FILE_PROVIDER_PATHS"
+                android:resource="@xml/file_paths" />
+        </provider>
+    </application>
+</manifest>

+ 4 - 0
lib_base/src/main/res/xml/file_paths.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<paths>
+    <external-path name="external_files" path="." />  <!-- 可以根据需要修改路径 -->
+</paths>

+ 28 - 0
lib_common/src/main/java/com/quyunshuo/sbm10/common/constant/MMKVName.kt

@@ -1,7 +1,9 @@
 package com.quyunshuo.sbm10.common.constant
 
 import android.graphics.Typeface
+import android.os.Build
 import com.quyunshuo.sbm10.base.BaseApplication
+import com.quyunshuo.sbm10.base.utils.SpUtils
 
 abstract class MMKVName {
 
@@ -185,6 +187,32 @@ abstract class MMKVName {
         val IS_SHOW_CHANGLOGE: String
             //是否展示修改logo
             get() = "IS_SHOW_CHANGLOGE"
+
+        val PLC_PATH:String
+            get() {
+                val path: String
+                if (Build.MODEL.equals("rk3566_r")){
+                    path="ttyS7"
+                }else if (Build.MODEL.equals("rk3288")){
+                    path= "ttyS1"
+                }else{
+                    path="ttyS1"
+                }
+                return  path
+            }
+        val MDB_PATH:String
+            get() {
+                val path: String
+                if (Build.MODEL.equals("rk3566_r")){
+                    path="ttyS5"
+                }else if (Build.MODEL.equals("rk3288")){
+                    path= "ttyS2"
+                }else{
+                    path="ttyS2"
+                }
+                return  path
+            }
+
     }
     // 这里可以继续添加其他常量
 

+ 99 - 0
lib_common/src/main/java/com/quyunshuo/sbm10/common/util/AppManager.java

@@ -0,0 +1,99 @@
+package com.quyunshuo.sbm10.common.util;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.Context;
+
+import java.util.Stack;
+
+public class AppManager {
+    private static Stack<Activity> activityStack;
+    private static AppManager instance;
+
+    /**
+     * 单例模式实例
+     */
+    public static AppManager getAppManager() {
+        if (instance == null) {
+            instance = new AppManager();
+        }
+        return instance;
+    }
+
+    /**
+     * 添加Activity到堆栈
+     */
+    public void addActivity(Activity activity) {
+        if (activityStack == null) {
+            activityStack = new Stack<Activity>();
+        }
+        activityStack.add(activity);
+    }
+
+    /**
+     * 获取当前Activity(堆栈中最后一个压入的)
+     */
+    public Activity currentActivity() {
+        Activity activity = activityStack.lastElement();
+        return activity;
+    }
+
+    /**
+     * 结束当前Activity(堆栈中最后一个压入的)
+     */
+    public void finishActivity() {
+        Activity activity = activityStack.lastElement();
+        if (activity != null) {
+            activity.finish();
+            activity = null;
+        }
+    }
+
+    /**
+     * 结束指定的Activity
+     */
+    public void finishActivity(Activity activity) {
+        if (activity != null) {
+            activityStack.remove(activity);
+            activity.finish();
+            activity = null;
+        }
+    }
+
+    /**
+     * 结束指定类名的Activity
+     */
+    public void finishActivity(Class<?> cls) {
+        for (Activity activity : activityStack) {
+            if (activity.getClass().equals(cls)) {
+                finishActivity(activity);
+            }
+        }
+    }
+
+    /**
+     * 结束所有Activity
+     */
+    public void finishAllActivity() {
+        for (int i = 0, size = activityStack.size(); i < size; i++) {
+            if (null != activityStack.get(i)) {
+                activityStack.get(i).finish();
+            }
+        }
+        activityStack.clear();
+    }
+
+    /**
+     * 退出应用程序
+     */
+    public void AppExit(Context context) {
+        try {
+            finishAllActivity();
+            ActivityManager activityMgr = (ActivityManager) context
+                    .getSystemService(Context.ACTIVITY_SERVICE);
+            activityMgr.restartPackage(context.getPackageName());
+            System.exit(0);
+        } catch (Exception e) {
+        }
+    }
+}

+ 2 - 1
module_backstage/src/main/AndroidManifest.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
     <!-- android:theme="@style/SplashTeme"-->
     <application>
         <activity

+ 26 - 16
module_backstage/src/main/java/com/module/backstage/activity/setting/SettingActivity.kt

@@ -3,6 +3,7 @@ package com.module.backstage.activity.setting
 import android.annotation.SuppressLint
 import android.app.XzjhSystemManager
 import android.content.Context
+import android.content.Intent
 import android.content.res.Resources
 import android.graphics.Color
 import android.os.Build
@@ -23,10 +24,10 @@ import android.widget.Toast
 import androidx.activity.viewModels
 import androidx.annotation.RequiresApi
 import androidx.core.content.ContextCompat
+import androidx.core.content.FileProvider
 import androidx.core.view.get
 import androidx.lifecycle.LifecycleObserver
 import androidx.navigation.findNavController
-import androidx.navigation.fragment.findNavController
 import com.alibaba.android.arouter.facade.annotation.Route
 import com.alibaba.android.arouter.launcher.ARouter
 import com.google.gson.Gson
@@ -45,6 +46,7 @@ import com.module.backstage.dialog.DevOnOffDialog
 import com.module.backstage.dialog.UpdateAppDialog
 import com.module.backstage.model.ApkInfoBean
 import com.quyunshuo.sbm10.base.ktx.observeLiveData
+import com.quyunshuo.sbm10.base.utils.LanguageUtil
 import com.quyunshuo.sbm10.base.utils.RegisterEventBus
 import com.quyunshuo.sbm10.base.utils.SpUtils
 import com.quyunshuo.sbm10.common.bean.SettingTypeBean
@@ -56,8 +58,6 @@ import com.quyunshuo.sbm10.common.constant.RouteUrl.Main.MainActivity
 import com.quyunshuo.sbm10.common.constant.event.ApiMessageEvent
 import com.quyunshuo.sbm10.common.enums.ConnectStateEnum
 import com.quyunshuo.sbm10.common.ui.BaseActivity
-import com.quyunshuo.sbm10.base.utils.LanguageUtil
-import com.quyunshuo.sbm10.common.constant.PayName
 import com.quyunshuo.sbm10.common.util.LongClickUtils
 import com.quyunshuo.sbm10.common.util.ToastUtil
 import com.quyunshuo.sbm10.common.util.UiUtil
@@ -498,20 +498,30 @@ class SettingActivity : BaseActivity<BackstageActivitySettingBinding, SettingVie
 
                 override fun onDownloadSuccess(file: File) {
                     Log.d(TAG, "onDownloadEnd: 下载成功")
+                    if (Build.MODEL.equals("rk3566_r")){
+                        val mManager: XzjhSystemManager =
+                            getSystemService("xzjh_server") as XzjhSystemManager
+                        mManager.xzjhSilentInstallApkV2(
+                            Environment.getExternalStorageDirectory().path + "/apk/" + "mht.apk",
+                            true
+                        )
+                        Log.d(TAG, "onDownloadStart 安装查找目录: "+Environment.getExternalStorageDirectory().path)
+                    }else if (Build.MODEL.equals("rk3288")){
+                        val file = File("/storage/emulated/0/apk/mht.apk") // 替换为您的文件路径
+                        val uri = FileProvider.getUriForFile(
+                            baseContext,
+                            baseContext.getPackageName() + ".fileprovider",
+                            file
+                        )
+                        val intent = Intent(Intent.ACTION_VIEW)
+                        intent.setDataAndType(
+                            uri,
+                            "application/vnd.android.package-archive"
+                        ) // 设置 MIME 类型
+                        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 授予临时权限
+                        startActivity(intent)
+                    }
                     //下载成功安装
-//                    val intent = Intent(Intent.ACTION_VIEW)
-//                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-//                    intent.setDataAndType(
-//                        Uri.fromFile(file), "application/vnd.android.package-archive"
-//                    )
-//                    startActivity(intent)
-                    val mManager: XzjhSystemManager =
-                        getSystemService("xzjh_server") as XzjhSystemManager
-                    mManager.xzjhSilentInstallApkV2(
-                        Environment.getExternalStorageDirectory().path + "/apk/" + "mht.apk",
-                        true
-                    )
-                    Log.d(TAG, "onDownloadStart 安装查找目录: "+Environment.getExternalStorageDirectory().path)
                     updateAppDialog?.dismiss()
                 }
 

+ 12 - 18
module_backstage/src/main/java/com/module/backstage/adapter/TestAdapter.kt

@@ -6,6 +6,7 @@ import android.app.XzjhSystemManager
 import android.content.Context
 import android.content.Intent
 import android.media.AudioManager
+import android.os.Build
 import android.provider.Settings
 import android.util.Log
 import android.view.LayoutInflater
@@ -16,7 +17,6 @@ import android.widget.AdapterView
 import android.widget.AdapterView.OnItemSelectedListener
 import android.widget.ArrayAdapter
 import android.widget.SeekBar
-import androidx.core.content.ContextCompat.getSystemService
 import androidx.core.content.ContextCompat.startActivity
 import androidx.recyclerview.widget.RecyclerView
 import com.chad.library.adapter4.BaseMultiItemAdapter
@@ -258,12 +258,9 @@ class TestAdapter(var productList: MutableList<OtherEnum>) :
                 }
 
                 override fun onBind(holder: SliderVH, position: Int, item: OtherEnum?) {
-                    // 绑定 item 数据
-                    if (context.getSystemService("xzjh_server") != null) {
-                        val mManager = context.getSystemService("xzjh_server") as XzjhSystemManager
+                        // 绑定 item 数据
                         val audioManager =
                             context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
-
                         itemListener?.onClickListener(holder.itemView, position, null)
                         holder.viewBinding.run {
                             tvName.text = UiUtil.getStringRes(item!!.nameId)
@@ -279,15 +276,20 @@ class TestAdapter(var productList: MutableList<OtherEnum>) :
                                     sbLight.progress =
                                         audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
                                 }
-
                                 MMKVName.LUMINANCE -> {
-                                    XLogUtil.d("亮度:" + ZtlManager.GetInstance().systemMaxBrightness + ":" + mManager.xzjhGetBacklight())
                                     sbLight.max =
                                         ZtlManager.GetInstance().systemMaxBrightness //maxBrightness 为 Android 系统最大亮度
-                                    sbLight.progress = mManager.xzjhGetBacklight()
+//                                    if (Build.MODEL.equals("rk3566_r")) {
+//                                        val mManager =
+//                                            context.getSystemService("xzjh_server") as XzjhSystemManager
+//                                        sbLight.progress = mManager.xzjhGetBacklight()
+//                                    }else{
+                                        sbLight.progress =
+                                            Settings.System.getInt(context.contentResolver, Settings.System.SCREEN_BRIGHTNESS)
+//                                    }
+                                    XLogUtil.d("亮度:" + ZtlManager.GetInstance().systemMaxBrightness + ":" + sbLight.progress)
                                 }
                             }
-
                             sbLight.setOnSeekBarChangeListener(object :
                                 SeekBar.OnSeekBarChangeListener {
                                 override fun onProgressChanged(
@@ -298,7 +300,6 @@ class TestAdapter(var productList: MutableList<OtherEnum>) :
                                     //设置进度
                                     setPro(seekBar, progress);
                                 }
-
                                 private fun setPro(seekBar: SeekBar?, progress: Int) {
                                     when (item.mmkvName) {
                                         MMKVName.VOLUME -> {
@@ -309,27 +310,20 @@ class TestAdapter(var productList: MutableList<OtherEnum>) :
                                                 AudioManager.FLAG_SHOW_UI
                                             )
                                         }
-
                                         MMKVName.LUMINANCE -> {
                                             //设置 Android 系统亮度为 200
-                                            mManager.xzjhSetBacklight(progress);
+                                                Settings.System.putInt(context.contentResolver, Settings.System.SCREEN_BRIGHTNESS, progress);
                                         }
                                     }
                                 }
-
                                 override fun onStartTrackingTouch(seekBar: SeekBar?) {
-
                                 }
-
                                 override fun onStopTrackingTouch(seekBar: SeekBar?) {
                                 }
-
                             });
                         }
-                    }
                 }
 
-
                 override fun isFullSpanItem(itemType: Int): Boolean {
                     // 使用GridLayoutManager时,此类型的 item 是否是满跨度
                     return true;

+ 1 - 0
module_home/build.gradle

@@ -29,5 +29,6 @@ dependencies {
     implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.4'
     implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
     api project(path: ':lib_base')
+    implementation 'com.github.a-voyager:AutoInstaller:v1.0'
 
 }

+ 12 - 1
module_home/src/main/AndroidManifest.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <!-- .接收启动完成的广播权限 -->
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@@ -8,6 +9,7 @@
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
     <application>
         <!--  Main 首页  -->
         <activity
@@ -95,6 +97,15 @@
                 <action android:name="android.intent.action.Timed_Cleaning_Task" />
             </intent-filter>
         </receiver>
+<!--        <provider-->
+<!--            android:name="androidx.core.content.FileProvider"-->
+<!--            android:authorities="${applicationId}.home.fileprovider"-->
+<!--            android:exported="false"-->
+<!--            android:grantUriPermissions="true">-->
+<!--        <meta-data-->
+<!--            android:name="android.support.FILE_PROVIDER_PATHS"-->
+<!--            android:resource="@xml/home_file_paths" />  &lt;!&ndash; 不同的路径配置 &ndash;&gt;-->
+<!--        </provider>-->
     </application>
 
 </manifest>

+ 2 - 1
module_home/src/main/java/com/quyunshuo/module/home/service/ForceBackToAppService.kt

@@ -108,11 +108,12 @@ class ForceBackToAppService : LifecycleService() {
                         BaseApplication.context,
                         "com.quyunshuo.sbm10"
                     )
-                    XLogUtil.d("MyTestService,Build.MODEL onReceive:程序未开启============$isRunning")
+                    Log.d(TAG, "forceBackToApp: 1")
                     //运行中,跳过他。
                     if (isRunning) {
                         continue
                     }
+                    Log.d(TAG, "forceBackToApp: 2")
                     val intent: Intent = Intent(
                         BaseApplication.context,
                         MainActivity::class.java

+ 4 - 0
module_home/src/main/java/com/quyunshuo/module/home/service/GlobalService.kt

@@ -1,9 +1,12 @@
 package com.quyunshuo.module.home.service
 
 import android.annotation.SuppressLint
+import android.app.AlarmManager
 import android.app.Notification
 import android.app.NotificationChannel
 import android.app.NotificationManager
+import android.app.PendingIntent
+import android.content.Context
 import android.content.Intent
 import android.os.Build
 import android.os.IBinder
@@ -95,6 +98,7 @@ class GlobalService : LifecycleService() {
         observeLiveData(globalServiceViewModel.initIsSuccess, ::initIsSuccess)
         observeLiveData(globalServiceViewModel.alarmType, ::getAlarmType)
 
+        globalServiceViewModel.forceBackToApp()
     }
 
     private fun initIsSuccess(initIsSuccess: Boolean) {

+ 93 - 6
module_home/src/main/java/com/quyunshuo/module/home/service/GlobalServiceViewModel.kt

@@ -1,6 +1,13 @@
 package com.quyunshuo.module.home.service
 
+import android.annotation.SuppressLint
+import android.app.ActivityManager
+import android.app.AlarmManager
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
 import android.os.Environment
+import android.os.Process
 import android.util.Log
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleOwner
@@ -13,12 +20,13 @@ import com.hboxs.serialport.plc.util.HexUtils
 import com.hboxs.serialport.plc.util.HexadecimalUtil
 import com.hboxs.serialport.sbc.SBCHeartbeat
 import com.hboxs.serialport.sbc.VBoxMessage
-import com.hboxs.serialport.sbc.frame.VboxCommand
 import com.hboxs.serialport.sbc.thread.ThreadGlobalParam
 import com.hjq.http.EasyHttp
 import com.hjq.http.listener.OnDownloadListener
 import com.hjq.http.model.HttpMethod
+import com.quyunshuo.module.home.activity.main.MainActivity
 import com.quyunshuo.sbm10.base.BaseApplication
+import com.quyunshuo.sbm10.base.BaseApplication.Companion.context
 import com.quyunshuo.sbm10.base.utils.SpUtils
 import com.quyunshuo.sbm10.common.bean.DataItem
 import com.quyunshuo.sbm10.common.bean.LocalAlarmClockBean
@@ -26,15 +34,14 @@ import com.quyunshuo.sbm10.common.bean.VideoInfoBean
 import com.quyunshuo.sbm10.common.constant.Heartbeat
 import com.quyunshuo.sbm10.common.constant.MMKVName
 import com.quyunshuo.sbm10.common.enums.AlarmClockEnum
-import com.quyunshuo.sbm10.common.util.AlarmManagerUtil
 import com.quyunshuo.sbm10.common.util.AlarmSettingUtil
-import com.quyunshuo.sbm10.common.util.ByteUtils
 import com.quyunshuo.sbm10.common.util.FileUtil
 import com.quyunshuo.sbm10.common.util.LogUtil
-import com.quyunshuo.sbm10.common.util.LogUtil.d
 import com.quyunshuo.sbm10.common.util.XLogUtil
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.catch
 import kotlinx.coroutines.launch
 import java.io.File
@@ -61,8 +68,8 @@ class GlobalServiceViewModel @Inject constructor(
     // 报警类型。
     private val _alarmType = MutableLiveData<String>()
     val alarmType: LiveData<String> get() = _alarmType
-
-
+    //强制返回App的携程
+    var forceBackToAppJob: Job? = null
     fun getVideoRule() {
         if (Heartbeat.managerId == "") {
             //没有连接服务器,那么就不没有必要执行。
@@ -530,7 +537,12 @@ class GlobalServiceViewModel @Inject constructor(
             _initIsSuccess.value = false
             SBCHeartbeat.initIsSuccess = false
         }
+        if (!agin){
+            agin=true
+            aginInit()
+        }
     }
+    private var agin: Boolean = false
 
     /**
      * 处理 单片机 后台数据
@@ -576,4 +588,79 @@ class GlobalServiceViewModel @Inject constructor(
 //            nextRunTime - currentTime
 //        }
 //    }
+    /**
+     * 强制跳回App
+     */
+    fun forceBackToApp() {
+        if (forceBackToAppJob == null) {
+            forceBackToAppJob = CoroutineScope(Dispatchers.IO).launch {
+                while (true) {
+                    delay(4000)
+                    //判断程序是否在运行
+                    val isRunning: Boolean = isServiceStarted(
+                        BaseApplication.context,
+                        "com.quyunshuo.sbm10"
+                    )
+                    Log.d(TAG, "forceBackToApp: 1")
+                    //运行中,跳过他。
+                    if (isRunning) {
+                        continue
+                    }
+                    Log.d(TAG, "forceBackToApp: 2")
+                    val intent: Intent = Intent(
+                        BaseApplication.context,
+                        MainActivity::class.java
+                    ) //此处我是根据需要重新启动时先进入欢迎页
+                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) //关掉所要到的界面中间的activity
+
+                    @SuppressLint("WrongConstant") val restartIntent = PendingIntent.getActivity(
+                        BaseApplication.context, 0, intent,
+                        Intent.FLAG_ACTIVITY_NEW_TASK or PendingIntent.FLAG_IMMUTABLE
+                    )
+
+                    //退出程序
+                    val mgr =
+                        BaseApplication.context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
+                    mgr[AlarmManager.RTC, System.currentTimeMillis() + 1000] =
+                        restartIntent // 1秒钟后重启应用,这个可以根据需要自己定义
+
+                    //干掉当前的程序
+                    LogUtil.d("MyTestService", "uncaughtException2: ")
+                    Process.killProcess(Process.myPid())
+                    System.exit(0)
+                }
+            }
+        }
+    }
+    /**
+     * 检测一个android程序是否在运行
+     *
+     * @param context
+     * @param PackageName
+     * @return
+     */
+    fun isServiceStarted(context: Context, packageName: String): Boolean {
+        val am = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
+        val runningProcesses = am.runningAppProcesses
+        for (processInfo in runningProcesses) {
+            if (processInfo.processName == packageName) {
+                return true
+            }
+        }
+        return false
+    }
+
+    fun aginInit() {
+        val intent = context.packageManager.getLaunchIntentForPackage(context.packageName)?.apply {
+            addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
+        }
+        context.startActivity(intent)
+        (context.getSystemService(Context.ALARM_SERVICE) as AlarmManager).apply {
+            set(
+                AlarmManager.RTC, System.currentTimeMillis() + 500,
+                PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
+            )
+        }
+        Process.killProcess(Process.myPid())
+    }
 }

+ 58 - 31
module_home/src/main/java/com/quyunshuo/module/home/utils/RemotePushUtil.kt

@@ -2,8 +2,10 @@ package com.quyunshuo.module.home.utils
 
 import android.app.XzjhSystemManager
 import android.content.Context
+import android.content.Intent
 import android.media.AudioManager
 import android.media.MediaScannerConnection
+import android.os.Build
 import android.os.Environment
 import android.util.Log
 import com.google.gson.Gson
@@ -13,9 +15,15 @@ import com.qiniu.android.http.ResponseInfo
 import com.qiniu.android.storage.UpCompletionHandler
 import com.qiniu.android.storage.UploadManager
 import com.qiniu.android.storage.UploadOptions
+import com.quyunshuo.module.home.R
+import com.quyunshuo.module.home.bean.AlarmClockBean
+import com.quyunshuo.module.home.bean.PaySuccessBean
+import com.quyunshuo.module.home.getui.BaseBean
+import com.quyunshuo.module.home.getui.MqttBaseBean
 import com.quyunshuo.sbm10.base.BaseApplication
 import com.quyunshuo.sbm10.base.BaseApplication.Companion.context
 import com.quyunshuo.sbm10.base.addressenum.PlcSettingAddressEnum
+import com.quyunshuo.sbm10.base.utils.JsonUtils
 import com.quyunshuo.sbm10.base.utils.SpUtils
 import com.quyunshuo.sbm10.common.bean.PaySucessBean
 import com.quyunshuo.sbm10.common.constant.Heartbeat
@@ -27,16 +35,11 @@ import com.quyunshuo.sbm10.common.enums.ConnectStateEnum
 import com.quyunshuo.sbm10.common.util.AlarmManagerUtil
 import com.quyunshuo.sbm10.common.util.ToastUtil
 import com.quyunshuo.sbm10.common.util.UiUtil
-import com.quyunshuo.module.home.R
-import com.quyunshuo.module.home.bean.AlarmClockBean
-import com.quyunshuo.module.home.bean.PaySuccessBean
-import com.quyunshuo.module.home.getui.BaseBean
-import com.quyunshuo.module.home.getui.MqttBaseBean
-import com.quyunshuo.sbm10.base.utils.JsonUtils
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 import okhttp3.Call
 import okhttp3.Callback
 import okhttp3.OkHttpClient
@@ -46,6 +49,7 @@ import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
 import org.json.JSONObject
+import top.wuhaojie.installerlibrary.AutoInstaller
 import java.io.ByteArrayOutputStream
 import java.io.DataInputStream
 import java.io.File
@@ -63,8 +67,10 @@ import javax.inject.Inject
 
 class RemotePushUtil @Inject constructor() {
     private val TAG = "RemotePushUtil"
+
     @Inject
     lateinit var threadSettingParam: ThreadSettingParam
+
     init {
         registerToEventBus()
     }
@@ -87,6 +93,7 @@ class RemotePushUtil @Inject constructor() {
             Message.Type.ack -> {
                 ack(messageEvent)
             }
+
             Message.Type.response -> {}
             Message.Type.connected -> {}
             Message.Type.disconnected -> {}
@@ -106,6 +113,7 @@ class RemotePushUtil @Inject constructor() {
                     threadSettingParam.startRstM3()
                 }
             }
+
             PlcSettingAddressEnum.RM3.address -> {
                 threadSettingParam.stopRstM3()
             }
@@ -184,13 +192,16 @@ class RemotePushUtil @Inject constructor() {
                 //远程上传日志文件
                 uploadLogApi(baseBean.kind_data)
             }
+
             MqName.updateApk -> {
                 //远程推送apk或图片
                 upDateApk(baseBean.kind_data)
             }
+
             else -> {}
         }
     }
+
     fun getMqttMessage(msg: String) {
         Log.d(TAG, "MqttMessage:" + msg)
         var kindStr = JsonUtils.getValue(msg, "dataContent", String::class.java)
@@ -204,31 +215,32 @@ class RemotePushUtil @Inject constructor() {
             }
         }
     }
+
     fun uploadLog(mqtt: MqttBaseBean) {
         try {
             var filePath = "/storage/emulated/0/logdata/${mqtt.kind_data}.txt"
             val uploadManager = UploadManager()
             val uploadFile: File = File(filePath)
-            val uploadFileKey: String =  mqtt.key
+            val uploadFileKey: String = mqtt.key
                 .trim()
-            Log.d(TAG, "uploadLog: "+filePath)
+            Log.d(TAG, "uploadLog: " + filePath)
             val options = UploadOptions(null, null, false,
                 { key, percent ->
                 }, { // 当需要取消时,此处返回 true,SDK 内部会多次检查返回值,当返回值为 true 时会取消上传操作
                     false
                 })
-            uploadManager.put(uploadFile,uploadFileKey,mqtt.token,object : UpCompletionHandler {
+            uploadManager.put(uploadFile, uploadFileKey, mqtt.token, object : UpCompletionHandler {
                 override fun complete(key: String?, info: ResponseInfo?, response: JSONObject?) {
-                    Log.d(TAG, "complete:" +  JsonUtils.getJSONString(info))
+                    Log.d(TAG, "complete:" + JsonUtils.getJSONString(info))
                     if (info != null && info.isOK()) {
                         // 上传成功
                     } else {
-                        Log.d(TAG, "失败:" +  JsonUtils.getJSONString(info))
+                        Log.d(TAG, "失败:" + JsonUtils.getJSONString(info))
                         // 上传失败
                     }
                 }
 
-            },options)
+            }, options)
         } catch (e: IOException) {
             Log.e("QiniuLab", e.message!!)
         }
@@ -243,16 +255,16 @@ class RemotePushUtil @Inject constructor() {
         var str1 = ""
         val targetString = ".com.cn/"
         var startIndex: Int = kindData.indexOf(targetString)
-        var result =""
+        var result = ""
         if (startIndex != -1) {
             startIndex += targetString.length
             result = kindData.substring(startIndex)
-            Log.d(TAG, "upDateApk: "+result)
+            Log.d(TAG, "upDateApk: " + result)
             str1 = if (result.endsWith(".apk")) {
                 "apk"
             } else if (result.endsWith(".png")) {
                 "png"
-            }  else if (result.endsWith(".jpg")) {
+            } else if (result.endsWith(".jpg")) {
                 "jpg"
             } else {
                 "mp4"
@@ -266,7 +278,7 @@ class RemotePushUtil @Inject constructor() {
 
         client.newCall(request).enqueue(object : Callback {
             override fun onFailure(call: Call, e: IOException) {
-                Log.d(TAG, "newCall onFailure: "+e.message)
+                Log.d(TAG, "newCall onFailure: " + e.message)
                 e.printStackTrace()
             }
 
@@ -276,34 +288,49 @@ class RemotePushUtil @Inject constructor() {
                     // 下载成功
                     val inputStream: InputStream? = response.body?.byteStream()
                     var pathName = ""
-                    if (str1.equals("apk")){
-                        pathName="/apk/" + "mht.apk"
-                    }else if (str1=="jpg"||str1=="png"){
-                        pathName="/pic/"+result
+                    if (str1.equals("apk")) {
+                        pathName = "/apk/" + "mht.apk"
+                    } else if (str1 == "jpg" || str1 == "png") {
+                        pathName = "/pic/" + result
                     }
-                    Log.d(TAG, "upDateApk:2  "+pathName+"  :"+str1)
+                    Log.d(TAG, "upDateApk:2  " + pathName + "  :" + str1)
                     // 获取目标目录
                     var file = File(pathName)
                     if (!file.exists()) {
                         file.mkdirs()
                     }
 
-                    file= File(Environment.getExternalStorageDirectory().path + pathName)
+                    file = File(Environment.getExternalStorageDirectory().path + pathName)
                     val outputStream = FileOutputStream(file)
                     inputStream?.use { input ->
                         outputStream.use { output ->
                             input.copyTo(output)
                         }
                     }
-                    if (str1!="apk"){
-                        MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, null)
-                    }else{
-                        val mManager: XzjhSystemManager =
-                            context.getSystemService("xzjh_server") as XzjhSystemManager
-                        mManager.xzjhSilentInstallApkV2(
-                            Environment.getExternalStorageDirectory().path + "/apk/" + "mht.apk",
-                            true
+                    if (str1 != "apk") {
+                        MediaScannerConnection.scanFile(
+                            context,
+                            arrayOf(file.absolutePath),
+                            null,
+                            null
                         )
+                    } else {
+                        if (Build.MODEL.equals("rk3566_r")) {
+                            val mManager: XzjhSystemManager =
+                                context.getSystemService("xzjh_server") as XzjhSystemManager
+                            mManager.xzjhSilentInstallApkV2(
+                                Environment.getExternalStorageDirectory().path + "/apk/" + "mht.apk",
+                                true
+                            )
+                        } else {
+                            Log.d(TAG, "onResponse: installerapk")
+                            CoroutineScope(Dispatchers.IO).launch {
+                                withContext(Dispatchers.Main) {
+                                    val installer: AutoInstaller = AutoInstaller.getDefault(context)
+                                    installer.install(Environment.getExternalStorageDirectory().path + "/apk/mht.apk")
+                                }
+                            }
+                        }
                     }
                 } else {
                     Log.d(TAG, "newCall failed: ")
@@ -418,7 +445,7 @@ class RemotePushUtil @Inject constructor() {
         //没有关机
         if (kind_data == "1") {
             //开机
-           threadSettingParam.startUp()
+            threadSettingParam.startUp()
         }
 
     }

+ 2 - 2
module_pay/src/main/java/com/module/pay/common/OtherEnum.kt

@@ -35,8 +35,8 @@ enum class OtherEnum(var nameId:Int,var nameS:String,var category:String,var def
     //    BILL_COUNTRY(R.string.bill_country,"国家纸币选择","串口设置",ArrayList<String>(listOf("MDB","ICT")), 3,MMKVName.BILL_COUNTRY),
     NAYAX_MODE(R.string.nayax_mode,"Nayax闲置模式","串口设置",false,1,MMKVName.NAYAX_MODE),
     TTYS_NAYAX(R.string.ttys_nayax,"Nayax 串口","串口设置","ttyS3",7,MMKVName.TTYS_NAYAX),
-    TTYS_MDB(R.string.ttys_mdb,"MDB 串口","串口设置","ttyS5",7,MMKVName.TTYS_MDB),
-    TTYS_PLC(R.string.ttys_plc,"PLC 串口","串口设置","ttyS7",7,MMKVName.TTYS_PLC),
+    TTYS_MDB(R.string.ttys_mdb,"MDB 串口","串口设置",MMKVName.MDB_PATH,7,MMKVName.TTYS_MDB),
+    TTYS_PLC(R.string.ttys_plc,"PLC 串口","串口设置",MMKVName.PLC_PATH,7,MMKVName.TTYS_PLC),
     BILL_COLLOCATION(R.string.bill_collocation,"MDB 纸币托管","通讯设置",false,1,MMKVName.BILL_COLLOCATION),
     MDB_LEVEL(R.string.mdb_level,"MDB L3级别","通讯设置",true,1,MMKVName.MDB_LEVEL),
     MDB_RATE(R.string.mdb_rate,"MDB 倍率","串口设置","100",2,MMKVName.MDB_RATE),

+ 2 - 1
module_pay/src/main/java/com/module/pay/strategy/PaySendDataICTStrategy.kt

@@ -2,6 +2,7 @@ package com.module.pay.strategy
 
 import android.util.Log
 import com.module.pay.serialport.SerialPortUtil
+import com.quyunshuo.sbm10.common.constant.MMKVName
 
 object PaySendDataICTStrategy : PaySendDataStrategy {
     private var serialPortUtil: SerialPortUtil? = null
@@ -10,7 +11,7 @@ object PaySendDataICTStrategy : PaySendDataStrategy {
         //工厂构建
         val createStrategy = SerialPortFactory().createStrategy(StrategyType.ICT)
         serialPortUtil = SerialPortUtil(createStrategy)
-        serialPortUtil?.openSerialPort("/dev/ttyS5",9600,0,1)
+        serialPortUtil?.openSerialPort("/dev/"+MMKVName.MDB_PATH,9600,0,1)
     }
 
     override fun billInit() {

+ 1 - 1
module_pay/src/main/java/com/module/pay/strategy/PaySendDataMDBStrategy.kt

@@ -19,7 +19,7 @@ object PaySendDataMDBStrategy : PaySendDataStrategy {
         //工厂构建
         val createStrategy = SerialPortFactory().createStrategy(StrategyType.MDB)
         serialPortUtil = SerialPortUtil(createStrategy)
-        serialPortUtil?.openSerialPort("/dev/ttyS5", 9600, 0, 0)
+        serialPortUtil?.openSerialPort("/dev/"+MMKVName.PLC_PATH, 9600, 0, 0)
     }
 
     override fun billInit() {

+ 2 - 0
serialport-api/src/main/java/com/hboxs/serialport/sbc/VboxSerialPortDevice.java

@@ -1,5 +1,7 @@
 package com.hboxs.serialport.sbc;
 
+import android.util.Log;
+
 /**
  * 串口设备
  */