diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..e8a952a --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include_directories(src/main/jni) \ No newline at end of file diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..e8a952a --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include_directories(src/main/jni) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index b4ce9a7..95fbe4e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,13 @@ targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录 daoPackage 'com.casic.detector.greendao'//设置DaoMaster、DaoSession、Dao包名 } + + //配置CMake路径 + externalNativeBuild { + cmake { + path 'CMakeLists.txt' + } + } } static def getBuildDate() { diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..e8a952a --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include_directories(src/main/jni) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index b4ce9a7..95fbe4e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,13 @@ targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录 daoPackage 'com.casic.detector.greendao'//设置DaoMaster、DaoSession、Dao包名 } + + //配置CMake路径 + externalNativeBuild { + cmake { + path 'CMakeLists.txt' + } + } } static def getBuildDate() { diff --git a/app/src/main/java/android_serialport_api/SerialPort.java b/app/src/main/java/android_serialport_api/SerialPort.java deleted file mode 100644 index 4b975d9..0000000 --- a/app/src/main/java/android_serialport_api/SerialPort.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2009 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. - */ - -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"; - - /* - * Do not remove or rename the field mFd: it is used by native method close(); - */ - private FileDescriptor mFd; - private final FileInputStream mFileInputStream; - private final FileOutputStream mFileOutputStream; - - public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { - - /* Check access permission */ - if (!device.canRead() || !device.canWrite()) { - try { - /* Missing read/write permission, trying to chmod the file */ - Process su; - su = Runtime.getRuntime().exec("/system/bin/su"); - String cmd = "chmod 666 " + 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 - private native static FileDescriptor open(String path, int baudrate, int flags); - - public native void close(); - - static { - System.loadLibrary("serial_port"); - } -} diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..e8a952a --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include_directories(src/main/jni) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index b4ce9a7..95fbe4e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,13 @@ targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录 daoPackage 'com.casic.detector.greendao'//设置DaoMaster、DaoSession、Dao包名 } + + //配置CMake路径 + externalNativeBuild { + cmake { + path 'CMakeLists.txt' + } + } } static def getBuildDate() { diff --git a/app/src/main/java/android_serialport_api/SerialPort.java b/app/src/main/java/android_serialport_api/SerialPort.java deleted file mode 100644 index 4b975d9..0000000 --- a/app/src/main/java/android_serialport_api/SerialPort.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2009 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. - */ - -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"; - - /* - * Do not remove or rename the field mFd: it is used by native method close(); - */ - private FileDescriptor mFd; - private final FileInputStream mFileInputStream; - private final FileOutputStream mFileOutputStream; - - public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { - - /* Check access permission */ - if (!device.canRead() || !device.canWrite()) { - try { - /* Missing read/write permission, trying to chmod the file */ - Process su; - su = Runtime.getRuntime().exec("/system/bin/su"); - String cmd = "chmod 666 " + 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 - private native static FileDescriptor open(String path, int baudrate, int flags); - - public native void close(); - - static { - System.loadLibrary("serial_port"); - } -} diff --git a/app/src/main/java/android_serialport_api/SerialPortFinder.java b/app/src/main/java/android_serialport_api/SerialPortFinder.java deleted file mode 100644 index 23e6b89..0000000 --- a/app/src/main/java/android_serialport_api/SerialPortFinder.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2009 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. - */ - -package android_serialport_api; - -import android.util.Log; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.LineNumberReader; -import java.util.Iterator; -import java.util.Vector; - -public class SerialPortFinder { - - public class Driver { - public Driver(String name, String root) { - mDriverName = name; - mDeviceRoot = root; - } - - private String mDriverName; - private String mDeviceRoot; - Vector mDevices = null; - - public Vector getDevices() { - if (mDevices == null) { - mDevices = new Vector(); - File dev = new File("/dev"); - File[] files = dev.listFiles(); - int i; - for (i = 0; i < files.length; i++) { - if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) { - Log.d(TAG, "Found new device: " + files[i]); - mDevices.add(files[i]); - } - } - } - return mDevices; - } - - public String getName() { - return mDriverName; - } - } - - private static final String TAG = "SerialPort"; - - private Vector mDrivers = null; - - Vector getDrivers() throws IOException { - if (mDrivers == null) { - mDrivers = new Vector(); - LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers")); - String l; - while ((l = r.readLine()) != null) { - // Issue 3: - // Since driver name may contain spaces, we do not extract driver name with split() - String drivername = l.substring(0, 0x15).trim(); - String[] w = l.split(" +"); - if ((w.length >= 5) && (w[w.length - 1].equals("serial"))) { - Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length - 4]); - mDrivers.add(new Driver(drivername, w[w.length - 4])); - } - } - r.close(); - } - return mDrivers; - } - - public String[] getAllDevices() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getName(); - String value = String.format("%s (%s)", device, driver.getName()); - devices.add(value); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } - - public String[] getAllDevicesPath() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getAbsolutePath(); - devices.add(device); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } -} diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..e8a952a --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include_directories(src/main/jni) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index b4ce9a7..95fbe4e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,13 @@ targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录 daoPackage 'com.casic.detector.greendao'//设置DaoMaster、DaoSession、Dao包名 } + + //配置CMake路径 + externalNativeBuild { + cmake { + path 'CMakeLists.txt' + } + } } static def getBuildDate() { diff --git a/app/src/main/java/android_serialport_api/SerialPort.java b/app/src/main/java/android_serialport_api/SerialPort.java deleted file mode 100644 index 4b975d9..0000000 --- a/app/src/main/java/android_serialport_api/SerialPort.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2009 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. - */ - -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"; - - /* - * Do not remove or rename the field mFd: it is used by native method close(); - */ - private FileDescriptor mFd; - private final FileInputStream mFileInputStream; - private final FileOutputStream mFileOutputStream; - - public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { - - /* Check access permission */ - if (!device.canRead() || !device.canWrite()) { - try { - /* Missing read/write permission, trying to chmod the file */ - Process su; - su = Runtime.getRuntime().exec("/system/bin/su"); - String cmd = "chmod 666 " + 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 - private native static FileDescriptor open(String path, int baudrate, int flags); - - public native void close(); - - static { - System.loadLibrary("serial_port"); - } -} diff --git a/app/src/main/java/android_serialport_api/SerialPortFinder.java b/app/src/main/java/android_serialport_api/SerialPortFinder.java deleted file mode 100644 index 23e6b89..0000000 --- a/app/src/main/java/android_serialport_api/SerialPortFinder.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2009 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. - */ - -package android_serialport_api; - -import android.util.Log; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.LineNumberReader; -import java.util.Iterator; -import java.util.Vector; - -public class SerialPortFinder { - - public class Driver { - public Driver(String name, String root) { - mDriverName = name; - mDeviceRoot = root; - } - - private String mDriverName; - private String mDeviceRoot; - Vector mDevices = null; - - public Vector getDevices() { - if (mDevices == null) { - mDevices = new Vector(); - File dev = new File("/dev"); - File[] files = dev.listFiles(); - int i; - for (i = 0; i < files.length; i++) { - if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) { - Log.d(TAG, "Found new device: " + files[i]); - mDevices.add(files[i]); - } - } - } - return mDevices; - } - - public String getName() { - return mDriverName; - } - } - - private static final String TAG = "SerialPort"; - - private Vector mDrivers = null; - - Vector getDrivers() throws IOException { - if (mDrivers == null) { - mDrivers = new Vector(); - LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers")); - String l; - while ((l = r.readLine()) != null) { - // Issue 3: - // Since driver name may contain spaces, we do not extract driver name with split() - String drivername = l.substring(0, 0x15).trim(); - String[] w = l.split(" +"); - if ((w.length >= 5) && (w[w.length - 1].equals("serial"))) { - Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length - 4]); - mDrivers.add(new Driver(drivername, w[w.length - 4])); - } - } - r.close(); - } - return mDrivers; - } - - public String[] getAllDevices() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getName(); - String value = String.format("%s (%s)", device, driver.getName()); - devices.add(value); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } - - public String[] getAllDevicesPath() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getAbsolutePath(); - devices.add(device); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } -} diff --git a/app/src/main/java/com/casic/detector/base/BaseApplication.kt b/app/src/main/java/com/casic/detector/base/BaseApplication.kt index c36fcea..1250e19 100644 --- a/app/src/main/java/com/casic/detector/base/BaseApplication.kt +++ b/app/src/main/java/com/casic/detector/base/BaseApplication.kt @@ -1,9 +1,9 @@ package com.casic.detector.base import android.app.Application -import android_serialport_api.SerialPort import com.casic.detector.greendao.DaoMaster import com.casic.detector.greendao.DaoSession +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.utils.SaveKeyValues import java.io.File import java.io.IOException diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..e8a952a --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include_directories(src/main/jni) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index b4ce9a7..95fbe4e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,13 @@ targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录 daoPackage 'com.casic.detector.greendao'//设置DaoMaster、DaoSession、Dao包名 } + + //配置CMake路径 + externalNativeBuild { + cmake { + path 'CMakeLists.txt' + } + } } static def getBuildDate() { diff --git a/app/src/main/java/android_serialport_api/SerialPort.java b/app/src/main/java/android_serialport_api/SerialPort.java deleted file mode 100644 index 4b975d9..0000000 --- a/app/src/main/java/android_serialport_api/SerialPort.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2009 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. - */ - -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"; - - /* - * Do not remove or rename the field mFd: it is used by native method close(); - */ - private FileDescriptor mFd; - private final FileInputStream mFileInputStream; - private final FileOutputStream mFileOutputStream; - - public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { - - /* Check access permission */ - if (!device.canRead() || !device.canWrite()) { - try { - /* Missing read/write permission, trying to chmod the file */ - Process su; - su = Runtime.getRuntime().exec("/system/bin/su"); - String cmd = "chmod 666 " + 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 - private native static FileDescriptor open(String path, int baudrate, int flags); - - public native void close(); - - static { - System.loadLibrary("serial_port"); - } -} diff --git a/app/src/main/java/android_serialport_api/SerialPortFinder.java b/app/src/main/java/android_serialport_api/SerialPortFinder.java deleted file mode 100644 index 23e6b89..0000000 --- a/app/src/main/java/android_serialport_api/SerialPortFinder.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2009 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. - */ - -package android_serialport_api; - -import android.util.Log; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.LineNumberReader; -import java.util.Iterator; -import java.util.Vector; - -public class SerialPortFinder { - - public class Driver { - public Driver(String name, String root) { - mDriverName = name; - mDeviceRoot = root; - } - - private String mDriverName; - private String mDeviceRoot; - Vector mDevices = null; - - public Vector getDevices() { - if (mDevices == null) { - mDevices = new Vector(); - File dev = new File("/dev"); - File[] files = dev.listFiles(); - int i; - for (i = 0; i < files.length; i++) { - if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) { - Log.d(TAG, "Found new device: " + files[i]); - mDevices.add(files[i]); - } - } - } - return mDevices; - } - - public String getName() { - return mDriverName; - } - } - - private static final String TAG = "SerialPort"; - - private Vector mDrivers = null; - - Vector getDrivers() throws IOException { - if (mDrivers == null) { - mDrivers = new Vector(); - LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers")); - String l; - while ((l = r.readLine()) != null) { - // Issue 3: - // Since driver name may contain spaces, we do not extract driver name with split() - String drivername = l.substring(0, 0x15).trim(); - String[] w = l.split(" +"); - if ((w.length >= 5) && (w[w.length - 1].equals("serial"))) { - Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length - 4]); - mDrivers.add(new Driver(drivername, w[w.length - 4])); - } - } - r.close(); - } - return mDrivers; - } - - public String[] getAllDevices() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getName(); - String value = String.format("%s (%s)", device, driver.getName()); - devices.add(value); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } - - public String[] getAllDevicesPath() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getAbsolutePath(); - devices.add(device); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } -} diff --git a/app/src/main/java/com/casic/detector/base/BaseApplication.kt b/app/src/main/java/com/casic/detector/base/BaseApplication.kt index c36fcea..1250e19 100644 --- a/app/src/main/java/com/casic/detector/base/BaseApplication.kt +++ b/app/src/main/java/com/casic/detector/base/BaseApplication.kt @@ -1,9 +1,9 @@ package com.casic.detector.base import android.app.Application -import android_serialport_api.SerialPort import com.casic.detector.greendao.DaoMaster import com.casic.detector.greendao.DaoSession +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.utils.SaveKeyValues import java.io.File import java.io.IOException diff --git a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt index c7229ad..ca5c1f8 100644 --- a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt +++ b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt @@ -1,8 +1,8 @@ package com.casic.detector.base import android.os.Bundle -import android_serialport_api.SerialPort import androidx.appcompat.app.AppCompatActivity +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.extensions.show import java.io.IOException import java.io.InputStream diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..e8a952a --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include_directories(src/main/jni) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index b4ce9a7..95fbe4e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,13 @@ targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录 daoPackage 'com.casic.detector.greendao'//设置DaoMaster、DaoSession、Dao包名 } + + //配置CMake路径 + externalNativeBuild { + cmake { + path 'CMakeLists.txt' + } + } } static def getBuildDate() { diff --git a/app/src/main/java/android_serialport_api/SerialPort.java b/app/src/main/java/android_serialport_api/SerialPort.java deleted file mode 100644 index 4b975d9..0000000 --- a/app/src/main/java/android_serialport_api/SerialPort.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2009 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. - */ - -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"; - - /* - * Do not remove or rename the field mFd: it is used by native method close(); - */ - private FileDescriptor mFd; - private final FileInputStream mFileInputStream; - private final FileOutputStream mFileOutputStream; - - public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { - - /* Check access permission */ - if (!device.canRead() || !device.canWrite()) { - try { - /* Missing read/write permission, trying to chmod the file */ - Process su; - su = Runtime.getRuntime().exec("/system/bin/su"); - String cmd = "chmod 666 " + 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 - private native static FileDescriptor open(String path, int baudrate, int flags); - - public native void close(); - - static { - System.loadLibrary("serial_port"); - } -} diff --git a/app/src/main/java/android_serialport_api/SerialPortFinder.java b/app/src/main/java/android_serialport_api/SerialPortFinder.java deleted file mode 100644 index 23e6b89..0000000 --- a/app/src/main/java/android_serialport_api/SerialPortFinder.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2009 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. - */ - -package android_serialport_api; - -import android.util.Log; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.LineNumberReader; -import java.util.Iterator; -import java.util.Vector; - -public class SerialPortFinder { - - public class Driver { - public Driver(String name, String root) { - mDriverName = name; - mDeviceRoot = root; - } - - private String mDriverName; - private String mDeviceRoot; - Vector mDevices = null; - - public Vector getDevices() { - if (mDevices == null) { - mDevices = new Vector(); - File dev = new File("/dev"); - File[] files = dev.listFiles(); - int i; - for (i = 0; i < files.length; i++) { - if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) { - Log.d(TAG, "Found new device: " + files[i]); - mDevices.add(files[i]); - } - } - } - return mDevices; - } - - public String getName() { - return mDriverName; - } - } - - private static final String TAG = "SerialPort"; - - private Vector mDrivers = null; - - Vector getDrivers() throws IOException { - if (mDrivers == null) { - mDrivers = new Vector(); - LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers")); - String l; - while ((l = r.readLine()) != null) { - // Issue 3: - // Since driver name may contain spaces, we do not extract driver name with split() - String drivername = l.substring(0, 0x15).trim(); - String[] w = l.split(" +"); - if ((w.length >= 5) && (w[w.length - 1].equals("serial"))) { - Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length - 4]); - mDrivers.add(new Driver(drivername, w[w.length - 4])); - } - } - r.close(); - } - return mDrivers; - } - - public String[] getAllDevices() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getName(); - String value = String.format("%s (%s)", device, driver.getName()); - devices.add(value); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } - - public String[] getAllDevicesPath() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getAbsolutePath(); - devices.add(device); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } -} diff --git a/app/src/main/java/com/casic/detector/base/BaseApplication.kt b/app/src/main/java/com/casic/detector/base/BaseApplication.kt index c36fcea..1250e19 100644 --- a/app/src/main/java/com/casic/detector/base/BaseApplication.kt +++ b/app/src/main/java/com/casic/detector/base/BaseApplication.kt @@ -1,9 +1,9 @@ package com.casic.detector.base import android.app.Application -import android_serialport_api.SerialPort import com.casic.detector.greendao.DaoMaster import com.casic.detector.greendao.DaoSession +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.utils.SaveKeyValues import java.io.File import java.io.IOException diff --git a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt index c7229ad..ca5c1f8 100644 --- a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt +++ b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt @@ -1,8 +1,8 @@ package com.casic.detector.base import android.os.Bundle -import android_serialport_api.SerialPort import androidx.appcompat.app.AppCompatActivity +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.extensions.show import java.io.IOException import java.io.InputStream diff --git a/app/src/main/java/com/casic/detector/uart/SerialPort.java b/app/src/main/java/com/casic/detector/uart/SerialPort.java new file mode 100644 index 0000000..550b461 --- /dev/null +++ b/app/src/main/java/com/casic/detector/uart/SerialPort.java @@ -0,0 +1,73 @@ +package com.casic.detector.uart; + +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"; + + /** + * .so 库名字。需要去掉生成时自带的lib前缀 + * */ + static { + System.loadLibrary("serial_port"); + } + + /** + * JNI + *

