Browse Source

增加大朝华15.6寸主机NFC刷卡解锁

weizhengliang 8 months ago
parent
commit
61857c0664

+ 1 - 0
android_host/src/main/h10_wke_1h/AndroidManifest.xml

@@ -57,6 +57,7 @@
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
     <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
+    <uses-permission android:name="android.permission.NFC" />
 
     <!-- Needed for full screen intent in incoming call notifications -->
     <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />

+ 15 - 4
android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/activity/AppUpdateActivity.kt

@@ -12,12 +12,9 @@ import com.wdkl.ncs.android.middleware.common.Constants
 import com.wdkl.ncs.android.component.nursehome.databinding.UpdateLayBinding
 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.AppUpdateHelper
+import com.wdkl.ncs.android.component.nursehome.util.*
 import com.wdkl.ncs.android.component.nursehome.util.AppUpdateHelper.FILE_APK_NAME
 import com.wdkl.ncs.android.component.nursehome.util.AppUpdateHelper.FILE_APK_PATH
-import com.wdkl.ncs.android.component.nursehome.util.HttpHelper
-import com.wdkl.ncs.android.component.nursehome.util.LocaleMangerUtils
-import com.wdkl.ncs.android.component.nursehome.util.StatusBarHelper
 import com.wdkl.ncs.android.lib.base.BaseActivity
 import com.wdkl.ncs.android.lib.utils.showMessage
 import com.wdkl.ncs.android.lib.vo.filter
@@ -83,6 +80,20 @@ class AppUpdateActivity :BaseActivity<AppUpdatePresenter, UpdateLayBinding>(), A
         }
     }
 
+    override fun onResume() {
+        super.onResume()
+
+        if (NfcUtils.getInstance().isNfcEnabled) {
+            NfcUtils.getInstance().NfcOnResume(this)
+        }
+    }
+
+    override fun onPause() {
+        super.onPause()
+
+        NfcUtils.getInstance().clear(this)
+    }
+
     /**
      * 下载APK包
      */

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

@@ -17,6 +17,7 @@ import com.wdkl.ncs.android.component.nursehome.databinding.MessageCreateDialogA
 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.NfcUtils
 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
@@ -98,6 +99,20 @@ class CreateMessageActivity : BaseActivity<MessagePresenter, MessageCreateDialog
         }
     }
 
