소스 검색

增加添加文本留言,添加语音留言,删除留言,查看留言功能等

weizhengliang 1 년 전
부모
커밋
7113508e25
38개의 변경된 파일1320개의 추가작업 그리고 89개의 파일을 삭제
  1. 6 4
      android_host/src/main/h10_wke_1h/AndroidManifest.xml
  2. 299 0
      android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/activity/CreateMessageActivity.kt
  3. 63 0
      android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/adapter/CreatorAdapter.java
  4. 31 1
      android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/adapter/MessageAdapter.kt
  5. 2 0
      android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/di/NurseHomeComponent.kt
  6. 1 0
      android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/fragment/CallRecordsFragment.kt
  7. 111 6
      android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/fragment/MessageFragment.kt
  8. 24 12
      android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/util/ConfirmDialogHelper.java
  9. 96 0
      android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/util/MessageDialogHelper.java
  10. 11 3
      android_host/src/main/h10_wke_1h/port/AndroidManifest.xml
  11. 6 0
      android_host/src/main/h10_wke_1h/res/drawable/loading_bg_ripple_shape.xml
  12. 1 0
      android_host/src/main/h10_wke_1h/res/drawable/selector_bottom_btn_text_color.xml
  13. 5 0
      android_host/src/main/h10_wke_1h/res/drawable/selector_record_btn.xml
  14. 2 1
      android_host/src/main/h10_wke_1h/res/layout-land/activity_nurse_home.xml
  15. 7 5
      android_host/src/main/h10_wke_1h/res/layout-land/confirm_dialog.xml
  16. 2 1
      android_host/src/main/h10_wke_1h/res/layout/activity_nurse_home.xml
  17. 30 17
      android_host/src/main/h10_wke_1h/res/layout/adapter_message_item.xml
  18. 6 4
      android_host/src/main/h10_wke_1h/res/layout/confirm_dialog.xml
  19. 22 0
      android_host/src/main/h10_wke_1h/res/layout/creator_item.xml
  20. 29 10
      android_host/src/main/h10_wke_1h/res/layout/fragment_message.xml
  21. 181 0
      android_host/src/main/h10_wke_1h/res/layout/message_create_dialog_activity.xml
  22. 46 0
      android_host/src/main/h10_wke_1h/res/layout/message_dialog.xml
  23. 1 1
      app/src/main/code/com/wdkl/app/ncs/application/Application.kt
  24. 8 11
      common/src/main/code/com/wdkl/ncs/android/lib/base/BaseActivity.kt
  25. 26 4
      middleware/src/main/code/com/wdkl/ncs/android/middleware/api/DeviceApi.kt
  26. 10 4
      middleware/src/main/code/com/wdkl/ncs/android/middleware/helper/RecordHelper.java
  27. 22 2
      middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/contract/nursehome/MessageContract.kt
  28. 0 1
      middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/presenter/nursehome/CallRecordsFragmentPresenter.kt
  29. 149 2
      middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/presenter/nursehome/MessagePresenter.kt
  30. 43 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/utils/ScreenUtils.java
  31. 6 0
      resource/src/main/res/drawable/shape_password_bt_bg.xml
  32. BIN
      resource/src/main/res/mipmap-mdpi/ic_record_normal.png
  33. BIN
      resource/src/main/res/mipmap-mdpi/ic_record_press.png
  34. 17 0
      resource/src/main/res/values-es/strings.xml
  35. 17 0
      resource/src/main/res/values-ru/strings.xml
  36. 17 0
      resource/src/main/res/values-zh/strings.xml
  37. 17 0
      resource/src/main/res/values/strings.xml
  38. 6 0
      resource/src/main/res/values/styles.xml

+ 6 - 4
android_host/src/main/h10_wke_1h/AndroidManifest.xml

@@ -106,6 +106,12 @@
             android:launchMode="singleTask"
             android:excludeFromRecents="true"/>
 
+        <activity android:name=".activity.CreateMessageActivity"
+            android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"
+            android:windowSoftInputMode="stateAlwaysHidden"
+            android:screenOrientation="landscape"
+            android:launchMode="singleInstance"/>
+
         <receiver
             android:name=".receiver.WdBootReceiver"
             android:enabled="true"
@@ -118,10 +124,6 @@
         <activity android:name="com.wdkl.ncs.host.activity.SipTestActivity" />
         <activity android:name="com.wdkl.ncs.host.activity.CallActivity" />
 
-        <!--<service
-            android:name="com.wdkl.ncs.host.service.WdklSipService"
-            android:label="@string/app_name" />-->
-
         <service
             android:name="com.wdkl.ncs.host.sip.core.LinCoreService"
             android:foregroundServiceType="phoneCall|camera|microphone"

+ 299 - 0
android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/activity/CreateMessageActivity.kt