+ * 必须用 native 标识JNI方法 + */ + private native static FileDescriptor open(String path, int baudRate, int flags); + + public native void close(); + + /** + * Do not remove or rename the field mFd: it is used by native method close(); + */ + private FileDescriptor mFd; + private final FileInputStream mFileInputStream; + private final FileOutputStream mFileOutputStream; + + public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { + + if (!device.canRead() || !device.canWrite()) { + try { + Process su; + su = Runtime.getRuntime().exec("/system/bin/su"); + String cmd = "chmod 666 " + 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); + } + + public InputStream getInputStream() { + return mFileInputStream; + } + + public OutputStream getOutputStream() { + return mFileOutputStream; + } +} diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..e8a952a --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include_directories(src/main/jni) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index b4ce9a7..95fbe4e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,13 @@ targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录 daoPackage 'com.casic.detector.greendao'//设置DaoMaster、DaoSession、Dao包名 } + + //配置CMake路径 + externalNativeBuild { + cmake { + path 'CMakeLists.txt' + } + } } static def getBuildDate() { diff --git a/app/src/main/java/android_serialport_api/SerialPort.java b/app/src/main/java/android_serialport_api/SerialPort.java deleted file mode 100644 index 4b975d9..0000000 --- a/app/src/main/java/android_serialport_api/SerialPort.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2009 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. - */ - -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"; - - /* - * Do not remove or rename the field mFd: it is used by native method close(); - */ - private FileDescriptor mFd; - private final FileInputStream mFileInputStream; - private final FileOutputStream mFileOutputStream; - - public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { - - /* Check access permission */ - if (!device.canRead() || !device.canWrite()) { - try { - /* Missing read/write permission, trying to chmod the file */ - Process su; - su = Runtime.getRuntime().exec("/system/bin/su"); - String cmd = "chmod 666 " + 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 - private native static FileDescriptor open(String path, int baudrate, int flags); - - public native void close(); - - static { - System.loadLibrary("serial_port"); - } -} diff --git a/app/src/main/java/android_serialport_api/SerialPortFinder.java b/app/src/main/java/android_serialport_api/SerialPortFinder.java deleted file mode 100644 index 23e6b89..0000000 --- a/app/src/main/java/android_serialport_api/SerialPortFinder.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2009 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. - */ - -package android_serialport_api; - -import android.util.Log; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.LineNumberReader; -import java.util.Iterator; -import java.util.Vector; - -public class SerialPortFinder { - - public class Driver { - public Driver(String name, String root) { - mDriverName = name; - mDeviceRoot = root; - } - - private String mDriverName; - private String mDeviceRoot; - Vector mDevices = null; - - public Vector getDevices() { - if (mDevices == null) { - mDevices = new Vector(); - File dev = new File("/dev"); - File[] files = dev.listFiles(); - int i; - for (i = 0; i < files.length; i++) { - if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) { - Log.d(TAG, "Found new device: " + files[i]); - mDevices.add(files[i]); - } - } - } - return mDevices; - } - - public String getName() { - return mDriverName; - } - } - - private static final String TAG = "SerialPort"; - - private Vector mDrivers = null; - - Vector getDrivers() throws IOException { - if (mDrivers == null) { - mDrivers = new Vector(); - LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers")); - String l; - while ((l = r.readLine()) != null) { - // Issue 3: - // Since driver name may contain spaces, we do not extract driver name with split() - String drivername = l.substring(0, 0x15).trim(); - String[] w = l.split(" +"); - if ((w.length >= 5) && (w[w.length - 1].equals("serial"))) { - Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length - 4]); - mDrivers.add(new Driver(drivername, w[w.length - 4])); - } - } - r.close(); - } - return mDrivers; - } - - public String[] getAllDevices() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getName(); - String value = String.format("%s (%s)", device, driver.getName()); - devices.add(value); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } - - public String[] getAllDevicesPath() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getAbsolutePath(); - devices.add(device); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } -} diff --git a/app/src/main/java/com/casic/detector/base/BaseApplication.kt b/app/src/main/java/com/casic/detector/base/BaseApplication.kt index c36fcea..1250e19 100644 --- a/app/src/main/java/com/casic/detector/base/BaseApplication.kt +++ b/app/src/main/java/com/casic/detector/base/BaseApplication.kt @@ -1,9 +1,9 @@ package com.casic.detector.base import android.app.Application -import android_serialport_api.SerialPort import com.casic.detector.greendao.DaoMaster import com.casic.detector.greendao.DaoSession +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.utils.SaveKeyValues import java.io.File import java.io.IOException diff --git a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt index c7229ad..ca5c1f8 100644 --- a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt +++ b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt @@ -1,8 +1,8 @@ package com.casic.detector.base import android.os.Bundle -import android_serialport_api.SerialPort import androidx.appcompat.app.AppCompatActivity +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.extensions.show import java.io.IOException import java.io.InputStream diff --git a/app/src/main/java/com/casic/detector/uart/SerialPort.java b/app/src/main/java/com/casic/detector/uart/SerialPort.java new file mode 100644 index 0000000..550b461 --- /dev/null +++ b/app/src/main/java/com/casic/detector/uart/SerialPort.java @@ -0,0 +1,73 @@ +package com.casic.detector.uart; + +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"; + + /** + * .so 库名字。需要去掉生成时自带的lib前缀 + * */ + static { + System.loadLibrary("serial_port"); + } + + /** + * JNI + *

