├── .gitignore ├── .idea ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── dictionaries │ └── w.xml ├── encodings.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── exce │ │ └── bluetooth │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── exce │ │ │ └── bluetooth │ │ │ ├── bean │ │ │ ├── Constants.java │ │ │ ├── EcgPoint.java │ │ │ ├── FragmentInfo.java │ │ │ ├── MyField.java │ │ │ └── UserInfo.java │ │ │ ├── ui │ │ │ ├── LoginActivity.java │ │ │ ├── MainTabActivity.java │ │ │ ├── PersonalActivity.java │ │ │ ├── activity │ │ │ │ ├── ble │ │ │ │ │ └── BLEActivity.java │ │ │ │ ├── usb │ │ │ │ │ └── USBActivity.java │ │ │ │ └── wifi │ │ │ │ │ ├── Server.java │ │ │ │ │ ├── WifiConfigActivity.java │ │ │ │ │ ├── WifiServerActivity.java │ │ │ │ │ └── tcp │ │ │ │ │ ├── TcpClient.java │ │ │ │ │ └── TcpServer.java │ │ │ ├── adapter │ │ │ │ ├── BleListAdapter.java │ │ │ │ ├── ViewPagerAdapter.java │ │ │ │ └── WifiListAdapter.java │ │ │ └── fragment │ │ │ │ ├── TabOneFragment.java │ │ │ │ ├── TabThreeFragment.java │ │ │ │ └── TabTwoFragment.java │ │ │ ├── utils │ │ │ ├── MyObjIterator.java │ │ │ ├── SPUntil.java │ │ │ ├── SharedPreferenceUtil.java │ │ │ ├── Utils.java │ │ │ └── test.java │ │ │ └── view │ │ │ ├── EcgView.java │ │ │ └── EcgViewTT.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── background_card.9.png │ │ ├── ic_launcher_background.xml │ │ ├── ic_new.png │ │ ├── radius_drawable_bg.xml │ │ └── refresh_fab.xml │ │ ├── layout-v21 │ │ └── dialog_scan_device.xml │ │ ├── layout │ │ ├── act_ble.xml │ │ ├── act_usb.xml │ │ ├── act_wifi.xml │ │ ├── activity_ecg_register.xml │ │ ├── activity_login.xml │ │ ├── activity_peronal.xml │ │ ├── activity_set.xml │ │ ├── activity_sidebar.xml │ │ ├── activity_tab.xml │ │ ├── dialog_scan_device.xml │ │ ├── fragment_home.xml │ │ ├── fragment_home_wifi.xml │ │ ├── fragment_location.xml │ │ ├── fragment_mine.xml │ │ ├── item_list_scan.xml │ │ ├── layout_header.xml │ │ ├── wifi_dialog_scan_device.xml │ │ ├── wifi_item_list.xml │ │ └── wifi_main.xml │ │ ├── menu │ │ ├── menu_left.xml │ │ └── toolbar_menu.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── bg_header.jpg │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ ├── ic_menu_more_overflow.png │ │ ├── ic_message.png │ │ ├── ic_ref.png │ │ ├── ic_search.png │ │ ├── ic_setting.png │ │ ├── icon_message.png │ │ ├── message.png │ │ ├── setting.png │ │ └── update.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 │ │ ├── login_paw_code.png │ │ └── login_paw_left.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── raw │ │ └── exceecg.txt │ │ └── values │ │ ├── array.xml │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── exce │ └── bluetooth │ └── ExampleUnitTest.java ├── bleutils ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── exce │ │ └── bleutils │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── exce │ │ │ └── bleutils │ │ │ ├── BleController.java │ │ │ ├── callback │ │ │ ├── BleDevceScanCallback.java │ │ │ ├── ConnectCallback.java │ │ │ ├── OnReceiverCallback.java │ │ │ ├── OnWriteCallback.java │ │ │ └── ScanCallback.java │ │ │ ├── request │ │ │ ├── IRequestQueue.java │ │ │ └── ReceiverRequestQueue.java │ │ │ └── utils │ │ │ └── HexUtil.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── exce │ └── bleutils │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── wifiutils ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src ├── androidTest └── java │ └── com │ └── exce │ └── wifiutils │ └── ExampleInstrumentedTest.java ├── main ├── AndroidManifest.xml ├── java │ └── com │ │ └── exce │ │ └── wifiutils │ │ ├── ConfigSecurities.java │ │ ├── ConnectorUtils.java │ │ ├── LocationUtils.java │ │ ├── WeakHandler.java │ │ ├── WifiConnectorBuilder.java │ │ ├── WifiUtils.java │ │ ├── wifiConnect │ │ ├── ConnectionScanResultsListener.java │ │ ├── ConnectionSuccessListener.java │ │ ├── WifiConnectionCallback.java │ │ └── WifiConnectionReceiver.java │ │ ├── wifiScan │ │ ├── ScanResultsListener.java │ │ ├── WifiScanCallback.java │ │ └── WifiScanReceiver.java │ │ ├── wifiState │ │ ├── WifiStateCallback.java │ │ ├── WifiStateListener.java │ │ └── WifiStateReceiver.java │ │ └── wifiWps │ │ └── ConnectionWpsListener.java └── res │ └── values │ └── strings.xml └── test └── java └── com └── exce └── wifiutils └── ExampleUnitTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/libraries 5 | /.idea/modules.xml 6 | /.idea/workspace.xml 7 | .DS_Store 8 | /build 9 | /captures 10 | .externalNativeBuild 11 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/dictionaries/w.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 37 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android-ECG-Test 2 | android app 界面显示心电图,三种通信(BLE,WIFI,USB)。 3 | 目前实现TCP测试demo,BLE正在测试中。。2018/04/20 4 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 27 5 | defaultConfig { 6 | applicationId "com.exce.bluetooth" 7 | minSdkVersion 19 8 | targetSdkVersion 27 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 | compileOptions { 20 | encoding "UTF-8" 21 | sourceCompatibility JavaVersion.VERSION_1_8 22 | targetCompatibility JavaVersion.VERSION_1_8 23 | } 24 | } 25 | 26 | dependencies { 27 | implementation fileTree(include: ['*.jar'], dir: 'libs') 28 | implementation 'com.android.support:appcompat-v7:27.1.1' 29 | implementation 'com.android.support:design:27.1.1' 30 | testImplementation 'junit:junit:4.12' 31 | implementation 'com.google.guava:guava:24.1-android' 32 | implementation 'com.google.code.gson:gson:2.8.2' 33 | androidTestImplementation 'com.android.support.test:runner:1.0.1' 34 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' 35 | implementation project(':wifiutils') 36 | implementation project(':bleutils') 37 | } 38 | -------------------------------------------------------------------------------- /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/androidTest/java/com/exce/bluetooth/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth; 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 | * Instrumented 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() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.exce.bluetooth", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 28 | 29 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/bean/Constants.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.bean; 2 | 3 | /** 4 | * @Author Wangjj 5 | * @Create 2018/4/20. 6 | * @Title 常用的一些常量 7 | */ 8 | public class Constants { 9 | 10 | public static final byte UNKNOWN = 0; // 性别未知 11 | public static final byte BOY = 1; // 男 12 | public static final byte GIRL = 2; // 女 13 | 14 | public static final int II = 1; 15 | public static final int III = 2; 16 | public static final int aVR = 3; 17 | public static final int aVL = 4; 18 | public static final int aVF = 5; 19 | public static final int V1 = 6; 20 | public static final int V2 = 7; 21 | public static final int V3 = 8; 22 | public static final int V4 = 9; 23 | public static final int V5 = 10; 24 | public static final int V6 = 11; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/bean/EcgPoint.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.bean; 2 | 3 | /** 4 | * 点 5 | * @Author Wangjj 6 | * @Create 2018/3/29. 7 | * @Content 8 | */ 9 | public class EcgPoint { 10 | private float x; 11 | private float y; 12 | 13 | public EcgPoint(float x, float y) { 14 | this.x = x; 15 | this.y = y; 16 | } 17 | 18 | public float getX() { 19 | return x; 20 | } 21 | 22 | public void setX(float x) { 23 | this.x = x; 24 | } 25 | 26 | public float getY() { 27 | return y; 28 | } 29 | 30 | public void setY(float y) { 31 | this.y = y; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/bean/FragmentInfo.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.bean; 2 | 3 | /** 4 | * @Author Wangjj 5 | * @Create 2017/12/21. 6 | * @Content 7 | */ 8 | 9 | public class FragmentInfo { 10 | 11 | private String title; 12 | 13 | private Class fragment; 14 | 15 | public FragmentInfo(String title, Class fragment) { 16 | this.title = title; 17 | this.fragment = fragment; 18 | } 19 | 20 | public String getTitle() { 21 | return title; 22 | } 23 | 24 | public void setTitle(String title) { 25 | this.title = title; 26 | } 27 | 28 | public Class getFragment() { 29 | return fragment; 30 | } 31 | 32 | public void setFragment(Class fragment) { 33 | this.fragment = fragment; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/bean/MyField.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.bean; 2 | 3 | import java.lang.reflect.Type; 4 | 5 | /** 6 | * @Author Wangjj 7 | * @Create 2018/4/20. 8 | * @Content 9 | */ 10 | public class MyField { 11 | private String name; 12 | private Type type; 13 | private Object value; 14 | 15 | public MyField() { 16 | } 17 | 18 | public MyField(String name, Type type, Object value) { 19 | this.name = name; 20 | this.type = type; 21 | this.value = value; 22 | } 23 | 24 | public String getName() { 25 | return name; 26 | } 27 | 28 | public void setName(String name) { 29 | this.name = name; 30 | } 31 | 32 | public Type getType() { 33 | return type; 34 | } 35 | 36 | public void setType(Type type) { 37 | this.type = type; 38 | } 39 | 40 | public Object getValue() { 41 | return value; 42 | } 43 | 44 | public void setValue(Object value) { 45 | this.value = value; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/bean/UserInfo.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.bean; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @Author Wangjj 7 | * @Create 2018/4/9. 8 | * @Content 9 | */ 10 | public class UserInfo implements Serializable { 11 | private String openId;//账号 12 | private byte age;//年龄 13 | private float height;//身高 14 | private String userName;//姓名 15 | private byte sex;//性别 16 | private float weight; // 体重 17 | private String phone;//手机号 18 | private String cid;//身份证 19 | private short sampleSpeed;//采样速率 20 | public byte gain; //增益 21 | private byte patientType;// 病人类型 22 | private byte displayLines;// 显示通道 8 23 | 24 | public String getOpenId() { 25 | return openId; 26 | } 27 | 28 | public UserInfo setOpenId(String openId) { 29 | this.openId = openId; 30 | return this; 31 | } 32 | 33 | public byte getAge() { 34 | return age; 35 | } 36 | 37 | public UserInfo setAge(byte age) { 38 | this.age = age; 39 | return this; 40 | } 41 | 42 | public float getHeight() { 43 | return height; 44 | } 45 | 46 | public UserInfo setHeight(float height) { 47 | this.height = height; 48 | return this; 49 | } 50 | 51 | public String getUserName() { 52 | return userName; 53 | } 54 | 55 | public UserInfo setUserName(String userName) { 56 | this.userName = userName; 57 | return this; 58 | } 59 | 60 | public byte getSex() { 61 | return sex; 62 | } 63 | 64 | public UserInfo setSex(byte sex) { 65 | this.sex = sex; 66 | return this; 67 | } 68 | 69 | public float getWeight() { 70 | return weight; 71 | } 72 | 73 | public UserInfo setWeight(float weight) { 74 | this.weight = weight; 75 | return this; 76 | } 77 | 78 | public String getPhone() { 79 | return phone; 80 | } 81 | 82 | public UserInfo setPhone(String phone) { 83 | this.phone = phone; 84 | return this; 85 | } 86 | 87 | public String getCid() { 88 | return cid; 89 | } 90 | 91 | public UserInfo setCid(String cid) { 92 | this.cid = cid; 93 | return this; 94 | } 95 | 96 | public short getSampleSpeed() { 97 | return sampleSpeed; 98 | } 99 | 100 | public UserInfo setSampleSpeed(short sampleSpeed) { 101 | this.sampleSpeed = sampleSpeed; 102 | return this; 103 | } 104 | 105 | public byte getGain() { 106 | return gain; 107 | } 108 | 109 | public UserInfo setGain(byte gain) { 110 | this.gain = gain; 111 | return this; 112 | } 113 | 114 | public byte getPatientType() { 115 | return patientType; 116 | } 117 | 118 | public UserInfo setPatientType(byte patientType) { 119 | this.patientType = patientType; 120 | return this; 121 | } 122 | 123 | public byte getDisplayLines() { 124 | return displayLines; 125 | } 126 | 127 | public UserInfo setDisplayLines(byte displayLines) { 128 | this.displayLines = displayLines; 129 | return this; 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/ui/LoginActivity.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.ui; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.View; 8 | import android.view.View.OnClickListener; 9 | import android.widget.Button; 10 | import android.widget.EditText; 11 | import android.widget.Toast; 12 | 13 | import com.exce.bluetooth.R; 14 | 15 | /** 16 | * @Author Wangjj 17 | * @Create 2018/4/9. 18 | * @Content 19 | */ 20 | public class LoginActivity extends AppCompatActivity implements OnClickListener { 21 | 22 | EditText mUsername, mPassword; 23 | Button mBtnLogin; 24 | private String login_name, login_password; 25 | @Override 26 | protected void onCreate(@Nullable Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | setContentView(R.layout.activity_login); 29 | init(); 30 | } 31 | 32 | private void init() { 33 | mUsername = findViewById(R.id.username); 34 | mPassword = findViewById(R.id.password); 35 | mBtnLogin = findViewById(R.id.main_btn_login); 36 | mBtnLogin.setOnClickListener(this); 37 | // 38 | // mUsername.setText(SharedPreferenceUtil.getLoginName(this)); 39 | // mPassword.setText(SharedPreferenceUtil.getLoginPassword(this)); 40 | } 41 | 42 | @Override 43 | public void onClick(View v) { 44 | switch (v.getId()) { 45 | case R.id.main_btn_login: 46 | login_name = mUsername.getText().toString(); 47 | login_password = mPassword.getText().toString(); 48 | if (mUsername.getText().toString().equals(login_name) && 49 | mPassword.getText().toString().equals(login_password)) { 50 | Intent intent = new Intent(this, MainTabActivity.class); 51 | startActivity(intent); 52 | // SharedPreferenceUtil.putLoginName(getApplicationContext(), login_name); 53 | // SharedPreferenceUtil.putLoginPassword(getApplicationContext(), login_password); 54 | Toast.makeText(getApplicationContext(), "登陆成功...", Toast.LENGTH_SHORT).show(); 55 | }else{ 56 | Toast.makeText(getApplicationContext(), "重新登陆...", Toast.LENGTH_SHORT).show(); 57 | } 58 | break; 59 | default: 60 | break; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/ui/MainTabActivity.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.ui; 2 | 3 | import android.content.Intent; 4 | import android.support.design.widget.NavigationView; 5 | import android.support.design.widget.TabLayout; 6 | import android.support.v4.view.PagerAdapter; 7 | import android.support.v4.view.ViewPager; 8 | import android.support.v4.widget.DrawerLayout; 9 | import android.support.v7.app.AppCompatActivity; 10 | import android.os.Bundle; 11 | import android.view.View; 12 | import android.widget.Toast; 13 | 14 | import com.exce.bluetooth.R; 15 | import com.exce.bluetooth.ui.adapter.ViewPagerAdapter; 16 | 17 | public class MainTabActivity extends AppCompatActivity { 18 | 19 | NavigationView mNavigationView; 20 | DrawerLayout mDrawerLayout; 21 | TabLayout mTabLayout; 22 | ViewPager mViewPager; 23 | private View headerView; 24 | 25 | @Override 26 | protected void onCreate(Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | setContentView(R.layout.activity_tab); 29 | init(); 30 | } 31 | 32 | public void init() { 33 | mNavigationView = findViewById(R.id.navigation_view); 34 | mDrawerLayout = findViewById(R.id.drawer_layout); 35 | 36 | mTabLayout = findViewById(R.id.tab_layout); 37 | mViewPager = findViewById(R.id.view_pager); 38 | initDrawerLayout(); 39 | initTablayout(); 40 | } 41 | 42 | private void initTablayout() { 43 | 44 | PagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); 45 | mViewPager.setAdapter(adapter); 46 | mViewPager.setOffscreenPageLimit(adapter.getCount()); 47 | mTabLayout.setupWithViewPager(mViewPager); 48 | 49 | } 50 | 51 | private void initDrawerLayout() { 52 | 53 | headerView = mNavigationView.getHeaderView(0); 54 | headerView.setOnClickListener(v -> { 55 | Intent intent = new Intent(getApplicationContext(),LoginActivity.class); 56 | startActivity(intent); 57 | Toast.makeText(MainTabActivity.this, "headerView clicked", Toast.LENGTH_LONG).show(); 58 | }); 59 | 60 | mNavigationView.setNavigationItemSelectedListener(item -> { 61 | 62 | switch (item.getItemId()) { 63 | case R.id.menu_app_update: 64 | Toast.makeText(MainTabActivity.this, "点击了应用更新", Toast.LENGTH_LONG).show(); 65 | break; 66 | case R.id.menu_message: 67 | Toast.makeText(MainTabActivity.this, "点击了消息", Toast.LENGTH_LONG).show(); 68 | break; 69 | } 70 | 71 | return false; 72 | }); 73 | 74 | 75 | 76 | // ActionBarDrawerToggle drawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolBar, R.string.open, R.string.close); 77 | // 78 | // drawerToggle.syncState(); 79 | // 80 | // mDrawerLayout.addDrawerListener(drawerToggle); 81 | 82 | } 83 | 84 | 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/ui/PersonalActivity.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.ui; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.util.Log; 7 | import android.view.View; 8 | import android.widget.AdapterView; 9 | import android.widget.Button; 10 | import android.widget.EditText; 11 | import android.widget.Spinner; 12 | 13 | import com.exce.bluetooth.R; 14 | import com.exce.bluetooth.bean.UserInfo; 15 | import com.exce.bluetooth.utils.SharedPreferenceUtil; 16 | 17 | /** 18 | * @Author Wangjj 19 | * @Create 2018/4/10. 20 | * @Content 个人中心 21 | */ 22 | public class PersonalActivity extends AppCompatActivity implements View.OnClickListener, AdapterView.OnItemSelectedListener { 23 | private EditText mAge, mHeight, mUserName, mSex, mWeight, mPhone, mCid; 24 | private Button save; 25 | private Spinner mSampleSpeed, mGain, mPaintType, mDisplayLines; 26 | private UserInfo ui; 27 | 28 | @Override 29 | protected void onCreate(@Nullable Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_peronal); 32 | initArgs(); 33 | } 34 | // 初始化参数 35 | private void initArgs() { 36 | mAge = findViewById(R.id.ecg_age); 37 | mHeight = findViewById(R.id.ecg_height); 38 | mUserName = findViewById(R.id.ecg_name); 39 | mSex = findViewById(R.id.ecg_sex); 40 | mWeight = findViewById(R.id.wcg_weight); 41 | mPhone = findViewById(R.id.ecg_phone); 42 | mCid = findViewById(R.id.ecg_cid); 43 | mSampleSpeed = findViewById(R.id.ecg_sample_speed); 44 | mGain = findViewById(R.id.ecg_gain); 45 | mPaintType = findViewById(R.id.ecg_paint_type); 46 | mDisplayLines = findViewById(R.id.ecg_display_lines); 47 | 48 | mSampleSpeed.setOnItemSelectedListener(this); 49 | mGain.setOnItemSelectedListener(this); 50 | mPaintType.setOnItemSelectedListener(this); 51 | mDisplayLines.setOnItemSelectedListener(this); 52 | 53 | save = findViewById(R.id.ecg_save); 54 | save.setOnClickListener(this); 55 | ui = new UserInfo(); 56 | ui.setAge(Byte.parseByte(mAge.getText().toString())) 57 | .setHeight(mHeight.getHeight()) 58 | .setUserName(mUserName.getText().toString()) 59 | .setSex(Byte.parseByte(mSex.getText().toString())) 60 | .setWeight(Float.parseFloat(mWeight.getText().toString())) 61 | .setPhone(mPhone.getText().toString()) 62 | .setCid(mCid.getText().toString()) 63 | .setSampleSpeed((short) 360) 64 | .setGain((byte) 2) 65 | .setPatientType((byte) 22) 66 | .setDisplayLines((byte) 12); 67 | 68 | } 69 | 70 | @Override 71 | public void onClick(View v) { 72 | //点击保存个人信息数据 73 | try { 74 | SharedPreferenceUtil.saveUser(getApplicationContext(), "ecg", "config_msg", ui); 75 | } catch (Exception e) { 76 | e.printStackTrace(); 77 | } 78 | finish(); 79 | } 80 | 81 | @Override 82 | public void onItemSelected(AdapterView parent, View view, int position, long id) { 83 | switch (parent.getId()) { 84 | case R.id.ecg_sample_speed: 85 | String[] sampleArr = getResources().getStringArray(R.array.sample_speed);//获取采样速率列表数据 86 | // ui.setSampleSpeed(sampleArr[position]); 87 | Log.e("onItemSelected: ", "---------sampleArr--------" + sampleArr[position]); 88 | break; 89 | case R.id.ecg_gain: 90 | String[] gainArr = getResources().getStringArray(R.array.gain);//获取增益列表数据 91 | // ui.setGain(gainArr[position]); 92 | Log.e("onItemSelected: ", "---------gainArr--------" + gainArr[position]); 93 | break; 94 | case R.id.ecg_paint_type: 95 | String[] paintArr = getResources().getStringArray(R.array.patient_type);//获取病人类型列表数据 96 | // ui.setPatientType(paintArr[position]); 97 | Log.e("onItemSelected: ", "---------paintArr--------" + paintArr[position]); 98 | break; 99 | case R.id.ecg_display_lines: 100 | String[] linesArr = getResources().getStringArray(R.array.display_line);//获取显示导联列表数据 101 | // ui.setDisplayLines(linesArr[position]); 102 | Log.e("onItemSelected: ", "---------linesArr--------" + linesArr[position]); 103 | break; 104 | 105 | default: 106 | break; 107 | } 108 | } 109 | 110 | @Override 111 | public void onNothingSelected(AdapterView parent) { 112 | 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/ui/activity/usb/USBActivity.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.ui.activity.usb; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | 7 | import com.exce.bluetooth.R; 8 | 9 | /** 10 | * @Author Wangjj 11 | * @Create 2018/4/8. 12 | * @Content 13 | */ 14 | public class USBActivity extends AppCompatActivity{ 15 | @Override 16 | protected void onCreate(@Nullable Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.act_usb); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/ui/activity/wifi/Server.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.ui.activity.wifi; 2 | 3 | import com.google.common.primitives.Bytes; 4 | import com.google.common.primitives.Shorts; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.DataInputStream; 8 | import java.io.DataOutputStream; 9 | import java.io.File; 10 | import java.io.FileReader; 11 | import java.io.IOException; 12 | import java.io.OutputStream; 13 | import java.net.ServerSocket; 14 | import java.net.Socket; 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | /** 19 | * @Author Wangjj 20 | * @Create 2018/4/8. 21 | * @Content 22 | */ 23 | public class Server { 24 | //协议头 2 字节 总长度 2 字节 帧类型 2 字节 数据长度 2 字节 数据 2 字节 结束字 2 字节 25 | private static void genProtocol(DataOutputStream out, short data) throws IOException { 26 | // 数据 27 | byte[] dataBuffer = Shorts.toByteArray(data); 28 | List sendList = new ArrayList(); 29 | 30 | //帧类型 31 | byte type = 0x30; 32 | sendList.add(type); 33 | 34 | //数据长度 35 | short datalen = (short) ((dataBuffer.length) * 12); 36 | byte[] lenArr = Shorts.toByteArray(datalen); 37 | 38 | for (byte dataLen : lenArr) { 39 | sendList.add(dataLen); 40 | } 41 | //数据 2 * 8 42 | for (int i = 0; i < 12; i++) { 43 | for (byte d : dataBuffer) { 44 | sendList.add(d); 45 | } 46 | } 47 | //结束字 2 48 | byte foot = 0x55; 49 | sendList.add(foot); 50 | sendList.add(foot); 51 | 52 | //总长度 2 53 | short allLen = (short) (sendList.size()); 54 | byte[] allArr = Shorts.toByteArray(allLen); 55 | for (int i = allArr.length-1; i >= 0 ; i--) { 56 | sendList.add(0, allArr[i]); 57 | } 58 | 59 | // 协议头 2 60 | byte head = 0xaa - 256; 61 | sendList.add(0,head); 62 | sendList.add(0,head); 63 | 64 | byte[] send = Bytes.toArray(sendList); 65 | //写入消息内容 66 | out.write(send); 67 | 68 | } 69 | 70 | public class CommunicateThread extends Thread { 71 | Socket socket; 72 | DataInputStream dis; 73 | DataOutputStream dos; 74 | String filename = "D:\\Exce_company\\exceecg.txt"; 75 | 76 | public CommunicateThread(Socket socket) { 77 | this.socket = socket; 78 | try { 79 | dis = new DataInputStream(socket.getInputStream()); 80 | dos = new DataOutputStream(socket.getOutputStream()); 81 | } catch (IOException e) { 82 | e.printStackTrace(); 83 | } 84 | } 85 | 86 | @Override 87 | public void run() { 88 | super.run(); 89 | System.out.println("1连接......"); 90 | OutputStream os = null; 91 | try { 92 | os = socket.getOutputStream(); 93 | DataOutputStream outs = new DataOutputStream(os); 94 | String dataStr = readFileByLines(filename); 95 | String[] dataStrArr = dataStr.split(","); 96 | System.out.println("开始发送"); 97 | int count = 0; 98 | boolean sendover = false; 99 | while (!sendover) { 100 | for (String d : dataStrArr) { 101 | count++; 102 | genProtocol(outs, Short.parseShort(d)); 103 | // Thread.sleep(10); 104 | System.out.println("----------------data: " + d); 105 | } 106 | sendover = true; 107 | System.out.println("tatal received: " + count); 108 | System.out.println("发送完成"); 109 | } 110 | System.out.println("关闭"); 111 | 112 | } catch (Exception e) { 113 | e.printStackTrace(); 114 | } 115 | 116 | } 117 | } 118 | 119 | 120 | public void startServer() { 121 | try { 122 | //服务器在9990端口监听客户端的连接 123 | ServerSocket ss = new ServerSocket(12306); 124 | System.out.println("server is listening..."); 125 | while (true) { 126 | //阻塞的accept方法,当一个客户端连接上,才会返回Socket对象 127 | Socket s = ss.accept(); 128 | System.out.println("a client has connected!"); 129 | 130 | //开启线程处理通信 131 | new CommunicateThread(s).start(); 132 | } 133 | } catch (IOException e) { 134 | e.printStackTrace(); 135 | } 136 | } 137 | 138 | 139 | /** 140 | * 以行为单位读取文件,常用于读面向行的格式化文件 141 | */ 142 | public static String readFileByLines(String fileName) { 143 | File file = new File(fileName); 144 | BufferedReader reader = null; 145 | try { 146 | System.out.println("以行为单位读取文件内容,一次读一整行:"); 147 | reader = new BufferedReader(new FileReader(file)); 148 | String tempString = null; 149 | String temp = ""; 150 | int line = 1; 151 | // 一次读入一行,直到读入null为文件结束 152 | while ((tempString = reader.readLine()) != null) { 153 | // 显示行号 154 | System.out.println("line " + line + ": " + tempString); 155 | temp += tempString; 156 | line++; 157 | } 158 | reader.close(); 159 | return temp; 160 | } catch (IOException e) { 161 | e.printStackTrace(); 162 | } finally { 163 | if (reader != null) { 164 | try { 165 | reader.close(); 166 | } catch (IOException e1) { 167 | } 168 | } 169 | } 170 | return readFileByLines(fileName); 171 | } 172 | 173 | 174 | public static void main(String[] args) { 175 | new Server().startServer(); 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/ui/activity/wifi/WifiConfigActivity.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.ui.activity.wifi; 2 | 3 | import android.Manifest; 4 | import android.annotation.SuppressLint; 5 | import android.app.Dialog; 6 | import android.content.ComponentName; 7 | import android.content.Context; 8 | import android.content.Intent; 9 | import android.net.wifi.ScanResult; 10 | import android.net.wifi.WifiInfo; 11 | import android.net.wifi.WifiManager; 12 | import android.os.Bundle; 13 | import android.os.Handler; 14 | import android.os.Message; 15 | import android.support.v4.app.ActivityCompat; 16 | import android.support.v7.app.AppCompatActivity; 17 | import android.util.Log; 18 | import android.view.LayoutInflater; 19 | import android.view.View; 20 | import android.widget.Button; 21 | import android.widget.EditText; 22 | import android.widget.ListView; 23 | import android.widget.TextView; 24 | import android.widget.Toast; 25 | 26 | import com.exce.bluetooth.R; 27 | import com.exce.bluetooth.ui.activity.wifi.tcp.TcpClient; 28 | import com.exce.bluetooth.ui.adapter.WifiListAdapter; 29 | import com.exce.bluetooth.utils.SPUntil; 30 | import com.exce.wifiutils.WifiUtils; 31 | 32 | import java.lang.ref.WeakReference; 33 | import java.util.ArrayList; 34 | import java.util.List; 35 | import java.util.concurrent.ExecutorService; 36 | import java.util.concurrent.Executors; 37 | 38 | /** 39 | * @Author Wangjj 40 | * @Create 2018/5/8 17:37. 41 | * @Title 42 | */ 43 | public class WifiConfigActivity extends AppCompatActivity { 44 | 45 | private static final String TAG = "MainActivity"; 46 | public static Context context; 47 | private final MyHandler myHandler = new MyHandler(this); 48 | 49 | 50 | private Dialog dialog; 51 | private Button btRefresh, btSaveMySelf, btSureSend, btOpenWifi, btConnWifi; 52 | private TextView deviceTv, wifiInfo; 53 | private EditText edInput; 54 | private WifiListAdapter mWifiListAdapter; 55 | private String password; 56 | List mResultList; 57 | 58 | private String serverIP = "10.1.1.251"; 59 | private int serverPort = 12306; 60 | private static TcpClient tcpClient = null; 61 | ExecutorService exec = Executors.newCachedThreadPool(); 62 | 63 | @Override 64 | protected void onCreate(Bundle savedInstanceState) { 65 | super.onCreate(savedInstanceState); 66 | setContentView(R.layout.wifi_main); 67 | tcpClient = new TcpClient(serverIP, serverPort); 68 | exec.execute(tcpClient); 69 | ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 555); 70 | //检查wifi是否开启 71 | WifiUtils.enableLog(true); 72 | context = this; 73 | init(); 74 | 75 | } 76 | 77 | //初始化控件 78 | private void init() { 79 | mWifiListAdapter = new WifiListAdapter(this); 80 | wifiInfo = findViewById(R.id.info); 81 | wifiInfo.setText(getInfoSave()); 82 | edInput = findViewById(R.id.ed_input_pwd); 83 | btSaveMySelf = findViewById(R.id.bt_save_myself); 84 | btSureSend = findViewById(R.id.bt_sure_send); 85 | btOpenWifi = findViewById(R.id.bt_open_wifi); 86 | btConnWifi = findViewById(R.id.bt_conn_wifi); 87 | deviceTv = findViewById(R.id.tv_device_wifi); 88 | 89 | btSaveMySelf.setOnClickListener(v -> getInfoSave()); 90 | btSureSend.setOnClickListener(v -> sureSend()); 91 | btOpenWifi.setOnClickListener(v -> systemWifi()); 92 | btConnWifi.setOnClickListener(v -> connWifi()); 93 | deviceTv.setOnClickListener(v -> showDeviceListDialog()); 94 | } 95 | 96 | private void connWifi() { 97 | password = edInput.getText().toString(); 98 | WifiUtils.withContext(getApplicationContext()) 99 | .connectWith(ssid, password) 100 | .setTimeout(40000) 101 | .onConnectionResult(this::checkResult) 102 | .start(); 103 | } 104 | 105 | //获取系统WiFi 106 | private void systemWifi() { 107 | Intent it = new Intent(); 108 | ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.wifi.WifiSettings"); 109 | it.setComponent(cn); 110 | startActivity(it); 111 | } 112 | 113 | //获取当前WiFi信息 并 保存我自己wifi信息 114 | private String getInfoSave() { 115 | WifiManager wifi = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); 116 | WifiInfo info = wifi.getConnectionInfo(); 117 | String maxText = info.getMacAddress(); 118 | String ipText = intToIp(info.getIpAddress()); 119 | String status = ""; 120 | if (wifi.getWifiState() == WifiManager.WIFI_STATE_ENABLED) { 121 | status = "WIFI_STATE_ENABLED"; 122 | } 123 | String ssid = info.getSSID(); 124 | int networkID = info.getNetworkId(); 125 | int speed = info.getLinkSpeed(); 126 | SPUntil.putMyselfWifi(getApplicationContext(), ipText); 127 | Toast.makeText(getApplicationContext(), "保存成功--->" + ipText, Toast.LENGTH_SHORT).show(); 128 | return "mac:" + maxText + "\n\r" 129 | + "ip:" + ipText + "\n\r" 130 | + "wifi status :" + status + "\n\r" 131 | + "ssid :" + ssid + "\n\r" 132 | + "net work id :" + networkID + "\n\r" 133 | + "connection speed:" + speed + "\n\r"; 134 | } 135 | 136 | 137 | // 连接wifi 确定发送信息 138 | private void sureSend() { 139 | Message message = Message.obtain(); 140 | message.what = 2; 141 | message.obj = SPUntil.getMyselfWifi(context); 142 | myHandler.sendMessage(message); 143 | exec.execute(() -> tcpClient.send(SPUntil.getMyselfWifi(context))); 144 | } 145 | 146 | @SuppressLint("HandlerLeak") 147 | private class MyHandler extends Handler { 148 | private WeakReference mActivity; 149 | MyHandler(WifiConfigActivity activity) { 150 | mActivity = new WeakReference<>(activity); 151 | } 152 | 153 | @Override 154 | public void handleMessage(Message msg) { 155 | if (mActivity != null) { 156 | switch (msg.what) { 157 | case 1: 158 | // txtRcv.append(msg.obj.toString()); 159 | break; 160 | case 2: 161 | 162 | // txtSend.append(msg.obj.toString()); 163 | break; 164 | } 165 | } 166 | } 167 | } 168 | 169 | //ip地址写法 170 | private String intToIp(int ip) { 171 | return (ip & 0xFF) + "." + ((ip >> 8) & 0xFF) + "." + ((ip >> 16) & 0xFF) + "." 172 | + ((ip >> 24) & 0xFF); 173 | } 174 | 175 | //wifi 连接返回成功或失败 176 | private void checkResult(boolean isSuccess) { 177 | if (isSuccess) 178 | Toast.makeText(this, "SUCCESS!", Toast.LENGTH_SHORT).show(); 179 | else 180 | Toast.makeText(this, "EPIC FAIL!", Toast.LENGTH_SHORT).show(); 181 | } 182 | 183 | //扫描周围wifi 184 | private void scanWifi() { 185 | WifiUtils.withContext(getApplicationContext()).scanWifi(scanResults -> { 186 | if (scanResults.isEmpty()) { 187 | Log.i(TAG, "SCAN RESULTS IT'S EMPTY"); 188 | return; 189 | } 190 | Log.i(TAG, "GOT SCAN RESULTS " + scanResults); 191 | mWifiListAdapter.addData(scanResults); 192 | System.out.println("scanresults.........................................." + scanResults); 193 | }).start(); 194 | } 195 | 196 | String ssid; 197 | 198 | //列表显示&&刷新 199 | private void showDeviceListDialog() { 200 | LayoutInflater factory = LayoutInflater.from(this); 201 | View view = factory.inflate(R.layout.wifi_dialog_scan_device, null); 202 | dialog = new Dialog(this, R.style.MyDialog); 203 | dialog.setContentView(view); 204 | dialog.setCancelable(false); 205 | dialog.show(); 206 | Button btnCancle = view.findViewById(R.id.btn_scan_cancle); 207 | btRefresh = view.findViewById(R.id.btn_refresh_wifi); 208 | ListView lvDevice = view.findViewById(R.id.lv_wifi_device); 209 | lvDevice.setAdapter(mWifiListAdapter); 210 | scanWifi(); 211 | btRefresh.setOnClickListener(v -> { 212 | mWifiListAdapter.clear(); 213 | scanWifi(); 214 | Toast.makeText(getApplicationContext(), "刷新wifi列表。。。", Toast.LENGTH_SHORT).show(); 215 | }); 216 | 217 | lvDevice.setOnItemClickListener((parent, view1, position, id) -> { 218 | mResultList = new ArrayList<>(); 219 | mWifiListAdapter = (WifiListAdapter) parent.getAdapter(); 220 | for (int i = 0; i < mWifiListAdapter.getCount(); i++) { 221 | ScanResult item = (ScanResult) mWifiListAdapter.getItem(position); 222 | ssid = item.SSID; 223 | deviceTv.setText(ssid); 224 | } 225 | Toast.makeText(getApplicationContext(), "选择... ", Toast.LENGTH_SHORT).show(); 226 | dialog.dismiss(); 227 | }); 228 | btnCancle.setOnClickListener(v -> dialog.dismiss()); 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/ui/activity/wifi/WifiServerActivity.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.ui.activity.wifi; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | 7 | import com.exce.bluetooth.R; 8 | 9 | /** 10 | * @Author Wangjj 11 | * @Create 2018/5/9 13:08. 12 | * @Title 13 | */ 14 | public class WifiServerActivity extends AppCompatActivity{ 15 | 16 | 17 | 18 | @Override 19 | protected void onCreate(@Nullable Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.fragment_home); 22 | } 23 | 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/ui/activity/wifi/tcp/TcpClient.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.ui.activity.wifi.tcp; 2 | 3 | import android.content.Intent; 4 | import android.util.Log; 5 | 6 | import com.exce.bluetooth.ui.activity.wifi.WifiConfigActivity; 7 | import com.exce.bluetooth.ui.fragment.TabOneFragment; 8 | import com.exce.bluetooth.utils.Utils; 9 | import com.google.common.primitives.Shorts; 10 | 11 | import java.io.DataInputStream; 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.io.PrintWriter; 15 | import java.net.Socket; 16 | import java.util.concurrent.BlockingQueue; 17 | import java.util.concurrent.LinkedBlockingQueue; 18 | 19 | /** 20 | * @Author Wangjj 21 | * @Create 2018/5/8 10:18. 22 | * @Title 23 | */ 24 | 25 | public class TcpClient implements Runnable { 26 | private String TAG = "TcpClient"; 27 | 28 | private BlockingQueue data0Q = new LinkedBlockingQueue<>(); 29 | private BlockingQueue dataB = new LinkedBlockingQueue<>(); 30 | private boolean dataHandThread_isRunning = false; //数据处理线程 31 | 32 | private String serverIP = "10.1.1.251"; 33 | private int serverPort = 12306; 34 | private PrintWriter pw; 35 | private InputStream is; 36 | private DataInputStream dis; 37 | private boolean isRun = true; 38 | private Socket socket = null; 39 | byte buff[] = new byte[4096]; 40 | private String rcvMsg; 41 | private int rcvLen; 42 | 43 | 44 | 45 | public TcpClient(String ip , int port ){ 46 | this.serverIP = ip; 47 | this.serverPort = port; 48 | 49 | } 50 | 51 | public void closeSelf(){ 52 | isRun = false; 53 | } 54 | 55 | public void send(String msg){ 56 | pw.println(msg); 57 | pw.flush(); 58 | } 59 | 60 | @Override 61 | public void run() { 62 | try { 63 | socket = new Socket(serverIP,serverPort); 64 | socket.setSoTimeout(5000); 65 | pw = new PrintWriter(socket.getOutputStream(),true); 66 | is = socket.getInputStream(); 67 | dis = new DataInputStream(is); 68 | genProtocol(); 69 | } catch (IOException e) { 70 | e.printStackTrace(); 71 | } 72 | while (isRun){ 73 | try { 74 | rcvLen = dis.read(buff); 75 | rcvMsg = new String(buff,0,rcvLen,"utf-8"); 76 | Log.i(TAG, "run: 收到消息:"+ rcvMsg); 77 | Intent intent =new Intent(); 78 | intent.setAction("tcpClientReceiver"); 79 | intent.putExtra("tcpClientReceiver",rcvMsg); 80 | WifiConfigActivity.context.sendBroadcast(intent);//将消息发送给主界面 81 | if (rcvMsg.equals("QuitClient")){ //服务器要求客户端结束 82 | isRun = false; 83 | } 84 | } catch (IOException e) { 85 | e.printStackTrace(); 86 | } 87 | 88 | } 89 | try { 90 | pw.close(); 91 | is.close(); 92 | dis.close(); 93 | socket.close(); 94 | } catch (IOException e) { 95 | e.printStackTrace(); 96 | } 97 | } 98 | 99 | 100 | /** 101 | * 客户端解析报文 102 | * STX (2B) SERIAL(2B) LEN (2B) DATA(nB) LRC (1B) ETX (2B) 103 | */ 104 | private void genProtocol() { 105 | if (!dataHandThread_isRunning) { 106 | dataHandThread_isRunning = true; 107 | new Thread(() -> { 108 | // 数据 109 | byte[] buffer = new byte[4096]; 110 | int len; 111 | 112 | while (dataHandThread_isRunning) { 113 | // 取协议头 114 | byte b; 115 | b = Utils.dequeue(dataB); 116 | if (b != Utils.unsigned_byte(0xD3)) continue; 117 | b = Utils.dequeue(dataB); 118 | if (b != Utils.unsigned_byte(0x96)) continue; 119 | //stral 120 | for (int i = 0; i < 2; i++) { 121 | buffer[i] = Utils.dequeue(dataB); 122 | } 123 | // 取len 124 | for (int i = 0; i < 2; i++) { 125 | buffer[i] = Utils.dequeue(dataB); 126 | } 127 | len = Shorts.fromBytes(buffer[2], buffer[3]); 128 | 129 | // 取剩下的 130 | for (int i = 0; i < len; i++) { 131 | buffer[i] = Utils.dequeue(dataB); 132 | } 133 | 134 | // 判断协议完整性(判断尾或crc) 135 | if (buffer[len - 2] != Utils.unsigned_byte(0Xd6)) continue; 136 | if (buffer[len - 1] != Utils.unsigned_byte(0x93)) continue; 137 | 138 | //LRC:从STX字段开始到ETX字段逐个进行异或的值 139 | byte temp = 0; 140 | for (byte lrc : buffer) { 141 | temp ^= lrc; 142 | } 143 | // 数据 144 | Float[] f = new Float[12]; 145 | for (int i = 0; i < len / 2; i++) { 146 | f[i] = (float) Shorts.fromBytes(buffer[2 * i + 4], buffer[2 * i + 5]); 147 | } 148 | data0Q.add(f); 149 | } 150 | }).start(); 151 | } 152 | } 153 | 154 | } 155 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/ui/activity/wifi/tcp/TcpServer.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.ui.activity.wifi.tcp; 2 | 3 | import android.content.Intent; 4 | import android.util.Log; 5 | 6 | import com.exce.bluetooth.ui.fragment.TabOneFragment; 7 | import com.google.common.primitives.Bytes; 8 | import com.google.common.primitives.Shorts; 9 | 10 | import java.io.DataOutputStream; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.io.OutputStream; 14 | import java.io.PrintWriter; 15 | import java.net.ServerSocket; 16 | import java.net.Socket; 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | 20 | /** 21 | * @Author Wangjj 22 | * @Create 2018/5/8 10:18. 23 | * @Title 24 | */ 25 | 26 | public class TcpServer implements Runnable { 27 | private String TAG = "TcpServer"; 28 | private int port = 12306; 29 | private boolean isListen = true; //线程监听标志位 30 | public ArrayList SST = new ArrayList(); 31 | public TcpServer(int port) { 32 | this.port = port; 33 | } 34 | 35 | //更改监听标志位 36 | public void setIsListen(boolean b) { 37 | isListen = b; 38 | } 39 | 40 | public void closeSelf() { 41 | isListen = false; 42 | for (ServerSocketThread s : SST) { 43 | s.isRun = false; 44 | } 45 | SST.clear(); 46 | } 47 | 48 | private Socket getSocket(ServerSocket serverSocket) { 49 | try { 50 | return serverSocket.accept(); 51 | } catch (IOException e) { 52 | e.printStackTrace(); 53 | Log.i(TAG, "run: 监听超时"); 54 | return null; 55 | } 56 | } 57 | 58 | @Override 59 | public void run() { 60 | try { 61 | ServerSocket serverSocket = new ServerSocket(port); 62 | serverSocket.setSoTimeout(5000); 63 | while (isListen) { 64 | Log.i(TAG, "run: 开始监听..."); 65 | Socket socket = getSocket(serverSocket); 66 | if (socket != null) { 67 | new ServerSocketThread(socket); 68 | } 69 | } 70 | serverSocket.close(); 71 | } catch (IOException e) { 72 | e.printStackTrace(); 73 | } 74 | } 75 | 76 | public class ServerSocketThread extends Thread { 77 | Socket socket = null; 78 | private PrintWriter pw; 79 | private InputStream is = null; 80 | private OutputStream os = null; 81 | private String ip = null; 82 | private boolean isRun = true; 83 | 84 | ServerSocketThread(Socket socket) { 85 | this.socket = socket; 86 | ip = socket.getInetAddress().toString(); 87 | Log.i(TAG, "ServerSocketThread:检测到新的客户端联入,ip:" + ip); 88 | try { 89 | socket.setSoTimeout(5000); 90 | os = socket.getOutputStream(); 91 | is = socket.getInputStream(); 92 | //发送 93 | sendProtocol(os); 94 | pw = new PrintWriter(os, true); 95 | start(); 96 | } catch (IOException e) { 97 | e.printStackTrace(); 98 | } 99 | } 100 | 101 | public void send(String msg){ 102 | pw.println(msg); 103 | pw.flush(); //强制送出数据 104 | } 105 | 106 | @Override 107 | public void run() { 108 | byte buff[] = new byte[4096]; 109 | String rcvMsg; 110 | int rcvLen; 111 | SST.add(this); 112 | while (isRun && !socket.isClosed() && !socket.isInputShutdown()) { 113 | try { 114 | if ((rcvLen = is.read(buff)) != -1) { 115 | rcvMsg = new String(buff, 0, rcvLen, "utf-8"); 116 | Log.i(TAG, "run:收到消息: " + rcvMsg); 117 | Intent intent = new Intent(); 118 | intent.setAction("tcpServerReceiver"); 119 | intent.putExtra("tcpServerReceiver", rcvMsg); 120 | TabOneFragment.context.sendBroadcast(intent);//将消息发送给主界面 121 | if (rcvMsg.equals("QuitServer")) { 122 | isRun = false; 123 | } 124 | } 125 | } catch (IOException e) { 126 | e.printStackTrace(); 127 | } 128 | } 129 | try { 130 | socket.close(); 131 | SST.clear(); 132 | Log.i(TAG, "run: 断开连接"); 133 | } catch (IOException e) { 134 | e.printStackTrace(); 135 | } 136 | } 137 | } 138 | 139 | /** 140 | * 服务端发送报文 141 | * STX (2B) SERIAL(2B) LEN (2B) DATA(nB) LRC (1B) ETX (2B) 142 | * 143 | * @param out DataOutputStream 144 | 145 | * @throws IOException 异常 146 | */ 147 | private void sendProtocol(OutputStream out ) throws IOException { 148 | // 数据 149 | byte buff[] = new byte[4096]; 150 | List sendList = new ArrayList(); 151 | 152 | //帧类型 153 | byte type = 0x30; 154 | sendList.add(type); 155 | 156 | //数据长度 157 | short datalen = (short) ((buff.length) * 12); 158 | byte[] lenArr = Shorts.toByteArray(datalen); 159 | 160 | for (byte dataLen : lenArr) { 161 | sendList.add(dataLen); 162 | } 163 | //数据 2 * 8 164 | for (int i = 0; i < 12; i++) { 165 | for (byte d : buff) { 166 | sendList.add(d); 167 | } 168 | } 169 | //结束字 2 170 | byte foot = 0x55; 171 | sendList.add(foot); 172 | sendList.add(foot); 173 | 174 | //总长度 2 175 | short allLen = (short) (sendList.size()); 176 | byte[] allArr = Shorts.toByteArray(allLen); 177 | for (int i = allArr.length - 1; i >= 0; i--) { 178 | sendList.add(0, allArr[i]); 179 | } 180 | 181 | // 协议头 2 182 | byte head = 0xaa - 256; 183 | sendList.add(0, head); 184 | sendList.add(0, head); 185 | 186 | byte[] send = Bytes.toArray(sendList); 187 | //写入消息内容 188 | out.write(send); 189 | 190 | } 191 | 192 | } 193 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/ui/adapter/BleListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.ui.adapter; 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 com.exce.bluetooth.R; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | /** 17 | * @Author Wangjj 18 | * @Create 2018/3/8. 19 | * @Content 蓝牙设备适配器处理 20 | */ 21 | public class BleListAdapter extends BaseAdapter { 22 | //设备列表 23 | public List mBleDevices; 24 | private List mRssis; 25 | private Context mContext; 26 | 27 | public BleListAdapter(Context mContext) { 28 | this.mContext = mContext; 29 | mBleDevices = new ArrayList(); 30 | mRssis = new ArrayList(); 31 | } 32 | 33 | public void addDevice(BluetoothDevice device, Double rssi) { 34 | if (!mBleDevices.contains(device)) { 35 | mBleDevices.add(device); 36 | mRssis.add(rssi); 37 | } 38 | notifyDataSetChanged(); 39 | } 40 | 41 | 42 | public BluetoothDevice getDevice(int position) { 43 | if (mBleDevices != null) { 44 | return mBleDevices.get(position); 45 | } 46 | return null; 47 | } 48 | 49 | public String getAddress(int position) { 50 | if (mBleDevices != null) { 51 | return mBleDevices.get(position).getAddress(); 52 | } 53 | return null; 54 | } 55 | 56 | public void clear() { 57 | mBleDevices.clear(); 58 | } 59 | 60 | @Override 61 | public int getCount() { 62 | if (mBleDevices != null) { 63 | return mBleDevices.size(); 64 | } 65 | return 0; 66 | } 67 | 68 | @Override 69 | public Object getItem(int position) { 70 | return mBleDevices.get(position); 71 | } 72 | 73 | @Override 74 | public long getItemId(int position) { 75 | return position; 76 | } 77 | 78 | @Override 79 | public View getView(int position, View convertView, ViewGroup parent) { 80 | ViewHolder viewHolder; 81 | if (convertView == null) { 82 | convertView = LayoutInflater.from(parent.getContext()).inflate( 83 | R.layout.item_list_scan, null); 84 | viewHolder = new ViewHolder(); 85 | viewHolder.tv_device = (TextView) convertView.findViewById(R.id.tv_device); 86 | 87 | convertView.setTag(viewHolder); 88 | } else { 89 | viewHolder = (ViewHolder) convertView.getTag(); 90 | } 91 | Double mrssi = mRssis.get(position); 92 | String msg = "名称:" + mBleDevices.get(position).getName() + " 地址: " + 93 | mBleDevices.get(position).getAddress() + " " + "Rssi:" + String.format("%.2f", mrssi); 94 | 95 | viewHolder.tv_device.setText(msg); 96 | 97 | return convertView; 98 | } 99 | 100 | class ViewHolder { 101 | TextView tv_device; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/ui/adapter/ViewPagerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.ui.adapter; 2 | 3 | import android.support.v4.app.Fragment; 4 | import android.support.v4.app.FragmentManager; 5 | import android.support.v4.app.FragmentStatePagerAdapter; 6 | 7 | import com.exce.bluetooth.bean.FragmentInfo; 8 | import com.exce.bluetooth.ui.fragment.TabOneFragment; 9 | import com.exce.bluetooth.ui.fragment.TabThreeFragment; 10 | import com.exce.bluetooth.ui.fragment.TabTwoFragment; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | /** 16 | * @Author Wangjj 17 | * @Create 2017/12/21. 18 | * @Content 19 | */ 20 | 21 | public class ViewPagerAdapter extends FragmentStatePagerAdapter { 22 | 23 | private List mFragments = new ArrayList<>(4); 24 | 25 | public ViewPagerAdapter(FragmentManager fm) { 26 | super(fm); 27 | initFragments(); 28 | } 29 | 30 | private void initFragments() { 31 | 32 | mFragments.add(new FragmentInfo("主页", TabOneFragment.class)); 33 | mFragments.add(new FragmentInfo("本地", TabTwoFragment.class)); 34 | mFragments.add(new FragmentInfo("我的", TabThreeFragment.class)); 35 | 36 | } 37 | 38 | @Override 39 | public Fragment getItem(int position) { 40 | 41 | try { 42 | return (Fragment) mFragments.get(position).getFragment().newInstance(); 43 | 44 | } catch (InstantiationException | IllegalAccessException e) { 45 | e.printStackTrace(); 46 | } 47 | 48 | return null; 49 | 50 | } 51 | 52 | @Override 53 | public int getCount() { 54 | return mFragments.size(); 55 | } 56 | 57 | @Override 58 | public CharSequence getPageTitle(int position) { 59 | return mFragments.get(position).getTitle(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/ui/adapter/WifiListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.ui.adapter; 2 | 3 | import android.content.Context; 4 | import android.net.wifi.ScanResult; 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 com.exce.bluetooth.R; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | 17 | public class WifiListAdapter extends BaseAdapter { 18 | //设备列表 19 | public List mScanResults; 20 | 21 | private Context mContext; 22 | 23 | public WifiListAdapter(Context mContext) { 24 | this.mContext = mContext; 25 | mScanResults = new ArrayList(); 26 | } 27 | 28 | public void addData(List datas) { 29 | 30 | if (mScanResults.size() > 0) { 31 | mScanResults.clear(); 32 | } 33 | mScanResults.addAll(datas); 34 | notifyDataSetChanged(); 35 | 36 | } 37 | 38 | public void clear() { 39 | mScanResults.clear(); 40 | } 41 | 42 | @Override 43 | public int getCount() { 44 | if (mScanResults != null) { 45 | return mScanResults.size(); 46 | } 47 | return 0; 48 | } 49 | 50 | @Override 51 | public Object getItem(int position) { 52 | return mScanResults.get(position); 53 | } 54 | 55 | @Override 56 | public long getItemId(int position) { 57 | return position; 58 | } 59 | 60 | @Override 61 | public View getView(int position, View convertView, ViewGroup parent) { 62 | ViewHolder viewHolder; 63 | if (convertView == null) { 64 | convertView = LayoutInflater.from(parent.getContext()).inflate( 65 | R.layout.wifi_item_list, null); 66 | viewHolder = new ViewHolder(); 67 | viewHolder.tv_device = convertView.findViewById(R.id.tv_wifi_device); 68 | 69 | convertView.setTag(viewHolder); 70 | } else { 71 | viewHolder = (ViewHolder) convertView.getTag(); 72 | } 73 | 74 | String msg = "SSID:" + mScanResults.get(position).SSID; 75 | 76 | viewHolder.tv_device.setText(msg); 77 | 78 | return convertView; 79 | } 80 | 81 | class ViewHolder { 82 | TextView tv_device; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/ui/fragment/TabOneFragment.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.ui.fragment; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.IntentFilter; 7 | import android.os.Bundle; 8 | import android.os.Message; 9 | import android.support.annotation.NonNull; 10 | import android.support.annotation.Nullable; 11 | import android.support.v4.app.Fragment; 12 | import android.support.v7.widget.Toolbar; 13 | import android.util.Log; 14 | import android.view.LayoutInflater; 15 | import android.view.View; 16 | import android.view.ViewGroup; 17 | import android.widget.Button; 18 | import android.widget.EditText; 19 | import android.widget.TextView; 20 | import android.widget.Toast; 21 | 22 | import com.exce.bluetooth.R; 23 | import com.exce.bluetooth.ui.activity.ble.BLEActivity; 24 | import com.exce.bluetooth.ui.activity.usb.USBActivity; 25 | import com.exce.bluetooth.ui.activity.wifi.WifiConfigActivity; 26 | import com.exce.bluetooth.ui.activity.wifi.tcp.TcpServer; 27 | import com.exce.bluetooth.utils.Utils; 28 | import com.exce.bluetooth.view.EcgView; 29 | 30 | import java.lang.ref.WeakReference; 31 | import java.net.Inet6Address; 32 | import java.net.InetAddress; 33 | import java.net.NetworkInterface; 34 | import java.net.SocketException; 35 | import java.util.ArrayList; 36 | import java.util.Enumeration; 37 | import java.util.List; 38 | import java.util.Timer; 39 | import java.util.TimerTask; 40 | import java.util.concurrent.BlockingQueue; 41 | import java.util.concurrent.ExecutorService; 42 | import java.util.concurrent.Executors; 43 | import java.util.concurrent.LinkedBlockingQueue; 44 | 45 | /** 46 | * @Author Wangjj 47 | * @Create 2017/12/21. 48 | * @Content 49 | */ 50 | public class TabOneFragment extends Fragment { 51 | public static Context context; 52 | //---------------------心电--------------------- 53 | private BlockingQueue data0Q = new LinkedBlockingQueue<>(); 54 | private BlockingQueue dataB = new LinkedBlockingQueue<>(); 55 | private boolean dataHandThread_isRunning = false; //数据处理线程 56 | //------------------------------------------ 57 | private View mRootView; 58 | private Toolbar mToolBar; 59 | private EditText editServerPort; 60 | private TextView txtServerIp; 61 | private Button btnStartServer, btnCloseServer; 62 | private MyBtnClicker myBtnClicker = new MyBtnClicker(); 63 | private static TcpServer tcpServer = null; 64 | private MyHandler myHandler = new MyHandler( ); 65 | private MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver(); 66 | ExecutorService exec = Executors.newCachedThreadPool(); 67 | 68 | 69 | public TabOneFragment() { 70 | } 71 | 72 | @Nullable 73 | @Override 74 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 75 | mRootView = inflater.inflate(R.layout.fragment_home_wifi, container, false); 76 | init(mRootView); 77 | bindReceiver(); 78 | Utils.hideIputKeyboard(getContext()); 79 | return mRootView; 80 | } 81 | 82 | 83 | /** 84 | * 绑定ID 85 | */ 86 | private void init(View view) { 87 | btnStartServer = view.findViewById(R.id.btn_tcpServerConn); 88 | btnCloseServer = view.findViewById(R.id.btn_tcpServerClose); 89 | txtServerIp = view.findViewById(R.id.txt_Server_Ip); 90 | editServerPort = view.findViewById(R.id.edit_Server_Port); 91 | 92 | btnStartServer.setOnClickListener(myBtnClicker); 93 | btnCloseServer.setOnClickListener(myBtnClicker); 94 | 95 | btnCloseServer.setEnabled(false); 96 | txtServerIp.setText(getHostIP()); 97 | 98 | mToolBar = view.findViewById(R.id.tool_bar); 99 | mToolBar.inflateMenu(R.menu.toolbar_menu); 100 | mToolBar.setOnMenuItemClickListener(item -> { 101 | //在这里执行我们的逻辑代码 102 | switch (item.getItemId()) { 103 | case R.id.change_usb: 104 | Intent intent1 = new Intent(getContext(), USBActivity.class); 105 | startActivity(intent1); 106 | Toast.makeText(getContext(), "选择usb", Toast.LENGTH_SHORT).show(); 107 | break; 108 | case R.id.change_ble: 109 | Intent intent2 = new Intent(getContext(), BLEActivity.class); 110 | startActivity(intent2); 111 | Toast.makeText(getContext(), "选择ble", Toast.LENGTH_SHORT).show(); 112 | break; 113 | case R.id.change_wifi_config: 114 | Intent intent3 = new Intent(getContext(), WifiConfigActivity.class); 115 | startActivity(intent3); 116 | Toast.makeText(getContext(), "WiFi配置", Toast.LENGTH_SHORT).show(); 117 | break; 118 | default: 119 | break; 120 | } 121 | return false; 122 | }); 123 | } 124 | 125 | 126 | private static class MyHandler extends android.os.Handler { 127 | private final WeakReference mActivity; 128 | 129 | MyHandler(TabOneFragment activity) { 130 | mActivity = new WeakReference(activity); 131 | } 132 | 133 | @Override 134 | public void handleMessage(Message msg) { 135 | TabOneFragment activity = mActivity.get(); 136 | if (activity != null) { 137 | switch (msg.what) { 138 | case 1: 139 | // txtRcv.append(msg.obj.toString()); 140 | break; 141 | case 2: 142 | // txtSend.append(msg.obj.toString()); 143 | break; 144 | } 145 | } 146 | } 147 | } 148 | 149 | private class MyBroadcastReceiver extends BroadcastReceiver { 150 | 151 | @Override 152 | public void onReceive(Context context, Intent intent) { 153 | String mAction = intent.getAction(); 154 | switch (mAction) { 155 | case "tcpServerReceiver": 156 | String msg = intent.getStringExtra("tcpServerReceiver"); 157 | Message message = Message.obtain(); 158 | message.what = 1; 159 | message.obj = msg; 160 | myHandler.sendMessage(message); 161 | break; 162 | } 163 | } 164 | } 165 | 166 | private void bindReceiver() { 167 | IntentFilter intentFilter = new IntentFilter("tcpServerReceiver"); 168 | // registerReceiver(myBroadcastReceiver, intentFilter); 169 | } 170 | 171 | /** 172 | * 监听点击事件 173 | */ 174 | private class MyBtnClicker implements View.OnClickListener { 175 | private static final String TAG = "MyBtnClicker"; 176 | 177 | @Override 178 | public void onClick(View view) { 179 | switch (view.getId()) { 180 | case R.id.btn_tcpServerConn: 181 | Log.i("A", "onClick: 开启服务端"); 182 | btnStartServer.setEnabled(false); 183 | btnCloseServer.setEnabled(true); 184 | tcpServer = new TcpServer(getHost(editServerPort.getText().toString())); 185 | exec.execute(tcpServer); 186 | break; 187 | case R.id.btn_tcpServerClose: 188 | tcpServer.closeSelf(); 189 | btnStartServer.setEnabled(true); 190 | btnCloseServer.setEnabled(false); 191 | break; 192 | default: 193 | break; 194 | } 195 | } 196 | } 197 | 198 | private int getHost(String msg) { 199 | if (msg.equals("")) { 200 | msg = "12306"; 201 | } 202 | return Integer.parseInt(msg); 203 | } 204 | 205 | /** 206 | * 获取ip地址 207 | * 208 | * @return 209 | */ 210 | public String getHostIP() { 211 | 212 | String hostIp = null; 213 | try { 214 | Enumeration nis = NetworkInterface.getNetworkInterfaces(); 215 | InetAddress ia = null; 216 | while (nis.hasMoreElements()) { 217 | NetworkInterface ni = (NetworkInterface) nis.nextElement(); 218 | Enumeration ias = ni.getInetAddresses(); 219 | while (ias.hasMoreElements()) { 220 | ia = ias.nextElement(); 221 | if (ia instanceof Inet6Address) { 222 | continue;// skip ipv6 223 | } 224 | String ip = ia.getHostAddress(); 225 | if (!"127.0.0.1".equals(ip)) { 226 | hostIp = ia.getHostAddress(); 227 | break; 228 | } 229 | } 230 | } 231 | 232 | } catch (SocketException e) { 233 | Log.i("FuncTcpServer", "SocketException"); 234 | e.printStackTrace(); 235 | } 236 | return hostIp; 237 | 238 | } 239 | 240 | /** 241 | * 显示心电图 242 | */ 243 | private void simulator() { 244 | new Timer().schedule(new TimerTask() { 245 | @Override 246 | public void run() { 247 | if (EcgView.isRunning) { 248 | if (data0Q.size() > 0) { 249 | EcgView.addEcgData0(data0Q.poll()); 250 | } 251 | } 252 | 253 | } 254 | }, 0, 2); 255 | } 256 | 257 | } 258 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/ui/fragment/TabThreeFragment.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.ui.fragment; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.annotation.NonNull; 6 | import android.support.annotation.Nullable; 7 | import android.support.v4.app.Fragment; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.ImageView; 12 | import android.widget.TextView; 13 | 14 | import com.exce.bluetooth.R; 15 | import com.exce.bluetooth.ui.PersonalActivity; 16 | 17 | /** 18 | * @Author Wangjj 19 | * @Create 2017/12/21. 20 | * @Content 21 | */ 22 | public class TabThreeFragment extends Fragment implements View.OnClickListener{ 23 | private View mRootView; 24 | private TextView accountTv; 25 | private ImageView nextImg; 26 | String login_name; 27 | 28 | @Nullable 29 | @Override 30 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 31 | mRootView = inflater.inflate(R.layout.fragment_mine, container, false); 32 | accountTv = mRootView.findViewById(R.id.account_msg); 33 | nextImg = mRootView.findViewById(R.id.account_next); 34 | 35 | login_name = accountTv.getText().toString(); 36 | // accountTv.setText(SharedPreferenceUtil.getLoginName(getContext())); 37 | nextImg.setOnClickListener(this); 38 | return mRootView; 39 | } 40 | 41 | @Override 42 | public void onClick(View v) { 43 | switch (v.getId()){ 44 | case R.id.account_next: 45 | Intent intent = new Intent(getContext(),PersonalActivity.class); 46 | startActivity(intent); 47 | break; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/ui/fragment/TabTwoFragment.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.ui.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.app.Fragment; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | 11 | 12 | import com.exce.bluetooth.R; 13 | 14 | /** 15 | * @Author Wangjj 16 | * @Create 2017/12/21. 17 | * @Content 18 | */ 19 | public class TabTwoFragment extends Fragment { 20 | private View mRootView; 21 | 22 | @Nullable 23 | @Override 24 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 25 | mRootView = inflater.inflate(R.layout.fragment_location, container, false); 26 | 27 | return mRootView; 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/utils/MyObjIterator.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.utils; 2 | 3 | import com.exce.bluetooth.bean.MyField; 4 | 5 | import java.lang.reflect.Field; 6 | import java.lang.reflect.InvocationTargetException; 7 | import java.lang.reflect.Method; 8 | 9 | /** 10 | * 自定义对象迭代器 11 | * @Author Wangjj 12 | * @Create 2018/4/19. 13 | * @Content 14 | */ 15 | public class MyObjIterator { 16 | private Field[] fields; 17 | private Object obj; 18 | private int subscript = 0; // 当前下标 19 | private int maxSubscript; // 下标的最大值 20 | 21 | public MyObjIterator(Object obj) { 22 | this.obj = obj; 23 | fields = obj.getClass().getDeclaredFields(); 24 | maxSubscript = fields.length - 1; 25 | } 26 | 27 | // 查看下一个还有木有 28 | public boolean hasNext() { 29 | return subscript <= maxSubscript; 30 | } 31 | 32 | // 获取下一个属性 33 | public MyField next() { 34 | String name = fields[subscript].getName(); 35 | String getMethod = "get" + name.substring(0, 1).toUpperCase() + name.substring(1); 36 | Object value; 37 | try { 38 | Method m = obj.getClass().getMethod(getMethod); 39 | value = m.invoke(obj); 40 | } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { 41 | e.printStackTrace(); 42 | throw new RuntimeException(e); 43 | } 44 | 45 | MyField myField = new MyField(name, fields[subscript].getType(), value); 46 | subscript++; 47 | return myField; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/utils/SPUntil.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.utils; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | import static android.content.Context.MODE_PRIVATE; 7 | 8 | /** 9 | * @Author Wangjj 10 | * @Create 2017/12/27. 11 | * @Content SharedPreferences 的封装 12 | */ 13 | 14 | public class SPUntil { 15 | 16 | private static String PROJECT_NAME = "wifi"; 17 | private static final String MYSELF_WIFI = "my_self"; 18 | 19 | private static SharedPreferences mSharedPreferences; 20 | 21 | /** 22 | * 保存 23 | * 24 | * @param context 25 | * @param contents 26 | */ 27 | public static void putMyselfWifi(Context context, String contents) { 28 | mSharedPreferences = context.getSharedPreferences(PROJECT_NAME, MODE_PRIVATE); 29 | SharedPreferences.Editor edit = mSharedPreferences.edit(); 30 | edit.putString(MYSELF_WIFI, contents); 31 | edit.apply(); 32 | } 33 | 34 | /** 35 | * 取出 36 | * 37 | * @param context 38 | * @return 39 | */ 40 | public static String getMyselfWifi(Context context) { 41 | mSharedPreferences = context.getSharedPreferences(PROJECT_NAME, MODE_PRIVATE); 42 | return mSharedPreferences.getString(MYSELF_WIFI, ""); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/utils/SharedPreferenceUtil.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.utils; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.util.Base64; 6 | 7 | import com.exce.bluetooth.bean.UserInfo; 8 | 9 | import java.io.ByteArrayInputStream; 10 | import java.io.ByteArrayOutputStream; 11 | import java.io.IOException; 12 | import java.io.ObjectInputStream; 13 | import java.io.ObjectOutputStream; 14 | import java.io.Serializable; 15 | import java.lang.reflect.InvocationTargetException; 16 | import java.lang.reflect.Method; 17 | import java.util.Map; 18 | 19 | import static android.content.Context.MODE_PRIVATE; 20 | 21 | /** 22 | * @Author Wangjj 23 | * @Create 2018/4/17. 24 | * @Content 25 | */ 26 | public class SharedPreferenceUtil { 27 | /** 28 | * 保存在手机里面的文件名(自定义) 29 | */ 30 | public static final String FILE_NAME = "share_ecg_data"; 31 | 32 | //保存UserInfo 33 | public static void saveUser(Context context, String preferenceName, String key, UserInfo user) throws Exception { 34 | if (user instanceof Serializable) { 35 | SharedPreferences sharedPreferences = context.getSharedPreferences(preferenceName, context.MODE_PRIVATE); 36 | SharedPreferences.Editor editor = sharedPreferences.edit(); 37 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 38 | try { 39 | ObjectOutputStream oos = new ObjectOutputStream(baos); 40 | oos.writeObject(user);//把对象写到流里 41 | String temp = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT)); 42 | editor.putString(key, temp); 43 | editor.apply(); 44 | } catch (IOException e) { 45 | e.printStackTrace(); 46 | } 47 | } else { 48 | throw new Exception("User must implements Serializable"); 49 | } 50 | } 51 | 52 | 53 | public static UserInfo getUser(Context context, String preferenceName, String key) { 54 | SharedPreferences sharedPreferences = context.getSharedPreferences(preferenceName, context.MODE_PRIVATE); 55 | String temp = sharedPreferences.getString(key, ""); 56 | ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(temp.getBytes(), Base64.DEFAULT)); 57 | UserInfo user = null; 58 | try { 59 | ObjectInputStream ois = new ObjectInputStream(bais); 60 | user = (UserInfo) ois.readObject(); 61 | } catch (IOException e) { 62 | e.printStackTrace(); 63 | } catch (ClassNotFoundException e1) { 64 | 65 | } 66 | return user; 67 | } 68 | 69 | 70 | /** 71 | * 移除某个key值已经对应的值 72 | * 73 | * @param context 74 | * @param key 75 | */ 76 | public static void remove(Context context, String key) { 77 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME, 78 | Context.MODE_PRIVATE); 79 | SharedPreferences.Editor editor = sp.edit(); 80 | editor.remove(key); 81 | SharedPreferencesCompat.apply(editor); 82 | } 83 | 84 | /** 85 | * 清除所有数据 86 | * 87 | * @param context 88 | */ 89 | public static void clear(Context context) { 90 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME, 91 | Context.MODE_PRIVATE); 92 | SharedPreferences.Editor editor = sp.edit(); 93 | editor.clear(); 94 | SharedPreferencesCompat.apply(editor); 95 | } 96 | 97 | /** 98 | * 查询某个key是否已经存在 99 | * 100 | * @param context 101 | * @param key 102 | * @return 103 | */ 104 | public static boolean contains(Context context, String key) { 105 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME, 106 | Context.MODE_PRIVATE); 107 | return sp.contains(key); 108 | } 109 | 110 | /** 111 | * 返回所有的键值对 112 | * 113 | * @param context 114 | * @return 115 | */ 116 | public static Map getAll(Context context) { 117 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME, 118 | Context.MODE_PRIVATE); 119 | return sp.getAll(); 120 | } 121 | 122 | /** 123 | * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类 124 | * 125 | * @author zhy 126 | */ 127 | private static class SharedPreferencesCompat { 128 | private static final Method sApplyMethod = findApplyMethod(); 129 | 130 | /** 131 | * 反射查找apply的方法 132 | * 133 | * @return 134 | */ 135 | @SuppressWarnings({"unchecked", "rawtypes"}) 136 | private static Method findApplyMethod() { 137 | try { 138 | Class clz = SharedPreferences.Editor.class; 139 | return clz.getMethod("apply"); 140 | } catch (NoSuchMethodException e) { 141 | } 142 | return null; 143 | } 144 | 145 | /** 146 | * 如果找到则使用apply执行,否则使用commit 147 | * 148 | * @param editor 149 | */ 150 | public static void apply(SharedPreferences.Editor editor) { 151 | try { 152 | if (sApplyMethod != null) { 153 | sApplyMethod.invoke(editor); 154 | return; 155 | } 156 | } catch (IllegalArgumentException e) { 157 | } catch (IllegalAccessException e) { 158 | } catch (InvocationTargetException e) { 159 | } 160 | editor.commit(); 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.utils; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.view.View; 6 | import android.view.WindowManager; 7 | import android.view.inputmethod.InputMethodManager; 8 | 9 | import com.google.common.primitives.Floats; 10 | import com.google.common.primitives.Ints; 11 | 12 | import java.util.LinkedList; 13 | import java.util.List; 14 | import java.util.concurrent.BlockingQueue; 15 | 16 | /** 17 | * @Author Wangjj 18 | * @Create 2018/4/9. 19 | * @Content 20 | */ 21 | public class Utils { 22 | /** 23 | * 数组byte转int数据(大端) 24 | * 25 | * @param source byte[] 26 | * @return int 27 | */ 28 | public static int be2Int24(byte[] source, int offset) { 29 | int target = 0; 30 | for (int i = 0; i < 3; i++) { 31 | target += (source[i + offset] & 0xff) << (8 * (3 - 1 - i)); 32 | } 33 | System.out.println(Integer.toHexString(target)); 34 | if ((target & 0x00800000) == 0x00800000) { 35 | target = target | 0xff000000; 36 | } 37 | return target; 38 | } 39 | 40 | /** 41 | * 数组byte转int数据(小端) 42 | * 43 | * @param source byte[] 44 | * @return int 45 | */ 46 | public static int le2Int24(byte[] source, int offset) { 47 | int target = 0; 48 | for (int i = 0; i < 3; i++) { 49 | target += (source[i + offset] & 0xff) << (8 * i); 50 | } 51 | System.out.println(Integer.toHexString(target)); 52 | if ((target & 0x00800000) == 0x00800000) { 53 | target = target | 0xff000000; 54 | } 55 | return target; 56 | } 57 | 58 | 59 | /** 60 | * 取出队列中的一个数据 61 | * 62 | * @param queue BlockingQueue 63 | * @return byte 64 | */ 65 | public static byte dequeue(BlockingQueue queue) { 66 | Byte b; 67 | do { 68 | b = queue.poll(); 69 | if (b == null) { 70 | try { 71 | Thread.sleep(200); 72 | } catch (InterruptedException e) { 73 | e.printStackTrace(); 74 | } 75 | } 76 | } while (b == null); 77 | return b; 78 | } 79 | 80 | /** 81 | * 模拟unsigned 的 byte类型 82 | * 83 | * @param i int 84 | * @return byte 85 | */ 86 | public static byte unsigned_byte(int i) { 87 | if (i > 255 || i < 0) { 88 | throw new RuntimeException("i 必须在 0x00 - 0xff 之间"); 89 | } 90 | if (i > 127) { 91 | return (byte) (i - 256); 92 | } else { 93 | return (byte) i; 94 | } 95 | } 96 | 97 | /** 98 | * byte[] 拼接 99 | * 100 | * @return byte[] 101 | */ 102 | public static byte[] byteAppend(byte[]... bytes) { 103 | int len = 0; 104 | int subscript = 0; 105 | for (byte[] b : bytes) { 106 | if (b == null) continue; 107 | len += b.length; 108 | } 109 | byte[] all = new byte[len]; 110 | for (byte[] b : bytes) { 111 | if (b == null) continue; 112 | for (byte sb : b) { 113 | all[subscript] = sb; 114 | subscript++; 115 | } 116 | } 117 | return all; 118 | } 119 | 120 | /** 121 | * float 转 byte[] 122 | * 123 | * @param f float 124 | * @return byte[] 125 | */ 126 | public static byte[] float2Bytes(float f) { 127 | return Ints.toByteArray(Float.floatToIntBits(f)); 128 | } 129 | 130 | /** 131 | * byte[] 转 float 132 | * 133 | * @param b byte[] 134 | * @return float 135 | */ 136 | public static float bytes2Float(byte[] b) { 137 | return Float.intBitsToFloat(Ints.fromByteArray(b)); 138 | } 139 | 140 | /** 141 | * 隐藏虚拟键盘 142 | */ 143 | public static void hideIputKeyboard(final Context context) { 144 | final Activity activity = (Activity) context; 145 | activity.runOnUiThread(() -> { 146 | InputMethodManager mInputKeyBoard = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); 147 | if (activity.getCurrentFocus() != null) { 148 | mInputKeyBoard.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); 149 | activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); 150 | } 151 | }); 152 | } 153 | 154 | } 155 | -------------------------------------------------------------------------------- /app/src/main/java/com/exce/bluetooth/utils/test.java: -------------------------------------------------------------------------------- 1 | package com.exce.bluetooth.utils; 2 | 3 | /** 4 | * @Author Wangjj 5 | * @Create 2018/5/3 13:56. 6 | * @Title 7 | */ 8 | public class test { 9 | 10 | public static void main(String[] args) { 11 | 12 | byte aa[] = { 22, 38,38, 22,22, 4, 4, 11, 11 }; 13 | byte temp = 0; 14 | for (byte anAa : aa) { 15 | temp ^= anAa; 16 | } 17 | System.out.println(temp); 18 | 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /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/background_card.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Janain/Android-ECG-Test/b492b923658cbe3cd8f361991eab21c21d4b2c62/app/src/main/res/drawable/background_card.9.png -------------------------------------------------------------------------------- /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/drawable/ic_new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Janain/Android-ECG-Test/b492b923658cbe3cd8f361991eab21c21d4b2c62/app/src/main/res/drawable/ic_new.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/radius_drawable_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout-v21/dialog_scan_device.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 24 | 25 | 37 | 38 | 48 | 49 |