weizhengliang 4 лет назад
Родитель
Сommit
661cd9410e

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

@@ -6,6 +6,7 @@ import com.enation.javashop.net.engine.config.NetEngineConfig
 import com.enation.javashop.net.engine.plugin.exception.RestfulExceptionInterceptor
 import com.enation.javashop.utils.base.config.BaseConfig
 import com.wdkl.app.ncs.callingbed.helper.NetHelper
+import serialporttest.utils.SerialPortUtil
 
 /**
  * @author LDD
@@ -83,5 +84,7 @@ class Application : BaseApplication() {
 
         //init net
         NetHelper.getInstance().init(applicationContext)
+        //open serial port
+        SerialPortUtil.getInstance().openSerialPort();
     }
 }

+ 1 - 0
bedlib/.gitignore

@@ -0,0 +1 @@
+/build

+ 23 - 0
bedlib/build.gradle

@@ -0,0 +1,23 @@
+apply plugin: 'com.android.library'
+
+android {
+    compileSdkVersion target_sdk_version
+    buildToolsVersion build_tools_version
+
+
+    buildTypes {
+        sourceSets {
+            main { jni.srcDirs = [] }
+        }
+    }
+
+}
+
+dependencies {
+    compile fileTree(dir: 'libs', include: ['*.jar'])
+    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+        exclude group: 'com.android.support', module: 'support-annotations'
+    })
+    compile 'com.android.support.constraint:constraint-layout:1.0.2'
+    testCompile 'junit:junit:4.12'
+}

+ 25 - 0
bedlib/proguard-rules.pro

@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in D:\android_studio\sdk_path/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile

+ 26 - 0
bedlib/src/androidTest/java/serialcommunication/wdkl/com/bedlib/ExampleInstrumentedTest.java

@@ -0,0 +1,26 @@
+package serialcommunication.wdkl.com.bedlib;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumentation test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() throws Exception {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getTargetContext();
+
+        assertEquals("serialcommunication.wdkl.com.bedlib.test", appContext.getPackageName());
+    }
+}

+ 10 - 0
bedlib/src/main/AndroidManifest.xml

@@ -0,0 +1,10 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+
+    package="serialcommunication.wdkl.com.bedlib">
+
+    <application android:allowBackup="true" android:label="@string/app_name"
+        android:supportsRtl="true">
+
+    </application>
+
+</manifest>

+ 74 - 0
bedlib/src/main/java/android_serialport_api/SerialPort.java

@@ -0,0 +1,74 @@
+package android_serialport_api;
+
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class SerialPort {
+
+    private static final String TAG = "SerialPort";
+    private FileDescriptor mFd;
+    private FileInputStream mFileInputStream;
+    private FileOutputStream mFileOutputStream;
+
+    public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {
+
+        //检查访问权限,如果没有读写权限,进行文件操作,修改文件访问权限
+        if (!device.canRead() || !device.canWrite()) {
+            try {
+                //通过挂载到linux的方式,修改文件的操作权限
+                Process su = Runtime.getRuntime().exec("/system/xbin/su");
+                String cmd = "chmod 777 " + device.getAbsolutePath() + "\n" + "exit\n";
+                su.getOutputStream().write(cmd.getBytes());
+
+                if ((su.waitFor() != 0) || !device.canRead() || !device.canWrite()) {
+                    throw new SecurityException();
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new SecurityException();
+            }
+        }
+
+        mFd = open(device.getAbsolutePath(), baudrate, flags);
+
+        if (mFd == null) {
+            Log.e(TAG, "native open returns null");
+            throw new IOException();
+        }
+
+        mFileInputStream = new FileInputStream(mFd);
+        mFileOutputStream = new FileOutputStream(mFd);
+    }
+
+    // Getters and setters
+    public InputStream getInputStream() {
+        return mFileInputStream;
+    }
+
+    public OutputStream getOutputStream() {
+        return mFileOutputStream;
+    }
+
+
+    // JNI(调用java本地接口,实现串口的打开和关闭)
+/**串口有五个重要的参数:串口设备名,波特率,检验位,数据位,停止位
+ 其中检验位一般默认位NONE,数据位一般默认为8,停止位默认为1*/
+    /**
+     * @param path     串口设备的据对路径
+     * @param baudrate 波特率
+     * @param flags    校验位
+     */
+    private native static FileDescriptor open(String path, int baudrate, int flags);
+    public native void close();
+
+    static {//加载jni下的C文件库
+        System.loadLibrary("serial_port");
+    }
+}