+ * 必须用 native 标识JNI方法 + */ + private native static FileDescriptor open(String path, int baudRate, int flags); + + public native void close(); + + /** + * Do not remove or rename the field mFd: it is used by native method close(); + */ + private FileDescriptor mFd; + private final FileInputStream mFileInputStream; + private final FileOutputStream mFileOutputStream; + + public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { + + if (!device.canRead() || !device.canWrite()) { + try { + Process su; + su = Runtime.getRuntime().exec("/system/bin/su"); + String cmd = "chmod 666 " + 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); + } + + public InputStream getInputStream() { + return mFileInputStream; + } + + public OutputStream getOutputStream() { + return mFileOutputStream; + } +} diff --git a/app/src/main/jni/Android.mk b/app/src/main/jni/Android.mk index f4ce1c3..94bf9d0 100644 --- a/app/src/main/jni/Android.mk +++ b/app/src/main/jni/Android.mk @@ -1,26 +1,23 @@ -# -# Copyright 2009 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. -# - +# Android.mk必须以LOCAL_PATH开头,注释#除外 +# 设置工作目录,而my-dir则会返回Android.mk文件所在的目录 LOCAL_PATH := $(call my-dir) +# 借助CLEAR_VARS变量清除除LOCAL_PATH外的所有LOCAL_变量 include $(CLEAR_VARS) +# android-3 对应Android 1.5 TARGET_PLATFORM := android-3 + +# 设置模块的名称,即编译出来.so文件名 +# 注,要和上述步骤中build.gradle中NDK节点设置的名字相同 LOCAL_MODULE := serial_port + +# 指定参与模块编译的C/C++源文件列表,多文件用"\"隔开 LOCAL_SRC_FILES := SerialPort.c + LOCAL_LDLIBS := -llog +# 必须在文件结尾定义编译类型,指定生成的静态库或者共享库在运行时依赖的共享库模块列表。 +# BUILD_SHARED_LIBRARY 共享库,供java或者其他共享库调用 +# BUILD_STATIC_LIBRARY 静态库,供共享库调用,不能直接被java调用 include $(BUILD_SHARED_LIBRARY) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..e8a952a --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include_directories(src/main/jni) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index b4ce9a7..95fbe4e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,13 @@ targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录 daoPackage 'com.casic.detector.greendao'//设置DaoMaster、DaoSession、Dao包名 } + + //配置CMake路径 + externalNativeBuild { + cmake { + path 'CMakeLists.txt' + } + } } static def getBuildDate() { diff --git a/app/src/main/java/android_serialport_api/SerialPort.java b/app/src/main/java/android_serialport_api/SerialPort.java deleted file mode 100644 index 4b975d9..0000000 --- a/app/src/main/java/android_serialport_api/SerialPort.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2009 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. - */ - -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"; - - /* - * Do not remove or rename the field mFd: it is used by native method close(); - */ - private FileDescriptor mFd; - private final FileInputStream mFileInputStream; - private final FileOutputStream mFileOutputStream; - - public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { - - /* Check access permission */ - if (!device.canRead() || !device.canWrite()) { - try { - /* Missing read/write permission, trying to chmod the file */ - Process su; - su = Runtime.getRuntime().exec("/system/bin/su"); - String cmd = "chmod 666 " + 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 - private native static FileDescriptor open(String path, int baudrate, int flags); - - public native void close(); - - static { - System.loadLibrary("serial_port"); - } -} diff --git a/app/src/main/java/android_serialport_api/SerialPortFinder.java b/app/src/main/java/android_serialport_api/SerialPortFinder.java deleted file mode 100644 index 23e6b89..0000000 --- a/app/src/main/java/android_serialport_api/SerialPortFinder.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2009 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. - */ - -package android_serialport_api; - -import android.util.Log; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.LineNumberReader; -import java.util.Iterator; -import java.util.Vector; - -public class SerialPortFinder { - - public class Driver { - public Driver(String name, String root) { - mDriverName = name; - mDeviceRoot = root; - } - - private String mDriverName; - private String mDeviceRoot; - Vector mDevices = null; - - public Vector getDevices() { - if (mDevices == null) { - mDevices = new Vector(); - File dev = new File("/dev"); - File[] files = dev.listFiles(); - int i; - for (i = 0; i < files.length; i++) { - if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) { - Log.d(TAG, "Found new device: " + files[i]); - mDevices.add(files[i]); - } - } - } - return mDevices; - } - - public String getName() { - return mDriverName; - } - } - - private static final String TAG = "SerialPort"; - - private Vector mDrivers = null; - - Vector getDrivers() throws IOException { - if (mDrivers == null) { - mDrivers = new Vector(); - LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers")); - String l; - while ((l = r.readLine()) != null) { - // Issue 3: - // Since driver name may contain spaces, we do not extract driver name with split() - String drivername = l.substring(0, 0x15).trim(); - String[] w = l.split(" +"); - if ((w.length >= 5) && (w[w.length - 1].equals("serial"))) { - Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length - 4]); - mDrivers.add(new Driver(drivername, w[w.length - 4])); - } - } - r.close(); - } - return mDrivers; - } - - public String[] getAllDevices() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getName(); - String value = String.format("%s (%s)", device, driver.getName()); - devices.add(value); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } - - public String[] getAllDevicesPath() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getAbsolutePath(); - devices.add(device); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } -} diff --git a/app/src/main/java/com/casic/detector/base/BaseApplication.kt b/app/src/main/java/com/casic/detector/base/BaseApplication.kt index c36fcea..1250e19 100644 --- a/app/src/main/java/com/casic/detector/base/BaseApplication.kt +++ b/app/src/main/java/com/casic/detector/base/BaseApplication.kt @@ -1,9 +1,9 @@ package com.casic.detector.base import android.app.Application -import android_serialport_api.SerialPort import com.casic.detector.greendao.DaoMaster import com.casic.detector.greendao.DaoSession +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.utils.SaveKeyValues import java.io.File import java.io.IOException diff --git a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt index c7229ad..ca5c1f8 100644 --- a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt +++ b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt @@ -1,8 +1,8 @@ package com.casic.detector.base import android.os.Bundle -import android_serialport_api.SerialPort import androidx.appcompat.app.AppCompatActivity +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.extensions.show import java.io.IOException import java.io.InputStream diff --git a/app/src/main/java/com/casic/detector/uart/SerialPort.java b/app/src/main/java/com/casic/detector/uart/SerialPort.java new file mode 100644 index 0000000..550b461 --- /dev/null +++ b/app/src/main/java/com/casic/detector/uart/SerialPort.java @@ -0,0 +1,73 @@ +package com.casic.detector.uart; + +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"; + + /** + * .so 库名字。需要去掉生成时自带的lib前缀 + * */ + static { + System.loadLibrary("serial_port"); + } + + /** + * JNI + *

+ * 必须用 native 标识JNI方法 + */ + private native static FileDescriptor open(String path, int baudRate, int flags); + + public native void close(); + + /** + * Do not remove or rename the field mFd: it is used by native method close(); + */ + private FileDescriptor mFd; + private final FileInputStream mFileInputStream; + private final FileOutputStream mFileOutputStream; + + public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { + + if (!device.canRead() || !device.canWrite()) { + try { + Process su; + su = Runtime.getRuntime().exec("/system/bin/su"); + String cmd = "chmod 666 " + 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); + } + + public InputStream getInputStream() { + return mFileInputStream; + } + + public OutputStream getOutputStream() { + return mFileOutputStream; + } +} diff --git a/app/src/main/jni/Android.mk b/app/src/main/jni/Android.mk index f4ce1c3..94bf9d0 100644 --- a/app/src/main/jni/Android.mk +++ b/app/src/main/jni/Android.mk @@ -1,26 +1,23 @@ -# -# Copyright 2009 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. -# - +# Android.mk必须以LOCAL_PATH开头,注释#除外 +# 设置工作目录,而my-dir则会返回Android.mk文件所在的目录 LOCAL_PATH := $(call my-dir) +# 借助CLEAR_VARS变量清除除LOCAL_PATH外的所有LOCAL_变量 include $(CLEAR_VARS) +# android-3 对应Android 1.5 TARGET_PLATFORM := android-3 + +# 设置模块的名称,即编译出来.so文件名 +# 注,要和上述步骤中build.gradle中NDK节点设置的名字相同 LOCAL_MODULE := serial_port + +# 指定参与模块编译的C/C++源文件列表,多文件用"\"隔开 LOCAL_SRC_FILES := SerialPort.c + LOCAL_LDLIBS := -llog +# 必须在文件结尾定义编译类型,指定生成的静态库或者共享库在运行时依赖的共享库模块列表。 +# BUILD_SHARED_LIBRARY 共享库,供java或者其他共享库调用 +# BUILD_STATIC_LIBRARY 静态库,供共享库调用,不能直接被java调用 include $(BUILD_SHARED_LIBRARY) diff --git a/app/src/main/jni/SerialPort.c b/app/src/main/jni/SerialPort.c index 84748a7..5dad4bf 100644 --- a/app/src/main/jni/SerialPort.c +++ b/app/src/main/jni/SerialPort.c @@ -1,19 +1,3 @@ -/* - * 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 #include #include @@ -25,143 +9,164 @@ #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) + +static const char *TAG = "serial_port"; #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; - } +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 + * Class: com_casic_detector_uart_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; +JNIEXPORT jobject JNICALL +Java_com_casic_detector_uart_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; - } - } + /* Check arguments */ + { + speed = getBaudRate(baudRate); + if (speed == -1) { + 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; - } - } + /* 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) { + LOGE("Cannot open port"); + 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; - } + /* Configure device */ + { + struct termios cfg; + LOGD("Configuring serial port"); + if (tcgetattr(fd, &cfg)) { + LOGE("tcgetattr() failed"); + close(fd); + return NULL; + } - cfmakeraw(&cfg); - cfsetispeed(&cfg, speed); - cfsetospeed(&cfg, speed); + cfmakeraw(&cfg); + cfsetispeed(&cfg, speed); + cfsetospeed(&cfg, speed); - if (tcsetattr(fd, TCSANOW, &cfg)) - { - LOGE("tcsetattr() failed"); - close(fd); - /* TODO: throw an exception */ - return NULL; - } - } + if (tcsetattr(fd, TCSANOW, &cfg)) { + LOGE("tcsetattr() failed"); + close(fd); + return NULL; + } + } - /* Create a corresponding file descriptor */ - { - jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); - jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "", "()V"); - jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); - mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); - (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint)fd); - } + /* Create a corresponding file descriptor */ + { + jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); + jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "", "()V"); + jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); + mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); + (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint) fd); + } - return mFileDescriptor; + return mFileDescriptor; } /* - * Class: cedric_serial_SerialPort + * Class: com_casic_detector_uart_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"); +JNIEXPORT void JNICALL Java_com_casic_detector_uart_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"); + 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); + jobject mFd = (*env)->GetObjectField(env, thiz, mFdID); + jint descriptor = (*env)->GetIntField(env, mFd, descriptorID); - LOGD("close(fd = %d)", descriptor); - close(descriptor); + LOGD("close(fd = %d)", descriptor); + close(descriptor); } diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..e8a952a --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include_directories(src/main/jni) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index b4ce9a7..95fbe4e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,13 @@ targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录 daoPackage 'com.casic.detector.greendao'//设置DaoMaster、DaoSession、Dao包名 } + + //配置CMake路径 + externalNativeBuild { + cmake { + path 'CMakeLists.txt' + } + } } static def getBuildDate() { diff --git a/app/src/main/java/android_serialport_api/SerialPort.java b/app/src/main/java/android_serialport_api/SerialPort.java deleted file mode 100644 index 4b975d9..0000000 --- a/app/src/main/java/android_serialport_api/SerialPort.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2009 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. - */ - -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"; - - /* - * Do not remove or rename the field mFd: it is used by native method close(); - */ - private FileDescriptor mFd; - private final FileInputStream mFileInputStream; - private final FileOutputStream mFileOutputStream; - - public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { - - /* Check access permission */ - if (!device.canRead() || !device.canWrite()) { - try { - /* Missing read/write permission, trying to chmod the file */ - Process su; - su = Runtime.getRuntime().exec("/system/bin/su"); - String cmd = "chmod 666 " + 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 - private native static FileDescriptor open(String path, int baudrate, int flags); - - public native void close(); - - static { - System.loadLibrary("serial_port"); - } -} diff --git a/app/src/main/java/android_serialport_api/SerialPortFinder.java b/app/src/main/java/android_serialport_api/SerialPortFinder.java deleted file mode 100644 index 23e6b89..0000000 --- a/app/src/main/java/android_serialport_api/SerialPortFinder.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2009 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. - */ - -package android_serialport_api; - -import android.util.Log; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.LineNumberReader; -import java.util.Iterator; -import java.util.Vector; - -public class SerialPortFinder { - - public class Driver { - public Driver(String name, String root) { - mDriverName = name; - mDeviceRoot = root; - } - - private String mDriverName; - private String mDeviceRoot; - Vector mDevices = null; - - public Vector getDevices() { - if (mDevices == null) { - mDevices = new Vector(); - File dev = new File("/dev"); - File[] files = dev.listFiles(); - int i; - for (i = 0; i < files.length; i++) { - if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) { - Log.d(TAG, "Found new device: " + files[i]); - mDevices.add(files[i]); - } - } - } - return mDevices; - } - - public String getName() { - return mDriverName; - } - } - - private static final String TAG = "SerialPort"; - - private Vector mDrivers = null; - - Vector getDrivers() throws IOException { - if (mDrivers == null) { - mDrivers = new Vector(); - LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers")); - String l; - while ((l = r.readLine()) != null) { - // Issue 3: - // Since driver name may contain spaces, we do not extract driver name with split() - String drivername = l.substring(0, 0x15).trim(); - String[] w = l.split(" +"); - if ((w.length >= 5) && (w[w.length - 1].equals("serial"))) { - Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length - 4]); - mDrivers.add(new Driver(drivername, w[w.length - 4])); - } - } - r.close(); - } - return mDrivers; - } - - public String[] getAllDevices() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getName(); - String value = String.format("%s (%s)", device, driver.getName()); - devices.add(value); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } - - public String[] getAllDevicesPath() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getAbsolutePath(); - devices.add(device); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } -} diff --git a/app/src/main/java/com/casic/detector/base/BaseApplication.kt b/app/src/main/java/com/casic/detector/base/BaseApplication.kt index c36fcea..1250e19 100644 --- a/app/src/main/java/com/casic/detector/base/BaseApplication.kt +++ b/app/src/main/java/com/casic/detector/base/BaseApplication.kt @@ -1,9 +1,9 @@ package com.casic.detector.base import android.app.Application -import android_serialport_api.SerialPort import com.casic.detector.greendao.DaoMaster import com.casic.detector.greendao.DaoSession +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.utils.SaveKeyValues import java.io.File import java.io.IOException diff --git a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt index c7229ad..ca5c1f8 100644 --- a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt +++ b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt @@ -1,8 +1,8 @@ package com.casic.detector.base import android.os.Bundle -import android_serialport_api.SerialPort import androidx.appcompat.app.AppCompatActivity +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.extensions.show import java.io.IOException import java.io.InputStream diff --git a/app/src/main/java/com/casic/detector/uart/SerialPort.java b/app/src/main/java/com/casic/detector/uart/SerialPort.java new file mode 100644 index 0000000..550b461 --- /dev/null +++ b/app/src/main/java/com/casic/detector/uart/SerialPort.java @@ -0,0 +1,73 @@ +package com.casic.detector.uart; + +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"; + + /** + * .so 库名字。需要去掉生成时自带的lib前缀 + * */ + static { + System.loadLibrary("serial_port"); + } + + /** + * JNI + *