@@ -0,0 +1,299 @@
+package com.wdkl.ncs.android.component.nursehome.activity
+
+import android.annotation.SuppressLint
+import android.graphics.Color
+import android.os.Bundle
+import android.os.SystemClock
+import android.text.TextUtils
+import android.util.Log
+import android.view.MotionEvent
+import android.view.View
+import android.view.WindowManager
+import android.widget.AdapterView
+import com.enation.javashop.net.engine.model.NetState
+import com.wdkl.ncs.android.component.nursehome.R
+import com.wdkl.ncs.android.component.nursehome.adapter.CreatorAdapter
+import com.wdkl.ncs.android.component.nursehome.databinding.MessageCreateDialogActivityBinding
+import com.wdkl.ncs.android.component.nursehome.launch.NurseHomeLaunch
+import com.wdkl.ncs.android.component.nursehome.settingconfig.SettingConfig
+import com.wdkl.ncs.android.component.nursehome.util.MediaPlayHelper
+import com.wdkl.ncs.android.component.nursehome.util.RingPlayHelper
+import com.wdkl.ncs.android.component.nursehome.util.SpeechUtil
+import com.wdkl.ncs.android.lib.base.BaseActivity
+import com.wdkl.ncs.android.lib.utils.showMessage
+import com.wdkl.ncs.android.middleware.common.Constants
+import com.wdkl.ncs.android.middleware.helper.RecordHelper
+import com.wdkl.ncs.android.middleware.logic.contract.nursehome.MessageContract
+import com.wdkl.ncs.android.middleware.logic.presenter.nursehome.MessagePresenter
+import com.wdkl.ncs.android.middleware.model.dos.ClerkDO
+import com.wdkl.ncs.android.middleware.model.dos.FrameDO
+import com.wdkl.ncs.android.middleware.model.dos.RemarkDO
+import com.wdkl.ncs.android.middleware.utils.CommonUtils
+import com.wdkl.ncs.android.middleware.utils.MessageEvent
+import com.wdkl.ncs.android.middleware.utils.ScreenUtils
+import kotlinx.android.synthetic.main.message_create_dialog_activity.*
+import okhttp3.MediaType
+import okhttp3.MultipartBody
+import okhttp3.RequestBody
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+import java.io.File
+
+
+class CreateMessageActivity : BaseActivity<MessagePresenter, MessageCreateDialogActivityBinding>(), MessageContract.View {
+    val TAG = CreateMessageActivity::class.java.simpleName
+
+    private var messageType = 2  //1--用户备注,2--便签留言,3--语音留言
+    private var voiceMsgPath = ""
+
+    var downTime : Long = 0
+    var upTime : Long = 0
+    var downY : Float = 0f
+    var cancel : Boolean = false
+    var voiceFile : String? = null
+
+    var creatorAdapter: CreatorAdapter? = null
+    var selectClerk: String? = ""
+
+    override fun getLayId(): Int {
+        return R.layout.message_create_dialog_activity
+    }
+
+    override fun bindDagger() {
+        NurseHomeLaunch.component.inject(this)
+    }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        setTheme(R.style.Theme_AppCompat_Translucent)
+
+        super.onCreate(savedInstanceState)
+    }
+
+    override fun init() {
+        val lp: WindowManager.LayoutParams = window.attributes
+        lp.width = ScreenUtils.getScreenWidth(this)*2 / 3 // 屏幕宽度的一半
+        lp.height = ScreenUtils.getScreenHeight(this)*3 / 4 // 屏幕高度的一半
+        window.attributes = lp // 设置参数给window
+
+        setFinishOnTouchOutside(false)
+
+        RecordHelper.getInstance().init()
+
+        radio_text_msg.isChecked = true
+        if (group_message_type.checkedRadioButtonId == R.id.radio_voice_msg) {
+            //语音
+            messageType = 3
+            edit_text_message.visibility = View.GONE
+            ll_voice_message.visibility = View.VISIBLE
+        } else {
+            //文本
+            messageType = 2
+            edit_text_message.visibility = View.VISIBLE
+            ll_voice_message.visibility = View.GONE
+        }
+
+        if (Constants.part_id != -1) {
+            presenter.loadClerks(Constants.part_id)
+        }
+    }
+
+    @SuppressLint("ClickableViewAccessibility")
+    override fun bindEvent() {
+        btn_add_cancel.setOnClickListener {
+            finish()
+        }
+
+        btn_add_save.setOnClickListener {
+            val remark = RemarkDO()
+            remark.partId = Constants.part_id
+            remark.type = messageType
+            if (TextUtils.isEmpty(selectClerk)) {
+                showMessage(R.string.str_invalid_creator_name)
+                return@setOnClickListener
+            } else {
+                remark.createName = selectClerk
+            }
+            if (messageType == 2) {
+                if (TextUtils.isEmpty(edit_text_message.text)) {
+                    showMessage(R.string.str_message_content_error)
+                    return@setOnClickListener
+                } else {
+                    remark.content = edit_text_message.text.toString()
+                }
+            } else if (messageType == 3) {
+                if (TextUtils.isEmpty(voiceMsgPath)) {
+                    showMessage(R.string.str_voice_message_invalid)
+                    return@setOnClickListener
+                } else {
+                    remark.content = getString(R.string.voice_message)
+                    remark.filePath = voiceMsgPath
+                }
+            }
+
+            presenter.addNewMessage(remark)
+        }
+
+        ll_message_view.setOnClickListener {
+            //收起软键盘
+            CommonUtils.hideInputKeyboard(activity.window.decorView.windowToken)
+        }
+
+        group_message_type.setOnCheckedChangeListener { group, checkedId ->
+            //收起软键盘
+            CommonUtils.hideInputKeyboard(activity.window.decorView.windowToken)
+
+            if (checkedId == R.id.radio_voice_msg) {
+                //语音
+                messageType = 3
+                edit_text_message.visibility = View.GONE
+                ll_voice_message.visibility = View.VISIBLE
+            } else {
+                //文本
+                messageType = 2
+                edit_text_message.visibility = View.VISIBLE
+                ll_voice_message.visibility = View.GONE
+            }
+        }
+
+
+        //语音留言
+        btn_voice_record.setOnTouchListener { v, event ->
+            when(event.action) {
+                MotionEvent.ACTION_DOWN -> {
+                    cancel = false
+                    downTime = System.currentTimeMillis()
+                    downY = event.getY()
+
+                    //先停止其他语音或铃声
+                    RingPlayHelper.stopRingTone()
+                    SpeechUtil.getInstance().stopSpeak(true)
+                    MediaPlayHelper.getInstance().stopMusic()
+
+                    //开始录制语音消息
+                    RecordHelper.getInstance().startRecord()
+                    tv_voice_record.setText(R.string.str_voice_msg_btn_title)
+                    voice_record_timer.base = SystemClock.elapsedRealtime()
+                    voice_record_timer.start()
+                    voiceFile = RecordHelper.getInstance().audiofilePath
+
+                    //按下时保持常亮
+                    //wakeLock.acquire()
+                }
+
+                MotionEvent.ACTION_MOVE -> {
+                    val moveY = event.getY()
+                    if (Math.abs(downY - moveY) > 100) {
+                        cancel = true
+                    }
+                }
+
+                MotionEvent.ACTION_UP -> {
+                    upTime = System.currentTimeMillis()
+                    RecordHelper.getInstance().stopRecord()
+                    tv_voice_record.setText(R.string.str_voice_msg_btn_text)
+                    voice_record_timer.base = SystemClock.elapsedRealtime()
+                    voice_record_timer.stop()
+
+                    if (Math.abs(upTime - downTime) <= 1000) {
+                        RecordHelper.getInstance().deleteAudioFile(voiceFile)
+                        showMessage(R.string.str_voice_msg_record_loss)
+                    } else if(cancel) {
+                        RecordHelper.getInstance().deleteAudioFile(voiceFile)
+                        showMessage(R.string.str_voice_msg_record_cancel)
+                    } else {
+                        //上传语音留言
+                        if (voiceFile != null) {
+                            val part = MultipartBody.Part.createFormData("file",
+                                voiceFile,
+                                RequestBody.create(MediaType.parse("multipart/form-data"), File(voiceFile!!))
+                            )
+                            presenter.uploadVoiceMsg(part)
+                        }
+                    }
+
+                    //松开时释放
+                    //wakeLock.release()
+                }
+            }
+
+            return@setOnTouchListener false
+        }
+    }
+
+    override fun destory() {
+        //退出时删除本地语音留言音频文件
+        if (!TextUtils.isEmpty(voiceFile)) {
+            RecordHelper.getInstance().deleteAudioFile(voiceFile)
+        }
+    }
+
+    override fun showMessages(data: ArrayList<RemarkDO>) {
+
+    }
+
+    override fun showPageMessages(data: ArrayList<RemarkDO>) {
+
+    }
+
+    override fun resultAddMessage(remarkDO: RemarkDO) {
+        //添加便签留言返回的响应
+        Log.e(TAG, "message save success!")
+        showMessage(R.string.str_message_save_success)
+        setResult(11)
+        finish()
+    }
+
+    override fun resultDelMessage(data: String) {
+
+    }
+
+    override fun uploadResponse(result: String) {
+        voiceMsgPath = result
+        tv_voice_msg_state.setTextColor(Color.parseColor("#00ff00"))
+        tv_voice_msg_state.setText(R.string.str_record_message_success)
+        //上传完成后删除本地文件
+        RecordHelper.getInstance().deleteAudioFile(voiceFile)
+    }
+
+    override fun showClerks(data: ArrayList<ClerkDO>) {
+        if (data.size > 0) {
+            creatorAdapter = CreatorAdapter(activity, data)
+            spinner_creator.adapter = creatorAdapter
+            spinner_creator.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
+                override fun onItemSelected(
+                    parent: AdapterView<*>?,
+                    view: View,
+                    position: Int,
+                    id: Long
+                ) {
+                    selectClerk = data[position].clerkName
+                    Log.e(TAG, "select clerk name: " + selectClerk)
+                }
+
+                override fun onNothingSelected(parent: AdapterView<*>?) {}
+            }
+            spinner_creator.setSelection(0)
+        }
+    }
+
+    override fun onError(message: String, type: Int) {
+
+    }
+
+    override fun complete(message: String, type: Int) {
+
+    }
+
+    override fun start() {
+
+    }
+
+    override fun networkMonitor(state: NetState) {
+
+    }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    fun onMoonEvent(messageEvent: MessageEvent) {
+    }
+
+}

+ 63 - 0
android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/adapter/CreatorAdapter.java

@@ -0,0 +1,63 @@
+package com.wdkl.ncs.android.component.nursehome.adapter;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import com.wdkl.ncs.android.component.nursehome.R;
+import com.wdkl.ncs.android.middleware.model.dos.ClerkDO;
+
+import java.util.List;
+
+public class CreatorAdapter extends BaseAdapter {
+
+    private Context context;
+    private List<ClerkDO> clerkDOS;
+
+    public CreatorAdapter(Context context, List<ClerkDO> list) {
+        this.context = context;
+        this.clerkDOS = list;
+    }
+
+    @Override
+    public int getCount() {
+        return clerkDOS.size();
+    }
+
+    @Override
+    public Object getItem(int position) {
+        return clerkDOS.get(position);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+
+        ViewHolder holder = null;
+
+        if (convertView == null) {
+            convertView = View.inflate(context, R.layout.creator_item, null);
+
+            holder = new ViewHolder();
+            holder.tv = (TextView) convertView.findViewById(R.id.tv_frame_name);
+
+            convertView.setTag(holder);
+        } else {
+            holder = (ViewHolder) convertView.getTag();
+        }
+
+        holder.tv.setText(clerkDOS.get(position).getClerkName());
+
+        return convertView;
+    }
+
+    static class ViewHolder {
+        private TextView tv;
+    }
+}

+ 31 - 1
android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/adapter/MessageAdapter.kt

@@ -1,15 +1,23 @@
 package com.wdkl.ncs.android.component.nursehome.adapter
 
+import android.graphics.Color
+import android.text.TextUtils
 import android.util.Log
+import android.view.View
 import android.view.ViewGroup
 import com.alibaba.android.vlayout.LayoutHelper
 import com.alibaba.android.vlayout.layout.GridLayoutHelper
 import com.wdkl.ncs.android.component.nursehome.R
 import com.wdkl.ncs.android.component.nursehome.databinding.AdapterMessageItemBinding
+import com.wdkl.ncs.android.component.nursehome.util.MediaPlayHelper
+import com.wdkl.ncs.android.component.nursehome.util.RingPlayHelper
+import com.wdkl.ncs.android.component.nursehome.util.SpeechUtil
 import com.wdkl.ncs.android.component.nursehome.util.TimeTransition
 import com.wdkl.ncs.android.lib.adapter.BaseDelegateAdapter
 import com.wdkl.ncs.android.lib.utils.BaseRecyclerViewHolder
