Explorar o código

## [1.1.24] version 43 - 2020-08-10
### Changed
- 优化启动时的TCP和RTC连接逻辑
- 优化断线时的处理,每2秒重试连接,最多30次。10分钟后再次重新尝试1分钟内连接30次
### Fixed
- 首次SOS不出声的问题
- 修复若干个其它问题

allen %!s(int64=3) %!d(string=hai) anos
pai
achega
3f37f2c6e7
Modificáronse 21 ficheiros con 269 adicións e 122 borrados
  1. 15 13
      WebRTC/src/main/java/com/wdkl/core/socket/SocketManager.java
  2. 2 2
      build.gradle
  3. 9 8
      common/src/main/code/com/wdkl/ncs/android/lib/utils/ConnectionObserver.kt
  4. 4 1
      common/src/main/res/layout/custom_loading.xml
  5. 31 0
      common/src/main/res/layout/netoff_loading.xml
  6. 5 0
      home/src/main/AndroidManifest.xml
  7. 4 0
      home/src/main/code/com/wdkl/ncs/android/component/home/activity/NewEventListActivity.kt
  8. 2 1
      home/src/main/code/com/wdkl/ncs/android/component/home/activity/WatchCallRecordsActivity.kt
  9. 87 48
      home/src/main/code/com/wdkl/ncs/android/component/home/activity/WatchHome2Activity.kt
  10. 16 21
      home/src/main/code/com/wdkl/ncs/android/component/home/service/WdKeepAliveService.kt
  11. 1 1
      home/src/main/code/com/wdkl/ncs/android/component/home/util/AnrFcExceptionUtil.java
  12. 15 0
      home/src/main/code/com/wdkl/ncs/android/component/home/util/TcpCallbackImpl.java
  13. 10 10
      home/src/main/res/layout/watch_activity_call_records.xml
  14. 10 2
      home/src/main/res/layout/watch_activity_home2.xml
  15. 9 0
      home/src/main/res/layout/watch_activity_register.xml
  16. 5 1
      keepalive/src/main/java/com/wdkl/ncs/keepbackground/watch/WatchDogService.java
  17. 4 0
      keepalive/src/main/java/com/wdkl/ncs/keepbackground/work/DaemonEnv.java
  18. 5 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/ITcpCallBack.java
  19. 23 12
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/TcpClient.java
  20. 3 2
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/TcpClientHandler.java
  21. 9 0
      readme.md

+ 15 - 13
WebRTC/src/main/java/com/wdkl/core/socket/SocketManager.java