+ * 必须用 native 标识JNI方法 + */ + private native static FileDescriptor open(String path, int baudRate, int flags); + + public native void close(); + + /** + * Do not remove or rename the field mFd: it is used by native method close(); + */ + private FileDescriptor mFd; + private final FileInputStream mFileInputStream; + private final FileOutputStream mFileOutputStream; + + public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { + + if (!device.canRead() || !device.canWrite()) { + try { + Process su; + su = Runtime.getRuntime().exec("/system/bin/su"); + String cmd = "chmod 666 " + 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); + } + + public InputStream getInputStream() { + return mFileInputStream; + } + + public OutputStream getOutputStream() { + return mFileOutputStream; + } +} diff --git a/app/src/main/jni/Android.mk b/app/src/main/jni/Android.mk index f4ce1c3..94bf9d0 100644 --- a/app/src/main/jni/Android.mk +++ b/app/src/main/jni/Android.mk @@ -1,26 +1,23 @@ -# -# Copyright 2009 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. -# - +# Android.mk必须以LOCAL_PATH开头,注释#除外 +# 设置工作目录,而my-dir则会返回Android.mk文件所在的目录 LOCAL_PATH := $(call my-dir) +# 借助CLEAR_VARS变量清除除LOCAL_PATH外的所有LOCAL_变量 include $(CLEAR_VARS) +# android-3 对应Android 1.5 TARGET_PLATFORM := android-3 + +# 设置模块的名称,即编译出来.so文件名 +# 注,要和上述步骤中build.gradle中NDK节点设置的名字相同 LOCAL_MODULE := serial_port + +# 指定参与模块编译的C/C++源文件列表,多文件用"\"隔开 LOCAL_SRC_FILES := SerialPort.c + LOCAL_LDLIBS := -llog +# 必须在文件结尾定义编译类型,指定生成的静态库或者共享库在运行时依赖的共享库模块列表。 +# BUILD_SHARED_LIBRARY 共享库,供java或者其他共享库调用 +# BUILD_STATIC_LIBRARY 静态库,供共享库调用,不能直接被java调用 include $(BUILD_SHARED_LIBRARY) diff --git a/app/src/main/jni/SerialPort.c b/app/src/main/jni/SerialPort.c index 84748a7..5dad4bf 100644 --- a/app/src/main/jni/SerialPort.c +++ b/app/src/main/jni/SerialPort.c @@ -1,19 +1,3 @@ -/* - * 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 #include #include @@ -25,143 +9,164 @@ #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) + +static const char *TAG = "serial_port"; #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; - } +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 + * Class: com_casic_detector_uart_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; +JNIEXPORT jobject JNICALL +Java_com_casic_detector_uart_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; - } - } + /* Check arguments */ + { + speed = getBaudRate(baudRate); + if (speed == -1) { + 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; - } - } + /* 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) { + LOGE("Cannot open port"); + 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; - } + /* Configure device */ + { + struct termios cfg; + LOGD("Configuring serial port"); + if (tcgetattr(fd, &cfg)) { + LOGE("tcgetattr() failed"); + close(fd); + return NULL; + } - cfmakeraw(&cfg); - cfsetispeed(&cfg, speed); - cfsetospeed(&cfg, speed); + cfmakeraw(&cfg); + cfsetispeed(&cfg, speed); + cfsetospeed(&cfg, speed); - if (tcsetattr(fd, TCSANOW, &cfg)) - { - LOGE("tcsetattr() failed"); - close(fd); - /* TODO: throw an exception */ - return NULL; - } - } + if (tcsetattr(fd, TCSANOW, &cfg)) { + LOGE("tcsetattr() failed"); + close(fd); + return NULL; + } + } - /* Create a corresponding file descriptor */ - { - jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); - jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "", "()V"); - jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); - mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); - (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint)fd); - } + /* Create a corresponding file descriptor */ + { + jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); + jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "", "()V"); + jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); + mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); + (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint) fd); + } - return mFileDescriptor; + return mFileDescriptor; } /* - * Class: cedric_serial_SerialPort + * Class: com_casic_detector_uart_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"); +JNIEXPORT void JNICALL Java_com_casic_detector_uart_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"); + 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); + jobject mFd = (*env)->GetObjectField(env, thiz, mFdID); + jint descriptor = (*env)->GetIntField(env, mFd, descriptorID); - LOGD("close(fd = %d)", descriptor); - close(descriptor); + LOGD("close(fd = %d)", descriptor); + close(descriptor); } diff --git a/app/src/main/jni/SerialPort.h b/app/src/main/jni/SerialPort.h index 61f1fb2..93a4771 100644 --- a/app/src/main/jni/SerialPort.h +++ b/app/src/main/jni/SerialPort.h @@ -1,27 +1,27 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ #include -/* Header for class android_serialport_api_SerialPort */ +/* Header for class com_casic_detector_uart_SerialPort */ -#ifndef _Included_android_serialport_api_SerialPort -#define _Included_android_serialport_api_SerialPort +#ifndef _Included_com_casic_detector_uart_SerialPort +#define _Included_com_casic_detector_uart_SerialPort #ifdef __cplusplus extern "C" { #endif /* - * Class: android_serialport_api_SerialPort + * Class: com_casic_detector_uart_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); +JNIEXPORT jobject JNICALL Java_com_casic_detector_uart_SerialPort_open + (JNIEnv *, jclass, jstring, jint, jint); /* - * Class: android_serialport_api_SerialPort + * Class: com_casic_detector_uart_SerialPort * Method: close * Signature: ()V */ -JNIEXPORT void JNICALL Java_android_1serialport_1api_SerialPort_close - (JNIEnv *, jobject); +JNIEXPORT void JNICALL Java_com_casic_detector_uart_SerialPort_close + (JNIEnv *, jobject); #ifdef __cplusplus } diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..e8a952a --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include_directories(src/main/jni) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index b4ce9a7..95fbe4e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,13 @@ targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录 daoPackage 'com.casic.detector.greendao'//设置DaoMaster、DaoSession、Dao包名 } + + //配置CMake路径 + externalNativeBuild { + cmake { + path 'CMakeLists.txt' + } + } } static def getBuildDate() { diff --git a/app/src/main/java/android_serialport_api/SerialPort.java b/app/src/main/java/android_serialport_api/SerialPort.java deleted file mode 100644 index 4b975d9..0000000 --- a/app/src/main/java/android_serialport_api/SerialPort.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2009 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. - */ - -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"; - - /* - * Do not remove or rename the field mFd: it is used by native method close(); - */ - private FileDescriptor mFd; - private final FileInputStream mFileInputStream; - private final FileOutputStream mFileOutputStream; - - public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { - - /* Check access permission */ - if (!device.canRead() || !device.canWrite()) { - try { - /* Missing read/write permission, trying to chmod the file */ - Process su; - su = Runtime.getRuntime().exec("/system/bin/su"); - String cmd = "chmod 666 " + 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 - private native static FileDescriptor open(String path, int baudrate, int flags); - - public native void close(); - - static { - System.loadLibrary("serial_port"); - } -} diff --git a/app/src/main/java/android_serialport_api/SerialPortFinder.java b/app/src/main/java/android_serialport_api/SerialPortFinder.java deleted file mode 100644 index 23e6b89..0000000 --- a/app/src/main/java/android_serialport_api/SerialPortFinder.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2009 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. - */ - -package android_serialport_api; - -import android.util.Log; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.LineNumberReader; -import java.util.Iterator; -import java.util.Vector; - -public class SerialPortFinder { - - public class Driver { - public Driver(String name, String root) { - mDriverName = name; - mDeviceRoot = root; - } - - private String mDriverName; - private String mDeviceRoot; - Vector mDevices = null; - - public Vector getDevices() { - if (mDevices == null) { - mDevices = new Vector(); - File dev = new File("/dev"); - File[] files = dev.listFiles(); - int i; - for (i = 0; i < files.length; i++) { - if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) { - Log.d(TAG, "Found new device: " + files[i]); - mDevices.add(files[i]); - } - } - } - return mDevices; - } - - public String getName() { - return mDriverName; - } - } - - private static final String TAG = "SerialPort"; - - private Vector mDrivers = null; - - Vector getDrivers() throws IOException { - if (mDrivers == null) { - mDrivers = new Vector(); - LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers")); - String l; - while ((l = r.readLine()) != null) { - // Issue 3: - // Since driver name may contain spaces, we do not extract driver name with split() - String drivername = l.substring(0, 0x15).trim(); - String[] w = l.split(" +"); - if ((w.length >= 5) && (w[w.length - 1].equals("serial"))) { - Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length - 4]); - mDrivers.add(new Driver(drivername, w[w.length - 4])); - } - } - r.close(); - } - return mDrivers; - } - - public String[] getAllDevices() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getName(); - String value = String.format("%s (%s)", device, driver.getName()); - devices.add(value); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } - - public String[] getAllDevicesPath() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getAbsolutePath(); - devices.add(device); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } -} diff --git a/app/src/main/java/com/casic/detector/base/BaseApplication.kt b/app/src/main/java/com/casic/detector/base/BaseApplication.kt index c36fcea..1250e19 100644 --- a/app/src/main/java/com/casic/detector/base/BaseApplication.kt +++ b/app/src/main/java/com/casic/detector/base/BaseApplication.kt @@ -1,9 +1,9 @@ package com.casic.detector.base import android.app.Application -import android_serialport_api.SerialPort import com.casic.detector.greendao.DaoMaster import com.casic.detector.greendao.DaoSession +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.utils.SaveKeyValues import java.io.File import java.io.IOException diff --git a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt index c7229ad..ca5c1f8 100644 --- a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt +++ b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt @@ -1,8 +1,8 @@ package com.casic.detector.base import android.os.Bundle -import android_serialport_api.SerialPort import androidx.appcompat.app.AppCompatActivity +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.extensions.show import java.io.IOException import java.io.InputStream diff --git a/app/src/main/java/com/casic/detector/uart/SerialPort.java b/app/src/main/java/com/casic/detector/uart/SerialPort.java new file mode 100644 index 0000000..550b461 --- /dev/null +++ b/app/src/main/java/com/casic/detector/uart/SerialPort.java @@ -0,0 +1,73 @@ +package com.casic.detector.uart; + +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"; + + /** + * .so 库名字。需要去掉生成时自带的lib前缀 + * */ + static { + System.loadLibrary("serial_port"); + } + + /** + * JNI + *