+import com.wdkl.ncs.android.lib.utils.showMessage
 import com.wdkl.ncs.android.lib.utils.then
+import com.wdkl.ncs.android.middleware.api.UrlManager
 import com.wdkl.ncs.android.middleware.model.dos.RemarkDO
 
 class MessageAdapter (val data:ArrayList<RemarkDO>) : BaseDelegateAdapter<BaseRecyclerViewHolder<AdapterMessageItemBinding>, RemarkDO>(){
@@ -45,7 +53,7 @@ class MessageAdapter (val data:ArrayList<RemarkDO>) : BaseDelegateAdapter<BaseRe
             self.hGap = 10
 
             /**设置上下间距*/
-            self.vGap = 10
+            self.vGap = 16
 
             /**设置Margin*/
             self.setMargin(0,0,0,0)
@@ -66,8 +74,30 @@ class MessageAdapter (val data:ArrayList<RemarkDO>) : BaseDelegateAdapter<BaseRe
     override fun onBindViewHolder(holder: BaseRecyclerViewHolder<AdapterMessageItemBinding>?, position: Int) {
         holder?.bind { binding ->
             val itemData = getItem(position)
+            if (position%2 == 1) {
+                binding.llMessage.setBackgroundColor(Color.parseColor("#8ef6e4"))
+            } else {
+                binding.llMessage.setBackgroundColor(Color.parseColor("#edb1f1"))
+            }
+
+            if (itemData.type == 3) {
+                binding.ivMessagePlay.setImageResource(R.drawable.ic_bc_play)
+            } else {
+                binding.ivMessagePlay.setImageResource(R.drawable.ic_message)
+            }
+
             binding.tvMessageContent.text = itemData.content
+            binding.tvMessageCreator.text = itemData.createName
             binding.tvMessageTime.text = TimeTransition.stampToYearDateTime(itemData.createTime * 1000)
+
+            binding.ivMessagePlay.setOnClickListener {
+                if (!TextUtils.isEmpty(itemData.filePath)) {
+                    RingPlayHelper.stopRingTone()
+                    SpeechUtil.getInstance().stopSpeak(true)
+                    showMessage("start play")
+                    MediaPlayHelper.getInstance().playUrlMusic(UrlManager.build().buyer + "/" + itemData.filePath, 1.0f, false)
+                }
+            }
         }
     }
 

+ 2 - 0
android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/di/NurseHomeComponent.kt

@@ -1,5 +1,6 @@
 package com.wdkl.ncs.android.component.nursehome.di
 
+import com.wdkl.ncs.android.component.nursehome.activity.CreateMessageActivity
 import com.wdkl.ncs.android.component.nursehome.activity.AppUpdateActivity
 import com.wdkl.ncs.android.component.nursehome.activity.NurseHomeActivity
 import com.wdkl.ncs.android.component.nursehome.activity.TestActivity
@@ -17,6 +18,7 @@ interface NurseHomeComponent{
     fun inject(activity: NurseHomeActivity)
     fun inject(activity: AppUpdateActivity)
     fun inject(activity: TestActivity)
+    fun inject(activity: CreateMessageActivity)
 
     fun inject(fragment: FramePartFragment)
     fun inject(fragment: BroadcastFragment)

+ 1 - 0
android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/fragment/CallRecordsFragment.kt

@@ -273,6 +273,7 @@ class CallRecordsFragment: BaseFragment<CallRecordsFragmentPresenter, FragmentCa
 
     override fun onError(message: String, type: Int) {
         refresh.finishRefresh()
+        refresh.finishLoadMore()
         //errorLog("error",message)
         showMessage(message)
     }

+ 111 - 6
android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/fragment/MessageFragment.kt

@@ -1,19 +1,25 @@
 package com.wdkl.ncs.android.component.nursehome.fragment
 
+import android.content.Intent
 import android.util.Log
 import com.alibaba.android.vlayout.DelegateAdapter
 import com.alibaba.android.vlayout.VirtualLayoutManager
 import com.enation.javashop.net.engine.model.NetState
 import com.scwang.smartrefresh.layout.footer.ClassicsFooter
 import com.wdkl.ncs.android.component.nursehome.R
+import com.wdkl.ncs.android.component.nursehome.activity.CreateMessageActivity
 import com.wdkl.ncs.android.component.nursehome.adapter.MessageAdapter
 import com.wdkl.ncs.android.component.nursehome.databinding.FragmentMessageBinding
 import com.wdkl.ncs.android.component.nursehome.launch.NurseHomeLaunch
+import com.wdkl.ncs.android.component.nursehome.util.ConfirmDialogHelper
+import com.wdkl.ncs.android.component.nursehome.util.MessageDialogHelper
+import com.wdkl.ncs.android.lib.base.BaseApplication
 import com.wdkl.ncs.android.lib.base.BaseFragment
 import com.wdkl.ncs.android.lib.utils.showMessage
 import com.wdkl.ncs.android.middleware.common.Constants
 import com.wdkl.ncs.android.middleware.logic.contract.nursehome.MessageContract
 import com.wdkl.ncs.android.middleware.logic.presenter.nursehome.MessagePresenter
+import com.wdkl.ncs.android.middleware.model.dos.ClerkDO
 import com.wdkl.ncs.android.middleware.model.dos.RemarkDO
 import com.wdkl.ncs.android.middleware.utils.MessageEvent
 import kotlinx.android.synthetic.main.fragment_message.*
@@ -28,6 +34,9 @@ class MessageFragment : BaseFragment<MessagePresenter, FragmentMessageBinding>()
 
     private var messageAdapter: MessageAdapter? = null
 
+    private val pageSize: Int = 10
+    private var pageNo: Int = 1
+
     /**
      * 提供layoutID
      */
@@ -60,7 +69,7 @@ class MessageFragment : BaseFragment<MessagePresenter, FragmentMessageBinding>()
         rv_messages.adapter = delegateAdapter
 
         if (Constants.part_id != -1) {
-            presenter.loadMessage(Constants.part_id)
+            presenter.loadMessageByPage(pageNo, pageSize, Constants.part_id)
         }
     }
 
@@ -70,14 +79,47 @@ class MessageFragment : BaseFragment<MessagePresenter, FragmentMessageBinding>()
     override fun bindEvent() {
         message_refresh.setOnRefreshListener {
             if (Constants.part_id != -1) {
-                presenter.loadMessage(Constants.part_id)
+                pageNo = 1
+                presenter.loadMessageByPage(pageNo, pageSize, Constants.part_id)
+            }
+        }
+
+        message_refresh.setOnLoadMoreListener {
+            if (Constants.part_id != -1) {
+                pageNo += 1
+                presenter.loadMessageByPage(pageNo, pageSize, Constants.part_id)
+            }
+        }
+
+        btn_add_message.setOnClickListener {
+            val intent = Intent(BaseApplication.appContext, CreateMessageActivity::class.java)
+            //startActivity(intent)
+            startActivityForResult(intent, 1)
+        }
+
+        messageAdapter?.setOnItemLongClickListener { data, position ->
+            //删除便签留言
+            ConfirmDialogHelper.showDialog(activity, getString(R.string.str_delete_tip)) {
+                presenter.deleteMessage(data.id)
             }
         }
+
+        messageAdapter?.setOnItemClickListener { data, position ->
+            //放大显示
+            MessageDialogHelper.showDialog(activity, data)
+        }
+    }
+
+    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+        super.onActivityResult(requestCode, resultCode, data)
+        //Log.e(TAG, "activity requestCode: $requestCode, resultCode: $resultCode")
+        if (requestCode == 1 && resultCode == 11) {
+            //添加留言成功,刷新列表
+            pageNo = 1
+            presenter.loadMessageByPage(pageNo, pageSize, Constants.part_id)
+        }
     }
 
-    /**
-     *页面销毁回调
-     */
     override fun destory() {
     }
 
@@ -86,16 +128,79 @@ class MessageFragment : BaseFragment<MessagePresenter, FragmentMessageBinding>()
 
         messageAdapter!!.data.clear()
         if (data.size > 0) {
-            messageAdapter!!.data.addAll(data)
+            for (remark in data) {
+                if (remark.type == 2 || remark.type == 3) {
+                    //便签或语音留言
+                    messageAdapter!!.data.add(remark)
+                }
+            }
         }
         messageAdapter!!.notifyDataSetChanged()
     }
 