@@ -133,20 +133,20 @@ public class SocketManager implements IEvent {
 
     // ======================================================================================
     public void createRoom(String room, int roomSize) {
-        if (webSocket != null) {
+        if (webSocket != null && webSocket.isOpen()) {
             webSocket.createRoom(room, roomSize, myId);
         }
 
     }
 
     public void sendInvite(String room, List<String> users, boolean audioOnly) {
-        if (webSocket != null) {
+        if (webSocket != null && webSocket.isOpen()) {
             webSocket.sendInvite(room, myId, users, audioOnly);
         }
     }
 
     public void sendLeave(String room, String userId) {
-        if (webSocket != null) {
+        if (webSocket != null && webSocket.isOpen()) {
             webSocket.sendLeave(myId, room, userId);
         }
 
@@ -154,13 +154,13 @@ public class SocketManager implements IEvent {
     }
 
     public void sendRingBack(String targetId, String room) {
-        if (webSocket != null) {
+        if (webSocket != null && webSocket.isOpen()) {
             webSocket.sendRing(myId, targetId, room);
         }
     }
 
     public void sendRefuse(String room, String inviteId, int refuseType) {
-        if (webSocket != null) {
+        if (webSocket != null && webSocket.isOpen()) {
             webSocket.sendRefuse(room, inviteId, myId, refuseType);
         }
 
@@ -168,7 +168,7 @@ public class SocketManager implements IEvent {
     }
 
     public void sendCancel(String mRoomId, List<String> userIds) {
-        if (webSocket != null) {
+        if (webSocket != null && webSocket.isOpen()) {
             webSocket.sendCancel(mRoomId, myId, userIds);
         }
 
@@ -176,7 +176,7 @@ public class SocketManager implements IEvent {
     }
 
     public void sendJoin(String room) {
-        if (webSocket != null) {
+        if (webSocket != null && webSocket.isOpen()) {
             webSocket.sendJoin(room, myId);
         }
 
@@ -188,31 +188,31 @@ public class SocketManager implements IEvent {
     }
 
     public void sendOffer(String userId, String sdp) {
-        if (webSocket != null) {
+        if (webSocket != null && webSocket.isOpen()) {
             webSocket.sendOffer(myId, userId, sdp);
         }
     }
 
     public void sendAnswer(String userId, String sdp) {
-        if (webSocket != null) {
+        if (webSocket != null && webSocket.isOpen()) {
             webSocket.sendAnswer(myId, userId, sdp);
         }
     }
 
     public void sendIceCandidate(String userId, String id, int label, String candidate) {
-        if (webSocket != null) {
+        if (webSocket != null && webSocket.isOpen()) {
             webSocket.sendIceCandidate(myId, userId, id, label, candidate);
         }
     }
 
     public void sendTransAudio(String userId) {
-        if (webSocket != null) {
+        if (webSocket != null && webSocket.isOpen()) {
             webSocket.sendTransAudio(myId, userId);
         }
     }
 
     public void sendDisconnect(String room, String userId) {
-        if (webSocket != null) {
+        if (webSocket != null && webSocket.isOpen()) {
             webSocket.sendDisconnect(room, myId, userId);
         }
     }
@@ -367,7 +367,9 @@ public class SocketManager implements IEvent {
     @Override
     public void reConnect() {
         handler.post(() -> {
-            webSocket.reconnect();
+            if (webSocket!=null) {
+                webSocket.reconnect();
+            }
         });
     }
     //===========================================================================================

+ 2 - 2
build.gradle

@@ -47,12 +47,12 @@ buildscript {
     /**
      * APP版本码
      */
-    ext.app_version_code = 42
+    ext.app_version_code = 43
 
     /**
      * APP版本号
      */
-    ext.app_version = "1.1.23"
+    ext.app_version = "1.1.24"
 
     /**
      * 项目依赖库

+ 9 - 8
common/src/main/code/com/wdkl/ncs/android/lib/utils/ConnectionObserver.kt

@@ -119,14 +119,15 @@ abstract class BaseObserver<T>(private val context: Context) : Observer<T> {
                 this.onError(ExceptionHandle.handleException(e))
                 return
             }
-            val obj = JSONObject(errorJSon)
-            if (obj.has("code")){
-                val result = ExceptionHandle.ResponeThrowable(e,420)
-                result.customMessage = obj.getString("message")
-                this.onError(result)
-            }else{
-                this.onError(ExceptionHandle.handleException(e))
-            }
+            this.onError(ExceptionHandle.handleException(e))
+//            val obj = JSONObject(errorJSon)
+//            if (obj.has("code")){
+//                val result = ExceptionHandle.ResponeThrowable(e,420)
+//                result.customMessage = obj.getString("message")
+//                this.onError(result)
+//            }else{
+//                this.onError(ExceptionHandle.handleException(e))
+//            }
         } else {
             this.onError(ExceptionHandle.ResponeThrowable(e, 1000).then {
                 if (e.message == null) {

+ 4 - 1
common/src/main/res/layout/custom_loading.xml

@@ -1,4 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
+<layout>
 <LinearLayout android:gravity="center"
               android:orientation="vertical"
               android:id="@+id/dialog_view"
@@ -18,6 +19,7 @@
             android:src="@drawable/loading" />
 
         <TextView
+            android:id="@+id/loading_text"
             android:layout_width="150.0dip"
             android:layout_height="150.0dip"
             android:gravity="center"
@@ -25,4 +27,5 @@
             android:textColor="#ffcccccc"
             android:textSize="30.0sp" />
     </RelativeLayout>
-</LinearLayout>
+</LinearLayout>
+</layout>

+ 31 - 0
common/src/main/res/layout/netoff_loading.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+<LinearLayout android:gravity="center"
+              android:orientation="vertical"
+              android:id="@+id/dialog_view"
+              android:background="#00000000"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              xmlns:android="http://schemas.android.com/apk/res/android">
+    <RelativeLayout android:gravity="center"
+                    android:id="@+id/background"
+                    android:layout_width="fill_parent"
+                    android:layout_height="fill_parent">
+
+        <ImageView
+            android:id="@+id/netoff_loading_image"
+            android:layout_width="150.0dip"
+            android:layout_height="150.0dip"
+            android:src="@drawable/loading" />
+
+        <TextView
+            android:id="@+id/loading_text"
+            android:layout_width="150.0dip"
+            android:layout_height="150.0dip"
+            android:gravity="center"
+            android:text="重连中"
+            android:textColor="#ffcccccc"
+            android:textSize="30.0sp" />
+    </RelativeLayout>
+</LinearLayout>
+</layout>

+ 5 - 0
home/src/main/AndroidManifest.xml

@@ -42,6 +42,11 @@
 <!--                <action android:name="android.media.AUDIO.BECOMING_NOISY" />-->
 <!--            </intent-filter>-->
 <!--        </receiver>-->
+        <service android:name="com.wdkl.ncs.keepbackground.watch.WatchDogService">
+            <intent-filter>
+                <action android:name="com.wdkl.ncs.keepbackground.watch.WatchDogService"/>
+            </intent-filter>
+        </service>
 
         <provider
             android:name="android.support.v4.content.FileProvider"

+ 4 - 0
home/src/main/code/com/wdkl/ncs/android/component/home/activity/NewEventListActivity.kt

@@ -79,6 +79,10 @@ class NewEventListActivity : BaseActivity<NewEventListPresenter,ActivityEventLis
 
             } else if (tcpModel.type == TcpType.IM && tcpModel.action == TcpAction.IMAction.MSG) {
                 SpeechUtil.getInstance().newSpeech("您有新的语音留言待处理", false)
+            } else if (tcpModel.type == TcpType.SOS && tcpModel.action == TcpAction.SOSAction.CALL) {
+                SpeechUtil.getInstance().stopSpeak()
+                MediaPlayHelper.getInstance().stopMusic()
+                MediaPlayHelper.getInstance().playResMusic(R.raw.sos2, 1.0f, false)
             }
         }
 

+ 2 - 1
home/src/main/code/com/wdkl/ncs/android/component/home/activity/WatchCallRecordsActivity.kt

@@ -189,6 +189,7 @@ class WatchCallRecordsActivity : BaseActivity<WatchCallRecordsFragmentPresenter,
             EventBus.getDefault().post(MessageEvent(data, Constants.EVENT_UNTREATED_QUANTITY))
         }
 
+        tv_empty_records.visibility = View.GONE
         refresh.finishRefresh()
         if (page == 1) {
             refresh.resetNoMoreData()
@@ -198,7 +199,7 @@ class WatchCallRecordsActivity : BaseActivity<WatchCallRecordsFragmentPresenter,
                 Log.i("abc1", " " + data.size);
                 watchCallRecordsItemAdapter.notifyDataSetChanged()
             } else {
-                tv_empty_contacts.visibility = View.VISIBLE
+                tv_empty_records.visibility = View.VISIBLE
             }
             refresh.finishLoadMore()
         } else {

+ 87 - 48
home/src/main/code/com/wdkl/ncs/android/component/home/activity/WatchHome2Activity.kt

@@ -4,12 +4,9 @@ import android.Manifest
 import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
-import android.content.pm.PackageManager
 import android.graphics.Color
 import android.os.Bundle
 import android.os.CountDownTimer
-import android.support.v4.app.ActivityCompat
-import android.support.v4.content.ContextCompat
 import android.telephony.PhoneStateListener
 import android.telephony.SignalStrength
 import android.telephony.TelephonyManager
@@ -41,7 +38,6 @@ import com.wdkl.ncs.android.lib.utils.AppTool
 import com.wdkl.ncs.android.lib.utils.joinManager
 import com.wdkl.ncs.android.lib.utils.push
 import com.wdkl.ncs.android.lib.utils.showMessage
-import com.wdkl.ncs.android.middleware.api.UrlManager
 import com.wdkl.ncs.android.middleware.logic.contract.home.WatchHomeActivityContract
 import com.wdkl.ncs.android.middleware.logic.presenter.home.WatchHomeActivityPresenter
 import com.wdkl.ncs.android.middleware.model.dos.AppVersionDO
@@ -49,6 +45,7 @@ import com.wdkl.ncs.android.middleware.model.dos.PartSettingDO
 import com.wdkl.ncs.android.middleware.model.dto.TcpSeverDTO
 import com.wdkl.ncs.android.middleware.model.vo.DeviceVO
 import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
+import com.wdkl.ncs.android.middleware.tcp.ITcpCallBack
 import com.wdkl.ncs.android.middleware.tcp.TcpClient
 import com.wdkl.ncs.android.middleware.utils.MessageEvent
 import com.wdkl.ncs.keepbackground.utils.SpManager
@@ -70,10 +67,13 @@ class WatchHome2Activity : BaseActivity<WatchHomeActivityPresenter, WatchActivit
 
     lateinit var batteryBroadcastReceiver: BatteryBroadcastReceiver
     lateinit var myMediaButtonReceiver: MyMediaButtonReceiver
-    private var isRegister = true
+    private var isUnRegister = true
     lateinit var loadingDialog: LoadingDialog
+    lateinit var netOffLoadingDialog: LoadingDialog
     lateinit var countDownTimer: CountDownTimer
 
+    val iTcpCallBack:ITcpCallBack = TcpCallbackImpl()
+
     private val WRITE_EXTERNAL_STORAGE_REQUEST_CODE = 127//这个值是自定义的一个int值,在申请多个权限时要
 
     override fun onCreate(savedInstanceState: Bundle?) {
@@ -102,11 +102,10 @@ class WatchHome2Activity : BaseActivity<WatchHomeActivityPresenter, WatchActivit
         //TTS初始化
         SpeechUtil.getInstance().init(BaseApplication.appContext)
         SpeechUtil.getInstance().startSpeechThread()
-
-        //保活守护进程
-        DaemonEnv.init(this);
+        DaemonEnv.initContext(this);
 
         loadingDialog = CommonTool.createLoadingDialog(this, R.layout.custom_loading,R.id.loadding_image)
+        netOffLoadingDialog = CommonTool.createLoadingDialog(this, R.layout.netoff_loading,R.id.netoff_loading_image)
         initCountDownTimer()
 
         //网络强度监听
@@ -124,19 +123,23 @@ class WatchHome2Activity : BaseActivity<WatchHomeActivityPresenter, WatchActivit
             if (teleManager != null) {
                 teleManager.listen(object : PhoneStateListener() {
                     override fun onSignalStrengthsChanged(signalStrength: SignalStrength) {
-                        val signalinfo = signalStrength.toString()
-                        val parts = signalinfo.split(" ".toRegex()).toTypedArray()
-                        val ltedbm = parts[9].toInt()
-                        if (ltedbm>=-79){
-                            tv_signal_strength.text = "网络极好"
-                        } else if (ltedbm>=-89 && ltedbm<=-80){
-                            tv_signal_strength.text = "网络好"
-                        } else if (ltedbm>=-99 && ltedbm<=-90){
-                            tv_signal_strength.text = "网络正常"
-                        } else if (ltedbm>=-109 && ltedbm<=-100){
-                            tv_signal_strength.text = "网络较差"
-                        } else if (ltedbm>=-120 && ltedbm<=-110){
-                            tv_signal_strength.text = "网络极差"
+                        if (NetHelper.getInstance().getNetworkState(applicationContext) == NetHelper.NETWORK_NONE){
+                            tv_signal_strength.text = "网络断开"
+                        } else {
+                            val signalinfo = signalStrength.toString()
+                            val parts = signalinfo.split(" ".toRegex()).toTypedArray()
+                            val ltedbm = parts[9].toInt()
+                            if (ltedbm >= -79) {
+                                tv_signal_strength.text = "网络极好"
+                            } else if (ltedbm >= -89 && ltedbm <= -80) {
+                                tv_signal_strength.text = "网络好"
+                            } else if (ltedbm >= -99 && ltedbm <= -90) {
+                                tv_signal_strength.text = "网络正常"
+                            } else if (ltedbm >= -109 && ltedbm <= -100) {
+                                tv_signal_strength.text = "网络较差"
+                            } else if (ltedbm >= -120 && ltedbm <= -110) {
+                                tv_signal_strength.text = "网络极差"
+                            }
                         }
                         //Log.i(TAG, "网络:LTE 信号强度:$ltedbm======Detail:$signalinfo")
 
@@ -164,25 +167,18 @@ class WatchHome2Activity : BaseActivity<WatchHomeActivityPresenter, WatchActivit
                 return
             }
 
+            DaemonEnv.sendStopWorkBroadcast(this)
+            SocketManager.getInstance().unConnect()
+
             Constants.imei = Util.getIMEI(this)
             Log.i(TAG, "IMEI " + Util.getIMEI(this))
 
             Log.i(TAG, "mac " + Constants.mac)
             tv_feedback_device_info.text = Constants.imei
 
-            //获取TCP服务器IP和端口
-            Thread(Runnable {
-                while (isRegister) {
-                    Log.i(TAG, "获取TCP服务器IP和端口")
-                    runOnUiThread(Runnable {
-                        presenter.getTcpServerHost()
-                    })
-                    try {
-                        Thread.sleep(3000)
-                    } catch (e: Exception) {
-                    }
-                }
-            }).start()
+            if (NetHelper.getInstance().getNetworkState(this) != NetHelper.NETWORK_NONE){
+                initTcp()
+            }
         }
     }
 
@@ -215,18 +211,13 @@ class WatchHome2Activity : BaseActivity<WatchHomeActivityPresenter, WatchActivit
      * 返回的tcp信息
      */
     override fun setTcpServerHost(tcpSeverDTO: TcpSeverDTO) {
-        isRegister = false
         if(tcpSeverDTO.publicIp!= null && tcpSeverDTO.tcpPort != null && tcpSeverDTO.readerIdleTime != null){
             Constants.tcpServer = tcpSeverDTO.publicIp
             Constants.tcpPort = tcpSeverDTO.tcpPort
             Constants.heartBeat = tcpSeverDTO.readerIdleTime
             tv_server_ip.text = tcpSeverDTO.publicIp
 
-            if (SpManager.getInstance().getBoolean(Constants.SYSTEM_REGISTERED)){
-                presenter.getDeviceVO(Constants.imei)
-            } else {
-                tv_register_status.text = "本机未注册,请将识别码发给管理员。管理员注册本机后请点击注册完成进入"
-            }
+            presenter.getDeviceVO(Constants.imei)
         }
     }
 
@@ -273,6 +264,8 @@ class WatchHome2Activity : BaseActivity<WatchHomeActivityPresenter, WatchActivit
             tv_register_status.text = "本机未注册,请将识别码发给管理员。管理员注册本机后请点击注册完成进入"
             SpManager.getInstance().putBoolean(Constants.SYSTEM_REGISTERED,false)
             tv_register_ok.visibility = View.VISIBLE
+            watch_activity_register_layout.visibility = View.VISIBLE
+            watch_activity_home_linyout.visibility = View.GONE
             return
         }
 
@@ -280,7 +273,7 @@ class WatchHome2Activity : BaseActivity<WatchHomeActivityPresenter, WatchActivit
             Thread(Runnable {
                 //连接TCP
                 if (TcpClient.getInstance().channel==null || !TcpClient.getInstance().channel.isActive) {
-                    TcpClient.getInstance().init(Constants.tcpServer, Constants.tcpPort, Constants.heartBeat)
+                    TcpClient.getInstance().init(Constants.tcpServer, Constants.tcpPort, Constants.heartBeat,iTcpCallBack)
                 }
                 while (!(TcpClient.getInstance().channel==null || !TcpClient.getInstance().channel.isActive)) {
                     presenter.getDeviceVO(Constants.imei)
@@ -293,7 +286,7 @@ class WatchHome2Activity : BaseActivity<WatchHomeActivityPresenter, WatchActivit
             Thread(Runnable {
                 //连接TCP
                 if (TcpClient.getInstance().channel==null || !TcpClient.getInstance().channel.isActive) {
-                    TcpClient.getInstance().init(Constants.tcpServer, Constants.tcpPort, Constants.heartBeat)
+                    TcpClient.getInstance().init(Constants.tcpServer, Constants.tcpPort, Constants.heartBeat,iTcpCallBack)
                 }
             }).start()
         }
@@ -307,6 +300,7 @@ class WatchHome2Activity : BaseActivity<WatchHomeActivityPresenter, WatchActivit
         tv_register_status.setTextColor(Color.GREEN)
 
         SpManager.getInstance().putBoolean(Constants.SYSTEM_REGISTERED,true)
+        isUnRegister = false
 
         Log.i(TAG, "收到返回的设备信息 ")
         Constants.partId = data.partId
@@ -321,6 +315,8 @@ class WatchHome2Activity : BaseActivity<WatchHomeActivityPresenter, WatchActivit
 
         presenter.getAppVersion(Constants.partId, 7)
 
+        //保活守护进程
+        DaemonEnv.init(this);
         DaemonEnv.startServiceSafelyWithData(this, WdKeepAliveService::class.java)
 
         if (Constants.deviceId<=0 || TextUtils.isEmpty(Constants.sipId)) {
@@ -387,19 +383,28 @@ class WatchHome2Activity : BaseActivity<WatchHomeActivityPresenter, WatchActivit
 
     override fun userLogin() {
         Log.i(TAG, "wdkl rtc 登录成功")
+
         runOnUiThread(Runnable {
+            tv_net_reconnect_text.visibility = View.GONE
+            tv_signal_strength.text = "网络正常"
+            netOffLoadingDialog.dismiss()
             sip_state_tv.setBackgroundColor(Color.parseColor("#00FFFF"))
         })
     }
 
     override fun userLogout() {
         Log.w(TAG, "wdkl rtc 用户登出")
+
         runOnUiThread(Runnable {
+            tv_signal_strength.text = "网络断开"
+            tv_net_reconnect_text.visibility = View.VISIBLE
+            netOffLoadingDialog.show()
             sip_state_tv.setBackgroundColor(Color.parseColor("#FF0000"))
+            SocketManager.getInstance().unConnect()
         })
-        if (SocketManager.getInstance().connectFlag) {
-            reConnectRTC()
-        }
+//        if (SocketManager.getInstance().connectFlag) {
+//            reConnectRTC()
+//        }
     }
 
     fun reConnectRTC(){
@@ -420,19 +425,50 @@ class WatchHome2Activity : BaseActivity<WatchHomeActivityPresenter, WatchActivit
         state_linlyout.setOnClickListener(this)
         other_linyout.setOnClickListener(this)
         tv_register_ok.setOnClickListener({
-            loadingDialog.show()
-            presenter.getDeviceVO(Constants.imei)
+            initTcp()
+
+            //presenter.getDeviceVO(Constants.imei)
             countDownTimer.start()
         })
     }
 
+    fun initTcp(){
+        loadingDialog.show()
+
+        var count = 10
+        Thread(Runnable {
+            while (isUnRegister && count>0 && Strings.isNullOrEmpty(Constants.tcpServer)) {
+                SocketManager.getInstance().unConnect()
+                DaemonEnv.sendStopWorkBroadcast(this)
+                Log.i(TAG, "获取TCP服务器IP和端口")
+                runOnUiThread(Runnable {
+                    presenter.getTcpServerHost()
+                })
+                try {
+                    Thread.sleep(3000)
+                } catch (e: Exception) {
+                }
+                count--
+            }
+            loadingDialog.dismiss()
+
+            if (NetHelper.getInstance().getNetworkState(this) == NetHelper.NETWORK_NONE) {
+                runOnUiThread(Runnable {
+                    showMessage("未能正确连接,请重试")
+                })
+            } else if (!Strings.isNullOrEmpty(Constants.tcpServer)){    //有网且得到了服务器IP
+                presenter.getTcpServerHost()
+            }
+        }).start()
+    }
+
     fun initCountDownTimer() {
         countDownTimer = object : CountDownTimer(1 * 1000L, 1000) {
             override fun onTick(millisUntilFinished: Long) {
             }
             override fun onFinish() {
                 tv_register_ok.isEnabled = true
-                loadingDialog.dismiss()
+                //loadingDialog.dismiss()
             }
         }
     }
@@ -535,6 +571,9 @@ class WatchHome2Activity : BaseActivity<WatchHomeActivityPresenter, WatchActivit
         } else if (messageEvent.tag == Constants.EVENT_RTC_STATE){
             runOnUiThread(Runnable {
                 sip_state_tv.setBackgroundColor(Color.parseColor("#00FFFF"))
+                netOffLoadingDialog.dismiss()
+                //tv_signal_strength.text = "网络恢复"
+                tv_net_reconnect_text.visibility = View.GONE
             })
         }
     }

+ 16 - 21
home/src/main/code/com/wdkl/ncs/android/component/home/service/WdKeepAliveService.kt

@@ -17,15 +17,13 @@ import com.wdkl.core.socket.SocketManager
 import com.wdkl.ncs.android.component.home.BuildConfig
 import com.wdkl.ncs.android.component.home.activity.*
 import com.wdkl.ncs.android.component.home.settingconfig.SettingConfig
-import com.wdkl.ncs.android.component.home.util.AppUtils
-import com.wdkl.ncs.android.component.home.util.NetHelper
-import com.wdkl.ncs.android.component.home.util.SpeechUtil
-import com.wdkl.ncs.android.component.home.util.Util
+import com.wdkl.ncs.android.component.home.util.*
 import com.wdkl.ncs.android.component.nursehome.common.Constants
 import com.wdkl.ncs.android.lib.utils.getJsonString
 import com.wdkl.ncs.android.middleware.api.ApiManager
 import com.wdkl.ncs.android.middleware.model.dos.PartSettingDO
 import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
+import com.wdkl.ncs.android.middleware.tcp.ITcpCallBack
 import com.wdkl.ncs.android.middleware.tcp.TcpClient
 import com.wdkl.ncs.android.middleware.tcp.TcpClientHandler
 import com.wdkl.ncs.android.middleware.tcp.channel.DeviceChannel
@@ -50,6 +48,7 @@ class WdKeepAliveService : AbsWorkService() {
     }
 
     private var mIsRunning = false
+    val iTcpCallBack: ITcpCallBack = TcpCallbackImpl()
 
     override fun startWork() {
         EventBus.getDefault().register(this)
@@ -296,25 +295,21 @@ class WdKeepAliveService : AbsWorkService() {
                     }
                     TcpClient.getInstance().sendMsg("0")
 
-                    //socket 重连
-                    if (!SocketManager.getInstance().connectFlag){
-                        SocketManager.getInstance().connect(Urls.WS, Constants.sipId, 0)
-                    } else {
-                        EventBus.getDefault().post(MessageEvent(TcpModel(),Constants.EVENT_RTC_STATE))
-                    }
-
                     if (NetHelper.getInstance().getNetworkState(this@WdKeepAliveService) == NetHelper.NETWORK_NONE || !TcpClientHandler.getConnected()) {
                         Log.w(TAG, "断网唤醒CPU")
-                        val wakeLock = Util.wakeUpAndUnlock(this@WdKeepAliveService)
-                        Thread(Runnable {
-                            Thread.sleep(1000)
-                            wakeLock?.release()
-                        })
-//                        if (TcpClient.getInstance().channel==null || TcpClient.getInstance().bootstrap == null) {
-//                            TcpClient.getInstance().init(Constants.tcpServer, Constants.tcpPort, Constants.heartBeat)
-//                        } else if (!TcpClient.getInstance().channel.isActive){
-//                            TcpClient.getInstance().doConnect()
-//                        }
+                        val wakeLock = Util.getCpuWakeLock(this@WdKeepAliveService)
+                        wakeLock.acquire(1000)
+                        if (TcpClient.getInstance().channel==null || TcpClient.getInstance().bootstrap == null) {
+                            TcpClient.getInstance().init(Constants.tcpServer, Constants.tcpPort, Constants.heartBeat,iTcpCallBack)
+                        } else if (!TcpClient.getInstance().channel.isActive && TcpClient.getInstance().retryTimes<30){
+                            TcpClient.getInstance().init(Constants.tcpServer, Constants.tcpPort, Constants.heartBeat,iTcpCallBack)
+                        }
+                    } else {
+                        if (SocketManager.getInstance().connectFlag){
+                            EventBus.getDefault().post(MessageEvent(TcpModel(),Constants.EVENT_RTC_STATE))
+                        } else {
+                            iTcpCallBack.connected()
+                        }
                     }
                 }
             }

+ 1 - 1
home/src/main/code/com/wdkl/ncs/android/component/home/util/AnrFcExceptionUtil.java

@@ -135,7 +135,7 @@ public class AnrFcExceptionUtil implements Thread.UncaughtExceptionHandler {
         formBody.add("stack_trace",stack_trace);
         Log.w(TAG,urlManager.getDevice_url());
         Request request  = new Request.Builder()
-                .url(urlManager.getDevice_url() + "/device/error_log")
+                .url(urlManager.getDevice_url() + "device/error_log")
                 .post(formBody.build())
                 .build();
 

+ 15 - 0
home/src/main/code/com/wdkl/ncs/android/component/home/util/TcpCallbackImpl.java

@@ -0,0 +1,15 @@
+package com.wdkl.ncs.android.component.home.util;
+
+import com.wdkl.core.consts.Urls;
+import com.wdkl.core.socket.SocketManager;
+import com.wdkl.ncs.android.component.nursehome.common.Constants;
+import com.wdkl.ncs.android.middleware.tcp.ITcpCallBack;
+
+import org.greenrobot.eventbus.EventBus;
+
+public class TcpCallbackImpl implements ITcpCallBack {
+    @Override
+    public void connected() {
+        SocketManager.getInstance().connect(Urls.WS, Constants.Companion.getSipId(), 0);
+    }
+}

+ 10 - 10
home/src/main/res/layout/watch_activity_call_records.xml

@@ -6,16 +6,6 @@
         android:layout_height="match_parent"
         android:background="#FFBDC3">
 
-        <TextView
-            android:id="@+id/tv_empty_records"
-            android:textAlignment="center"
-            android:layout_marginTop="50dp"
-            android:textSize="20sp"
-            android:textColor="@color/warn_orange"
-            android:text="@string/data_empty"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
-
         <com.scwang.smartrefresh.layout.SmartRefreshLayout
             android:id="@+id/refresh"
             android:layout_width="match_parent"
@@ -47,5 +37,15 @@
                 android:layout_centerInParent="true"
                 android:background="@drawable/yu_yin_jie_ting" />
         </RelativeLayout>
+
+        <TextView
+            android:id="@+id/tv_empty_records"
+            android:textAlignment="center"
+            android:layout_marginTop="50dp"
+            android:textSize="20sp"
+            android:textColor="@color/warn_orange"
+            android:text="@string/data_empty"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
     </RelativeLayout>
 </layout>

+ 10 - 2
home/src/main/res/layout/watch_activity_home2.xml

@@ -8,7 +8,6 @@
       <include
           android:id="@+id/watch_activity_register_layout"
           layout="@layout/watch_activity_register"
-          android:visibility="gone"
           ></include>
 
         <LinearLayout
@@ -16,7 +15,7 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:orientation="vertical"
-            android:visibility="visible">
+            android:visibility="gone">
 
             <LinearLayout
                 android:layout_width="match_parent"
@@ -252,6 +251,15 @@
                                 android:layout_marginTop="2dp"
                                 android:src="@drawable/geng_duo" />
 
+                            <TextView
+                                android:id="@+id/tv_net_reconnect_text"
+                                android:visibility="gone"
+                                android:text="重连中"
+                                android:layout_width="wrap_content"
+                                android:layout_height="wrap_content"
+                                android:textColor="@color/warn_orange"
+                                />
+
                         </LinearLayout>
 
                     </LinearLayout>

+ 9 - 0
home/src/main/res/layout/watch_activity_register.xml

@@ -17,6 +17,15 @@
         android:orientation="vertical">
 
         <TextView
+            android:id="@+id/tv_register_nonet"
+            android:visibility="gone"
+            android:text="没有网络"
+            android:textColor="@color/warn_orange"
+            android:layout_width="match_parent"
+            android:gravity="center_vertical"
+            android:layout_height="wrap_content"/>
+
+        <TextView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="10dp"

+ 5 - 1
keepalive/src/main/java/com/wdkl/ncs/keepbackground/watch/WatchDogService.java

@@ -160,7 +160,11 @@ public class WatchDogService extends Service {
         WatchProcessPrefHelper.setIsStartSDaemon(this,false);
         cancelJobAlarmSub();
         if (mConnection.mConnectedState) {
-            unbindService(mConnection);
+            try {
+                unbindService(mConnection);
+            }catch (Exception e){
+                Log.e("stopService error", e.toString());
+            }
         }
         exit();
     }

+ 4 - 0
keepalive/src/main/java/com/wdkl/ncs/keepbackground/work/DaemonEnv.java

@@ -45,6 +45,10 @@ public final class DaemonEnv {
     public static final int MINIMAL_WAKE_UP_INTERVAL = 60 * 1000; // 最小时间为 1 分钟
 
     public static Context app;
+    public static void initContext(Context context){
+        app=context.getApplicationContext();
+    }
+
     public static void init(Context context){
         //开启保护
         app=context.getApplicationContext();

+ 5 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/ITcpCallBack.java

@@ -0,0 +1,5 @@
+package com.wdkl.ncs.android.middleware.tcp;
+
+public interface ITcpCallBack {
+    void connected();
+}

+ 23 - 12
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/TcpClient.java

@@ -32,7 +32,7 @@ public class TcpClient {
     //重试间隔
     private Integer retrySeconds = 2;
     //重试计数
-    private Integer retryTimes = 1;
+    public Integer retryTimes = 1;
 
 
     //单例
@@ -45,7 +45,7 @@ public class TcpClient {
     }
 
     //初始化Netty Tcp Client 并连接
-    public synchronized void init(String serverIP, Integer serverPort, Integer heartBeatSeconds) {
+    public synchronized void init(String serverIP, Integer serverPort, Integer heartBeatSeconds, ITcpCallBack iTcpCallBack) {
         if (bootstrap!=null){
             return;
         }
@@ -74,11 +74,11 @@ public class TcpClient {
                         socketChannel.pipeline().addLast(tcpClientHandler);
                     }
                 }).remoteAddress(serverIP, serverPort);
-        doConnect();
+        doConnect(iTcpCallBack);
     }
 
     //独立连接方法,用于重新连接
-    public synchronized void doConnect() {
+    public synchronized void doConnect(final ITcpCallBack iTcpCallBack) {
         if (channel != null && channel.isActive()) {
             System.out.println("TcpClient connecting");
             return;
@@ -87,11 +87,14 @@ public class TcpClient {
         System.out.println("TcpClient connect start");
         ChannelFuture future = bootstrap.connect().addListener(new ChannelFutureListener() {
             @Override
-            public void operationComplete(ChannelFuture channelFuture) throws Exception {
+            public void operationComplete(final ChannelFuture channelFuture) throws Exception {
                 if (channelFuture.isSuccess()) {
                     channel = channelFuture.channel();
                     retryTimes = 0;
                     System.out.println("TcpClient connect success");
+                    if (iTcpCallBack!=null) {
+                        iTcpCallBack.connected();
+                    }
                 } else {
                     //连接失败时的处理
                     System.out.println("TcpClient connect retry : " + retryTimes);
@@ -101,14 +104,20 @@ public class TcpClient {
                             retryTimes++;
                             if (retryTimes > 30) {
                                 System.out.println("TcpClient 重试" + (retryTimes - 1) + "次,结束");
-                                workGroup.shutdownGracefully();
-                                //从API获取新的serverIP和serverPort,全新连接
-                                TcpClient.getInstance().init(Constants.Companion.getTcpServer(), Constants.Companion.getTcpPort(), Constants.Companion.getHeartBeat());
+
+                                channelFuture.channel().eventLoop().schedule(new Runnable() {
+                                    @Override
+                                    public void run() {
+                                        retryTimes = 0;
+                                        System.out.println("TcpClient 1分钟后 重试连接");
+                                        doConnect(iTcpCallBack);
+                                    }
+                                },60*10, TimeUnit.SECONDS);
                                 return;
                             }
-                            doConnect();
+                            doConnect(iTcpCallBack);
                         }
-                    }, retrySeconds * retryTimes, TimeUnit.SECONDS);
+                    }, retrySeconds, TimeUnit.SECONDS);
                 }
             }
         });
@@ -129,9 +138,11 @@ public class TcpClient {
 
     //发送消息,线程安全
     public synchronized void sendMsg(String content) {
-        Log.i(TAG, "发送的数据 " + content);
+        Log.i(TAG, "准备发送的数据 " + content);
         if (tcpClientHandler != null) {
             tcpClientHandler.sendMsg(content);
+        } else {
+            Log.i(TAG, "未能发送数据 " + content);
         }
     }
 
@@ -141,7 +152,7 @@ public class TcpClient {
         new Thread(new Runnable() {
             @Override
             public void run() {
-                TcpClient.getInstance().init("192.168.1.188", 5080, 9);
+                TcpClient.getInstance().init("192.168.1.188", 5080, 9,null);
             }
         }).start();
 

+ 3 - 2
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/TcpClientHandler.java

@@ -114,6 +114,7 @@ public class TcpClientHandler extends SimpleChannelInboundHandler<String> {
     public void sendMsg(final String msg){
         if (ctx!=null && ctx.channel().isActive()){
             ctx.writeAndFlush(Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8));
+            Log.i(TAG,"TcpClientHandler 发送成功:" + msg);
             return;
         }
         //掉线后的消息处理
@@ -153,7 +154,7 @@ public class TcpClientHandler extends SimpleChannelInboundHandler<String> {
                 public void run() {
                     while (!TcpClientHandler.connected) {
                         if (TcpClient.getInstance().channel == null || !TcpClient.getInstance().channel.isActive()) {
-                            TcpClient.getInstance().init(Constants.Companion.getTcpServer(), Constants.Companion.getTcpPort(), Constants.Companion.getHeartBeat());
+                            TcpClient.getInstance().init(Constants.Companion.getTcpServer(), Constants.Companion.getTcpPort(), Constants.Companion.getHeartBeat(),null);
                             try {
                                 Thread.sleep(10 * 60 * 1000);   //每10分钟重试
                             } catch (InterruptedException e) {
@@ -171,7 +172,7 @@ public class TcpClientHandler extends SimpleChannelInboundHandler<String> {
             @Override
             public void run() {
                 System.out.println("TcpClientHandler 重新连接,第"+retryTimes+"次");
-                TcpClient.getInstance().doConnect();
+                TcpClient.getInstance().doConnect(null);
             }
         },retrySeconds*retryTimes, TimeUnit.SECONDS);
     }

+ 9 - 0
readme.md

@@ -26,6 +26,15 @@
 
 ---
 
+## [1.1.24] version 43 - 2020-08-10
+### Changed
+- 优化启动时的TCP和RTC连接逻辑
+- 优化断线时的处理,每2秒重试连接,最多30次。10分钟后再次重新尝试1分钟内连接30次
+### Fixed
+- 首次SOS不出声的问题
+
+---
+
 ## [1.1.23] version 42 - 2020-08-06
 ### Fixed
 - 修复若干BUG