+ * 必须用 native 标识JNI方法 + */ + private native static FileDescriptor open(String path, int baudRate, int flags); + + public native void close(); + + /** + * Do not remove or rename the field mFd: it is used by native method close(); + */ + private FileDescriptor mFd; + private final FileInputStream mFileInputStream; + private final FileOutputStream mFileOutputStream; + + public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { + + if (!device.canRead() || !device.canWrite()) { + try { + Process su; + su = Runtime.getRuntime().exec("/system/bin/su"); + String cmd = "chmod 666 " + 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); + } + + public InputStream getInputStream() { + return mFileInputStream; + } + + public OutputStream getOutputStream() { + return mFileOutputStream; + } +} diff --git a/app/src/main/jni/Android.mk b/app/src/main/jni/Android.mk index f4ce1c3..94bf9d0 100644 --- a/app/src/main/jni/Android.mk +++ b/app/src/main/jni/Android.mk @@ -1,26 +1,23 @@ -# -# Copyright 2009 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. -# - +# Android.mk必须以LOCAL_PATH开头,注释#除外 +# 设置工作目录,而my-dir则会返回Android.mk文件所在的目录 LOCAL_PATH := $(call my-dir) +# 借助CLEAR_VARS变量清除除LOCAL_PATH外的所有LOCAL_变量 include $(CLEAR_VARS) +# android-3 对应Android 1.5 TARGET_PLATFORM := android-3 + +# 设置模块的名称,即编译出来.so文件名 +# 注,要和上述步骤中build.gradle中NDK节点设置的名字相同 LOCAL_MODULE := serial_port + +# 指定参与模块编译的C/C++源文件列表,多文件用"\"隔开 LOCAL_SRC_FILES := SerialPort.c + LOCAL_LDLIBS := -llog +# 必须在文件结尾定义编译类型,指定生成的静态库或者共享库在运行时依赖的共享库模块列表。 +# BUILD_SHARED_LIBRARY 共享库,供java或者其他共享库调用 +# BUILD_STATIC_LIBRARY 静态库,供共享库调用,不能直接被java调用 include $(BUILD_SHARED_LIBRARY) diff --git a/app/src/main/jni/SerialPort.c b/app/src/main/jni/SerialPort.c index 84748a7..5dad4bf 100644 --- a/app/src/main/jni/SerialPort.c +++ b/app/src/main/jni/SerialPort.c @@ -1,19 +1,3 @@ -/* - * 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 #include #include @@ -25,143 +9,164 @@ #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) + +static const char *TAG = "serial_port"; #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; - } +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 + * Class: com_casic_detector_uart_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; +JNIEXPORT jobject JNICALL +Java_com_casic_detector_uart_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; - } - } + /* Check arguments */ + { + speed = getBaudRate(baudRate); + if (speed == -1) { + 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; - } - } + /* 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) { + LOGE("Cannot open port"); + 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; - } + /* Configure device */ + { + struct termios cfg; + LOGD("Configuring serial port"); + if (tcgetattr(fd, &cfg)) { + LOGE("tcgetattr() failed"); + close(fd); + return NULL; + } - cfmakeraw(&cfg); - cfsetispeed(&cfg, speed); - cfsetospeed(&cfg, speed); + cfmakeraw(&cfg); + cfsetispeed(&cfg, speed); + cfsetospeed(&cfg, speed); - if (tcsetattr(fd, TCSANOW, &cfg)) - { - LOGE("tcsetattr() failed"); - close(fd); - /* TODO: throw an exception */ - return NULL; - } - } + if (tcsetattr(fd, TCSANOW, &cfg)) { + LOGE("tcsetattr() failed"); + close(fd); + return NULL; + } + } - /* Create a corresponding file descriptor */ - { - jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); - jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "", "()V"); - jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); - mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); - (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint)fd); - } + /* Create a corresponding file descriptor */ + { + jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); + jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "", "()V"); + jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); + mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); + (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint) fd); + } - return mFileDescriptor; + return mFileDescriptor; } /* - * Class: cedric_serial_SerialPort + * Class: com_casic_detector_uart_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"); +JNIEXPORT void JNICALL Java_com_casic_detector_uart_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"); + 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); + jobject mFd = (*env)->GetObjectField(env, thiz, mFdID); + jint descriptor = (*env)->GetIntField(env, mFd, descriptorID); - LOGD("close(fd = %d)", descriptor); - close(descriptor); + LOGD("close(fd = %d)", descriptor); + close(descriptor); } diff --git a/app/src/main/jni/SerialPort.h b/app/src/main/jni/SerialPort.h index 61f1fb2..93a4771 100644 --- a/app/src/main/jni/SerialPort.h +++ b/app/src/main/jni/SerialPort.h @@ -1,27 +1,27 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ #include -/* Header for class android_serialport_api_SerialPort */ +/* Header for class com_casic_detector_uart_SerialPort */ -#ifndef _Included_android_serialport_api_SerialPort -#define _Included_android_serialport_api_SerialPort +#ifndef _Included_com_casic_detector_uart_SerialPort +#define _Included_com_casic_detector_uart_SerialPort #ifdef __cplusplus extern "C" { #endif /* - * Class: android_serialport_api_SerialPort + * Class: com_casic_detector_uart_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); +JNIEXPORT jobject JNICALL Java_com_casic_detector_uart_SerialPort_open + (JNIEnv *, jclass, jstring, jint, jint); /* - * Class: android_serialport_api_SerialPort + * Class: com_casic_detector_uart_SerialPort * Method: close * Signature: ()V */ -JNIEXPORT void JNICALL Java_android_1serialport_1api_SerialPort_close - (JNIEnv *, jobject); +JNIEXPORT void JNICALL Java_com_casic_detector_uart_SerialPort_close + (JNIEnv *, jobject); #ifdef __cplusplus } diff --git a/app/src/main/jni/gen_SerialPort_h.sh b/app/src/main/jni/gen_SerialPort_h.sh index 5414670..d2983c6 100755 --- a/app/src/main/jni/gen_SerialPort_h.sh +++ b/app/src/main/jni/gen_SerialPort_h.sh @@ -1,3 +1,3 @@ #!/bin/sh -javah -o SerialPort.h -jni -classpath ../java android_serialport_api.SerialPort +javah -encoding utf-8 -o SerialPort.h -jni -classpath ../java com.casic.detector.uart.SerialPort diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..e8a952a --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include_directories(src/main/jni) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index b4ce9a7..95fbe4e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,13 @@ targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录 daoPackage 'com.casic.detector.greendao'//设置DaoMaster、DaoSession、Dao包名 } + + //配置CMake路径 + externalNativeBuild { + cmake { + path 'CMakeLists.txt' + } + } } static def getBuildDate() { diff --git a/app/src/main/java/android_serialport_api/SerialPort.java b/app/src/main/java/android_serialport_api/SerialPort.java deleted file mode 100644 index 4b975d9..0000000 --- a/app/src/main/java/android_serialport_api/SerialPort.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2009 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. - */ - -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"; - - /* - * Do not remove or rename the field mFd: it is used by native method close(); - */ - private FileDescriptor mFd; - private final FileInputStream mFileInputStream; - private final FileOutputStream mFileOutputStream; - - public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { - - /* Check access permission */ - if (!device.canRead() || !device.canWrite()) { - try { - /* Missing read/write permission, trying to chmod the file */ - Process su; - su = Runtime.getRuntime().exec("/system/bin/su"); - String cmd = "chmod 666 " + 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 - private native static FileDescriptor open(String path, int baudrate, int flags); - - public native void close(); - - static { - System.loadLibrary("serial_port"); - } -} diff --git a/app/src/main/java/android_serialport_api/SerialPortFinder.java b/app/src/main/java/android_serialport_api/SerialPortFinder.java deleted file mode 100644 index 23e6b89..0000000 --- a/app/src/main/java/android_serialport_api/SerialPortFinder.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2009 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. - */ - -package android_serialport_api; - -import android.util.Log; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.LineNumberReader; -import java.util.Iterator; -import java.util.Vector; - -public class SerialPortFinder { - - public class Driver { - public Driver(String name, String root) { - mDriverName = name; - mDeviceRoot = root; - } - - private String mDriverName; - private String mDeviceRoot; - Vector mDevices = null; - - public Vector getDevices() { - if (mDevices == null) { - mDevices = new Vector(); - File dev = new File("/dev"); - File[] files = dev.listFiles(); - int i; - for (i = 0; i < files.length; i++) { - if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) { - Log.d(TAG, "Found new device: " + files[i]); - mDevices.add(files[i]); - } - } - } - return mDevices; - } - - public String getName() { - return mDriverName; - } - } - - private static final String TAG = "SerialPort"; - - private Vector mDrivers = null; - - Vector getDrivers() throws IOException { - if (mDrivers == null) { - mDrivers = new Vector(); - LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers")); - String l; - while ((l = r.readLine()) != null) { - // Issue 3: - // Since driver name may contain spaces, we do not extract driver name with split() - String drivername = l.substring(0, 0x15).trim(); - String[] w = l.split(" +"); - if ((w.length >= 5) && (w[w.length - 1].equals("serial"))) { - Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length - 4]); - mDrivers.add(new Driver(drivername, w[w.length - 4])); - } - } - r.close(); - } - return mDrivers; - } - - public String[] getAllDevices() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getName(); - String value = String.format("%s (%s)", device, driver.getName()); - devices.add(value); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } - - public String[] getAllDevicesPath() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getAbsolutePath(); - devices.add(device); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } -} diff --git a/app/src/main/java/com/casic/detector/base/BaseApplication.kt b/app/src/main/java/com/casic/detector/base/BaseApplication.kt index c36fcea..1250e19 100644 --- a/app/src/main/java/com/casic/detector/base/BaseApplication.kt +++ b/app/src/main/java/com/casic/detector/base/BaseApplication.kt @@ -1,9 +1,9 @@ package com.casic.detector.base import android.app.Application -import android_serialport_api.SerialPort import com.casic.detector.greendao.DaoMaster import com.casic.detector.greendao.DaoSession +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.utils.SaveKeyValues import java.io.File import java.io.IOException diff --git a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt index c7229ad..ca5c1f8 100644 --- a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt +++ b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt @@ -1,8 +1,8 @@ package com.casic.detector.base import android.os.Bundle -import android_serialport_api.SerialPort import androidx.appcompat.app.AppCompatActivity +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.extensions.show import java.io.IOException import java.io.InputStream diff --git a/app/src/main/java/com/casic/detector/uart/SerialPort.java b/app/src/main/java/com/casic/detector/uart/SerialPort.java new file mode 100644 index 0000000..550b461 --- /dev/null +++ b/app/src/main/java/com/casic/detector/uart/SerialPort.java @@ -0,0 +1,73 @@ +package com.casic.detector.uart; + +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"; + + /** + * .so 库名字。需要去掉生成时自带的lib前缀 + * */ + static { + System.loadLibrary("serial_port"); + } + + /** + * JNI + *

