├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── dhht │ │ └── serialportutil │ │ └── MainActivity.java │ └── res │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ └── ic_launcher_background.xml │ ├── layout │ └── activity_main.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── serialportlibrary ├── .gitignore ├── build.gradle ├── libs │ ├── arm64-v8a │ │ └── libserial_port.so │ ├── armeabi-v7a │ │ └── libserial_port.so │ ├── armeabi │ │ └── libserial_port.so │ ├── mips │ │ └── libserial_port.so │ ├── mips64 │ │ └── libserial_port.so │ ├── x86 │ │ └── libserial_port.so │ └── x86_64 │ │ └── libserial_port.so ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ ├── android │ │ └── serialport │ │ │ ├── SerialPort.java │ │ │ └── SerialPortFinder.java │ └── com │ │ └── serialportlibrary │ │ ├── service │ │ ├── ISerialPortService.java │ │ └── impl │ │ │ ├── SerialPortBuilder.java │ │ │ └── SerialPortService.java │ │ └── util │ │ ├── ByteStringUtil.java │ │ └── LogUtil.java │ ├── jni │ ├── Android.mk │ └── SerialPort.c │ └── res │ └── values │ └── strings.xml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### macOS template 3 | # General 4 | .DS_Store 5 | .AppleDouble 6 | .LSOverride 7 | 8 | # Icon must end with two \r 9 | Icon 10 | 11 | # Thumbnails 12 | ._* 13 | 14 | # Files that might appear in the root of a volume 15 | .DocumentRevisions-V100 16 | .fseventsd 17 | .Spotlight-V100 18 | .TemporaryItems 19 | .Trashes 20 | .VolumeIcon.icns 21 | .com.apple.timemachine.donotpresent 22 | 23 | # Directories potentially created on remote AFP share 24 | .AppleDB 25 | .AppleDesktop 26 | Network Trash Folder 27 | Temporary Items 28 | .apdisk 29 | ### Android template 30 | # Built application files 31 | *.apk 32 | *.ap_ 33 | 34 | # Files for the ART/Dalvik VM 35 | *.dex 36 | 37 | # Java class files 38 | *.class 39 | 40 | # Generated files 41 | bin/ 42 | gen/ 43 | out/ 44 | 45 | # Gradle files 46 | .gradle/ 47 | build/ 48 | 49 | # Local configuration file (sdk path, etc) 50 | local.properties 51 | 52 | # Proguard folder generated by Eclipse 53 | proguard/ 54 | 55 | # Log Files 56 | *.log 57 | 58 | # Android Studio Navigation editor temp files 59 | .navigation/ 60 | 61 | # Android Studio captures folder 62 | captures/ 63 | 64 | # IntelliJ 65 | *.iml 66 | .idea/workspace.xml 67 | .idea/tasks.xml 68 | .idea/gradle.xml 69 | .idea/assetWizardSettings.xml 70 | .idea/dictionaries 71 | .idea/libraries 72 | .idea/caches 73 | 74 | .idea/libraries/ 75 | .idea/.name 76 | .idea/compiler.xml 77 | .idea/copyright/profiles_settings.xml 78 | .idea/encodings.xml 79 | .idea/misc.xml 80 | .idea/modules.xml 81 | .idea/scopes/scope_settings.xml 82 | .idea/vcs.xml 83 | .classpath 84 | .project 85 | 86 | .idea 87 | #.idea/workspace.xml - remove # and delete .idea if it better suit your needs. 88 | .gradle 89 | 90 | # Keystore files 91 | # Uncomment the following line if you do not want to check your keystore files in. 92 | #*.jks 93 | 94 | # External native build folder generated in Android Studio 2.2 and later 95 | .externalNativeBuild 96 | 97 | # Google Services (e.g. APIs or Firebase) 98 | google-services.json 99 | 100 | # Freeline 101 | freeline.py 102 | freeline/ 103 | freeline_project_description.json 104 | 105 | # fastlane 106 | fastlane/report.xml 107 | fastlane/Preview.html 108 | fastlane/screenshots 109 | fastlane/test_output 110 | fastlane/readme.md 111 | 112 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SerialPortUtil 2 | Android串口通信简单封装,可以用于和连接串口的硬件通信或者进行硬件调试 3 | 4 | ### 集成方法: 5 | Step 1. Add the JitPack repository to your build file 6 | ``` 7 | //Add it in your root build.gradle at the end of repositories: 8 | allprojects { 9 | repositories { 10 | ... 11 | maven { url 'https://jitpack.io' } 12 | } 13 | } 14 | ``` 15 | Step 2. Add the dependency 16 | ``` 17 | //Add the dependency 18 | dependencies { 19 | implementation 'com.github.tyhjh:SerialPortUtil:1.0.0' 20 | } 21 | ``` 22 | 23 | ### 调用方法 24 | 读取文件权限应该是需要的 25 | ```java 26 | 27 | ``` 28 | 29 | 获取所有串口地址 30 | ``` 31 | String[] devicesPath = new SerialPortFinder().getDevicesPaths(); 32 | ``` 33 | 34 | 打开串口,设置读取返回数据超时时间 35 | ```java 36 | SerialPortService serialPortService = new SerialPortBuilder() 37 | .setTimeOut(100L) 38 | .setBaudrate(9600) 39 | .setDevicePath("dev/ttyS4") 40 | .createService(); 41 | ``` 42 | 43 | 发送指令 44 | ```java 45 | //发送byte数组数据 46 | byte[] receiveData = serialPortService.sendData(new byte[2]); 47 | 48 | //发送16进制的字符串 49 | byte[] receiveData = serialPortService.sendData("55AA0101010002"); 50 | Log.e("MainActivity:", ByteStringUtil.byteArrayToHexStr(receiveData)); 51 | ``` 52 | 53 | 打开或者关闭日志,默认关闭 54 | ```java 55 | serialPortService.isOutputLog(true); 56 | ``` 57 | //关闭串口 58 | ```java 59 | serialPortService.close(); 60 | ``` 61 | 62 | > 项目源码:https://github.com/tyhjh/SerialPortUtil 63 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | defaultConfig { 6 | applicationId "com.example.dhht.serialportutil" 7 | minSdkVersion 15 8 | targetSdkVersion 25 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation fileTree(include: ['*.jar'], dir: 'libs') 23 | implementation 'com.android.support:appcompat-v7:25.0.0' 24 | testImplementation 'junit:junit:4.12' 25 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 26 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 27 | implementation project(':serialportlibrary') 28 | } 29 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/dhht/serialportutil/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.dhht.serialportutil; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | import android.util.Log; 6 | 7 | import android.serialport.SerialPortFinder; 8 | import android.view.View; 9 | import android.widget.TextView; 10 | 11 | import com.serialportlibrary.service.impl.SerialPortBuilder; 12 | import com.serialportlibrary.service.impl.SerialPortService; 13 | import com.serialportlibrary.util.ByteStringUtil; 14 | 15 | import java.util.Arrays; 16 | 17 | public class MainActivity extends AppCompatActivity { 18 | 19 | TextView tv_hello; 20 | 21 | @Override 22 | protected void onCreate(Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | setContentView(R.layout.activity_main); 25 | 26 | tv_hello = (TextView) findViewById(R.id.tv_hello); 27 | 28 | //获取所有串口名字 29 | String[] devices = new SerialPortFinder().getDevices(); 30 | //获取所用串口地址 31 | String[] devicesPath = new SerialPortFinder().getDevicesPaths(); 32 | 33 | 34 | for (String path : devicesPath) { 35 | Log.e("MainActivity:", path); 36 | } 37 | for (String device : devices) { 38 | Log.e("MainActivity:", device); 39 | } 40 | tv_hello.setOnClickListener(new View.OnClickListener() { 41 | @Override 42 | public void onClick(View v) { 43 | 44 | 45 | SerialPortService serialPortService = new SerialPortBuilder() 46 | .setTimeOut(100L) 47 | .setBaudrate(9600) 48 | .setDevicePath("dev/ttyS4") 49 | .createService(); 50 | serialPortService.isOutputLog(true); 51 | //发送开门指令 52 | byte[] receiveData = serialPortService.sendData("55AA0101010002"); 53 | Log.e("MainActivity:", ByteStringUtil.byteArrayToHexStr(receiveData)); 54 | 55 | 56 | } 57 | }); 58 | 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | SerialportUtil 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.2.0' 11 | 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | google() 21 | jcenter() 22 | } 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } 28 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | 15 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /serialportlibrary/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /serialportlibrary/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 25 5 | defaultConfig { 6 | minSdkVersion 15 7 | targetSdkVersion 25 8 | versionCode 1 9 | versionName "1.0" 10 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 11 | 12 | } 13 | 14 | /*packagingOptions { 15 | pickFirst 'lib/x86_64/libserial_port.so' 16 | pickFirst 'lib/armeabi/libserial_port.so' 17 | pickFirst 'lib/x86/libserial_port.so' 18 | pickFirst 'lib/armeabi-v7a/libserial_port.so' 19 | pickFirst 'lib/arm64-v8a/libserial_port.so' 20 | }*/ 21 | 22 | 23 | /*externalNativeBuild { 24 | 25 | // Encapsulates your CMake build configurations. 26 | ndkBuild { 27 | path "src/main/jni/Android.mk" 28 | } 29 | }*/ 30 | 31 | 32 | buildTypes { 33 | release { 34 | minifyEnabled false 35 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 36 | } 37 | } 38 | 39 | sourceSets { 40 | main { 41 | jni.srcDirs = [] //禁止使用默认的ndk编译系统 42 | jniLibs.srcDirs 'libs' //so存放地方 43 | } 44 | } 45 | 46 | } 47 | 48 | 49 | 50 | 51 | dependencies { 52 | implementation fileTree(dir: 'libs', include: ['*.jar']) 53 | implementation 'com.android.support:appcompat-v7:25.0.0' 54 | testImplementation 'junit:junit:4.12' 55 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 56 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 57 | } 58 | -------------------------------------------------------------------------------- /serialportlibrary/libs/arm64-v8a/libserial_port.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/serialportlibrary/libs/arm64-v8a/libserial_port.so -------------------------------------------------------------------------------- /serialportlibrary/libs/armeabi-v7a/libserial_port.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/serialportlibrary/libs/armeabi-v7a/libserial_port.so -------------------------------------------------------------------------------- /serialportlibrary/libs/armeabi/libserial_port.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/serialportlibrary/libs/armeabi/libserial_port.so -------------------------------------------------------------------------------- /serialportlibrary/libs/mips/libserial_port.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/serialportlibrary/libs/mips/libserial_port.so -------------------------------------------------------------------------------- /serialportlibrary/libs/mips64/libserial_port.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/serialportlibrary/libs/mips64/libserial_port.so -------------------------------------------------------------------------------- /serialportlibrary/libs/x86/libserial_port.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/serialportlibrary/libs/x86/libserial_port.so -------------------------------------------------------------------------------- /serialportlibrary/libs/x86_64/libserial_port.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyhjh/SerialPortUtil/c63a4cac57d92f41a20c51e6e3785cf32a5df6fa/serialportlibrary/libs/x86_64/libserial_port.so -------------------------------------------------------------------------------- /serialportlibrary/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /serialportlibrary/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /serialportlibrary/src/main/java/android/serialport/SerialPort.java: -------------------------------------------------------------------------------- 1 | package android.serialport; 2 | 3 | import android.util.Log; 4 | 5 | import java.io.File; 6 | import java.io.FileDescriptor; 7 | import java.io.FileInputStream; 8 | import java.io.FileOutputStream; 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.io.OutputStream; 12 | 13 | /** 14 | * 串口通信,打开串口,读写数据 15 | */ 16 | public class SerialPort { 17 | 18 | private FileDescriptor mFd; 19 | private FileInputStream mFileInputStream; 20 | private FileOutputStream mFileOutputStream; 21 | 22 | static { 23 | System.loadLibrary("serial_port"); 24 | } 25 | 26 | /** 27 | * 打开串口 28 | * 29 | * @param device 30 | * @param baudrate 31 | */ 32 | public SerialPort(File device, int baudrate) throws IOException { 33 | if (!device.canRead() || !device.canWrite()) { 34 | try { 35 | Process su; 36 | su = Runtime.getRuntime().exec("su"); 37 | String cmd = "chmod 777 " + device.getAbsolutePath(); 38 | su.getOutputStream().write(cmd.getBytes()); 39 | su.getOutputStream().flush(); 40 | int waitFor = su.waitFor(); 41 | boolean canRead = device.canRead(); 42 | boolean canWrite = device.canWrite(); 43 | if (waitFor != 0 || !canRead || !canWrite) { 44 | throw new SecurityException(); 45 | } 46 | } catch (Exception e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | mFd = open(device.getAbsolutePath(), baudrate); 51 | 52 | if (mFd == null) { 53 | throw new IOException(); 54 | } 55 | mFileInputStream = new FileInputStream(mFd); 56 | mFileOutputStream = new FileOutputStream(mFd); 57 | } 58 | 59 | /** 60 | * 关闭串口 61 | */ 62 | public void closePort() { 63 | if (this.mFd != null) { 64 | try { 65 | this.close(); 66 | this.mFd = null; 67 | this.mFileInputStream = null; 68 | this.mFileOutputStream = null; 69 | } catch (Exception var2) { 70 | var2.printStackTrace(); 71 | } 72 | } 73 | } 74 | 75 | public InputStream getInputStream() { 76 | return mFileInputStream; 77 | } 78 | 79 | public OutputStream getOutputStream() { 80 | return mFileOutputStream; 81 | } 82 | 83 | /** 84 | * JNI,设备地址和波特率 85 | */ 86 | private native static FileDescriptor open(String path, int baudrate); 87 | 88 | private native void close(); 89 | 90 | 91 | } 92 | -------------------------------------------------------------------------------- /serialportlibrary/src/main/java/android/serialport/SerialPortFinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Cedric Priscal 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.serialport; 18 | 19 | import java.io.File; 20 | import java.io.FileReader; 21 | import java.io.IOException; 22 | import java.io.LineNumberReader; 23 | import java.util.Iterator; 24 | import java.util.Vector; 25 | 26 | public class SerialPortFinder { 27 | 28 | private static final String TAG = "info"; 29 | private Vector mDrivers = null; 30 | 31 | Vector getDrivers() throws IOException { 32 | if (mDrivers == null) { 33 | mDrivers = new Vector(); 34 | LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers")); 35 | String l; 36 | while ((l = r.readLine()) != null) { 37 | String[] w = l.split(" +"); 38 | if ((w.length == 5) && ("serial".equals(w[4]))) { 39 | mDrivers.add(new Driver(w[0], w[1])); 40 | } 41 | } 42 | r.close(); 43 | } 44 | return mDrivers; 45 | } 46 | 47 | /** 48 | * 获取所有的设备,名字 49 | * 50 | * @return 51 | */ 52 | public String[] getDevices() { 53 | Vector devices = new Vector(); 54 | Iterator itdriv; 55 | try { 56 | itdriv = getDrivers().iterator(); 57 | while (itdriv.hasNext()) { 58 | Driver driver = itdriv.next(); 59 | Iterator itdev = driver.getDevices().iterator(); 60 | while (itdev.hasNext()) { 61 | String device = itdev.next().getName(); 62 | String value = String.format("%s (%s)", device, driver.getName()); 63 | devices.add(value); 64 | } 65 | } 66 | } catch (IOException e) { 67 | e.printStackTrace(); 68 | } 69 | return devices.toArray(new String[devices.size()]); 70 | } 71 | 72 | /** 73 | * 获取所有设备的地址 74 | * 75 | * @return 76 | */ 77 | public String[] getDevicesPaths() { 78 | Vector devices = new Vector(); 79 | Iterator itdriv; 80 | try { 81 | itdriv = getDrivers().iterator(); 82 | while (itdriv.hasNext()) { 83 | Driver driver = itdriv.next(); 84 | Iterator itdev = driver.getDevices().iterator(); 85 | while (itdev.hasNext()) { 86 | String device = itdev.next().getAbsolutePath(); 87 | devices.add(device); 88 | } 89 | } 90 | } catch (IOException e) { 91 | e.printStackTrace(); 92 | } 93 | return devices.toArray(new String[devices.size()]); 94 | } 95 | 96 | public class Driver { 97 | Vector mDevices = null; 98 | private String mDriverName; 99 | private String mDeviceRoot; 100 | 101 | public Driver(String name, String root) { 102 | mDriverName = name; 103 | mDeviceRoot = root; 104 | } 105 | 106 | public Vector getDevices() { 107 | if (mDevices == null) { 108 | mDevices = new Vector(); 109 | File dev = new File("/dev"); 110 | File[] files = dev.listFiles(); 111 | int i; 112 | for (i = 0; i < files.length; i++) { 113 | if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) { 114 | mDevices.add(files[i]); 115 | } 116 | } 117 | } 118 | return mDevices; 119 | } 120 | 121 | public String getName() { 122 | return mDriverName; 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /serialportlibrary/src/main/java/com/serialportlibrary/service/ISerialPortService.java: -------------------------------------------------------------------------------- 1 | package com.serialportlibrary.service; 2 | 3 | /** 4 | * @author HanPei 5 | * @date 2018/12/26 下午2:55 6 | */ 7 | public interface ISerialPortService { 8 | 9 | /** 10 | * 发送byteArray数据 11 | * 12 | * @param data 13 | * @return 14 | */ 15 | byte[] sendData(byte[] data); 16 | 17 | /** 18 | * 发送十六进制的字符串数据 19 | * 20 | * @param data 21 | * @return 22 | */ 23 | byte[] sendData(String data); 24 | 25 | /** 26 | * 关闭串口 27 | */ 28 | void close(); 29 | } 30 | -------------------------------------------------------------------------------- /serialportlibrary/src/main/java/com/serialportlibrary/service/impl/SerialPortBuilder.java: -------------------------------------------------------------------------------- 1 | package com.serialportlibrary.service.impl; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * @author HanPei 7 | * @date 2018/12/26 下午3:39 8 | */ 9 | public class SerialPortBuilder { 10 | 11 | /** 12 | * 读取返回结果超时时间 13 | */ 14 | private Long mTimeOut = 100L; 15 | /** 16 | * 串口地址 17 | */ 18 | private String mDevicePath; 19 | 20 | /** 21 | * 波特率 22 | */ 23 | private int mBaudrate; 24 | 25 | public SerialPortBuilder setBaudrate(int baudrate) { 26 | mBaudrate = baudrate; 27 | return this; 28 | } 29 | 30 | 31 | public SerialPortBuilder setDevicePath(String devicePath) { 32 | mDevicePath = devicePath; 33 | return this; 34 | } 35 | 36 | 37 | public SerialPortBuilder setTimeOut(Long timeOut) { 38 | mTimeOut = timeOut; 39 | return this; 40 | } 41 | 42 | public SerialPortService createService() { 43 | SerialPortService serialPortService = null; 44 | try { 45 | serialPortService = new SerialPortService(mDevicePath, mBaudrate, mTimeOut); 46 | } catch (IOException e) { 47 | e.printStackTrace(); 48 | } 49 | return serialPortService; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /serialportlibrary/src/main/java/com/serialportlibrary/service/impl/SerialPortService.java: -------------------------------------------------------------------------------- 1 | package com.serialportlibrary.service.impl; 2 | 3 | import android.os.SystemClock; 4 | 5 | import android.serialport.SerialPort; 6 | 7 | import com.serialportlibrary.service.ISerialPortService; 8 | import com.serialportlibrary.util.ByteStringUtil; 9 | import com.serialportlibrary.util.LogUtil; 10 | 11 | import java.io.File; 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.io.OutputStream; 15 | import java.util.Arrays; 16 | 17 | 18 | /** 19 | * @author HanPei 20 | * @date 2018/12/26 下午2:42 21 | */ 22 | public class SerialPortService implements ISerialPortService { 23 | 24 | /** 25 | * 尝试读取数据间隔时间 26 | */ 27 | private static int RE_READ_WAITE_TIME = 10; 28 | 29 | /** 30 | * 读取返回结果超时时间 31 | */ 32 | private Long mTimeOut = 100L; 33 | /** 34 | * 串口地址 35 | */ 36 | private String mDevicePath; 37 | 38 | /** 39 | * 波特率 40 | */ 41 | private int mBaudrate; 42 | 43 | SerialPort mSerialPort; 44 | 45 | /** 46 | * 初始化串口 47 | * 48 | * @param devicePath 串口地址 49 | * @param baudrate 波特率 50 | * @param timeOut 数据返回超时时间 51 | * @throws IOException 打开串口出错 52 | */ 53 | public SerialPortService(String devicePath, int baudrate, Long timeOut) throws IOException { 54 | mTimeOut = timeOut; 55 | mDevicePath = devicePath; 56 | mBaudrate = baudrate; 57 | mSerialPort = new SerialPort(new File(mDevicePath), mBaudrate); 58 | } 59 | 60 | @Override 61 | public byte[] sendData(byte[] data) { 62 | synchronized (SerialPortService.this) { 63 | try { 64 | InputStream inputStream = mSerialPort.getInputStream(); 65 | OutputStream outputStream = mSerialPort.getOutputStream(); 66 | int available = inputStream.available(); 67 | byte[] returnData; 68 | if (available > 0) { 69 | returnData = new byte[available]; 70 | inputStream.read(returnData); 71 | } 72 | outputStream.write(data); 73 | outputStream.flush(); 74 | LogUtil.e("发送数据-------" + Arrays.toString(data)); 75 | Long time = System.currentTimeMillis(); 76 | //暂存每次返回数据长度,不变的时候为读取完数据 77 | int receiveLeanth = 0; 78 | while (System.currentTimeMillis() - time < mTimeOut) { 79 | available = inputStream.available(); 80 | if (available > 0 && available == receiveLeanth) { 81 | returnData = new byte[available]; 82 | inputStream.read(returnData); 83 | LogUtil.e("接收--数据-------" + Arrays.toString(returnData)); 84 | return returnData; 85 | } else { 86 | receiveLeanth = available; 87 | } 88 | SystemClock.sleep(RE_READ_WAITE_TIME); 89 | } 90 | } catch (IOException e) { 91 | e.printStackTrace(); 92 | } 93 | return null; 94 | } 95 | } 96 | 97 | @Override 98 | public byte[] sendData(String date) { 99 | try { 100 | return sendData(ByteStringUtil.hexStrToByteArray(date)); 101 | } catch (Exception e) { 102 | e.printStackTrace(); 103 | return null; 104 | } 105 | } 106 | 107 | @Override 108 | public void close() { 109 | if (mSerialPort != null) { 110 | mSerialPort.closePort(); 111 | } 112 | } 113 | 114 | 115 | public void isOutputLog(boolean debug) { 116 | LogUtil.isDebug = debug; 117 | } 118 | 119 | 120 | } 121 | -------------------------------------------------------------------------------- /serialportlibrary/src/main/java/com/serialportlibrary/util/ByteStringUtil.java: -------------------------------------------------------------------------------- 1 | package com.serialportlibrary.util; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * Created by Tyhj on 2017/3/10. 7 | */ 8 | 9 | public class ByteStringUtil { 10 | 11 | public static byte[] hexStrToByteArray(String str) { 12 | if (str == null) { 13 | return null; 14 | } 15 | if (str.length() == 0) { 16 | return new byte[0]; 17 | } 18 | byte[] byteArray = new byte[str.length() / 2]; 19 | for (int i = 0; i < byteArray.length; i++){ 20 | String subStr = str.substring(2 * i, 2 * i + 2); 21 | byteArray[i] = ((byte)Integer.parseInt(subStr, 16)); 22 | } 23 | return byteArray; 24 | } 25 | 26 | public static String byteArrayToHexStr(byte[] byteArray) { 27 | if (byteArray == null){ 28 | return null; 29 | } 30 | char[] hexArray = "0123456789ABCDEF".toCharArray(); 31 | char[] hexChars = new char[byteArray.length * 2]; 32 | for (int j = 0; j < byteArray.length; j++) { 33 | int v = byteArray[j] & 0xFF; 34 | hexChars[j * 2] = hexArray[v >>> 4]; 35 | hexChars[j * 2 + 1] = hexArray[v & 0x0F]; 36 | } 37 | return new String(hexChars); 38 | } 39 | 40 | 41 | public static String StrToAddHexStr(String[] strings){ 42 | long all=Long.parseLong("0",16); 43 | for (int i=0;i 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "android/log.h" 26 | 27 | static const char *TAG = "serial_port"; 28 | #define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##args) 29 | #define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args) 30 | #define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args) 31 | 32 | static speed_t getBaudrate(jint baudrate) { 33 | switch (baudrate) { 34 | case 0: 35 | return B0; 36 | case 50: 37 | return B50; 38 | case 75: 39 | return B75; 40 | case 110: 41 | return B110; 42 | case 134: 43 | return B134; 44 | case 150: 45 | return B150; 46 | case 200: 47 | return B200; 48 | case 300: 49 | return B300; 50 | case 600: 51 | return B600; 52 | case 1200: 53 | return B1200; 54 | case 1800: 55 | return B1800; 56 | case 2400: 57 | return B2400; 58 | case 4800: 59 | return B4800; 60 | case 9600: 61 | return B9600; 62 | case 19200: 63 | return B19200; 64 | case 38400: 65 | return B38400; 66 | case 57600: 67 | return B57600; 68 | case 115200: 69 | return B115200; 70 | case 230400: 71 | return B230400; 72 | case 460800: 73 | return B460800; 74 | case 500000: 75 | return B500000; 76 | case 576000: 77 | return B576000; 78 | case 921600: 79 | return B921600; 80 | case 1000000: 81 | return B1000000; 82 | case 1152000: 83 | return B1152000; 84 | case 1500000: 85 | return B1500000; 86 | case 2000000: 87 | return B2000000; 88 | case 2500000: 89 | return B2500000; 90 | case 3000000: 91 | return B3000000; 92 | case 3500000: 93 | return B3500000; 94 | case 4000000: 95 | return B4000000; 96 | default: 97 | return -1; 98 | } 99 | } 100 | 101 | /* 102 | * Class: cedric_serial_SerialPort 103 | * Method: open 104 | * Signature: (Ljava/lang/String;)V 105 | */ 106 | JNIEXPORT jobject JNICALL Java_android_serialport_SerialPort_open 107 | (JNIEnv *env, jobject thiz, jstring path, jint baudrate) { 108 | int fd; 109 | speed_t speed; 110 | jobject mFileDescriptor; 111 | 112 | /* Check arguments */ 113 | { 114 | speed = getBaudrate(baudrate); 115 | if (speed == -1) { 116 | LOGE("Invalid baudrate"); 117 | return NULL; 118 | } 119 | } 120 | 121 | /* Opening device */ 122 | { 123 | jboolean iscopy; 124 | const char *path_utf = (*env)->GetStringUTFChars(env, path, &iscopy); 125 | LOGD("Opening serial port %s", path_utf); 126 | fd = open(path_utf, O_RDWR); 127 | LOGD("open() fd = %d", fd); 128 | (*env)->ReleaseStringUTFChars(env, path, path_utf); 129 | if (fd == -1) { 130 | /* Throw an exception */ 131 | LOGE("Cannot open port"); 132 | return NULL; 133 | } 134 | } 135 | 136 | /* Configure device */ 137 | { 138 | struct termios cfg; 139 | LOGD("Configuring serial port"); 140 | if (tcgetattr(fd, &cfg)) { 141 | LOGE("tcgetattr() failed"); 142 | close(fd); 143 | return NULL; 144 | } 145 | 146 | cfmakeraw(&cfg); 147 | cfsetispeed(&cfg, speed); 148 | cfsetospeed(&cfg, speed); 149 | 150 | if (tcsetattr(fd, TCSANOW, &cfg)) { 151 | LOGE("tcsetattr() failed"); 152 | close(fd); 153 | return NULL; 154 | } 155 | } 156 | 157 | /* Create a corresponding file descriptor */ 158 | { 159 | jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); 160 | jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "", "()V"); 161 | jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); 162 | mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); 163 | (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint) fd); 164 | } 165 | 166 | return mFileDescriptor; 167 | } 168 | 169 | /* 170 | * Class: cedric_serial_SerialPort 171 | * Method: close 172 | * Signature: ()V 173 | */ 174 | JNIEXPORT void JNICALL Java_android_serialport_SerialPort_close 175 | (JNIEnv *env, jobject thiz) { 176 | jclass SerialPortClass = (*env)->GetObjectClass(env, thiz); 177 | jclass FileDescriptorClass = (*env)->FindClass(env, "java/io/FileDescriptor"); 178 | 179 | jfieldID mFdID = (*env)->GetFieldID(env, SerialPortClass, "mFd", "Ljava/io/FileDescriptor;"); 180 | jfieldID descriptorID = (*env)->GetFieldID(env, FileDescriptorClass, "descriptor", "I"); 181 | 182 | jobject mFd = (*env)->GetObjectField(env, thiz, mFdID); 183 | jint descriptor = (*env)->GetIntField(env, mFd, descriptorID); 184 | 185 | LOGD("close(fd = %d)", descriptor); 186 | close(descriptor); 187 | } 188 | -------------------------------------------------------------------------------- /serialportlibrary/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | serialportLibrary 3 | 4 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':serialportlibrary' 2 | --------------------------------------------------------------------------------