├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── drawable-hdpi
│ │ │ │ ├── bamboo.jpg
│ │ │ │ ├── logo.png
│ │ │ │ ├── mat2.jpg
│ │ │ │ ├── mat3.jpg
│ │ │ │ ├── photo.jpg
│ │ │ │ ├── photo2.jpg
│ │ │ │ ├── ic_info_black_24dp.png
│ │ │ │ ├── ic_mic_white_24dp.png
│ │ │ │ ├── ic_sync_black_24dp.png
│ │ │ │ ├── ic_hotel_grey600_24dp.png
│ │ │ │ ├── ic_settings_black_24dp.png
│ │ │ │ ├── ic_arrow_back_white_24dp.png
│ │ │ │ └── ic_notifications_black_24dp.png
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_drawer_home.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_bluetooth_black_36dp.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── drawable-mdpi
│ │ │ │ ├── ic_info_black_24dp.png
│ │ │ │ ├── ic_sync_black_24dp.png
│ │ │ │ └── ic_notifications_black_24dp.png
│ │ │ ├── drawable-xhdpi
│ │ │ │ ├── ic_info_black_24dp.png
│ │ │ │ ├── ic_sync_black_24dp.png
│ │ │ │ └── ic_notifications_black_24dp.png
│ │ │ ├── drawable-xxhdpi
│ │ │ │ ├── ic_info_black_24dp.png
│ │ │ │ ├── ic_sync_black_24dp.png
│ │ │ │ └── ic_notifications_black_24dp.png
│ │ │ ├── drawable-xxxhdpi
│ │ │ │ ├── ic_info_black_24dp.png
│ │ │ │ ├── ic_sync_black_24dp.png
│ │ │ │ └── ic_notifications_black_24dp.png
│ │ │ ├── values
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── colors.xml
│ │ │ │ ├── styles.xml
│ │ │ │ └── strings.xml
│ │ │ ├── menu
│ │ │ │ └── menu.xml
│ │ │ ├── values-w820dp
│ │ │ │ └── dimens.xml
│ │ │ ├── drawable-v21
│ │ │ │ ├── ic_info_black_24dp.xml
│ │ │ │ ├── ic_notifications_black_24dp.xml
│ │ │ │ └── ic_sync_black_24dp.xml
│ │ │ ├── drawable
│ │ │ │ └── bg_card.xml
│ │ │ ├── layout
│ │ │ │ ├── activity_main.xml
│ │ │ │ ├── record_item.xml
│ │ │ │ ├── pw_change.xml
│ │ │ │ ├── fragment_users.xml
│ │ │ │ ├── activity_record.xml
│ │ │ │ ├── list_item.xml
│ │ │ │ ├── activity_setting.xml
│ │ │ │ ├── add_user.xml
│ │ │ │ ├── activity_login.xml
│ │ │ │ ├── fragment_main.xml
│ │ │ │ └── activity_about.xml
│ │ │ └── xml
│ │ │ │ ├── pref_headers.xml
│ │ │ │ ├── pref_data_sync.xml
│ │ │ │ ├── pref_notification.xml
│ │ │ │ └── pref_general.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ ├── zhai
│ │ │ │ └── btlock
│ │ │ │ │ └── MainActivity.java
│ │ │ │ └── rocky
│ │ │ │ └── btlock
│ │ │ │ ├── data
│ │ │ │ ├── Record.java
│ │ │ │ ├── User.java
│ │ │ │ └── Constant.java
│ │ │ │ ├── activity
│ │ │ │ ├── AboutActivity.java
│ │ │ │ ├── RecordActivity.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── SettingActivity.java
│ │ │ │ └── LoginActivity.java
│ │ │ │ ├── fragment
│ │ │ │ ├── FragmentMain.java
│ │ │ │ └── FragmentUsers.java
│ │ │ │ ├── adapter
│ │ │ │ ├── RecordAdapter.java
│ │ │ │ └── ListAdapter.java
│ │ │ │ ├── utils
│ │ │ │ └── Utils.java
│ │ │ │ └── bluetooth
│ │ │ │ └── BluetoothLeClass.java
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ ├── rocky
│ │ │ └── btlock
│ │ │ │ └── ExampleUnitTest.java
│ │ │ └── zhai
│ │ │ └── btlock
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ ├── rocky
│ │ └── btlock
│ │ │ └── ApplicationTest.java
│ │ └── zhai
│ │ └── btlock
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── Screenshot
├── about.png
├── login.png
├── main.jpeg
├── main.png
├── photo.jpeg
├── record.png
├── xieyi.png
├── openlock.png
├── setting.png
└── usermannger.png
├── .idea
├── copyright
│ └── profiles_settings.xml
├── modules.xml
├── runConfigurations.xml
├── compiler.xml
├── gradle.xml
└── misc.xml
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── gradle.properties
├── README.md
├── gradlew.bat
└── gradlew
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/Screenshot/about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/Screenshot/about.png
--------------------------------------------------------------------------------
/Screenshot/login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/Screenshot/login.png
--------------------------------------------------------------------------------
/Screenshot/main.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/Screenshot/main.jpeg
--------------------------------------------------------------------------------
/Screenshot/main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/Screenshot/main.png
--------------------------------------------------------------------------------
/Screenshot/photo.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/Screenshot/photo.jpeg
--------------------------------------------------------------------------------
/Screenshot/record.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/Screenshot/record.png
--------------------------------------------------------------------------------
/Screenshot/xieyi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/Screenshot/xieyi.png
--------------------------------------------------------------------------------
/Screenshot/openlock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/Screenshot/openlock.png
--------------------------------------------------------------------------------
/Screenshot/setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/Screenshot/setting.png
--------------------------------------------------------------------------------
/Screenshot/usermannger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/Screenshot/usermannger.png
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/bamboo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-hdpi/bamboo.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-hdpi/logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/mat2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-hdpi/mat2.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/mat3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-hdpi/mat3.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/photo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-hdpi/photo.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/photo2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-hdpi/photo2.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_drawer_home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/mipmap-hdpi/ic_drawer_home.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_info_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-hdpi/ic_info_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_mic_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-hdpi/ic_mic_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_sync_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-hdpi/ic_sync_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_info_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-mdpi/ic_info_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_sync_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-mdpi/ic_sync_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_hotel_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-hdpi/ic_hotel_grey600_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_info_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-xhdpi/ic_info_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_sync_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-xhdpi/ic_sync_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_info_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-xxhdpi/ic_info_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_sync_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-xxhdpi/ic_sync_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_info_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-xxxhdpi/ic_info_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_sync_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-xxxhdpi/ic_sync_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_bluetooth_black_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/mipmap-mdpi/ic_bluetooth_black_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_settings_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-hdpi/ic_settings_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_arrow_back_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-hdpi/ic_arrow_back_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_notifications_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-hdpi/ic_notifications_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_notifications_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-mdpi/ic_notifications_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_notifications_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-xhdpi/ic_notifications_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_notifications_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-xxhdpi/ic_notifications_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_notifications_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rockzhai/BLE-Lock-Android/HEAD/app/src/main/res/drawable-xxxhdpi/ic_notifications_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 150dp
6 | 8dp
7 | 16dp
8 |
9 |
--------------------------------------------------------------------------------
/app/src/test/java/com/rocky/btlock/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.rocky.btlock;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zhai/btlock/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.zhai.btlock;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 | import android.os.Bundle;
5 |
6 | public class MainActivity extends AppCompatActivity {
7 |
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 | setContentView(R.layout.activity_main);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/rocky/btlock/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.rocky.btlock;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_info_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/test/java/com/zhai/btlock/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.zhai.btlock;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_notifications_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_sync_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_card.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
7 |
8 |
9 |
10 |
11 |
12 | -
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/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:\ProgramFiles\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 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rocky/btlock/data/Record.java:
--------------------------------------------------------------------------------
1 | package com.rocky.btlock.data;
2 |
3 | /**
4 | * Created by Rocky on 2016/6/2.
5 | */
6 | public class Record {
7 | public int getId() {
8 | return id;
9 | }
10 |
11 | public void setId(int id) {
12 | this.id = id;
13 | }
14 |
15 | public String getTime() {
16 | return time;
17 | }
18 |
19 | public void setTime(String time) {
20 | this.time = time;
21 | }
22 |
23 | private int id;
24 |
25 | public String getName() {
26 | return name;
27 | }
28 |
29 | public void setName(String name) {
30 | this.name = name;
31 | }
32 |
33 | private String name;
34 | private String time;
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rocky/btlock/data/User.java:
--------------------------------------------------------------------------------
1 | package com.rocky.btlock.data;
2 |
3 | /**
4 | * Created by Rocky on 2016/6/1.
5 | */
6 | public class User {
7 | public int getId() {
8 | return id;
9 | }
10 |
11 | public void setId(int id) {
12 | this.id = id;
13 | }
14 |
15 | public boolean isHaveFiger() {
16 | return haveFiger;
17 | }
18 |
19 | public void setHaveFiger(boolean haveFiger) {
20 | this.haveFiger = haveFiger;
21 | }
22 |
23 | public String getName() {
24 | return name;
25 | }
26 |
27 | public void setName(String name) {
28 | this.name = name;
29 | }
30 |
31 | private int id ;
32 | private boolean haveFiger;
33 | private String name;
34 | }
35 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/record_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/zhai/btlock/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.zhai.btlock;
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.zhai.btlock", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/pref_headers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
14 |
15 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/app/src/main/res/layout/pw_change.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_users.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
15 |
16 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 | #3c4caf4f
7 | #FFC107
8 | #FFA000
9 | #4CAF50
10 | #2E7D32
11 | #536DFE
12 | #304FFE
13 | #4527A0
14 | #311B92
15 | #FF4081
16 | #F50057
17 | #D50000
18 | #d2d7d1
19 | #fff
20 | #1f1f1f
21 | #5b5b5b
22 |
23 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion "25.0.2"
6 |
7 | defaultConfig {
8 | applicationId "com.rocky.btlock"
9 | minSdkVersion 18
10 | targetSdkVersion 25
11 | versionCode 1
12 | versionName "1.0"
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 | testCompile 'junit:junit:4.12'
25 | compile 'com.android.support:appcompat-v7:23.3.0'
26 | compile 'it.neokree:MaterialNavigationDrawer:1.3.3'
27 | compile 'me.drakeet.materialdialog:library:1.3.1'
28 | compile 'com.android.support:design:23.3.0'
29 | compile 'com.github.dmytrodanylyk.android-process-button:library:1.0.0'
30 | compile 'com.android.support:support-v4:23.3.0'
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rocky/btlock/activity/AboutActivity.java:
--------------------------------------------------------------------------------
1 | package com.rocky.btlock.activity;
2 |
3 | import android.support.v7.app.ActionBar;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.os.Bundle;
6 | import android.view.MenuItem;
7 |
8 | import com.rocky.btlock.R;
9 |
10 | public class AboutActivity extends AppCompatActivity {
11 | private ActionBar actionBar;
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_about);
16 | actionBar = getSupportActionBar();
17 | actionBar.setDisplayHomeAsUpEnabled(true);
18 | actionBar.setTitle("关于");
19 | }
20 |
21 | @Override
22 | public boolean onOptionsItemSelected(MenuItem item) {
23 | switch (item.getItemId()) {
24 | case android.R.id.home:
25 | this.finish();
26 | default:
27 | return super.onOptionsItemSelected(item);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
16 |
17 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/pref_data_sync.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
14 |
15 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/pref_notification.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
10 |
11 |
12 |
13 |
19 |
20 |
21 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Android-BLE-Lock
2 | #### 基于多级安全机制的蓝牙智能门锁Android客户端实现
3 |
4 |
5 | 该项目客户端基于 Android 平台,通过 CC2541 蓝牙芯片和底层进行通信,以 HT32F1656 单片机为控制核心。
6 |
7 | 基于蓝牙技术、生物传感技术,RFID技术等,实现智能记忆门锁功能。
8 |
9 | 利用生物传感技术、RFID技术实现多种识别验证机制。
10 |
11 | 同时通过备用复位系统,解决失效死机问题,通过备用电池电源供电系统,防止主电源断电的续航工作。
12 |
13 | 该开源内容仅为 Android 客户端,调试方式时使用[串口调试助手(丁丁)](http://www.cr173.com/soft/43649.html)。
14 |
15 | 该串口调试助手可以自定义存储命令,实践中调试比较方便。
16 |
17 | 相关技术博文请参考个人博客:http://zhaidongyan.cn/android-ble-lock/
18 |
19 | 关于在 Android 6.0 下开启定位权限问题请参考:http://blog.csdn.net/kjunchen/article/details/52769915
20 | 感谢稀土掘金用户[你画的彩虹](https://juejin.im/user/57d616a8d20309002c1b80b8) 提出的问题。
21 |
22 | 欢迎提问,如果喜欢,期待您的 star
23 |
24 | 软件运行截图:
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/pref_general.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
20 |
21 |
23 |
24 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rocky/btlock/fragment/FragmentMain.java:
--------------------------------------------------------------------------------
1 | package com.rocky.btlock.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.os.CountDownTimer;
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 | import android.widget.Button;
11 | import android.widget.TextView;
12 |
13 | import com.dd.processbutton.iml.ActionProcessButton;
14 | import com.rocky.btlock.activity.LoginActivity;
15 | import com.rocky.btlock.R;
16 | import com.rocky.btlock.utils.Utils;
17 | import com.rocky.btlock.data.Constant;
18 |
19 | /**
20 | * Created by Rocky on 2016/5/28.
21 | */
22 | public class FragmentMain extends Fragment {
23 | private static ActionProcessButton openLock;
24 | private View view;
25 |
26 | @Override
27 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
28 | view = inflater.inflate(R.layout.fragment_main, container, false);
29 | openLock = (ActionProcessButton) view.findViewById(R.id.btnOpenLock);
30 | openLock.setOnClickListener(new View.OnClickListener() {
31 | @Override
32 | public void onClick(View v) {
33 | LoginActivity.writeChar(Utils.hexStringToBytes(Constant.OPEN_LOCK));
34 | openLock.setProgress(50);
35 | }
36 | });
37 | return view;
38 | }
39 |
40 | public static void setOpen() {
41 | openLock.setProgress(100);
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_record.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
30 |
31 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
22 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
25 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_setting.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
22 |
23 |
31 |
39 |
40 |
41 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rocky/btlock/adapter/RecordAdapter.java:
--------------------------------------------------------------------------------
1 | package com.rocky.btlock.adapter;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.BaseAdapter;
8 | import android.widget.RelativeLayout;
9 | import android.widget.TextView;
10 | import android.widget.Toast;
11 |
12 | import com.dd.processbutton.iml.ActionProcessButton;
13 | import com.rocky.btlock.R;
14 | import com.rocky.btlock.activity.LoginActivity;
15 | import com.rocky.btlock.data.Constant;
16 | import com.rocky.btlock.data.Record;
17 | import com.rocky.btlock.data.User;
18 | import com.rocky.btlock.utils.Utils;
19 |
20 | import java.util.ArrayList;
21 |
22 | /**
23 | * Created by rocky.
24 | */
25 | public class RecordAdapter extends BaseAdapter {
26 | private ArrayList goodses;
27 | private LayoutInflater inflater;
28 | Context context;
29 |
30 | public RecordAdapter(Context context, ArrayList arrayList) {
31 | this.goodses = arrayList;
32 | this.context = context;
33 | inflater = LayoutInflater.from(context);
34 | }
35 |
36 | @Override
37 | public int getCount() {
38 | return goodses.size();
39 | }
40 |
41 | @Override
42 | public Object getItem(int position) {
43 | return goodses.size();
44 | }
45 |
46 | @Override
47 | public long getItemId(int position) {
48 | return position;
49 | }
50 |
51 | @Override
52 | public View getView(final int position, View convertView, ViewGroup parent) {
53 | View view = convertView;
54 | Holder holder = null;
55 | if (view == null) {
56 | holder = new Holder();
57 | view = inflater.inflate(R.layout.record_item, null);
58 | holder.time = (TextView) view.findViewById(R.id.time);
59 |
60 | view.setTag(holder);
61 | } else {
62 | holder = (Holder) view.getTag();
63 | }
64 | holder.time.setText(goodses.get(position).getTime());
65 | return view;
66 | }
67 |
68 | class Holder {
69 | TextView time;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/add_user.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
16 |
17 |
28 |
33 |
34 |
35 |
46 |
51 |
52 |
53 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Btlock
3 | Sign in
4 |
5 |
6 | 六位密码哦~
7 | 密码错误
8 | 请填写您的信息
9 | "Contacts permissions are needed for providing email
10 | completions."
11 |
12 | 设置
13 |
14 |
15 |
16 |
17 | General
18 |
19 | Enable social recommendations
20 | Recommendations for people to contact
21 | based on your message history
22 |
23 |
24 | Display name
25 | John Smith
26 |
27 | Add friends to messages
28 |
29 | - Always
30 | - When possible
31 | - Never
32 |
33 |
34 | - 1
35 | - 0
36 | - -1
37 |
38 |
39 |
40 | Data & sync
41 |
42 | Sync frequency
43 |
44 | - 15 minutes
45 | - 30 minutes
46 | - 1 hour
47 | - 3 hours
48 | - 6 hours
49 | - Never
50 |
51 |
52 | - 15
53 | - 30
54 | - 60
55 | - 180
56 | - 360
57 | - -1
58 |
59 |
60 | System sync settings
61 |
62 |
63 | Notifications
64 |
65 | New message notifications
66 |
67 | Ringtone
68 | Silent
69 |
70 | Vibrate
71 | 开发者
72 | Github: https://github.com/rockzhai
73 | 用到的开源库
74 | MaterialNavigationDrawer:1.3.3\n\nme.drakeet.materialdialog:library:1.3.1\n\ndmytrodanylyk.android-process-button:library:1.0.0
75 | 技术博客: https://www.zhaidy.cc
76 | 这是一款为蓝牙锁的智能终端应用,提供蓝牙开锁,用户管理,指纹添加等功能。\n\n\n 通过蓝牙连接,走向智能家居的第一步…
77 |
78 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rocky/btlock/data/Constant.java:
--------------------------------------------------------------------------------
1 | package com.rocky.btlock.data;
2 |
3 | /**
4 | * Created by Rocky on 2016/5/30.
5 | */
6 | public class Constant {
7 |
8 | //全局常量
9 | //结束字符
10 | public static final String END_CHAR = "0d";
11 | //字头
12 | public static final String HEAD_CHAR = "aa";
13 | //蓝牙芯片终端(以下两个字段用于识别发送和识别信息对象)
14 | public static final String SEVER_BLUETOOTH = "01";
15 | //客户端
16 | public static final String APP = "02";
17 | //功能
18 | //发送本机蓝牙地址
19 | public static final String SEND_ADDRESS = "01";
20 | //创建管理员
21 | public static final String CREAT_ADMIN = "02";
22 | public static final String CREAT_ADMIN_SUCCESS = "03";
23 | public static final String CREAT_ADMIN_FAIL = "04";
24 | //校验用户登陆信息
25 | public static final String LOGIN = "05";
26 | //管理员登陆
27 | public static final String LOGIN_ADMIN = "07";
28 | //普通用户登陆
29 | public static final String LOGIN_USERS = "06";
30 | //用户登录失败
31 | public static final String LOGIN_FAIL_NUM = "08";
32 | //开锁
33 | public static final String LOCK_OPEN_NUM = "09";
34 | //开锁成功
35 | public static final String LOCK_OPEN_SUCCESS_NUM = "0a";
36 | //查看记录
37 | public static final String RECORD_REQUEST_NUM = "0b";
38 | //获取存储记录
39 | public static final String GET_RECORD_NUM = "0c";
40 | //记录发送完毕
41 | public static final String RECORD_END_NUM = "0d";
42 | //修改触摸屏密码
43 | public static final String CHANGE_PASSWORD_NUM = "0e";
44 | //修改触摸屏密码成功
45 | public static final String CHANGE_PASSWORD_SUCCESS_NUM = "0f";
46 | //新增用户
47 | public static final String NEW_USER_NUM = "10";
48 | //新增用户成功
49 | public static final String NEW_USER_SUCCESS_NUM = "11";
50 | //删除用户
51 | public static final String DEL_USER_NUM = "12";
52 | //删除用户成功
53 | public static final String DEL_SUCCESS_NUM = "14";
54 | //增加指纹
55 | public static final String ADD_NEW_FINGER_NUM = "15";
56 | //增加指纹成功
57 | public static final String ADD_FINGER_SUCCESS_NUM = "16";
58 | //增加指纹失败
59 | public static final String ADD_FINGER_FAIL_NUM = "17";
60 | //没有发送地址
61 | public static final String NO_BLUE_ADDRESS = "aa0518020d";
62 |
63 | //固定返回指令
64 | //创建管理员成功和失败
65 | public static final String CREAT_ADMIN_CALLBACK_SUCCESS = HEAD_CHAR + "05" + CREAT_ADMIN_SUCCESS + APP + END_CHAR;
66 | public static final String CREAT_ADMIN_CALLBACK_FAIL = HEAD_CHAR + "05" + CREAT_ADMIN_FAIL + APP + END_CHAR;
67 | //管理员登陆成功
68 | public static final String LOGIN_ADMIN_SUCCESS = HEAD_CHAR + "05" + LOGIN_ADMIN + APP + END_CHAR;
69 | //普通用户登录成功
70 | public static final String LOGIN_USER_SUCCESS = HEAD_CHAR + "05" + LOGIN_USERS + APP + END_CHAR;
71 | //用户登录失败
72 | public static final String LOGIN_FAIL = HEAD_CHAR + "05" + LOGIN_FAIL_NUM + APP + END_CHAR;
73 | //开锁指令
74 | public static final String OPEN_LOCK = HEAD_CHAR + "05" + LOCK_OPEN_NUM + SEVER_BLUETOOTH + END_CHAR;
75 | //开锁成功
76 | public static final String OPEN_LOCK_SUCCESS = HEAD_CHAR + "05" + LOCK_OPEN_SUCCESS_NUM + APP + END_CHAR;
77 | //查看记录
78 | public static final String RECORD_REQUEST = HEAD_CHAR + "05" + RECORD_REQUEST_NUM + SEVER_BLUETOOTH + END_CHAR;
79 | //记录发送完毕
80 | public static final String RECORE_END = HEAD_CHAR + "05" + RECORD_END_NUM + APP + END_CHAR;
81 | //修改触摸屏密码成功
82 | public static final String CHANGE_PASSWORD_SUCCESS = HEAD_CHAR + "05" + CHANGE_PASSWORD_SUCCESS_NUM + APP + END_CHAR;
83 | //新增用户成功
84 | public static final String ADD_USERS_SUCCESS = HEAD_CHAR + "05" + NEW_USER_SUCCESS_NUM + APP + END_CHAR;
85 | //删除用户成功
86 | public static final String DEL_USER_SUCCESS = HEAD_CHAR + "05" + DEL_SUCCESS_NUM + APP + END_CHAR;
87 | //添加指纹成功
88 | public static final String ADD_FINGER_SUCCESS = HEAD_CHAR + "05" + ADD_FINGER_SUCCESS_NUM + APP + END_CHAR;
89 | //添加指纹失败
90 | public static final String ADD_FINGER_FAIL = HEAD_CHAR + "05" + ADD_FINGER_FAIL_NUM + APP + END_CHAR;
91 | //查看用户
92 | public static final String GET_USER_REQUEST = "aa0519010d";
93 | //查看用户
94 | public static final String USER_END = "aa0521020d";
95 | //增加用户失败
96 | public static final String ADD_USE_FAIL = "aa0512020d";
97 | //时间校验成功
98 | public static final String TIME_SUCESS = "aa0523020d";
99 |
100 | public static final String ADMIN_DEL_FAIL = "aa0524020d";
101 | }
102 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
20 |
21 |
25 |
26 |
31 |
32 |
35 |
36 |
44 |
45 |
46 |
49 |
50 |
62 |
63 |
64 |
69 |
73 |
83 |
84 |
94 |
95 |
96 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
26 |
31 |
32 |
39 |
40 |
45 |
46 |
52 |
53 |
63 |
64 |
73 |
74 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
94 |
95 |
102 |
103 |
109 |
110 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rocky/btlock/activity/RecordActivity.java:
--------------------------------------------------------------------------------
1 | package com.rocky.btlock.activity;
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.view.MenuItem;
8 | import android.view.View;
9 | import android.widget.Button;
10 | import android.widget.ListView;
11 | import android.widget.Toast;
12 |
13 | import com.dd.processbutton.iml.ActionProcessButton;
14 | import com.rocky.btlock.R;
15 | import com.rocky.btlock.adapter.RecordAdapter;
16 | import com.rocky.btlock.data.Constant;
17 | import com.rocky.btlock.data.Record;
18 | import com.rocky.btlock.utils.Utils;
19 |
20 | import java.util.ArrayList;
21 |
22 | import me.drakeet.materialdialog.MaterialDialog;
23 |
24 | public class RecordActivity extends AppCompatActivity {
25 | private static ListView mRecordList;
26 | private static ArrayList arrayList;
27 | private static ActionProcessButton getRecord;
28 | private static RecordAdapter mAdapter;
29 | private static Handler mHandler1;
30 | private static Handler mHandler;
31 | private static RecordActivity instance;
32 |
33 | @Override
34 | protected void onCreate(Bundle savedInstanceState) {
35 | super.onCreate(savedInstanceState);
36 | setContentView(R.layout.activity_record);
37 | getSupportActionBar().setTitle("开锁记录");
38 | mHandler = new Handler() {
39 | @Override
40 | public void handleMessage(Message msg) {
41 | super.handleMessage(msg);
42 | Bundle bundle = msg.getData();
43 | String time = bundle.getString("time");
44 | int id = bundle.getInt("id");
45 | Record record = new Record();
46 | record.setTime(time);
47 | record.setId(id);
48 | arrayList.add(record);
49 | mAdapter.notifyDataSetChanged();
50 | }
51 | };
52 |
53 | instance = this;
54 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
55 | arrayList = new ArrayList();
56 | LoginActivity.writeChar(Utils.hexStringToBytes(Constant.RECORD_REQUEST));
57 | getRecord = (ActionProcessButton) findViewById(R.id.getRecord);
58 | mRecordList = (ListView) findViewById(R.id.recordList);
59 | mAdapter = new RecordAdapter(this, arrayList);
60 | mRecordList.setAdapter(mAdapter);
61 | getRecord.setProgress(50);
62 | getRecord.setOnClickListener(new View.OnClickListener() {
63 | @Override
64 | public void onClick(View v) {
65 | LoginActivity.writeChar(Utils.hexStringToBytes(Constant.RECORD_REQUEST));
66 | getRecord.setProgress(50);
67 | }
68 | });
69 |
70 |
71 | }
72 |
73 | @Override
74 | public boolean onOptionsItemSelected(MenuItem item) {
75 | switch (item.getItemId()) {
76 | case android.R.id.home:
77 | this.finish();
78 | default:
79 | return super.onOptionsItemSelected(item);
80 | }
81 | }
82 |
83 | public static void addData(int id, String time) {
84 | Message msg = new Message();
85 | Bundle bundle = new Bundle();
86 | // int a, b, c, d;
87 |
88 | bundle.putInt("id", id);
89 | bundle.putString("time", Utils.hexToString(time.substring(8, 16)) + "\n" + Utils.getTime(time));
90 | msg.setData(bundle);
91 | mHandler.sendMessage(msg);
92 | }
93 |
94 | // //添加纪录
95 | // public static void addRecord(final int id, final String time) {
96 | // mHandler1.post(new Runnable() {
97 | // @Override
98 | // public synchronized void run() {
99 | // int a ,b;
100 | // a= time.charAt(10)*10+time.charAt(11);
101 | // b=time.charAt(12)*10+time.charAt(12);
102 | // String string = (a*256+b)+"";
103 | // addData(id, string);
104 | // addData(id, time);
105 | //
106 | // }
107 | // });
108 | //
109 | //
110 | // }
111 |
112 | //完成读取
113 | public static void addEnd() {
114 | mHandler.post(new Runnable() {
115 | @Override
116 | public synchronized void run() {
117 | final MaterialDialog materiaDialog = new MaterialDialog(RecordActivity.instance);
118 | materiaDialog.setTitle("提示");
119 | materiaDialog.setMessage("记录更新完毕!");
120 | materiaDialog.setNegativeButton("确定", new View.OnClickListener() {
121 | @Override
122 | public void onClick(View v) {
123 | materiaDialog.dismiss();
124 |
125 | }
126 | });
127 | materiaDialog.show();
128 | getRecord.setProgress(100);
129 | }
130 | });
131 |
132 |
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rocky/btlock/adapter/ListAdapter.java:
--------------------------------------------------------------------------------
1 | package com.rocky.btlock.adapter;
2 |
3 | import android.content.Context;
4 | import android.os.Message;
5 | import android.util.Log;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.BaseAdapter;
10 | import android.widget.RelativeLayout;
11 | import android.widget.TextView;
12 | import android.widget.Toast;
13 |
14 | import com.dd.processbutton.iml.ActionProcessButton;
15 | import com.rocky.btlock.R;
16 | import com.rocky.btlock.activity.LoginActivity;
17 | import com.rocky.btlock.activity.MainActivity;
18 | import com.rocky.btlock.data.Constant;
19 | import com.rocky.btlock.data.User;
20 | import com.rocky.btlock.utils.Utils;
21 |
22 | import java.util.ArrayList;
23 |
24 | import me.drakeet.materialdialog.MaterialDialog;
25 |
26 | /**
27 | * Created by rocky.
28 | */
29 | public class ListAdapter extends BaseAdapter {
30 | private ArrayList goodses;
31 | private LayoutInflater inflater;
32 | Context context;
33 |
34 | public ListAdapter(Context context, ArrayList arrayList) {
35 | this.goodses = arrayList;
36 | this.context = context;
37 | inflater = LayoutInflater.from(context);
38 | }
39 |
40 | @Override
41 | public int getCount() {
42 | return goodses.size();
43 | }
44 |
45 | @Override
46 | public Object getItem(int position) {
47 | return goodses.size();
48 | }
49 |
50 | @Override
51 | public long getItemId(int position) {
52 | return position;
53 | }
54 |
55 | @Override
56 | public View getView(final int position, View convertView, ViewGroup parent) {
57 | View view = convertView;
58 | Holder holder = null;
59 | if (view == null) {
60 | holder = new Holder();
61 | view = inflater.inflate(R.layout.list_item, null);
62 | holder.name = (TextView) view.findViewById(R.id.name);
63 | holder.addFinger = (ActionProcessButton) view.findViewById(R.id.btn_finger_add);
64 | holder.list = (RelativeLayout) view.findViewById(R.id.mlist_item);
65 |
66 | view.setTag(holder);
67 | } else {
68 | holder = (Holder) view.getTag();
69 | }
70 | holder.name.setText(goodses.get(position).getName());
71 |
72 | if (goodses.get(position).isHaveFiger()) {
73 | holder.addFinger.setProgress(100);
74 | } else {
75 | holder.addFinger.setProgress(0);
76 | }
77 | final Holder finalHolder = holder;
78 | holder.addFinger.setOnClickListener(new View.OnClickListener() {
79 | @Override
80 | public void onClick(View v) {
81 | if (finalHolder.addFinger.getProgress() == 0) {
82 | Log.e("+++++++++++++++++++++++", Constant.HEAD_CHAR + "09" + Constant.ADD_NEW_FINGER_NUM + Constant.SEVER_BLUETOOTH + Utils.toHexString(goodses.get(position).getName()) + Constant.END_CHAR);
83 | LoginActivity.writeChar(Utils.hexStringToBytes(Constant.HEAD_CHAR + "09" + Constant.ADD_NEW_FINGER_NUM + Constant.SEVER_BLUETOOTH + Utils.toHexString(goodses.get(position).getName()) + Constant.END_CHAR));
84 | Log.e("+++++++++++++++++++++++", Constant.HEAD_CHAR + "09" + Constant.ADD_NEW_FINGER_NUM + Constant.SEVER_BLUETOOTH + Utils.toHexString(goodses.get(position).getName()) + Constant.END_CHAR);
85 | Toast.makeText(context, "请根据语音提示进行指纹添加操作", Toast.LENGTH_LONG).show();
86 | finalHolder.addFinger.setProgress(50);
87 | }
88 | }
89 | });
90 | finalHolder.list.setOnLongClickListener(new View.OnLongClickListener() {
91 | @Override
92 | public boolean onLongClick(View v) {
93 | final MaterialDialog materialDialog = new MaterialDialog(MainActivity.instance);
94 | materialDialog.setTitle("提示");
95 | materialDialog.setMessage("确定删除" + goodses.get(position).getName() + "用户吗?");
96 | materialDialog.setPositiveButton("确定", new View.OnClickListener() {
97 | @Override
98 | public void onClick(View v) {
99 | LoginActivity.writeChar(Utils.hexStringToBytes("aa091301" + Utils.toHexString(goodses.get(position).getName()) + Constant.END_CHAR));
100 | // materialDialog.setMessage("aao91301" + Utils.toHexString(goodses.get(position).getName()) + "od"+"/n");
101 | materialDialog.dismiss();
102 |
103 |
104 | goodses.remove(position);
105 | notifyDataSetChanged();
106 | }
107 | });
108 | materialDialog.setNegativeButton("取消", new View.OnClickListener() {
109 | @Override
110 | public void onClick(View v) {
111 | materialDialog.dismiss();
112 | }
113 | });
114 | materialDialog.setCanceledOnTouchOutside(true);
115 | materialDialog.show();
116 |
117 | return true;
118 | }
119 | });
120 | return view;
121 | }
122 |
123 | class Holder {
124 | TextView name;
125 | ActionProcessButton addFinger;
126 | RelativeLayout list;
127 |
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rocky/btlock/activity/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.rocky.btlock.activity;
2 |
3 |
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.os.Handler;
7 | import android.support.v7.widget.Toolbar;
8 | import android.view.KeyEvent;
9 | import android.view.Menu;
10 | import android.view.MenuItem;
11 | import android.view.View;
12 | import android.widget.Toast;
13 |
14 | import com.rocky.btlock.R;
15 | import com.rocky.btlock.fragment.FragmentMain;
16 | import com.rocky.btlock.fragment.FragmentUsers;
17 |
18 | import it.neokree.materialnavigationdrawer.MaterialNavigationDrawer;
19 | import it.neokree.materialnavigationdrawer.elements.MaterialAccount;
20 | import it.neokree.materialnavigationdrawer.elements.MaterialSection;
21 | import it.neokree.materialnavigationdrawer.elements.listeners.MaterialAccountListener;
22 | import me.drakeet.materialdialog.MaterialDialog;
23 |
24 | /**
25 | * Created by Rocky on 2016/5/28.
26 | */
27 | public class MainActivity extends MaterialNavigationDrawer {
28 | private final static String TAG = "MainActivity";
29 | //点击两次返回键退出
30 | private long mExitTime = 0;
31 | public static FragmentMain mainFragment;
32 | public static MainActivity instance;
33 | private static Toolbar toolbar;
34 | private static MaterialDialog materiaDialog;
35 | private static Handler mHandler = new Handler();
36 | private boolean isAdmin = true;
37 | private String userName, userAttr = "普通用户";
38 |
39 | @Override
40 | public void init(Bundle savedInstanceState) {
41 | instance = this;
42 | Intent in = getIntent();
43 | //isAdmin = in.getExtras().getBoolean("isAdmin");
44 | //userName = in.getExtras().getString("UserName");
45 | if (isAdmin) {
46 | userAttr = "管理员账户";
47 | }
48 | Intent toSet = new Intent(MainActivity.this, SettingActivity.class);
49 | toSet.putExtra("isAdmin", isAdmin);
50 | toolbar = getToolbar();
51 | toolbar.setPopupTheme(R.style.ToolbarPopupTheme);
52 | toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
53 | @Override
54 | public boolean onMenuItemClick(MenuItem item) {
55 | switch (item.getItemId()) {
56 | case R.id.action_about:
57 | startActivity(new Intent(MainActivity.this, AboutActivity.class));
58 | break;
59 | }
60 | return false;
61 | }
62 | });
63 | final MaterialAccount account = new MaterialAccount(this.getResources(), userName, userAttr, R.drawable.photo, R.drawable.bamboo);
64 | this.addAccount(account);
65 | mainFragment = new FragmentMain();
66 | MaterialSection mSection = newSection("智能开锁", mainFragment);
67 | this.addSection(mSection);
68 | if (isAdmin) {
69 | this.addSection(newSection("开锁记录", new Intent(this, RecordActivity.class)));
70 | this.addSection(newSection("用户管理", new FragmentUsers()));
71 | userAttr = "管理员账户";
72 | }
73 |
74 | this.addSection(newSection("关于我们", new Intent(this, AboutActivity.class)));
75 | this.addBottomSection(newSection("设置", R.drawable.ic_settings_black_24dp, toSet));
76 | this.setAccountListener(new MaterialAccountListener() {
77 | @Override
78 | public void onAccountOpening(MaterialAccount account) {
79 | if (account.getAccountNumber() == 0) {
80 | Toast.makeText(getApplication(), "当前用户:" + account.getTitle(), Toast.LENGTH_SHORT).show();
81 | }
82 | }
83 |
84 | @Override
85 | public void onChangeAccount(MaterialAccount newAccount) {
86 | if (account.getAccountNumber() == 0) {
87 | // TODO
88 | }
89 | }
90 | });
91 |
92 | }
93 |
94 | //开锁成功弹窗提示
95 | public static void setOpen() {
96 | mHandler.post(new Runnable() {
97 | @Override
98 | public synchronized void run() {
99 | materiaDialog = new MaterialDialog(MainActivity.instance)
100 | .setTitle("提示")
101 | .setMessage("开锁成功!")
102 | .setPositiveButton("确认", new View.OnClickListener() {
103 | @Override
104 | public void onClick(View v) {
105 | materiaDialog.dismiss();
106 |
107 | }
108 | })
109 | .setNegativeButton("取消", new View.OnClickListener() {
110 | @Override
111 | public void onClick(View v) {
112 | materiaDialog.dismiss();
113 |
114 | }
115 | });
116 |
117 | materiaDialog.show();
118 |
119 | mainFragment.setOpen();
120 | }
121 | });
122 |
123 |
124 | }
125 |
126 | @Override
127 | public boolean onKeyDown(int keyCode, KeyEvent event) {
128 | if (keyCode == KeyEvent.KEYCODE_BACK) {
129 | if ((System.currentTimeMillis() - mExitTime) > 2000) {//
130 | // 如果两次按键时间间隔大于2000毫秒,则不退出
131 | Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
132 | mExitTime = System.currentTimeMillis();// 更新mExitTime
133 | } else {
134 | // 否则退出程序
135 | LoginActivity.instance.finish();
136 | System.exit(0);
137 |
138 | }
139 | return true;
140 | }
141 |
142 | return super.onKeyDown(keyCode, event);
143 | }
144 |
145 | @Override
146 | public boolean onCreateOptionsMenu(Menu menu) {
147 | // Inflate the menu; this adds items to the action bar if it is present.
148 | getMenuInflater().inflate(R.menu.menu, menu);
149 | return true;
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_about.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
13 |
14 |
18 |
19 |
27 |
28 |
33 |
34 |
42 |
43 |
44 |
50 |
51 |
58 |
59 |
64 |
65 |
72 |
73 |
74 |
75 |
80 |
81 |
88 |
89 |
93 |
94 |
100 |
101 |
111 |
112 |
121 |
122 |
131 |
132 |
133 |
134 |
139 |
140 |
147 |
148 |
154 |
155 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rocky/btlock/activity/SettingActivity.java:
--------------------------------------------------------------------------------
1 | package com.rocky.btlock.activity;
2 |
3 | import android.content.Intent;
4 | import android.content.SharedPreferences;
5 | import android.os.Handler;
6 | import android.os.Message;
7 | import android.support.v7.app.ActionBar;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.os.Bundle;
10 | import android.util.Log;
11 | import android.view.LayoutInflater;
12 | import android.view.MenuItem;
13 | import android.view.View;
14 | import android.widget.Button;
15 | import android.widget.EditText;
16 | import android.widget.Toast;
17 |
18 | import com.rocky.btlock.R;
19 | import com.rocky.btlock.data.Constant;
20 | import com.rocky.btlock.utils.Utils;
21 |
22 | import java.text.SimpleDateFormat;
23 | import java.util.Locale;
24 |
25 | import me.drakeet.materialdialog.MaterialDialog;
26 |
27 | public class SettingActivity extends AppCompatActivity {
28 | private static Handler mHandler;
29 | private static MaterialDialog materialDialog;
30 | private static MaterialDialog materiaDialog;
31 | public static SettingActivity instance;
32 | private static MaterialDialog maDialog;
33 | private boolean isAdmin = true;
34 |
35 | @Override
36 | protected void onCreate(Bundle savedInstanceState) {
37 | super.onCreate(savedInstanceState);
38 | setContentView(R.layout.activity_setting);
39 | mHandler = new Handler();
40 | instance = this;
41 | ActionBar actionBar = getSupportActionBar();
42 | actionBar.setDisplayHomeAsUpEnabled(true);
43 | Intent in = getIntent();
44 | isAdmin = in.getExtras().getBoolean("isAdmin");
45 |
46 | Button logout = (Button) findViewById(R.id.logout);
47 | Button exit = (Button) findViewById(R.id.exit);
48 | final Button clear = (Button) findViewById(R.id.clear);
49 | Button changePW = (Button) findViewById(R.id.changePassword);
50 |
51 |
52 | logout.setOnClickListener(new View.OnClickListener() {
53 | @Override
54 | public void onClick(View v) {
55 | startActivity(new Intent(SettingActivity.this, LoginActivity.class));
56 | MainActivity.instance.finish();
57 | }
58 | });
59 | exit.setOnClickListener(new View.OnClickListener() {
60 | @Override
61 | public void onClick(View v) {
62 | MainActivity.instance.finish();
63 | LoginActivity.instance.finish();
64 | System.exit(0);
65 | }
66 | });
67 | clear.setText("校验系统时间");
68 | clear.setOnClickListener(new View.OnClickListener() {
69 | @Override
70 | public void onClick(View v) {
71 | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss",
72 | Locale.getDefault());
73 | String time = sdf.format(System.currentTimeMillis());
74 | //20160624232850
75 | int year, month, day, hour, min, second;
76 | //
77 | year = Integer.valueOf(time.substring(0, 4));
78 | month = Integer.valueOf(time.substring(4, 6));
79 | day = Integer.valueOf(time.substring(6, 8));
80 | hour = Integer.valueOf(time.substring(8, 10));
81 | min = Integer.valueOf(time.substring(10, 12));
82 | second = Integer.valueOf(time.substring(12, 14));
83 | String str_year = "0" + Integer.toHexString(year);
84 | String str_month = "0" + Integer.toHexString(month);
85 | String str_day = Integer.toHexString(day) + "";
86 | if (str_day.length() % 2 == 1) {
87 | str_day = "0" + str_day;
88 | }
89 |
90 |
91 | String str_hour = Integer.toHexString(hour) + "";
92 | if (str_hour.length() % 2 == 1) {
93 | str_hour = "0" + str_hour;
94 | }
95 | String str_min = Integer.toHexString(min) + "";
96 | if (str_min.length() % 2 == 1) {
97 | str_min = "0" + str_min;
98 | }
99 | String str_sec = Integer.toHexString(second) + "";
100 | if (str_sec.length() % 2 == 1) {
101 | str_sec = "0" + str_sec;
102 | }
103 | LoginActivity.writeChar(Utils.hexStringToBytes(Constant.HEAD_CHAR + "0c" + "22" + Constant.SEVER_BLUETOOTH + str_year + str_month + str_day + str_hour + str_min + str_sec + Constant.END_CHAR));
104 | Log.e("+++++++++++++++++++++++=",Constant.HEAD_CHAR + "0c" + "22" + Constant.SEVER_BLUETOOTH + str_year + str_month + str_day + str_hour + str_min + str_sec + Constant.END_CHAR);
105 |
106 | }
107 | });
108 | changePW.setOnClickListener(new View.OnClickListener() {
109 | @Override
110 | public void onClick(View v) {
111 | View view = getLayoutInflater().inflate(R.layout.pw_change, null);
112 | final EditText editText = (EditText) view.findViewById(R.id.pw_change_edit);
113 | materialDialog = new MaterialDialog(SettingActivity.this).setView(view).setTitle("请输入密码:")
114 | .setPositiveButton("确定", new View.OnClickListener() {
115 | @Override
116 | public void onClick(View v) {
117 | String str = editText.getText().toString();
118 | if (!str.isEmpty() && str.length() == 6) {
119 | str = Utils.toHexString(str);
120 | LoginActivity.writeChar(Utils.hexStringToBytes(Constant.HEAD_CHAR + "0b" + Constant.CHANGE_PASSWORD_NUM + Constant.SEVER_BLUETOOTH + str + Constant.END_CHAR));
121 | materialDialog.dismiss();
122 | } else {
123 | editText.setError("六位数字密码哦");
124 | }
125 |
126 | }
127 | })
128 | .setNegativeButton("取消", new View.OnClickListener() {
129 | @Override
130 | public void onClick(View v) {
131 | materialDialog.dismiss();
132 | }
133 | });
134 | materialDialog.show();
135 | }
136 | });
137 | if (!isAdmin) {
138 | clear.setVisibility(View.GONE);
139 | changePW.setVisibility(View.GONE);
140 | }
141 |
142 | }
143 |
144 | //开锁成功弹窗提示
145 | public static void chagneSuccess() {
146 | mHandler.post(new Runnable() {
147 | @Override
148 | public synchronized void run() {
149 | materiaDialog = new MaterialDialog(SettingActivity.instance)
150 | .setTitle("提示")
151 | .setMessage("修改触屏密码成功!")
152 | .setPositiveButton("确认", new View.OnClickListener() {
153 | @Override
154 | public void onClick(View v) {
155 | materiaDialog.dismiss();
156 |
157 | }
158 | })
159 | .setNegativeButton("取消", new View.OnClickListener() {
160 | @Override
161 | public void onClick(View v) {
162 | materiaDialog.dismiss();
163 |
164 | }
165 | });
166 |
167 | materiaDialog.show();
168 |
169 | }
170 | });
171 | }
172 |
173 |
174 | //弹窗提示
175 | public static void sendTimeSuccess() {
176 | mHandler.post(new Runnable() {
177 | @Override
178 | public synchronized void run() {
179 | maDialog = new MaterialDialog(SettingActivity.instance)
180 | .setTitle("提示")
181 | .setMessage("时间同步成功!");
182 | maDialog.setCanceledOnTouchOutside(true);
183 | maDialog.show();
184 | }
185 | });
186 | }
187 |
188 | @Override
189 | public boolean onOptionsItemSelected(MenuItem item) {
190 | switch (item.getItemId()) {
191 | case android.R.id.home:
192 | this.finish();
193 | default:
194 | return super.onOptionsItemSelected(item);
195 | }
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rocky/btlock/utils/Utils.java:
--------------------------------------------------------------------------------
1 |
2 | package com.rocky.btlock.utils;
3 |
4 | import java.util.ArrayList;
5 | import java.util.HashMap;
6 | import java.util.List;
7 |
8 | import android.bluetooth.BluetoothGattCharacteristic;
9 | import android.bluetooth.BluetoothGattDescriptor;
10 | import android.bluetooth.BluetoothGattService;
11 | import android.content.Intent;
12 | import android.text.TextUtils;
13 | import android.util.Log;
14 |
15 | /**
16 | * This class includes a small subset of standard GATT attributes for demonstration purposes.
17 | */
18 | public class Utils {
19 |
20 | private static HashMap serviceTypes = new HashMap();
21 |
22 | static {
23 | // Sample Services.
24 | serviceTypes.put(BluetoothGattService.SERVICE_TYPE_PRIMARY, "PRIMARY");
25 | serviceTypes.put(BluetoothGattService.SERVICE_TYPE_SECONDARY, "SECONDARY");
26 | }
27 |
28 | public static String getServiceType(int type) {
29 | return serviceTypes.get(type);
30 | }
31 |
32 |
33 | //-------------------------------------------
34 | private static HashMap charPermissions = new HashMap();
35 |
36 | static {
37 | charPermissions.put(0, "UNKNOW");
38 | charPermissions.put(BluetoothGattCharacteristic.PERMISSION_READ, "READ");
39 | charPermissions.put(BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED, "READ_ENCRYPTED");
40 | charPermissions.put(BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED_MITM, "READ_ENCRYPTED_MITM");
41 | charPermissions.put(BluetoothGattCharacteristic.PERMISSION_WRITE, "WRITE");
42 | charPermissions.put(BluetoothGattCharacteristic.PERMISSION_WRITE_ENCRYPTED, "WRITE_ENCRYPTED");
43 | charPermissions.put(BluetoothGattCharacteristic.PERMISSION_WRITE_ENCRYPTED_MITM, "WRITE_ENCRYPTED_MITM");
44 | charPermissions.put(BluetoothGattCharacteristic.PERMISSION_WRITE_SIGNED, "WRITE_SIGNED");
45 | charPermissions.put(BluetoothGattCharacteristic.PERMISSION_WRITE_SIGNED_MITM, "WRITE_SIGNED_MITM");
46 | }
47 |
48 | public static String getCharPermission(int permission) {
49 | return getHashMapValue(charPermissions, permission);
50 | }
51 |
52 | //-------------------------------------------
53 | private static HashMap charProperties = new HashMap();
54 |
55 | static {
56 |
57 | charProperties.put(BluetoothGattCharacteristic.PROPERTY_BROADCAST, "BROADCAST");
58 | charProperties.put(BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS, "EXTENDED_PROPS");
59 | charProperties.put(BluetoothGattCharacteristic.PROPERTY_INDICATE, "INDICATE");
60 | charProperties.put(BluetoothGattCharacteristic.PROPERTY_NOTIFY, "NOTIFY");
61 | charProperties.put(BluetoothGattCharacteristic.PROPERTY_READ, "READ");
62 | charProperties.put(BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE, "SIGNED_WRITE");
63 | charProperties.put(BluetoothGattCharacteristic.PROPERTY_WRITE, "WRITE");
64 | charProperties.put(BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE, "WRITE_NO_RESPONSE");
65 | }
66 |
67 | public static String getCharPropertie(int property) {
68 | return getHashMapValue(charProperties, property);
69 | }
70 |
71 | //--------------------------------------------------------------------------
72 | private static HashMap descPermissions = new HashMap();
73 |
74 | static {
75 | descPermissions.put(0, "UNKNOW");
76 | descPermissions.put(BluetoothGattDescriptor.PERMISSION_READ, "READ");
77 | descPermissions.put(BluetoothGattDescriptor.PERMISSION_READ_ENCRYPTED, "READ_ENCRYPTED");
78 | descPermissions.put(BluetoothGattDescriptor.PERMISSION_READ_ENCRYPTED_MITM, "READ_ENCRYPTED_MITM");
79 | descPermissions.put(BluetoothGattDescriptor.PERMISSION_WRITE, "WRITE");
80 | descPermissions.put(BluetoothGattDescriptor.PERMISSION_WRITE_ENCRYPTED, "WRITE_ENCRYPTED");
81 | descPermissions.put(BluetoothGattDescriptor.PERMISSION_WRITE_ENCRYPTED_MITM, "WRITE_ENCRYPTED_MITM");
82 | descPermissions.put(BluetoothGattDescriptor.PERMISSION_WRITE_SIGNED, "WRITE_SIGNED");
83 | descPermissions.put(BluetoothGattDescriptor.PERMISSION_WRITE_SIGNED_MITM, "WRITE_SIGNED_MITM");
84 | }
85 |
86 | public static String getDescPermission(int property) {
87 | return getHashMapValue(descPermissions, property);
88 | }
89 |
90 |
91 | private static String getHashMapValue(HashMap hashMap, int number) {
92 | String result = hashMap.get(number);
93 | if (TextUtils.isEmpty(result)) {
94 | List numbers = getElement(number);
95 | result = "";
96 | for (int i = 0; i < numbers.size(); i++) {
97 | result += hashMap.get(numbers.get(i)) + "|";
98 | }
99 | }
100 | return result;
101 | }
102 |
103 | /**
104 | * 位运算结果的反推函数10 -> 2 | 8;
105 | */
106 | private static List getElement(int number) {
107 | List result = new ArrayList();
108 | for (int i = 0; i < 32; i++) {
109 | int b = 1 << i;
110 | if ((number & b) > 0)
111 | result.add(b);
112 | }
113 |
114 | return result;
115 | }
116 |
117 | // 转化十六进制编码为字符串
118 | public static String hexToString(String s) {
119 | byte[] baKeyword = new byte[s.length() / 2];
120 | for (int i = 0; i < baKeyword.length; i++) {
121 | try {
122 | baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(
123 | i * 2, i * 2 + 2), 16));
124 | } catch (Exception e) {
125 | e.printStackTrace();
126 | }
127 | }
128 | try {
129 | s = new String(baKeyword, "utf-8");// UTF-16le:Not
130 | } catch (Exception e1) {
131 | e1.printStackTrace();
132 | }
133 | return s;
134 | }
135 |
136 |
137 | //byte转化成string
138 | public static String bytesToHexString(byte[] src) {
139 | StringBuilder stringBuilder = new StringBuilder("");
140 | if (src == null || src.length <= 0) {
141 | return null;
142 | }
143 | for (int i = 0; i < src.length; i++) {
144 | int v = src[i] & 0xFF;
145 | String hv = Integer.toHexString(v);
146 | if (hv.length() < 2) {
147 | stringBuilder.append(0);
148 | }
149 | stringBuilder.append(hv);
150 | }
151 | return stringBuilder.toString();
152 | }
153 |
154 | //字符串转byte
155 | public static byte[] hexStringToBytes(String hexString) {
156 | if (hexString == null || hexString.equals("")) {
157 | return null;
158 | }
159 | hexString = hexString.toUpperCase();
160 | int length = hexString.length() / 2;
161 | char[] hexChars = hexString.toCharArray();
162 | byte[] d = new byte[length];
163 | for (int i = 0; i < length; i++) {
164 | int pos = i * 2;
165 | d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
166 | }
167 | return d;
168 | }
169 |
170 | // 转化字符串为十六进制编码
171 | public static String toHexString(String s) {
172 | String str = "";
173 | for (int i = 0; i < s.length(); i++) {
174 | int ch = (int) s.charAt(i);
175 | String s4 = Integer.toHexString(ch);
176 | str = str + s4;
177 | }
178 | return str;
179 | }
180 |
181 | private static byte charToByte(char c) {
182 | return (byte) "0123456789ABCDEF".indexOf(c);
183 | }
184 |
185 | //int类型转byte
186 | public static byte[] intToByteArray(int i) {
187 | byte[] result = new byte[4];
188 | //由高位到低位
189 | result[0] = (byte) ((i >> 24) & 0xFF);
190 | result[1] = (byte) ((i >> 16) & 0xFF);
191 | result[2] = (byte) ((i >> 8) & 0xFF);
192 | result[3] = (byte) (i & 0xFF);
193 | return result;
194 | }
195 |
196 | //字符转int
197 | public static int charToInt(char c) {
198 | int i;
199 | if (c >= '0' && c <= '9') {
200 | i = c - 48;
201 | } else {
202 | i = c - 87;
203 | }
204 | return i;
205 | }
206 |
207 | //处理开锁时间
208 | public static String getTime(String time) {
209 | int a, b, c, d, month_1, month_2, day_1, day_2, hour_1, hour_2, min_1, min_2;
210 | //年份
211 | a = Utils.charToInt(time.charAt(16));
212 | b = Utils.charToInt(time.charAt(17));
213 | c = Utils.charToInt(time.charAt(18));
214 | d = Utils.charToInt(time.charAt(19));
215 | a = a * 16 + b;
216 | c = c * 16 + d;
217 |
218 | //月份
219 | month_1 = Utils.charToInt(time.charAt(20));
220 | month_2 = Utils.charToInt(time.charAt(21));
221 | month_1 = month_1 * 16 + month_2;
222 | //天
223 | day_1 = Utils.charToInt(time.charAt(22));
224 | day_2 = Utils.charToInt(time.charAt(23));
225 | day_1 = day_1 * 16 + day_2;
226 | //时
227 | hour_1 = Utils.charToInt(time.charAt(24));
228 | hour_2 = Utils.charToInt(time.charAt(25));
229 | hour_1 = hour_1 * 16 + hour_2;
230 | //分
231 | min_1 = Utils.charToInt(time.charAt(26));
232 | min_2 = Utils.charToInt(time.charAt(27));
233 | min_1 = min_1 * 16 + min_2;
234 |
235 | String string = (a * 256 + c) + "年" + month_1 + "月" + day_1 + "日" + hour_1 + "时" + min_1 + "分";
236 | return string;
237 | }
238 |
239 | }
240 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rocky/btlock/fragment/FragmentUsers.java:
--------------------------------------------------------------------------------
1 | package com.rocky.btlock.fragment;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.os.Bundle;
6 | import android.os.CountDownTimer;
7 | import android.os.Handler;
8 | import android.os.Message;
9 | import android.support.annotation.Nullable;
10 | import android.support.v4.app.Fragment;
11 | import android.util.Log;
12 | import android.view.LayoutInflater;
13 | import android.view.View;
14 | import android.view.ViewGroup;
15 | import android.widget.AdapterView;
16 | import android.widget.Button;
17 | import android.widget.EditText;
18 | import android.widget.ListView;
19 | import android.widget.TextView;
20 | import android.widget.Toast;
21 |
22 | import com.dd.processbutton.iml.ActionProcessButton;
23 | import com.rocky.btlock.R;
24 | import com.rocky.btlock.activity.LoginActivity;
25 | import com.rocky.btlock.activity.MainActivity;
26 | import com.rocky.btlock.adapter.ListAdapter;
27 | import com.rocky.btlock.data.Constant;
28 | import com.rocky.btlock.data.Record;
29 | import com.rocky.btlock.data.User;
30 | import com.rocky.btlock.utils.Utils;
31 |
32 | import java.util.ArrayList;
33 |
34 | import me.drakeet.materialdialog.MaterialDialog;
35 |
36 | /**
37 | * Created by Rocky on 2016/5/28.
38 | */
39 | public class FragmentUsers extends Fragment {
40 |
41 | private static Handler mHandler, mHandler_Update;
42 | private View view;
43 | private static View viewDialog;
44 | private static ListAdapter mAdapter;
45 | private static ListView listView;
46 | private static ArrayList arrayList;
47 | private Button addUser, addNew;
48 | private static MaterialDialog mDialog, materialDialog, md_del;
49 | private EditText name, password;
50 | private int id = 1;
51 | private static final String TAG = "Fragment_USER";
52 |
53 | @Override
54 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
55 |
56 | view = inflater.inflate(R.layout.fragment_users, container, false);
57 | viewDialog = inflater.inflate(R.layout.add_user, container, false);
58 | listView = (ListView) view.findViewById(R.id.user_listView);
59 | addUser = (Button) view.findViewById(R.id.btn_add_user);
60 | addNew = (Button) viewDialog.findViewById(R.id.btn_add_new_user);
61 | name = (EditText) viewDialog.findViewById(R.id.name);
62 | password = (EditText) viewDialog.findViewById(R.id.password);
63 | arrayList = new ArrayList();
64 | mAdapter = new ListAdapter(getActivity(), arrayList);
65 | listView.setAdapter(mAdapter);
66 | mDialog = new MaterialDialog(MainActivity.instance).setTitle("添加用户").setView(viewDialog);
67 | mDialog.setCanceledOnTouchOutside(true);
68 | LoginActivity.writeChar(Utils.hexStringToBytes("aa0519010d"));
69 |
70 | mHandler = new Handler() {
71 | @Override
72 | public void handleMessage(Message msg) {
73 | super.handleMessage(msg);
74 | Bundle bundle = msg.getData();
75 | String name = bundle.getString("name");
76 | int id = bundle.getInt("id");
77 | boolean isHaveFinger = bundle.getBoolean("isHaveFinger");
78 | User user = new User();
79 | user.setId(id);
80 | user.setHaveFiger(isHaveFinger);
81 | user.setName(name);
82 | arrayList.add(user);
83 | mAdapter.notifyDataSetChanged();
84 | }
85 | };
86 | mHandler_Update = new Handler() {
87 | @Override
88 | public void handleMessage(Message msg) {
89 | super.handleMessage(msg);
90 | mAdapter.notifyDataSetChanged();
91 | }
92 | };
93 |
94 |
95 | addUser.setOnClickListener(new View.OnClickListener() {
96 | @Override
97 | public void onClick(View v) {
98 | mDialog.show();
99 | }
100 | });
101 |
102 | addNew.setOnClickListener(new View.OnClickListener() {
103 | @Override
104 | public void onClick(View v) {
105 | if (name.getText().length() != 4) {
106 | name.setError("请输入四位用户名");
107 | } else if (password.getText().length() != 6) {
108 | password.setError("请输入六位密码");
109 | } else {
110 | String str = Utils.toHexString(name.getText().toString() + password.getText().toString());
111 | LoginActivity.writeChar(Utils.hexStringToBytes(Constant.HEAD_CHAR + "0f" + Constant.NEW_USER_NUM + Constant.SEVER_BLUETOOTH + str + Constant.END_CHAR));
112 | Log.e(TAG, Constant.HEAD_CHAR + "0f" + Constant.NEW_USER_NUM + Constant.SEVER_BLUETOOTH + str + Constant.END_CHAR);
113 | mDialog.dismiss();
114 | }
115 | }
116 | });
117 |
118 |
119 | // listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
120 | // @Override
121 | // public boolean onItemLongClick(AdapterView> parent, View view, final int position, long id) {
122 | // Log.e("TAG","++++++++++++++++++++++++++++++idiiididididididi");
123 | // Toast.makeText(MainActivity.instance, "删除操作", Toast.LENGTH_LONG).show();
124 | //// md_del = new MaterialDialog(MainActivity.instance)
125 | //// .setTitle("删除提示")
126 | //// .setPositiveButton("确定", new View.OnClickListener() {
127 | //// @Override
128 | //// public void onClick(View v) {
129 | //// String del_name = Utils.toHexString(arrayList.get(position).getName());
130 | //// LoginActivity.writeChar(Utils.hexStringToBytes(Constant.HEAD_CHAR + "09" + Constant.DEL_USER_NUM + Constant.SEVER_BLUETOOTH + del_name + Constant.END_CHAR));
131 | //// arrayList.remove(position);
132 | //// mAdapter.notifyDataSetChanged();
133 | //// }
134 | //// })
135 | //// .setNegativeButton("取消", new View.OnClickListener() {
136 | //// @Override
137 | //// public void onClick(View v) {
138 | //// md_del.dismiss();
139 | //// }
140 | //// });
141 | //// md_del.show();
142 | // return true;
143 | // }
144 | // });
145 | return view;
146 | }
147 |
148 |
149 | // //读取本地数据
150 | // private void loadData() {
151 | // // for (id = 1; sp.getString(id + "", "end").equals("end"); id++) {
152 | // //读取数据
153 | // sp = getActivity().getSharedPreferences("SP", Context.MODE_PRIVATE);
154 | // boolean isFinger = false;
155 | // String str = sp.getString(id + "", "none0");
156 | // if (str.charAt(4) != '0') {
157 | // isFinger = true;
158 | // }
159 | // str = str.substring(0, str.length() - 1);
160 | // addData(id, str + "(管理员)", isFinger);
161 | // // }
162 | // }
163 |
164 | public static void addData(int id, String name, boolean isHaveFinger) {
165 | Message msg = new Message();
166 | Bundle bundle = new Bundle();
167 | bundle.putInt("id", id);
168 | bundle.putString("name", name);
169 | bundle.putBoolean("isHaveFinger", isHaveFinger);
170 | msg.setData(bundle);
171 | mHandler.sendMessage(msg);
172 | }
173 |
174 | //添加指纹成功,反馈刷新
175 | public static void addFingerSuccess(final String name) {
176 | mHandler.post(new Runnable() {
177 | @Override
178 | public synchronized void run() {
179 | for (int i = 0; i < arrayList.size(); i++) {
180 | if (arrayList.get(i).getName().equals(name)) {
181 | arrayList.get(i).setHaveFiger(true);
182 | mAdapter.notifyDataSetChanged();
183 | }
184 | }
185 |
186 |
187 | }
188 | });
189 | }
190 |
191 | //弹窗提示
192 | public static void setDialog(final String str) {
193 | mHandler.post(new Runnable() {
194 | @Override
195 | public synchronized void run() {
196 | materialDialog = new MaterialDialog(MainActivity.instance)
197 | .setTitle("提示")
198 | .setMessage(str)
199 | .setPositiveButton("确定", new View.OnClickListener() {
200 | @Override
201 | public void onClick(View v) {
202 | materialDialog.dismiss();
203 | mHandler_Update.sendMessage(new Message());
204 | }
205 | });
206 | materialDialog.show();
207 | materialDialog.setCanceledOnTouchOutside(true);
208 | }
209 | });
210 | }
211 |
212 | //添加指纹失败
213 | public static void addFingerFail() {
214 | mHandler_Update.post(new Runnable() {
215 | @Override
216 | public synchronized void run() {
217 | materialDialog = new MaterialDialog(MainActivity.instance)
218 | .setTitle("提示")
219 | .setMessage("增加指纹失败")
220 | .setPositiveButton("确定", new View.OnClickListener() {
221 | @Override
222 | public void onClick(View v) {
223 | materialDialog.dismiss();
224 | mHandler_Update.sendMessage(new Message());
225 | }
226 | });
227 | materialDialog.show();
228 | }
229 | });
230 | }
231 |
232 |
233 | }
234 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rocky/btlock/bluetooth/BluetoothLeClass.java:
--------------------------------------------------------------------------------
1 | package com.rocky.btlock.bluetooth;
2 |
3 | import android.bluetooth.BluetoothAdapter;
4 | import android.bluetooth.BluetoothDevice;
5 | import android.bluetooth.BluetoothGatt;
6 | import android.bluetooth.BluetoothGattCallback;
7 | import android.bluetooth.BluetoothGattCharacteristic;
8 | import android.bluetooth.BluetoothGattService;
9 | import android.bluetooth.BluetoothManager;
10 | import android.bluetooth.BluetoothProfile;
11 | import android.content.Context;
12 | import android.util.Log;
13 |
14 | import java.util.List;
15 |
16 | /**
17 | * Service for managing connection and data communication with a GATT server hosted on a
18 | * given Bluetooth LE device.
19 | */
20 | public class BluetoothLeClass{
21 | private final static String TAG = BluetoothLeClass.class.getSimpleName();
22 |
23 | private BluetoothManager mBluetoothManager;
24 | private BluetoothAdapter mBluetoothAdapter;
25 | private String mBluetoothDeviceAddress;
26 | private BluetoothGatt mBluetoothGatt;
27 |
28 | public interface OnConnectListener {
29 | public void onConnect(BluetoothGatt gatt);
30 | }
31 | public interface OnDisconnectListener {
32 | public void onDisconnect(BluetoothGatt gatt);
33 | }
34 | public interface OnServiceDiscoverListener {
35 | public void onServiceDiscover(BluetoothGatt gatt);
36 | }
37 | public interface OnDataAvailableListener {
38 | public void onCharacteristicRead(BluetoothGatt gatt,
39 | BluetoothGattCharacteristic characteristic,
40 | int status);
41 | public void onCharacteristicWrite(BluetoothGatt gatt,
42 | BluetoothGattCharacteristic characteristic);
43 | }
44 |
45 | private OnConnectListener mOnConnectListener;
46 | private OnDisconnectListener mOnDisconnectListener;
47 | private OnServiceDiscoverListener mOnServiceDiscoverListener;
48 | private OnDataAvailableListener mOnDataAvailableListener;
49 | private Context mContext;
50 | public void setOnConnectListener(OnConnectListener l){
51 | mOnConnectListener = l;
52 | }
53 | public void setOnDisconnectListener(OnDisconnectListener l){
54 | mOnDisconnectListener = l;
55 | }
56 | public void setOnServiceDiscoverListener(OnServiceDiscoverListener l){
57 | mOnServiceDiscoverListener = l;
58 | }
59 | public void setOnDataAvailableListener(OnDataAvailableListener l){
60 | mOnDataAvailableListener = l;
61 | }
62 |
63 | public BluetoothLeClass(Context c){
64 | mContext = c;
65 | }
66 |
67 | // Implements callback methods for GATT events that the app cares about. For example,
68 | // connection change and services discovered.
69 | private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
70 | @Override
71 | public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
72 | if (newState == BluetoothProfile.STATE_CONNECTED) {
73 | if(mOnConnectListener!=null)
74 | mOnConnectListener.onConnect(gatt);
75 | Log.i(TAG, "Connected to GATT server.");
76 | // Attempts to discover services after successful connection.
77 | Log.i(TAG, "Attempting to start service discovery:" +
78 | mBluetoothGatt.discoverServices());
79 |
80 | } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
81 | if(mOnDisconnectListener!=null)
82 | mOnDisconnectListener.onDisconnect(gatt);
83 | Log.i(TAG, "Disconnected from GATT server.");
84 | }
85 | }
86 |
87 | @Override
88 | public void onServicesDiscovered(BluetoothGatt gatt, int status) {
89 | if (status == BluetoothGatt.GATT_SUCCESS && mOnServiceDiscoverListener!=null) {
90 | mOnServiceDiscoverListener.onServiceDiscover(gatt);
91 | } else {
92 | Log.w(TAG, "onServicesDiscovered received: " + status);
93 | }
94 | }
95 |
96 | @Override
97 | public void onCharacteristicRead(BluetoothGatt gatt,
98 | BluetoothGattCharacteristic characteristic,
99 | int status) {
100 | if (mOnDataAvailableListener!=null)
101 | mOnDataAvailableListener.onCharacteristicRead(gatt, characteristic, status);
102 | }
103 |
104 | @Override
105 | public void onCharacteristicChanged(BluetoothGatt gatt,
106 | BluetoothGattCharacteristic characteristic) {
107 | if (mOnDataAvailableListener!=null)
108 | mOnDataAvailableListener.onCharacteristicWrite(gatt, characteristic);
109 | }
110 | };
111 |
112 | /**
113 | * Initializes a reference to the local Bluetooth adapter.
114 | *
115 | * @return Return true if the initialization is successful.
116 | */
117 | public boolean initialize() {
118 | // For API level 18 and above, get a reference to BluetoothAdapter through
119 | // BluetoothManager.
120 | if (mBluetoothManager == null) {
121 | mBluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
122 | if (mBluetoothManager == null) {
123 | Log.e(TAG, "Unable to initialize BluetoothManager.");
124 | return false;
125 | }
126 | }
127 |
128 | mBluetoothAdapter = mBluetoothManager.getAdapter();
129 | if (mBluetoothAdapter == null) {
130 | Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
131 | return false;
132 | }
133 |
134 | return true;
135 | }
136 |
137 | /**
138 | * Connects to the GATT server hosted on the Bluetooth LE device.
139 | *
140 | * @param address The device address of the destination device.
141 | *
142 | * @return Return true if the connection is initiated successfully. The connection result
143 | * is reported asynchronously through the
144 | * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
145 | * callback.
146 | */
147 | public boolean connect(final String address) {
148 | if (mBluetoothAdapter == null || address == null) {
149 | Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
150 | return false;
151 | }
152 |
153 | // Previously connected device. Try to reconnect.
154 | if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
155 | && mBluetoothGatt != null) {
156 | Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
157 | if (mBluetoothGatt.connect()) {
158 | return true;
159 | } else {
160 | return false;
161 | }
162 | }
163 |
164 | final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
165 | if (device == null) {
166 | Log.w(TAG, "Device not found. Unable to connect.");
167 | return false;
168 | }
169 | // We want to directly connect to the device, so we are setting the autoConnect
170 | // parameter to false.
171 | mBluetoothGatt = device.connectGatt(mContext, false, mGattCallback);
172 | Log.d(TAG, "Trying to create a new connection.");
173 | mBluetoothDeviceAddress = address;
174 | return true;
175 | }
176 |
177 | /**
178 | * Disconnects an existing connection or cancel a pending connection. The disconnection result
179 | * is reported asynchronously through the
180 | * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
181 | * callback.
182 | */
183 | public void disconnect() {
184 | if (mBluetoothAdapter == null || mBluetoothGatt == null) {
185 | Log.w(TAG, "BluetoothAdapter not initialized");
186 | return;
187 | }
188 | mBluetoothGatt.disconnect();
189 | }
190 |
191 | /**
192 | * After using a given BLE device, the app must call this method to ensure resources are
193 | * released properly.
194 | */
195 | public void close() {
196 | if (mBluetoothGatt == null) {
197 | return;
198 | }
199 | mBluetoothGatt.close();
200 | mBluetoothGatt = null;
201 | }
202 |
203 | /**
204 | * Request a read on a given {@code BluetoothGattCharacteristic}. The read result is reported
205 | * asynchronously through the {@code BluetoothGattCallback#onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)}
206 | * callback.
207 | *
208 | * @param characteristic The characteristic to read from.
209 | */
210 | public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
211 | if (mBluetoothAdapter == null || mBluetoothGatt == null) {
212 | Log.w(TAG, "BluetoothAdapter not initialized");
213 | return;
214 | }
215 | mBluetoothGatt.readCharacteristic(characteristic);
216 | }
217 |
218 | /**
219 | * Enables or disables notification on a give characteristic.
220 | *
221 | * @param characteristic Characteristic to act on.
222 | * @param enabled If true, enable notification. False otherwise.
223 | */
224 | public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
225 | boolean enabled) {
226 | if (mBluetoothAdapter == null || mBluetoothGatt == null) {
227 | Log.w(TAG, "BluetoothAdapter not initialized");
228 | return;
229 | }
230 | mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
231 | }
232 |
233 | public void writeCharacteristic(BluetoothGattCharacteristic characteristic){
234 | mBluetoothGatt.writeCharacteristic(characteristic);
235 | }
236 | /**
237 | * Retrieves a list of supported GATT services on the connected device. This should be
238 | * invoked only after {@code BluetoothGatt#discoverServices()} completes successfully.
239 | *
240 | * @return A {@code List} of supported services.
241 | */
242 | public List getSupportedGattServices() {
243 | if (mBluetoothGatt == null) return null;
244 |
245 | return mBluetoothGatt.getServices();
246 | }
247 | }
248 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rocky/btlock/activity/LoginActivity.java:
--------------------------------------------------------------------------------
1 | package com.rocky.btlock.activity;
2 |
3 |
4 | import android.bluetooth.BluetoothAdapter;
5 | import android.bluetooth.BluetoothDevice;
6 | import android.bluetooth.BluetoothGatt;
7 | import android.bluetooth.BluetoothGattCharacteristic;
8 | import android.bluetooth.BluetoothGattDescriptor;
9 | import android.bluetooth.BluetoothGattService;
10 | import android.bluetooth.BluetoothManager;
11 | import android.content.Context;
12 | import android.content.Intent;
13 | import android.content.SharedPreferences;
14 | import android.os.Handler;
15 | import android.support.v7.app.ActionBar;
16 | import android.support.v7.app.AppCompatActivity;
17 |
18 | import android.os.Bundle;
19 |
20 | import android.util.Log;
21 | import android.view.View;
22 | import android.view.View.OnClickListener;
23 | import android.widget.AutoCompleteTextView;
24 | import android.widget.Button;
25 | import android.widget.EditText;
26 | import android.widget.TextView;
27 | import android.widget.Toast;
28 |
29 | import com.rocky.btlock.bluetooth.BluetoothLeClass;
30 | import com.rocky.btlock.R;
31 | import com.rocky.btlock.data.Constant;
32 | import com.rocky.btlock.fragment.FragmentUsers;
33 | import com.rocky.btlock.utils.Utils;
34 |
35 | import java.util.List;
36 |
37 | import me.drakeet.materialdialog.MaterialDialog;
38 |
39 | /**
40 | * 登陆
41 | */
42 | public class LoginActivity extends AppCompatActivity {
43 | private TextView testText;
44 | private Button checkAddress;
45 | private MaterialDialog materialDialog;
46 | private static Handler mHandler = new Handler();
47 |
48 | @Override
49 | protected void onCreate(Bundle savedInstanceState) {
50 | super.onCreate(savedInstanceState);
51 | setContentView(R.layout.activity_login);
52 | instance = this;
53 | //初始化登陆界面
54 | testText = (TextView) findViewById(R.id.show);
55 | nameView = (AutoCompleteTextView) findViewById(R.id.user_name);
56 | mPasswordView = (EditText) findViewById(R.id.password);
57 | Button mLogInButton = (Button) findViewById(R.id.login_button);
58 | mReg = (Button) findViewById(R.id.login_register);
59 | checkAddress = (Button) findViewById(R.id.checkBlueadress);
60 | mActionbar = getSupportActionBar();
61 | mActionbar.setSubtitle("尚未连接设备");
62 | //蓝牙相关
63 | final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
64 | mBluetoothAdapter = bluetoothManager.getAdapter();
65 | Log.i(TAG, "mBluetoothAdapter = " + mBluetoothAdapter);
66 | //打开蓝牙
67 | mBluetoothAdapter.enable();
68 | mActionbar.setSubtitle("蓝牙已打开");
69 | myBleAddress = mBluetoothAdapter.getAddress();
70 | //底层说并没有给冒号安排存储空间,把冒号去掉=-=
71 | myBleAddress = myBleAddress.replaceAll(":", "");
72 | mBLE = new BluetoothLeClass(this);
73 | if (!mBLE.initialize()) {
74 | Log.e(TAG, "Unable to initialize Bluetooth");
75 | finish();
76 | }
77 | Log.i(TAG, "mBLE = e" + mBLE);
78 | mActionbar.setSubtitle("正在寻找智能锁设备...");
79 | // 发现BLE终端的Service时回调事件
80 | mBLE.setOnServiceDiscoverListener(mServiceDiscover);
81 |
82 | // 收到BLE终端数据交互的事件
83 | mBLE.setOnDataAvailableListener(mOnDataAvailable);
84 | final String str = Utils.toHexString("root");
85 |
86 | mReg.setOnClickListener(new OnClickListener() {
87 | @Override
88 | public void onClick(View v) {
89 | attemptLogin();
90 | SharedPreferences sp = instance.getSharedPreferences("SP", MODE_PRIVATE);
91 | //存入数据
92 | // SharedPreferences.Editor editor = sp.edit();
93 | // editor.putString(1 + "", nameView.getText().toString() + 0);
94 | // editor.putInt("id", 1);
95 | // editor.commit();
96 | String reg = Utils.toHexString(nameView.getText().toString() + mPasswordView.getText().toString());
97 | writeChar(Utils.hexStringToBytes(Constant.HEAD_CHAR + "0f" + Constant.CREAT_ADMIN + Constant.SEVER_BLUETOOTH + reg + Constant.END_CHAR));
98 |
99 | }
100 | });
101 |
102 | mLogInButton.setOnClickListener(new OnClickListener() {
103 | @Override
104 | public void onClick(View v) {
105 | attemptLogin();
106 | login();
107 | }
108 | });
109 |
110 | checkAddress.setOnClickListener(new OnClickListener() {
111 | @Override
112 | public void onClick(View v) {
113 | // checkAddress.setText("AA0b");
114 | writeChar(Utils.hexStringToBytes(Constant.HEAD_CHAR + "0b" + Constant.SEND_ADDRESS + Constant.SEVER_BLUETOOTH + myBleAddress + Constant.END_CHAR));
115 | Toast.makeText(getApplicationContext(), "蓝牙地址发送成功", Toast.LENGTH_SHORT).show();
116 | }
117 | });
118 |
119 | }
120 |
121 | //登录验证
122 | private void login() {
123 | if (checkFormat) {
124 | String str = Utils.toHexString(nameView.getText().toString() + mPasswordView.getText().toString());
125 |
126 | writeChar(Utils.hexStringToBytes(Constant.HEAD_CHAR + "0f" + Constant.LOGIN + Constant.SEVER_BLUETOOTH + str + Constant.END_CHAR));
127 | }
128 | }
129 |
130 | /**
131 | * 登录验证
132 | */
133 | private void attemptLogin() {
134 | nameView.setError(null);
135 | mPasswordView.setError(null);
136 | //获取用户输入值
137 | String name = nameView.getText().toString();
138 | String password = mPasswordView.getText().toString();
139 | //检查密码有效性
140 | if (name.length() != 4) {
141 | if (name.length() == 0) {
142 | nameView.setError("请输入用户名");
143 | } else {
144 | nameView.setError("用户名为四位哦~");
145 | }
146 | } else if (password.length() != 6 || password.isEmpty()) {
147 | mPasswordView.setError("Tips:六位密码");
148 | } else {
149 | checkFormat = true;
150 | }
151 |
152 | }
153 |
154 | //弹窗提示
155 | public void makeDialog(final String str) {
156 | mHandler.post(new Runnable() {
157 | @Override
158 | public void run() {
159 | materialDialog = new MaterialDialog(LoginActivity.instance)
160 | .setTitle("提示")
161 | .setMessage(str)
162 | .setPositiveButton("确认", new View.OnClickListener() {
163 | @Override
164 | public void onClick(View v) {
165 | materialDialog.dismiss();
166 |
167 | }
168 | });
169 | materialDialog.show();
170 | }
171 | });
172 |
173 | }
174 |
175 |
176 | private BluetoothLeClass.OnServiceDiscoverListener mServiceDiscover = new BluetoothLeClass.OnServiceDiscoverListener() {
177 | @Override
178 | public void onServiceDiscover(BluetoothGatt gatt) {
179 | displayGattServices(mBLE.getSupportedGattServices());
180 | }
181 | };
182 |
183 | private BluetoothLeClass.OnDataAvailableListener mOnDataAvailable = new BluetoothLeClass.OnDataAvailableListener() {
184 | /**
185 | * BLE终端数据被读的事件
186 | */
187 | @Override
188 | public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
189 | Log.e(TAG,
190 | "onCharRead " + gatt.getDevice().getName() + " read "
191 | + characteristic.getUuid().toString() + " -> "
192 | + Utils.bytesToHexString(characteristic.getValue()));
193 | }
194 |
195 | /**
196 | * 收到BLE终端写入数据回调
197 | */
198 | @Override
199 | public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
200 | // Log.e(TAG, "onCharWrite " + gatt.getDevice().getName() + " write "
201 | // + characteristic.getUuid().toString() + " -> "
202 | // + new String(characteristic.getValue()));
203 | String str = Utils.bytesToHexString(characteristic.getValue());
204 | Log.e(TAG, "+++++++++++++++++++++" + str);
205 | //管理员登录成功指令
206 | // String str2 = "aa0406020d";
207 | // Log.e(TAG, "+++++++++++++++++++++" + str2);
208 | Intent in = new Intent(LoginActivity.this, MainActivity.class);
209 | switch (str) {
210 | case Constant.NO_BLUE_ADDRESS:
211 | makeDialog("请先验证蓝牙地址");
212 | break;
213 | //创建管理员账号成功
214 | case Constant.CREAT_ADMIN_CALLBACK_SUCCESS:
215 | makeDialog("管理员账号创建成功");
216 | break;
217 | //创建管理员账号失败
218 | case Constant.CREAT_ADMIN_CALLBACK_FAIL:
219 | makeDialog("管理员账号创建失败");
220 | break;
221 | //管理员登陆成功
222 | case Constant.LOGIN_ADMIN_SUCCESS:
223 | Log.e(TAG, "++++++++++++++++++++admin login");
224 | in.putExtra("isAdmin", true);
225 | in.putExtra("UserName", nameView.getText().toString());
226 | startActivity(in);
227 | break;
228 | //普通用户登录成功
229 | case Constant.LOGIN_USER_SUCCESS:
230 | Log.e(TAG, "++++++++++++++++++++admin login");
231 | in.putExtra("isAdmin", false);
232 | in.putExtra("UserName", nameView.getText().toString());
233 | startActivity(in);
234 | break;
235 | //用户登录失败
236 | case Constant.LOGIN_FAIL:
237 | makeDialog("登录失败,请重试");
238 | break;
239 | //开锁成功
240 | case Constant.OPEN_LOCK_SUCCESS:
241 | MainActivity.setOpen();
242 | break;
243 | //记录发送完毕
244 | case Constant.RECORE_END:
245 | RecordActivity.addEnd();
246 | break;
247 | //修改触摸屏密码成功
248 | case Constant.CHANGE_PASSWORD_SUCCESS:
249 | SettingActivity.chagneSuccess();
250 | break;
251 | //新增用户成功
252 | case Constant.ADD_USERS_SUCCESS:
253 | FragmentUsers.setDialog("新增用户成功");
254 | break;
255 | //删除用户成功
256 | case Constant.DEL_USER_SUCCESS:
257 | FragmentUsers.setDialog("删除用户成功");
258 | break;
259 | //新增用户失败
260 | case Constant.ADD_USE_FAIL:
261 | FragmentUsers.setDialog("该用户名已被占用");
262 | break;
263 | //添加指纹失败
264 | case Constant.ADD_FINGER_FAIL:
265 | FragmentUsers.addFingerFail();
266 | break;
267 | //时间
268 | case Constant.TIME_SUCESS:
269 | SettingActivity.sendTimeSuccess();
270 | break;
271 | //管理员
272 | case Constant.ADMIN_DEL_FAIL:
273 | FragmentUsers.setDialog("管理员用户不可删");
274 | break;
275 |
276 | }
277 | //添加存储记录
278 | if (str.charAt(4) == '0' && str.charAt(5) == 'c') {
279 | RecordActivity.addData(1, str);
280 | Log.e(TAG, "+++++++++++++++++++" + str);
281 | }
282 | //添加用户信息
283 | if (str.charAt(4) == '2' && str.charAt(5) == '0') {
284 | // int id = Utils.charToInt(str.charAt(8)) * 16 + Utils.charToInt(str.charAt(9));
285 | String str_name = Utils.hexToString(str.substring(8, 16));
286 | boolean b = false;
287 | if (str.charAt(17) == '1') {
288 | b = true;
289 | }
290 | FragmentUsers.addData(1, str_name, b);
291 | Log.e(TAG, "+++++++++++++++++++" + str);
292 | }
293 | //添加指纹成功
294 | if (str.charAt(4) == '1' && str.charAt(5) == '6') {
295 | FragmentUsers.addFingerSuccess(Utils.hexToString(str.substring(8, 16)));
296 | Log.e(TAG, "+++++++++++++++++++" + str);
297 | }
298 |
299 | }
300 | };
301 |
302 | public static void writeChar(byte[] bytes) {
303 | Log.i(TAG, "Message = " + bytes);
304 | if (gattCharacteristic_char != null) {
305 | gattCharacteristic_char.setValue(bytes);
306 | mBLE.writeCharacteristic(gattCharacteristic_char);
307 | }
308 | }
309 |
310 | //搜索设备
311 | private void scanLeDevice(final boolean enable) {
312 | if (enable) {
313 | mScanning = true;
314 | mBluetoothAdapter.startLeScan(mLeScanCallback);
315 | } else {
316 | mScanning = false;
317 | mBluetoothAdapter.stopLeScan(mLeScanCallback);
318 | }
319 | }
320 |
321 | // 设备搜索结果
322 | private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
323 |
324 | @Override
325 | public void onLeScan(final BluetoothDevice device, int rssi,
326 | byte[] scanRecord) {
327 |
328 | runOnUiThread(new Runnable() {
329 | @Override
330 | public void run() {
331 | //5F:52:CC:7F:86:55
332 | //20:91:48:50:5C:8E
333 | //D4:F5:13:78:E9:63
334 | //20:91:48:50:58:DE
335 | if (device.getAddress().equals("20:91:48:50:58:DE")) {
336 | scanLeDevice(false);
337 | Log.e(TAG, device.getAddress());
338 | Log.e(TAG, device.getName());
339 | boolean bRet = mBLE.connect(device.getAddress());
340 | try {
341 | Thread.sleep(2000);
342 | } catch (InterruptedException e) {
343 | e.printStackTrace();
344 | }
345 | if (bRet) {
346 | mActionbar.setSubtitle("已连接,请登录");
347 | Log.e(TAG, "connect+++++success");
348 | Log.e(TAG, Constant.HEAD_CHAR + "0B" + Constant.SEND_ADDRESS + Constant.SEVER_BLUETOOTH + myBleAddress + Constant.END_CHAR);
349 | }
350 |
351 | }
352 |
353 | }
354 | });
355 | // rssi
356 | Log.i(TAG, "rssi = " + rssi);
357 | Log.i(TAG, "mac = " + device.getAddress());
358 | Log.i(TAG, "scanRecord.length = " + scanRecord.length);
359 | }
360 |
361 | };
362 |
363 | @Override
364 | protected void onResume() {
365 | Log.i(TAG, "---> onResume");
366 | super.onResume();
367 | mBLE.close();
368 | scanLeDevice(true);
369 | }
370 |
371 | @Override
372 | protected void onPause() {
373 | Log.i(TAG, "---> onPause");
374 | super.onPause();
375 | }
376 |
377 | @Override
378 | protected void onStop() {
379 | Log.i(TAG, "---> onStop");
380 | super.onStop();
381 | }
382 |
383 | @Override
384 | protected void onDestroy() {
385 | Log.i(TAG, "---> onDestroy");
386 | super.onDestroy();
387 | Log.e(TAG, "start onDestroy~~~");
388 | scanLeDevice(false);
389 | mBLE.disconnect();
390 | mBLE.close();
391 | }
392 |
393 | private void displayGattServices(List gattServices) {
394 | if (gattServices == null)
395 | return;
396 | BluetoothGattCharacteristic Characteristic_cur = null;
397 |
398 | for (BluetoothGattService gattService : gattServices) {
399 | // -----Service的字段信息----//
400 | int type = gattService.getType();
401 | Log.e(TAG, "-->service type:" + Utils.getServiceType(type));
402 | Log.e(TAG, "-->includedServices size:"
403 | + gattService.getIncludedServices().size());
404 | Log.e(TAG, "-->service uuid:" + gattService.getUuid());
405 |
406 | // -----Characteristics的字段信息----//
407 | List gattCharacteristics = gattService
408 | .getCharacteristics();
409 | for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
410 | Log.e(TAG, "---->char uuid:" + gattCharacteristic.getUuid());
411 |
412 | int permission = gattCharacteristic.getPermissions();
413 | Log.e(TAG,
414 | "---->char permission:"
415 | + Utils.getCharPermission(permission));
416 |
417 | int property = gattCharacteristic.getProperties();
418 | Log.e(TAG,
419 | "---->char property:"
420 | + Utils.getCharPropertie(property));
421 |
422 | byte[] data = gattCharacteristic.getValue();
423 | if (data != null && data.length > 0) {
424 | Log.e(TAG, "---->char value:" + new String(data));
425 | }
426 |
427 | if (gattCharacteristic.getUuid().toString().equals(UUID_CHAR6)) {
428 | // 把char1 保存起来以方便后面读写数据时使用
429 | gattCharacteristic_char = gattCharacteristic;
430 | Characteristic_cur = gattCharacteristic;
431 | mBLE.setCharacteristicNotification(gattCharacteristic, true);
432 | Log.i(TAG, "+++++++++UUID_CHAR");
433 | }
434 |
435 | if (gattCharacteristic.getUuid().toString()
436 | .equals(UUID_HERATRATE)) {
437 | // 把heartrate 保存起来以方便后面读写数据时使用
438 | gattCharacteristic_heartrate = gattCharacteristic;
439 | Characteristic_cur = gattCharacteristic;
440 | mBLE.setCharacteristicNotification(gattCharacteristic, true);
441 | Log.i(TAG, "+++++++++UUID_HERATRATE");
442 | }
443 |
444 | if (gattCharacteristic.getUuid().toString()
445 | .equals(UUID_KEY_DATA)) {
446 | // 把heartrate 保存起来以方便后面读写数据时使用
447 | gattCharacteristic_keydata = gattCharacteristic;
448 | Characteristic_cur = gattCharacteristic;
449 | mBLE.setCharacteristicNotification(gattCharacteristic, true);
450 | Log.i(TAG, "+++++++++UUID_KEY_DATA");
451 | }
452 |
453 | if (gattCharacteristic.getUuid().toString()
454 | .equals(UUID_TEMPERATURE)) {
455 | // 把heartrate 保存起来以方便后面读写数据时使用
456 | gattCharacteristic_temperature = gattCharacteristic;
457 | Characteristic_cur = gattCharacteristic;
458 | mBLE.setCharacteristicNotification(gattCharacteristic, true);
459 | Log.i(TAG, "+++++++++UUID_TEMPERATURE");
460 | }
461 |
462 | // -----Descriptors的字段信息----//
463 | List gattDescriptors = gattCharacteristic
464 | .getDescriptors();
465 | for (BluetoothGattDescriptor gattDescriptor : gattDescriptors) {
466 | Log.e(TAG, "-------->desc uuid:" + gattDescriptor.getUuid());
467 | int descPermission = gattDescriptor.getPermissions();
468 | Log.e(TAG,
469 | "-------->desc permission:"
470 | + Utils.getDescPermission(descPermission));
471 |
472 | byte[] desData = gattDescriptor.getValue();
473 | if (desData != null && desData.length > 0) {
474 | Log.e(TAG, "-------->desc value:" + new String(desData));
475 | }
476 | }
477 | }
478 | }//
479 |
480 | }
481 |
482 |
483 | public static LoginActivity instance = null;
484 | private static final String TAG = "LoginAvtivity";
485 | private static String myBleAddress;
486 | // UI
487 | private AutoCompleteTextView nameView;
488 | private EditText mPasswordView;
489 | private boolean checkFormat = false;
490 | private boolean checkResult = false;
491 | private ActionBar mActionbar;
492 | private Button mReg;
493 |
494 | //初始化变量
495 | public static String UUID_KEY_DATA = "0000ffe1-0000-1000-8000-00805f9b34fb";
496 | public static String UUID_CHAR6 = "0000fff6-0000-1000-8000-00805f9b34fb";
497 | public static String UUID_HERATRATE = "00002a37-0000-1000-8000-00805f9b34fb";
498 | public static String UUID_TEMPERATURE = "00002a1c-0000-1000-8000-00805f9b34fb";
499 |
500 | static BluetoothGattCharacteristic gattCharacteristic_char1 = null;
501 | static BluetoothGattCharacteristic gattCharacteristic_char = null;
502 | static BluetoothGattCharacteristic gattCharacteristic_heartrate = null;
503 | static BluetoothGattCharacteristic gattCharacteristic_keydata = null;
504 | static BluetoothGattCharacteristic gattCharacteristic_temperature = null;
505 | ;
506 | // 搜索BLE终端
507 | private BluetoothAdapter mBluetoothAdapter;
508 | // 读写BLE终端
509 | static private BluetoothLeClass mBLE;
510 | public String bluetoothAddress;
511 | static private byte writeValue_char1 = 0;
512 | private boolean mScanning;
513 | private int mRssi;
514 |
515 | }
516 |
517 |
--------------------------------------------------------------------------------