├── .gitattributes ├── .gitignore ├── BuleTouthDemo ├── .idea │ ├── compiler.xml │ ├── copyright │ │ └── profiles_settings.xml │ ├── encodings.xml │ ├── gradle.xml │ ├── libraries │ │ ├── animated_vector_drawable_25_1_0.xml │ │ ├── appcompat_v7_25_1_0.xml │ │ ├── espresso_core_2_2_2.xml │ │ ├── espresso_idling_resource_2_2_2.xml │ │ ├── exposed_instrumentation_api_publish_0_5.xml │ │ ├── hamcrest_core_1_3.xml │ │ ├── hamcrest_integration_1_3.xml │ │ ├── hamcrest_library_1_3.xml │ │ ├── javawriter_2_1_1.xml │ │ ├── javax_annotation_api_1_2.xml │ │ ├── javax_inject_1.xml │ │ ├── jsr305_2_0_1.xml │ │ ├── junit_4_12.xml │ │ ├── rules_0_5.xml │ │ ├── runner_0_5.xml │ │ ├── support_annotations_25_1_0.xml │ │ ├── support_compat_25_1_0.xml │ │ ├── support_core_ui_25_1_0.xml │ │ ├── support_core_utils_25_1_0.xml │ │ ├── support_fragment_25_1_0.xml │ │ ├── support_media_compat_25_1_0.xml │ │ ├── support_v4_25_1_0.xml │ │ └── support_vector_drawable_25_1_0.xml │ ├── misc.xml │ ├── modules.xml │ ├── runConfigurations.xml │ ├── vcs.xml │ └── workspace.xml ├── app │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── wxxiaomi │ │ │ └── ming │ │ │ └── buletouthdemo │ │ │ └── ExampleInstrumentedTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── wxxiaomi │ │ │ │ └── ming │ │ │ │ └── buletouthdemo │ │ │ │ ├── BluetoothConnector.java │ │ │ │ ├── BluetoothDeviceAdapter.java │ │ │ │ ├── BluetoothHelper.java │ │ │ │ ├── BoundActivity.java │ │ │ │ ├── HomeActivity.java │ │ │ │ ├── RunActivity.java │ │ │ │ ├── latest │ │ │ │ └── BleUtil.java │ │ │ │ ├── touch │ │ │ │ └── TouchMsgThread.java │ │ │ │ └── ui │ │ │ │ └── RunActivity2.java │ │ └── res │ │ │ ├── layout │ │ │ ├── activity_home.xml │ │ │ ├── activity_main.xml │ │ │ ├── activity_run.xml │ │ │ ├── activity_run2.xml │ │ │ └── item_bluetooth_device.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-w820dp │ │ │ └── dimens.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── wxxiaomi │ │ └── ming │ │ └── buletouthdemo │ │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── speedviewlib │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── github │ │ └── anastr │ │ └── speedviewlib │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── github │ │ └── anastr │ │ └── speedviewlib │ │ ├── AwesomeSpeedometer.java │ │ ├── DeluxeSpeedView.java │ │ ├── ImageSpeedometer.java │ │ ├── PointerSpeedometer.java │ │ ├── RaySpeedometer.java │ │ ├── SpeedView.java │ │ ├── Speedometer.java │ │ ├── TubeSpeedometer.java │ │ ├── components │ │ ├── Indicators │ │ │ ├── ImageIndicator.java │ │ │ ├── Indicator.java │ │ │ ├── LineIndicator.java │ │ │ ├── NoIndicator.java │ │ │ ├── NormalIndicator.java │ │ │ ├── NormalSmallIndicator.java │ │ │ ├── SpindleIndicator.java │ │ │ └── TriangleIndicator.java │ │ └── note │ │ │ ├── ImageNote.java │ │ │ ├── Note.java │ │ │ └── TextNote.java │ │ └── util │ │ ├── OnSectionChangeListener.java │ │ └── OnSpeedChangeListener.java │ └── res │ └── values │ ├── attrs.xml │ └── strings.xml ├── README.md └── pwm调节小车速度 ├── HJ-4WD.h ├── HJ-4WD_PWM.h ├── main.LST ├── main.OBJ ├── main.c ├── pwm调节小车速度 ├── pwm调节小车速度.M51 ├── pwm调节小车速度.hex ├── pwm调节小车速度.lnp ├── pwm调节小车速度.plg ├── pwm调节小车速度.uvopt └── pwm调节小车速度.uvproj /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | 38 | # Keystore files 39 | *.jks 40 | 41 | # ========================= 42 | # Operating System Files 43 | # ========================= 44 | 45 | # OSX 46 | # ========================= 47 | 48 | .DS_Store 49 | .AppleDouble 50 | .LSOverride 51 | 52 | # Thumbnails 53 | ._* 54 | 55 | # Files that might appear in the root of a volume 56 | .DocumentRevisions-V100 57 | .fseventsd 58 | .Spotlight-V100 59 | .TemporaryItems 60 | .Trashes 61 | .VolumeIcon.icns 62 | 63 | # Directories potentially created on remote AFP share 64 | .AppleDB 65 | .AppleDesktop 66 | Network Trash Folder 67 | Temporary Items 68 | .apdisk 69 | 70 | # Windows 71 | # ========================= 72 | 73 | # Windows image file caches 74 | Thumbs.db 75 | ehthumbs.db 76 | 77 | # Folder config file 78 | Desktop.ini 79 | 80 | # Recycle Bin used on file shares 81 | $RECYCLE.BIN/ 82 | 83 | # Windows Installer files 84 | *.cab 85 | *.msi 86 | *.msm 87 | *.msp 88 | 89 | # Windows shortcuts 90 | *.lnk 91 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/animated_vector_drawable_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/appcompat_v7_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/espresso_core_2_2_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/espresso_idling_resource_2_2_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/exposed_instrumentation_api_publish_0_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/hamcrest_core_1_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/hamcrest_integration_1_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/hamcrest_library_1_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/javawriter_2_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/javax_annotation_api_1_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/javax_inject_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/jsr305_2_0_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/junit_4_12.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/rules_0_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/runner_0_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/support_annotations_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/support_compat_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/support_core_ui_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/support_core_utils_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/support_fragment_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/support_media_compat_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/support_v4_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/libraries/support_vector_drawable_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 1.8 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /BuleTouthDemo/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /BuleTouthDemo/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /BuleTouthDemo/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.1" 6 | defaultConfig { 7 | applicationId "com.wxxiaomi.ming.buletouthdemo" 8 | minSdkVersion 16 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 25 | exclude group: 'com.android.support', module: 'support-annotations' 26 | }) 27 | compile 'com.android.support:appcompat-v7:25.1.0' 28 | testCompile 'junit:junit:4.12' 29 | compile project(path: ':speedviewlib') 30 | } 31 | -------------------------------------------------------------------------------- /BuleTouthDemo/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\work\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /BuleTouthDemo/app/src/androidTest/java/com/wxxiaomi/ming/buletouthdemo/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.wxxiaomi.ming.buletouthdemo; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.wxxiaomi.ming.buletouthdemo", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /BuleTouthDemo/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /BuleTouthDemo/app/src/main/java/com/wxxiaomi/ming/buletouthdemo/BluetoothConnector.java: -------------------------------------------------------------------------------- 1 | package com.wxxiaomi.ming.buletouthdemo; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | import java.lang.reflect.Method; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.UUID; 10 | 11 | import android.bluetooth.BluetoothAdapter; 12 | import android.bluetooth.BluetoothDevice; 13 | import android.bluetooth.BluetoothSocket; 14 | import android.util.Log; 15 | 16 | public class BluetoothConnector { 17 | 18 | private BluetoothSocketWrapper bluetoothSocket; 19 | private BluetoothDevice device; 20 | private boolean secure; 21 | private BluetoothAdapter adapter; 22 | private List uuidCandidates; 23 | private int candidate; 24 | 25 | 26 | /** 27 | * @param device the device 28 | * @param secure if connection should be done via a secure socket 29 | * @param adapter the Android BT adapter 30 | * @param uuidCandidates a list of UUIDs. if null or empty, the Serial PP id is used 31 | */ 32 | public BluetoothConnector(BluetoothDevice device, boolean secure, BluetoothAdapter adapter, 33 | List uuidCandidates) { 34 | this.device = device; 35 | this.secure = secure; 36 | this.adapter = adapter; 37 | this.uuidCandidates = uuidCandidates; 38 | 39 | if (this.uuidCandidates == null || this.uuidCandidates.isEmpty()) { 40 | this.uuidCandidates = new ArrayList(); 41 | this.uuidCandidates.add(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")); 42 | } 43 | } 44 | 45 | public BluetoothSocketWrapper connect() throws IOException { 46 | boolean success = false; 47 | while (selectSocket()) { 48 | adapter.cancelDiscovery(); 49 | 50 | try { 51 | bluetoothSocket.connect(); 52 | success = true; 53 | break; 54 | } catch (IOException e) { 55 | //try the fallback 56 | try { 57 | bluetoothSocket = new FallbackBluetoothSocket(bluetoothSocket.getUnderlyingSocket()); 58 | Thread.sleep(500); 59 | bluetoothSocket.connect(); 60 | success = true; 61 | break; 62 | } catch (FallbackException e1) { 63 | Log.w("BT", "Could not initialize FallbackBluetoothSocket classes.", e); 64 | } catch (InterruptedException e1) { 65 | Log.w("BT", e1.getMessage(), e1); 66 | } catch (IOException e1) { 67 | Log.w("BT", "Fallback failed. Cancelling.", e1); 68 | } 69 | } 70 | } 71 | 72 | if (!success) { 73 | throw new IOException("Could not connect to device: "+ device.getAddress()); 74 | } 75 | 76 | return bluetoothSocket; 77 | } 78 | 79 | private boolean selectSocket() throws IOException { 80 | if (candidate >= uuidCandidates.size()) { 81 | return false; 82 | } 83 | 84 | BluetoothSocket tmp; 85 | UUID uuid = uuidCandidates.get(candidate++); 86 | 87 | Log.i("BT", "Attempting to connect to Protocol: "+ uuid); 88 | if (secure) { 89 | tmp = device.createRfcommSocketToServiceRecord(uuid); 90 | } else { 91 | tmp = device.createInsecureRfcommSocketToServiceRecord(uuid); 92 | } 93 | // tmp.connect(); 94 | bluetoothSocket = new NativeBluetoothSocket(tmp); 95 | 96 | return true; 97 | } 98 | 99 | public static interface BluetoothSocketWrapper { 100 | 101 | InputStream getInputStream() throws IOException; 102 | 103 | OutputStream getOutputStream() throws IOException; 104 | 105 | String getRemoteDeviceName(); 106 | 107 | void connect() throws IOException; 108 | 109 | String getRemoteDeviceAddress(); 110 | 111 | void close() throws IOException; 112 | 113 | BluetoothSocket getUnderlyingSocket(); 114 | 115 | } 116 | 117 | 118 | public static class NativeBluetoothSocket implements BluetoothSocketWrapper { 119 | 120 | private BluetoothSocket socket; 121 | 122 | public NativeBluetoothSocket(BluetoothSocket tmp) { 123 | this.socket = tmp; 124 | } 125 | 126 | @Override 127 | public InputStream getInputStream() throws IOException { 128 | return socket.getInputStream(); 129 | } 130 | 131 | @Override 132 | public OutputStream getOutputStream() throws IOException { 133 | return socket.getOutputStream(); 134 | } 135 | 136 | @Override 137 | public String getRemoteDeviceName() { 138 | return socket.getRemoteDevice().getName(); 139 | } 140 | 141 | @Override 142 | public void connect() throws IOException { 143 | socket.connect(); 144 | } 145 | 146 | @Override 147 | public String getRemoteDeviceAddress() { 148 | return socket.getRemoteDevice().getAddress(); 149 | } 150 | 151 | @Override 152 | public void close() throws IOException { 153 | socket.close(); 154 | } 155 | 156 | @Override 157 | public BluetoothSocket getUnderlyingSocket() { 158 | return socket; 159 | } 160 | 161 | } 162 | 163 | public class FallbackBluetoothSocket extends NativeBluetoothSocket { 164 | 165 | private BluetoothSocket fallbackSocket; 166 | 167 | public FallbackBluetoothSocket(BluetoothSocket tmp) throws FallbackException { 168 | super(tmp); 169 | try 170 | { 171 | Class clazz = tmp.getRemoteDevice().getClass(); 172 | Class[] paramTypes = new Class[] {Integer.TYPE}; 173 | Method m = clazz.getMethod("createRfcommSocket", paramTypes); 174 | Object[] params = new Object[] {Integer.valueOf(1)}; 175 | fallbackSocket = (BluetoothSocket) m.invoke(tmp.getRemoteDevice(), params); 176 | } 177 | catch (Exception e) 178 | { 179 | throw new FallbackException(e); 180 | } 181 | } 182 | 183 | @Override 184 | public InputStream getInputStream() throws IOException { 185 | return fallbackSocket.getInputStream(); 186 | } 187 | 188 | @Override 189 | public OutputStream getOutputStream() throws IOException { 190 | return fallbackSocket.getOutputStream(); 191 | } 192 | 193 | 194 | @Override 195 | public void connect() throws IOException { 196 | fallbackSocket.connect(); 197 | } 198 | 199 | 200 | @Override 201 | public void close() throws IOException { 202 | fallbackSocket.close(); 203 | } 204 | 205 | } 206 | 207 | public static class FallbackException extends Exception { 208 | 209 | /** 210 | * 211 | */ 212 | private static final long serialVersionUID = 1L; 213 | 214 | public FallbackException(Exception e) { 215 | super(e); 216 | } 217 | 218 | } 219 | } -------------------------------------------------------------------------------- /BuleTouthDemo/app/src/main/java/com/wxxiaomi/ming/buletouthdemo/BluetoothDeviceAdapter.java: -------------------------------------------------------------------------------- 1 | package com.wxxiaomi.ming.buletouthdemo; 2 | 3 | import android.bluetooth.BluetoothDevice; 4 | import android.content.Context; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.BaseAdapter; 9 | import android.widget.TextView; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | 15 | 16 | /** 17 | * Author 林乔 18 | * Package cc.huaxun.agbao.adapter 19 | * Description TODO 蓝牙设备列表的适配器 20 | * Date 16/8/15 下午3:37 21 | */ 22 | public class BluetoothDeviceAdapter extends BaseAdapter { 23 | 24 | private List devices = new ArrayList<>(); 25 | 26 | private LayoutInflater inflater; 27 | 28 | /** 29 | * 构造函数 30 | * 31 | * @param context Context对象 32 | * @param devices 蓝牙设备列表 33 | */ 34 | public BluetoothDeviceAdapter(Context context, List devices) { 35 | this.devices = devices; 36 | this.inflater = LayoutInflater.from(context); 37 | } 38 | 39 | @Override 40 | public int getCount() { 41 | return devices.size(); 42 | } 43 | 44 | @Override 45 | public Object getItem(int i) { 46 | return devices.get(i); 47 | } 48 | 49 | @Override 50 | public long getItemId(int i) { 51 | return i; 52 | } 53 | 54 | @Override 55 | public View getView(int i, View view, ViewGroup viewGroup) { 56 | ViewHolder holder; 57 | if (view == null) { 58 | view = inflater.inflate(R.layout.item_bluetooth_device, viewGroup, false); 59 | holder = new ViewHolder(view); 60 | view.setTag(holder); 61 | } else { 62 | holder = (ViewHolder) view.getTag(); 63 | } 64 | BluetoothDevice device = devices.get(i); 65 | holder.tv_device_name.setText(device.getName()); 66 | if (device.getBondState() == BluetoothDevice.BOND_BONDED) { 67 | holder.tv_device_status.setText("已配对"); 68 | } else if (device.getBondState() == BluetoothDevice.BOND_BONDING) { 69 | holder.tv_device_status.setText("正在配对"); 70 | } else { 71 | holder.tv_device_status.setText("未配对"); 72 | } 73 | return view; 74 | } 75 | 76 | /** 77 | * 控件容器 78 | */ 79 | static class ViewHolder { 80 | /** 81 | * 设备名 82 | */ 83 | TextView tv_device_name; 84 | /** 85 | * 设备绑定状态 86 | */ 87 | TextView tv_device_status; 88 | 89 | public ViewHolder(View view) { 90 | tv_device_name = (TextView) view.findViewById(R.id.tv_device_name); 91 | tv_device_status = (TextView) view.findViewById(R.id.tv_device_status); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /BuleTouthDemo/app/src/main/java/com/wxxiaomi/ming/buletouthdemo/BluetoothHelper.java: -------------------------------------------------------------------------------- 1 | package com.wxxiaomi.ming.buletouthdemo; 2 | 3 | import android.app.Activity; 4 | import android.bluetooth.BluetoothAdapter; 5 | import android.bluetooth.BluetoothDevice; 6 | import android.bluetooth.BluetoothGatt; 7 | import android.bluetooth.BluetoothGattCallback; 8 | import android.bluetooth.BluetoothGattCharacteristic; 9 | import android.bluetooth.BluetoothSocket; 10 | import android.content.Context; 11 | import android.content.Intent; 12 | import android.os.Build; 13 | import android.os.Handler; 14 | import android.support.annotation.NonNull; 15 | import android.util.Log; 16 | import android.widget.Toast; 17 | 18 | 19 | import com.wxxiaomi.ming.buletouthdemo.touch.TouchMsgThread; 20 | 21 | import java.io.IOException; 22 | import java.io.InputStream; 23 | import java.io.OutputStream; 24 | import java.lang.reflect.InvocationTargetException; 25 | import java.lang.reflect.Method; 26 | import java.util.ArrayList; 27 | import java.util.Iterator; 28 | import java.util.List; 29 | import java.util.Set; 30 | import java.util.UUID; 31 | 32 | 33 | /** 34 | * Author 林乔 35 | * Package cc.huaxun.agbao.manage 36 | * Description TODO 蓝牙功能工具类 37 | * Date 16/8/15 上午10:30 38 | */ 39 | public class BluetoothHelper { 40 | 41 | private Context context; 42 | private BluetoothDevice currentDevice; 43 | private BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 44 | BluetoothConnector connector; 45 | BluetoothConnector.BluetoothSocketWrapper connect; 46 | TouchMsgThread thread; 47 | /** 48 | * 已配对的蓝牙设备 49 | */ 50 | private List bluetoothDevices = new ArrayList<>(); 51 | 52 | private BluetoothHelper() {} 53 | public static BluetoothHelper INSTANCE; 54 | public static BluetoothHelper getInstance(){ 55 | if(INSTANCE==null){ 56 | INSTANCE = new BluetoothHelper(); 57 | } 58 | return INSTANCE; 59 | } 60 | public static void init(Context ct){ 61 | INSTANCE.context = ct; 62 | } 63 | 64 | /** 65 | * 打开蓝牙 66 | */ 67 | public static void openBluetooth(@NonNull Activity activity) { 68 | if (INSTANCE.bluetoothAdapter == null) { 69 | // 设备不支持蓝牙 70 | Toast.makeText(INSTANCE.context.getApplicationContext(), "您的设备似乎不支持蓝牙", Toast.LENGTH_SHORT).show(); 71 | return; 72 | } 73 | Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 74 | activity.startActivityForResult(enableBtIntent, 6); 75 | } 76 | 77 | /** 78 | * 关闭蓝牙 79 | */ 80 | public static void closeBluetooth() { 81 | if (INSTANCE.bluetoothAdapter != null) { 82 | INSTANCE.bluetoothAdapter.disable(); 83 | } 84 | } 85 | 86 | /** 87 | * 判断蓝牙是否打开 88 | * 89 | * @return boolean 蓝牙是否打开 90 | */ 91 | public static boolean isBluetoothOpen() { 92 | return INSTANCE.bluetoothAdapter != null && INSTANCE.bluetoothAdapter.isEnabled(); 93 | } 94 | 95 | /** 96 | * 搜索蓝牙设备 97 | */ 98 | public static void searchDevices() { 99 | INSTANCE.bluetoothDevices.clear(); 100 | if (INSTANCE.bluetoothAdapter != null) { 101 | // 寻找蓝牙设备,android会将查找到的设备以广播形式发出去 102 | INSTANCE.bluetoothAdapter.startDiscovery(); 103 | } 104 | } 105 | 106 | /** 107 | * 添加蓝牙设备到list集合 108 | * 109 | * @param device 蓝牙设备 110 | */ 111 | public static void addBluetoothDevices(BluetoothDevice device) { 112 | if (!INSTANCE.bluetoothDevices.contains(device)) { 113 | INSTANCE.bluetoothDevices.add(device); 114 | } 115 | } 116 | 117 | /** 118 | * 获取搜索到的蓝牙设备列表 119 | * 120 | * @return 蓝牙设备列表 121 | */ 122 | public static List getBluetoothDevices() { 123 | return INSTANCE.bluetoothDevices; 124 | } 125 | 126 | /** 127 | * 绑定设备 128 | * 129 | * @param device BluetoothDevice对象 130 | * @return 是否绑定成功 131 | */ 132 | public static boolean bondDevice(BluetoothDevice device) { 133 | if (INSTANCE.bluetoothAdapter == null) { 134 | return false; 135 | } 136 | // 取消蓝牙设备搜索 137 | INSTANCE.bluetoothAdapter.cancelDiscovery(); 138 | try { 139 | if (device.getBondState() == BluetoothDevice.BOND_NONE) { 140 | // 设备未配对,进行配对操作 141 | Method method = BluetoothDevice.class.getMethod("createBond"); 142 | method.invoke(device); 143 | } 144 | return true; 145 | } catch (Exception e) { 146 | e.printStackTrace(); 147 | } 148 | return false; 149 | } 150 | 151 | /** 152 | * 打印文档 153 | * 154 | * @param device BluetoothDevice对象 155 | * @return 是否打印成功 156 | */ 157 | public static boolean printDocument(@NonNull final BluetoothDevice device, String msg, Handler handler) { 158 | try { 159 | if (!isBluetoothOpen()) { 160 | return false; 161 | } 162 | // 连接蓝牙设备 163 | if (INSTANCE.connector == null) { 164 | INSTANCE.initConnector(device); 165 | } 166 | if (INSTANCE.connect == null) { 167 | INSTANCE.connect = INSTANCE.connector.connect(); 168 | if(INSTANCE.thread!=null){ 169 | INSTANCE.thread.cancel(); 170 | INSTANCE.thread.stop(); 171 | INSTANCE.thread = null; 172 | } 173 | INSTANCE.thread = new TouchMsgThread(INSTANCE.connect.getUnderlyingSocket(), handler); 174 | INSTANCE.thread.start(); 175 | } 176 | INSTANCE.thread.write(msg.getBytes()); 177 | return true; 178 | } catch (Exception e) { 179 | e.printStackTrace(); 180 | } 181 | return false; 182 | } 183 | 184 | private void initConnector(BluetoothDevice device) { 185 | connector = new BluetoothConnector(device, true, BluetoothHelper.this.bluetoothAdapter, null); 186 | } 187 | 188 | /** 189 | * 判断是否已经有绑定的设备了 190 | * 191 | * @return 192 | */ 193 | public static boolean isEverDevice(){ 194 | //应该取出已绑定的设备里面,已绑定的设备里面是否有这个东西 195 | Set bondedDevices = INSTANCE.bluetoothAdapter.getBondedDevices(); 196 | Iterator iterator = bondedDevices.iterator(); 197 | while(iterator.hasNext()){ 198 | BluetoothDevice device = iterator.next(); 199 | Log.i("wang","device:"+device.toString()); 200 | if(device.getAddress().equals("98:D3:31:FC:3A:3C")){ 201 | INSTANCE.currentDevice = device; 202 | return true; 203 | }else{ 204 | return false; 205 | } 206 | } 207 | return false; 208 | } 209 | 210 | public static BluetoothDevice getCurrentDevice(){ 211 | return INSTANCE.currentDevice; 212 | } 213 | 214 | public static void Destory(){ 215 | try { 216 | 217 | INSTANCE.connect.close(); 218 | INSTANCE.connect=null; 219 | INSTANCE.thread.cancel(); 220 | INSTANCE.thread=null; 221 | INSTANCE.connector=null; 222 | }catch (Exception e){ 223 | e.printStackTrace(); 224 | } 225 | } 226 | 227 | 228 | } 229 | -------------------------------------------------------------------------------- /BuleTouthDemo/app/src/main/java/com/wxxiaomi/ming/buletouthdemo/BoundActivity.java: -------------------------------------------------------------------------------- 1 | package com.wxxiaomi.ming.buletouthdemo; 2 | 3 | import android.app.ProgressDialog; 4 | import android.bluetooth.BluetoothAdapter; 5 | import android.bluetooth.BluetoothDevice; 6 | import android.content.BroadcastReceiver; 7 | import android.content.Context; 8 | import android.content.DialogInterface; 9 | import android.content.Intent; 10 | import android.content.IntentFilter; 11 | import android.support.v7.app.AlertDialog; 12 | import android.support.v7.app.AppCompatActivity; 13 | import android.os.Bundle; 14 | import android.util.Log; 15 | import android.view.View; 16 | import android.widget.AdapterView; 17 | import android.widget.Button; 18 | import android.widget.EditText; 19 | import android.widget.ListView; 20 | import android.widget.Toast; 21 | 22 | //import com.wxxiaomi.ming.buletouthdemo.latest.BleUtil; 23 | 24 | import com.wxxiaomi.ming.buletouthdemo.ui.RunActivity2; 25 | 26 | import java.util.Collections; 27 | import java.util.Comparator; 28 | 29 | public class BoundActivity extends AppCompatActivity { 30 | 31 | // private BluetoothHelper helper; 32 | 33 | // private TextView tv_current_bluetooth_status; 34 | private Button btn_search_devices; 35 | private ListView lv_bluetooth_devices; 36 | private EditText et; 37 | /** 38 | * 适配器 39 | */ 40 | private BluetoothDeviceAdapter deviceAdapter; 41 | /** 42 | * 询问笔录数据 43 | */ 44 | // private InquiryTranscripts data; 45 | 46 | 47 | @Override 48 | protected void onCreate(Bundle savedInstanceState) { 49 | super.onCreate(savedInstanceState); 50 | setContentView(R.layout.activity_main); 51 | // helper = new BluetoothHelper(this.getApplicationContext()); 52 | 53 | initView(); 54 | initListener(); 55 | 56 | if (BluetoothHelper.isBluetoothOpen()) { 57 | BluetoothHelper.searchDevices(); 58 | } 59 | } 60 | 61 | /** 62 | * 初始化界面控件 63 | */ 64 | private void initView() { 65 | et = (EditText) findViewById(R.id.et); 66 | btn_search_devices = (Button) findViewById(R.id.btn_search_devices); 67 | lv_bluetooth_devices = (ListView) findViewById(R.id.lv_bluetooth_devices); 68 | changeBluetoothStatus(); 69 | deviceAdapter = new BluetoothDeviceAdapter(BoundActivity.this, BluetoothHelper.getBluetoothDevices()); 70 | lv_bluetooth_devices.setAdapter(deviceAdapter); 71 | } 72 | 73 | 74 | 75 | /** 76 | * 修改界面中关于蓝牙状态的显示状态 77 | */ 78 | private void changeBluetoothStatus() { 79 | String argStr = "当前蓝牙状态:%1$s"; 80 | if (BluetoothHelper.isBluetoothOpen()) { 81 | // tv_current_bluetooth_status.setText(String.format(argStr, "已开启")); 82 | // btn_open_bluetooth.setVisibility(View.GONE); 83 | // btn_search_devices.setEnabled(true); 84 | } else { 85 | // tv_current_bluetooth_status.setText(String.format(argStr, "已关闭")); 86 | // btn_open_bluetooth.setVisibility(View.VISIBLE); 87 | // btn_search_devices.setEnabled(false); 88 | } 89 | } 90 | 91 | /** 92 | * 初始化控件监听器 93 | */ 94 | private void initListener() { 95 | // btn_open_bluetooth.setOnClickListener(new View.OnClickListener() { 96 | // @Override 97 | // public void onClick(View view) { 98 | // if (!helper.isBluetoothOpen()) { 99 | // helper.openBluetooth(BoundActivity.this); 100 | // } 101 | // } 102 | // }); 103 | btn_search_devices.setOnClickListener(new View.OnClickListener() { 104 | @Override 105 | public void onClick(View view) { 106 | BluetoothHelper.searchDevices(); 107 | } 108 | }); 109 | lv_bluetooth_devices.setOnItemClickListener(new AdapterView.OnItemClickListener() { 110 | @Override 111 | public void onItemClick(AdapterView adapterView, View view, final int i, long l) { 112 | Log.i("wang","i:"+i); 113 | final BluetoothDevice device = BluetoothHelper.getBluetoothDevices().get(i); 114 | if (device.getBondState() == BluetoothDevice.BOND_BONDED) { 115 | new AlertDialog.Builder(BoundActivity.this).setTitle("标题") 116 | .setMessage("确定使用" + device.getName() + "进行打印吗?") 117 | .setPositiveButton("取消", null) 118 | .setNegativeButton("确定", new DialogInterface.OnClickListener() { 119 | @Override 120 | public void onClick(DialogInterface dialogInterface, int i) { 121 | String text = et.getText().toString().trim(); 122 | BluetoothHelper.printDocument(device,text,null); 123 | 124 | } 125 | }).create().show(); 126 | } else if (device.getBondState() == BluetoothDevice.BOND_BONDING) { 127 | // 正在绑定 128 | Toast.makeText(getApplicationContext(), "正在配对该设备,暂时无法使用", Toast.LENGTH_SHORT).show(); 129 | } else { 130 | // 没有绑定 131 | new AlertDialog.Builder(BoundActivity.this).setTitle("标题") 132 | .setMessage("您确定要配对该设备吗?") 133 | .setPositiveButton("取消", null) 134 | .setNegativeButton("确定", new DialogInterface.OnClickListener() { 135 | @Override 136 | public void onClick(DialogInterface dialogInterface, int a) { 137 | // BluetoothHelper.getBluetoothDevices().get(i). 138 | 139 | boolean b = BluetoothHelper.bondDevice(BluetoothHelper.getBluetoothDevices().get(i)); 140 | Log.i("wang","绑定的结果:"+b); 141 | } 142 | }).create().show(); 143 | } 144 | } 145 | }); 146 | } 147 | 148 | @Override 149 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 150 | super.onActivityResult(requestCode, resultCode, data); 151 | if (requestCode == 6) { 152 | // 打开蓝牙的回调 153 | changeBluetoothStatus(); 154 | } 155 | } 156 | 157 | @Override 158 | protected void onStart() { 159 | super.onStart(); 160 | 161 | initIntentFilter(); 162 | } 163 | 164 | /** 165 | * 初始化过滤器 166 | */ 167 | private void initIntentFilter() { 168 | // 设置广播信息过滤 169 | IntentFilter intentFilter = new IntentFilter(); 170 | intentFilter.addAction(BluetoothDevice.ACTION_FOUND); 171 | intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); 172 | intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); 173 | intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 174 | intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); 175 | // intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 176 | // intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 177 | // intentFilter.addAction(BluetoothAdapter.ACTION_BOND_STATE_CHANGED); 178 | // 注册广播接收器,接收并处理搜索结果 179 | registerReceiver(receiver, intentFilter); 180 | } 181 | 182 | /** 183 | * 标记是否正在搜索设备 184 | */ 185 | private boolean isSearching = false; 186 | 187 | /** 188 | * 蓝牙广播接收器 189 | */ 190 | private BroadcastReceiver receiver = new BroadcastReceiver() { 191 | 192 | /** 193 | * 搜索设备的进度条对话框 194 | */ 195 | private ProgressDialog dialog; 196 | 197 | @Override 198 | public void onReceive(Context context, Intent intent) { 199 | String action = intent.getAction(); 200 | if (BluetoothDevice.ACTION_FOUND.equals(action)) { 201 | // 搜索到设备 202 | Log.i("wang","搜索到设备"); 203 | BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 204 | BluetoothHelper.addBluetoothDevices(device); 205 | } else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) { 206 | Log.i("wang","开始搜索"); 207 | // 开始搜索 208 | dialog = new ProgressDialog(context); 209 | dialog.setMessage("正在搜索设备,请稍候..."); 210 | dialog.setCancelable(false); 211 | dialog.show(); 212 | 213 | isSearching = true; 214 | } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { 215 | Log.i("wang","搜索结束"); 216 | // 搜索结束 217 | if (dialog != null && dialog.isShowing()) { 218 | dialog.dismiss(); 219 | } 220 | 221 | if (isSearching) { 222 | Toast.makeText(BoundActivity.this.getApplicationContext(), "搜索结束,共搜索到" + BluetoothHelper.getBluetoothDevices().size() + "台设备", Toast.LENGTH_SHORT).show(); 223 | } 224 | isSearching = false; 225 | // 根据配对情况进行排序 226 | Collections.sort(BluetoothHelper.getBluetoothDevices(), new Comparator() { 227 | @Override 228 | public int compare(BluetoothDevice device, BluetoothDevice t1) { 229 | return device.getBondState() - t1.getBondState(); 230 | } 231 | }); 232 | 233 | deviceAdapter.notifyDataSetChanged(); 234 | }else if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)){ 235 | 236 | } 237 | else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) { 238 | Log.i("wang","状态改变"); 239 | BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 240 | switch (device.getBondState()) { 241 | case BluetoothDevice.BOND_BONDING://正在配对 242 | Log.i("wang", "正在配对......"); 243 | // onRegisterBltReceiver.onBltIng(device); 244 | break; 245 | case BluetoothDevice.BOND_BONDED://配对结束 246 | Log.i("wang", "完成配对"); 247 | // onRegisterBltReceiver.onBltEnd(device); 248 | Intent i = new Intent(BoundActivity.this,RunActivity2.class); 249 | startActivity(i); 250 | finish(); 251 | break; 252 | case BluetoothDevice.BOND_NONE://取消配对/未配对 253 | Log.i("wang", "取消配对"); 254 | // onRegisterBltReceiver.onBltNone(device); 255 | default: 256 | break; 257 | } 258 | } 259 | if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) { 260 | Log.i("wang", "ACTION_STATE_CHANGED"); 261 | changeBluetoothStatus(); 262 | } 263 | } 264 | }; 265 | 266 | @Override 267 | protected void onStop() { 268 | super.onStop(); 269 | 270 | unregisterReceiver(receiver); 271 | } 272 | } 273 | -------------------------------------------------------------------------------- /BuleTouthDemo/app/src/main/java/com/wxxiaomi/ming/buletouthdemo/HomeActivity.java: -------------------------------------------------------------------------------- 1 | package com.wxxiaomi.ming.buletouthdemo; 2 | 3 | import android.content.Intent; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.Button; 8 | 9 | import com.wxxiaomi.ming.buletouthdemo.ui.RunActivity2; 10 | 11 | public class HomeActivity extends AppCompatActivity { 12 | 13 | private Button btn; 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.activity_home); 18 | BluetoothHelper.getInstance().init(getApplicationContext()); 19 | btn = (Button) findViewById(R.id.btn); 20 | btn.setOnClickListener(new View.OnClickListener() { 21 | @Override 22 | public void onClick(View view) { 23 | Intent intent = null; 24 | if(BluetoothHelper.isEverDevice()){ 25 | intent = new Intent(HomeActivity.this,RunActivity2.class); 26 | }else{ 27 | intent = new Intent(HomeActivity.this,BoundActivity.class); 28 | } 29 | startActivity(intent); 30 | } 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /BuleTouthDemo/app/src/main/java/com/wxxiaomi/ming/buletouthdemo/RunActivity.java: -------------------------------------------------------------------------------- 1 | package com.wxxiaomi.ming.buletouthdemo; 2 | 3 | import android.app.ProgressDialog; 4 | import android.bluetooth.BluetoothAdapter; 5 | import android.bluetooth.BluetoothDevice; 6 | import android.content.BroadcastReceiver; 7 | import android.content.Context; 8 | import android.content.Intent; 9 | import android.content.IntentFilter; 10 | import android.os.Handler; 11 | import android.os.Message; 12 | import android.support.v7.app.AppCompatActivity; 13 | import android.os.Bundle; 14 | import android.text.TextUtils; 15 | import android.util.Log; 16 | import android.view.View; 17 | import android.widget.Button; 18 | import android.widget.EditText; 19 | import android.widget.TextView; 20 | import android.widget.Toast; 21 | 22 | import com.wxxiaomi.ming.buletouthdemo.ui.RunActivity2; 23 | 24 | import java.util.Collections; 25 | import java.util.Comparator; 26 | 27 | public class RunActivity extends AppCompatActivity implements View.OnClickListener { 28 | private TextView tv; 29 | private Button ONA; 30 | private Button ONB; 31 | private Button ONC; 32 | private Button OND; 33 | private Button ONF; 34 | private Button send; 35 | private EditText et; 36 | private Handler hanlder = new Handler(){ 37 | @Override 38 | public void handleMessage(Message msg) { 39 | switch (msg.what){ 40 | case 1: 41 | Log.i("wang","初始化完成,链接成功"); 42 | break; 43 | } 44 | } 45 | }; 46 | @Override 47 | protected void onCreate(Bundle savedInstanceState) { 48 | super.onCreate(savedInstanceState); 49 | setContentView(R.layout.activity_run); 50 | tv = (TextView) findViewById(R.id.tv); 51 | ONA = (Button) findViewById(R.id.ONA); 52 | ONA.setOnClickListener(this); 53 | ONB = (Button) findViewById(R.id.ONB); 54 | ONB.setOnClickListener(this); 55 | ONC = (Button) findViewById(R.id.ONC); 56 | ONC.setOnClickListener(this); 57 | OND = (Button) findViewById(R.id.OND); 58 | OND.setOnClickListener(this); 59 | ONF = (Button) findViewById(R.id.ONF); 60 | ONF.setOnClickListener(this); 61 | send = (Button) findViewById(R.id.send); 62 | send.setOnClickListener(this); 63 | 64 | et = (EditText) findViewById(R.id.et); 65 | registe(); 66 | init(); 67 | 68 | 69 | } 70 | 71 | private void init() { 72 | Log.i("wang","假装这个是progress:正在初始化"); 73 | //此时应该测试链接 74 | new Thread(){ 75 | @Override 76 | public void run() { 77 | boolean b = BluetoothHelper.bondDevice(BluetoothHelper.getCurrentDevice()); 78 | if(b){ 79 | boolean ona = BluetoothHelper.printDocument(BluetoothHelper.getCurrentDevice(), "ONA",null); 80 | if(ona){ 81 | hanlder.sendEmptyMessage(1); 82 | } 83 | } 84 | } 85 | }.start(); 86 | 87 | } 88 | 89 | @Override 90 | public void onClick(View view) { 91 | switch (view.getId()){ 92 | case R.id.ONA: 93 | BluetoothHelper.printDocument(BluetoothHelper.getCurrentDevice(),"ONA",null); 94 | break; 95 | case R.id.ONB: 96 | BluetoothHelper.printDocument(BluetoothHelper.getCurrentDevice(),"ONB",null); 97 | break; 98 | case R.id.ONC: 99 | BluetoothHelper.printDocument(BluetoothHelper.getCurrentDevice(),"ONC",null); 100 | break; 101 | case R.id.OND: 102 | BluetoothHelper.printDocument(BluetoothHelper.getCurrentDevice(),"OND",null); 103 | break; 104 | case R.id.ONF: 105 | BluetoothHelper.printDocument(BluetoothHelper.getCurrentDevice(),"ONF",null); 106 | break; 107 | case R.id.send: 108 | String text = et.getText().toString().trim(); 109 | if(!TextUtils.isEmpty(text)){ 110 | BluetoothHelper.printDocument(BluetoothHelper.getCurrentDevice(),text,null); 111 | } 112 | 113 | break; 114 | } 115 | } 116 | 117 | @Override 118 | protected void onDestroy() { 119 | BluetoothHelper.Destory(); 120 | super.onDestroy(); 121 | } 122 | 123 | public void registe(){ 124 | IntentFilter intentFilter = new IntentFilter(); 125 | intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); 126 | intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); 127 | // intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); 128 | // intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 129 | // intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); 130 | registerReceiver(receiver, intentFilter); 131 | } 132 | 133 | private BroadcastReceiver receiver = new BroadcastReceiver() { 134 | 135 | /** 136 | * 搜索设备的进度条对话框 137 | */ 138 | 139 | @Override 140 | public void onReceive(Context context, Intent intent) { 141 | String action = intent.getAction(); 142 | if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) { 143 | Log.i("wang","收到广播:BluetoothDevice.ACTION_ACL_DISCONNECTED"); 144 | } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) { 145 | Log.i("wang","收到广播:BluetoothDevice.ACTION_ACL_DISCONNECTED"); 146 | } 147 | } 148 | }; 149 | } 150 | -------------------------------------------------------------------------------- /BuleTouthDemo/app/src/main/java/com/wxxiaomi/ming/buletouthdemo/touch/TouchMsgThread.java: -------------------------------------------------------------------------------- 1 | package com.wxxiaomi.ming.buletouthdemo.touch; 2 | 3 | import android.bluetooth.BluetoothSocket; 4 | import android.os.Handler; 5 | import android.os.Message; 6 | import android.util.Log; 7 | 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.io.OutputStream; 11 | 12 | /** 13 | * Created by Administrator on 2017/1/25. 14 | */ 15 | 16 | public class TouchMsgThread extends Thread { 17 | private BluetoothSocket socket; 18 | private InputStream inputStream; 19 | private OutputStream outputStream; 20 | private Handler handler; 21 | public TouchMsgThread(BluetoothSocket socket, Handler handler) { 22 | this.socket = socket; 23 | InputStream input = null; 24 | OutputStream output = null; 25 | this.handler = handler; 26 | try { 27 | input = socket.getInputStream(); 28 | output = socket.getOutputStream(); 29 | } catch (IOException e) { 30 | e.printStackTrace(); 31 | } 32 | this.inputStream = input; 33 | this.outputStream = output; 34 | } 35 | public void run() { 36 | // 37 | while (true) { 38 | try { 39 | int count = 5; 40 | byte[] bytes = new byte[count]; 41 | int readCount = 0; // 已经成功读取的字节的个数 42 | while (readCount < count) { 43 | readCount += inputStream.read(bytes, readCount, count - readCount); 44 | } 45 | int s = BinaryToHexString(bytes); 46 | 47 | Message message=handler.obtainMessage(); 48 | message.what = 333; 49 | message.obj=s; 50 | handler.sendMessage(message); 51 | } catch (Exception e) { 52 | e.printStackTrace(); 53 | break; 54 | } 55 | } 56 | } 57 | public void write(byte[] bytes) { 58 | try { 59 | byte[] b = {-1,1,2,3,-1}; 60 | // outputStream.write(-1); 61 | // outputStream.write(1); 62 | // outputStream.write(2); 63 | // outputStream.write(3); 64 | outputStream.write(b); 65 | outputStream.flush(); 66 | } catch (IOException e) { 67 | e.printStackTrace(); 68 | } 69 | } 70 | public void cancel() { 71 | try { 72 | if(outputStream!=null){ 73 | outputStream.close(); 74 | outputStream = null; 75 | } 76 | if(inputStream!=null){ 77 | inputStream.close(); 78 | inputStream = null; 79 | } 80 | //socket.close(); 81 | } catch (IOException e) { 82 | e.printStackTrace(); 83 | } 84 | } 85 | public static int BinaryToHexString(byte[] bytes) { 86 | // String hexStr = "0123456789ABCDEF"; 87 | int result = 0; 88 | String temp = ""; 89 | //String hex = "" = ""; 90 | for(int i=0;i<5;i++){ 91 | byte b = bytes[i]; 92 | 93 | 94 | if(i==2){ 95 | temp = Integer.toHexString((b & 0xff)); 96 | 97 | } 98 | if(i==3){ 99 | String hex = Integer.toHexString((b & 0xff)); 100 | result = Integer.parseInt(temp+hex, 16); 101 | } 102 | 103 | } 104 | Log.i("wang","result:"+result); 105 | // for (byte b : bytes) { 106 | // Log.i("wang","b:"+b); 107 | 108 | 109 | 110 | 111 | // hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 4)); 112 | // hex += String.valueOf(hexStr.charAt(b & 0x0F)); 113 | // int h = Integer.valueOf(hex); 114 | //// hex = new String(h); 115 | // result += hex + " "; 116 | // } 117 | return result; 118 | } 119 | } 120 | 121 | -------------------------------------------------------------------------------- /BuleTouthDemo/app/src/main/java/com/wxxiaomi/ming/buletouthdemo/ui/RunActivity2.java: -------------------------------------------------------------------------------- 1 | package com.wxxiaomi.ming.buletouthdemo.ui; 2 | 3 | import android.os.Handler; 4 | import android.os.Message; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.os.Bundle; 7 | import android.util.Log; 8 | 9 | import com.github.anastr.speedviewlib.DeluxeSpeedView; 10 | import com.github.anastr.speedviewlib.PointerSpeedometer; 11 | import com.wxxiaomi.ming.buletouthdemo.BluetoothHelper; 12 | import com.wxxiaomi.ming.buletouthdemo.R; 13 | 14 | public class RunActivity2 extends AppCompatActivity { 15 | 16 | PointerSpeedometer pointerSpeedometer; 17 | private Handler hanlder = new Handler(){ 18 | @Override 19 | public void handleMessage(Message msg) { 20 | switch (msg.what){ 21 | case 1: 22 | Log.i("wang","初始化完成,链接成功"); 23 | break; 24 | case 333: 25 | pointerSpeedometer.speedTo((int)msg.obj); 26 | break; 27 | } 28 | } 29 | }; 30 | 31 | @Override 32 | protected void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | setContentView(R.layout.activity_run2); 35 | pointerSpeedometer = (PointerSpeedometer) findViewById(R.id.pointerSpeedometer); 36 | // pointerSpeedometer.speedTo(90); 37 | // deluxeSpeedView.setWithEffects(true); 38 | init(); 39 | } 40 | 41 | private void init() { 42 | Log.i("wang","假装这个是progress:正在初始化"); 43 | //此时应该测试链接 44 | new Thread(){ 45 | @Override 46 | public void run() { 47 | boolean b = BluetoothHelper.bondDevice(BluetoothHelper.getCurrentDevice()); 48 | if(b){ 49 | boolean ona = BluetoothHelper.printDocument(BluetoothHelper.getCurrentDevice(), "ONA",hanlder); 50 | if(ona){ 51 | hanlder.sendEmptyMessage(1); 52 | } 53 | } 54 | } 55 | }.start(); 56 | 57 | } 58 | 59 | 60 | @Override 61 | protected void onDestroy() { 62 | BluetoothHelper.Destory(); 63 | super.onDestroy(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /BuleTouthDemo/app/src/main/res/layout/activity_home.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 |