+    override fun onResume() {
+        super.onResume()
+
+        if (NfcUtils.getInstance().isNfcEnabled) {
+            NfcUtils.getInstance().NfcOnResume(this)
+        }
+    }
+
+    override fun onPause() {
+        super.onPause()
+
+        NfcUtils.getInstance().clear(this)
+    }
+
     @SuppressLint("ClickableViewAccessibility")
     override fun bindEvent() {
         btn_add_cancel.setOnClickListener {

+ 118 - 4
android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/activity/LockScreenActivity.kt

@@ -1,8 +1,15 @@
 package com.wdkl.ncs.android.component.nursehome.activity
 
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.nfc.NfcAdapter
+import android.nfc.Tag
 import android.support.v7.widget.RecyclerView
 import android.support.v7.widget.helper.ItemTouchHelper
 import android.util.Log
+import android.view.KeyEvent
 import android.view.View
 import com.alibaba.android.vlayout.VirtualLayoutManager
 import com.enation.javashop.net.engine.model.NetState
@@ -10,6 +17,7 @@ import com.wdkl.ncs.android.component.nursehome.R
 import com.wdkl.ncs.android.component.nursehome.adapter.IncomingCallAdapter
 import com.wdkl.ncs.android.component.nursehome.databinding.LockScreenActivityBinding
 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.*
 import com.wdkl.ncs.android.lib.base.BaseActivity
 import com.wdkl.ncs.android.lib.base.BaseApplication
@@ -20,6 +28,7 @@ import com.wdkl.ncs.android.middleware.logic.presenter.nursehome.DevicePresenter
 import com.wdkl.ncs.android.middleware.model.PhoneBookItem
 import com.wdkl.ncs.android.middleware.model.vo.ClerkVO
 import com.wdkl.ncs.android.middleware.model.vo.NurseDeviceInfoVO
+import com.wdkl.ncs.android.middleware.tcp.channel.DeviceChannel
 import com.wdkl.ncs.android.middleware.utils.MessageEvent
 import kotlinx.android.synthetic.main.lock_screen_activity.*
 import org.greenrobot.eventbus.EventBus
@@ -27,10 +36,15 @@ import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
 import serialporttest.utils.StringUtils
 
-class LockScreenActivity : BaseActivity<DevicePresenter, LockScreenActivityBinding>(), DeviceContract.View, IncomingCallAdapter.UpdateCallback {
+class LockScreenActivity : BaseActivity<DevicePresenter, LockScreenActivityBinding>(), DeviceContract.View,
+    IncomingCallAdapter.UpdateCallback, NfcUtils.OnReadFromNdefListener {
     val TAG = LockScreenActivity::class.java.simpleName
 
     private var incomingCallAdapter: IncomingCallAdapter? = null
+    private var hookoffTime: Long = 0
+    private var hookonTime: Long = 0
+
+    private var nfcTagBroadcastReceiver: BroadcastReceiver? = null
 
     override fun getLayId(): Int {
         return R.layout.lock_screen_activity
@@ -45,6 +59,28 @@ class LockScreenActivity : BaseActivity<DevicePresenter, LockScreenActivityBindi
         lock_incoming_call_list.layoutManager = VirtualLayoutManager(activity)
         lock_incoming_call_list.adapter = incomingCallAdapter
 
+        NfcUtils.getInstance().setReadNdefListener(this)
+
+        nfcTagBroadcastReceiver = object : BroadcastReceiver() {
+            override fun onReceive(context: Context, intent: Intent) {
+                try {
+                    Log.d(TAG, "收到NFC广播")
+                    val tag: Tag? = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
+                    val hexNo = StringUtils.bytesToHex(tag?.getId())
+                    val decNo = StringUtils.bytesToTenNum(hexNo)
+
+                    Log.d(TAG, "nfc hexNo: $hexNo, decNo: $decNo")
+                    checkClerkValid(hexNo)
+
+                    //val s: String =  NfcUtils.getInstance().readMifareClassic(intent)
+                    //Log.i(TAG, "NFC 卡数据: $s")
+                } catch (e: Exception) {
+                    e.printStackTrace()
+                }
+            }
+        }
+        registerReceiver(nfcTagBroadcastReceiver, IntentFilter("NFC_DISCOVERYED"))
+
         val touchCallback: ItemTouchHelper.Callback =
             object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
                 override fun onMove(
@@ -101,6 +137,20 @@ class LockScreenActivity : BaseActivity<DevicePresenter, LockScreenActivityBindi
         }
     }
 
+    override fun onResume() {
+        super.onResume()
+
+        if (NfcUtils.getInstance().isNfcEnabled) {
+            NfcUtils.getInstance().NfcOnResume(this)
+        }
+    }
+
+    override fun onPause() {
+        super.onPause()
+
+        NfcUtils.getInstance().clear(this)
+    }
+
     override fun onStop() {
         super.onStop()
 
@@ -109,6 +159,10 @@ class LockScreenActivity : BaseActivity<DevicePresenter, LockScreenActivityBindi
 
     override fun destory() {
         Constants.showLock = false
+
+        if (nfcTagBroadcastReceiver != null) {
+            unregisterReceiver(nfcTagBroadcastReceiver)
+        }
     }
 
     override fun onBackPressed() {
@@ -153,6 +207,52 @@ class LockScreenActivity : BaseActivity<DevicePresenter, LockScreenActivityBindi
         //
     }
 
+    //大朝华15.6寸主机按键监听
+    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
+        Log.d(TAG, "keyDown ====> keyCode: $keyCode, action: ${event?.action}")
+        if (keyCode == 135 || keyCode == 139) {
+            //手柄拿起
+            Constants.hookOn = false
+            VoiceManagerUtil.setCallVoice(activity, SettingConfig.getHostCallVolume(activity))
+
+            if (System.currentTimeMillis() - hookoffTime > 2000) {
+                if (Constants.CALL_STATE == Constants.CALL_STANDBY) {
+                    //不是呼出也不是通话状态则接听电话
+                    EventBus.getDefault().post(MessageEvent("hookoff", Constants.EVENT_HOOK_OFF))
+                } else if (Constants.CALL_STATE == Constants.CALL_VISITING || Constants.CALL_STATE == Constants.CALL_V_INCOMING) {
+                    EventBus.getDefault().post(MessageEvent("hookoff", Constants.EVENT_V_HOOK_OFF))
+                }
+            }
+
+            EventBus.getDefault().post(MessageEvent(false, Constants.EVENT_TOGGLE_SPEAKER))
+            VoiceManagerUtil.switchAudioMode(activity, false)
+            hookoffTime = System.currentTimeMillis()
+        } else if (keyCode == 134 || keyCode == 138) {
+            //手柄放下
+            Constants.hookOn = true
+            VoiceManagerUtil.setCallVoice(activity, SettingConfig.getHostCallVolume(activity))
+
+            if (System.currentTimeMillis() - hookonTime > 2000) {
+                if (Constants.CALL_STATE == Constants.CALL_OUTGOING) {
+                    //呼出取消
+                    Constants.CALL_STATE = Constants.CALL_STANDBY
+                    DeviceChannel.calling = false
+                    EventBus.getDefault().post(MessageEvent("cancel", Constants.EVENT_END_CALL))
+                } else if (Constants.CALL_STATE == Constants.CALL_CALLING) {
+                    Constants.CALL_STATE = Constants.CALL_STANDBY
+                    DeviceChannel.calling = false
+                    EventBus.getDefault().post(MessageEvent("handoff", Constants.EVENT_END_CALL))
+                }
+                EventBus.getDefault().post(MessageEvent("hookon", Constants.EVENT_HOOK_ON))
+            }
+
+            EventBus.getDefault().post(MessageEvent(true, Constants.EVENT_TOGGLE_SPEAKER))
+            VoiceManagerUtil.switchAudioMode(activity, true)
+            hookonTime = System.currentTimeMillis()
+        }
+        return super.onKeyDown(keyCode, event)
+    }
+
     @Subscribe(threadMode = ThreadMode.MAIN)
     fun onMoonEvent(messageEvent: MessageEvent) {
         when (messageEvent.getType()) {
@@ -171,13 +271,17 @@ class LockScreenActivity : BaseActivity<DevicePresenter, LockScreenActivityBindi
                 val decNo = StringUtils.bytesToTenNum(hexNo)
 
                 Log.d(TAG, "nfc hexNo: $hexNo, decNo: $decNo, lock screen focused: " + hasWindowFocus())
-                if (hasWindowFocus()) {
-                    presenter.checkClerk(Constants.part_id, hexNo)
-                }
+                checkClerkValid(hexNo)
             }
         }
     }
 
+    private fun checkClerkValid(hexNo: String) {
+        if (hasWindowFocus()) {
+            presenter.checkClerk(Constants.part_id, hexNo)
+        }
+    }
+
     override fun onUpdateCalls() {
         if (Constants.callingList.size == 0) {
             ll_incoming_call.visibility = View.GONE
@@ -185,4 +289,14 @@ class LockScreenActivity : BaseActivity<DevicePresenter, LockScreenActivityBindi
             ll_incoming_call.visibility = View.VISIBLE
         }
     }
+
+    override fun Readsuccessfully(id: String?) {
+        //
+    }
+
+    override fun readFail() {
+        runOnUiThread {
+            showMessage("NFC read fail")
+        }
+    }
 }

+ 10 - 4
android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/activity/NurseHomeActivity.kt

@@ -63,7 +63,6 @@ import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
 import com.wdkl.ncs.android.middleware.model.vo.NurseDeviceInfoVO
 import com.wdkl.ncs.android.middleware.tcp.TcpClient
 import com.wdkl.ncs.android.middleware.tcp.channel.*
-import com.wdkl.ncs.android.middleware.tcp.dto.TcpCallback
 import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel
 import com.wdkl.ncs.android.middleware.tcp.enums.DeviceTypeEnum
 import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction
@@ -75,7 +74,6 @@ import com.wdkl.ncs.android.middleware.utils.StringUtil
 import com.wdkl.ncs.host.activity.CallActivity
 import com.wdkl.ncs.host.sip.callback.PhoneCallback
 import com.wdkl.ncs.host.sip.core.LinphoneManager
-//import com.wdkl.ncs.host.service.WdklSipService
 import com.wdkl.ncs.janus.util.JanusConstant
 import io.reactivex.Observable
 import kotlinx.android.synthetic.main.activity_nurse_home.*
@@ -85,14 +83,12 @@ import org.freedesktop.gstreamer.GStreamer
 import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
-import org.linphone.core.AccountCreator
 import org.linphone.core.Call
 import org.linphone.core.RegistrationState
 import org.linphone.core.TransportType
 import java.io.File
 import java.io.FileOutputStream
 import java.io.InputStream
-import java.net.InetAddress
 import java.util.*
 import java.util.concurrent.Executors
 import java.util.concurrent.ScheduledExecutorService
@@ -733,6 +729,10 @@ class NurseHomeActivity: BaseActivity<NurseHomeActivityPresenter, ActivityNurseH
         super.onResume()
         updateTcpState()
 
+        if (NfcUtils.getInstance().isNfcEnabled) {
+            NfcUtils.getInstance().NfcOnResume(this)
+        }
+
         if (initialized && Settings.canDrawOverlays(this) && Settings.System.canWrite(this))  {
             if (Build.BOARD.equals("k37tv1_64_bsp") || Build.BOARD.equals("k37mv1_64_bsp") || Build.MODEL.equals("KT10-3F") || "m3520b_bnkj_zx".equals(Build.MODEL)) {
                 StatusBarHelper.toggleStatusBar(activity, false)
@@ -746,6 +746,12 @@ class NurseHomeActivity: BaseActivity<NurseHomeActivityPresenter, ActivityNurseH
         }
     }
 
+    override fun onPause() {
+        super.onPause()
+
+        NfcUtils.getInstance().clear(this)
+    }
+
     override fun onStop() {
         super.onStop()
 

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

@@ -15,6 +15,7 @@ import com.wdkl.ncs.android.component.nursehome.databinding.TestActivityBinding
 import com.wdkl.ncs.android.component.nursehome.fragment.TestFragment
 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.NfcUtils
 import com.wdkl.ncs.android.component.nursehome.util.VoiceManagerUtil
 import com.wdkl.ncs.android.lib.base.BaseActivity
 import com.wdkl.ncs.android.middleware.common.Constants
@@ -53,6 +54,20 @@ class TestActivity : BaseActivity<DevicePresenter, TestActivityBinding>(), Devic
         switchFragment(R.id.test_frame, TestFragment(), "test_fragment")
     }
 
+    override fun onResume() {
+        super.onResume()
+
+        if (NfcUtils.getInstance().isNfcEnabled) {
+            NfcUtils.getInstance().NfcOnResume(this)
+        }
+    }
+
+    override fun onPause() {
+        super.onPause()
+
+        NfcUtils.getInstance().clear(this)
+    }
+
     override fun bindEvent() {
         //
     }

+ 1 - 1
android_host/src/main/h10_wke_1h/java/com/wdkl/ncs/android/component/nursehome/service/LockService.kt

@@ -160,7 +160,7 @@ class LockService : Service() {
 
         //悬浮框点击事件
         floatView?.setOnClickListener {
-            if (System.currentTimeMillis() - clickTime > 3000) {
+            if (System.currentTimeMillis() - clickTime > 2000) {
                 if (Constants.enableLock && !Constants.IN_CALL && !Constants.bcVoiceOn) {
                     //锁屏
                     EventBus.getDefault().post(MessageEvent(0, Constants.EVENT_SHOW_LOCK))

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

@@ -0,0 +1,435 @@
+package com.wdkl.ncs.android.component.nursehome.util;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.nfc.FormatException;
+import android.nfc.NdefMessage;
+import android.nfc.NdefRecord;
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.nfc.tech.MifareClassic;
+import android.nfc.tech.Ndef;
+import android.util.Log;
+
+import com.wdkl.ncs.android.component.nursehome.activity.NurseHomeActivity;
+import com.wdkl.ncs.android.lib.base.BaseApplication;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * NFC 相关的工具类
+ * SDK 最低版本为 14
+ * 参考 https://github.com/albert-lii/SUtils/blob/master/sutils/src/main/java/com/liyi/sutils/utils/NfcUtil.java
+ * @author xzy
+ */
+
+@SuppressWarnings("all")
+public class NfcUtils {
+    private static final String TAG = "NfcUtils";
+    /* NFC 适配器 */
+    private NfcAdapter mAdapter;
+    PendingIntent pIntent;
+    /* NDEF 标签读取监听 */
+    private OnReadFromNdefListener mReadNdefListener;
+    /* NDEF 标签写入监听 */
+    private OnWriteToNdefListener mWriteNdefListener;
+    /* NDEF 标签删除监听 */
+    private OnDeleteNdefListener mDeleteNdefListener;
+
+    public static NfcUtils getInstance() {
+        return NfcUtilsHolder.INSTANCE;
+    }
+
+    private static final class NfcUtilsHolder {
+        private static final NfcUtils INSTANCE = new NfcUtils();
+    }
+
+    private NfcUtils() {
+        mAdapter = NfcAdapter.getDefaultAdapter(BaseApplication.appContext);
+        pIntent = PendingIntent.getBroadcast(BaseApplication.appContext, 0,
+                //在Manifest里或者这里设置当前activity启动模式,否则每次向阳NFC事件,activity会重复创建
+                // 当然也要按照具体情况来,你设置成singleTask也不是不行,
+                new Intent("NFC_DISCOVERYED"),
+                PendingIntent.FLAG_UPDATE_CURRENT);
+    }
+
+    /**
+     * 判断设备是否支持 NFC 功能
+     *
+     * @return {@code true}: 支持<br>{@code false}: 不支持
+     */
+    public boolean isSupportNfc() {
+        return mAdapter != null;
+    }
+
+    /**
+     * 是否已经打开 NFC 功能
+     *
+     * @return {@code true}: 已经打开<br>{@code false}: 未打开
+     */
+    public boolean isNfcEnabled() {
+        if (mAdapter != null && mAdapter.isEnabled()) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 判断是否有 NFC 相关的 intent
+     * <p>
+     * <p>NDEF_DISCOVERED: 只过滤固定格式的 NDEF 数据,例如:纯文本、指定协议(http、ftp、smb等)的URI等</p>
+     * <p>
+     * <p>TECH_DISCOVERED: 当 ACTION_NDEF_DISCOVERED 指定的过滤机制无法匹配 Tag 时,就会使用这种过滤机制进行
+     * 匹配,
+     * <p>这种过滤机制并不是通过 Tag 中的数据格式进行匹配的,而是根据 Tag 支持的数据存储格式进行匹配,
+     * <p>因此这种过滤机制的范围更广</p>
+     * <p>
+     * <p>TAG_DISCOVERED: 当前面两种过滤机制都匹配失败后,系统就会利用这种过滤机制来处理,
+     * <p>这种过滤机制用来处理未识别的 Tag(数据格式不对,而且 Tag 支持的格式也不匹配)</p>
+     *
+     * @param intent
+     */
+    public boolean isHasNfcIntent(Intent intent) {
+        boolean isHasIntent = false;
+        // NFC 的三重过滤机制
+        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())
+                || NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())
+                || NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
+            isHasIntent = true;
+        }
+        return isHasIntent;
+    }
+
+    /**
+     * 获取 NFC 的适配器
+     *
+     * @return NfcAdapter
+     */
+    public NfcAdapter getNfcAdapter() {
+        if (mAdapter == null) {
+            mAdapter = NfcAdapter.getDefaultAdapter(BaseApplication.appContext);
+        }
+        return mAdapter;
+    }
+
+    public void NfcOnResume(Activity activity){
+        if (mAdapter == null) {
+            mAdapter = getNfcAdapter();
+        }
+
+        //添加intent-filter
+        IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
+        IntentFilter tag = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
+        IntentFilter tech = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
+        IntentFilter[] filters = new IntentFilter[]{ndef, tag, tech};
+        //添加 ACTION_TECH_DISCOVERED 情况下所能读取的NFC格式,这里列的比较全,实际我这里是没有用到的,因为测试的卡是NDEF的
+        String[][] techList = new String[][]{
+                new String[]{
+                        "android.nfc.tech.Ndef",
+                        "android.nfc.tech.NfcA",
+                        "android.nfc.tech.NfcB",
+                        "android.nfc.tech.NfcF",
+                        "android.nfc.tech.NfcV",
+                        "android.nfc.tech.NdefFormatable",
+                        "android.nfc.tech.MifareClassic",
+                        "android.nfc.tech.MifareUltralight",
+                        "android.nfc.tech.NfcBarcode"
+                }
+        };
+
+        if (mAdapter != null) {
+            mAdapter.enableForegroundDispatch(activity, pIntent, filters, techList);
+        }
+    }
+
+    public String readMifareClassic(Intent intent) {
+
+        String info = "";
+        List<byte[]> list = new ArrayList<>();
+        boolean auth = false;
+        //读取TAG
+        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
+        MifareClassic mfc = MifareClassic.get(tag);
+        if (tag != null){
+            try {
+                mfc.connect();
+                if (mfc.isConnected()) {
+                    int sectorCount = mfc.getSectorCount();//获取TAG中包含的扇区数
+                    if(sectorCount==16){
+                        int bindex = mfc.sectorToBlock(1);
+                        auth = mfc.authenticateSectorWithKeyA(1,
+                                MifareClassic.KEY_DEFAULT);
+                        if(auth){
+                            byte[] data = mfc.readBlock(bindex+1);
+                            info = new String(data, Charset.forName("utf-8"));
+                            Log.e(TAG, "读取写入的数据: "+info );
+                            if (mReadNdefListener != null) {
+                                mReadNdefListener.Readsuccessfully(info);
+                            }
+                            return info;
+
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                Log.e(TAG, e.getMessage());
+                if (mReadNdefListener != null) {
+                    mReadNdefListener.readFail();
+                }
+            } finally {
+                try {
+                    mfc.close();
+                } catch (IOException e) {
+                    Log.e(TAG, e.getMessage());
+                    if (mReadNdefListener != null) {
+                        mReadNdefListener.readFail();
+                    }
+                }
+            }
+        }else {
+            if (mReadNdefListener != null) {
+                mReadNdefListener.readFail();
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * 从 NDEF 标签中读取数据
+     *
+     * @param tag
+     * @return 读取到的标签信息
+     */
+    public String readFromNdef(Tag tag) {
+        try {
+            if (tag != null) {
+                // 解析 Tag 获取到 NDEF 实例
+                Ndef ndef = Ndef.get(tag);
+                // 打开连接
+                ndef.connect();
+                // 获取 NDEF 消息
+                NdefMessage message = null;
+                try {
+                    message = ndef.getNdefMessage();
+                } catch (FormatException e) {
+                    e.printStackTrace();
+                }
+                // 将消息转换成字节数组
+                byte[] data = Objects.requireNonNull(message).toByteArray();
+                // 将字节数组转换成字符串
+                String str = new String(data, Charset.forName("UTF-8"));
+                // 关闭连接
+                ndef.close();
+                return str;
+            } else {
+//                if (mReadNdefListener != null) {
+//                    mReadNdefListener.unConnect();
+//                }
+            }
+        } catch (IOException e) {
+            if (mReadNdefListener != null) {
+                mReadNdefListener.readFail();
+            }
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 向 NDEF 标签中写入信息
+     *
+     * @param tag
+     * @param ndefRecords
+     */
+    public void writeToNdef(Tag tag, NdefRecord[] ndefRecords) {
+        if (tag == null) {
+            return;
+        }
+        NdefMessage ndefMessage = new NdefMessage(ndefRecords);
+        // 获得写入大小
+        int size = ndefMessage.toByteArray().length;
+        // 判断是否是 NDEF 标签
+        try {
+            // 解析 TAG 获取到 NDEF 实例
+            Ndef ndef = Ndef.get(tag);
+            if (ndef != null) {
+                // 开始连接
+                ndef.connect();
+                // 判断是否可写
+                if (!ndef.isWritable()) {
+                    if (mWriteNdefListener != null) {
+                        mWriteNdefListener.unWritable();
+                    }
+                    return;
+                }
+                // 判断大小
+                if (ndef.getMaxSize() < size) {
+                    if (mWriteNdefListener != null) {
+                        mWriteNdefListener.sizeOver(ndef);
+                    }
+                    return;
+                }
+                // 写入NDEF信息
+                ndef.writeNdefMessage(ndefMessage);
+                // 关闭连接
+                ndef.close();
+            } else {
+//                if (mWriteNdefListener != null) {
+//                    mWriteNdefListener.;
+//                }
+            }
+        } catch (IOException e) {
+            if (mWriteNdefListener != null) {
+                mWriteNdefListener.writeFail();
+            }
+            e.printStackTrace();
+        } catch (FormatException e) {
+            if (mWriteNdefListener != null) {
+                mWriteNdefListener.writeFail();
+            }
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 删除 NDEF 标签中的信息
+     *
+     * @param tag
+     */
+    public void deleteNdef(Tag tag) {
+        try {
+            if (tag != null) {
+                // 新建一个里面无任何信息的 NdefRecord 实例
+                NdefRecord nullNdefRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA,
+                        new byte[]{}, new byte[]{}, new byte[]{});
+                NdefRecord[] records = {nullNdefRecord};
+                NdefMessage message = new NdefMessage(records);
+                // 解析 TAG 获取到 NDEF 实例
+                Ndef ndef = Ndef.get(tag);
+                // 打开连接
+                ndef.connect();
+                // 写入信息
+                ndef.writeNdefMessage(message);
+                // 关闭连接
+                ndef.close();
+            } else {
+                if (mDeleteNdefListener != null) {
+                    mDeleteNdefListener.unConnect();
+                }
+            }
+        } catch (IOException e) {
+            if (mDeleteNdefListener != null) {
+                mDeleteNdefListener.deleteFail();
+            }
+            e.printStackTrace();
+        } catch (FormatException e) {
+            if (mDeleteNdefListener != null) {
+                mDeleteNdefListener.deleteFail();
+            }
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 设置 NDEF 标签读取监听
+     *
+     * @param listener
+     */
+    public void setReadNdefListener(OnReadFromNdefListener listener) {
+        this.mReadNdefListener = listener;
+    }
+
+    /**
+     * 设置 NDEF 标签写入监听
+     *
+     * @param listener
+     */
+    public void setWriteNdefListener(OnWriteToNdefListener listener) {
+        this.mWriteNdefListener = listener;
+    }
+
+    /**
+     * 设置 NDEF 标签信息删除监听
+     *
+     * @param listener
+     */
+    public void setDeleteNdefListener(OnDeleteNdefListener listener) {
+        this.mDeleteNdefListener = listener;
+    }
+
+    /**
+     * 清除信息
+     */
+    public void clear(Activity activity) {
+        setReadNdefListener(null);
+        setWriteNdefListener(null);
+        setDeleteNdefListener(null);
+        if (mAdapter != null) {
+            mAdapter.disableForegroundDispatch(activity);
+        }
+    }
+
+    /**
+     * 从 NDEF 标签中读取数据监听
+     */
+    public interface OnReadFromNdefListener {
+        /**
+         *  读取成功
+         */
+        void Readsuccessfully(String id);
+        /**
+         * 读取失败
+         */
+        void readFail();
+    }
+
+    /**
+     * 向 NDEF 标签中写入数据监听
+     */
+    public interface OnWriteToNdefListener {
+
+        /**
+         * 没有连接成功
+         */
+        void Connect();
+
+        /**
+         * 当前设备不支持写入
+         */
+        void unWritable();
+
+        /**
+         * 要写入的信息容量大于标签支持的最大容量
+         *
+         * @param ndef
+         */
+        void sizeOver(Ndef ndef);
+
+        /**
+         * 写入失败
+         */
+        void writeFail();
+    }
+
+    /**
+     * 删除 NDEF 标签信息监听
+     */
+    public interface OnDeleteNdefListener {
+        /**
+         * 没有连接成功
+         */
+        void unConnect();
+
+        /**
+         * 删除失败
+         */
+        void deleteFail();
+    }
+}

+ 4 - 0
android_host/src/main/h10_wke_1h/port/AndroidManifest.xml

@@ -56,6 +56,10 @@
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
     <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
+    <uses-permission android:name="android.permission.NFC" />
+
+    <!-- Needed for full screen intent in incoming call notifications -->
+    <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
 
     <!--     设置屏幕亮度-->
     <uses-permission android:name="android.permission.CHANGE_CONFIGURATION"

+ 1 - 1
android_host/src/main/h10_z3128_1h/java/com/wdkl/ncs/android/component/nursehome/service/LockService.kt

@@ -160,7 +160,7 @@ class LockService : Service() {
 
         //悬浮框点击事件
         floatView?.setOnClickListener {
-            if (System.currentTimeMillis() - clickTime > 3000) {
+            if (System.currentTimeMillis() - clickTime > 2000) {
                 if (Constants.enableLock && !Constants.IN_CALL && !Constants.bcVoiceOn) {
                     //锁屏
                     EventBus.getDefault().post(MessageEvent(0, Constants.EVENT_SHOW_LOCK))

+ 14 - 5
nurseMainLib/src/main/java/serialporttest/utils/StringUtils.java

@@ -6,6 +6,7 @@ import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Bundle;
+import android.text.TextUtils;
 
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -1080,14 +1081,22 @@ public class StringUtils {
     }
 
     public static String bytesToHex(byte[] bytes) {
-        StringBuilder sb = new StringBuilder();
-        for (byte b : bytes) {
-            sb.append(String.format("%02x", b));
+        if (bytes != null) {
+            StringBuilder sb = new StringBuilder();
+            for (byte b : bytes) {
+                sb.append(String.format("%02x", b));
+            }
+            return sb.toString();
         }
-        return sb.toString();
+
+        return "";
     }
 
     public static Long bytesToTenNum(String src) {
-        return Long.valueOf(src, 16);
+        if (!TextUtils.isEmpty(src)) {
+            return Long.valueOf(src, 16);
+        }
+
+        return 0L;
     }
 }