+ * 必须用 native 标识JNI方法 + */ + private native static FileDescriptor open(String path, int baudRate, int flags); + + public native void close(); + + /** + * Do not remove or rename the field mFd: it is used by native method close(); + */ + private FileDescriptor mFd; + private final FileInputStream mFileInputStream; + private final FileOutputStream mFileOutputStream; + + public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { + + if (!device.canRead() || !device.canWrite()) { + try { + Process su; + su = Runtime.getRuntime().exec("/system/bin/su"); + String cmd = "chmod 666 " + 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); + } + + public InputStream getInputStream() { + return mFileInputStream; + } + + public OutputStream getOutputStream() { + return mFileOutputStream; + } +} diff --git a/app/src/main/jni/Android.mk b/app/src/main/jni/Android.mk index f4ce1c3..94bf9d0 100644 --- a/app/src/main/jni/Android.mk +++ b/app/src/main/jni/Android.mk @@ -1,26 +1,23 @@ -# -# Copyright 2009 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. -# - +# Android.mk必须以LOCAL_PATH开头,注释#除外 +# 设置工作目录,而my-dir则会返回Android.mk文件所在的目录 LOCAL_PATH := $(call my-dir) +# 借助CLEAR_VARS变量清除除LOCAL_PATH外的所有LOCAL_变量 include $(CLEAR_VARS) +# android-3 对应Android 1.5 TARGET_PLATFORM := android-3 + +# 设置模块的名称,即编译出来.so文件名 +# 注,要和上述步骤中build.gradle中NDK节点设置的名字相同 LOCAL_MODULE := serial_port + +# 指定参与模块编译的C/C++源文件列表,多文件用"\"隔开 LOCAL_SRC_FILES := SerialPort.c + LOCAL_LDLIBS := -llog +# 必须在文件结尾定义编译类型,指定生成的静态库或者共享库在运行时依赖的共享库模块列表。 +# BUILD_SHARED_LIBRARY 共享库,供java或者其他共享库调用 +# BUILD_STATIC_LIBRARY 静态库,供共享库调用,不能直接被java调用 include $(BUILD_SHARED_LIBRARY) diff --git a/app/src/main/jni/SerialPort.c b/app/src/main/jni/SerialPort.c index 84748a7..5dad4bf 100644 --- a/app/src/main/jni/SerialPort.c +++ b/app/src/main/jni/SerialPort.c @@ -1,19 +1,3 @@ -/* - * 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 #include #include @@ -25,143 +9,164 @@ #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) + +static const char *TAG = "serial_port"; #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; - } +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 + * Class: com_casic_detector_uart_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; +JNIEXPORT jobject JNICALL +Java_com_casic_detector_uart_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; - } - } + /* Check arguments */ + { + speed = getBaudRate(baudRate); + if (speed == -1) { + 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; - } - } + /* 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) { + LOGE("Cannot open port"); + 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; - } + /* Configure device */ + { + struct termios cfg; + LOGD("Configuring serial port"); + if (tcgetattr(fd, &cfg)) { + LOGE("tcgetattr() failed"); + close(fd); + return NULL; + } - cfmakeraw(&cfg); - cfsetispeed(&cfg, speed); - cfsetospeed(&cfg, speed); + cfmakeraw(&cfg); + cfsetispeed(&cfg, speed); + cfsetospeed(&cfg, speed); - if (tcsetattr(fd, TCSANOW, &cfg)) - { - LOGE("tcsetattr() failed"); - close(fd); - /* TODO: throw an exception */ - return NULL; - } - } + if (tcsetattr(fd, TCSANOW, &cfg)) { + LOGE("tcsetattr() failed"); + close(fd); + return NULL; + } + } - /* Create a corresponding file descriptor */ - { - jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); - jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "", "()V"); - jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); - mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); - (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint)fd); - } + /* Create a corresponding file descriptor */ + { + jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); + jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "", "()V"); + jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); + mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); + (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint) fd); + } - return mFileDescriptor; + return mFileDescriptor; } /* - * Class: cedric_serial_SerialPort + * Class: com_casic_detector_uart_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"); +JNIEXPORT void JNICALL Java_com_casic_detector_uart_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"); + 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); + jobject mFd = (*env)->GetObjectField(env, thiz, mFdID); + jint descriptor = (*env)->GetIntField(env, mFd, descriptorID); - LOGD("close(fd = %d)", descriptor); - close(descriptor); + LOGD("close(fd = %d)", descriptor); + close(descriptor); } diff --git a/app/src/main/jni/SerialPort.h b/app/src/main/jni/SerialPort.h index 61f1fb2..93a4771 100644 --- a/app/src/main/jni/SerialPort.h +++ b/app/src/main/jni/SerialPort.h @@ -1,27 +1,27 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ #include -/* Header for class android_serialport_api_SerialPort */ +/* Header for class com_casic_detector_uart_SerialPort */ -#ifndef _Included_android_serialport_api_SerialPort -#define _Included_android_serialport_api_SerialPort +#ifndef _Included_com_casic_detector_uart_SerialPort +#define _Included_com_casic_detector_uart_SerialPort #ifdef __cplusplus extern "C" { #endif /* - * Class: android_serialport_api_SerialPort + * Class: com_casic_detector_uart_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); +JNIEXPORT jobject JNICALL Java_com_casic_detector_uart_SerialPort_open + (JNIEnv *, jclass, jstring, jint, jint); /* - * Class: android_serialport_api_SerialPort + * Class: com_casic_detector_uart_SerialPort * Method: close * Signature: ()V */ -JNIEXPORT void JNICALL Java_android_1serialport_1api_SerialPort_close - (JNIEnv *, jobject); +JNIEXPORT void JNICALL Java_com_casic_detector_uart_SerialPort_close + (JNIEnv *, jobject); #ifdef __cplusplus } diff --git a/app/src/main/jni/gen_SerialPort_h.sh b/app/src/main/jni/gen_SerialPort_h.sh index 5414670..d2983c6 100755 --- a/app/src/main/jni/gen_SerialPort_h.sh +++ b/app/src/main/jni/gen_SerialPort_h.sh @@ -1,3 +1,3 @@ #!/bin/sh -javah -o SerialPort.h -jni -classpath ../java android_serialport_api.SerialPort +javah -encoding utf-8 -o SerialPort.h -jni -classpath ../java com.casic.detector.uart.SerialPort diff --git a/app/src/main/jniLibs/arm64-v8a/libserial_port.so b/app/src/main/jniLibs/arm64-v8a/libserial_port.so old mode 100755 new mode 100644 index fe664b1..d121a14 --- a/app/src/main/jniLibs/arm64-v8a/libserial_port.so +++ b/app/src/main/jniLibs/arm64-v8a/libserial_port.so Binary files differ diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..e8a952a --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include_directories(src/main/jni) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index b4ce9a7..95fbe4e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,13 @@ targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录 daoPackage 'com.casic.detector.greendao'//设置DaoMaster、DaoSession、Dao包名 } + + //配置CMake路径 + externalNativeBuild { + cmake { + path 'CMakeLists.txt' + } + } } static def getBuildDate() { diff --git a/app/src/main/java/android_serialport_api/SerialPort.java b/app/src/main/java/android_serialport_api/SerialPort.java deleted file mode 100644 index 4b975d9..0000000 --- a/app/src/main/java/android_serialport_api/SerialPort.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2009 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. - */ - -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"; - - /* - * Do not remove or rename the field mFd: it is used by native method close(); - */ - private FileDescriptor mFd; - private final FileInputStream mFileInputStream; - private final FileOutputStream mFileOutputStream; - - public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { - - /* Check access permission */ - if (!device.canRead() || !device.canWrite()) { - try { - /* Missing read/write permission, trying to chmod the file */ - Process su; - su = Runtime.getRuntime().exec("/system/bin/su"); - String cmd = "chmod 666 " + 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 - private native static FileDescriptor open(String path, int baudrate, int flags); - - public native void close(); - - static { - System.loadLibrary("serial_port"); - } -} diff --git a/app/src/main/java/android_serialport_api/SerialPortFinder.java b/app/src/main/java/android_serialport_api/SerialPortFinder.java deleted file mode 100644 index 23e6b89..0000000 --- a/app/src/main/java/android_serialport_api/SerialPortFinder.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2009 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. - */ - -package android_serialport_api; - -import android.util.Log; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.LineNumberReader; -import java.util.Iterator; -import java.util.Vector; - -public class SerialPortFinder { - - public class Driver { - public Driver(String name, String root) { - mDriverName = name; - mDeviceRoot = root; - } - - private String mDriverName; - private String mDeviceRoot; - Vector mDevices = null; - - public Vector getDevices() { - if (mDevices == null) { - mDevices = new Vector(); - File dev = new File("/dev"); - File[] files = dev.listFiles(); - int i; - for (i = 0; i < files.length; i++) { - if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) { - Log.d(TAG, "Found new device: " + files[i]); - mDevices.add(files[i]); - } - } - } - return mDevices; - } - - public String getName() { - return mDriverName; - } - } - - private static final String TAG = "SerialPort"; - - private Vector mDrivers = null; - - Vector getDrivers() throws IOException { - if (mDrivers == null) { - mDrivers = new Vector(); - LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers")); - String l; - while ((l = r.readLine()) != null) { - // Issue 3: - // Since driver name may contain spaces, we do not extract driver name with split() - String drivername = l.substring(0, 0x15).trim(); - String[] w = l.split(" +"); - if ((w.length >= 5) && (w[w.length - 1].equals("serial"))) { - Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length - 4]); - mDrivers.add(new Driver(drivername, w[w.length - 4])); - } - } - r.close(); - } - return mDrivers; - } - - public String[] getAllDevices() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getName(); - String value = String.format("%s (%s)", device, driver.getName()); - devices.add(value); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } - - public String[] getAllDevicesPath() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getAbsolutePath(); - devices.add(device); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } -} diff --git a/app/src/main/java/com/casic/detector/base/BaseApplication.kt b/app/src/main/java/com/casic/detector/base/BaseApplication.kt index c36fcea..1250e19 100644 --- a/app/src/main/java/com/casic/detector/base/BaseApplication.kt +++ b/app/src/main/java/com/casic/detector/base/BaseApplication.kt @@ -1,9 +1,9 @@ package com.casic.detector.base import android.app.Application -import android_serialport_api.SerialPort import com.casic.detector.greendao.DaoMaster import com.casic.detector.greendao.DaoSession +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.utils.SaveKeyValues import java.io.File import java.io.IOException diff --git a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt index c7229ad..ca5c1f8 100644 --- a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt +++ b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt @@ -1,8 +1,8 @@ package com.casic.detector.base import android.os.Bundle -import android_serialport_api.SerialPort import androidx.appcompat.app.AppCompatActivity +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.extensions.show import java.io.IOException import java.io.InputStream diff --git a/app/src/main/java/com/casic/detector/uart/SerialPort.java b/app/src/main/java/com/casic/detector/uart/SerialPort.java new file mode 100644 index 0000000..550b461 --- /dev/null +++ b/app/src/main/java/com/casic/detector/uart/SerialPort.java @@ -0,0 +1,73 @@ +package com.casic.detector.uart; + +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"; + + /** + * .so 库名字。需要去掉生成时自带的lib前缀 + * */ + static { + System.loadLibrary("serial_port"); + } + + /** + * JNI + *

+ * 必须用 native 标识JNI方法 + */ + private native static FileDescriptor open(String path, int baudRate, int flags); + + public native void close(); + + /** + * Do not remove or rename the field mFd: it is used by native method close(); + */ + private FileDescriptor mFd; + private final FileInputStream mFileInputStream; + private final FileOutputStream mFileOutputStream; + + public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { + + if (!device.canRead() || !device.canWrite()) { + try { + Process su; + su = Runtime.getRuntime().exec("/system/bin/su"); + String cmd = "chmod 666 " + 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); + } + + public InputStream getInputStream() { + return mFileInputStream; + } + + public OutputStream getOutputStream() { + return mFileOutputStream; + } +} diff --git a/app/src/main/jni/Android.mk b/app/src/main/jni/Android.mk index f4ce1c3..94bf9d0 100644 --- a/app/src/main/jni/Android.mk +++ b/app/src/main/jni/Android.mk @@ -1,26 +1,23 @@ -# -# Copyright 2009 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. -# - +# Android.mk必须以LOCAL_PATH开头,注释#除外 +# 设置工作目录,而my-dir则会返回Android.mk文件所在的目录 LOCAL_PATH := $(call my-dir) +# 借助CLEAR_VARS变量清除除LOCAL_PATH外的所有LOCAL_变量 include $(CLEAR_VARS) +# android-3 对应Android 1.5 TARGET_PLATFORM := android-3 + +# 设置模块的名称,即编译出来.so文件名 +# 注,要和上述步骤中build.gradle中NDK节点设置的名字相同 LOCAL_MODULE := serial_port + +# 指定参与模块编译的C/C++源文件列表,多文件用"\"隔开 LOCAL_SRC_FILES := SerialPort.c + LOCAL_LDLIBS := -llog +# 必须在文件结尾定义编译类型,指定生成的静态库或者共享库在运行时依赖的共享库模块列表。 +# BUILD_SHARED_LIBRARY 共享库,供java或者其他共享库调用 +# BUILD_STATIC_LIBRARY 静态库,供共享库调用,不能直接被java调用 include $(BUILD_SHARED_LIBRARY) diff --git a/app/src/main/jni/SerialPort.c b/app/src/main/jni/SerialPort.c index 84748a7..5dad4bf 100644 --- a/app/src/main/jni/SerialPort.c +++ b/app/src/main/jni/SerialPort.c @@ -1,19 +1,3 @@ -/* - * 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 #include #include @@ -25,143 +9,164 @@ #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) + +static const char *TAG = "serial_port"; #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; - } +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 + * Class: com_casic_detector_uart_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; +JNIEXPORT jobject JNICALL +Java_com_casic_detector_uart_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; - } - } + /* Check arguments */ + { + speed = getBaudRate(baudRate); + if (speed == -1) { + 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; - } - } + /* 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) { + LOGE("Cannot open port"); + 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; - } + /* Configure device */ + { + struct termios cfg; + LOGD("Configuring serial port"); + if (tcgetattr(fd, &cfg)) { + LOGE("tcgetattr() failed"); + close(fd); + return NULL; + } - cfmakeraw(&cfg); - cfsetispeed(&cfg, speed); - cfsetospeed(&cfg, speed); + cfmakeraw(&cfg); + cfsetispeed(&cfg, speed); + cfsetospeed(&cfg, speed); - if (tcsetattr(fd, TCSANOW, &cfg)) - { - LOGE("tcsetattr() failed"); - close(fd); - /* TODO: throw an exception */ - return NULL; - } - } + if (tcsetattr(fd, TCSANOW, &cfg)) { + LOGE("tcsetattr() failed"); + close(fd); + return NULL; + } + } - /* Create a corresponding file descriptor */ - { - jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); - jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "", "()V"); - jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); - mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); - (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint)fd); - } + /* Create a corresponding file descriptor */ + { + jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); + jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "", "()V"); + jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); + mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); + (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint) fd); + } - return mFileDescriptor; + return mFileDescriptor; } /* - * Class: cedric_serial_SerialPort + * Class: com_casic_detector_uart_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"); +JNIEXPORT void JNICALL Java_com_casic_detector_uart_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"); + 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); + jobject mFd = (*env)->GetObjectField(env, thiz, mFdID); + jint descriptor = (*env)->GetIntField(env, mFd, descriptorID); - LOGD("close(fd = %d)", descriptor); - close(descriptor); + LOGD("close(fd = %d)", descriptor); + close(descriptor); } diff --git a/app/src/main/jni/SerialPort.h b/app/src/main/jni/SerialPort.h index 61f1fb2..93a4771 100644 --- a/app/src/main/jni/SerialPort.h +++ b/app/src/main/jni/SerialPort.h @@ -1,27 +1,27 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ #include -/* Header for class android_serialport_api_SerialPort */ +/* Header for class com_casic_detector_uart_SerialPort */ -#ifndef _Included_android_serialport_api_SerialPort -#define _Included_android_serialport_api_SerialPort +#ifndef _Included_com_casic_detector_uart_SerialPort +#define _Included_com_casic_detector_uart_SerialPort #ifdef __cplusplus extern "C" { #endif /* - * Class: android_serialport_api_SerialPort + * Class: com_casic_detector_uart_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); +JNIEXPORT jobject JNICALL Java_com_casic_detector_uart_SerialPort_open + (JNIEnv *, jclass, jstring, jint, jint); /* - * Class: android_serialport_api_SerialPort + * Class: com_casic_detector_uart_SerialPort * Method: close * Signature: ()V */ -JNIEXPORT void JNICALL Java_android_1serialport_1api_SerialPort_close - (JNIEnv *, jobject); +JNIEXPORT void JNICALL Java_com_casic_detector_uart_SerialPort_close + (JNIEnv *, jobject); #ifdef __cplusplus } diff --git a/app/src/main/jni/gen_SerialPort_h.sh b/app/src/main/jni/gen_SerialPort_h.sh index 5414670..d2983c6 100755 --- a/app/src/main/jni/gen_SerialPort_h.sh +++ b/app/src/main/jni/gen_SerialPort_h.sh @@ -1,3 +1,3 @@ #!/bin/sh -javah -o SerialPort.h -jni -classpath ../java android_serialport_api.SerialPort +javah -encoding utf-8 -o SerialPort.h -jni -classpath ../java com.casic.detector.uart.SerialPort diff --git a/app/src/main/jniLibs/arm64-v8a/libserial_port.so b/app/src/main/jniLibs/arm64-v8a/libserial_port.so old mode 100755 new mode 100644 index fe664b1..d121a14 --- a/app/src/main/jniLibs/arm64-v8a/libserial_port.so +++ b/app/src/main/jniLibs/arm64-v8a/libserial_port.so Binary files differ diff --git a/app/src/main/jniLibs/armeabi-v7a/libserial_port.so b/app/src/main/jniLibs/armeabi-v7a/libserial_port.so old mode 100755 new mode 100644 index 88819f8..bcfa53e --- a/app/src/main/jniLibs/armeabi-v7a/libserial_port.so +++ b/app/src/main/jniLibs/armeabi-v7a/libserial_port.so Binary files differ diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..e8a952a --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include_directories(src/main/jni) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index b4ce9a7..95fbe4e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,13 @@ targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录 daoPackage 'com.casic.detector.greendao'//设置DaoMaster、DaoSession、Dao包名 } + + //配置CMake路径 + externalNativeBuild { + cmake { + path 'CMakeLists.txt' + } + } } static def getBuildDate() { diff --git a/app/src/main/java/android_serialport_api/SerialPort.java b/app/src/main/java/android_serialport_api/SerialPort.java deleted file mode 100644 index 4b975d9..0000000 --- a/app/src/main/java/android_serialport_api/SerialPort.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2009 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. - */ - -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"; - - /* - * Do not remove or rename the field mFd: it is used by native method close(); - */ - private FileDescriptor mFd; - private final FileInputStream mFileInputStream; - private final FileOutputStream mFileOutputStream; - - public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { - - /* Check access permission */ - if (!device.canRead() || !device.canWrite()) { - try { - /* Missing read/write permission, trying to chmod the file */ - Process su; - su = Runtime.getRuntime().exec("/system/bin/su"); - String cmd = "chmod 666 " + 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 - private native static FileDescriptor open(String path, int baudrate, int flags); - - public native void close(); - - static { - System.loadLibrary("serial_port"); - } -} diff --git a/app/src/main/java/android_serialport_api/SerialPortFinder.java b/app/src/main/java/android_serialport_api/SerialPortFinder.java deleted file mode 100644 index 23e6b89..0000000 --- a/app/src/main/java/android_serialport_api/SerialPortFinder.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2009 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. - */ - -package android_serialport_api; - -import android.util.Log; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.LineNumberReader; -import java.util.Iterator; -import java.util.Vector; - -public class SerialPortFinder { - - public class Driver { - public Driver(String name, String root) { - mDriverName = name; - mDeviceRoot = root; - } - - private String mDriverName; - private String mDeviceRoot; - Vector mDevices = null; - - public Vector getDevices() { - if (mDevices == null) { - mDevices = new Vector(); - File dev = new File("/dev"); - File[] files = dev.listFiles(); - int i; - for (i = 0; i < files.length; i++) { - if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) { - Log.d(TAG, "Found new device: " + files[i]); - mDevices.add(files[i]); - } - } - } - return mDevices; - } - - public String getName() { - return mDriverName; - } - } - - private static final String TAG = "SerialPort"; - - private Vector mDrivers = null; - - Vector getDrivers() throws IOException { - if (mDrivers == null) { - mDrivers = new Vector(); - LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers")); - String l; - while ((l = r.readLine()) != null) { - // Issue 3: - // Since driver name may contain spaces, we do not extract driver name with split() - String drivername = l.substring(0, 0x15).trim(); - String[] w = l.split(" +"); - if ((w.length >= 5) && (w[w.length - 1].equals("serial"))) { - Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length - 4]); - mDrivers.add(new Driver(drivername, w[w.length - 4])); - } - } - r.close(); - } - return mDrivers; - } - - public String[] getAllDevices() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getName(); - String value = String.format("%s (%s)", device, driver.getName()); - devices.add(value); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } - - public String[] getAllDevicesPath() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getAbsolutePath(); - devices.add(device); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } -} diff --git a/app/src/main/java/com/casic/detector/base/BaseApplication.kt b/app/src/main/java/com/casic/detector/base/BaseApplication.kt index c36fcea..1250e19 100644 --- a/app/src/main/java/com/casic/detector/base/BaseApplication.kt +++ b/app/src/main/java/com/casic/detector/base/BaseApplication.kt @@ -1,9 +1,9 @@ package com.casic.detector.base import android.app.Application -import android_serialport_api.SerialPort import com.casic.detector.greendao.DaoMaster import com.casic.detector.greendao.DaoSession +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.utils.SaveKeyValues import java.io.File import java.io.IOException diff --git a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt index c7229ad..ca5c1f8 100644 --- a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt +++ b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt @@ -1,8 +1,8 @@ package com.casic.detector.base import android.os.Bundle -import android_serialport_api.SerialPort import androidx.appcompat.app.AppCompatActivity +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.extensions.show import java.io.IOException import java.io.InputStream diff --git a/app/src/main/java/com/casic/detector/uart/SerialPort.java b/app/src/main/java/com/casic/detector/uart/SerialPort.java new file mode 100644 index 0000000..550b461 --- /dev/null +++ b/app/src/main/java/com/casic/detector/uart/SerialPort.java @@ -0,0 +1,73 @@ +package com.casic.detector.uart; + +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"; + + /** + * .so 库名字。需要去掉生成时自带的lib前缀 + * */ + static { + System.loadLibrary("serial_port"); + } + + /** + * JNI + *