+    override fun showPageMessages(data: ArrayList<RemarkDO>) {
+        message_refresh.finishRefresh()
+        if (pageNo == 1) {
+            //刷新数据
+            message_refresh.resetNoMoreData()
+            message_refresh.finishLoadMore()
+
+            messageAdapter!!.data.clear()
+            if (data.size > 0) {
+                for (remark in data) {
+                    if (remark.type == 2 || remark.type == 3) {
+                        //便签或语音留言
+                        messageAdapter!!.data.add(remark)
+                    }
+                }
+            }
+            messageAdapter!!.notifyDataSetChanged()
+        } else {
+            //加载更多
+            if (data.size > 0) {
+                message_refresh.finishLoadMore()
+
+                for (remark in data) {
+                    if (remark.type == 2 || remark.type == 3) {
+                        //便签或语音留言
+                        messageAdapter!!.data.add(remark)
+                    }
+                }
+                messageAdapter!!.notifyDataSetChanged()
+            } else {
+                //已经没有更多数据了
+                message_refresh.finishLoadMoreWithNoMoreData()
+            }
+        }
+    }
+
+    override fun resultAddMessage(remarkDO: RemarkDO) {
+
+    }
+
+    override fun resultDelMessage(data: String) {
+        Log.e(TAG, data)
+        showMessage(data)
+
+        //删除成功后刷新列表
+        pageNo = 1
+        presenter.loadMessageByPage(pageNo, pageSize, Constants.part_id)
+    }
+
+    override fun uploadResponse(result: String) {
+
+    }
+
+    override fun showClerks(data: ArrayList<ClerkDO>) {
+
+    }
+
     /**
      *处理错误信息
      */
     override fun onError(message: String, type: Int) {
         message_refresh.finishRefresh()
+        message_refresh.finishLoadMore()
 
         //messageAdapter!!.data.clear()
         //messageAdapter!!.notifyDataSetChanged()

+ 24 - 12
android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/util/ConfirmDialogHelper.java

@@ -2,6 +2,8 @@ package com.wdkl.ncs.android.component.nursehome.util;
 
 import android.app.Activity;
 import android.app.AlertDialog;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -16,7 +18,7 @@ public class ConfirmDialogHelper {
 
     private static AlertDialog dialog;
 
-    public static void showDialog(final Activity activity, String titleText, View.OnClickListener clickListener) {
+    public static void showDialog(final Activity activity, String titleText, MyListener clickListener) {
         if (dialog != null) {
             dialog.dismiss();
             dialog = null;
@@ -30,29 +32,35 @@ public class ConfirmDialogHelper {
         Button buttonCancel = contentView.findViewById(R.id.cancel_button);
 
         textView.setText(titleText);
-        buttonConfirm.setOnClickListener(clickListener);
-        buttonCancel.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                if (dialog != null) {
-                    dialog.dismiss();
-                }
+        buttonConfirm.setOnClickListener(v -> {
+            if (clickListener != null) {
+                clickListener.onConfirm();
+            }
+
+            if (dialog != null) {
+                dialog.dismiss();
+            }
+        });
+        buttonCancel.setOnClickListener(v -> {
+            if (dialog != null) {
+                dialog.dismiss();
             }
         });
 
         dialog = builder.create();
-        dialog.setCanceledOnTouchOutside(false);
-        dialog.setCancelable(false);
+        //dialog.setCanceledOnTouchOutside(false);
+        //dialog.setCancelable(false);
         dialog.show();
 
         //设置dialog宽高及位置
         try {
             Window window = dialog.getWindow();
             WindowManager.LayoutParams lp = window.getAttributes();
-            lp.width = 480;
-            lp.height = 360;
+            lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
+            lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
             lp.gravity = Gravity.CENTER;
             window.setAttributes(lp);
+            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
 
             window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                     | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
@@ -65,4 +73,8 @@ public class ConfirmDialogHelper {
             e.printStackTrace();
         }
     }
+
+    public interface MyListener{
+        void onConfirm();
+    }
 }

+ 96 - 0
android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/util/MessageDialogHelper.java

@@ -0,0 +1,96 @@
+package com.wdkl.ncs.android.component.nursehome.util;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.text.TextUtils;
+import android.text.method.ScrollingMovementMethod;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.TextView;
+
+import com.wdkl.ncs.android.component.nursehome.R;
+import com.wdkl.ncs.android.middleware.api.UrlManager;
+import com.wdkl.ncs.android.middleware.model.dos.RemarkDO;
+
+import static com.wdkl.ncs.android.lib.utils.ExtendMethodsKt.showMessage;
+
+public class MessageDialogHelper {
+
+    private static AlertDialog dialog;
+
+    public static void showDialog(final Activity activity, final RemarkDO remarkDO) {
+        if (dialog != null) {
+            dialog.dismiss();
+            dialog = null;
+        }
+
+        View contentView = LayoutInflater.from(activity).inflate(R.layout.message_dialog, null);
+        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+        builder.setView(contentView);
+        TextView textView = contentView.findViewById(R.id.message_text);
+        ImageButton play = contentView.findViewById(R.id.btn_message_play);
+        Button buttonCancel = contentView.findViewById(R.id.btn_cancel);
+        textView.setMovementMethod(ScrollingMovementMethod.getInstance());
+
+        if (remarkDO.getType() == 3) {
+            play.setVisibility(View.VISIBLE);
+        } else {
+            play.setVisibility(View.GONE);
+        }
+
+        textView.setText(remarkDO.getContent());
+        buttonCancel.setOnClickListener(v -> {
+            if (dialog != null) {
+                dialog.dismiss();
+            }
+        });
+
+        play.setOnClickListener(v -> {
+            if (!TextUtils.isEmpty(remarkDO.getFilePath())) {
+                RingPlayHelper.stopRingTone();
+                SpeechUtil.getInstance().stopSpeak(true);
+                showMessage("start play");
+                MediaPlayHelper.getInstance().playUrlMusic(UrlManager.Companion.build().getBuyer() + "/" + remarkDO.getFilePath(), 1.0f, false);
+            }
+        });
+
+        dialog = builder.create();
+        //dialog.setCanceledOnTouchOutside(false);
+        //dialog.setCancelable(false);
+        dialog.show();
+        dialog.setOnDismissListener(dialog -> {
+            if (remarkDO.getType() == 3 && MediaPlayHelper.getInstance().isMediaPlaying()) {
+                MediaPlayHelper.getInstance().stopMusic();
+            }
+        });
+
+        //设置dialog宽高及位置
+        try {
+            Window window = dialog.getWindow();
+            WindowManager.LayoutParams lp = window.getAttributes();
+            lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
+            lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
+            lp.gravity = Gravity.CENTER;
+            window.setAttributes(lp);
+            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+
+            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+                    | View.SYSTEM_UI_FLAG_FULLSCREEN);
+            window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 11 - 3
android_host/src/main/h10_wke_1h/port/AndroidManifest.xml

@@ -99,6 +99,12 @@
             android:launchMode="singleTask"
             android:excludeFromRecents="true"/>
 
+        <activity android:name=".activity.CreateMessageActivity"
+            android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"
+            android:windowSoftInputMode="stateAlwaysHidden"
+            android:screenOrientation="portrait"
+            android:launchMode="singleInstance"/>
+
         <receiver
             android:name=".receiver.WdBootReceiver"
             android:enabled="true"
@@ -108,15 +114,17 @@
             </intent-filter>
         </receiver>
         <activity android:name=".activity.TestActivity"
-            android:screenOrientation="landscape"
+            android:screenOrientation="portrait"
             android:launchMode="singleInstance"/>
 
         <activity android:name="com.wdkl.ncs.host.activity.SipTestActivity" />
         <activity android:name="com.wdkl.ncs.host.activity.CallActivity" />
 
         <service
-            android:name="com.wdkl.ncs.host.service.WdklSipService"
-            android:label="@string/app_name" />
+            android:name="com.wdkl.ncs.host.sip.core.LinCoreService"
+            android:foregroundServiceType="phoneCall|camera|microphone"
+            android:label="@string/app_name"
+            android:stopWithTask="false" />
 
     </application>
 

+ 6 - 0
android_host/src/main/h10_wke_1h/res/drawable/loading_bg_ripple_shape.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="#e7e7e7"/>
+    <corners android:radius="20dp" />
+</shape>

+ 1 - 0
android_host/src/main/h10_wke_1h/res/drawable/selector_bottom_btn_text_color.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:color="@color/text_name_color" android:state_checked="true"/>
+    <item android:color="@color/text_name_color" android:state_pressed="true"/>
     <item android:color="@color/white"/>
 </selector>

+ 5 - 0
android_host/src/main/h10_wke_1h/res/drawable/selector_record_btn.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@mipmap/ic_record_press" android:state_pressed="true"/>
+    <item android:drawable="@mipmap/ic_record_normal"/>
+</selector>

+ 2 - 1
android_host/src/main/h10_wke_1h/res/layout-land/activity_nurse_home.xml

@@ -331,7 +331,8 @@
                             android:gravity="center"
                             android:textColor="@drawable/selector_bottom_btn_text_color"
                             android:text="@string/str_note_message"
-                            android:textSize="24sp" />
+                            android:textSize="24sp"
+                            android:visibility="gone"/>
 
                         <com.wdkl.ncs.android.lib.widget.CustomRadioButton
                             android:id="@+id/system_settings_radio_bt"

+ 7 - 5
android_host/src/main/h10_wke_1h/res/layout-land/confirm_dialog.xml

@@ -2,9 +2,10 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:padding="10dp"
+    android:padding="20dp"
     android:gravity="center"
-    android:orientation="vertical">
+    android:orientation="vertical"
+    android:background="@drawable/loading_bg_ripple_shape">
 
     <TextView
         android:id="@+id/confirm_text"
@@ -21,12 +22,13 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginTop="40dp"
+        android:layout_marginBottom="20dp"
         android:gravity="center">
         <Button
             android:id="@+id/confirm_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:background="@drawable/bg_bottom_btn"
+            android:background="@drawable/shape_main_hos_txt_bg"
             android:padding="8dp"
             android:text="@string/str_confirm"
             android:textSize="20sp"
@@ -36,8 +38,8 @@
             android:id="@+id/cancel_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginLeft="20dp"
-            android:background="@drawable/bg_bottom_btn"
+            android:layout_marginLeft="30dp"
+            android:background="@drawable/shape_password_bt_bg"
             android:padding="8dp"
             android:text="@string/str_cancel"
             android:textSize="20sp"

+ 2 - 1
android_host/src/main/h10_wke_1h/res/layout/activity_nurse_home.xml

@@ -330,7 +330,8 @@
                             android:gravity="center"
                             android:textColor="@drawable/selector_bottom_btn_text_color"
                             android:text="@string/str_note_message"
-                            android:textSize="24sp" />
+                            android:textSize="24sp"
+                            android:visibility="gone"/>
 
                         <com.wdkl.ncs.android.lib.widget.CustomRadioButton
                             android:id="@+id/system_settings_radio_bt"

+ 30 - 17
android_host/src/main/h10_wke_1h/res/layout/adapter_message_item.xml

@@ -1,15 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
 <layout>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_marginTop="10dp"
-    android:orientation="vertical">
-
-    <LinearLayout
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/ll_message"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:padding="10dp">
+        android:layout_height="92dp"
+        android:layout_marginTop="10dp"
+        android:gravity="center_vertical"
+        android:padding="20dp">
 
         <ImageView
             android:layout_width="wrap_content"
@@ -23,30 +20,46 @@
             android:id="@+id/tv_message_content"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
-            android:layout_weight="4"
             android:layout_marginLeft="20dp"
             android:layout_marginRight="20dp"
+            android:layout_weight="4"
             android:gravity="center_vertical"
+            android:paddingLeft="10dp"
+            android:paddingRight="10dp"
+            android:singleLine="true"
+            android:ellipsize="end"
             android:text="----"
             android:textColor="@color/black"
+            android:textSize="28sp" />
+
+        <ImageView
+            android:id="@+id/iv_message_play"
+            android:layout_width="36dp"
+            android:layout_height="match_parent"
+            android:src="@drawable/ic_message" />
+
+        <TextView
+            android:id="@+id/tv_message_creator"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dp"
+            android:layout_marginRight="10dp"
+            android:layout_weight="1"
+            android:gravity="center"
+            android:text="--"
+            android:textColor="@color/black"
             android:textSize="24sp" />
 
         <TextView
             android:id="@+id/tv_message_time"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
-            android:layout_weight="2"
             android:layout_marginLeft="10dp"
             android:layout_marginRight="10dp"
+            android:layout_weight="2"
             android:gravity="center"
             android:text="--"
             android:textSize="20sp" />
 
     </LinearLayout>
-
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="1dp"
-        android:background="#2F9DF1"/>
-</LinearLayout>
 </layout>

+ 6 - 4
android_host/src/main/h10_wke_1h/res/layout/confirm_dialog.xml

@@ -2,9 +2,10 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:padding="10dp"
+    android:padding="20dp"
     android:gravity="center"
-    android:orientation="vertical">
+    android:orientation="vertical"
+    android:background="@drawable/loading_bg_ripple_shape">
 
     <TextView
         android:id="@+id/confirm_text"
@@ -21,12 +22,13 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginTop="40dp"
+        android:layout_marginBottom="20dp"
         android:gravity="center">
         <Button
             android:id="@+id/confirm_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:background="@drawable/bg_bottom_btn"
+            android:background="@drawable/shape_main_hos_txt_bg"
             android:padding="8dp"
             android:text="@string/str_confirm"
             android:textSize="20sp"
@@ -37,7 +39,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginLeft="20dp"
-            android:background="@drawable/bg_bottom_btn"
+            android:background="@drawable/shape_password_bt_bg"
             android:padding="8dp"
             android:text="@string/str_cancel"
             android:textSize="20sp"

+ 22 - 0
android_host/src/main/h10_wke_1h/res/layout/creator_item.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="wrap_content"
+    android:layout_width="wrap_content"
+    android:orientation="vertical"
+    android:background="#e7e7e7">
+
+    <TextView
+        android:id="@+id/tv_frame_name"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:padding="8dp"
+        android:gravity="center"
+        android:text="--"
+        android:textSize="26sp"
+        android:textColor="@color/black" />
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="@color/black" />
+</LinearLayout>

+ 29 - 10
android_host/src/main/h10_wke_1h/res/layout/fragment_message.xml

@@ -1,21 +1,40 @@
 <?xml version="1.0" encoding="utf-8"?>
 <layout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:bind="http://schemas.android.com/apk/res-auto">
-
-    <com.scwang.smartrefresh.layout.SmartRefreshLayout
-        android:id="@+id/message_refresh"
+    <RelativeLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        bind:srlEnableLoadMore="false"
-        bind:srlEnableRefresh="true">
+        android:background="#EAF2F9">
+
+        <Button
+            android:id="@+id/btn_add_message"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="20dp"
+            android:layout_marginBottom="40dp"
+            android:padding="10dp"
+            android:layout_alignParentBottom="true"
+            android:layout_centerHorizontal="true"
+            android:background="@drawable/shape_main_hos_txt_bg"
+            android:textColor="@drawable/selector_bottom_btn_text_color"
+            android:text="@string/str_add_message"
+            android:textSize="28sp" />
 
-        <android.support.v7.widget.RecyclerView
-            android:id="@+id/rv_messages"
+        <com.scwang.smartrefresh.layout.SmartRefreshLayout
+            android:id="@+id/message_refresh"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:background="#EAF2F9"
-            android:padding="10dp"/>
+            android:layout_above="@id/btn_add_message"
+            bind:srlEnableLoadMore="true"
+            bind:srlEnableRefresh="true">
+
+            <android.support.v7.widget.RecyclerView
+                android:id="@+id/rv_messages"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:padding="20dp"/>
 
-    </com.scwang.smartrefresh.layout.SmartRefreshLayout>
+        </com.scwang.smartrefresh.layout.SmartRefreshLayout>
+    </RelativeLayout>
 
 </layout>

+ 181 - 0
android_host/src/main/h10_wke_1h/res/layout/message_create_dialog_activity.xml

@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/ll_message_view"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/loading_bg_ripple_shape"
+    android:gravity="center_horizontal"
+    android:padding="10dp"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dp"
+        android:paddingLeft="20dp"
+        android:paddingRight="20dp"
+        android:orientation="horizontal">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:text="@string/str_message_type"
+            android:textColor="#000000"
+            android:textSize="28sp" />
+
+        <RadioGroup
+            android:id="@+id/group_message_type"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="20dp"
+            android:orientation="horizontal">
+
+            <RadioButton
+                android:id="@+id/radio_text_msg"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/str_text_message"
+                android:textColor="#000000"
+                android:textSize="28sp"
+                android:checked="true"/>
+
+            <RadioButton
+                android:id="@+id/radio_voice_msg"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="20dp"
+                android:text="@string/str_voice_message"
+                android:textColor="#000000"
+                android:textSize="28sp" />
+        </RadioGroup>
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="60dp"
+        android:layout_marginTop="20dp"
+        android:paddingLeft="20dp"
+        android:paddingRight="20dp">
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:gravity="center_vertical"
+            android:text="@string/str_message_creator"
+            android:textColor="#000000"
+            android:textSize="28sp"/>
+        <Spinner
+            android:id="@+id/spinner_creator"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_marginStart="10dp"
+            android:gravity="center_vertical"
+            android:spinnerMode="dropdown"/>
+
+    </LinearLayout>
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="260dp"
+        android:layout_marginTop="20dp"
+        android:paddingTop="10dp">
+
+        <EditText
+            android:id="@+id/edit_text_message"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textColor="#000000"
+            android:textSize="28sp"
+            android:visibility="gone"/>
+
+        <LinearLayout
+            android:id="@+id/ll_voice_message"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:orientation="vertical"
+            android:visibility="visible">
+
+            <Chronometer
+                android:id="@+id/voice_record_timer"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:textColor="#000000"
+                android:textSize="20sp"
+                android:text="00:00" />
+
+            <Button
+                android:id="@+id/btn_voice_record"
+                android:layout_width="120dp"
+                android:layout_height="120dp"
+                android:layout_marginTop="10dp"
+                android:layout_gravity="center"
+                android:background="@drawable/selector_record_btn" />
+
+            <TextView
+                android:id="@+id/tv_voice_record"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:gravity="center"
+                android:text="@string/str_voice_msg_btn_text"
+                android:textColor="#000000"
+                android:textSize="24sp"/>
+
+            <TextView
+                android:id="@+id/tv_voice_msg_state"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dp"
+                android:gravity="center"
+                android:text="@string/str_empty_voice_msg"
+                android:textColor="#ff0000"
+                android:textSize="22sp"/>
+        </LinearLayout>
+
+    </FrameLayout>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="40dp"
+        android:layout_marginBottom="20dp">
+        <Button
+            android:id="@+id/btn_add_save"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="40dp"
+            android:paddingRight="40dp"
+            android:paddingTop="10dp"
+            android:paddingBottom="10dp"
+            android:background="@drawable/shape_main_hos_txt_bg"
+            android:textColor="@drawable/selector_bottom_btn_text_color"
+            android:text="@string/str_save"
+            android:textSize="28sp"
+            style="?android:attr/buttonBarButtonStyle" />
+
+        <View
+            android:layout_width="60dp"
+            android:layout_height="60dp"/>
+
+        <Button
+            android:id="@+id/btn_add_cancel"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="40dp"
+            android:paddingRight="40dp"
+            android:paddingTop="10dp"
+            android:paddingBottom="10dp"
+            android:background="@drawable/shape_main_hos_txt_bg"
+            android:textColor="@drawable/selector_bottom_btn_text_color"
+            android:text="@string/str_cancel"
+            android:textSize="28sp"
+            style="?android:attr/buttonBarButtonStyle" />
+    </LinearLayout>
+
+
+</LinearLayout>
+</layout>

+ 46 - 0
android_host/src/main/h10_wke_1h/res/layout/message_dialog.xml

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:padding="20dp"
+    android:gravity="center"
+    android:orientation="vertical"
+    android:background="@drawable/loading_bg_ripple_shape">
+
+    <TextView
+        android:id="@+id/message_text"
+        android:layout_width="720dp"
+        android:layout_height="340dp"
+        android:layout_marginTop="20dp"
+        android:padding="8dp"
+        android:gravity="start"
+        android:textColor="@color/black"
+        android:textSize="32sp"
+        android:letterSpacing="0.2"
+        android:lineSpacingExtra="8dp"
+        android:scrollbars="vertical"
+        android:fadeScrollbars="false"/>
+
+    <ImageButton
+        android:id="@+id/btn_message_play"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dp"
+        android:background="@android:color/transparent"
+        android:src="@drawable/ic_bc_play"
+        android:visibility="gone"/>
+
+    <Button
+        android:id="@+id/btn_cancel"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dp"
+        android:layout_marginBottom="20dp"
+        android:gravity="center"
+        android:background="@drawable/shape_password_bt_bg"
+        android:padding="10dp"
+        android:text="@string/str_confirm"
+        android:textSize="28sp"
+        android:textColor="@drawable/selector_bottom_btn_text_color"/>
+
+</LinearLayout>

+ 1 - 1
app/src/main/code/com/wdkl/app/ncs/application/Application.kt

@@ -98,7 +98,7 @@ class Application : BaseApplication() {
         super.attachBaseContext(base)
     }
 
-    override fun onConfigurationChanged(newConfig: Configuration?) {
+    override fun onConfigurationChanged(newConfig: Configuration) {
         super.onConfigurationChanged(newConfig)
         val languageId: Int = SettingConfig.getLanguageId(baseContext)
         LocaleMangerUtils.setApplicationLanguageByIndex(baseContext, languageId)

+ 8 - 11
common/src/main/code/com/wdkl/ncs/android/lib/base/BaseActivity.kt

@@ -126,6 +126,10 @@ abstract class BaseActivity<PresenterType : BaseContract.BasePresenter, DataBind
 
         /**执行绑定event操作*/
         bindEvent()
+
+        if (!EventBus.getDefault().isRegistered(this)) {
+            EventBus.getDefault().register(this)
+        }
     }
 
     /**
@@ -146,17 +150,6 @@ abstract class BaseActivity<PresenterType : BaseContract.BasePresenter, DataBind
         window.decorView.systemUiVisibility = FULL_SCREEN_FLAG
     }
 
-    override fun onStart() {
-        super.onStart()
-        EventBus.getDefault().register(this)
-    }
-
-
-    override fun onStop() {
-        super.onStop()
-        EventBus.getDefault().unregister(this)
-    }
-
 
     /**
      * @author LDD
@@ -194,6 +187,10 @@ abstract class BaseActivity<PresenterType : BaseContract.BasePresenter, DataBind
         //fixInputMethodManagerLeak(activity)
         errorLog("PageDestory","页面销毁======>$localClassName")
 
+        if (EventBus.getDefault().isRegistered(this)) {
+            EventBus.getDefault().unregister(this)
+        }
+
         try {
             manager?.unBindAIDLService(this)
         } catch (e: Exception) {

+ 26 - 4
middleware/src/main/code/com/wdkl/ncs/android/middleware/api/DeviceApi.kt

@@ -1,11 +1,9 @@
 package com.wdkl.ncs.android.middleware.api
 
 import io.reactivex.Observable
+import okhttp3.MultipartBody
 import okhttp3.ResponseBody
-import retrofit2.http.GET
-import retrofit2.http.POST
-import retrofit2.http.Path
-import retrofit2.http.Query
+import retrofit2.http.*
 
 interface DeviceApi {
     @GET("/deviceNurse/getDeviceByEthMac/{ethMac}")
@@ -43,4 +41,28 @@ interface DeviceApi {
 
     @GET("/deviceNurse/getRemarkByPartId/{partId}")
     fun getMessages(@Path("partId") partId: Int): Observable<ResponseBody>
+
+    //分页查询便签留言
+    @POST("/deviceNurse/remark/page")
+    fun getMessageByPage(@Query("page_no") pageNo: Int, @Query("page_size") pageSize: Int, @Query("part_id") partId: Int): Observable<ResponseBody>
+
+    //添加便签留言
+    @POST("/deviceNurse/remark")
+    fun addRemark(@Query("id") id: Int?, @Query("unionId") unionId: String?
+                  ,@Query("createTime") createTime: Long?, @Query("partId") partId: Int
+                  ,@Query("type") type: Int, @Query("memberId") memberId: Int?
+                  ,@Query("createName") createName: String?, @Query("content") content: String?
+                  ,@Query("fileName") fileName: String?, @Query("filePath") filePath: String?): Observable<ResponseBody>
+
+    //删除便签留言
+    @DELETE("/deviceNurse/remark/{ids}")
+    fun deleteRemark(@Path("ids") ids: Int): Observable<ResponseBody>
+
+    //上传文件
+    @Multipart
+    @POST("/ncs/upload/file")
+    fun uploadFile(@Part() file : MultipartBody.Part): Observable<ResponseBody>
+
+    @GET("/deviceNurse/clerks_by_shop_id/{shop_id}")
+    fun getClerks(@Path("shop_id") shopId: Int): Observable<ResponseBody>
 }

+ 10 - 4
middleware/src/main/code/com/wdkl/ncs/android/middleware/helper/RecordHelper.java

@@ -4,6 +4,8 @@ import android.media.MediaRecorder;
 import android.os.Environment;
 import android.util.Log;
 
+import com.wdkl.ncs.android.lib.utils.TimeHandle;
+
 import java.io.File;
 import java.io.IOException;
 
@@ -39,7 +41,7 @@ public class RecordHelper {
     }
 
     public void startRecord() {
-        audiofilePath = VOICE_MSG_FILE_PATH + "/" + System.currentTimeMillis() + "_voice.mp3";
+        audiofilePath = VOICE_MSG_FILE_PATH + "/" + TimeHandle.INSTANCE.getRecTimeFilename() + "_voice.mp3";
         new Thread(new Runnable() {
             @Override
             public void run() {
@@ -109,9 +111,13 @@ public class RecordHelper {
 
     public void deleteAudioFile(String path) {
         synchronized (lock) {
-            File file = new File(path);
-            if (file.exists()) {
-                file.delete();
+            try {
+                File file = new File(path);
+                if (file.exists()) {
+                    file.delete();
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
             }
         }
     }

+ 22 - 2
middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/contract/nursehome/MessageContract.kt

@@ -1,19 +1,39 @@
 package com.wdkl.ncs.android.middleware.logic.contract.nursehome
 
 import com.wdkl.ncs.android.lib.base.BaseContract
+import com.wdkl.ncs.android.middleware.model.dos.ClerkDO
 import com.wdkl.ncs.android.middleware.model.dos.RemarkDO
+import okhttp3.MultipartBody
 
 
 interface MessageContract {
 
-    interface View:BaseContract.BaseView{
+    interface View:BaseContract.BaseView {
         fun showMessages(data: ArrayList<RemarkDO>)
 
+        fun showPageMessages(data: ArrayList<RemarkDO>)
+
+        fun resultAddMessage(remarkDO: RemarkDO)
+
+        fun resultDelMessage(data: String)
+
+        fun uploadResponse(result: String)
+
+        fun showClerks(data: ArrayList<ClerkDO>)
     }
 
-    interface Presenter:BaseContract.BasePresenter{
+    interface Presenter:BaseContract.BasePresenter {
         fun loadMessage(partId: Int)
 
+        fun loadMessageByPage(pageNo: Int, pageSize: Int, partId: Int)
+
+        fun addNewMessage(remarkDO: RemarkDO)
+
+        fun deleteMessage(ids: Int)
+
+        fun uploadVoiceMsg(multipart : MultipartBody.Part)
+
+        fun loadClerks(shopIp: Int)
     }
 
 }

+ 0 - 1
middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/presenter/nursehome/CallRecordsFragmentPresenter.kt

@@ -116,7 +116,6 @@ class CallRecordsFragmentPresenter @Inject constructor() :RxPresenter<CallRecord
     @SuppressLint("LongLogTag")
     override fun loadFloor(page_no: Int, page_size: Int, part_id: Int, choice: Int,event_id:String) {
         //page_no页码 page_size每页显示的数量 part_id科室ID  choice 0所有记录 1未接 2通话 3事假
-        Log.e("CallRecordsFragmentPresenter", "qqqqqqq")
         if(TextUtils.isEmpty(event_id)) {
             callRecordsFragmentApi.getCallRecords(page_no, page_size, part_id, choice)
                 .map {

+ 149 - 2
middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/presenter/nursehome/MessagePresenter.kt

@@ -7,13 +7,15 @@ import com.google.gson.FieldNamingPolicy
 import com.google.gson.GsonBuilder
 import com.google.gson.reflect.TypeToken
 import com.wdkl.ncs.android.lib.base.RxPresenter
-import com.wdkl.ncs.android.lib.utils.ConnectionObserver
-import com.wdkl.ncs.android.lib.utils.getJsonString
+import com.wdkl.ncs.android.lib.utils.*
 import com.wdkl.ncs.android.middleware.api.DeviceApi
 import com.wdkl.ncs.android.middleware.di.MiddlewareDaggerComponent
 import com.wdkl.ncs.android.middleware.logic.contract.nursehome.MessageContract
+import com.wdkl.ncs.android.middleware.model.dos.ClerkDO
 import com.wdkl.ncs.android.middleware.model.dos.RemarkDO
 import io.reactivex.disposables.Disposable
+import okhttp3.MultipartBody
+import okhttp3.ResponseBody
 import javax.inject.Inject
 
 class MessagePresenter@Inject constructor():RxPresenter<MessageContract.View>(), MessageContract.Presenter {
@@ -45,7 +47,96 @@ class MessagePresenter@Inject constructor():RxPresenter<MessageContract.View>(),
         override fun attachSubscribe(var1: Disposable) {
             addDisposable(var1)
         }
+    }
+
+    private val observable2 = object : ConnectionObserver<Any>() {
+        override fun onStartWithConnection() {
+            providerView()
+        }
+
+        override fun onNextWithConnection(result: Any, connectionQuality: ConnectionQuality) {
+            providerView().complete()
+            providerView().showPageMessages(result as ArrayList<RemarkDO>)
+        }
+
+        override fun onErrorWithConnection(
+            error: ExceptionHandle.ResponeThrowable,
+            connectionQuality: ConnectionQuality
+        ) {
+            providerView().onError(error.customMessage)
+        }
+
+        override fun attachSubscribe(var1: Disposable) {
+            addDisposable(var1)
+        }
+    }
+
+    private val observable3 = object : ConnectionObserver<Any>() {
+        override fun onStartWithConnection() {
+            providerView()
+        }
 
+        override fun onNextWithConnection(result: Any, connectionQuality: ConnectionQuality) {
+            providerView().complete()
+            providerView().showClerks(result as ArrayList<ClerkDO>)
+        }
+
+        override fun onErrorWithConnection(
+            error: ExceptionHandle.ResponeThrowable,
+            connectionQuality: ConnectionQuality
+        ) {
+            providerView().onError(error.customMessage)
+        }
+
+        override fun attachSubscribe(var1: Disposable) {
+            addDisposable(var1)
+        }
+    }
+
+    private val observer = object : ConnectionObserver<Any>() {
+        override fun onStartWithConnection() {
+            providerView()
+        }
+
+        override fun onNextWithConnection(result: Any, connectionQuality: ConnectionQuality) {
+            providerView().complete("")
+            when (result) {
+                is RemarkDO -> {
+                    providerView().resultAddMessage(result)
+                }
+
+                is String -> {
+                    providerView().resultDelMessage(result)
+                }
+            }
+        }
+
+        override fun onErrorWithConnection(error: ExceptionHandle.ResponeThrowable, connectionQuality: ConnectionQuality) {
+            providerView().onError(error.customMessage)
+        }
+
+        override fun attachSubscribe(var1: Disposable) {
+            addDisposable(var1)
+        }
+    }
+
+    private val observer2 = object : ConnectionObserver<ResponseBody>() {
+        override fun onStartWithConnection() {
+            providerView()
+        }
+
+        override fun onNextWithConnection(result: ResponseBody, connectionQuality: ConnectionQuality) {
+            providerView().complete("")
+            providerView().uploadResponse(result.getJsonString())
+        }
+
+        override fun onErrorWithConnection(error: ExceptionHandle.ResponeThrowable, connectionQuality: ConnectionQuality) {
+            providerView().onError(error.customMessage)
+        }
+
+        override fun attachSubscribe(var1: Disposable) {
+            addDisposable(var1)
+        }
     }
 
 
@@ -63,4 +154,60 @@ class MessagePresenter@Inject constructor():RxPresenter<MessageContract.View>(),
             .subscribe(observable)
     }
 
+    override fun loadMessageByPage(pageNo: Int, pageSize: Int, partId: Int) {
+        deviceApi.getMessageByPage(pageNo, pageSize, partId)
+            .map {
+                val remarkList = ArrayList<RemarkDO>()
+                val gson = GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create()
+                it.toJsonObject().valueJsonArray("data").arrayObjects().forEach { dic ->
+                    remarkList.add(gson.fromJson(dic.toString(), RemarkDO::class.java))
+                }
+
+                return@map remarkList
+            }
+            .compose(ThreadFromUtils.defaultSchedulers())
+            .subscribe(observable2)
+    }
+
+    override fun addNewMessage(remarkDO: RemarkDO) {
+        deviceApi.addRemark(remarkDO.id, remarkDO.unionId, remarkDO.createTime, remarkDO.partId, remarkDO.type,
+            remarkDO.memberId, remarkDO.createName, remarkDO.content, remarkDO.fileName, remarkDO.filePath)
+            .map {
+                val gson = GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create()
+                val result = gson.fromJson(it.getJsonString(), RemarkDO::class.java)
+                return@map result
+            }
+            .compose(ThreadFromUtils.defaultSchedulers())
+            .subscribe(observer)
+    }
+
+    override fun deleteMessage(ids: Int) {
+        deviceApi.deleteRemark(ids)
+            .map {
+                val result = "Delete success"
+                return@map result
+            }
+            .compose(ThreadFromUtils.defaultSchedulers())
+            .subscribe(observer)
+    }
+
+    override fun uploadVoiceMsg(multipart: MultipartBody.Part) {
+        deviceApi.uploadFile(multipart)
+            .compose(ThreadFromUtils.defaultSchedulers())
+            .subscribe(observer2)
+    }
+
+    override fun loadClerks(shopIp: Int) {
+        deviceApi.getClerks(shopIp)
+            .map {
+                val data = it.getJsonString()
+                val gson = GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create()
+                val itemType = object : TypeToken<ArrayList<ClerkDO>>(){}.type
+                val clerkList = gson.fromJson<ArrayList<ClerkDO>>(data, itemType)
+
+                return@map clerkList
+            }
+            .compose(ThreadFromUtils.defaultSchedulers())
+            .subscribe(observable3)
+    }
 }

+ 43 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/utils/ScreenUtils.java

@@ -0,0 +1,43 @@
+package com.wdkl.ncs.android.middleware.utils;
+
+import android.content.Context;
+import android.util.DisplayMetrics;
+import android.view.WindowManager;
+
+public class ScreenUtils {
+    public static int getScreenHeight(Context context) {
+        DisplayMetrics metric = new DisplayMetrics();
+        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+        wm.getDefaultDisplay().getMetrics(metric);
+        return metric.heightPixels;
+    }
+
+    public static int getScreenWidth(Context context) {
+        DisplayMetrics metric = new DisplayMetrics();
+        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+        wm.getDefaultDisplay().getMetrics(metric);
+        return metric.widthPixels;
+    }
+
+    /**
+     * px转dp
+     * @param context
+     * @param pxValue
+     * @return
+     */
+    public static int px2dp(Context context, float pxValue){
+        float density = context.getResources().getDisplayMetrics().density;//得到设备的密度
+        return (int) (pxValue/density+0.5f);
+    }
+
+    /**
+     * dp转px
+     * @param context
+     * @param dpValue
+     * @return
+     */
+    public static int dp2px(Context context, float dpValue){
+        float density = context.getResources().getDisplayMetrics().density;
+        return (int) (dpValue*density+0.5f);
+    }
+}

+ 6 - 0
resource/src/main/res/drawable/shape_password_bt_bg.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#97A2BE" />
+    <corners
+        android:radius="18dp"/>
+</shape>

BIN
resource/src/main/res/mipmap-mdpi/ic_record_normal.png


BIN
resource/src/main/res/mipmap-mdpi/ic_record_press.png


+ 17 - 0
resource/src/main/res/values-es/strings.xml

@@ -164,6 +164,11 @@
     <string name="str_trusteeship">Tutela</string>
     <string name="str_led">LED</string>
     <string name="str_note_message">Message</string>
+    <string name="str_add_message">Add message</string>
+    <string name="str_message_type">Message type:</string>
+    <string name="str_text_message">Text</string>
+    <string name="str_voice_message">Voice</string>
+    <string name="str_message_creator">Creator:</string>
     <string name="str_nb_iot">Dispositivo IoT</string>
     <string name="str_offline_device">Dispositivo fuera de línea</string>
     <string name="str_low_battery_device">Bateria baja en dispositivo</string>
@@ -278,6 +283,18 @@
     <string name="broadcast_playing">Transmitiendo…</string>
     <string name="broadcast_stop">Detener transmisión</string>
 
+    <string name="str_voice_msg_btn_title">Suelte para guardar el mensaje</string>
+    <string name="str_voice_msg_btn_text">Presione para grabar el mensaje</string>
+    <string name="str_voice_msg_record_loss">El tiempo es demasiado corto</string>
+    <string name="str_voice_msg_record_cancel">Mensaje de voz cancelado</string>
+    <string name="str_empty_voice_msg">No voice message</string>
+    <string name="str_delete_tip">Delete?</string>
+    <string name="str_message_content_error">Invalid message</string>
+    <string name="str_voice_message_invalid">Invalid voice message</string>
+    <string name="str_message_save_success">Success!</string>
+    <string name="str_record_message_success">Record success!</string>
+    <string name="str_invalid_creator_name">Please select creator</string>
+
     <string name="str_warning">Advertencia</string>
     <string name="str_fall_alarm">Alarma de caída</string>
     <string name="none_warning">Sin alertas</string>

+ 17 - 0
resource/src/main/res/values-ru/strings.xml

@@ -165,6 +165,11 @@
     <string name="str_trusteeship">Доверительное управление</string>
     <string name="str_led">светодиод</string>
     <string name="str_note_message">Message</string>
+    <string name="str_add_message">Add message</string>
+    <string name="str_message_type">Message type:</string>
+    <string name="str_text_message">Text</string>
+    <string name="str_voice_message">Voice</string>
+    <string name="str_message_creator">Creator:</string>
     <string name="str_nb_iot">IoT device</string>
     <string name="str_offline_device">Offline device</string>
     <string name="str_low_battery_device">Low battery device</string>
@@ -280,6 +285,18 @@
     <string name="broadcast_playing">Broadcast playing…</string>
     <string name="broadcast_stop">Broadcast stop</string>
 
+    <string name="str_voice_msg_btn_title">Отпустите, чтобы сохранить сообщение</string>
+    <string name="str_voice_msg_btn_text">Нажмите, чтобы записать сообщение</string>
+    <string name="str_voice_msg_record_loss">слишком мало времени</string>
+    <string name="str_voice_msg_record_cancel">Голосовое сообщение отменено</string>
+    <string name="str_empty_voice_msg">No voice message</string>
+    <string name="str_delete_tip">Delete?</string>
+    <string name="str_message_content_error">Invalid message</string>
+    <string name="str_voice_message_invalid">Invalid voice message</string>
+    <string name="str_message_save_success">Success!</string>
+    <string name="str_record_message_success">Record success!</string>
+    <string name="str_invalid_creator_name">Please select creator</string>
+
     <string name="str_warning">тревога</string>
     <string name="str_fall_alarm">fall alarm</string>
     <string name="none_warning">Никто не предупреждает</string>

+ 17 - 0
resource/src/main/res/values-zh/strings.xml

@@ -166,6 +166,11 @@
     <string name="str_trusteeship">托管</string>
     <string name="str_led">点阵屏</string>
     <string name="str_note_message">留言</string>
+    <string name="str_add_message">添加留言</string>
+    <string name="str_message_type">留言类型:</string>
+    <string name="str_text_message">文本</string>
+    <string name="str_voice_message">语音</string>
+    <string name="str_message_creator">创建人:</string>
     <string name="str_nb_iot">IoT设备</string>
     <string name="str_offline_device">离线设备</string>
     <string name="str_low_battery_device">低电设备</string>
@@ -203,6 +208,18 @@
     <string name="broadcast_playing">正在广播…</string>
     <string name="broadcast_stop">广播已停止</string>
 
+    <string name="str_voice_msg_btn_title">松开保存,滑动取消</string>
+    <string name="str_voice_msg_btn_text">按住说话</string>
+    <string name="str_voice_msg_record_loss">说话时间太短</string>
+    <string name="str_voice_msg_record_cancel">语音留言已取消</string>
+    <string name="str_empty_voice_msg">未录制语音</string>
+    <string name="str_delete_tip">确认删除?</string>
+    <string name="str_message_content_error">留言内容为空</string>
+    <string name="str_voice_message_invalid">语音留言文件无效</string>
+    <string name="str_message_save_success">留言成功!</string>
+    <string name="str_record_message_success">语音录制成功!</string>
+    <string name="str_invalid_creator_name">请先选择创建人</string>
+
     <string name="setting_day_night_time">白天-晚上时间设置</string>
     <string name="setting_call_type">播报模式:</string>
     <string name="setting_call_type_tts">TTS</string>

+ 17 - 0
resource/src/main/res/values/strings.xml

@@ -166,6 +166,11 @@
     <string name="str_trusteeship">Trusteeship</string>
     <string name="str_led">LED</string>
     <string name="str_note_message">Message</string>
+    <string name="str_add_message">Add message</string>
+    <string name="str_message_type">Message type:</string>
+    <string name="str_text_message">Text</string>
+    <string name="str_voice_message">Voice</string>
+    <string name="str_message_creator">Creator:</string>
     <string name="str_nb_iot">IoT device</string>
     <string name="str_offline_device">Offline device</string>
     <string name="str_low_battery_device">Low battery device</string>
@@ -203,6 +208,18 @@
     <string name="broadcast_playing">Broadcast playing…</string>
     <string name="broadcast_stop">Broadcast stop</string>
 
+    <string name="str_voice_msg_btn_title">Release to save message</string>
+    <string name="str_voice_msg_btn_text">Press to record message</string>
+    <string name="str_voice_msg_record_loss">time is too short</string>
+    <string name="str_voice_msg_record_cancel">Voice message canceled</string>
+    <string name="str_empty_voice_msg">No voice message</string>
+    <string name="str_delete_tip">Delete?</string>
+    <string name="str_message_content_error">Invalid message</string>
+    <string name="str_voice_message_invalid">Invalid voice message</string>
+    <string name="str_message_save_success">Success!</string>
+    <string name="str_record_message_success">Record success!</string>
+    <string name="str_invalid_creator_name">Please select creator</string>
+
     <string name="setting_day_night_time">Day-night time set</string>
     <string name="setting_call_type">Call type:</string>
     <string name="setting_call_type_tts">TTS</string>

+ 6 - 0
resource/src/main/res/values/styles.xml

@@ -33,4 +33,10 @@
         <item name="android:autoSizeMaxTextSize" tools:targetApi="o">20sp</item>
         <item name="android:autoSizeStepGranularity" tools:targetApi="o">2sp</item>
     </style>
+
+    <style name="Theme.AppCompat.Translucent" parent="Theme.AppCompat.NoActionBar">
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowTranslucentStatus">true</item>
+    </style>
 </resources>