+ 499 - 0
bedlib/src/main/java/serialporttest/utils/SerialPortUtil.java

@@ -0,0 +1,499 @@
+package serialporttest.utils;
+
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import android_serialport_api.SerialPort;
+
+/**
+ * Created by Administrator on 2017/6/6.
+ */
+
+public class SerialPortUtil {
+    private String TAG = "SerialPortUtil";
+
+    public SerialPort serialPort = null;
+    public InputStream inputStream = null;
+    public OutputStream outputStream = null;
+
+    ISerialPortBedOnclickEvent onDataReceiveListener = null;
+    ISerialPortBedOnclickString onDataReceiveStringListener = null;
+    public boolean isOpenSerialPortUtil = false;
+    private static int length = 9;
+    private static byte[] KeyValue = new byte[length];
+
+    int DataIndex = 0;
+    int DataValue = -1;
+
+    public Thread receiveThread = null;
+
+    public static SerialPortUtil instance = null;
+
+    public Timer timer ;
+    public TimerTask timerTask ;
+
+    public SerialPortUtil() {
+    }
+
+    public static SerialPortUtil getInstance() {
+        if (instance == null) {
+            synchronized (SerialPortUtil.class) {
+                if (instance == null) {
+                    instance = new SerialPortUtil();
+                }
+            }
+        }
+        return instance;
+    }
+
+    /**
+     * 打开串口的方法
+     */
+    public void openSerialPort() {
+        Log.i(TAG, "打开串口");
+        try {
+            serialPort = new SerialPort(new File("/dev/" + getSystemPort()), getSystemBaudrate(), 0);
+            //获取打开的串口中的输入输出流,以便于串口数据的收发
+            inputStream = serialPort.getInputStream();
+            outputStream = serialPort.getOutputStream();
+            isOpenSerialPortUtil = true;
+            receiveSerialPort();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 接收串口数据的方法
+     */
+    private byte[] buffer;
+    private String data;
+
+    public byte[] re_buffer = new byte[2048];
+    String data1 = "";
+    public int writeIndex = 0, readIndex = 0;
+    public boolean finshFlag = false;
+
+    /**
+     * 请求设备维一序列号(设备 ID)
+     */
+    public static String KEY_ID = "";
+
+    public void receiveSerialPort() {
+        initKeyValue();
+        Log.i(TAG, "接收串口数据");
+        if (receiveThread != null)
+            return;
+        buffer = new byte[1024];
+        receiveThread = new Thread() {
+            @Override
+            public void run() {
+                while (isOpenSerialPortUtil) {
+                    try {
+                        if (inputStream == null) {
+                            return;
+                        }
+                        int size = inputStream.read(buffer);
+                        if (size > 0 && isOpenSerialPortUtil) {
+                            data = new String(buffer, 0, size);
+                            Log.d("aaaa", "data==" + data);
+
+                            if (systemVersionIsO()) {//安卓7.0.1 or 8.1.0 版用
+                                //addByData(data);//my do
+                                changeData(size);//吴总改了后的
+                            } else {//安卓4.2.0 版用
+                                sendData(data);
+                            }
+
+                        }
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        };
+        //启动接收线程
+        receiveThread.start();
+    }
+
+    String addData = "";
+
+    public synchronized void addByData(String data) {
+        addData = addData + data;
+        if (StringUtils.vagueInquiry(data, "$") && StringUtils.vagueInquiry(data, "#")) {
+            sendData(addData);
+            addData = "";
+        }
+    }
+
+    public void changeData(int size) {
+        if (size > 0) {
+            for (int i = 0; i < size; i++) {
+                re_buffer[writeIndex] = buffer[i];
+                writeIndex++;
+                if (writeIndex > 2047) {
+                    writeIndex = 0;
+                }
+            }
+        }
+        if (readIndex != writeIndex) {
+            while (readIndex != writeIndex) {
+                if (re_buffer[readIndex] == '$') {
+                    data1 = "$";
+                    readIndex++;
+                    if (readIndex > 2047) {
+                        readIndex = 0;
+                    }
+                } else if (re_buffer[readIndex] == '#') {
+                    data1 = data1 + "#";
+                    readIndex++;
+                    if (readIndex > 2047) {
+                        readIndex = 0;
+                    }
+                    finshFlag = true;
+                    break;
+                } else if (data1.length() > 0) {
+                    data1 = data1 + new String(re_buffer, readIndex, 1);
+                    readIndex++;
+                    if (readIndex > 2047) {
+                        readIndex = 0;
+                    }
+                } else {
+                    readIndex++;
+                    if (readIndex > 2047) {
+                        readIndex = 0;
+                    }
+                }
+            }
+        }
+        if (finshFlag) {
+            sendData(data1);
+            data1 = "";
+            finshFlag = false;
+        }
+    }
+
+    public void sendData(String data) {
+        Log.d("bbbb", "data==" + data);
+        if (!StringUtils.notEmpty(data)) return;
+        if (isOpenSerialPortUtil) {
+            //reset data
+            DataIndex = 0;
+            DataValue = -1;
+            if (data.contains("ID")) {
+                String str = data.substring(data.indexOf(",") + 1, data.indexOf("1#"));
+                int i = 0;
+                while (i < 10) {
+                    if (str.length() > 4) {
+                        break;
+                    } else {
+                        try {
+                            Thread.sleep(100);
+                        } catch (InterruptedException e) {
+                            e.printStackTrace();
+                        }
+                        getKeyId();
+                        i++;
+                    }
+                }
+                Log.e(TAG, str);
+                KEY_ID = str;
+            } else {
+                if (data.contains("$") && data.contains("#")) {
+
+                    if (null != onDataReceiveStringListener) {//add by waderson 20190708
+                        onDataReceiveStringListener.serialPortBedOnclickString(data);
+                    }
+
+                    String str = data.substring(data.indexOf("$") + 1, data.indexOf("#"));
+                    if (TextUtils.isDigitsOnly(str.substring(3, 4)) && TextUtils.isDigitsOnly(str.substring(5, 6))) {
+                        DataIndex = Integer.parseInt(str.substring(3, 4));
+                        DataValue = Integer.parseInt(str.substring(5, 6));
+                    }
+                    if (DataIndex < length && DataIndex >= 0) {
+                        KeyValue[DataIndex] = (byte) DataValue;
+                    }
+                    if (null != onDataReceiveListener) {
+                        onDataReceiveListener.serialPortBedOnclick(KeyValue);
+                    }
+                    //======================================
+                    for (int i = 0; i < KeyValue.length; i++) {
+                        if (KeyValue[i] > 0) KeyValue[i] = -1;
+                    }
+                    //======================================
+                }
+            }
+
+        }
+    }
+
+    /**
+     * 判断是否是7.1以上的系统版本
+     *
+     * @return
+     */
+    public static boolean systemVersionIsO() {
+        if (android.os.Build.VERSION.SDK_INT >= 24) {//7.1以上的系统
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 关闭串口的方法
+     * 关闭串口中的输入输出流
+     * 然后将flag的值设为flag,终止接收数据线程
+     */
+    public void closeSerialPort() {
+        Log.i(TAG, "关闭串口");
+        try {
+            if (inputStream != null) {
+                inputStream.close();
+            }
+            if (outputStream != null) {
+                outputStream.close();
+            }
+            if (receiveThread != null && receiveThread.isAlive()) {
+                receiveThread.interrupt();
+                receiveThread = null;
+            }
+            isOpenSerialPortUtil = false;
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    //初始化 key值
+    public static void initKeyValue() {
+        KeyValue[0] = -1;
+        KeyValue[1] = -1;
+        KeyValue[2] = -1;
+        KeyValue[3] = -1;
+        KeyValue[4] = -1;
+        KeyValue[5] = -1;
+        KeyValue[6] = -1;
+        KeyValue[7] = -1;
+        KeyValue[8] = -1;
+    }
+
+    public void startHeartBeat() {
+        if (timer != null) timer.purge();
+        if (timerTask != null) timerTask.cancel();
+        timer = new Timer();
+        timerTask = new TimerTask() {
+            @Override
+            public void run() {
+                startHeart();
+            }
+        };
+        timer.schedule(timerTask, 0, 5000);
+    }
+
+    /**
+     * 心跳信号
+     */
+    public void startHeart() {
+        send("$HEART,1F#");
+    }
+
+    /**
+     * 关闭心跳<br>
+     * 若MCU在10秒内没有收到信号,将自动重启Android.  随机数为“W”时将关闭心跳<br>
+     */
+    public void closeHeart() {
+        send("$HEART,WE#");
+    }
+
+    /**
+     * 系统重启
+     */
+    public void systemRestart() {
+        send("$SYSRESET,2D#");
+        Log.i(TAG, "系统重启发送");
+    }
+
+    /*
+    * 进入系统ROM升级模式
+    * */
+    public void systemUpDate() {
+        Log.i(TAG, "系统ROM升级模式串口数据");
+        send("$SYSUPDATE,3C#");
+        Log.i(TAG, "系统ROM升级模式发送");
+
+    }
+
+
+    /**
+     * 发送串口数据的方法
+     *
+     * @param command 要发送的数据
+     */
+    private void send(String command) {
+        try {
+            if (isOpenSerialPortUtil) {
+                byte[] sendData = command.getBytes();
+                outputStream.write(sendData);
+                Log.d("NURSELIGHT","==command=="+"护理灯串口数据发送成功");
+                Log.i(TAG, "串口数据发送成功");
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+            Log.d("NURSELIGHT","==command=="+"护理灯串口数据发送失败");
+            Log.i(TAG, "串口数据发送失败");
+        }
+    }
+
+    public void setOnDataReceiveListener(ISerialPortBedOnclickEvent dataReceiveListener) {
+        onDataReceiveListener = dataReceiveListener;
+    }
+    public void setOnDataReceiveStringListener(ISerialPortBedOnclickString dataReceiveStringListener) {
+        onDataReceiveStringListener = dataReceiveStringListener;
+    }
+
+//    private void saveKeyValue() {
+//        if (timer != null) {
+//            timer.purge();
+//        }
+//        timer = new Timer();
+//
+//        if (timerTask != null) {
+//            timerTask.cancel();
+//        }
+//        timerTask = new TimerTask() {
+//            @Override
+//            public void run() {
+//                if (KeyValue[DataIndex] > 0) {
+//                    initKeyValue();
+//                }
+//            }
+//        };
+//        timer.schedule(timerTask, 10, mTimeInterval);
+//    }
+
+    public static int getSystemVersion() {
+        return android.os.Build.VERSION.SDK_INT;
+    }
+
+    public static String getSystemPort() {
+        String port;
+        if (getSystemVersion() >= 26) { //android8.0 = 26
+            port = "ttyS4";// rk3368 android8.1
+        } else if (getSystemVersion() >= 24) { //android7.0 = 24
+            port = "ttyS1";//rk3128 android7.1
+        } else {
+            port = "ttyS2";// a33 android4.4
+        }
+        return port;
+    }
+
+    /**
+     * 得到波特率
+     *
+     * @return String
+     */
+    public static int getSystemBaudrate() {
+        int baudrate;
+        if (getSystemVersion() >= 26) { //android8.0 = 26
+            baudrate = 115200;// rk3368 android8.1
+        } else if (getSystemVersion() >= 24) { //android7.0 = 24
+            baudrate = 115200;//rk3128 android7.1
+        } else {
+            baudrate = 115200;// a20 android4.2
+        }
+        return baudrate;
+    }
+
+
+    public interface ISerialPortBedOnclickEvent {
+        void serialPortBedOnclick(byte[] buffer);
+    }
+
+    public interface ISerialPortBedOnclickString {
+        void serialPortBedOnclickString(String str);
+    }
+
+    //------------------------below things was add by Waderson 20171106  -----------------------------------
+
+    public static final String C_HEARD = "$";//开头符
+    public static final String C_END = "#";//结束符
+    public static final String C_SEPARATE = ",";//分隔符
+
+    /**
+     * 手柄MIC切换<br>
+     */
+    public static final String MIC = "MIC";
+    /**
+     * 床头灯的切换<br> 0 关闭 1打开 2闪烁
+     */
+    public static final String BEDLIGHT = "RELAY";
+    /**
+     * 门灯控制开关
+     */
+    public static final String DOORLIGHT = "DOORLED";
+    /**
+     * 卫生间呼叫灯控制<br>
+     */
+    public static final String ULED = "ULED";
+    /**
+     * 护理灯光控制<br>
+     */
+    public static final String NURSELIGHT = "NLED";
+    /**
+     * 当前 SIP 协议状态<br>
+     */
+    public static final String SIP_STATUS = "SIP";
+    /**
+     * 呼叫状态<br>
+     */
+    public static final String CALL_STATUS = "CALL";
+    /**
+     * 网络状态<br>
+     */
+    public static final String NET_STATUS = "NETRESET";
+
+    /**
+     * 心跳控制<br>
+     * 若MCU在10秒内没有收到信号,将自动重启Android.  随机数为“W”时将关闭心跳<br>
+     * $ HEART ,1 E #  <br>
+     */
+
+    /**
+     * 写入串口<br>
+     * Waderson 20171103
+     * command  命令 <br>
+     * random   随机数<br>
+     * check  校验符<br>
+     */
+    public void sendCommand(String command, String random, String check) {//$NLED3,beComeDoublF#
+        String random_v = "1", check_v = "F";
+        if (null == command || "".equals(command)) {// beComeDoubleStr(rr) + beComeDoubleStr(gg) + beComeDoubleStr(bb), "F"
+            return;
+        }
+        if (null != random && !"".equals(random)) {
+            random_v = random;
+        }
+        if (null != check && !"".equals(check)) {
+            check_v = check;
+        }
+        Log.d("NURSELIGHT","=="+C_HEARD + command + C_SEPARATE + random_v + check_v + C_END);
+        send(C_HEARD + command + C_SEPARATE + random_v + check_v + C_END);
+    }
+
+    /**
+     * 请求设备维一序列号(设备 ID)
+     */
+    public void getKeyId() {
+        send("$ID,11#");
+    }
+
+
+}

Разница между файлами не показана из-за своего большого размера
+ 1081 - 0
bedlib/src/main/java/serialporttest/utils/StringUtils.java


+ 11 - 0
bedlib/src/main/jni/Android.mk

@@ -0,0 +1,11 @@
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+TARGET_PLATFORM := android-3
+LOCAL_MODULE    := serial_port
+LOCAL_SRC_FILES := SerialPort.c
+LOCAL_LDLIBS    := -llog
+
+include $(BUILD_SHARED_LIBRARY)

+ 1 - 0
bedlib/src/main/jni/Application.mk

@@ -0,0 +1 @@
+APP_ABI := armeabi armeabi-v7a x86

+ 167 - 0
bedlib/src/main/jni/SerialPort.c

@@ -0,0 +1,167 @@
+/*
+ * Copyright 2009-2011 Cedric Priscal
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <termios.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <jni.h>
+
+#include "SerialPort.h"
+
+#include "android/log.h"
+static const char *TAG="serial_port";
+#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO,  TAG, fmt, ##args)
+#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
+#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
+
+static speed_t getBaudrate(jint baudrate)
+{
+	switch(baudrate) {
+	case 0: return B0;
+	case 50: return B50;
+	case 75: return B75;
+	case 110: return B110;
+	case 134: return B134;
+	case 150: return B150;
+	case 200: return B200;
+	case 300: return B300;
+	case 600: return B600;
+	case 1200: return B1200;
+	case 1800: return B1800;
+	case 2400: return B2400;
+	case 4800: return B4800;
+	case 9600: return B9600;
+	case 19200: return B19200;
+	case 38400: return B38400;
+	case 57600: return B57600;
+	case 115200: return B115200;
+	case 230400: return B230400;
+	case 460800: return B460800;
+	case 500000: return B500000;
+	case 576000: return B576000;
+	case 921600: return B921600;
+	case 1000000: return B1000000;
+	case 1152000: return B1152000;
+	case 1500000: return B1500000;
+	case 2000000: return B2000000;
+	case 2500000: return B2500000;
+	case 3000000: return B3000000;
+	case 3500000: return B3500000;
+	case 4000000: return B4000000;
+	default: return -1;
+	}
+}
+
+/*
+ * Class:     android_serialport_SerialPort
+ * Method:    open
+ * Signature: (Ljava/lang/String;II)Ljava/io/FileDescriptor;
+ */
+JNIEXPORT jobject JNICALL Java_android_1serialport_1api_SerialPort_open
+  (JNIEnv *env, jclass thiz, jstring path, jint baudrate, jint flags)
+{
+	int fd;
+	speed_t speed;
+	jobject mFileDescriptor;
+
+	/* Check arguments */
+	{
+		speed = getBaudrate(baudrate);
+		if (speed == -1) {
+			/* TODO: throw an exception */
+			LOGE("Invalid baudrate");
+			return NULL;
+		}
+	}
+
+	/* Opening device */
+	{
+		jboolean iscopy;
+		const char *path_utf = (*env)->GetStringUTFChars(env, path, &iscopy);
+		LOGD("Opening serial port %s with flags 0x%x", path_utf, O_RDWR | flags);
+		fd = open(path_utf, O_RDWR | flags);
+		LOGD("open() fd = %d", fd);
+		(*env)->ReleaseStringUTFChars(env, path, path_utf);
+		if (fd == -1)
+		{
+			/* Throw an exception */
+			LOGE("Cannot open port");
+			/* TODO: throw an exception */
+			return NULL;
+		}
+	}
+
+	/* Configure device */
+	{
+		struct termios cfg;
+		LOGD("Configuring serial port");
+		if (tcgetattr(fd, &cfg))
+		{
+			LOGE("tcgetattr() failed");
+			close(fd);
+			/* TODO: throw an exception */
+			return NULL;
+		}
+
+		cfmakeraw(&cfg);
+		cfsetispeed(&cfg, speed);
+		cfsetospeed(&cfg, speed);
+
+		if (tcsetattr(fd, TCSANOW, &cfg))
+		{
+			LOGE("tcsetattr() failed");
+			close(fd);
+			/* TODO: throw an exception */
+			return NULL;
+		}
+	}
+
+	/* Create a corresponding file descriptor */
+	{
+		jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor");
+		jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "<init>", "()V");
+		jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I");
+		mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor);
+		(*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint)fd);
+	}
+
+	return mFileDescriptor;
+}
+
+/*
+ * Class:     cedric_serial_SerialPort
+ * Method:    close
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_android_1serialport_1api_SerialPort_close
+  (JNIEnv *env, jobject thiz)
+{
+	jclass SerialPortClass = (*env)->GetObjectClass(env, thiz);
+	jclass FileDescriptorClass = (*env)->FindClass(env, "java/io/FileDescriptor");
+
+	jfieldID mFdID = (*env)->GetFieldID(env, SerialPortClass, "mFd", "Ljava/io/FileDescriptor;");
+	jfieldID descriptorID = (*env)->GetFieldID(env, FileDescriptorClass, "descriptor", "I");
+
+	jobject mFd = (*env)->GetObjectField(env, thiz, mFdID);
+	jint descriptor = (*env)->GetIntField(env, mFd, descriptorID);
+
+	LOGD("close(fd = %d)", descriptor);
+	close(descriptor);
+}
+

+ 29 - 0
bedlib/src/main/jni/SerialPort.h

@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class android_serialport_api_SerialPort */
+
+#ifndef _Included_android_serialport_api_SerialPort
+#define _Included_android_serialport_api_SerialPort
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     android_serialport_api_SerialPort
+ * Method:    open
+ * Signature: (Ljava/lang/String;II)Ljava/io/FileDescriptor;
+ */
+JNIEXPORT jobject JNICALL Java_android_1serialport_1api_SerialPort_open
+  (JNIEnv *, jclass, jstring, jint, jint);
+
+/*
+ * Class:     android_serialport_api_SerialPort
+ * Method:    close
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_android_1serialport_1api_SerialPort_close
+  (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif

+ 3 - 0
bedlib/src/main/jni/gen_SerialPort_h.sh

@@ -0,0 +1,3 @@
+#!/bin/sh
+javah -o SerialPort.h -jni -classpath ../src android_serialport_api.SerialPort
+

BIN
bedlib/src/main/jniLibs/armeabi-v7a/libserial_port.so


BIN
bedlib/src/main/jniLibs/armeabi/libserial_port.so


BIN
bedlib/src/main/jniLibs/x86/libserial_port.so


+ 3 - 0
bedlib/src/main/res/values/strings.xml

@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">bedlib</string>
+</resources>

+ 17 - 0
bedlib/src/test/java/serialcommunication/wdkl/com/bedlib/ExampleUnitTest.java

@@ -0,0 +1,17 @@
+package serialcommunication.wdkl.com.bedlib;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() throws Exception {
+        assertEquals(4, 2 + 2);
+    }
+}

+ 1 - 0
callingbed/build.gradle

@@ -73,6 +73,7 @@ dependencies {
      */
     compile project(':middleware')
     compile project(':sip2')
+    compile project(':bedlib')
 
     //netty
     compile 'io.netty:netty-all:4.1.20.Final'

+ 24 - 1
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/activity/CallingbedActivity.kt

@@ -31,6 +31,7 @@ import kotlinx.android.synthetic.main.view_title_layout.*
 import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
+import serialporttest.utils.SerialPortUtil
 
 
 /**
@@ -41,7 +42,8 @@ import org.greenrobot.eventbus.ThreadMode
  */
 
 @Router(path = "/callingbed/main")
-class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMainLayBinding>(), CallingbedActivityContract.View, IVvsipServiceListener {
+class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMainLayBinding>(), CallingbedActivityContract.View, IVvsipServiceListener,
+        SerialPortUtil.ISerialPortBedOnclickEvent, SerialPortUtil.ISerialPortBedOnclickString{
 
     private lateinit var receiver: TimeReceiver;
 
@@ -62,6 +64,8 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
         updateDateTime()
         //注册广播
         regReceiver()
+        //串口监听
+        setSerialListner()
 
         //启动主fragment
         supportFragmentManager.beginTransaction().replace(R.id.callingbed_main_frame, MainFragment(), "main_fragment")
@@ -73,6 +77,8 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
     }
 
     override fun destory() {
+        SerialPortUtil.getInstance().closeHeart()
+        SerialPortUtil.getInstance().closeSerialPort()
         SipHelper.getInstance().unRegisterSip()
         unRegReceiver()
     }
@@ -129,6 +135,13 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
         super.onStop()
     }
 
+    private fun setSerialListner() {
+        SerialPortUtil.getInstance().setOnDataReceiveListener(this)
+        SerialPortUtil.getInstance().setOnDataReceiveStringListener(this)
+        //开启串口心跳
+        SerialPortUtil.getInstance().startHeartBeat()
+    }
+
     private fun regReceiver() {
         receiver = TimeReceiver()
         var intentFilter = IntentFilter()
@@ -202,6 +215,16 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
         }*/
     }
 
+    override fun serialPortBedOnclick(buffer: ByteArray) {
+        Log.d("serialPortBedOnclick", "buffer[0]:" + buffer[0] + ", buffer[1]:" + buffer[1] + ", buffer[2]:" + buffer[2]
+                + ", buffer[3]:" + buffer[3] + ", buffer[4]:" + buffer[4] + ", buffer[5]:" + buffer[5] + ", buffer[6]:" + buffer[6]
+                + ", buffer[7]:" + buffer[7] + ", buffer[8]:" + buffer[8])
+    }
+
+    override fun serialPortBedOnclickString(str: String) {
+        //
+    }
+
     @Subscribe(threadMode = ThreadMode.MAIN)
     fun onMoonEvent(messageEvent: MessageEvent) {
         when (messageEvent.getType()) {

+ 8 - 0
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/helper/SerialPortHelper.java

@@ -0,0 +1,8 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import serialporttest.utils.SerialPortUtil;
+
+public class SerialPortHelper {
+
+
+}

+ 1 - 1
settings.gradle

@@ -1 +1 @@
-include ':app', ':common', ':welcome', ':home', ':resource', ':middleware', ':shop', ':setting', ':extra', ':hello', ':sip2', ":callingbed"
+include ':app', ':common', ':welcome', ':home', ':resource', ':middleware', ':shop', ':setting', ':extra', ':hello', ':sip2', ":callingbed", ":bedlib"