+ * 必须用 native 标识JNI方法 + */ + private native static FileDescriptor open(String path, int baudRate, int flags); + + public native void close(); + + /** + * Do not remove or rename the field mFd: it is used by native method close(); + */ + private FileDescriptor mFd; + private final FileInputStream mFileInputStream; + private final FileOutputStream mFileOutputStream; + + public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { + + if (!device.canRead() || !device.canWrite()) { + try { + Process su; + su = Runtime.getRuntime().exec("/system/bin/su"); + String cmd = "chmod 666 " + 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); + } + + public InputStream getInputStream() { + return mFileInputStream; + } + + public OutputStream getOutputStream() { + return mFileOutputStream; + } +} diff --git a/app/src/main/jni/Android.mk b/app/src/main/jni/Android.mk index f4ce1c3..94bf9d0 100644 --- a/app/src/main/jni/Android.mk +++ b/app/src/main/jni/Android.mk @@ -1,26 +1,23 @@ -# -# Copyright 2009 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. -# - +# Android.mk必须以LOCAL_PATH开头,注释#除外 +# 设置工作目录,而my-dir则会返回Android.mk文件所在的目录 LOCAL_PATH := $(call my-dir) +# 借助CLEAR_VARS变量清除除LOCAL_PATH外的所有LOCAL_变量 include $(CLEAR_VARS) +# android-3 对应Android 1.5 TARGET_PLATFORM := android-3 + +# 设置模块的名称,即编译出来.so文件名 +# 注,要和上述步骤中build.gradle中NDK节点设置的名字相同 LOCAL_MODULE := serial_port + +# 指定参与模块编译的C/C++源文件列表,多文件用"\"隔开 LOCAL_SRC_FILES := SerialPort.c + LOCAL_LDLIBS := -llog +# 必须在文件结尾定义编译类型,指定生成的静态库或者共享库在运行时依赖的共享库模块列表。 +# BUILD_SHARED_LIBRARY 共享库,供java或者其他共享库调用 +# BUILD_STATIC_LIBRARY 静态库,供共享库调用,不能直接被java调用 include $(BUILD_SHARED_LIBRARY) diff --git a/app/src/main/jni/SerialPort.c b/app/src/main/jni/SerialPort.c index 84748a7..5dad4bf 100644 --- a/app/src/main/jni/SerialPort.c +++ b/app/src/main/jni/SerialPort.c @@ -1,19 +1,3 @@ -/* - * 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 #include #include @@ -25,143 +9,164 @@ #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) + +static const char *TAG = "serial_port"; #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; - } +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 + * Class: com_casic_detector_uart_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; +JNIEXPORT jobject JNICALL +Java_com_casic_detector_uart_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; - } - } + /* Check arguments */ + { + speed = getBaudRate(baudRate); + if (speed == -1) { + 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; - } - } + /* 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) { + LOGE("Cannot open port"); + 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; - } + /* Configure device */ + { + struct termios cfg; + LOGD("Configuring serial port"); + if (tcgetattr(fd, &cfg)) { + LOGE("tcgetattr() failed"); + close(fd); + return NULL; + } - cfmakeraw(&cfg); - cfsetispeed(&cfg, speed); - cfsetospeed(&cfg, speed); + cfmakeraw(&cfg); + cfsetispeed(&cfg, speed); + cfsetospeed(&cfg, speed); - if (tcsetattr(fd, TCSANOW, &cfg)) - { - LOGE("tcsetattr() failed"); - close(fd); - /* TODO: throw an exception */ - return NULL; - } - } + if (tcsetattr(fd, TCSANOW, &cfg)) { + LOGE("tcsetattr() failed"); + close(fd); + return NULL; + } + } - /* Create a corresponding file descriptor */ - { - jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); - jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "", "()V"); - jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); - mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); - (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint)fd); - } + /* Create a corresponding file descriptor */ + { + jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); + jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "", "()V"); + jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); + mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); + (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint) fd); + } - return mFileDescriptor; + return mFileDescriptor; } /* - * Class: cedric_serial_SerialPort + * Class: com_casic_detector_uart_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"); +JNIEXPORT void JNICALL Java_com_casic_detector_uart_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"); + 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); + jobject mFd = (*env)->GetObjectField(env, thiz, mFdID); + jint descriptor = (*env)->GetIntField(env, mFd, descriptorID); - LOGD("close(fd = %d)", descriptor); - close(descriptor); + LOGD("close(fd = %d)", descriptor); + close(descriptor); } diff --git a/app/src/main/jni/SerialPort.h b/app/src/main/jni/SerialPort.h index 61f1fb2..93a4771 100644 --- a/app/src/main/jni/SerialPort.h +++ b/app/src/main/jni/SerialPort.h @@ -1,27 +1,27 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ #include -/* Header for class android_serialport_api_SerialPort */ +/* Header for class com_casic_detector_uart_SerialPort */ -#ifndef _Included_android_serialport_api_SerialPort -#define _Included_android_serialport_api_SerialPort +#ifndef _Included_com_casic_detector_uart_SerialPort +#define _Included_com_casic_detector_uart_SerialPort #ifdef __cplusplus extern "C" { #endif /* - * Class: android_serialport_api_SerialPort + * Class: com_casic_detector_uart_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); +JNIEXPORT jobject JNICALL Java_com_casic_detector_uart_SerialPort_open + (JNIEnv *, jclass, jstring, jint, jint); /* - * Class: android_serialport_api_SerialPort + * Class: com_casic_detector_uart_SerialPort * Method: close * Signature: ()V */ -JNIEXPORT void JNICALL Java_android_1serialport_1api_SerialPort_close - (JNIEnv *, jobject); +JNIEXPORT void JNICALL Java_com_casic_detector_uart_SerialPort_close + (JNIEnv *, jobject); #ifdef __cplusplus } diff --git a/app/src/main/jni/gen_SerialPort_h.sh b/app/src/main/jni/gen_SerialPort_h.sh index 5414670..d2983c6 100755 --- a/app/src/main/jni/gen_SerialPort_h.sh +++ b/app/src/main/jni/gen_SerialPort_h.sh @@ -1,3 +1,3 @@ #!/bin/sh -javah -o SerialPort.h -jni -classpath ../java android_serialport_api.SerialPort +javah -encoding utf-8 -o SerialPort.h -jni -classpath ../java com.casic.detector.uart.SerialPort diff --git a/app/src/main/jniLibs/arm64-v8a/libserial_port.so b/app/src/main/jniLibs/arm64-v8a/libserial_port.so old mode 100755 new mode 100644 index fe664b1..d121a14 --- a/app/src/main/jniLibs/arm64-v8a/libserial_port.so +++ b/app/src/main/jniLibs/arm64-v8a/libserial_port.so Binary files differ diff --git a/app/src/main/jniLibs/armeabi-v7a/libserial_port.so b/app/src/main/jniLibs/armeabi-v7a/libserial_port.so old mode 100755 new mode 100644 index 88819f8..bcfa53e --- a/app/src/main/jniLibs/armeabi-v7a/libserial_port.so +++ b/app/src/main/jniLibs/armeabi-v7a/libserial_port.so Binary files differ diff --git a/app/src/main/jniLibs/x86/libserial_port.so b/app/src/main/jniLibs/x86/libserial_port.so old mode 100755 new mode 100644 index f6eb9ba..4ebea50 --- a/app/src/main/jniLibs/x86/libserial_port.so +++ b/app/src/main/jniLibs/x86/libserial_port.so Binary files differ diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..e8a952a --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include_directories(src/main/jni) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index b4ce9a7..95fbe4e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,13 @@ targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录 daoPackage 'com.casic.detector.greendao'//设置DaoMaster、DaoSession、Dao包名 } + + //配置CMake路径 + externalNativeBuild { + cmake { + path 'CMakeLists.txt' + } + } } static def getBuildDate() { diff --git a/app/src/main/java/android_serialport_api/SerialPort.java b/app/src/main/java/android_serialport_api/SerialPort.java deleted file mode 100644 index 4b975d9..0000000 --- a/app/src/main/java/android_serialport_api/SerialPort.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2009 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. - */ - -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"; - - /* - * Do not remove or rename the field mFd: it is used by native method close(); - */ - private FileDescriptor mFd; - private final FileInputStream mFileInputStream; - private final FileOutputStream mFileOutputStream; - - public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { - - /* Check access permission */ - if (!device.canRead() || !device.canWrite()) { - try { - /* Missing read/write permission, trying to chmod the file */ - Process su; - su = Runtime.getRuntime().exec("/system/bin/su"); - String cmd = "chmod 666 " + 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 - private native static FileDescriptor open(String path, int baudrate, int flags); - - public native void close(); - - static { - System.loadLibrary("serial_port"); - } -} diff --git a/app/src/main/java/android_serialport_api/SerialPortFinder.java b/app/src/main/java/android_serialport_api/SerialPortFinder.java deleted file mode 100644 index 23e6b89..0000000 --- a/app/src/main/java/android_serialport_api/SerialPortFinder.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2009 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. - */ - -package android_serialport_api; - -import android.util.Log; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.LineNumberReader; -import java.util.Iterator; -import java.util.Vector; - -public class SerialPortFinder { - - public class Driver { - public Driver(String name, String root) { - mDriverName = name; - mDeviceRoot = root; - } - - private String mDriverName; - private String mDeviceRoot; - Vector mDevices = null; - - public Vector getDevices() { - if (mDevices == null) { - mDevices = new Vector(); - File dev = new File("/dev"); - File[] files = dev.listFiles(); - int i; - for (i = 0; i < files.length; i++) { - if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) { - Log.d(TAG, "Found new device: " + files[i]); - mDevices.add(files[i]); - } - } - } - return mDevices; - } - - public String getName() { - return mDriverName; - } - } - - private static final String TAG = "SerialPort"; - - private Vector mDrivers = null; - - Vector getDrivers() throws IOException { - if (mDrivers == null) { - mDrivers = new Vector(); - LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers")); - String l; - while ((l = r.readLine()) != null) { - // Issue 3: - // Since driver name may contain spaces, we do not extract driver name with split() - String drivername = l.substring(0, 0x15).trim(); - String[] w = l.split(" +"); - if ((w.length >= 5) && (w[w.length - 1].equals("serial"))) { - Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length - 4]); - mDrivers.add(new Driver(drivername, w[w.length - 4])); - } - } - r.close(); - } - return mDrivers; - } - - public String[] getAllDevices() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getName(); - String value = String.format("%s (%s)", device, driver.getName()); - devices.add(value); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } - - public String[] getAllDevicesPath() { - Vector devices = new Vector(); - // Parse each driver - Iterator itdriv; - try { - itdriv = getDrivers().iterator(); - while (itdriv.hasNext()) { - Driver driver = itdriv.next(); - Iterator itdev = driver.getDevices().iterator(); - while (itdev.hasNext()) { - String device = itdev.next().getAbsolutePath(); - devices.add(device); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return devices.toArray(new String[devices.size()]); - } -} diff --git a/app/src/main/java/com/casic/detector/base/BaseApplication.kt b/app/src/main/java/com/casic/detector/base/BaseApplication.kt index c36fcea..1250e19 100644 --- a/app/src/main/java/com/casic/detector/base/BaseApplication.kt +++ b/app/src/main/java/com/casic/detector/base/BaseApplication.kt @@ -1,9 +1,9 @@ package com.casic.detector.base import android.app.Application -import android_serialport_api.SerialPort import com.casic.detector.greendao.DaoMaster import com.casic.detector.greendao.DaoSession +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.utils.SaveKeyValues import java.io.File import java.io.IOException diff --git a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt index c7229ad..ca5c1f8 100644 --- a/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt +++ b/app/src/main/java/com/casic/detector/base/SerialPortActivity.kt @@ -1,8 +1,8 @@ package com.casic.detector.base import android.os.Bundle -import android_serialport_api.SerialPort import androidx.appcompat.app.AppCompatActivity +import com.casic.detector.uart.SerialPort import com.pengxh.kt.lite.extensions.show import java.io.IOException import java.io.InputStream diff --git a/app/src/main/java/com/casic/detector/uart/SerialPort.java b/app/src/main/java/com/casic/detector/uart/SerialPort.java new file mode 100644 index 0000000..550b461 --- /dev/null +++ b/app/src/main/java/com/casic/detector/uart/SerialPort.java @@ -0,0 +1,73 @@ +package com.casic.detector.uart; + +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"; + + /** + * .so 库名字。需要去掉生成时自带的lib前缀 + * */ + static { + System.loadLibrary("serial_port"); + } + + /** + * JNI + *

+ * 必须用 native 标识JNI方法 + */ + private native static FileDescriptor open(String path, int baudRate, int flags); + + public native void close(); + + /** + * Do not remove or rename the field mFd: it is used by native method close(); + */ + private FileDescriptor mFd; + private final FileInputStream mFileInputStream; + private final FileOutputStream mFileOutputStream; + + public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { + + if (!device.canRead() || !device.canWrite()) { + try { + Process su; + su = Runtime.getRuntime().exec("/system/bin/su"); + String cmd = "chmod 666 " + 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); + } + + public InputStream getInputStream() { + return mFileInputStream; + } + + public OutputStream getOutputStream() { + return mFileOutputStream; + } +} diff --git a/app/src/main/jni/Android.mk b/app/src/main/jni/Android.mk index f4ce1c3..94bf9d0 100644 --- a/app/src/main/jni/Android.mk +++ b/app/src/main/jni/Android.mk @@ -1,26 +1,23 @@ -# -# Copyright 2009 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. -# - +# Android.mk必须以LOCAL_PATH开头,注释#除外 +# 设置工作目录,而my-dir则会返回Android.mk文件所在的目录 LOCAL_PATH := $(call my-dir) +# 借助CLEAR_VARS变量清除除LOCAL_PATH外的所有LOCAL_变量 include $(CLEAR_VARS) +# android-3 对应Android 1.5 TARGET_PLATFORM := android-3 + +# 设置模块的名称,即编译出来.so文件名 +# 注,要和上述步骤中build.gradle中NDK节点设置的名字相同 LOCAL_MODULE := serial_port + +# 指定参与模块编译的C/C++源文件列表,多文件用"\"隔开 LOCAL_SRC_FILES := SerialPort.c + LOCAL_LDLIBS := -llog +# 必须在文件结尾定义编译类型,指定生成的静态库或者共享库在运行时依赖的共享库模块列表。 +# BUILD_SHARED_LIBRARY 共享库,供java或者其他共享库调用 +# BUILD_STATIC_LIBRARY 静态库,供共享库调用,不能直接被java调用 include $(BUILD_SHARED_LIBRARY) diff --git a/app/src/main/jni/SerialPort.c b/app/src/main/jni/SerialPort.c index 84748a7..5dad4bf 100644 --- a/app/src/main/jni/SerialPort.c +++ b/app/src/main/jni/SerialPort.c @@ -1,19 +1,3 @@ -/* - * 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 #include #include @@ -25,143 +9,164 @@ #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) + +static const char *TAG = "serial_port"; #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; - } +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 + * Class: com_casic_detector_uart_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; +JNIEXPORT jobject JNICALL +Java_com_casic_detector_uart_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; - } - } + /* Check arguments */ + { + speed = getBaudRate(baudRate); + if (speed == -1) { + 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; - } - } + /* 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) { + LOGE("Cannot open port"); + 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; - } + /* Configure device */ + { + struct termios cfg; + LOGD("Configuring serial port"); + if (tcgetattr(fd, &cfg)) { + LOGE("tcgetattr() failed"); + close(fd); + return NULL; + } - cfmakeraw(&cfg); - cfsetispeed(&cfg, speed); - cfsetospeed(&cfg, speed); + cfmakeraw(&cfg); + cfsetispeed(&cfg, speed); + cfsetospeed(&cfg, speed); - if (tcsetattr(fd, TCSANOW, &cfg)) - { - LOGE("tcsetattr() failed"); - close(fd); - /* TODO: throw an exception */ - return NULL; - } - } + if (tcsetattr(fd, TCSANOW, &cfg)) { + LOGE("tcsetattr() failed"); + close(fd); + return NULL; + } + } - /* Create a corresponding file descriptor */ - { - jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); - jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "", "()V"); - jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); - mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); - (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint)fd); - } + /* Create a corresponding file descriptor */ + { + jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); + jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "", "()V"); + jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); + mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); + (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint) fd); + } - return mFileDescriptor; + return mFileDescriptor; } /* - * Class: cedric_serial_SerialPort + * Class: com_casic_detector_uart_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"); +JNIEXPORT void JNICALL Java_com_casic_detector_uart_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"); + 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); + jobject mFd = (*env)->GetObjectField(env, thiz, mFdID); + jint descriptor = (*env)->GetIntField(env, mFd, descriptorID); - LOGD("close(fd = %d)", descriptor); - close(descriptor); + LOGD("close(fd = %d)", descriptor); + close(descriptor); } diff --git a/app/src/main/jni/SerialPort.h b/app/src/main/jni/SerialPort.h index 61f1fb2..93a4771 100644 --- a/app/src/main/jni/SerialPort.h +++ b/app/src/main/jni/SerialPort.h @@ -1,27 +1,27 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ #include -/* Header for class android_serialport_api_SerialPort */ +/* Header for class com_casic_detector_uart_SerialPort */ -#ifndef _Included_android_serialport_api_SerialPort -#define _Included_android_serialport_api_SerialPort +#ifndef _Included_com_casic_detector_uart_SerialPort +#define _Included_com_casic_detector_uart_SerialPort #ifdef __cplusplus extern "C" { #endif /* - * Class: android_serialport_api_SerialPort + * Class: com_casic_detector_uart_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); +JNIEXPORT jobject JNICALL Java_com_casic_detector_uart_SerialPort_open + (JNIEnv *, jclass, jstring, jint, jint); /* - * Class: android_serialport_api_SerialPort + * Class: com_casic_detector_uart_SerialPort * Method: close * Signature: ()V */ -JNIEXPORT void JNICALL Java_android_1serialport_1api_SerialPort_close - (JNIEnv *, jobject); +JNIEXPORT void JNICALL Java_com_casic_detector_uart_SerialPort_close + (JNIEnv *, jobject); #ifdef __cplusplus } diff --git a/app/src/main/jni/gen_SerialPort_h.sh b/app/src/main/jni/gen_SerialPort_h.sh index 5414670..d2983c6 100755 --- a/app/src/main/jni/gen_SerialPort_h.sh +++ b/app/src/main/jni/gen_SerialPort_h.sh @@ -1,3 +1,3 @@ #!/bin/sh -javah -o SerialPort.h -jni -classpath ../java android_serialport_api.SerialPort +javah -encoding utf-8 -o SerialPort.h -jni -classpath ../java com.casic.detector.uart.SerialPort diff --git a/app/src/main/jniLibs/arm64-v8a/libserial_port.so b/app/src/main/jniLibs/arm64-v8a/libserial_port.so old mode 100755 new mode 100644 index fe664b1..d121a14 --- a/app/src/main/jniLibs/arm64-v8a/libserial_port.so +++ b/app/src/main/jniLibs/arm64-v8a/libserial_port.so Binary files differ diff --git a/app/src/main/jniLibs/armeabi-v7a/libserial_port.so b/app/src/main/jniLibs/armeabi-v7a/libserial_port.so old mode 100755 new mode 100644 index 88819f8..bcfa53e --- a/app/src/main/jniLibs/armeabi-v7a/libserial_port.so +++ b/app/src/main/jniLibs/armeabi-v7a/libserial_port.so Binary files differ diff --git a/app/src/main/jniLibs/x86/libserial_port.so b/app/src/main/jniLibs/x86/libserial_port.so old mode 100755 new mode 100644 index f6eb9ba..4ebea50 --- a/app/src/main/jniLibs/x86/libserial_port.so +++ b/app/src/main/jniLibs/x86/libserial_port.so Binary files differ diff --git a/app/src/main/jniLibs/x86_64/libserial_port.so b/app/src/main/jniLibs/x86_64/libserial_port.so old mode 100755 new mode 100644 index 14cbf6b..5a4baca --- a/app/src/main/jniLibs/x86_64/libserial_port.so +++ b/app/src/main/jniLibs/x86_64/libserial_port.so Binary files differ