Commit d7ceb85c695d5a5c476077bd8d0c7d23b6a3196e
0 parents
小家音箱初始化
Showing
86 changed files
with
4505 additions
and
0 deletions
Too many changes to show.
To preserve performance only 86 of 266 files are displayed.
.gitignore
0 → 100644
.idea/codeStyles/Project.xml
0 → 100644
| 1 | +++ a/.idea/codeStyles/Project.xml | |
| 1 | +<component name="ProjectCodeStyleConfiguration"> | |
| 2 | + <code_scheme name="Project" version="173"> | |
| 3 | + <Objective-C-extensions> | |
| 4 | + <file> | |
| 5 | + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" /> | |
| 6 | + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" /> | |
| 7 | + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" /> | |
| 8 | + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" /> | |
| 9 | + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" /> | |
| 10 | + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" /> | |
| 11 | + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" /> | |
| 12 | + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" /> | |
| 13 | + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" /> | |
| 14 | + </file> | |
| 15 | + <class> | |
| 16 | + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" /> | |
| 17 | + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" /> | |
| 18 | + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" /> | |
| 19 | + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" /> | |
| 20 | + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" /> | |
| 21 | + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" /> | |
| 22 | + </class> | |
| 23 | + <extensions> | |
| 24 | + <pair source="cpp" header="h" fileNamingConvention="NONE" /> | |
| 25 | + <pair source="c" header="h" fileNamingConvention="NONE" /> | |
| 26 | + </extensions> | |
| 27 | + </Objective-C-extensions> | |
| 28 | + <codeStyleSettings language="XML"> | |
| 29 | + <arrangement> | |
| 30 | + <rules> | |
| 31 | + <section> | |
| 32 | + <rule> | |
| 33 | + <match> | |
| 34 | + <AND> | |
| 35 | + <NAME>xmlns:android</NAME> | |
| 36 | + <XML_ATTRIBUTE /> | |
| 37 | + <XML_NAMESPACE>^$</XML_NAMESPACE> | |
| 38 | + </AND> | |
| 39 | + </match> | |
| 40 | + </rule> | |
| 41 | + </section> | |
| 42 | + <section> | |
| 43 | + <rule> | |
| 44 | + <match> | |
| 45 | + <AND> | |
| 46 | + <NAME>xmlns:.*</NAME> | |
| 47 | + <XML_ATTRIBUTE /> | |
| 48 | + <XML_NAMESPACE>^$</XML_NAMESPACE> | |
| 49 | + </AND> | |
| 50 | + </match> | |
| 51 | + <order>BY_NAME</order> | |
| 52 | + </rule> | |
| 53 | + </section> | |
| 54 | + <section> | |
| 55 | + <rule> | |
| 56 | + <match> | |
| 57 | + <AND> | |
| 58 | + <NAME>.*:id</NAME> | |
| 59 | + <XML_ATTRIBUTE /> | |
| 60 | + <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | |
| 61 | + </AND> | |
| 62 | + </match> | |
| 63 | + </rule> | |
| 64 | + </section> | |
| 65 | + <section> | |
| 66 | + <rule> | |
| 67 | + <match> | |
| 68 | + <AND> | |
| 69 | + <NAME>.*:name</NAME> | |
| 70 | + <XML_ATTRIBUTE /> | |
| 71 | + <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | |
| 72 | + </AND> | |
| 73 | + </match> | |
| 74 | + </rule> | |
| 75 | + </section> | |
| 76 | + <section> | |
| 77 | + <rule> | |
| 78 | + <match> | |
| 79 | + <AND> | |
| 80 | + <NAME>name</NAME> | |
| 81 | + <XML_ATTRIBUTE /> | |
| 82 | + <XML_NAMESPACE>^$</XML_NAMESPACE> | |
| 83 | + </AND> | |
| 84 | + </match> | |
| 85 | + </rule> | |
| 86 | + </section> | |
| 87 | + <section> | |
| 88 | + <rule> | |
| 89 | + <match> | |
| 90 | + <AND> | |
| 91 | + <NAME>style</NAME> | |
| 92 | + <XML_ATTRIBUTE /> | |
| 93 | + <XML_NAMESPACE>^$</XML_NAMESPACE> | |
| 94 | + </AND> | |
| 95 | + </match> | |
| 96 | + </rule> | |
| 97 | + </section> | |
| 98 | + <section> | |
| 99 | + <rule> | |
| 100 | + <match> | |
| 101 | + <AND> | |
| 102 | + <NAME>.*</NAME> | |
| 103 | + <XML_ATTRIBUTE /> | |
| 104 | + <XML_NAMESPACE>^$</XML_NAMESPACE> | |
| 105 | + </AND> | |
| 106 | + </match> | |
| 107 | + <order>BY_NAME</order> | |
| 108 | + </rule> | |
| 109 | + </section> | |
| 110 | + <section> | |
| 111 | + <rule> | |
| 112 | + <match> | |
| 113 | + <AND> | |
| 114 | + <NAME>.*</NAME> | |
| 115 | + <XML_ATTRIBUTE /> | |
| 116 | + <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | |
| 117 | + </AND> | |
| 118 | + </match> | |
| 119 | + <order>ANDROID_ATTRIBUTE_ORDER</order> | |
| 120 | + </rule> | |
| 121 | + </section> | |
| 122 | + <section> | |
| 123 | + <rule> | |
| 124 | + <match> | |
| 125 | + <AND> | |
| 126 | + <NAME>.*</NAME> | |
| 127 | + <XML_ATTRIBUTE /> | |
| 128 | + <XML_NAMESPACE>.*</XML_NAMESPACE> | |
| 129 | + </AND> | |
| 130 | + </match> | |
| 131 | + <order>BY_NAME</order> | |
| 132 | + </rule> | |
| 133 | + </section> | |
| 134 | + </rules> | |
| 135 | + </arrangement> | |
| 136 | + </codeStyleSettings> | |
| 137 | + </code_scheme> | |
| 138 | +</component> | |
| 0 | 139 | \ No newline at end of file | ... | ... |
.idea/gradle.xml
0 → 100644
| 1 | +++ a/.idea/gradle.xml | |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<project version="4"> | |
| 3 | + <component name="GradleSettings"> | |
| 4 | + <option name="linkedExternalProjectsSettings"> | |
| 5 | + <GradleProjectSettings> | |
| 6 | + <compositeConfiguration> | |
| 7 | + <compositeBuild compositeDefinitionSource="SCRIPT" /> | |
| 8 | + </compositeConfiguration> | |
| 9 | + <option name="distributionType" value="DEFAULT_WRAPPED" /> | |
| 10 | + <option name="externalProjectPath" value="$PROJECT_DIR$" /> | |
| 11 | + <option name="resolveModulePerSourceSet" value="false" /> | |
| 12 | + <option name="testRunner" value="PLATFORM" /> | |
| 13 | + </GradleProjectSettings> | |
| 14 | + </option> | |
| 15 | + </component> | |
| 16 | +</project> | |
| 0 | 17 | \ No newline at end of file | ... | ... |
.idea/inspectionProfiles/Project_Default.xml
0 → 100644
| 1 | +++ a/.idea/inspectionProfiles/Project_Default.xml | |
| 1 | +<component name="InspectionProjectProfileManager"> | |
| 2 | + <profile version="1.0"> | |
| 3 | + <option name="myName" value="Project Default" /> | |
| 4 | + <inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true"> | |
| 5 | + <option name="TOP_LEVEL_CLASS_OPTIONS"> | |
| 6 | + <value> | |
| 7 | + <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> | |
| 8 | + <option name="REQUIRED_TAGS" value="" /> | |
| 9 | + </value> | |
| 10 | + </option> | |
| 11 | + <option name="INNER_CLASS_OPTIONS"> | |
| 12 | + <value> | |
| 13 | + <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> | |
| 14 | + <option name="REQUIRED_TAGS" value="" /> | |
| 15 | + </value> | |
| 16 | + </option> | |
| 17 | + <option name="METHOD_OPTIONS"> | |
| 18 | + <value> | |
| 19 | + <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> | |
| 20 | + <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" /> | |
| 21 | + </value> | |
| 22 | + </option> | |
| 23 | + <option name="FIELD_OPTIONS"> | |
| 24 | + <value> | |
| 25 | + <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> | |
| 26 | + <option name="REQUIRED_TAGS" value="" /> | |
| 27 | + </value> | |
| 28 | + </option> | |
| 29 | + <option name="IGNORE_DEPRECATED" value="false" /> | |
| 30 | + <option name="IGNORE_JAVADOC_PERIOD" value="true" /> | |
| 31 | + <option name="IGNORE_DUPLICATED_THROWS" value="false" /> | |
| 32 | + <option name="IGNORE_POINT_TO_ITSELF" value="false" /> | |
| 33 | + <option name="myAdditionalJavadocTags" value="date" /> | |
| 34 | + </inspection_tool> | |
| 35 | + </profile> | |
| 36 | +</component> | |
| 0 | 37 | \ No newline at end of file | ... | ... |
.idea/misc.xml
0 → 100644
| 1 | +++ a/.idea/misc.xml | |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<project version="4"> | |
| 3 | + <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK"> | |
| 4 | + <output url="file://$PROJECT_DIR$/build/classes" /> | |
| 5 | + </component> | |
| 6 | + <component name="ProjectType"> | |
| 7 | + <option name="id" value="Android" /> | |
| 8 | + </component> | |
| 9 | +</project> | |
| 0 | 10 | \ No newline at end of file | ... | ... |
.idea/runConfigurations.xml
0 → 100644
| 1 | +++ a/.idea/runConfigurations.xml | |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<project version="4"> | |
| 3 | + <component name="RunConfigurationProducerService"> | |
| 4 | + <option name="ignoredProducers"> | |
| 5 | + <set> | |
| 6 | + <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" /> | |
| 7 | + <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" /> | |
| 8 | + <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" /> | |
| 9 | + </set> | |
| 10 | + </option> | |
| 11 | + </component> | |
| 12 | +</project> | |
| 0 | 13 | \ No newline at end of file | ... | ... |
.idea/vcs.xml
0 → 100644
app/.gitignore
0 → 100644
app/build.gradle
0 → 100644
| 1 | +++ a/app/build.gradle | |
| 1 | +apply plugin: 'com.android.application' | |
| 2 | + | |
| 3 | +android { | |
| 4 | + compileSdkVersion 28 | |
| 5 | + defaultConfig { | |
| 6 | + applicationId "com.cnlive.strike.xiaojiaspeaker" | |
| 7 | + minSdkVersion 18 | |
| 8 | + targetSdkVersion 28 | |
| 9 | + versionCode 1 | |
| 10 | + versionName "1.0" | |
| 11 | + testInstrumentationRunner "android.test.runner.AndroidJUnitRunner" | |
| 12 | + } | |
| 13 | + buildTypes { | |
| 14 | + release { | |
| 15 | + minifyEnabled false | |
| 16 | + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | |
| 17 | + } | |
| 18 | + } | |
| 19 | + dataBinding { | |
| 20 | + enabled = true | |
| 21 | + } | |
| 22 | + compileOptions { | |
| 23 | + sourceCompatibility = 1.8 | |
| 24 | + targetCompatibility = 1.8 | |
| 25 | + } | |
| 26 | + buildToolsVersion = '29.0.2' | |
| 27 | +} | |
| 28 | + | |
| 29 | +dependencies { | |
| 30 | + implementation fileTree(dir: 'libs', include: ['*.jar']) | |
| 31 | + testImplementation 'junit:junit:4.12' | |
| 32 | + compile project(path: ':module_xiaojiaspeaker') | |
| 33 | + implementation "com.android.support:support-v4:$rootProject.supportV4" | |
| 34 | + implementation "com.android.support:appcompat-v7:$rootProject.appcompatV7" | |
| 35 | + implementation "com.android.support:design:$rootProject.design" | |
| 36 | + implementation "com.android.support:support-v13:$rootProject.supportV13" | |
| 37 | + implementation "com.android.support:recyclerview-v7:$rootProject.recyclerviewV7" | |
| 38 | + implementation "com.cnlive:app_arch:$rootProject.appArch" | |
| 39 | + implementation "com.qmuiteam:qmui:$rootProject.qmui" | |
| 40 | + implementation "com.cnlive.libs:base:$rootProject.libBase" | |
| 41 | +} | ... | ... |
app/proguard-rules.pro
0 → 100644
| 1 | +++ a/app/proguard-rules.pro | |
| 1 | +# Add project specific ProGuard rules here. | |
| 2 | +# You can control the set of applied configuration files using the | |
| 3 | +# proguardFiles setting in build.gradle. | |
| 4 | +# | |
| 5 | +# For more details, see | |
| 6 | +# http://developer.android.com/guide/developing/tools/proguard.html | |
| 7 | + | |
| 8 | +# If your project uses WebView with JS, uncomment the following | |
| 9 | +# and specify the fully qualified class name to the JavaScript interface | |
| 10 | +# class: | |
| 11 | +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | |
| 12 | +# public *; | |
| 13 | +#} | |
| 14 | + | |
| 15 | +# Uncomment this to preserve the line number information for | |
| 16 | +# debugging stack traces. | |
| 17 | +#-keepattributes SourceFile,LineNumberTable | |
| 18 | + | |
| 19 | +# If you keep the line number information, uncomment this to | |
| 20 | +# hide the original source file name. | |
| 21 | +#-renamesourcefileattribute SourceFile | ... | ... |
app/src/androidTest/java/com/cnlive/strike/xiaojiaspeaker/ExampleInstrumentedTest.java
0 → 100644
| 1 | +++ a/app/src/androidTest/java/com/cnlive/strike/xiaojiaspeaker/ExampleInstrumentedTest.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker; | |
| 2 | + | |
| 3 | +import android.content.Context; | |
| 4 | + | |
| 5 | +import androidx.test.platform.app.InstrumentationRegistry; | |
| 6 | +import androidx.test.ext.junit.runners.AndroidJUnit4; | |
| 7 | + | |
| 8 | +import org.junit.Test; | |
| 9 | +import org.junit.runner.RunWith; | |
| 10 | + | |
| 11 | +import static org.junit.Assert.*; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * Instrumented test, which will execute on an Android device. | |
| 15 | + * | |
| 16 | + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> | |
| 17 | + */ | |
| 18 | +@RunWith(AndroidJUnit4.class) | |
| 19 | +public class ExampleInstrumentedTest { | |
| 20 | + @Test | |
| 21 | + public void useAppContext() { | |
| 22 | + // Context of the app under test. | |
| 23 | + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); | |
| 24 | + | |
| 25 | + assertEquals("com.cnlive.strike.xiaojiaspeaker", appContext.getPackageName()); | |
| 26 | + } | |
| 27 | +} | ... | ... |
app/src/main/AndroidManifest.xml
0 → 100644
| 1 | +++ a/app/src/main/AndroidManifest.xml | |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
| 3 | + package="com.cnlive.strike.speaker"> | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + <application | |
| 8 | + android:allowBackup="true" | |
| 9 | + android:icon="@mipmap/ic_launcher" | |
| 10 | + android:label="@string/app_name" | |
| 11 | + android:roundIcon="@mipmap/ic_launcher_round" | |
| 12 | + android:supportsRtl="true" | |
| 13 | + android:theme="@style/AppTheme"> | |
| 14 | + <activity android:name="com.cnlive.strike.xiaojiaspeaker.MainActivity"> | |
| 15 | + <intent-filter> | |
| 16 | + <action android:name="android.intent.action.MAIN" /> | |
| 17 | + | |
| 18 | + <category android:name="android.intent.category.LAUNCHER" /> | |
| 19 | + </intent-filter> | |
| 20 | + </activity> | |
| 21 | + </application> | |
| 22 | + | |
| 23 | +</manifest> | |
| 0 | 24 | \ No newline at end of file | ... | ... |
app/src/main/java/com/cnlive/strike/xiaojiaspeaker/MainActivity.java
0 → 100644
| 1 | +++ a/app/src/main/java/com/cnlive/strike/xiaojiaspeaker/MainActivity.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker; | |
| 2 | + | |
| 3 | + | |
| 4 | +import android.content.Intent; | |
| 5 | +import android.os.Bundle; | |
| 6 | +import android.support.v7.app.AppCompatActivity; | |
| 7 | + | |
| 8 | +import com.cnlive.strike.xiaojiaspeaker.ui.activity.BlueToothStep1Activity; | |
| 9 | +import com.cnlive.strike.xiaojiaspeaker.ui.activity.BluetoothConnActivity; | |
| 10 | +import com.cnlive.strike.xiaojiaspeaker.ui.activity.SearchDeviceActivity; | |
| 11 | +import com.cnlive.strike.xiaojiaspeaker.ui.activity.SpeakerMainActivity; | |
| 12 | + | |
| 13 | +public class MainActivity extends AppCompatActivity { | |
| 14 | + private static final String TAG = "MainActivity"; | |
| 15 | + | |
| 16 | + @Override | |
| 17 | + protected void onCreate(Bundle savedInstanceState) { | |
| 18 | + super.onCreate(savedInstanceState); | |
| 19 | + setContentView(R.layout.activity_speaker_main); | |
| 20 | +// startActivity(new Intent(MainActivity.this, SpeakerMainActivity.class)); | |
| 21 | +// startActivity(new Intent(MainActivity.this, BluetoothConnActivity.class)); | |
| 22 | + startActivity(new Intent(MainActivity.this, BlueToothStep1Activity.class)); | |
| 23 | + | |
| 24 | + | |
| 25 | + finish(); | |
| 26 | + } | |
| 27 | + | |
| 28 | +} | ... | ... |
app/src/main/java/com/cnlive/strike/xiaojiaspeaker/MyApp.java
0 → 100644
app/src/main/res/drawable-hdpi/wifi1.png
0 → 100644
987 Bytes
app/src/main/res/drawable-hdpi/wifi2.png
0 → 100644
977 Bytes
app/src/main/res/drawable-hdpi/wifi3.png
0 → 100644
924 Bytes
app/src/main/res/drawable-hdpi/wifi4.png
0 → 100644
873 Bytes
app/src/main/res/drawable-v24/ic_launcher_foreground.xml
0 → 100644
| 1 | +++ a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml | |
| 1 | +<vector xmlns:android="http://schemas.android.com/apk/res/android" | |
| 2 | + xmlns:aapt="http://schemas.android.com/aapt" | |
| 3 | + android:width="108dp" | |
| 4 | + android:height="108dp" | |
| 5 | + android:viewportWidth="108" | |
| 6 | + android:viewportHeight="108"> | |
| 7 | + <path | |
| 8 | + android:fillType="evenOdd" | |
| 9 | + android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z" | |
| 10 | + android:strokeWidth="1" | |
| 11 | + android:strokeColor="#00000000"> | |
| 12 | + <aapt:attr name="android:fillColor"> | |
| 13 | + <gradient | |
| 14 | + android:endX="78.5885" | |
| 15 | + android:endY="90.9159" | |
| 16 | + android:startX="48.7653" | |
| 17 | + android:startY="61.0927" | |
| 18 | + android:type="linear"> | |
| 19 | + <item | |
| 20 | + android:color="#44000000" | |
| 21 | + android:offset="0.0" /> | |
| 22 | + <item | |
| 23 | + android:color="#00000000" | |
| 24 | + android:offset="1.0" /> | |
| 25 | + </gradient> | |
| 26 | + </aapt:attr> | |
| 27 | + </path> | |
| 28 | + <path | |
| 29 | + android:fillColor="#FFFFFF" | |
| 30 | + android:fillType="nonZero" | |
| 31 | + android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z" | |
| 32 | + android:strokeWidth="1" | |
| 33 | + android:strokeColor="#00000000" /> | |
| 34 | +</vector> | ... | ... |
app/src/main/res/drawable-xhdpi/wifi1.png
0 → 100644
2.41 KB
app/src/main/res/drawable-xhdpi/wifi2.png
0 → 100644
2.24 KB
app/src/main/res/drawable-xhdpi/wifi3.png
0 → 100644
2.04 KB
app/src/main/res/drawable-xhdpi/wifi4.png
0 → 100644
1.79 KB
app/src/main/res/drawable-xxhdpi/wifi1.png
0 → 100644
5.83 KB
app/src/main/res/drawable-xxhdpi/wifi2.png
0 → 100644
5.4 KB
app/src/main/res/drawable-xxhdpi/wifi3.png
0 → 100644
4.81 KB
app/src/main/res/drawable-xxhdpi/wifi4.png
0 → 100644
3.83 KB
app/src/main/res/layout/activity_main.xml
0 → 100644
| 1 | +++ a/app/src/main/res/layout/activity_main.xml | |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | + | |
| 3 | + <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
| 4 | + xmlns:app="http://schemas.android.com/apk/res-auto" | |
| 5 | + xmlns:tools="http://schemas.android.com/tools" | |
| 6 | + android:layout_width="match_parent" | |
| 7 | + android:layout_height="match_parent" | |
| 8 | + > | |
| 9 | + | |
| 10 | + <android.support.v7.widget.RecyclerView | |
| 11 | + android:id="@+id/recycler" | |
| 12 | + android:layout_width="match_parent" | |
| 13 | + android:layout_height="match_parent" /> | |
| 14 | + | |
| 15 | + </LinearLayout> | |
| 0 | 16 | \ No newline at end of file | ... | ... |
app/src/main/res/layout/dialog_select.xml
0 → 100644
| 1 | +++ a/app/src/main/res/layout/dialog_select.xml | |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
| 3 | + android:layout_width="match_parent" | |
| 4 | + android:layout_height="wrap_content" | |
| 5 | + android:gravity="center_horizontal"> | |
| 6 | + | |
| 7 | + | |
| 8 | + <LinearLayout | |
| 9 | + android:id="@+id/ll_child" | |
| 10 | + android:layout_width="match_parent" | |
| 11 | + android:layout_height="wrap_content" | |
| 12 | + android:background="@drawable/free_dialog_bg" | |
| 13 | + android:orientation="vertical" | |
| 14 | + android:paddingTop="10dp" | |
| 15 | + > | |
| 16 | + | |
| 17 | + <TextView | |
| 18 | + android:id="@+id/tv_dialog_tip" | |
| 19 | + android:layout_width="wrap_content" | |
| 20 | + android:layout_height="wrap_content" | |
| 21 | + android:minHeight="75dp" | |
| 22 | + android:gravity="center" | |
| 23 | + android:layout_gravity="center" | |
| 24 | + android:text="标题" | |
| 25 | + android:textColor="@color/black" | |
| 26 | + android:textSize="17sp" | |
| 27 | + android:textStyle="bold" /> | |
| 28 | + | |
| 29 | + | |
| 30 | + <View | |
| 31 | + android:layout_width="match_parent" | |
| 32 | + android:layout_height="1dp" | |
| 33 | + android:layout_marginTop="3dp" | |
| 34 | + android:background="@color/line" /> | |
| 35 | + | |
| 36 | + <LinearLayout | |
| 37 | + android:layout_width="match_parent" | |
| 38 | + android:layout_height="40dp" | |
| 39 | + android:orientation="horizontal"> | |
| 40 | + | |
| 41 | + | |
| 42 | + <LinearLayout | |
| 43 | + android:layout_width="0dp" | |
| 44 | + android:layout_height="match_parent" | |
| 45 | + android:layout_gravity="center" | |
| 46 | + android:layout_weight="1" | |
| 47 | + android:gravity="center"> | |
| 48 | + | |
| 49 | + <Button | |
| 50 | + android:id="@+id/btn_cancel" | |
| 51 | + android:layout_width="match_parent" | |
| 52 | + android:layout_height="match_parent" | |
| 53 | + android:layout_gravity="center" | |
| 54 | + android:background="@drawable/selector_dialog_btn_left" | |
| 55 | + android:text="否" | |
| 56 | + android:textColor="@color/black" | |
| 57 | + android:textSize="15sp" | |
| 58 | + android:textStyle="bold" /> | |
| 59 | + </LinearLayout> | |
| 60 | + | |
| 61 | + <View | |
| 62 | + android:layout_width="1dp" | |
| 63 | + android:layout_height="match_parent" | |
| 64 | + android:background="@color/line" /> | |
| 65 | + | |
| 66 | + <LinearLayout | |
| 67 | + android:layout_width="0dp" | |
| 68 | + android:layout_height="match_parent" | |
| 69 | + android:layout_gravity="center" | |
| 70 | + android:layout_weight="1" | |
| 71 | + android:gravity="center"> | |
| 72 | + | |
| 73 | + <Button | |
| 74 | + android:id="@+id/btn_ok" | |
| 75 | + android:layout_width="match_parent" | |
| 76 | + android:layout_height="match_parent" | |
| 77 | + android:layout_gravity="center" | |
| 78 | + android:background="@drawable/selector_dialog_btn_right" | |
| 79 | + android:text="否" | |
| 80 | + android:textColor="@color/black" | |
| 81 | + android:textSize="15sp" | |
| 82 | + android:textStyle="bold" /> | |
| 83 | + </LinearLayout> | |
| 84 | + | |
| 85 | + </LinearLayout> | |
| 86 | + </LinearLayout> | |
| 87 | +</LinearLayout> | ... | ... |
app/src/main/res/layout/list_item_wifi.xml
0 → 100644
| 1 | +++ a/app/src/main/res/layout/list_item_wifi.xml | |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<layout> | |
| 3 | + | |
| 4 | + <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
| 5 | + android:id="@+id/rl_root" | |
| 6 | + android:layout_width="match_parent" | |
| 7 | + android:layout_height="50dp" | |
| 8 | + android:background="?android:attr/selectableItemBackground" | |
| 9 | + android:clickable="true" | |
| 10 | + android:focusable="true" | |
| 11 | + android:gravity="center_vertical"> | |
| 12 | + | |
| 13 | + <TextView | |
| 14 | + android:id="@+id/tv_wifi_name" | |
| 15 | + android:layout_width="wrap_content" | |
| 16 | + android:layout_height="wrap_content" | |
| 17 | + android:layout_alignParentLeft="true" | |
| 18 | + android:layout_centerVertical="true" | |
| 19 | + android:layout_marginLeft="10dp" | |
| 20 | + android:textColor="#000000" | |
| 21 | + android:textSize="15sp" /> | |
| 22 | + | |
| 23 | + <ImageView | |
| 24 | + android:id="@+id/iv_wifi" | |
| 25 | + android:layout_width="20dp" | |
| 26 | + android:layout_height="20dp" | |
| 27 | + android:layout_alignParentRight="true" | |
| 28 | + android:layout_centerVertical="true" | |
| 29 | + android:layout_marginRight="10dp" /> | |
| 30 | + </RelativeLayout> | |
| 31 | +</layout> | |
| 0 | 32 | \ No newline at end of file | ... | ... |
app/src/main/res/mipmap-hdpi/ic_launcher.png
0 → 100644
2.89 KB
app/src/main/res/mipmap-hdpi/ic_launcher_round.png
0 → 100644
4.79 KB
app/src/main/res/mipmap-mdpi/ic_launcher.png
0 → 100644
2.01 KB
app/src/main/res/mipmap-mdpi/ic_launcher_round.png
0 → 100644
2.72 KB
app/src/main/res/mipmap-xhdpi/ic_launcher.png
0 → 100644
4.38 KB
app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
0 → 100644
6.73 KB
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
0 → 100644
6.24 KB
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
0 → 100644
10.2 KB
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
0 → 100644
8.91 KB
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
0 → 100644
14.8 KB
app/src/main/res/values/colors.xml
0 → 100644
| 1 | +++ a/app/src/main/res/values/colors.xml | |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<resources> | |
| 3 | + <color name="colorPrimary">#4A90E2</color> | |
| 4 | + <color name="colorPrimaryDark">#1976D2</color> | |
| 5 | + <color name="colorAccent">#03A9F4</color> | |
| 6 | + <color name="white">#FFFFFF</color> | |
| 7 | + <color name="black">#000000</color> | |
| 8 | + | |
| 9 | + <!--自定义对话框的线--> | |
| 10 | + <color name="app_color_blue">#FF4081</color> | |
| 11 | + <color name="line">#EEEEEE</color> | |
| 12 | + <color name="transparent">#00000000</color> | |
| 13 | +</resources> | ... | ... |
app/src/main/res/values/strings.xml
0 → 100644
app/src/main/res/values/styles.xml
0 → 100644
| 1 | +++ a/app/src/main/res/values/styles.xml | |
| 1 | +<resources> | |
| 2 | + | |
| 3 | + <!-- Base application theme. --> | |
| 4 | + <style name="AppTheme" parent="QMUI.Compat.NoActionBar"> | |
| 5 | + <!-- Customize your theme here. --> | |
| 6 | + <item name="colorPrimary">@color/colorPrimary</item> | |
| 7 | + <item name="colorPrimaryDark">@color/colorPrimaryDark</item> | |
| 8 | + <item name="colorAccent">@color/colorAccent</item> | |
| 9 | + </style> | |
| 10 | + | |
| 11 | + <!--自定义Dialog背景全透明无边框theme--> | |
| 12 | + <style name="MyDialog" parent="android:style/Theme.Dialog"> | |
| 13 | + <item name="android:windowFrame">@null</item> | |
| 14 | + <item name="android:windowBackground">@android:color/transparent</item> | |
| 15 | + <item name="android:windowNoTitle">true</item> | |
| 16 | + <item name="android:windowIsFloating">true</item> | |
| 17 | + <item name="android:windowContentOverlay">@null</item> | |
| 18 | + <item name="android:background">@android:color/transparent</item> | |
| 19 | + </style> | |
| 20 | +</resources> | ... | ... |
app/src/test/java/com/cnlive/strike/xiaojiaspeaker/ExampleUnitTest.java
0 → 100644
| 1 | +++ a/app/src/test/java/com/cnlive/strike/xiaojiaspeaker/ExampleUnitTest.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker; | |
| 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 <a href="http://d.android.com/tools/testing">Testing documentation</a> | |
| 11 | + */ | |
| 12 | +public class ExampleUnitTest { | |
| 13 | + @Test | |
| 14 | + public void addition_isCorrect() { | |
| 15 | + assertEquals(4, 2 + 2); | |
| 16 | + } | |
| 17 | +} | |
| 0 | 18 | \ No newline at end of file | ... | ... |
build.gradle
0 → 100644
| 1 | +++ a/build.gradle | |
| 1 | +// Top-level build file where you can add configuration options common to all sub-projects/modules. | |
| 2 | +apply from: "config.gradle" | |
| 3 | +buildscript { | |
| 4 | + repositories { | |
| 5 | + google() | |
| 6 | + jcenter() | |
| 7 | + | |
| 8 | + } | |
| 9 | + dependencies { | |
| 10 | + classpath 'com.android.tools.build:gradle:3.5.0' | |
| 11 | + | |
| 12 | + // NOTE: Do not place your application dependencies here; they belong | |
| 13 | + // in the individual module build.gradle files | |
| 14 | + } | |
| 15 | +} | |
| 16 | + | |
| 17 | +allprojects { | |
| 18 | + repositories { | |
| 19 | + google() | |
| 20 | + jcenter() | |
| 21 | + //------------------ 资源库配置 ------------------ | |
| 22 | + maven { | |
| 23 | + url "http://android.nexus.cnlive.com/repository/cnlive-mixed/" | |
| 24 | + credentials { username = nexusId; password = nexusPw } | |
| 25 | + } | |
| 26 | + //------------------ 资源库配置 END------------------ | |
| 27 | + maven { | |
| 28 | + url 'https://dl.bintray.com/granzon/cnlive' | |
| 29 | + } | |
| 30 | + maven { | |
| 31 | + url 'https://dl.bintray.com/granzon/cnliveLibs' | |
| 32 | + } | |
| 33 | + maven { | |
| 34 | + url "https://jitpack.io" | |
| 35 | + } | |
| 36 | + } | |
| 37 | +} | |
| 38 | + | |
| 39 | +task clean(type: Delete) { | |
| 40 | + delete rootProject.buildDir | |
| 41 | +} | |
| 42 | + | |
| 43 | +ext { | |
| 44 | + def versionMajor = 1 | |
| 45 | + def versionMinor = 0 | |
| 46 | + def versionPatch = 0 | |
| 47 | + def versionBuild = 0 | |
| 48 | + // module依赖库公共版本号 | |
| 49 | + versionCode = versionMajor * 1000 + versionMinor * 100 + versionPatch * 10 + versionBuild | |
| 50 | + versionName = "${versionMajor}.${versionMinor}.${versionPatch}.${versionBuild}" | |
| 51 | + | |
| 52 | + compileSdkVersion = 28 | |
| 53 | + buildToolsVersion = "28.0.3" | |
| 54 | + minSdkVersion = 18 | |
| 55 | + targetSdkVersion = 27 | |
| 56 | + | |
| 57 | + //support 相关 | |
| 58 | + supportV4 = '28.0.0' | |
| 59 | + appcompatV7 = '28.0.0' | |
| 60 | + design = '28.0.0' | |
| 61 | + supportV13 = '28.0.0' | |
| 62 | + recyclerviewV7 = '28.0.0' | |
| 63 | + cardviewV7 = '28.0.0' | |
| 64 | + | |
| 65 | + appArch = '1.0.3' | |
| 66 | + //qmui | |
| 67 | + qmui = '1.1.5' | |
| 68 | + | |
| 69 | + libBase = '1.0.9' | |
| 70 | + libNetwork = '1.1.0' | |
| 71 | + libLargeImage = '1.0.1' | |
| 72 | + libEmoj = '1.9.8' | |
| 73 | + libMenu = '1.0.4' | |
| 74 | + libAnalytics = '1.1.0' | |
| 75 | + | |
| 76 | + //glide | |
| 77 | + glide = '4.5.0' | |
| 78 | + glideTransformations = '3.0.1' | |
| 79 | + compiler = '4.5.0' | |
| 80 | + | |
| 81 | + magicindicator = '1.6.0' | |
| 82 | + | |
| 83 | + //SmartRefresh | |
| 84 | + SmartRefreshLayout = '1.1.0-alpha-1' | |
| 85 | + SmartRefreshHeader = '1.1.0-alpha-1' | |
| 86 | + | |
| 87 | + //阿里路由框架 | |
| 88 | + arouterApiVersion = '1.4.0' | |
| 89 | + arouterCompilerVersion = '1.2.1' | |
| 90 | + | |
| 91 | + //greendao | |
| 92 | + greendao = '3.2.2' | |
| 93 | +// loading动画 | |
| 94 | + avi = "2.1.3" | |
| 95 | + | |
| 96 | +} | |
| 97 | + | ... | ... |
config.gradle
0 → 100644
| 1 | +++ a/config.gradle | |
| 1 | +ext { | |
| 2 | + //Nexus 访问账号 | |
| 3 | + nexusId = "developer" | |
| 4 | + nexusPw = "android_2019" | |
| 5 | + | |
| 6 | + //Nexus 发布配置 | |
| 7 | + maven = [ | |
| 8 | + //发布版地址(暂未使用) | |
| 9 | + mavenUrl : "http://android.nexus.cnlive.com/repository/cnlive/", | |
| 10 | + //快照版地址(暂未使用) | |
| 11 | + mavenDevUrl : "http://android.nexus.cnlive.com/repository/cnlive-snapshot/", | |
| 12 | + //混合版地址 | |
| 13 | + mavenMixedUrl : "http://android.nexus.cnlive.com/repository/cnlive-mixed/", | |
| 14 | + //发布账号(单独分配) | |
| 15 | + mavenUserName: "developer", | |
| 16 | + mavenPwd : "android_2019" | |
| 17 | + ] | |
| 18 | + | |
| 19 | + //Maven Base库配置 | |
| 20 | + moudle_subscription = [ | |
| 21 | + //编译方式 | |
| 22 | + debug : false, | |
| 23 | + //版本号 | |
| 24 | + version: "0.0.1", | |
| 25 | + //Lib库前缀 | |
| 26 | + packeg : "com.cnlive.module", | |
| 27 | + //Lib库名称 | |
| 28 | + name : "xiaoJiaSpeaker" | |
| 29 | + ] | |
| 30 | +} | |
| 0 | 31 | \ No newline at end of file | ... | ... |
gradle.properties
0 → 100644
| 1 | +++ a/gradle.properties | |
| 1 | +# Project-wide Gradle settings. | |
| 2 | +# IDE (e.g. Android Studio) users: | |
| 3 | +# Gradle settings configured through the IDE *will override* | |
| 4 | +# any settings specified in this file. | |
| 5 | +# For more details on how to configure your build environment visit | |
| 6 | +# http://www.gradle.org/docs/current/userguide/build_environment.html | |
| 7 | +# Specifies the JVM arguments used for the daemon process. | |
| 8 | +# The setting is particularly useful for tweaking memory settings. | |
| 9 | +org.gradle.jvmargs=-Xmx1536m | |
| 10 | +# When configured, Gradle will run in incubating parallel mode. | |
| 11 | +# This option should only be used with decoupled projects. More details, visit | |
| 12 | +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects | |
| 13 | +# org.gradle.parallel=true | |
| 14 | +# AndroidX package structure to make it clearer which packages are bundled with the | |
| 15 | +# Android operating system, and which are packaged with your app's APK | |
| 16 | +# https://developer.android.com/topic/libraries/support-library/androidx-rn | |
| 17 | +android.useAndroidX=false | |
| 18 | +# Automatically convert third-party libraries to use AndroidX | |
| 19 | +android.enableJetifier=false | |
| 20 | + | ... | ... |
gradle/wrapper/gradle-wrapper.jar
0 → 100644
No preview for this file type
gradle/wrapper/gradle-wrapper.properties
0 → 100644
| 1 | +++ a/gradle/wrapper/gradle-wrapper.properties | |
| 1 | +#Tue Aug 27 10:06:28 CST 2019 | |
| 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-5.4.1-all.zip | ... | ... |
gradlew
0 → 100644
| 1 | +++ a/gradlew | |
| 1 | +#!/usr/bin/env sh | |
| 2 | + | |
| 3 | +############################################################################## | |
| 4 | +## | |
| 5 | +## Gradle start up script for UN*X | |
| 6 | +## | |
| 7 | +############################################################################## | |
| 8 | + | |
| 9 | +# Attempt to set APP_HOME | |
| 10 | +# Resolve links: $0 may be a link | |
| 11 | +PRG="$0" | |
| 12 | +# Need this for relative symlinks. | |
| 13 | +while [ -h "$PRG" ] ; do | |
| 14 | + ls=`ls -ld "$PRG"` | |
| 15 | + link=`expr "$ls" : '.*-> \(.*\)$'` | |
| 16 | + if expr "$link" : '/.*' > /dev/null; then | |
| 17 | + PRG="$link" | |
| 18 | + else | |
| 19 | + PRG=`dirname "$PRG"`"/$link" | |
| 20 | + fi | |
| 21 | +done | |
| 22 | +SAVED="`pwd`" | |
| 23 | +cd "`dirname \"$PRG\"`/" >/dev/null | |
| 24 | +APP_HOME="`pwd -P`" | |
| 25 | +cd "$SAVED" >/dev/null | |
| 26 | + | |
| 27 | +APP_NAME="Gradle" | |
| 28 | +APP_BASE_NAME=`basename "$0"` | |
| 29 | + | |
| 30 | +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | |
| 31 | +DEFAULT_JVM_OPTS="" | |
| 32 | + | |
| 33 | +# Use the maximum available, or set MAX_FD != -1 to use that value. | |
| 34 | +MAX_FD="maximum" | |
| 35 | + | |
| 36 | +warn () { | |
| 37 | + echo "$*" | |
| 38 | +} | |
| 39 | + | |
| 40 | +die () { | |
| 41 | + echo | |
| 42 | + echo "$*" | |
| 43 | + echo | |
| 44 | + exit 1 | |
| 45 | +} | |
| 46 | + | |
| 47 | +# OS specific support (must be 'true' or 'false'). | |
| 48 | +cygwin=false | |
| 49 | +msys=false | |
| 50 | +darwin=false | |
| 51 | +nonstop=false | |
| 52 | +case "`uname`" in | |
| 53 | + CYGWIN* ) | |
| 54 | + cygwin=true | |
| 55 | + ;; | |
| 56 | + Darwin* ) | |
| 57 | + darwin=true | |
| 58 | + ;; | |
| 59 | + MINGW* ) | |
| 60 | + msys=true | |
| 61 | + ;; | |
| 62 | + NONSTOP* ) | |
| 63 | + nonstop=true | |
| 64 | + ;; | |
| 65 | +esac | |
| 66 | + | |
| 67 | +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | |
| 68 | + | |
| 69 | +# Determine the Java command to use to start the JVM. | |
| 70 | +if [ -n "$JAVA_HOME" ] ; then | |
| 71 | + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | |
| 72 | + # IBM's JDK on AIX uses strange locations for the executables | |
| 73 | + JAVACMD="$JAVA_HOME/jre/sh/java" | |
| 74 | + else | |
| 75 | + JAVACMD="$JAVA_HOME/bin/java" | |
| 76 | + fi | |
| 77 | + if [ ! -x "$JAVACMD" ] ; then | |
| 78 | + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | |
| 79 | + | |
| 80 | +Please set the JAVA_HOME variable in your environment to match the | |
| 81 | +location of your Java installation." | |
| 82 | + fi | |
| 83 | +else | |
| 84 | + JAVACMD="java" | |
| 85 | + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | |
| 86 | + | |
| 87 | +Please set the JAVA_HOME variable in your environment to match the | |
| 88 | +location of your Java installation." | |
| 89 | +fi | |
| 90 | + | |
| 91 | +# Increase the maximum file descriptors if we can. | |
| 92 | +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then | |
| 93 | + MAX_FD_LIMIT=`ulimit -H -n` | |
| 94 | + if [ $? -eq 0 ] ; then | |
| 95 | + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then | |
| 96 | + MAX_FD="$MAX_FD_LIMIT" | |
| 97 | + fi | |
| 98 | + ulimit -n $MAX_FD | |
| 99 | + if [ $? -ne 0 ] ; then | |
| 100 | + warn "Could not set maximum file descriptor limit: $MAX_FD" | |
| 101 | + fi | |
| 102 | + else | |
| 103 | + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" | |
| 104 | + fi | |
| 105 | +fi | |
| 106 | + | |
| 107 | +# For Darwin, add options to specify how the application appears in the dock | |
| 108 | +if $darwin; then | |
| 109 | + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" | |
| 110 | +fi | |
| 111 | + | |
| 112 | +# For Cygwin, switch paths to Windows format before running java | |
| 113 | +if $cygwin ; then | |
| 114 | + APP_HOME=`cygpath --path --mixed "$APP_HOME"` | |
| 115 | + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` | |
| 116 | + JAVACMD=`cygpath --unix "$JAVACMD"` | |
| 117 | + | |
| 118 | + # We build the pattern for arguments to be converted via cygpath | |
| 119 | + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` | |
| 120 | + SEP="" | |
| 121 | + for dir in $ROOTDIRSRAW ; do | |
| 122 | + ROOTDIRS="$ROOTDIRS$SEP$dir" | |
| 123 | + SEP="|" | |
| 124 | + done | |
| 125 | + OURCYGPATTERN="(^($ROOTDIRS))" | |
| 126 | + # Add a user-defined pattern to the cygpath arguments | |
| 127 | + if [ "$GRADLE_CYGPATTERN" != "" ] ; then | |
| 128 | + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" | |
| 129 | + fi | |
| 130 | + # Now convert the arguments - kludge to limit ourselves to /bin/sh | |
| 131 | + i=0 | |
| 132 | + for arg in "$@" ; do | |
| 133 | + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` | |
| 134 | + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option | |
| 135 | + | |
| 136 | + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition | |
| 137 | + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` | |
| 138 | + else | |
| 139 | + eval `echo args$i`="\"$arg\"" | |
| 140 | + fi | |
| 141 | + i=$((i+1)) | |
| 142 | + done | |
| 143 | + case $i in | |
| 144 | + (0) set -- ;; | |
| 145 | + (1) set -- "$args0" ;; | |
| 146 | + (2) set -- "$args0" "$args1" ;; | |
| 147 | + (3) set -- "$args0" "$args1" "$args2" ;; | |
| 148 | + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; | |
| 149 | + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | |
| 150 | + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | |
| 151 | + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | |
| 152 | + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | |
| 153 | + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | |
| 154 | + esac | |
| 155 | +fi | |
| 156 | + | |
| 157 | +# Escape application args | |
| 158 | +save () { | |
| 159 | + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done | |
| 160 | + echo " " | |
| 161 | +} | |
| 162 | +APP_ARGS=$(save "$@") | |
| 163 | + | |
| 164 | +# Collect all arguments for the java command, following the shell quoting and substitution rules | |
| 165 | +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" | |
| 166 | + | |
| 167 | +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong | |
| 168 | +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then | |
| 169 | + cd "$(dirname "$0")" | |
| 170 | +fi | |
| 171 | + | |
| 172 | +exec "$JAVACMD" "$@" | ... | ... |
gradlew.bat
0 → 100644
| 1 | +++ a/gradlew.bat | |
| 1 | +@if "%DEBUG%" == "" @echo off | |
| 2 | +@rem ########################################################################## | |
| 3 | +@rem | |
| 4 | +@rem Gradle startup script for Windows | |
| 5 | +@rem | |
| 6 | +@rem ########################################################################## | |
| 7 | + | |
| 8 | +@rem Set local scope for the variables with windows NT shell | |
| 9 | +if "%OS%"=="Windows_NT" setlocal | |
| 10 | + | |
| 11 | +set DIRNAME=%~dp0 | |
| 12 | +if "%DIRNAME%" == "" set DIRNAME=. | |
| 13 | +set APP_BASE_NAME=%~n0 | |
| 14 | +set APP_HOME=%DIRNAME% | |
| 15 | + | |
| 16 | +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | |
| 17 | +set DEFAULT_JVM_OPTS= | |
| 18 | + | |
| 19 | +@rem Find java.exe | |
| 20 | +if defined JAVA_HOME goto findJavaFromJavaHome | |
| 21 | + | |
| 22 | +set JAVA_EXE=java.exe | |
| 23 | +%JAVA_EXE% -version >NUL 2>&1 | |
| 24 | +if "%ERRORLEVEL%" == "0" goto init | |
| 25 | + | |
| 26 | +echo. | |
| 27 | +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | |
| 28 | +echo. | |
| 29 | +echo Please set the JAVA_HOME variable in your environment to match the | |
| 30 | +echo location of your Java installation. | |
| 31 | + | |
| 32 | +goto fail | |
| 33 | + | |
| 34 | +:findJavaFromJavaHome | |
| 35 | +set JAVA_HOME=%JAVA_HOME:"=% | |
| 36 | +set JAVA_EXE=%JAVA_HOME%/bin/java.exe | |
| 37 | + | |
| 38 | +if exist "%JAVA_EXE%" goto init | |
| 39 | + | |
| 40 | +echo. | |
| 41 | +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | |
| 42 | +echo. | |
| 43 | +echo Please set the JAVA_HOME variable in your environment to match the | |
| 44 | +echo location of your Java installation. | |
| 45 | + | |
| 46 | +goto fail | |
| 47 | + | |
| 48 | +:init | |
| 49 | +@rem Get command-line arguments, handling Windows variants | |
| 50 | + | |
| 51 | +if not "%OS%" == "Windows_NT" goto win9xME_args | |
| 52 | + | |
| 53 | +:win9xME_args | |
| 54 | +@rem Slurp the command line arguments. | |
| 55 | +set CMD_LINE_ARGS= | |
| 56 | +set _SKIP=2 | |
| 57 | + | |
| 58 | +:win9xME_args_slurp | |
| 59 | +if "x%~1" == "x" goto execute | |
| 60 | + | |
| 61 | +set CMD_LINE_ARGS=%* | |
| 62 | + | |
| 63 | +:execute | |
| 64 | +@rem Setup the command line | |
| 65 | + | |
| 66 | +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | |
| 67 | + | |
| 68 | +@rem Execute Gradle | |
| 69 | +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% | |
| 70 | + | |
| 71 | +:end | |
| 72 | +@rem End local scope for the variables with windows NT shell | |
| 73 | +if "%ERRORLEVEL%"=="0" goto mainEnd | |
| 74 | + | |
| 75 | +:fail | |
| 76 | +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | |
| 77 | +rem the _cmd.exe /c_ return code! | |
| 78 | +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 | |
| 79 | +exit /b 1 | |
| 80 | + | |
| 81 | +:mainEnd | |
| 82 | +if "%OS%"=="Windows_NT" endlocal | |
| 83 | + | |
| 84 | +:omega | ... | ... |
module_xiaojiaspeaker/.gitignore
0 → 100644
module_xiaojiaspeaker/build.gradle
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/build.gradle | |
| 1 | +apply plugin: 'com.android.library' | |
| 2 | + | |
| 3 | +android { | |
| 4 | + compileSdkVersion 28 | |
| 5 | + | |
| 6 | + | |
| 7 | + defaultConfig { | |
| 8 | + minSdkVersion 18 | |
| 9 | + targetSdkVersion 28 | |
| 10 | + versionCode 1 | |
| 11 | + versionName "1.0" | |
| 12 | + | |
| 13 | + testInstrumentationRunner "android.test.runner.AndroidJUnitRunner" | |
| 14 | + consumerProguardFiles 'consumer-rules.pro' | |
| 15 | + } | |
| 16 | + dataBinding { | |
| 17 | + enabled = true | |
| 18 | + } | |
| 19 | + buildTypes { | |
| 20 | + release { | |
| 21 | + minifyEnabled false | |
| 22 | + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | |
| 23 | + } | |
| 24 | + } | |
| 25 | + | |
| 26 | +} | |
| 27 | + | |
| 28 | +dependencies { | |
| 29 | + implementation fileTree(dir: 'libs', include: ['*.jar']) | |
| 30 | + implementation "com.android.support:support-v4:$rootProject.supportV4" | |
| 31 | + implementation "com.android.support:appcompat-v7:$rootProject.appcompatV7" | |
| 32 | + implementation "com.android.support:design:$rootProject.design" | |
| 33 | + implementation "com.android.support:support-v13:$rootProject.supportV13" | |
| 34 | + implementation "com.android.support:recyclerview-v7:$rootProject.recyclerviewV7" | |
| 35 | + implementation "com.cnlive:app_arch:$rootProject.appArch" | |
| 36 | + implementation "com.qmuiteam:qmui:$rootProject.qmui" | |
| 37 | + implementation "com.cnlive.libs:base:$rootProject.libBase" | |
| 38 | +// implementation 'com.blakequ.androidblemanager:bluetooth-manager-lib:2.1.5' | |
| 39 | + implementation 'com.clj.fastble:FastBleLib:2.3.4' | |
| 40 | +// https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/README-CN.md | |
| 41 | +// implementation 'com.blankj:utilcode:1.25.9' | |
| 42 | + //glide | |
| 43 | + implementation "com.github.bumptech.glide:glide:$rootProject.glide" | |
| 44 | + implementation "jp.wasabeef:glide-transformations:$rootProject.glideTransformations" | |
| 45 | +// loading动画 | |
| 46 | + implementation "com.wang.avi:library:$rootProject.avi" | |
| 47 | + | |
| 48 | + implementation 'com.android.support.constraint:constraint-layout:1.1.3' | |
| 49 | +} | ... | ... |
module_xiaojiaspeaker/consumer-rules.pro
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/consumer-rules.pro | ... | ... |
module_xiaojiaspeaker/proguard-rules.pro
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/proguard-rules.pro | |
| 1 | +# Add project specific ProGuard rules here. | |
| 2 | +# You can control the set of applied configuration files using the | |
| 3 | +# proguardFiles setting in build.gradle. | |
| 4 | +# | |
| 5 | +# For more details, see | |
| 6 | +# http://developer.android.com/guide/developing/tools/proguard.html | |
| 7 | + | |
| 8 | +# If your project uses WebView with JS, uncomment the following | |
| 9 | +# and specify the fully qualified class name to the JavaScript interface | |
| 10 | +# class: | |
| 11 | +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | |
| 12 | +# public *; | |
| 13 | +#} | |
| 14 | + | |
| 15 | +# Uncomment this to preserve the line number information for | |
| 16 | +# debugging stack traces. | |
| 17 | +#-keepattributes SourceFile,LineNumberTable | |
| 18 | + | |
| 19 | +# If you keep the line number information, uncomment this to | |
| 20 | +# hide the original source file name. | |
| 21 | +#-renamesourcefileattribute SourceFile | ... | ... |
module_xiaojiaspeaker/src/androidTest/java/com/cnlive/strike/xiaojiaspeaker/ExampleInstrumentedTest.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/androidTest/java/com/cnlive/strike/xiaojiaspeaker/ExampleInstrumentedTest.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker; | |
| 2 | + | |
| 3 | +import android.content.Context; | |
| 4 | + | |
| 5 | +import androidx.test.platform.app.InstrumentationRegistry; | |
| 6 | +import androidx.test.ext.junit.runners.AndroidJUnit4; | |
| 7 | + | |
| 8 | +import org.junit.Test; | |
| 9 | +import org.junit.runner.RunWith; | |
| 10 | + | |
| 11 | +import static org.junit.Assert.*; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * Instrumented test, which will execute on an Android device. | |
| 15 | + * | |
| 16 | + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> | |
| 17 | + */ | |
| 18 | +@RunWith(AndroidJUnit4.class) | |
| 19 | +public class ExampleInstrumentedTest { | |
| 20 | + @Test | |
| 21 | + public void useAppContext() { | |
| 22 | + // Context of the app under test. | |
| 23 | + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); | |
| 24 | + | |
| 25 | + assertEquals("com.cnlive.strike.module_xiaojiaspeaker.test", appContext.getPackageName()); | |
| 26 | + } | |
| 27 | +} | ... | ... |
module_xiaojiaspeaker/src/main/AndroidManifest.xml
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/AndroidManifest.xml | |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
| 3 | + package="com.cnlive.strike.xiaojiaspeaker"> | |
| 4 | + | |
| 5 | + <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> | |
| 6 | + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> | |
| 7 | + <uses-permission android:name="android.permission.BLUETOOTH" /> | |
| 8 | + <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> | |
| 9 | + <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> | |
| 10 | + <uses-permission android:name="android.permission.INTERNET" /> | |
| 11 | + <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> | |
| 12 | + <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> | |
| 13 | + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> | |
| 14 | + | |
| 15 | + <application> | |
| 16 | + <activity android:name=".ui.activity.SelectWifiActivity"></activity> | |
| 17 | + <activity android:name=".ui.activity.BlueToothStep2Activity" /> | |
| 18 | + <activity android:name=".ui.activity.BlueToothStep1Activity" /> | |
| 19 | + <activity android:name=".ui.activity.BlueToothHelpActivity" /> | |
| 20 | + <activity android:name=".ui.activity.SearchDeviceActivity" /> | |
| 21 | + <activity android:name=".ui.activity.SpeakerMainActivity" /> | |
| 22 | + <activity android:name=".ui.activity.BluetoothConnActivity" /> | |
| 23 | + </application> | |
| 24 | + | |
| 25 | +</manifest> | |
| 0 | 26 | \ No newline at end of file | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/constants/BlufiConstants.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/constants/BlufiConstants.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.constants; | |
| 2 | + | |
| 3 | +import java.util.UUID; | |
| 4 | + | |
| 5 | +public final class BlufiConstants { | |
| 6 | + public static final String BLUFI_PREFIX = "HEMU"; | |
| 7 | + | |
| 8 | + public static final UUID UUID_WIFI_SERVICE = UUID.fromString("00001111-0000-1000-8000-00805f9b34fb"); | |
| 9 | + public static final UUID UUID_WRITE_CHARACTERISTIC = UUID.fromString("00002222-0000-1000-8000-00805f9b34fb"); | |
| 10 | + public static final UUID UUID_NOTIFY_CHARACTERISTIC = UUID.fromString("0000a007-0000-1000-8000-00805f9b34fb"); | |
| 11 | + | |
| 12 | + public static final String KEY_BLE_DEVICES = "key_ble_devices"; | |
| 13 | + | |
| 14 | + public static final String KEY_CONFIGURE_PARAM = "configure_param"; | |
| 15 | + public static final String KEY_CONFIGURE_MULTITHREAD = "configure_multithread"; | |
| 16 | + | |
| 17 | + public static final int DEFAULT_MTU_LENGTH = 60; | |
| 18 | + public static final int MIN_MTU_LENGTH = 30; | |
| 19 | + | |
| 20 | + public static final int POST_DATA_LENGTH_LESS = 16; | |
| 21 | + | |
| 22 | + public static final String PREF_MESH_IDS_NAME = "espblufi_mesh_ids"; | |
| 23 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/frame/presenter/SearchDevicefragmentPresenter.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/frame/presenter/SearchDevicefragmentPresenter.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.frame.presenter; | |
| 2 | + | |
| 3 | +import com.cnlive.strike.xiaojiaspeaker.frame.view.SearchDevicefragmentView; | |
| 4 | +import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter; | |
| 5 | + | |
| 6 | +public class SearchDevicefragmentPresenter extends MvpBasePresenter<SearchDevicefragmentView> { | |
| 7 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/frame/presenter/SelectWifiFragmentPresenter.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/frame/presenter/SelectWifiFragmentPresenter.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.frame.presenter; | |
| 2 | + | |
| 3 | +import com.cnlive.strike.xiaojiaspeaker.frame.view.SelectWifiFragmentView; | |
| 4 | +import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter; | |
| 5 | + | |
| 6 | +public class SelectWifiFragmentPresenter extends MvpBasePresenter<SelectWifiFragmentView> { | |
| 7 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/frame/view/SearchDevicefragmentView.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/frame/view/SearchDevicefragmentView.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.frame.view; | |
| 2 | + | |
| 3 | +import android.app.Activity; | |
| 4 | +import android.bluetooth.BluetoothAdapter; | |
| 5 | +import android.bluetooth.BluetoothGatt; | |
| 6 | +import android.content.Intent; | |
| 7 | +import android.support.v4.content.ContextCompat; | |
| 8 | +import android.support.v7.widget.DefaultItemAnimator; | |
| 9 | +import android.support.v7.widget.LinearLayoutManager; | |
| 10 | +import android.text.TextUtils; | |
| 11 | +import android.util.Log; | |
| 12 | +import android.view.View; | |
| 13 | + | |
| 14 | +import com.clj.fastble.BleManager; | |
| 15 | +import com.clj.fastble.callback.BleGattCallback; | |
| 16 | +import com.clj.fastble.callback.BleNotifyCallback; | |
| 17 | +import com.clj.fastble.callback.BleScanCallback; | |
| 18 | +import com.clj.fastble.callback.BleWriteCallback; | |
| 19 | +import com.clj.fastble.data.BleDevice; | |
| 20 | +import com.clj.fastble.exception.BleException; | |
| 21 | +import com.cnlive.strike.xiaojiaspeaker.R; | |
| 22 | +import com.cnlive.strike.xiaojiaspeaker.constants.BlufiConstants; | |
| 23 | +import com.cnlive.strike.xiaojiaspeaker.ui.activity.BlueToothHelpActivity; | |
| 24 | +import com.cnlive.strike.xiaojiaspeaker.ui.activity.SelectWifiActivity; | |
| 25 | +import com.cnlive.strike.xiaojiaspeaker.ui.adapter.BluetoothDeviceAdapter; | |
| 26 | +import com.cnlive.strike.xiaojiaspeaker.ui.fragment.SearchDevicefragment; | |
| 27 | +import com.cnlive.strike.xiaojiaspeaker.ui.widget.SelectDialog; | |
| 28 | +import com.cnlive.strike.xiaojiaspeaker.util.BlueToothUtil; | |
| 29 | +import com.cnlive.strike.xiaojiaspeaker.util.WifiUtils; | |
| 30 | +import com.hannesdorfmann.mosby3.mvp.MvpView; | |
| 31 | + | |
| 32 | +import java.io.UnsupportedEncodingException; | |
| 33 | +import java.util.ArrayList; | |
| 34 | +import java.util.List; | |
| 35 | + | |
| 36 | +public class SearchDevicefragmentView implements MvpView { | |
| 37 | + private SearchDevicefragment fragment; | |
| 38 | + private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); | |
| 39 | + private List<BleDevice> bleDevices = new ArrayList<>(); | |
| 40 | + private BluetoothDeviceAdapter adapter; | |
| 41 | + private final String TAG = "SearchDeviceView"; | |
| 42 | + private WifiUtils wifiUtils; | |
| 43 | + private SelectDialog wifiDialog; | |
| 44 | + | |
| 45 | + public SearchDevicefragmentView(SearchDevicefragment fragment) { | |
| 46 | + this.fragment = fragment; | |
| 47 | + } | |
| 48 | + | |
| 49 | + public Activity getContext() { | |
| 50 | + return null == fragment ? null : fragment.getActivity(); | |
| 51 | + } | |
| 52 | + | |
| 53 | + public void initView() { | |
| 54 | + if (null == getContext()) { | |
| 55 | + return; | |
| 56 | + } | |
| 57 | + initWifiDialog(); | |
| 58 | + wifiUtils = new WifiUtils(getContext()); | |
| 59 | + //重试按钮点击事件 | |
| 60 | + fragment.binding.btnRetry.setOnClickListener(new View.OnClickListener() { | |
| 61 | + @Override | |
| 62 | + public void onClick(View view) { | |
| 63 | + scanBlueToothDevice(); | |
| 64 | + } | |
| 65 | + }); | |
| 66 | + //未发现设备帮助点击 | |
| 67 | + fragment.binding.tvNotFoundDevice.setOnClickListener(new View.OnClickListener() { | |
| 68 | + @Override | |
| 69 | + public void onClick(View view) { | |
| 70 | + BlueToothHelpActivity.startActivity(getContext()); | |
| 71 | + } | |
| 72 | + }); | |
| 73 | + //配对按钮点击 | |
| 74 | + fragment.binding.btnBondDevice.setOnClickListener(new View.OnClickListener() { | |
| 75 | + @Override | |
| 76 | + public void onClick(View view) { | |
| 77 | + //判断wifi是否打开 | |
| 78 | + if (!wifiUtils.isOpenWifi()) { | |
| 79 | + if (!wifiDialog.isShowing()) { | |
| 80 | + wifiDialog.show(); | |
| 81 | + } | |
| 82 | + } else { | |
| 83 | +// 获取当前选中设备 | |
| 84 | + if (null != adapter) { | |
| 85 | + BleDevice bleDevice = adapter.getSelectDevice(); | |
| 86 | + if (null != bleDevice) { | |
| 87 | + SelectWifiActivity.StartActivity(getContext(), bleDevice); | |
| 88 | + } | |
| 89 | + } | |
| 90 | + } | |
| 91 | + | |
| 92 | + } | |
| 93 | + }); | |
| 94 | + } | |
| 95 | + | |
| 96 | + private void initWifiDialog() { | |
| 97 | + wifiDialog = new SelectDialog(getContext(), "小家音箱需开启WIFI,是否允许?", "取消", new SelectDialog.DialogInterface() { | |
| 98 | + @Override | |
| 99 | + public void onClick(SelectDialog dialog) { | |
| 100 | + dialog.dismiss(); | |
| 101 | + } | |
| 102 | + }, "设置", new SelectDialog.DialogInterface() { | |
| 103 | + @Override | |
| 104 | + public void onClick(SelectDialog dialog) { | |
| 105 | + getContext().startActivity(new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS)); | |
| 106 | + dialog.dismiss(); | |
| 107 | + } | |
| 108 | + }); | |
| 109 | + wifiDialog.setRightBtnColor(R.color.btn_green); | |
| 110 | + wifiDialog.setCancelable(false); | |
| 111 | + wifiDialog.setCanceledOnTouchOutside(false); | |
| 112 | + } | |
| 113 | + | |
| 114 | + public void initListAdapter() { | |
| 115 | + if (null == getContext()) { | |
| 116 | + return; | |
| 117 | + } | |
| 118 | + //设置配对按钮不可点击 | |
| 119 | + setBondDeviceCantClick(); | |
| 120 | + adapter = new BluetoothDeviceAdapter(getContext(), bleDevices); | |
| 121 | + adapter.setHasStableIds(true); | |
| 122 | + fragment.binding.rvBlueTooth.setLayoutManager(new LinearLayoutManager(getContext())); | |
| 123 | + fragment.binding.rvBlueTooth.setAdapter(adapter); | |
| 124 | + ((DefaultItemAnimator) fragment.binding.rvBlueTooth.getItemAnimator()).setSupportsChangeAnimations(false); | |
| 125 | + | |
| 126 | + adapter.setOnItemClickListener(new BluetoothDeviceAdapter.OnItemClickListener() { | |
| 127 | + @Override | |
| 128 | + public void onItemClick(int position, BleDevice bleDevice) { | |
| 129 | + //设置配对按钮可以点击 | |
| 130 | + setBondDeviceClick(); | |
| 131 | + | |
| 132 | +// // | |
| 133 | + } | |
| 134 | + }); | |
| 135 | + //开始扫描蓝牙 | |
| 136 | + scanBlueToothDevice(); | |
| 137 | + } | |
| 138 | + | |
| 139 | + private void connectDevice(BleDevice bleDevice) { | |
| 140 | + BleManager.getInstance().disconnect(bleDevice); | |
| 141 | + BleManager.getInstance().connect(bleDevice, new BleGattCallback() { | |
| 142 | + // 开始连接 | |
| 143 | + @Override | |
| 144 | + public void onStartConnect() { | |
| 145 | + if (null == getContext()) { | |
| 146 | + return; | |
| 147 | + } | |
| 148 | + } | |
| 149 | + | |
| 150 | + // 连接失败 | |
| 151 | + @Override | |
| 152 | + public void onConnectFail(BleDevice bleDevice, BleException exception) { | |
| 153 | + | |
| 154 | + } | |
| 155 | + | |
| 156 | + // 连接成功,BleDevice即为所连接的BLE设备 | |
| 157 | + @Override | |
| 158 | + public void onConnectSuccess(final BleDevice bleDevice, BluetoothGatt gatt, int status) { | |
| 159 | + | |
| 160 | + BleManager.getInstance().notify( | |
| 161 | + bleDevice, | |
| 162 | + BlufiConstants.UUID_WIFI_SERVICE.toString(), | |
| 163 | + BlufiConstants.UUID_NOTIFY_CHARACTERISTIC.toString(), | |
| 164 | + new BleNotifyCallback() { | |
| 165 | + @Override | |
| 166 | + public void onNotifySuccess() { | |
| 167 | + Log.e(TAG, "onNotifySuccess: "); | |
| 168 | + // 打开通知操作成功 | |
| 169 | + BleManager.getInstance().write( | |
| 170 | + bleDevice, | |
| 171 | + BlufiConstants.UUID_WIFI_SERVICE.toString(), | |
| 172 | + BlufiConstants.UUID_WRITE_CHARACTERISTIC.toString(), | |
| 173 | + (BlueToothUtil.getSSIDAndPwd("CNLive-VIP", "cnlIVE_99", "he:28850150e8bd4c830314819939361b77")).getBytes(), | |
| 174 | + new BleWriteCallback() { | |
| 175 | + @Override | |
| 176 | + public void onWriteSuccess(int current, int total, byte[] justWrite) { | |
| 177 | + Log.e(TAG, "onWriteSuccess: " + justWrite.toString()); | |
| 178 | + // 发送数据到设备成功(分包发送的情况下,可以通过方法中返回的参数可以查看发送进度) | |
| 179 | + } | |
| 180 | + | |
| 181 | + @Override | |
| 182 | + public void onWriteFailure(BleException exception) { | |
| 183 | + Log.e(TAG, "onWriteFailure: "); | |
| 184 | + | |
| 185 | + } | |
| 186 | + }); | |
| 187 | + // | |
| 188 | + } | |
| 189 | + | |
| 190 | + @Override | |
| 191 | + public void onNotifyFailure(BleException exception) { | |
| 192 | + Log.e(TAG, "onNotifyFailure: " + exception); | |
| 193 | + } | |
| 194 | + | |
| 195 | + @Override | |
| 196 | + public void onCharacteristicChanged(byte[] data) { | |
| 197 | + try { | |
| 198 | + Log.e(TAG, "onCharacteristicChanged: " + new String(data, "UTF-8")); | |
| 199 | + } catch (UnsupportedEncodingException e) { | |
| 200 | + e.printStackTrace(); | |
| 201 | + } | |
| 202 | + } | |
| 203 | + } | |
| 204 | + ); | |
| 205 | + | |
| 206 | + | |
| 207 | + } | |
| 208 | + | |
| 209 | + // 连接中断,isActiveDisConnected表示是否是主动调用了断开连接方法 | |
| 210 | + @Override | |
| 211 | + public void onDisConnected(boolean isActiveDisConnected, BleDevice device, BluetoothGatt gatt, int status) { | |
| 212 | + | |
| 213 | + } | |
| 214 | + }); | |
| 215 | + } | |
| 216 | + | |
| 217 | + /** | |
| 218 | + * 开始扫描蓝牙设备 | |
| 219 | + */ | |
| 220 | + public void scanBlueToothDevice() { | |
| 221 | + if (null == getContext()) { | |
| 222 | + return; | |
| 223 | + } | |
| 224 | + //隐藏loading视图 | |
| 225 | + hideView(fragment.binding.llRetry); | |
| 226 | + if (null != bleDevices) { | |
| 227 | + bleDevices.clear(); | |
| 228 | + } | |
| 229 | + BleManager.getInstance().scan(new BleScanCallback() { | |
| 230 | + // 扫描结束,列出所有扫描到的符合扫描规则的BLE设备(主线程) | |
| 231 | + @Override | |
| 232 | + public void onScanFinished(List<BleDevice> scanResultList) { | |
| 233 | + if (null == getContext()) { | |
| 234 | + return; | |
| 235 | + } | |
| 236 | + //判断结果是否为空 | |
| 237 | + if (null == bleDevices || bleDevices.size() < 1) { | |
| 238 | + //隐藏loading视图 | |
| 239 | + hideView(fragment.binding.llLoading); | |
| 240 | + //显示重试视图 | |
| 241 | + showView(fragment.binding.llRetry); | |
| 242 | + } | |
| 243 | + | |
| 244 | + } | |
| 245 | + | |
| 246 | + // 开始扫描(主线程) | |
| 247 | + @Override | |
| 248 | + public void onScanStarted(boolean success) { | |
| 249 | + //隐藏重试 | |
| 250 | + hideView(fragment.binding.llRetry); | |
| 251 | + //显示loading | |
| 252 | + showView(fragment.binding.llLoading); | |
| 253 | + } | |
| 254 | + | |
| 255 | + // 扫描到一个符合扫描规则的BLE设备(主线程) | |
| 256 | + @Override | |
| 257 | + public void onScanning(BleDevice bleDevice) { | |
| 258 | + if (TextUtils.isEmpty(bleDevice.getName()) || bleDevice.getName().indexOf("HEMU-") == -1) { | |
| 259 | + return; | |
| 260 | + } | |
| 261 | + | |
| 262 | + if (null != adapter) { | |
| 263 | + adapter.addListData(bleDevice); | |
| 264 | + //隐藏loading | |
| 265 | + hideView(fragment.binding.llLoading); | |
| 266 | + //隐藏重试 | |
| 267 | + hideView(fragment.binding.llRetry); | |
| 268 | + | |
| 269 | + } | |
| 270 | + } | |
| 271 | + }); | |
| 272 | + } | |
| 273 | + | |
| 274 | + /** | |
| 275 | + * 隐藏视图 | |
| 276 | + * | |
| 277 | + * @param view | |
| 278 | + */ | |
| 279 | + private void hideView(View view) { | |
| 280 | + if (view.getVisibility() == View.VISIBLE) { | |
| 281 | + view.setVisibility(View.GONE); | |
| 282 | + } | |
| 283 | + } | |
| 284 | + | |
| 285 | + /** | |
| 286 | + * 显示视图 | |
| 287 | + * | |
| 288 | + * @param view | |
| 289 | + */ | |
| 290 | + private void showView(View view) { | |
| 291 | + if (view.getVisibility() != View.VISIBLE) { | |
| 292 | + view.setVisibility(View.VISIBLE); | |
| 293 | + } | |
| 294 | + } | |
| 295 | + | |
| 296 | + /** | |
| 297 | + * 设置绑定按钮不可点击 | |
| 298 | + */ | |
| 299 | + private void setBondDeviceCantClick() { | |
| 300 | + if (null == getContext()) { | |
| 301 | + return; | |
| 302 | + } | |
| 303 | + if (fragment.binding.btnBondDevice.isClickable()) { | |
| 304 | + fragment.binding.btnBondDevice.setClickable(false); | |
| 305 | + fragment.binding.btnBondDevice.setBackground(ContextCompat.getDrawable(getContext(), R.drawable.shape_btn_press)); | |
| 306 | + } | |
| 307 | + } | |
| 308 | + | |
| 309 | + /** | |
| 310 | + * 设置绑定按钮可点击 | |
| 311 | + */ | |
| 312 | + private void setBondDeviceClick() { | |
| 313 | + if (null == getContext()) { | |
| 314 | + return; | |
| 315 | + } | |
| 316 | + if (!fragment.binding.btnBondDevice.isClickable()) { | |
| 317 | + fragment.binding.btnBondDevice.setClickable(true); | |
| 318 | + fragment.binding.btnBondDevice.setBackground(ContextCompat.getDrawable(getContext(), R.drawable.selector_btn_green)); | |
| 319 | + } | |
| 320 | + } | |
| 321 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/frame/view/SelectWifiFragmentView.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/frame/view/SelectWifiFragmentView.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.frame.view; | |
| 2 | + | |
| 3 | +import android.app.Activity; | |
| 4 | +import android.content.BroadcastReceiver; | |
| 5 | +import android.content.Context; | |
| 6 | +import android.content.Intent; | |
| 7 | +import android.content.IntentFilter; | |
| 8 | +import android.net.NetworkInfo; | |
| 9 | +import android.net.wifi.ScanResult; | |
| 10 | +import android.net.wifi.WifiManager; | |
| 11 | +import android.support.v7.widget.LinearLayoutManager; | |
| 12 | +import android.util.Log; | |
| 13 | + | |
| 14 | +import com.cnlive.strike.xiaojiaspeaker.model.WifiConnModel; | |
| 15 | +import com.cnlive.strike.xiaojiaspeaker.ui.activity.SpeakerMainActivity; | |
| 16 | +import com.cnlive.strike.xiaojiaspeaker.ui.adapter.WifiRecycleAdapter; | |
| 17 | +import com.cnlive.strike.xiaojiaspeaker.ui.fragment.SelectWifiFragment; | |
| 18 | +import com.cnlive.strike.xiaojiaspeaker.util.WifiUtils; | |
| 19 | +import com.hannesdorfmann.mosby3.mvp.MvpView; | |
| 20 | + | |
| 21 | +import java.util.ArrayList; | |
| 22 | +import java.util.List; | |
| 23 | + | |
| 24 | +public class SelectWifiFragmentView implements MvpView { | |
| 25 | + private SelectWifiFragment fragment; | |
| 26 | + private WifiRecycleAdapter adapter; | |
| 27 | + private List<ScanResult> results = new ArrayList<>(); | |
| 28 | + private WifiUtils wifiUtils; | |
| 29 | + private String TAG = "SelectWifiView"; | |
| 30 | + | |
| 31 | + public SelectWifiFragmentView(SelectWifiFragment fragment) { | |
| 32 | + this.fragment = fragment; | |
| 33 | + wifiUtils = new WifiUtils(fragment.getActivity()); | |
| 34 | + } | |
| 35 | + | |
| 36 | + public Activity getContext() { | |
| 37 | + return fragment == null ? null : fragment.getActivity(); | |
| 38 | + } | |
| 39 | + | |
| 40 | + public void initWifiList() { | |
| 41 | + if (null == adapter) { | |
| 42 | + adapter = new WifiRecycleAdapter(getContext(), results); | |
| 43 | + fragment.binding.rvWifi.setLayoutManager(new LinearLayoutManager(getContext())); | |
| 44 | + fragment.binding.rvWifi.setAdapter(adapter); | |
| 45 | + } | |
| 46 | + wifiUtils.startScanWifi(); | |
| 47 | + } | |
| 48 | + | |
| 49 | + public void updateWifiList() { | |
| 50 | + List<ScanResult> scanResults = wifiUtils.getScanResults(); | |
| 51 | + if (null != scanResults && null != results) { | |
| 52 | + results.clear(); | |
| 53 | + results.addAll(scanResults); | |
| 54 | + if (null != adapter) { | |
| 55 | + adapter.notifyDataSetChanged(); | |
| 56 | + } | |
| 57 | + } | |
| 58 | + } | |
| 59 | +} | |
| 60 | + | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/listener/WifiChangeListener.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/listener/WifiChangeListener.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.listener; | |
| 2 | + | |
| 3 | +import android.net.NetworkInfo; | |
| 4 | +import android.net.wifi.ScanResult; | |
| 5 | + | |
| 6 | +import com.cnlive.strike.xiaojiaspeaker.model.WifiConnModel; | |
| 7 | + | |
| 8 | +public interface WifiChangeListener { | |
| 9 | + void onScanResultAvailable(); | |
| 10 | + | |
| 11 | + void onWiFiStateChanged(int wifiState); | |
| 12 | + | |
| 13 | + void onNetWorkStateChanged(NetworkInfo.DetailedState state, String SSID); | |
| 14 | + | |
| 15 | + void onWifiPasswordFault(); | |
| 16 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/model/BlueToothMsgEvent.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/model/BlueToothMsgEvent.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.model; | |
| 2 | + | |
| 3 | +public class BlueToothMsgEvent { | |
| 4 | + public static final int BOND_DEVICE = 1;//配对 | |
| 5 | + public static final int BOND_DEVICE_SUCCESS = 2;//配对成功 | |
| 6 | + public static final int CONN_DEVICE_SUCCESS = 3;//连接成功 | |
| 7 | + public static final int CONN_DEVICE_FAILED = 4;//连接失败 | |
| 8 | + | |
| 9 | + public BlueToothMsgEvent(int msgType, Object data) { | |
| 10 | + this.msgType = msgType; | |
| 11 | + this.data = data; | |
| 12 | + } | |
| 13 | + | |
| 14 | + public BlueToothMsgEvent(int msgType, Object data, int position) { | |
| 15 | + this.msgType = msgType; | |
| 16 | + this.data = data; | |
| 17 | + this.position = position; | |
| 18 | + } | |
| 19 | + | |
| 20 | + private int msgType; | |
| 21 | + private Object data; | |
| 22 | + private int position; | |
| 23 | + | |
| 24 | + public int getPosition() { | |
| 25 | + return position; | |
| 26 | + } | |
| 27 | + | |
| 28 | + public void setPosition(int position) { | |
| 29 | + this.position = position; | |
| 30 | + } | |
| 31 | + | |
| 32 | + public int getMsgType() { | |
| 33 | + return msgType; | |
| 34 | + } | |
| 35 | + | |
| 36 | + public void setMsgType(int msgType) { | |
| 37 | + this.msgType = msgType; | |
| 38 | + } | |
| 39 | + | |
| 40 | + public Object getData() { | |
| 41 | + return data; | |
| 42 | + } | |
| 43 | + | |
| 44 | + public void setData(Object data) { | |
| 45 | + this.data = data; | |
| 46 | + } | |
| 47 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/model/BluetoothDeviceInfo.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/model/BluetoothDeviceInfo.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.model; | |
| 2 | + | |
| 3 | +import android.bluetooth.BluetoothDevice; | |
| 4 | + | |
| 5 | +public class BluetoothDeviceInfo { | |
| 6 | + private BluetoothDevice bluetoothDevice; | |
| 7 | + private boolean connect; | |
| 8 | + | |
| 9 | + public BluetoothDevice getBluetoothDevice() { | |
| 10 | + return bluetoothDevice; | |
| 11 | + } | |
| 12 | + | |
| 13 | + public void setBluetoothDevice(BluetoothDevice bluetoothDevice) { | |
| 14 | + this.bluetoothDevice = bluetoothDevice; | |
| 15 | + } | |
| 16 | + | |
| 17 | + public boolean isConnect() { | |
| 18 | + return connect; | |
| 19 | + } | |
| 20 | + | |
| 21 | + public void setConnect(boolean connect) { | |
| 22 | + this.connect = connect; | |
| 23 | + } | |
| 24 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/model/WifiConnModel.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/model/WifiConnModel.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.model; | |
| 2 | + | |
| 3 | +import android.net.wifi.ScanResult; | |
| 4 | + | |
| 5 | +public class WifiConnModel { | |
| 6 | + public static final int WIFI_NORMAL = 0; | |
| 7 | + public static final int WIFI_CONNECTING = 1; | |
| 8 | + public static final int WIFI_CONN_SUCCESS = 2; | |
| 9 | + public static final int WIFI_CONN_FAILED = 3; | |
| 10 | + public static final int WIFI_BREAK_CONN = 4;//断开连接 | |
| 11 | + private int state; | |
| 12 | + private ScanResult scanResult; | |
| 13 | + private boolean isCurrentConn;//是否是当前连接的 | |
| 14 | + | |
| 15 | + public boolean isCurrentConn() { | |
| 16 | + return isCurrentConn; | |
| 17 | + } | |
| 18 | + | |
| 19 | + public void setCurrentConn(boolean currentConn) { | |
| 20 | + isCurrentConn = currentConn; | |
| 21 | + } | |
| 22 | + | |
| 23 | + public int getState() { | |
| 24 | + return state; | |
| 25 | + } | |
| 26 | + | |
| 27 | + public void setState(int state) { | |
| 28 | + this.state = state; | |
| 29 | + } | |
| 30 | + | |
| 31 | + public ScanResult getScanResult() { | |
| 32 | + return scanResult; | |
| 33 | + } | |
| 34 | + | |
| 35 | + public void setScanResult(ScanResult scanResult) { | |
| 36 | + this.scanResult = scanResult; | |
| 37 | + } | |
| 38 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/model/WifiMsgEvent.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/model/WifiMsgEvent.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.model; | |
| 2 | + | |
| 3 | +public class WifiMsgEvent { | |
| 4 | + public static final int RECEIVE_MSG = 1;//收到信息 | |
| 5 | + | |
| 6 | + public WifiMsgEvent(int msgType, Object data) { | |
| 7 | + this.msgType = msgType; | |
| 8 | + this.data = data; | |
| 9 | + } | |
| 10 | + | |
| 11 | + public WifiMsgEvent(int msgType, Object data, int position) { | |
| 12 | + this.msgType = msgType; | |
| 13 | + this.data = data; | |
| 14 | + this.position = position; | |
| 15 | + } | |
| 16 | + | |
| 17 | + private int msgType; | |
| 18 | + private Object data; | |
| 19 | + private int position; | |
| 20 | + | |
| 21 | + public int getPosition() { | |
| 22 | + return position; | |
| 23 | + } | |
| 24 | + | |
| 25 | + public void setPosition(int position) { | |
| 26 | + this.position = position; | |
| 27 | + } | |
| 28 | + | |
| 29 | + public int getMsgType() { | |
| 30 | + return msgType; | |
| 31 | + } | |
| 32 | + | |
| 33 | + public void setMsgType(int msgType) { | |
| 34 | + this.msgType = msgType; | |
| 35 | + } | |
| 36 | + | |
| 37 | + public Object getData() { | |
| 38 | + return data; | |
| 39 | + } | |
| 40 | + | |
| 41 | + public void setData(Object data) { | |
| 42 | + this.data = data; | |
| 43 | + } | |
| 44 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/BlueToothHelpActivity.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/BlueToothHelpActivity.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.activity; | |
| 2 | + | |
| 3 | +import android.app.Activity; | |
| 4 | +import android.content.Intent; | |
| 5 | +import android.databinding.DataBindingUtil; | |
| 6 | +import android.support.v4.content.ContextCompat; | |
| 7 | +import android.support.v7.app.AppCompatActivity; | |
| 8 | +import android.os.Bundle; | |
| 9 | +import android.view.View; | |
| 10 | + | |
| 11 | +import com.cnlive.libs.base.util.StatusBarUtil; | |
| 12 | +import com.cnlive.libs.base.util.StatusBarUtil2; | |
| 13 | +import com.cnlive.strike.xiaojiaspeaker.R; | |
| 14 | +import com.cnlive.strike.xiaojiaspeaker.databinding.ActivityBlueToothHelpBinding; | |
| 15 | + | |
| 16 | +public class BlueToothHelpActivity extends AppCompatActivity { | |
| 17 | + private ActivityBlueToothHelpBinding binding; | |
| 18 | + | |
| 19 | + @Override | |
| 20 | + protected void onCreate(Bundle savedInstanceState) { | |
| 21 | + super.onCreate(savedInstanceState); | |
| 22 | + binding = DataBindingUtil.setContentView(this, R.layout.activity_blue_tooth_help); | |
| 23 | + initTopBar(); | |
| 24 | + } | |
| 25 | + | |
| 26 | + private void initTopBar() { | |
| 27 | + StatusBarUtil.setStatusBarWrite(this); | |
| 28 | + StatusBarUtil2.setColor(this, ContextCompat.getColor(this, R.color.white), 0); | |
| 29 | + if (null != binding) { | |
| 30 | + binding.topbar.setTitle("帮助").setTextColor(ContextCompat.getColor(this, R.color.color_282828)); | |
| 31 | + //设置返回按钮 | |
| 32 | + binding.topbar.addLeftImageButton(R.drawable.icon_back, R.id.left_back).setOnClickListener(new View.OnClickListener() { | |
| 33 | + @Override | |
| 34 | + public void onClick(View view) { | |
| 35 | + finish(); | |
| 36 | + } | |
| 37 | + }); | |
| 38 | + } | |
| 39 | + } | |
| 40 | + | |
| 41 | + public static void startActivity(Activity activity) { | |
| 42 | + activity.startActivity(new Intent(activity, BlueToothHelpActivity.class)); | |
| 43 | + } | |
| 44 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/BlueToothStep1Activity.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/BlueToothStep1Activity.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.activity; | |
| 2 | + | |
| 3 | +import android.app.Activity; | |
| 4 | +import android.content.Intent; | |
| 5 | +import android.databinding.DataBindingUtil; | |
| 6 | +import android.support.v4.content.ContextCompat; | |
| 7 | +import android.support.v7.app.AppCompatActivity; | |
| 8 | +import android.os.Bundle; | |
| 9 | +import android.view.View; | |
| 10 | + | |
| 11 | +import com.cnlive.libs.base.util.StatusBarUtil; | |
| 12 | +import com.cnlive.libs.base.util.StatusBarUtil2; | |
| 13 | +import com.cnlive.strike.xiaojiaspeaker.R; | |
| 14 | +import com.cnlive.strike.xiaojiaspeaker.databinding.ActivityBlueToothStep1Binding; | |
| 15 | + | |
| 16 | +public class BlueToothStep1Activity extends AppCompatActivity { | |
| 17 | + private ActivityBlueToothStep1Binding binding; | |
| 18 | + | |
| 19 | + @Override | |
| 20 | + protected void onCreate(Bundle savedInstanceState) { | |
| 21 | + super.onCreate(savedInstanceState); | |
| 22 | + binding = DataBindingUtil.setContentView(this, R.layout.activity_blue_tooth_step1); | |
| 23 | + initTopBar(); | |
| 24 | + initView(); | |
| 25 | + } | |
| 26 | + | |
| 27 | + private void initView() { | |
| 28 | + //下一步 | |
| 29 | + binding.btnNext.setOnClickListener(new View.OnClickListener() { | |
| 30 | + @Override | |
| 31 | + public void onClick(View view) { | |
| 32 | + BlueToothStep2Activity.startActivity(BlueToothStep1Activity.this); | |
| 33 | + finish(); | |
| 34 | + } | |
| 35 | + }); | |
| 36 | + } | |
| 37 | + | |
| 38 | + private void initTopBar() { | |
| 39 | + StatusBarUtil.setStatusBarWrite(this); | |
| 40 | + StatusBarUtil2.setColor(this, ContextCompat.getColor(this, R.color.white), 0); | |
| 41 | + if (null != binding) { | |
| 42 | + //设置返回按钮 | |
| 43 | + binding.topbar.addLeftImageButton(R.drawable.icon_back, R.id.left_back).setOnClickListener(new View.OnClickListener() { | |
| 44 | + @Override | |
| 45 | + public void onClick(View view) { | |
| 46 | + finish(); | |
| 47 | + } | |
| 48 | + }); | |
| 49 | + } | |
| 50 | + } | |
| 51 | + | |
| 52 | + public static void startActivity(Activity activity) { | |
| 53 | + activity.startActivity(new Intent(activity, BlueToothStep1Activity.class)); | |
| 54 | + } | |
| 55 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/BlueToothStep2Activity.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/BlueToothStep2Activity.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.activity; | |
| 2 | + | |
| 3 | +import android.Manifest; | |
| 4 | +import android.app.Activity; | |
| 5 | +import android.bluetooth.BluetoothAdapter; | |
| 6 | +import android.content.BroadcastReceiver; | |
| 7 | +import android.content.Context; | |
| 8 | +import android.content.Intent; | |
| 9 | +import android.content.IntentFilter; | |
| 10 | +import android.content.pm.PackageManager; | |
| 11 | +import android.databinding.DataBindingUtil; | |
| 12 | +import android.net.Uri; | |
| 13 | +import android.provider.Settings; | |
| 14 | +import android.support.annotation.NonNull; | |
| 15 | +import android.support.v4.app.ActivityCompat; | |
| 16 | +import android.support.v4.content.ContextCompat; | |
| 17 | +import android.support.v7.app.AppCompatActivity; | |
| 18 | +import android.os.Bundle; | |
| 19 | +import android.util.Log; | |
| 20 | +import android.view.View; | |
| 21 | +import android.view.animation.Animation; | |
| 22 | +import android.view.animation.AnimationUtils; | |
| 23 | + | |
| 24 | +import com.clj.fastble.BleManager; | |
| 25 | +import com.cnlive.libs.base.util.StatusBarUtil; | |
| 26 | +import com.cnlive.libs.base.util.StatusBarUtil2; | |
| 27 | +import com.cnlive.strike.xiaojiaspeaker.R; | |
| 28 | +import com.cnlive.strike.xiaojiaspeaker.databinding.ActivityBlueToothStep2Binding; | |
| 29 | +import com.cnlive.strike.xiaojiaspeaker.ui.widget.SelectDialog; | |
| 30 | +import com.cnlive.strike.xiaojiaspeaker.util.lib_permisshelper.PermissionsListener; | |
| 31 | +import com.cnlive.strike.xiaojiaspeaker.util.lib_permisshelper.PermissionsUtils; | |
| 32 | + | |
| 33 | +public class BlueToothStep2Activity extends AppCompatActivity { | |
| 34 | + private ActivityBlueToothStep2Binding binding; | |
| 35 | + private PermissionsUtils mPermissionsUtils = new PermissionsUtils();//权限申请 | |
| 36 | + private int permissionRequestCount = 0;//权限请求次数 | |
| 37 | + private SelectDialog selectDialog; | |
| 38 | + private String TAG = "BlueToothStep2"; | |
| 39 | + private boolean isClickNextBtn = false; | |
| 40 | + | |
| 41 | + @Override | |
| 42 | + protected void onCreate(Bundle savedInstanceState) { | |
| 43 | + super.onCreate(savedInstanceState); | |
| 44 | + binding = DataBindingUtil.setContentView(this, R.layout.activity_blue_tooth_step2); | |
| 45 | + initTopBar(); | |
| 46 | + initView(); | |
| 47 | + initPermissionDefineTip(); | |
| 48 | + initBlueToothReceiver(); | |
| 49 | + } | |
| 50 | + | |
| 51 | + @Override | |
| 52 | + protected void onDestroy() { | |
| 53 | + super.onDestroy(); | |
| 54 | + if (null != mStatusReceive) { | |
| 55 | + unregisterReceiver(mStatusReceive); | |
| 56 | + } | |
| 57 | + } | |
| 58 | + | |
| 59 | + private void initBlueToothReceiver() { | |
| 60 | + //监听蓝牙是否开启 | |
| 61 | + IntentFilter statusFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); | |
| 62 | + registerReceiver(mStatusReceive, statusFilter); | |
| 63 | + } | |
| 64 | + | |
| 65 | + private void initView() { | |
| 66 | + BleManager.getInstance().init(getApplication()); | |
| 67 | + //上一步 | |
| 68 | + binding.tvPreviousStep.setOnClickListener(new View.OnClickListener() { | |
| 69 | + @Override | |
| 70 | + public void onClick(View view) { | |
| 71 | + BlueToothStep1Activity.startActivity(BlueToothStep2Activity.this); | |
| 72 | + finish(); | |
| 73 | + } | |
| 74 | + }); | |
| 75 | + //下一步 | |
| 76 | + binding.btnNext.setOnClickListener(new View.OnClickListener() { | |
| 77 | + @Override | |
| 78 | + public void onClick(View view) { | |
| 79 | + //判断蓝牙是否打开 | |
| 80 | + getPermissionsWithTip(); | |
| 81 | + } | |
| 82 | + }); | |
| 83 | + } | |
| 84 | + | |
| 85 | + private void initTopBar() { | |
| 86 | + StatusBarUtil.setStatusBarWrite(this); | |
| 87 | + StatusBarUtil2.setColor(this, ContextCompat.getColor(this, R.color.white), 0); | |
| 88 | + if (null != binding) { | |
| 89 | + //设置返回按钮 | |
| 90 | + binding.topbar.addLeftImageButton(R.drawable.icon_back, R.id.left_back).setOnClickListener(new View.OnClickListener() { | |
| 91 | + @Override | |
| 92 | + public void onClick(View view) { | |
| 93 | + finish(); | |
| 94 | + } | |
| 95 | + }); | |
| 96 | + } | |
| 97 | + } | |
| 98 | + | |
| 99 | + public static void startActivity(Activity activity) { | |
| 100 | + activity.startActivity(new Intent(activity, BlueToothStep2Activity.class)); | |
| 101 | + } | |
| 102 | + | |
| 103 | + /** | |
| 104 | + * 一次申请一组权限(使用拒绝弹框)点击事件 | |
| 105 | + */ | |
| 106 | + public void getPermissionsWithTip() { | |
| 107 | + if (1 == permissionRequestCount) { | |
| 108 | + return; | |
| 109 | + } | |
| 110 | + mPermissionsUtils | |
| 111 | + .setPermissionsListener(new PermissionsListener() { | |
| 112 | + @Override | |
| 113 | + public void onDenied(String[] deniedPermissions) { | |
| 114 | +// getPermissionsWithTip(); | |
| 115 | + } | |
| 116 | + | |
| 117 | + @Override | |
| 118 | + public void onGranted() { | |
| 119 | + isClickNextBtn = true; | |
| 120 | + //判断蓝牙是否打开 | |
| 121 | + if (BleManager.getInstance().isBlueEnable()) { | |
| 122 | + SearchDeviceActivity.startActivity(BlueToothStep2Activity.this); | |
| 123 | + } else { | |
| 124 | + BleManager.getInstance().enableBluetooth(); | |
| 125 | + } | |
| 126 | + | |
| 127 | + } | |
| 128 | + }) | |
| 129 | + .withActivity(BlueToothStep2Activity.this) | |
| 130 | + .getPermissions(BlueToothStep2Activity.this | |
| 131 | + , 100 | |
| 132 | + , Manifest.permission.INTERNET | |
| 133 | + , Manifest.permission.ACCESS_FINE_LOCATION | |
| 134 | + , Manifest.permission.ACCESS_COARSE_LOCATION | |
| 135 | + ); | |
| 136 | +// .getPermissionsWithTips(MainActivity.this | |
| 137 | +// ,100 | |
| 138 | +// , new String[]{"人家要录音","我们需要读取你的信息,磨磨唧唧的","我要上网","我要读内存卡","我要看日历","我要定位"} | |
| 139 | +// , Manifest.permission.RECORD_AUDIO | |
| 140 | +// , Manifest.permission.READ_SMS | |
| 141 | +// , Manifest.permission.INTERNET | |
| 142 | +// , Manifest.permission.READ_EXTERNAL_STORAGE | |
| 143 | +// , Manifest.permission.READ_CALENDAR | |
| 144 | +// , Manifest.permission.ACCESS_FINE_LOCATION); | |
| 145 | + } | |
| 146 | + | |
| 147 | + | |
| 148 | + /** | |
| 149 | + * 权限回调 | |
| 150 | + * | |
| 151 | + * @param requestCode | |
| 152 | + * @param permissions | |
| 153 | + * @param grantResults | |
| 154 | + */ | |
| 155 | + @Override | |
| 156 | + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, | |
| 157 | + @NonNull int[] grantResults) { | |
| 158 | + super.onRequestPermissionsResult(requestCode, permissions, grantResults); | |
| 159 | + if (1 == permissionRequestCount) { | |
| 160 | + return; | |
| 161 | + } | |
| 162 | + boolean isShowPermissionTip = true; | |
| 163 | + for (int i = 0; i < grantResults.length; i++) {//判断权限的结果,如果有被拒绝,就return | |
| 164 | + if (grantResults[i] == PackageManager.PERMISSION_DENIED) { | |
| 165 | + if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) { | |
| 166 | + isShowPermissionTip = false; | |
| 167 | + break; | |
| 168 | + } | |
| 169 | + } | |
| 170 | + } | |
| 171 | + if (isShowPermissionTip) { | |
| 172 | + mPermissionsUtils.dealResult(requestCode, permissions, grantResults); | |
| 173 | + } else { | |
| 174 | + if (0 == permissionRequestCount) { | |
| 175 | + selectDialog.setCancelable(false); | |
| 176 | + selectDialog.setCanceledOnTouchOutside(false); | |
| 177 | + if (!selectDialog.isShowing()) { | |
| 178 | + selectDialog.show(); | |
| 179 | + permissionRequestCount = 1; | |
| 180 | + } | |
| 181 | + } else { | |
| 182 | + return; | |
| 183 | + } | |
| 184 | + } | |
| 185 | + } | |
| 186 | + | |
| 187 | + private void initPermissionDefineTip() { | |
| 188 | + selectDialog = new SelectDialog(BlueToothStep2Activity.this, "您尚未授予程序运行所需权限\n是否设置?", | |
| 189 | + "取消", new SelectDialog.DialogInterface() { | |
| 190 | + @Override | |
| 191 | + public void onClick(SelectDialog dialog) { | |
| 192 | + dialog.dismiss(); | |
| 193 | + permissionRequestCount = 0; | |
| 194 | + } | |
| 195 | + }, "设置", new SelectDialog.DialogInterface() { | |
| 196 | + @Override | |
| 197 | + public void onClick(SelectDialog dialog) { | |
| 198 | + dialog.dismiss(); | |
| 199 | + Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); | |
| 200 | + Uri uri = Uri.fromParts("package", getPackageName(), null); | |
| 201 | + intent.setData(uri); | |
| 202 | + startActivityForResult(intent, 0); | |
| 203 | + permissionRequestCount = 0; | |
| 204 | + } | |
| 205 | + }); | |
| 206 | + selectDialog.setRightBtnColor(R.color.green); | |
| 207 | + | |
| 208 | + } | |
| 209 | + | |
| 210 | + | |
| 211 | + private BroadcastReceiver mStatusReceive = new BroadcastReceiver() { | |
| 212 | + | |
| 213 | + @Override | |
| 214 | + public void onReceive(Context context, Intent intent) { | |
| 215 | + switch (intent.getAction()) { | |
| 216 | + case BluetoothAdapter.ACTION_STATE_CHANGED: | |
| 217 | + int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0); | |
| 218 | + switch (blueState) { | |
| 219 | + case BluetoothAdapter.STATE_TURNING_ON: | |
| 220 | + Log.e(TAG, "监听到蓝牙已开启"); | |
| 221 | + if (isClickNextBtn) { | |
| 222 | + SearchDeviceActivity.startActivity(BlueToothStep2Activity.this); | |
| 223 | + finish(); | |
| 224 | + } | |
| 225 | + break; | |
| 226 | + case BluetoothAdapter.STATE_ON: | |
| 227 | + Log.e(TAG, "监听到蓝牙已启动"); | |
| 228 | + break; | |
| 229 | + case BluetoothAdapter.STATE_TURNING_OFF: | |
| 230 | + break; | |
| 231 | + case BluetoothAdapter.STATE_OFF: | |
| 232 | + break; | |
| 233 | + } | |
| 234 | + break; | |
| 235 | + } | |
| 236 | + } | |
| 237 | + }; | |
| 238 | + | |
| 239 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/BluetoothConnActivity.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/BluetoothConnActivity.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.activity; | |
| 2 | + | |
| 3 | +import android.bluetooth.BluetoothAdapter; | |
| 4 | +import android.bluetooth.BluetoothDevice; | |
| 5 | +import android.bluetooth.BluetoothGatt; | |
| 6 | +import android.content.Intent; | |
| 7 | +import android.databinding.DataBindingUtil; | |
| 8 | +import android.os.Bundle; | |
| 9 | +import android.support.v7.app.AppCompatActivity; | |
| 10 | +import android.support.v7.widget.DefaultItemAnimator; | |
| 11 | +import android.support.v7.widget.LinearLayoutManager; | |
| 12 | +import android.text.TextUtils; | |
| 13 | +import android.util.Log; | |
| 14 | +import android.view.View; | |
| 15 | +import android.widget.Button; | |
| 16 | + | |
| 17 | +import com.clj.fastble.BleManager; | |
| 18 | +import com.clj.fastble.callback.BleGattCallback; | |
| 19 | +import com.clj.fastble.callback.BleNotifyCallback; | |
| 20 | +import com.clj.fastble.callback.BleScanCallback; | |
| 21 | +import com.clj.fastble.callback.BleWriteCallback; | |
| 22 | +import com.clj.fastble.data.BleDevice; | |
| 23 | +import com.clj.fastble.exception.BleException; | |
| 24 | +import com.clj.fastble.scan.BleScanRuleConfig; | |
| 25 | +import com.cnlive.libs.base.util.AlertUtil; | |
| 26 | +import com.cnlive.strike.xiaojiaspeaker.R; | |
| 27 | +import com.cnlive.strike.xiaojiaspeaker.constants.BlufiConstants; | |
| 28 | +import com.cnlive.strike.xiaojiaspeaker.databinding.ActivityBluetoothMainBinding; | |
| 29 | +import com.cnlive.strike.xiaojiaspeaker.model.BlueToothMsgEvent; | |
| 30 | +import com.cnlive.strike.xiaojiaspeaker.model.BluetoothDeviceInfo; | |
| 31 | +import com.cnlive.strike.xiaojiaspeaker.ui.adapter.BluetoothDeviceAdapter; | |
| 32 | + | |
| 33 | +import org.greenrobot.eventbus.EventBus; | |
| 34 | +import org.greenrobot.eventbus.Subscribe; | |
| 35 | +import org.greenrobot.eventbus.ThreadMode; | |
| 36 | + | |
| 37 | +import java.io.UnsupportedEncodingException; | |
| 38 | +import java.lang.reflect.Field; | |
| 39 | +import java.lang.reflect.Method; | |
| 40 | +import java.util.ArrayList; | |
| 41 | +import java.util.List; | |
| 42 | +import java.util.Set; | |
| 43 | + | |
| 44 | + | |
| 45 | +public class BluetoothConnActivity extends AppCompatActivity { | |
| 46 | + private static final String TAG = "BluetoothConnActivity"; | |
| 47 | + private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); | |
| 48 | + private ActivityBluetoothMainBinding binding; | |
| 49 | + private List<BleDevice> bleDevices = new ArrayList<>(); | |
| 50 | + private BluetoothDeviceAdapter adapter; | |
| 51 | + | |
| 52 | + @Override | |
| 53 | + protected void onCreate(Bundle savedInstanceState) { | |
| 54 | + super.onCreate(savedInstanceState); | |
| 55 | + binding = DataBindingUtil.setContentView(this, R.layout.activity_bluetooth_main); | |
| 56 | + initView(); | |
| 57 | + initBlueToothScanConfig(); | |
| 58 | + initListAdapter(); | |
| 59 | + openBluetooth(); | |
| 60 | + if (!EventBus.getDefault().isRegistered(this)) { | |
| 61 | + EventBus.getDefault().register(this); | |
| 62 | + } | |
| 63 | + } | |
| 64 | + | |
| 65 | + private void initListAdapter() { | |
| 66 | + adapter = new BluetoothDeviceAdapter(this, bleDevices); | |
| 67 | + adapter.setHasStableIds(true); | |
| 68 | + binding.rvBlueTooth.setLayoutManager(new LinearLayoutManager(BluetoothConnActivity.this)); | |
| 69 | + binding.rvBlueTooth.setAdapter(adapter); | |
| 70 | + ((DefaultItemAnimator) binding.rvBlueTooth.getItemAnimator()).setSupportsChangeAnimations(false); | |
| 71 | + adapter.setOnItemClickListener(new BluetoothDeviceAdapter.OnItemClickListener() { | |
| 72 | + @Override | |
| 73 | + public void onItemClick(int position, BleDevice bleDevice) { | |
| 74 | + BleManager.getInstance().disconnect(bleDevice); | |
| 75 | + BleManager.getInstance().connect(bleDevice, new BleGattCallback() { | |
| 76 | + // 开始连接 | |
| 77 | + @Override | |
| 78 | + public void onStartConnect() { | |
| 79 | + | |
| 80 | + } | |
| 81 | + | |
| 82 | + // 连接失败 | |
| 83 | + @Override | |
| 84 | + public void onConnectFail(BleDevice bleDevice, BleException exception) { | |
| 85 | + | |
| 86 | + } | |
| 87 | + | |
| 88 | + // 连接成功,BleDevice即为所连接的BLE设备 | |
| 89 | + @Override | |
| 90 | + public void onConnectSuccess(final BleDevice bleDevice, BluetoothGatt gatt, int status) { | |
| 91 | + | |
| 92 | + BleManager.getInstance().notify( | |
| 93 | + bleDevice, | |
| 94 | + BlufiConstants.UUID_WIFI_SERVICE.toString(), | |
| 95 | + BlufiConstants.UUID_NOTIFY_CHARACTERISTIC.toString(), | |
| 96 | + new BleNotifyCallback() { | |
| 97 | + @Override | |
| 98 | + public void onNotifySuccess() { | |
| 99 | + Log.e(TAG, "onNotifySuccess: " ); | |
| 100 | + // 打开通知操作成功 | |
| 101 | + BleManager.getInstance().write( | |
| 102 | + bleDevice, | |
| 103 | + BlufiConstants.UUID_WIFI_SERVICE.toString(), | |
| 104 | + BlufiConstants.UUID_WRITE_CHARACTERISTIC.toString(), | |
| 105 | + (getSSIDAndPwd("CNLive-VIP", "cnlIVE_99", "he:28850150e8bd4c830314819939361b77")).getBytes(), | |
| 106 | + new BleWriteCallback() { | |
| 107 | + @Override | |
| 108 | + public void onWriteSuccess(int current, int total, byte[] justWrite) { | |
| 109 | + Log.e(TAG, "onWriteSuccess: " + justWrite.toString()); | |
| 110 | + // 发送数据到设备成功(分包发送的情况下,可以通过方法中返回的参数可以查看发送进度) | |
| 111 | + | |
| 112 | +// if (mIsExit) { | |
| 113 | +// return; | |
| 114 | +// } | |
| 115 | + | |
| 116 | + if (current == total) { | |
| 117 | +// BleManager.getInstance().stopNotify(bleDevice, | |
| 118 | +// BlufiConstants.UUID_WIFI_SERVICE.toString(), | |
| 119 | +// BlufiConstants.UUID_NOTIFY_CHARACTERISTIC.toString()); | |
| 120 | + } | |
| 121 | + } | |
| 122 | + | |
| 123 | + @Override | |
| 124 | + public void onWriteFailure(BleException exception) { | |
| 125 | + Log.e(TAG, "onWriteFailure: "); | |
| 126 | + | |
| 127 | +// if (mIsExit) { | |
| 128 | +// return; | |
| 129 | +// } | |
| 130 | + | |
| 131 | +// mainHandler.post(new Runnable() { | |
| 132 | +// @Override | |
| 133 | +// public void run() { | |
| 134 | +// // 发送数据到设备失败 | |
| 135 | +// getActivityView().onSendWifiFailure("数据发送失败,请确认设备蓝牙正常"); | |
| 136 | +// } | |
| 137 | +// }); | |
| 138 | + | |
| 139 | +// BleManager.getInstance().stopNotify(bleDevice, | |
| 140 | +// BlufiConstants.UUID_WIFI_SERVICE.toString(), | |
| 141 | +// BlufiConstants.UUID_NOTIFY_CHARACTERISTIC.toString()); | |
| 142 | + } | |
| 143 | + }); | |
| 144 | + // | |
| 145 | + } | |
| 146 | + | |
| 147 | + @Override | |
| 148 | + public void onNotifyFailure(BleException exception) { | |
| 149 | + Log.e(TAG, "onNotifyFailure: "+exception ); | |
| 150 | + } | |
| 151 | + | |
| 152 | + @Override | |
| 153 | + public void onCharacteristicChanged(byte[] data) { | |
| 154 | + try { | |
| 155 | + Log.e(TAG, "onCharacteristicChanged: "+ new String(data,"UTF-8")); | |
| 156 | + } catch (UnsupportedEncodingException e) { | |
| 157 | + e.printStackTrace(); | |
| 158 | + } | |
| 159 | + } | |
| 160 | + } | |
| 161 | + ); | |
| 162 | + | |
| 163 | + | |
| 164 | + } | |
| 165 | + | |
| 166 | + // 连接中断,isActiveDisConnected表示是否是主动调用了断开连接方法 | |
| 167 | + @Override | |
| 168 | + public void onDisConnected(boolean isActiveDisConnected, BleDevice device, BluetoothGatt gatt, int status) { | |
| 169 | + | |
| 170 | + } | |
| 171 | + }); | |
| 172 | + // | |
| 173 | + | |
| 174 | + // | |
| 175 | + | |
| 176 | + } | |
| 177 | + }); | |
| 178 | + } | |
| 179 | + | |
| 180 | + public String getSSIDAndPwd(String ssid, String pwd, String uid) { | |
| 181 | + StringBuilder builder = new StringBuilder(); | |
| 182 | + builder.append("1111("); | |
| 183 | + builder.append("v1"); | |
| 184 | + builder.append('#'); | |
| 185 | + builder.append(encode(ssid)); | |
| 186 | + builder.append('#'); | |
| 187 | + builder.append(encode(pwd)); | |
| 188 | + builder.append('#'); | |
| 189 | + builder.append(encode(uid)); | |
| 190 | + builder.append('#'); | |
| 191 | + builder.append(")2222"); | |
| 192 | + String info = builder.toString(); | |
| 193 | + String infoSend = info.replaceAll("(.{16})", "$1DATA"); | |
| 194 | + return "DATA" + infoSend; | |
| 195 | + } | |
| 196 | + | |
| 197 | + /** | |
| 198 | + * 初始化蓝牙扫描 | |
| 199 | + */ | |
| 200 | + private void initBlueToothScanConfig() { | |
| 201 | + BleManager.getInstance().init(getApplication()); | |
| 202 | + BleScanRuleConfig scanRuleConfig = new BleScanRuleConfig.Builder() | |
| 203 | +// .setServiceUuids(serviceUuids) // 只扫描指定的服务的设备,可选 | |
| 204 | +// .setDeviceName(true, names) // 只扫描指定广播名的设备,可选 | |
| 205 | +// .setDeviceMac(mac) // 只扫描指定mac的设备,可选 | |
| 206 | +// .setAutoConnect(isAutoConnect) // 连接时的autoConnect参数,可选,默认false | |
| 207 | + .setScanTimeOut(15000) // 扫描超时时间,可选,默认10秒;小于等于0表示不限制扫描时间 | |
| 208 | + .build(); | |
| 209 | + BleManager.getInstance().initScanRule(scanRuleConfig); | |
| 210 | + } | |
| 211 | + | |
| 212 | + /** | |
| 213 | + * 开始扫描蓝牙设备 | |
| 214 | + */ | |
| 215 | + public void scanBlueToothDevice() { | |
| 216 | + if (null != bleDevices) { | |
| 217 | + bleDevices.clear(); | |
| 218 | + } | |
| 219 | + BleManager.getInstance().scan(new BleScanCallback() { | |
| 220 | + // 扫描结束,列出所有扫描到的符合扫描规则的BLE设备(主线程) | |
| 221 | + @Override | |
| 222 | + public void onScanFinished(List<BleDevice> scanResultList) { | |
| 223 | + binding.rlProgress.setVisibility(View.GONE); | |
| 224 | + | |
| 225 | + } | |
| 226 | + | |
| 227 | + // 开始扫描(主线程) | |
| 228 | + @Override | |
| 229 | + public void onScanStarted(boolean success) { | |
| 230 | + binding.rlProgress.setVisibility(View.VISIBLE); | |
| 231 | + } | |
| 232 | + | |
| 233 | + // 扫描到一个符合扫描规则的BLE设备(主线程) | |
| 234 | + @Override | |
| 235 | + public void onScanning(BleDevice bleDevice) { | |
| 236 | +// Log.e(TAG, "onScanning: " + GsonUtils.toJson(bleDevice)); | |
| 237 | + if (TextUtils.isEmpty(bleDevice.getName())) { | |
| 238 | + return; | |
| 239 | + } | |
| 240 | + if (null != adapter) { | |
| 241 | + adapter.addListData(bleDevice); | |
| 242 | + } | |
| 243 | + } | |
| 244 | + }); | |
| 245 | + } | |
| 246 | + | |
| 247 | + @Override | |
| 248 | + protected void onPause() { | |
| 249 | + super.onPause(); | |
| 250 | + } | |
| 251 | + | |
| 252 | + @Override | |
| 253 | + protected void onDestroy() { | |
| 254 | + super.onDestroy(); | |
| 255 | + if (EventBus.getDefault().isRegistered(this)) { | |
| 256 | + EventBus.getDefault().unregister(this); | |
| 257 | + } | |
| 258 | + BleManager.getInstance().destroy(); | |
| 259 | +// if (receiver != null) { | |
| 260 | +// //取消注册,防止内存泄露(onDestroy被回调代不代表Activity被回收?:具体回收看系统,由GC回收,同时广播会注册到系统 | |
| 261 | +// //管理的ams中,即使activity被回收,reciver也不会被回收,所以一定要取消注册), | |
| 262 | +// if (isRegisterReceiver) { | |
| 263 | +// unregisterReceiver(receiver); | |
| 264 | +// } | |
| 265 | +// } | |
| 266 | + } | |
| 267 | + | |
| 268 | + private void initView() { | |
| 269 | + //搜索蓝牙设备按钮 | |
| 270 | + binding.btnScanBluetooth.setOnClickListener(new View.OnClickListener() { | |
| 271 | + @Override | |
| 272 | + public void onClick(View view) { | |
| 273 | + binding.rlProgress.setVisibility(View.VISIBLE); | |
| 274 | + if (isBluetoothOpen()) { | |
| 275 | + scanBlueToothDevice(); | |
| 276 | + } else { | |
| 277 | + openBluetooth(); | |
| 278 | + } | |
| 279 | + | |
| 280 | + } | |
| 281 | + }); | |
| 282 | + | |
| 283 | + | |
| 284 | +// //监听蓝牙是否开启 | |
| 285 | +// IntentFilter statusFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); | |
| 286 | +// registerReceiver(mStatusReceive, statusFilter); | |
| 287 | + } | |
| 288 | + | |
| 289 | + | |
| 290 | + @Override | |
| 291 | + protected void onActivityResult(int requestCode, int resultCode, Intent data) { | |
| 292 | + if (requestCode == 1) { | |
| 293 | + if (resultCode == RESULT_OK) { | |
| 294 | + AlertUtil.showDeftToast(BluetoothConnActivity.this, "蓝牙已打开"); | |
| 295 | + } else if (resultCode == RESULT_CANCELED) { | |
| 296 | + // ToastUtil.msg(BluetoothConnActivity.this, "取消打开"); | |
| 297 | + } | |
| 298 | + } | |
| 299 | + } | |
| 300 | + | |
| 301 | + /** | |
| 302 | + * 判断蓝牙是否开启 | |
| 303 | + */ | |
| 304 | + private void init() { | |
| 305 | + // 判断手机是否支持蓝牙 | |
| 306 | + if (mBluetoothAdapter == null) { | |
| 307 | + AlertUtil.showDeftToast(BluetoothConnActivity.this, "设备不支持蓝牙!"); | |
| 308 | + return; | |
| 309 | + } | |
| 310 | + // 判断是否打开蓝牙 | |
| 311 | + if (!mBluetoothAdapter.isEnabled()) { | |
| 312 | + //弹出对话框提示用户是后打开 | |
| 313 | + Intent enableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); | |
| 314 | + startActivityForResult(enableBT, 1); | |
| 315 | + } else { | |
| 316 | + // 不做提示,强行打开 | |
| 317 | + // mBluetoothAdapter.enable(); | |
| 318 | + AlertUtil.showDeftToast(BluetoothConnActivity.this, "蓝牙成功打开!"); | |
| 319 | + | |
| 320 | + } | |
| 321 | + } | |
| 322 | + | |
| 323 | + /** | |
| 324 | + * 判断蓝牙是否打开 | |
| 325 | + * | |
| 326 | + * @return boolean | |
| 327 | + */ | |
| 328 | + public boolean isBluetoothOpen() { | |
| 329 | + return this.mBluetoothAdapter.isEnabled(); | |
| 330 | + } | |
| 331 | + | |
| 332 | + | |
| 333 | + /** | |
| 334 | + * 打开蓝牙 | |
| 335 | + */ | |
| 336 | + public void openBluetooth() { | |
| 337 | + if (mBluetoothAdapter == null) { | |
| 338 | + //表明此手机不支持蓝牙 | |
| 339 | + AlertUtil.showDeftToast(this, "该手机无蓝牙设备!"); | |
| 340 | + return; | |
| 341 | + } | |
| 342 | + if (!mBluetoothAdapter.isEnabled()) { //蓝牙未开启,则开启蓝牙 | |
| 343 | + Intent enableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); | |
| 344 | + startActivityForResult(enableBT, 1); | |
| 345 | + | |
| 346 | + } else { | |
| 347 | + AlertUtil.showDeftToast(this, "蓝牙已打开!"); | |
| 348 | + } | |
| 349 | + } | |
| 350 | + | |
| 351 | +// /** | |
| 352 | +// * 搜索蓝牙的方法 | |
| 353 | +// */ | |
| 354 | +// private void startScanBluth() { | |
| 355 | +// getBondBluetoothDeviceData(); | |
| 356 | +// // 判断是否在搜索,如果在搜索,就取消搜索 | |
| 357 | +// if (mBluetoothAdapter.isDiscovering()) { | |
| 358 | +// mBluetoothAdapter.cancelDiscovery(); | |
| 359 | +// } else { | |
| 360 | +// // 开始搜索 | |
| 361 | +// mBluetoothAdapter.startDiscovery(); | |
| 362 | +// QMUITipDialogUtil.loadingDialog(this, "正在搜索蓝牙设备,请稍后...", false); | |
| 363 | +// | |
| 364 | +// } | |
| 365 | +// | |
| 366 | +// } | |
| 367 | + | |
| 368 | + | |
| 369 | +// /** | |
| 370 | +// * 注册异步搜索蓝牙设备的广播 | |
| 371 | +// */ | |
| 372 | +// private void searchDevices() { | |
| 373 | +// // 找到设备的广播 | |
| 374 | +// IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); | |
| 375 | +// filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); | |
| 376 | +// // 注册广播 | |
| 377 | +// registerReceiver(receiver, filter); | |
| 378 | +// isRegisterReceiver = true; | |
| 379 | +// // 搜索完成的广播 | |
| 380 | +// IntentFilter filter1 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); | |
| 381 | +// // 注册广播 | |
| 382 | +// registerReceiver(receiver, filter1); | |
| 383 | +// isRegisterReceiver = true; | |
| 384 | +// Log.e(TAG, "startDiscovery: 注册广播"); | |
| 385 | +// startScanBluth(); | |
| 386 | +// } | |
| 387 | + | |
| 388 | + | |
| 389 | + /** | |
| 390 | + * 获取本机蓝牙地址 | |
| 391 | + */ | |
| 392 | + private String getBluetoothAddress() { | |
| 393 | + try { | |
| 394 | + BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); | |
| 395 | + Field field = bluetoothAdapter.getClass().getDeclaredField("mService"); | |
| 396 | + // 参数值为true,禁用访问控制检查 | |
| 397 | + field.setAccessible(true); | |
| 398 | + Object bluetoothManagerService = field.get(bluetoothAdapter); | |
| 399 | + if (bluetoothManagerService == null) { | |
| 400 | + return null; | |
| 401 | + } | |
| 402 | + Method method = bluetoothManagerService.getClass().getMethod("getAddress"); | |
| 403 | + Object address = method.invoke(bluetoothManagerService); | |
| 404 | + if (address != null && address instanceof String) { | |
| 405 | + return (String) address; | |
| 406 | + } else { | |
| 407 | + return null; | |
| 408 | + } | |
| 409 | + //抛一个总异常省的一堆代码... | |
| 410 | + } catch (Exception e) { | |
| 411 | + e.printStackTrace(); | |
| 412 | + } | |
| 413 | + return null; | |
| 414 | + } | |
| 415 | + | |
| 416 | + | |
| 417 | + /** | |
| 418 | + * 获取已经绑定的蓝牙设备 | |
| 419 | + */ | |
| 420 | + private List<BluetoothDevice> getBondedBluetoothDevice() { | |
| 421 | + Set<BluetoothDevice> bluetoothDeviceSet = mBluetoothAdapter.getBondedDevices(); | |
| 422 | + List<BluetoothDevice> bluetoothDeviceList = new ArrayList<>(bluetoothDeviceSet); | |
| 423 | + return bluetoothDeviceList; | |
| 424 | + } | |
| 425 | +// | |
| 426 | +// /** | |
| 427 | +// * 获取首次启动时已绑定的设备数据 | |
| 428 | +// */ | |
| 429 | +// private void getBondBluetoothDeviceData() { | |
| 430 | +// unbondDevices.removeAll(bondDevices); | |
| 431 | +// Log.e(TAG, "unbondDevices: " + unbondDevices.size()); | |
| 432 | +// bondDevices.clear(); | |
| 433 | +// final List<BluetoothDevice> bonds = getBondedBluetoothDevice(); | |
| 434 | +// for (BluetoothDevice bluetoothDevice : bonds) { | |
| 435 | +// BluetoothDeviceInfo info = new BluetoothDeviceInfo(); | |
| 436 | +// info.setConnect(false); | |
| 437 | +// info.setBluetoothDevice(bluetoothDevice); | |
| 438 | +// bondDevices.add(info); | |
| 439 | +// } | |
| 440 | +// mBluetoothAdapter.getProfileProxy(this, new BluetoothProfile.ServiceListener() { | |
| 441 | +// @Override | |
| 442 | +// public void onServiceConnected(int i, BluetoothProfile bluetoothProfile) { | |
| 443 | +// Log.e(TAG, "onServiceConnected: " + bluetoothProfile.getConnectedDevices().size()); | |
| 444 | +// //获取当前已连接的设备 | |
| 445 | +// if (null != bluetoothProfile && null != bluetoothProfile.getConnectedDevices()) { | |
| 446 | +// for (BluetoothDevice connDevice : bluetoothProfile.getConnectedDevices()) { | |
| 447 | +// if (null != bondDevices) { | |
| 448 | +// Log.e(TAG, "onServiceConnected: " + connDevice.getName()); | |
| 449 | +// for (BluetoothDeviceInfo info : bondDevices) { | |
| 450 | +// if (connDevice.getAddress().equals(info.getBluetoothDevice().getAddress())) { | |
| 451 | +// info.setConnect(true); | |
| 452 | +// if (null != unBondAdapter) { | |
| 453 | +// unBondAdapter.notifyDataSetChanged(); | |
| 454 | +// } | |
| 455 | +// break; | |
| 456 | +// } | |
| 457 | +// } | |
| 458 | +// } | |
| 459 | +// } | |
| 460 | +// } | |
| 461 | +// } | |
| 462 | +// | |
| 463 | +// @Override | |
| 464 | +// public void onServiceDisconnected(int i) { | |
| 465 | +// Log.e(TAG, "onServiceDisconnected: "); | |
| 466 | +// | |
| 467 | +// } | |
| 468 | +// }, BluetoothProfile.STATE_CONNECTED); | |
| 469 | +// unbondDevices.addAll(0, bondDevices); | |
| 470 | +// } | |
| 471 | + | |
| 472 | + | |
| 473 | + @Subscribe(threadMode = ThreadMode.MAIN) | |
| 474 | + public void onEvent(BlueToothMsgEvent blueToothMsgEvent) { | |
| 475 | + //进行配对 | |
| 476 | + if (blueToothMsgEvent.getMsgType() == BlueToothMsgEvent.BOND_DEVICE) { | |
| 477 | + BluetoothDevice bluetoothDevice = (BluetoothDevice) blueToothMsgEvent.getData(); | |
| 478 | + BluetoothConnThread connThread = new BluetoothConnThread(BluetoothConnActivity.this, blueToothMsgEvent.getPosition(), bluetoothDevice); | |
| 479 | + connThread.start(); | |
| 480 | + } | |
| 481 | + } | |
| 482 | + | |
| 483 | + private String encode(String str) { | |
| 484 | + StringBuilder builder = new StringBuilder(); | |
| 485 | + for (int i = 0; i < str.length(); ++i) { | |
| 486 | + char ch = str.charAt(i); | |
| 487 | + if (ch == '#') { | |
| 488 | + builder.append('\\'); | |
| 489 | + } else if (ch == '\\') { | |
| 490 | + builder.append('\\'); | |
| 491 | + } | |
| 492 | + builder.append(ch); | |
| 493 | + } | |
| 494 | + return builder.toString(); | |
| 495 | + } | |
| 496 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/BluetoothConnThread.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/BluetoothConnThread.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.activity; | |
| 2 | + | |
| 3 | +import android.annotation.SuppressLint; | |
| 4 | +import android.bluetooth.BluetoothDevice; | |
| 5 | +import android.bluetooth.BluetoothSocket; | |
| 6 | +import android.content.Context; | |
| 7 | +import android.os.Bundle; | |
| 8 | +import android.os.Handler; | |
| 9 | +import android.os.Message; | |
| 10 | +import android.util.Log; | |
| 11 | + | |
| 12 | + | |
| 13 | +import com.cnlive.strike.xiaojiaspeaker.model.BlueToothMsgEvent; | |
| 14 | +import com.cnlive.strike.xiaojiaspeaker.util.QMUITipDialogUtil; | |
| 15 | + | |
| 16 | +import org.greenrobot.eventbus.EventBus; | |
| 17 | + | |
| 18 | +import java.lang.reflect.InvocationTargetException; | |
| 19 | +import java.lang.reflect.Method; | |
| 20 | +import java.util.UUID; | |
| 21 | + | |
| 22 | +/* | |
| 23 | + *@date:2018/7/30 11:40 | |
| 24 | + *@auther:杨帅 | |
| 25 | + */public class BluetoothConnThread extends Thread { | |
| 26 | + private BluetoothDevice bluetoothDevice; | |
| 27 | + private Context context; | |
| 28 | + private static final String TAG = "BluetoothConnThread"; | |
| 29 | + private int itemPosition;//item点击的位置 | |
| 30 | + public boolean isConn;//是否是连接 | |
| 31 | + public volatile boolean exit = false;//是否终止线程 | |
| 32 | + private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); | |
| 33 | + | |
| 34 | + public BluetoothConnThread(Context context, int position, BluetoothDevice bluetoothDevice) { | |
| 35 | + this.bluetoothDevice = bluetoothDevice; | |
| 36 | + this.context = context; | |
| 37 | + this.itemPosition = position; | |
| 38 | + } | |
| 39 | + | |
| 40 | + @Override | |
| 41 | + public void run() { | |
| 42 | + while (!exit) { | |
| 43 | + //进行配对或连接 | |
| 44 | + try { | |
| 45 | + //是连接 | |
| 46 | + if (isConn) { | |
| 47 | + Log.e(TAG, "是连接"); | |
| 48 | + connect(bluetoothDevice); | |
| 49 | + exit = true; | |
| 50 | + } | |
| 51 | + //是配对 | |
| 52 | + else { | |
| 53 | + Log.e(TAG, "是配对"); | |
| 54 | + creatBond(bluetoothDevice); | |
| 55 | + exit = true; | |
| 56 | + } | |
| 57 | + Log.e(TAG, bluetoothDevice + ""); | |
| 58 | + } catch (InvocationTargetException e) { | |
| 59 | + e.printStackTrace(); | |
| 60 | + exit = true; | |
| 61 | + QMUITipDialogUtil.dismessDialog(); | |
| 62 | + } catch (IllegalAccessException e) { | |
| 63 | + e.printStackTrace(); | |
| 64 | + exit = true; | |
| 65 | + } catch (NoSuchMethodException e) { | |
| 66 | + e.printStackTrace(); | |
| 67 | + exit = true; | |
| 68 | + } | |
| 69 | + } | |
| 70 | + | |
| 71 | + } | |
| 72 | + | |
| 73 | + /** | |
| 74 | + * 尝试配对和连接 | |
| 75 | + * | |
| 76 | + * @param btDev | |
| 77 | + */ | |
| 78 | + @SuppressLint({"MissingPermission", "NewApi"}) | |
| 79 | + public void creatBond(BluetoothDevice btDev) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException { | |
| 80 | + if (btDev.getBondState() == BluetoothDevice.BOND_NONE) { | |
| 81 | + //如果这个设备取消了配对,则尝试配对 | |
| 82 | + // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | |
| 83 | + Method method = BluetoothDevice.class.getMethod("createBond"); | |
| 84 | + Log.e(TAG, "开始配对"); | |
| 85 | + method.invoke(btDev); | |
| 86 | + } else if (btDev.getBondState() == BluetoothDevice.BOND_BONDED) { | |
| 87 | + Log.e(TAG, "配对成功"); | |
| 88 | + exit = true; | |
| 89 | + EventBus.getDefault().post(new BlueToothMsgEvent(BlueToothMsgEvent.BOND_DEVICE_SUCCESS, bluetoothDevice, itemPosition)); | |
| 90 | + connect(btDev); | |
| 91 | + } | |
| 92 | + } | |
| 93 | + | |
| 94 | + | |
| 95 | + /** | |
| 96 | + * 尝试连接一个设备,子线程中完成,因为会线程阻塞 | |
| 97 | + * | |
| 98 | + * @param btDev 蓝牙设备对象 | |
| 99 | + * @return | |
| 100 | + */ | |
| 101 | + private void connect(BluetoothDevice btDev) { | |
| 102 | + BluetoothSocket mBluetoothSocket = null; | |
| 103 | + try { | |
| 104 | + //通过和服务器协商的uuid来进行连接 | |
| 105 | + mBluetoothSocket = btDev.createRfcommSocketToServiceRecord(SPP_UUID); | |
| 106 | + if (mBluetoothSocket != null) { | |
| 107 | + //你应当确保在调用connect()时设备没有执行搜索设备的操作。 | |
| 108 | + // 如果搜索设备也在同时进行,那么将会显著地降低连接速率,并很大程度上会连接失败。 | |
| 109 | + if (!mBluetoothSocket.isConnected()) { | |
| 110 | + mBluetoothSocket.connect();//进行连接 | |
| 111 | + Log.e("blueTooth", "...链接成功"); | |
| 112 | + EventBus.getDefault().post(new BlueToothMsgEvent(BlueToothMsgEvent.CONN_DEVICE_SUCCESS, bluetoothDevice, itemPosition)); | |
| 113 | + exit = true; | |
| 114 | + } else { | |
| 115 | + EventBus.getDefault().post(new BlueToothMsgEvent(BlueToothMsgEvent.CONN_DEVICE_SUCCESS, bluetoothDevice, itemPosition)); | |
| 116 | + exit = true; | |
| 117 | + } | |
| 118 | + } else { | |
| 119 | + mBluetoothSocket.close(); | |
| 120 | + mBluetoothSocket = null; | |
| 121 | + EventBus.getDefault().post(new BlueToothMsgEvent(BlueToothMsgEvent.CONN_DEVICE_FAILED, bluetoothDevice, itemPosition)); | |
| 122 | + exit = true; | |
| 123 | + } | |
| 124 | + | |
| 125 | + } catch (Exception e) { | |
| 126 | + e.printStackTrace(); | |
| 127 | + Log.e("blueTooth", "...链接失败,错误信息:" + e.getMessage()); | |
| 128 | + try { | |
| 129 | + mBluetoothSocket.close(); | |
| 130 | + mBluetoothSocket = null; | |
| 131 | + EventBus.getDefault().post(new BlueToothMsgEvent(BlueToothMsgEvent.CONN_DEVICE_FAILED, bluetoothDevice, itemPosition)); | |
| 132 | + exit = true; | |
| 133 | + } catch (Exception c) { | |
| 134 | + exit = true; | |
| 135 | + } | |
| 136 | + } | |
| 137 | + } | |
| 138 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/MobileServer.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/MobileServer.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.activity; | |
| 2 | + | |
| 3 | + | |
| 4 | +import com.cnlive.strike.xiaojiaspeaker.model.WifiMsgEvent; | |
| 5 | + | |
| 6 | +import org.greenrobot.eventbus.EventBus; | |
| 7 | + | |
| 8 | +import java.io.DataInputStream; | |
| 9 | +import java.io.IOException; | |
| 10 | +import java.net.ServerSocket; | |
| 11 | +import java.net.Socket; | |
| 12 | + | |
| 13 | +public class MobileServer implements Runnable { | |
| 14 | + private ServerSocket server; | |
| 15 | + private DataInputStream in; | |
| 16 | + private byte[] receice; | |
| 17 | + | |
| 18 | + | |
| 19 | + public MobileServer() { | |
| 20 | + } | |
| 21 | + | |
| 22 | + | |
| 23 | + @Override | |
| 24 | + public void run() { | |
| 25 | + | |
| 26 | + //5000是手机端开启的服务器的端口号,ESP8266进行TCP连接时使用的端口,而IP也是通过指令查询的联入设备的IP | |
| 27 | + try { | |
| 28 | + server = new ServerSocket(5000); | |
| 29 | + while (true) { | |
| 30 | + Socket client = server.accept(); | |
| 31 | + in = new DataInputStream(client.getInputStream()); | |
| 32 | + receice = new byte[50]; | |
| 33 | + in.read(receice); | |
| 34 | + in.close(); | |
| 35 | + EventBus.getDefault().post(new WifiMsgEvent(WifiMsgEvent.RECEIVE_MSG, receice)); | |
| 36 | + server.close(); | |
| 37 | + } | |
| 38 | + } catch (IOException e) { | |
| 39 | + e.printStackTrace(); | |
| 40 | + } | |
| 41 | + | |
| 42 | + } | |
| 43 | +} | |
| 0 | 44 | \ No newline at end of file | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/ReceiveThread.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/ReceiveThread.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.activity; | |
| 2 | + | |
| 3 | +import com.cnlive.strike.xiaojiaspeaker.model.WifiMsgEvent; | |
| 4 | + | |
| 5 | +import org.greenrobot.eventbus.EventBus; | |
| 6 | + | |
| 7 | +import java.io.IOException; | |
| 8 | +import java.io.InputStream; | |
| 9 | +import java.io.UnsupportedEncodingException; | |
| 10 | +import java.net.Socket; | |
| 11 | + | |
| 12 | +public class ReceiveThread extends Thread { | |
| 13 | + private InputStream inStrean = null; | |
| 14 | + private byte[] buf; | |
| 15 | + private String str = null; | |
| 16 | + private boolean stop = false; | |
| 17 | + | |
| 18 | + public ReceiveThread(Socket s) { | |
| 19 | + try { | |
| 20 | + this.inStrean = s.getInputStream(); | |
| 21 | + } catch (IOException e) { | |
| 22 | + e.printStackTrace(); | |
| 23 | + } | |
| 24 | + } | |
| 25 | + | |
| 26 | + //将输入流转化为字符串 | |
| 27 | + @Override | |
| 28 | + public void run() { | |
| 29 | + super.run(); | |
| 30 | + while (!stop) { | |
| 31 | + this.buf = new byte[1024]; | |
| 32 | + try { | |
| 33 | + this.inStrean.read(this.buf); | |
| 34 | + } catch (IOException e) { | |
| 35 | + e.printStackTrace(); | |
| 36 | + } | |
| 37 | + try { | |
| 38 | + this.str = new String(this.buf, "GB2312").trim(); | |
| 39 | + } catch (UnsupportedEncodingException e) { | |
| 40 | + e.printStackTrace(); | |
| 41 | + } | |
| 42 | + EventBus.getDefault().post(new WifiMsgEvent(WifiMsgEvent.RECEIVE_MSG,str)); | |
| 43 | + } | |
| 44 | + } | |
| 45 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/SearchDeviceActivity.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/SearchDeviceActivity.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.activity; | |
| 2 | + | |
| 3 | +import android.app.Activity; | |
| 4 | +import android.content.Intent; | |
| 5 | +import android.support.v7.app.AppCompatActivity; | |
| 6 | +import android.os.Bundle; | |
| 7 | + | |
| 8 | +import com.cnlive.strike.xiaojiaspeaker.R; | |
| 9 | +import com.cnlive.strike.xiaojiaspeaker.ui.fragment.SearchDevicefragment; | |
| 10 | + | |
| 11 | +public class SearchDeviceActivity extends AppCompatActivity { | |
| 12 | + | |
| 13 | + @Override | |
| 14 | + protected void onCreate(Bundle savedInstanceState) { | |
| 15 | + super.onCreate(savedInstanceState); | |
| 16 | + setContentView(R.layout.activity_search_device); | |
| 17 | + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,new SearchDevicefragment()).commit(); | |
| 18 | + | |
| 19 | + } | |
| 20 | + public static void startActivity(Activity activity) { | |
| 21 | + activity.startActivity(new Intent(activity, SearchDeviceActivity.class)); | |
| 22 | + } | |
| 23 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/SelectWifiActivity.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/SelectWifiActivity.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.activity; | |
| 2 | + | |
| 3 | +import android.Manifest; | |
| 4 | +import android.app.Activity; | |
| 5 | +import android.content.BroadcastReceiver; | |
| 6 | +import android.content.Context; | |
| 7 | +import android.content.Intent; | |
| 8 | +import android.content.IntentFilter; | |
| 9 | +import android.content.pm.PackageManager; | |
| 10 | +import android.net.NetworkInfo; | |
| 11 | +import android.net.Uri; | |
| 12 | +import android.net.wifi.WifiManager; | |
| 13 | +import android.os.Handler; | |
| 14 | +import android.provider.Settings; | |
| 15 | +import android.support.annotation.NonNull; | |
| 16 | +import android.support.v4.app.ActivityCompat; | |
| 17 | +import android.support.v7.app.AppCompatActivity; | |
| 18 | +import android.os.Bundle; | |
| 19 | +import android.util.Log; | |
| 20 | + | |
| 21 | +import com.clj.fastble.BleManager; | |
| 22 | +import com.clj.fastble.data.BleDevice; | |
| 23 | +import com.cnlive.strike.xiaojiaspeaker.R; | |
| 24 | +import com.cnlive.strike.xiaojiaspeaker.ui.fragment.SearchDevicefragment; | |
| 25 | +import com.cnlive.strike.xiaojiaspeaker.ui.fragment.SelectWifiFragment; | |
| 26 | +import com.cnlive.strike.xiaojiaspeaker.ui.widget.SelectDialog; | |
| 27 | +import com.cnlive.strike.xiaojiaspeaker.util.WifiUtils; | |
| 28 | +import com.cnlive.strike.xiaojiaspeaker.util.lib_permisshelper.PermissionsListener; | |
| 29 | +import com.cnlive.strike.xiaojiaspeaker.util.lib_permisshelper.PermissionsUtils; | |
| 30 | + | |
| 31 | +public class SelectWifiActivity extends AppCompatActivity { | |
| 32 | + private PermissionsUtils mPermissionsUtils = new PermissionsUtils();//权限申请 | |
| 33 | + private int permissionRequestCount = 0;//权限请求次数 | |
| 34 | + private SelectDialog selectDialog; | |
| 35 | + private WifiUtils wifiUtils; | |
| 36 | + private String TAG = "SelectWifiActivity"; | |
| 37 | + private BleDevice bleDevice; | |
| 38 | + private boolean isFirstCheckWifi = true; | |
| 39 | + private Runnable wifiRunable; | |
| 40 | + private Handler handler; | |
| 41 | + | |
| 42 | + @Override | |
| 43 | + protected void onCreate(Bundle savedInstanceState) { | |
| 44 | + super.onCreate(savedInstanceState); | |
| 45 | + setContentView(R.layout.activity_select_wifi); | |
| 46 | + if (null != getIntent().getExtras()) { | |
| 47 | + bleDevice = (BleDevice) getIntent().getExtras().get("bleDevice"); | |
| 48 | + } | |
| 49 | + wifiUtils = new WifiUtils(this); | |
| 50 | +// registerBroadcast(); | |
| 51 | +// getPermissionsWithTip(); | |
| 52 | + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SelectWifiFragment()).commitAllowingStateLoss(); | |
| 53 | + } | |
| 54 | + | |
| 55 | + | |
| 56 | + private void initPermissionDefineTip() { | |
| 57 | + selectDialog = new SelectDialog(SelectWifiActivity.this, "您尚未授予程序运行所需权限\n是否设置?", | |
| 58 | + "返回", new SelectDialog.DialogInterface() { | |
| 59 | + @Override | |
| 60 | + public void onClick(SelectDialog dialog) { | |
| 61 | + dialog.dismiss(); | |
| 62 | + finish(); | |
| 63 | + } | |
| 64 | + }, "设置", new SelectDialog.DialogInterface() { | |
| 65 | + @Override | |
| 66 | + public void onClick(SelectDialog dialog) { | |
| 67 | + dialog.dismiss(); | |
| 68 | + Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); | |
| 69 | + Uri uri = Uri.fromParts("package", getPackageName(), null); | |
| 70 | + intent.setData(uri); | |
| 71 | + startActivityForResult(intent, 0); | |
| 72 | + permissionRequestCount = 0; | |
| 73 | + } | |
| 74 | + }); | |
| 75 | + selectDialog.setRightBtnColor(R.color.green); | |
| 76 | + | |
| 77 | + } | |
| 78 | + | |
| 79 | + @Override | |
| 80 | + protected void onResume() { | |
| 81 | + super.onResume(); | |
| 82 | + Log.e(TAG, "onResume: " + wifiUtils.isOpenWifi()); | |
| 83 | + } | |
| 84 | + | |
| 85 | + /** | |
| 86 | + * 一次申请一组权限(使用拒绝弹框)点击事件 | |
| 87 | + */ | |
| 88 | + public void getPermissionsWithTip() { | |
| 89 | + if (1 == permissionRequestCount) { | |
| 90 | + return; | |
| 91 | + } | |
| 92 | + mPermissionsUtils | |
| 93 | + .setPermissionsListener(new PermissionsListener() { | |
| 94 | + @Override | |
| 95 | + public void onDenied(String[] deniedPermissions) { | |
| 96 | +// getPermissionsWithTip(); | |
| 97 | + } | |
| 98 | + | |
| 99 | + @Override | |
| 100 | + public void onGranted() { | |
| 101 | + //判断蓝牙是否打开 | |
| 102 | + if (null == getSupportFragmentManager().findFragmentById(R.id.fragment_container)) { | |
| 103 | + //判断wifi是否打开 | |
| 104 | + if (!wifiUtils.isOpenWifi()) { | |
| 105 | + wifiUtils.openWifi(); | |
| 106 | + } | |
| 107 | + } | |
| 108 | + } | |
| 109 | + }) | |
| 110 | + .withActivity(SelectWifiActivity.this) | |
| 111 | + .getPermissions(SelectWifiActivity.this | |
| 112 | + , 100 | |
| 113 | + , Manifest.permission.INTERNET | |
| 114 | + , Manifest.permission.ACCESS_FINE_LOCATION | |
| 115 | + , Manifest.permission.ACCESS_COARSE_LOCATION | |
| 116 | + ); | |
| 117 | +// .getPermissionsWithTips(MainActivity.this | |
| 118 | +// ,100 | |
| 119 | +// , new String[]{"人家要录音","我们需要读取你的信息,磨磨唧唧的","我要上网","我要读内存卡","我要看日历","我要定位"} | |
| 120 | +// , Manifest.permission.RECORD_AUDIO | |
| 121 | +// , Manifest.permission.READ_SMS | |
| 122 | +// , Manifest.permission.INTERNET | |
| 123 | +// , Manifest.permission.READ_EXTERNAL_STORAGE | |
| 124 | +// , Manifest.permission.READ_CALENDAR | |
| 125 | +// , Manifest.permission.ACCESS_FINE_LOCATION); | |
| 126 | + } | |
| 127 | + | |
| 128 | + /** | |
| 129 | + * 权限回调 | |
| 130 | + * | |
| 131 | + * @param requestCode | |
| 132 | + * @param permissions | |
| 133 | + * @param grantResults | |
| 134 | + */ | |
| 135 | + @Override | |
| 136 | + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, | |
| 137 | + @NonNull int[] grantResults) { | |
| 138 | + super.onRequestPermissionsResult(requestCode, permissions, grantResults); | |
| 139 | + if (1 == permissionRequestCount) { | |
| 140 | + return; | |
| 141 | + } | |
| 142 | + boolean isShowPermissionTip = true; | |
| 143 | + for (int i = 0; i < grantResults.length; i++) {//判断权限的结果,如果有被拒绝,就return | |
| 144 | + if (grantResults[i] == PackageManager.PERMISSION_DENIED) { | |
| 145 | + if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) { | |
| 146 | + isShowPermissionTip = false; | |
| 147 | + break; | |
| 148 | + } | |
| 149 | + } | |
| 150 | + } | |
| 151 | + if (isShowPermissionTip) { | |
| 152 | + mPermissionsUtils.dealResult(requestCode, permissions, grantResults); | |
| 153 | + } else { | |
| 154 | + if (0 == permissionRequestCount) { | |
| 155 | + selectDialog.setCancelable(false); | |
| 156 | + selectDialog.setCanceledOnTouchOutside(false); | |
| 157 | + if (!selectDialog.isShowing()) { | |
| 158 | + selectDialog.show(); | |
| 159 | + permissionRequestCount = 1; | |
| 160 | + } | |
| 161 | + } else { | |
| 162 | + return; | |
| 163 | + } | |
| 164 | + } | |
| 165 | + } | |
| 166 | + | |
| 167 | + @Override | |
| 168 | + protected void onDestroy() { | |
| 169 | + super.onDestroy(); | |
| 170 | +// if (null != mBroadcastReceiver) { | |
| 171 | +// unregisterReceiver(mBroadcastReceiver); | |
| 172 | +// } | |
| 173 | + } | |
| 174 | + | |
| 175 | +// private void registerBroadcast() { | |
| 176 | +// IntentFilter intentFilter = new IntentFilter(); | |
| 177 | +// intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); | |
| 178 | +// intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); | |
| 179 | +// intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); | |
| 180 | +// intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); | |
| 181 | +// registerReceiver(mBroadcastReceiver, intentFilter); | |
| 182 | +// } | |
| 183 | + | |
| 184 | +// private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { | |
| 185 | +// @Override | |
| 186 | +// public void onReceive(Context context, final Intent intent) { | |
| 187 | +// String resultAction = intent.getAction(); | |
| 188 | +// //当扫描结果后,进行刷新列表 | |
| 189 | +// if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { | |
| 190 | +// Log.e(TAG, "onReceive: SCAN_RESULTS_AVAILABLE_ACTION"); | |
| 191 | +// if (null == getSupportFragmentManager().findFragmentById(R.id.fragment_container)) { | |
| 192 | +// getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SelectWifiFragment()).commitAllowingStateLoss(); | |
| 193 | +// } | |
| 194 | +// } else if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {//wifi连接网络状态变化 | |
| 195 | +// NetworkInfo.DetailedState state = ((NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO)).getDetailedState(); | |
| 196 | +// Log.e(TAG, "onReceive: NETWORK_STATE_CHANGED_ACTION" + wifiUtils.isOpenWifi()); | |
| 197 | +// if (null == getSupportFragmentManager().findFragmentById(R.id.fragment_container)) { | |
| 198 | +// new Handler().postDelayed(new Runnable() { | |
| 199 | +// @Override | |
| 200 | +// public void run() { | |
| 201 | +// if (null == getSupportFragmentManager().findFragmentById(R.id.fragment_container)) { | |
| 202 | +// int mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0); | |
| 203 | +// if (mWifiState!=WifiManager.WIFI_STATE_ENABLING||mWifiState!=WifiManager.WIFI_STATE_ENABLED) { | |
| 204 | +// finish(); | |
| 205 | +// }else { | |
| 206 | +// getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SelectWifiFragment()).commitAllowingStateLoss(); | |
| 207 | +// } | |
| 208 | +// } | |
| 209 | +// } | |
| 210 | +// }, 2000); | |
| 211 | +// } | |
| 212 | +// | |
| 213 | +// } | |
| 214 | +// if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {//wifi状态变化 | |
| 215 | +// } else if (intent.getAction().equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { | |
| 216 | +// | |
| 217 | +// } | |
| 218 | +// } | |
| 219 | +// }; | |
| 220 | + | |
| 221 | + public static void StartActivity(Activity activity, BleDevice bleDevice) { | |
| 222 | + Intent intent = new Intent(activity, SelectWifiActivity.class); | |
| 223 | + intent.putExtra("bleDevice", bleDevice); | |
| 224 | + activity.startActivity(intent); | |
| 225 | + } | |
| 226 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/SpeakerMainActivity.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/activity/SpeakerMainActivity.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.activity; | |
| 2 | + | |
| 3 | + | |
| 4 | +import android.bluetooth.BluetoothDevice; | |
| 5 | +import android.content.BroadcastReceiver; | |
| 6 | +import android.content.Context; | |
| 7 | +import android.content.Intent; | |
| 8 | +import android.content.IntentFilter; | |
| 9 | +import android.databinding.DataBindingUtil; | |
| 10 | +import android.graphics.Color; | |
| 11 | +import android.net.NetworkInfo; | |
| 12 | +import android.net.wifi.ScanResult; | |
| 13 | +import android.net.wifi.WifiManager; | |
| 14 | +import android.os.Bundle; | |
| 15 | +import android.os.SystemClock; | |
| 16 | +import android.support.v7.app.AppCompatActivity; | |
| 17 | +import android.support.v7.widget.LinearLayoutManager; | |
| 18 | +import android.text.TextUtils; | |
| 19 | +import android.util.Log; | |
| 20 | + | |
| 21 | +import com.cnlive.libs.base.util.AlertUtil; | |
| 22 | +import com.cnlive.strike.xiaojiaspeaker.R; | |
| 23 | +import com.cnlive.strike.xiaojiaspeaker.databinding.ActivitySpeakerMainBinding; | |
| 24 | +import com.cnlive.strike.xiaojiaspeaker.listener.WifiChangeListener; | |
| 25 | +import com.cnlive.strike.xiaojiaspeaker.model.BlueToothMsgEvent; | |
| 26 | +import com.cnlive.strike.xiaojiaspeaker.model.WifiConnModel; | |
| 27 | +import com.cnlive.strike.xiaojiaspeaker.model.WifiMsgEvent; | |
| 28 | +import com.cnlive.strike.xiaojiaspeaker.ui.adapter.WifiRecycleAdapter; | |
| 29 | +import com.cnlive.strike.xiaojiaspeaker.ui.widget.WifiPwdDialog; | |
| 30 | +import com.cnlive.strike.xiaojiaspeaker.util.WifiCheckUtil; | |
| 31 | +import com.cnlive.strike.xiaojiaspeaker.util.WifiUtils; | |
| 32 | +import com.cnlive.strike.xiaojiaspeaker.util.utilcode.util.BarUtils; | |
| 33 | +import com.cnlive.strike.xiaojiaspeaker.util.utilcode.util.NetworkUtils; | |
| 34 | + | |
| 35 | +import org.greenrobot.eventbus.EventBus; | |
| 36 | +import org.greenrobot.eventbus.Subscribe; | |
| 37 | +import org.greenrobot.eventbus.ThreadMode; | |
| 38 | + | |
| 39 | +import java.io.IOException; | |
| 40 | +import java.io.OutputStream; | |
| 41 | +import java.io.PrintStream; | |
| 42 | +import java.net.Socket; | |
| 43 | +import java.util.ArrayList; | |
| 44 | +import java.util.List; | |
| 45 | + | |
| 46 | + | |
| 47 | +public class SpeakerMainActivity extends AppCompatActivity implements WifiChangeListener { | |
| 48 | + private static final String TAG = "SpeakerMainActivity"; | |
| 49 | + private WifiUtils wifiUtils; | |
| 50 | + private ActivitySpeakerMainBinding mainBinding; | |
| 51 | + private WifiRecycleAdapter adapter; | |
| 52 | + private WifiChangeListener listener; | |
| 53 | + private int connErrorCount = 0; | |
| 54 | + private String selectSSID = ""; | |
| 55 | + private String currentConnectingSSID = ""; | |
| 56 | + private boolean isFirstSetAdapter = false;//是否是第一次设置适配器 | |
| 57 | + | |
| 58 | + @Override | |
| 59 | + protected void onCreate(Bundle savedInstanceState) { | |
| 60 | + super.onCreate(savedInstanceState); | |
| 61 | + new Thread(new Runnable() { | |
| 62 | + @Override | |
| 63 | + public void run() { | |
| 64 | + Log.e(TAG, "onCreate: " + NetworkUtils.isWifiAvailable()); | |
| 65 | + } | |
| 66 | + }).start(); | |
| 67 | + mainBinding = DataBindingUtil.setContentView(this, R.layout.activity_speaker_main); | |
| 68 | + wifiUtils = new WifiUtils(this); | |
| 69 | + if (!wifiUtils.isOpenWifi()) { | |
| 70 | + wifiUtils.openWifi(); | |
| 71 | + } | |
| 72 | + listener = this; | |
| 73 | + wifiUtils.startScanWifi(); | |
| 74 | + registerBroadcast(); | |
| 75 | + if (!EventBus.getDefault().isRegistered(this)) { | |
| 76 | + EventBus.getDefault().register(this); | |
| 77 | + } | |
| 78 | + MobileServer mobileServer = new MobileServer(); | |
| 79 | + new Thread(mobileServer).start(); | |
| 80 | + } | |
| 81 | + | |
| 82 | + private void registerBroadcast() { | |
| 83 | + IntentFilter intentFilter = new IntentFilter(); | |
| 84 | + intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); | |
| 85 | + intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); | |
| 86 | + intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); | |
| 87 | + intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); | |
| 88 | + registerReceiver(mBroadcastReceiver, intentFilter); | |
| 89 | + } | |
| 90 | + | |
| 91 | + private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { | |
| 92 | + @Override | |
| 93 | + public void onReceive(Context context, Intent intent) { | |
| 94 | + String resultAction = intent.getAction(); | |
| 95 | + //当扫描结果后,进行刷新列表 | |
| 96 | + if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { | |
| 97 | + if (null != listener) { | |
| 98 | + listener.onScanResultAvailable(); | |
| 99 | + } | |
| 100 | + } else if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {//wifi连接网络状态变化 | |
| 101 | + NetworkInfo.DetailedState state = ((NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO)).getDetailedState(); | |
| 102 | + if (null != listener) { | |
| 103 | + listener.onNetWorkStateChanged(state, selectSSID); | |
| 104 | + } | |
| 105 | + } else if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {//wifi状态变化 | |
| 106 | + int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_DISABLED); | |
| 107 | + if (null != listener) { | |
| 108 | + listener.onWiFiStateChanged(wifiState); | |
| 109 | + } | |
| 110 | + } else if (intent.getAction().equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { | |
| 111 | +// SupplicantState state = intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE); | |
| 112 | +// int error = intent.getIntExtra(EXTRA_SUPPLICANT_ERROR, 0); | |
| 113 | +// if (null != listener) { | |
| 114 | +// if (error == WifiManager.ERROR_AUTHENTICATING) { | |
| 115 | +// //这里可以获取到监听连接wifi密码错误的时候进行回调 | |
| 116 | +// } | |
| 117 | +// listener.onWifiPasswordFault(); | |
| 118 | +// } | |
| 119 | + } | |
| 120 | + } | |
| 121 | + }; | |
| 122 | + int i = 0; | |
| 123 | + | |
| 124 | + private void setWifiAdapter() { | |
| 125 | + wifiUtils.getConnectedInfo(); | |
| 126 | + String SSID = wifiUtils.getConnectedSSID(); | |
| 127 | + List<ScanResult> scanResults = wifiUtils.getScanResults(); | |
| 128 | + List<WifiConnModel> results = new ArrayList<>(); | |
| 129 | + List<WifiConnModel> wifiConnModelList = null; | |
| 130 | + Log.e(TAG, "setWifiAdapter: " + scanResults.size()); | |
| 131 | + if (null != scanResults && scanResults.size() > 0) { | |
| 132 | + if (null != scanResults) { | |
| 133 | + for (ScanResult s : scanResults) { | |
| 134 | + WifiConnModel wifiConnModel = new WifiConnModel(); | |
| 135 | + wifiConnModel.setScanResult(s); | |
| 136 | + if (TextUtils.isEmpty(SSID)) { | |
| 137 | + wifiConnModel.setState(WifiConnModel.WIFI_NORMAL); | |
| 138 | + } else { | |
| 139 | + if (s.SSID.equals(SSID)) { | |
| 140 | + wifiConnModel.setState(WifiConnModel.WIFI_CONN_SUCCESS); | |
| 141 | + } | |
| 142 | + } | |
| 143 | + results.add(wifiConnModel); | |
| 144 | + } | |
| 145 | + } | |
| 146 | +// if (null == adapter) { | |
| 147 | +// adapter = new WifiRecycleAdapter(SpeakerMainActivity.this, results); | |
| 148 | +// if (null != mainBinding) { | |
| 149 | +// mainBinding.recycler.setLayoutManager(new LinearLayoutManager(SpeakerMainActivity.this)); | |
| 150 | +// mainBinding.recycler.setAdapter(adapter); | |
| 151 | +// } | |
| 152 | +// } else { | |
| 153 | +// if (null != results && results.size() > 0) { | |
| 154 | +// adapter.upDataAdapter(results); | |
| 155 | +// } | |
| 156 | +// } | |
| 157 | + | |
| 158 | + adapter.setOnItemClickListener(new WifiRecycleAdapter.onItemClickListener() { | |
| 159 | + @Override | |
| 160 | + public void onItemClick(int position, final WifiConnModel wifiConnModel) { | |
| 161 | + new Thread(new Runnable() { | |
| 162 | + @Override | |
| 163 | + public void run() { | |
| 164 | + try { | |
| 165 | + Log.e(TAG, "run: " + i); | |
| 166 | + byte[] msgBuffer = null; | |
| 167 | + String text = "---------Hello World---------- "; | |
| 168 | + String ip = wifiUtils.getConnectedIPAddr(); | |
| 169 | + Socket socket = new Socket(ip, 9101); | |
| 170 | + socket.setSoTimeout(5000); | |
| 171 | + PrintStream out = new PrintStream(socket.getOutputStream()); | |
| 172 | + out.println(00); | |
| 173 | + out.flush(); | |
| 174 | + out.close(); | |
| 175 | + socket.close(); | |
| 176 | + } catch (Exception e) { | |
| 177 | + e.printStackTrace(); | |
| 178 | + } | |
| 179 | + SystemClock.sleep(5000); | |
| 180 | + } | |
| 181 | + }).start(); | |
| 182 | +// selectSSID = wifiConnModel.getScanResult().SSID; | |
| 183 | +// Log.e(TAG, "onItemClick: "+wifiConnModel.getScanResult() ); | |
| 184 | +// connErrorCount = 0; | |
| 185 | +// boolean isConfig = wifiUtils.isHasConfiguration(wifiConnModel.getScanResult().SSID); | |
| 186 | +// if (!isConfig) { | |
| 187 | +// int networkId = wifiUtils.getSpeakerConnNetWorkId(wifiConnModel.getScanResult()); | |
| 188 | +// adapter.resetNetState(wifiConnModel); | |
| 189 | +// wifiUtils.connectWifi(networkId); | |
| 190 | +// } else { | |
| 191 | +// int networkId = wifiUtils.getSpeakerConnNetWorkId(wifiConnModel.getScanResult()); | |
| 192 | +// wifiUtils.connectWifi(networkId); | |
| 193 | +// | |
| 194 | +// } | |
| 195 | +// int networkId = wifiUtils.getWantConnNetWorkId(wifiConnModel.getScanResult(), pwd); | |
| 196 | +// adapter.resetNetState(wifiConnModel); | |
| 197 | +// wifiUtils.connectWifi(networkId); | |
| 198 | +// WifiPwdDialog wifiPwdDialog = new WifiPwdDialog(SpeakerMainActivity.this, wifiConnModel.getScanResult().SSID, "取消", new WifiPwdDialog.DialogInterface() { | |
| 199 | +// @Override | |
| 200 | +// public void onClick(WifiPwdDialog dialog) { | |
| 201 | +// dialog.dismiss(); | |
| 202 | +// } | |
| 203 | +// }, "连接", new WifiPwdDialog.ConnDialogInterface() { | |
| 204 | +// @Override | |
| 205 | +// public void onClick(WifiPwdDialog dialog, String pwd) { | |
| 206 | +// if (!TextUtils.isEmpty(pwd)) { | |
| 207 | +// int networkId = wifiUtils.getWantConnNetWorkId(wifiConnModel.getScanResult(), pwd); | |
| 208 | +// adapter.resetNetState(wifiConnModel); | |
| 209 | +// wifiUtils.connectWifi(networkId); | |
| 210 | +// dialog.dismiss(); | |
| 211 | +// } | |
| 212 | +// } | |
| 213 | +// }); | |
| 214 | +// wifiPwdDialog.setCancelable(false); | |
| 215 | +// wifiPwdDialog.setCanceledOnTouchOutside(false); | |
| 216 | +// if (!isConfig) { | |
| 217 | +// if (!wifiPwdDialog.isShowing()) { | |
| 218 | +// wifiPwdDialog.show(); | |
| 219 | +// } | |
| 220 | +// } else { | |
| 221 | +// int networkId = wifiUtils.getConfigurationNetworkId(wifiConnModel.getScanResult().SSID); | |
| 222 | +// if (networkId != -1) { | |
| 223 | +// adapter.resetNetState(wifiConnModel); | |
| 224 | +// wifiUtils.connectWifi(networkId); | |
| 225 | +// } | |
| 226 | +// } | |
| 227 | + } | |
| 228 | + }); | |
| 229 | + } | |
| 230 | + } | |
| 231 | + | |
| 232 | + @Override | |
| 233 | + public void onScanResultAvailable() { | |
| 234 | + if (!isFirstSetAdapter) { | |
| 235 | + isFirstSetAdapter = false; | |
| 236 | + } | |
| 237 | + setWifiAdapter(); | |
| 238 | + } | |
| 239 | + | |
| 240 | + @Override | |
| 241 | + public void onWiFiStateChanged(int wifiState) { | |
| 242 | + | |
| 243 | + } | |
| 244 | + | |
| 245 | + @Override | |
| 246 | + public void onNetWorkStateChanged(NetworkInfo.DetailedState state, String SSID) { | |
| 247 | + if (state == NetworkInfo.DetailedState.SCANNING) { | |
| 248 | + Log.e(TAG, "onReceive onNetWorkStateChanged: +正在扫描"); | |
| 249 | + } else if (state == NetworkInfo.DetailedState.CONNECTING) { | |
| 250 | + Log.e(TAG, "onReceive onNetWorkStateChanged: +正在连接" + wifiUtils.getConnectedSSID()); | |
| 251 | + currentConnectingSSID = wifiUtils.getConnectedSSID(); | |
| 252 | + if (adapter != null) { | |
| 253 | +// if (selectSSID.equals(wifiUtils.getConnectedSSID())) { | |
| 254 | +// adapter.updateConnNetState(selectSSID, WifiConnModel.WIFI_CONNECTING); | |
| 255 | +// } else { | |
| 256 | +// adapter.updateConnNetState(currentConnectingSSID, WifiConnModel.WIFI_CONNECTING); | |
| 257 | +// } | |
| 258 | + } | |
| 259 | + } else if (state == NetworkInfo.DetailedState.OBTAINING_IPADDR) { | |
| 260 | + Log.e(TAG, "onReceive onNetWorkStateChanged: +获取IP地址"); | |
| 261 | + | |
| 262 | + } else if (state == NetworkInfo.DetailedState.CONNECTED) { | |
| 263 | + Log.e(TAG, "onReceive onNetWorkStateChanged: +建立连接"); | |
| 264 | + connErrorCount = 0; | |
| 265 | + if (!isFirstSetAdapter) { | |
| 266 | + isFirstSetAdapter = false; | |
| 267 | + setWifiAdapter(); | |
| 268 | + } else { | |
| 269 | + if (null != adapter) { | |
| 270 | +// adapter.updateConnNetState(wifiUtils.getConnectedSSID(), WifiConnModel.WIFI_CONN_SUCCESS); | |
| 271 | + } | |
| 272 | + } | |
| 273 | + | |
| 274 | + | |
| 275 | + } else if (state == NetworkInfo.DetailedState.DISCONNECTING) { | |
| 276 | + Log.e(TAG, "onReceive onNetWorkStateChanged: +正在断开连接"); | |
| 277 | + | |
| 278 | + } else if (state == NetworkInfo.DetailedState.DISCONNECTED) { | |
| 279 | + Log.e(TAG, "onReceive onNetWorkStateChanged: +已断开连接"); | |
| 280 | + if (WifiCheckUtil.isFastOperate()) { | |
| 281 | + return; | |
| 282 | + } | |
| 283 | + if (!TextUtils.isEmpty(selectSSID)) { | |
| 284 | + if (selectSSID.equals(currentConnectingSSID)) { | |
| 285 | + connErrorCount++; | |
| 286 | + if (adapter != null) { | |
| 287 | + if (connErrorCount == 2) { | |
| 288 | + connErrorCount = 0; | |
| 289 | + AlertUtil.showDeftToast(this, "WIFI密码错误!"); | |
| 290 | + //断开连接 | |
| 291 | + wifiUtils.disconnect(); | |
| 292 | + int networkId = wifiUtils.getConfigurationNetworkId(selectSSID); | |
| 293 | + wifiUtils.removeNetwork(networkId); | |
| 294 | +// adapter.updateConnNetState(selectSSID, WifiConnModel.WIFI_NORMAL); | |
| 295 | + | |
| 296 | + } else { | |
| 297 | +// adapter.updateConnNetState(selectSSID, WifiConnModel.WIFI_BREAK_CONN); | |
| 298 | + } | |
| 299 | + } | |
| 300 | + } | |
| 301 | + | |
| 302 | + } else if (state == NetworkInfo.DetailedState.FAILED) { | |
| 303 | + Log.e(TAG, "onReceive onNetWorkStateChanged: +连接失败"); | |
| 304 | + } | |
| 305 | + } | |
| 306 | + } | |
| 307 | + | |
| 308 | + | |
| 309 | + @Override | |
| 310 | + public void onWifiPasswordFault() { | |
| 311 | + | |
| 312 | + } | |
| 313 | + | |
| 314 | + @Override | |
| 315 | + protected void onDestroy() { | |
| 316 | + super.onDestroy(); | |
| 317 | + if (EventBus.getDefault().isRegistered(this)) { | |
| 318 | + EventBus.getDefault().unregister(this); | |
| 319 | + } | |
| 320 | + } | |
| 321 | + | |
| 322 | + @Subscribe(threadMode = ThreadMode.MAIN) | |
| 323 | + public void onEvent(WifiMsgEvent wifiMsgEvent) { | |
| 324 | + if (wifiMsgEvent.getMsgType() == WifiMsgEvent.RECEIVE_MSG) { | |
| 325 | + Log.e(TAG, "onEvent: " + wifiMsgEvent.getData()); | |
| 326 | + } | |
| 327 | + } | |
| 328 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/adapter/BluetoothDeviceAdapter.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/adapter/BluetoothDeviceAdapter.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.adapter; | |
| 2 | + | |
| 3 | +import android.bluetooth.BluetoothClass; | |
| 4 | +import android.bluetooth.BluetoothDevice; | |
| 5 | +import android.content.Context; | |
| 6 | +import android.databinding.DataBindingUtil; | |
| 7 | +import android.support.v4.content.ContextCompat; | |
| 8 | +import android.support.v7.widget.RecyclerView; | |
| 9 | +import android.text.TextUtils; | |
| 10 | +import android.util.Log; | |
| 11 | +import android.view.LayoutInflater; | |
| 12 | +import android.view.View; | |
| 13 | +import android.view.ViewGroup; | |
| 14 | +import android.widget.CompoundButton; | |
| 15 | + | |
| 16 | + | |
| 17 | +import com.clj.fastble.data.BleDevice; | |
| 18 | +import com.cnlive.strike.application.GlideApp; | |
| 19 | +import com.cnlive.strike.xiaojiaspeaker.R; | |
| 20 | +import com.cnlive.strike.xiaojiaspeaker.databinding.ListItemBluetoothDeviceBinding; | |
| 21 | +import com.cnlive.strike.xiaojiaspeaker.model.BluetoothDeviceInfo; | |
| 22 | + | |
| 23 | +import java.util.HashMap; | |
| 24 | +import java.util.List; | |
| 25 | + | |
| 26 | + | |
| 27 | +/* | |
| 28 | + *@date:2018/7/23 12:11 | |
| 29 | + *@auther:杨帅 | |
| 30 | + */public class BluetoothDeviceAdapter extends RecyclerView.Adapter { | |
| 31 | + private static final String TAG = "BluetoothDeviceAdapter"; | |
| 32 | + private List<BleDevice> bluetoothDeviceList;//设备列表 | |
| 33 | + private LayoutInflater layoutInflater; | |
| 34 | + private Context context; | |
| 35 | + private HashMap<BleDevice, Boolean> hashMap; | |
| 36 | + | |
| 37 | + public BleDevice getSelectDevice() { | |
| 38 | + BleDevice bleDevice = null; | |
| 39 | + if (null != hashMap && null != bluetoothDeviceList) { | |
| 40 | + for (int i = 0; i < bluetoothDeviceList.size(); i++) { | |
| 41 | + if (hashMap.get(bluetoothDeviceList.get(i))) { | |
| 42 | + bleDevice = bluetoothDeviceList.get(i); | |
| 43 | + break; | |
| 44 | + } | |
| 45 | + } | |
| 46 | + | |
| 47 | + } | |
| 48 | + return bleDevice; | |
| 49 | + } | |
| 50 | + | |
| 51 | + public void setOnItemClickListener(OnItemClickListener onItemClickListener) { | |
| 52 | + this.onItemClickListener = onItemClickListener; | |
| 53 | + | |
| 54 | + } | |
| 55 | + | |
| 56 | + private OnItemClickListener onItemClickListener; | |
| 57 | + | |
| 58 | + | |
| 59 | + public void addListData(BleDevice bleDevice) { | |
| 60 | + if (null != bluetoothDeviceList) { | |
| 61 | + bluetoothDeviceList.add(bleDevice); | |
| 62 | + hashMap.put(bleDevice, false); | |
| 63 | + notifyDataSetChanged(); | |
| 64 | + } | |
| 65 | + | |
| 66 | + } | |
| 67 | + | |
| 68 | + public BluetoothDeviceAdapter(Context context, List<BleDevice> bluetoothDeviceList) { | |
| 69 | + this.bluetoothDeviceList = bluetoothDeviceList; | |
| 70 | + this.layoutInflater = LayoutInflater.from(context); | |
| 71 | + this.context = context; | |
| 72 | + hashMap = new HashMap<>(); | |
| 73 | + for (int i = 0; i < bluetoothDeviceList.size(); i++) { | |
| 74 | + hashMap.put(bluetoothDeviceList.get(i), false); | |
| 75 | + } | |
| 76 | + } | |
| 77 | + | |
| 78 | + @Override | |
| 79 | + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | |
| 80 | + LayoutInflater inflater = LayoutInflater.from(context); | |
| 81 | + ListItemBluetoothDeviceBinding binding = DataBindingUtil.inflate(inflater, R.layout.list_item_bluetooth_device, parent, false); | |
| 82 | + return new MyViewHolder(binding); | |
| 83 | + } | |
| 84 | + | |
| 85 | + @Override | |
| 86 | + public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { | |
| 87 | + final ListItemBluetoothDeviceBinding binding = ((MyViewHolder) holder).getBinding(); | |
| 88 | + //设备名称 | |
| 89 | + final BluetoothDevice bluetoothDevice = bluetoothDeviceList.get(position).getDevice(); | |
| 90 | + String deviceName = bluetoothDevice.getName(); | |
| 91 | + binding.tvDeviceName.setText("小家智能音箱" + (position + 1)); | |
| 92 | + String deviceAddress = bluetoothDevice.getAddress(); | |
| 93 | + //设备的状态(BOND_BONDED:已绑定 常量值:12, BOND_BONDING:绑定中 常量值:11, BOND_NONE:未匹配 常量值:10) | |
| 94 | + binding.tvDeviceAddress.setText(deviceAddress); | |
| 95 | + binding.llRoot.setOnClickListener(new View.OnClickListener() { | |
| 96 | + @Override | |
| 97 | + public void onClick(View view) { | |
| 98 | + if (!binding.checkBox.isChecked()) { | |
| 99 | + if (null != onItemClickListener) { | |
| 100 | + onItemClickListener.onItemClick(position, bluetoothDeviceList.get(position)); | |
| 101 | + } | |
| 102 | + for (int i = 0; i < bluetoothDeviceList.size(); i++) { | |
| 103 | + if (bluetoothDeviceList.get(i).getKey().equals(bluetoothDeviceList.get(position).getKey())) { | |
| 104 | + hashMap.put(bluetoothDeviceList.get(position), true); | |
| 105 | + } else { | |
| 106 | + hashMap.put(bluetoothDeviceList.get(i), false); | |
| 107 | + } | |
| 108 | + } | |
| 109 | + notifyDataSetChanged(); | |
| 110 | + } | |
| 111 | + } | |
| 112 | + }); | |
| 113 | + GlideApp.with(context) | |
| 114 | + .load(ContextCompat.getDrawable(context, R.drawable.icon_xiaojia)) | |
| 115 | + .skipMemoryCache(false) | |
| 116 | + .placeholder(ContextCompat.getDrawable(context, R.drawable.icon_xiaojia)) | |
| 117 | + .dontAnimate() | |
| 118 | + .into(binding.ivBluetoothDeviceIcon); | |
| 119 | + if (null != hashMap) { | |
| 120 | + if (hashMap.get(bluetoothDeviceList.get(position))) { | |
| 121 | + //选中 | |
| 122 | + binding.checkBox.setChecked(true); | |
| 123 | + } else { | |
| 124 | + //不选中 | |
| 125 | + binding.checkBox.setChecked(false); | |
| 126 | + } | |
| 127 | + } | |
| 128 | + } | |
| 129 | + | |
| 130 | + @Override | |
| 131 | + public int getItemCount() { | |
| 132 | + return bluetoothDeviceList.size(); | |
| 133 | + } | |
| 134 | + | |
| 135 | + private class MyViewHolder extends RecyclerView.ViewHolder { | |
| 136 | + public ListItemBluetoothDeviceBinding getBinding() { | |
| 137 | + return binding; | |
| 138 | + } | |
| 139 | + | |
| 140 | + private ListItemBluetoothDeviceBinding binding; | |
| 141 | + | |
| 142 | + public MyViewHolder(ListItemBluetoothDeviceBinding binding) { | |
| 143 | + super(binding.getRoot()); | |
| 144 | + this.binding = binding; | |
| 145 | + } | |
| 146 | + } | |
| 147 | + | |
| 148 | + public interface OnItemClickListener { | |
| 149 | + void onItemClick(int position, BleDevice bleDevice); | |
| 150 | + } | |
| 151 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/adapter/WifiRecycleAdapter.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/adapter/WifiRecycleAdapter.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.adapter; | |
| 2 | + | |
| 3 | +import android.content.Context; | |
| 4 | +import android.databinding.DataBindingUtil; | |
| 5 | +import android.net.NetworkInfo; | |
| 6 | +import android.net.wifi.ScanResult; | |
| 7 | +import android.net.wifi.WifiInfo; | |
| 8 | +import android.support.v7.widget.RecyclerView; | |
| 9 | +import android.text.TextUtils; | |
| 10 | +import android.util.Log; | |
| 11 | +import android.view.LayoutInflater; | |
| 12 | +import android.view.View; | |
| 13 | +import android.view.ViewGroup; | |
| 14 | + | |
| 15 | + | |
| 16 | +import com.cnlive.strike.xiaojiaspeaker.R; | |
| 17 | +import com.cnlive.strike.xiaojiaspeaker.databinding.ListItemWifi1Binding; | |
| 18 | +import com.cnlive.strike.xiaojiaspeaker.model.WifiConnModel; | |
| 19 | +import com.cnlive.strike.xiaojiaspeaker.util.WifiUtils; | |
| 20 | + | |
| 21 | +import java.util.List; | |
| 22 | + | |
| 23 | +public class WifiRecycleAdapter extends RecyclerView.Adapter { | |
| 24 | + private static final String TAG = "WifiRecycleAdapter"; | |
| 25 | + private Context context; | |
| 26 | + private List<ScanResult> scanResults; | |
| 27 | + private WifiUtils wifiUtils; | |
| 28 | + | |
| 29 | +// public void updateConnNetState(String SSID,int state) { | |
| 30 | +// if (null != scanResults) { | |
| 31 | +// for (WifiConnModel wifiConnModel : scanResults) { | |
| 32 | +// if (wifiConnModel.getScanResult().SSID.equals(SSID)) { | |
| 33 | +// wifiConnModel.setState(state); | |
| 34 | +// } else { | |
| 35 | +// wifiConnModel.setState(WifiConnModel.WIFI_NORMAL); | |
| 36 | +// } | |
| 37 | +// } | |
| 38 | +// notifyDataSetChanged(); | |
| 39 | +// } | |
| 40 | +// } | |
| 41 | + | |
| 42 | +// public void resetNetState(WifiConnModel wifiConnModel) { | |
| 43 | +// if (null != scanResults) { | |
| 44 | +// for (int i = 0; i < scanResults.size(); i++) { | |
| 45 | +// if (!wifiConnModel.getScanResult().BSSID.equals(scanResults.get(i).getScanResult().BSSID)) { | |
| 46 | +// scanResults.get(i).setState(WifiConnModel.WIFI_NORMAL); | |
| 47 | +// } | |
| 48 | +// } | |
| 49 | +// notifyDataSetChanged(); | |
| 50 | +// } | |
| 51 | +// } | |
| 52 | + | |
| 53 | + public void setOnItemClickListener(WifiRecycleAdapter.onItemClickListener onItemClickListener) { | |
| 54 | + this.onItemClickListener = onItemClickListener; | |
| 55 | + } | |
| 56 | + | |
| 57 | + private onItemClickListener onItemClickListener; | |
| 58 | + | |
| 59 | + public WifiRecycleAdapter(Context context, List<ScanResult> scanResults) { | |
| 60 | + this.context = context; | |
| 61 | + this.scanResults = scanResults; | |
| 62 | + wifiUtils = new WifiUtils(context); | |
| 63 | + } | |
| 64 | + | |
| 65 | + public void upDataList(ScanResult scanResult) { | |
| 66 | + this.scanResults.add(scanResult); | |
| 67 | + notifyDataSetChanged(); | |
| 68 | + } | |
| 69 | + | |
| 70 | + @Override | |
| 71 | + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | |
| 72 | + LayoutInflater inflater = LayoutInflater.from(context); | |
| 73 | + ListItemWifi1Binding binding = DataBindingUtil.inflate(inflater, R.layout.list_item_wifi1, parent, false); | |
| 74 | + return new MyViewHolder(binding); | |
| 75 | + } | |
| 76 | + | |
| 77 | + @Override | |
| 78 | + public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { | |
| 79 | + ListItemWifi1Binding binding = ((MyViewHolder) holder).getWifiBinding(); | |
| 80 | + binding.tvWifiName.setText(scanResults.get(position).SSID); | |
| 81 | +// if (getWifiLevel(scanResults.get(position).getScanResult().level) == 1) { | |
| 82 | +// binding.ivWifi.setBackground(context.getResources().getDrawable(R.drawable.wifi1)); | |
| 83 | +// } else if (getWifiLevel(scanResults.get(position).getScanResult().level) == 2) { | |
| 84 | +// binding.ivWifi.setBackground(context.getResources().getDrawable(R.drawable.wifi2)); | |
| 85 | +// } else if (getWifiLevel(scanResults.get(position).getScanResult().level) == 3) { | |
| 86 | +// binding.ivWifi.setBackground(context.getResources().getDrawable(R.drawable.wifi3)); | |
| 87 | +// } else { | |
| 88 | +// binding.ivWifi.setBackground(context.getResources().getDrawable(R.drawable.wifi4)); | |
| 89 | +// } | |
| 90 | +// | |
| 91 | +// if (scanResults.get(position).getState() == WifiConnModel.WIFI_NORMAL) { | |
| 92 | +// WifiInfo wifiInfo = wifiUtils.getConnectedInfo(); | |
| 93 | +// binding.tvWifiState.setVisibility(View.GONE); | |
| 94 | +// } else if (scanResults.get(position).getState() == WifiConnModel.WIFI_CONN_SUCCESS) { | |
| 95 | +// binding.tvWifiState.setVisibility(View.VISIBLE); | |
| 96 | +// binding.tvWifiState.setText("已连接"); | |
| 97 | +// } else if (scanResults.get(position).getState() == WifiConnModel.WIFI_BREAK_CONN) { | |
| 98 | +// binding.tvWifiState.setVisibility(View.VISIBLE); | |
| 99 | +// binding.tvWifiState.setText("连接已断开"); | |
| 100 | +// } else if (scanResults.get(position).getState() == WifiConnModel.WIFI_CONNECTING) { | |
| 101 | +// binding.tvWifiState.setVisibility(View.VISIBLE); | |
| 102 | +// binding.tvWifiState.setText("正在连接..."); | |
| 103 | +// } | |
| 104 | +//// | |
| 105 | +// binding.rlRoot.setOnClickListener(new View.OnClickListener() { | |
| 106 | +// @Override | |
| 107 | +// public void onClick(View view) { | |
| 108 | +// if (null != onItemClickListener) { | |
| 109 | +// onItemClickListener.onItemClick(position, scanResults.get(position)); | |
| 110 | +// } | |
| 111 | +// } | |
| 112 | +// }); | |
| 113 | + } | |
| 114 | + | |
| 115 | + @Override | |
| 116 | + public int getItemCount() { | |
| 117 | + return scanResults.size(); | |
| 118 | + } | |
| 119 | + | |
| 120 | + private class MyViewHolder extends RecyclerView.ViewHolder { | |
| 121 | + public ListItemWifi1Binding getWifiBinding() { | |
| 122 | + return wifiBinding; | |
| 123 | + } | |
| 124 | + | |
| 125 | + private ListItemWifi1Binding wifiBinding; | |
| 126 | + | |
| 127 | + public MyViewHolder(ListItemWifi1Binding wifiBinding) { | |
| 128 | + super(wifiBinding.getRoot()); | |
| 129 | + this.wifiBinding = wifiBinding; | |
| 130 | + } | |
| 131 | + } | |
| 132 | + | |
| 133 | + /** | |
| 134 | + * ,是一个int型数据, | |
| 135 | + * 其中0到-50表示信号最好, | |
| 136 | + * -50到-70表示信号偏差, | |
| 137 | + * 小于-70表示最差, | |
| 138 | + * 有可能连接不上或者掉线, | |
| 139 | + * 一般Wifi已断则值为-200 | |
| 140 | + * | |
| 141 | + * @param level | |
| 142 | + * @return | |
| 143 | + */ | |
| 144 | + private int getWifiLevel(int level) { | |
| 145 | + if (-50 < level) { | |
| 146 | + return 4; | |
| 147 | + } else if (-70 < level) { | |
| 148 | + return 3; | |
| 149 | + } else if (-100 < level) { | |
| 150 | + return 2; | |
| 151 | + } | |
| 152 | + return 1; | |
| 153 | + | |
| 154 | + } | |
| 155 | + | |
| 156 | + public interface onItemClickListener { | |
| 157 | + void onItemClick(int position, WifiConnModel wifiConnModel); | |
| 158 | + } | |
| 159 | + | |
| 160 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/fragment/SearchDevicefragment.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/fragment/SearchDevicefragment.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.fragment; | |
| 2 | + | |
| 3 | +import android.os.Bundle; | |
| 4 | +import android.support.annotation.Nullable; | |
| 5 | +import android.support.v4.content.ContextCompat; | |
| 6 | +import android.view.View; | |
| 7 | + | |
| 8 | +import com.clj.fastble.BleManager; | |
| 9 | +import com.clj.fastble.scan.BleScanRuleConfig; | |
| 10 | +import com.cnlive.libs.base.frame.fragment.MvpBindingFragment; | |
| 11 | +import com.cnlive.libs.base.util.StatusBarUtil; | |
| 12 | +import com.cnlive.libs.base.util.StatusBarUtil2; | |
| 13 | +import com.cnlive.strike.xiaojiaspeaker.R; | |
| 14 | +import com.cnlive.strike.xiaojiaspeaker.databinding.FragmentSearchDeviceBinding; | |
| 15 | +import com.cnlive.strike.xiaojiaspeaker.frame.presenter.SearchDevicefragmentPresenter; | |
| 16 | +import com.cnlive.strike.xiaojiaspeaker.frame.view.SearchDevicefragmentView; | |
| 17 | +import com.hannesdorfmann.mosby3.mvp.MvpFragment; | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * 搜索音箱界面 | |
| 21 | + * | |
| 22 | + * @author ys | |
| 23 | + */ | |
| 24 | +public class SearchDevicefragment extends MvpBindingFragment<SearchDevicefragmentView, SearchDevicefragmentPresenter, Object, FragmentSearchDeviceBinding> { | |
| 25 | + @Override | |
| 26 | + protected int getLayoutId() { | |
| 27 | + return R.layout.fragment_search_device; | |
| 28 | + } | |
| 29 | + | |
| 30 | + @Override | |
| 31 | + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { | |
| 32 | + super.onViewCreated(view, savedInstanceState); | |
| 33 | + initTopBar(); | |
| 34 | + initBlueToothScanConfig(); | |
| 35 | + if (null != getMvpView()) { | |
| 36 | + getMvpView().initView(); | |
| 37 | + getMvpView().initListAdapter(); | |
| 38 | + } | |
| 39 | + } | |
| 40 | + | |
| 41 | + @Override | |
| 42 | + public void onActivityCreated(@Nullable Bundle savedInstanceState) { | |
| 43 | + super.onActivityCreated(savedInstanceState); | |
| 44 | + StatusBarUtil.setStatusBarWrite(getActivity()); | |
| 45 | + StatusBarUtil2.setColor(getActivity(), ContextCompat.getColor(getActivity(), R.color.white), 0); | |
| 46 | + } | |
| 47 | + | |
| 48 | + private void initTopBar() { | |
| 49 | + | |
| 50 | + if (null != binding) { | |
| 51 | + binding.topbar.setTitle("选择配对设备").setTextColor(ContextCompat.getColor(getActivity(), R.color.color_282828)); | |
| 52 | + //设置返回按钮 | |
| 53 | + binding.topbar.addLeftImageButton(R.drawable.icon_back, R.id.left_back).setOnClickListener(new View.OnClickListener() { | |
| 54 | + @Override | |
| 55 | + public void onClick(View view) { | |
| 56 | + if (null != getActivity()) { | |
| 57 | + getActivity().finish(); | |
| 58 | + } | |
| 59 | + } | |
| 60 | + }); | |
| 61 | + } | |
| 62 | + } | |
| 63 | + | |
| 64 | + /** | |
| 65 | + * 初始化蓝牙扫描 | |
| 66 | + */ | |
| 67 | + private void initBlueToothScanConfig() { | |
| 68 | + BleManager.getInstance().init(getActivity().getApplication()); | |
| 69 | + BleScanRuleConfig scanRuleConfig = new BleScanRuleConfig.Builder() | |
| 70 | +// .setServiceUuids(serviceUuids) // 只扫描指定的服务的设备,可选 | |
| 71 | +// .setDeviceName(true, names) // 只扫描指定广播名的设备,可选 | |
| 72 | +// .setDeviceMac(mac) // 只扫描指定mac的设备,可选 | |
| 73 | +// .setAutoConnect(isAutoConnect) // 连接时的autoConnect参数,可选,默认false | |
| 74 | + .setScanTimeOut(1000*60) // 扫描超时时间,可选,默认10秒;小于等于0表示不限制扫描时间 | |
| 75 | + .build(); | |
| 76 | + BleManager.getInstance().initScanRule(scanRuleConfig); | |
| 77 | + //检查蓝牙是否打开 | |
| 78 | +// if (BleManager.getInstance().isBlueEnable()) | |
| 79 | + } | |
| 80 | + | |
| 81 | + @Override | |
| 82 | + public void onDestroy() { | |
| 83 | + super.onDestroy(); | |
| 84 | + BleManager.getInstance().cancelScan(); | |
| 85 | + } | |
| 86 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/fragment/SelectWifiFragment.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/fragment/SelectWifiFragment.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.fragment; | |
| 2 | + | |
| 3 | +import android.content.BroadcastReceiver; | |
| 4 | +import android.content.Context; | |
| 5 | +import android.content.Intent; | |
| 6 | +import android.content.IntentFilter; | |
| 7 | +import android.net.NetworkInfo; | |
| 8 | +import android.net.wifi.WifiManager; | |
| 9 | +import android.os.Bundle; | |
| 10 | +import android.support.annotation.Nullable; | |
| 11 | +import android.support.v4.content.ContextCompat; | |
| 12 | +import android.util.Log; | |
| 13 | +import android.view.View; | |
| 14 | + | |
| 15 | +import com.cnlive.libs.base.frame.fragment.MvpBindingFragment; | |
| 16 | +import com.cnlive.libs.base.util.StatusBarUtil; | |
| 17 | +import com.cnlive.libs.base.util.StatusBarUtil2; | |
| 18 | +import com.cnlive.strike.xiaojiaspeaker.R; | |
| 19 | +import com.cnlive.strike.xiaojiaspeaker.databinding.FragmentSelectWifiBinding; | |
| 20 | +import com.cnlive.strike.xiaojiaspeaker.frame.presenter.SelectWifiFragmentPresenter; | |
| 21 | +import com.cnlive.strike.xiaojiaspeaker.frame.view.SelectWifiFragmentView; | |
| 22 | + | |
| 23 | +public class SelectWifiFragment extends MvpBindingFragment<SelectWifiFragmentView, SelectWifiFragmentPresenter, Object, FragmentSelectWifiBinding> { | |
| 24 | + @Override | |
| 25 | + protected int getLayoutId() { | |
| 26 | + return R.layout.fragment_select_wifi; | |
| 27 | + } | |
| 28 | + | |
| 29 | + @Override | |
| 30 | + public void onActivityCreated(@Nullable Bundle savedInstanceState) { | |
| 31 | + super.onActivityCreated(savedInstanceState); | |
| 32 | + StatusBarUtil.setStatusBarWrite(getActivity()); | |
| 33 | + StatusBarUtil2.setColor(getActivity(), ContextCompat.getColor(getActivity(), R.color.white), 0); | |
| 34 | + } | |
| 35 | + | |
| 36 | + @Override | |
| 37 | + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { | |
| 38 | + super.onViewCreated(view, savedInstanceState); | |
| 39 | + initTopBar(); | |
| 40 | + if (null != getMvpView()) { | |
| 41 | + getMvpView().initWifiList(); | |
| 42 | + registerBroadcast(); | |
| 43 | + } | |
| 44 | + | |
| 45 | + } | |
| 46 | + | |
| 47 | + private void initTopBar() { | |
| 48 | + StatusBarUtil.setStatusBarWrite(getActivity()); | |
| 49 | + StatusBarUtil2.setColor(getActivity(), ContextCompat.getColor(getActivity(), R.color.white), 0); | |
| 50 | + if (null != binding) { | |
| 51 | + binding.topbar.setTitle("请选择WIFI网络").setTextColor(ContextCompat.getColor(getActivity(), R.color.color_282828)); | |
| 52 | + //设置返回按钮 | |
| 53 | + binding.topbar.addLeftImageButton(R.drawable.icon_back, R.id.left_back).setOnClickListener(new View.OnClickListener() { | |
| 54 | + @Override | |
| 55 | + public void onClick(View view) { | |
| 56 | + if (null != getActivity()) { | |
| 57 | + getActivity().finish(); | |
| 58 | + } | |
| 59 | + } | |
| 60 | + }); | |
| 61 | + } | |
| 62 | + } | |
| 63 | + | |
| 64 | + private void registerBroadcast() { | |
| 65 | + IntentFilter intentFilter = new IntentFilter(); | |
| 66 | + intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); | |
| 67 | + intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); | |
| 68 | + intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); | |
| 69 | + intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); | |
| 70 | + getActivity().registerReceiver(mBroadcastReceiver, intentFilter); | |
| 71 | + } | |
| 72 | + | |
| 73 | + @Override | |
| 74 | + public void onDestroy() { | |
| 75 | + super.onDestroy(); | |
| 76 | + if (null != mBroadcastReceiver) { | |
| 77 | + getActivity().unregisterReceiver(mBroadcastReceiver); | |
| 78 | + } | |
| 79 | + } | |
| 80 | + | |
| 81 | + private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { | |
| 82 | + @Override | |
| 83 | + public void onReceive(Context context, Intent intent) { | |
| 84 | + String resultAction = intent.getAction(); | |
| 85 | + //当扫描结果后,进行刷新列表 | |
| 86 | + if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { | |
| 87 | + Log.e("aa", "onReceive: SCAN_RESULTS_AVAILABLE_ACTION" ); | |
| 88 | + //扫描wifi | |
| 89 | + if (null != getMvpView()) { | |
| 90 | + getMvpView().updateWifiList(); | |
| 91 | + } | |
| 92 | + } else if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {//wifi连接网络状态变化 | |
| 93 | + NetworkInfo.DetailedState state = ((NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO)).getDetailedState(); | |
| 94 | + } else if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {//wifi状态变化 | |
| 95 | + int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_DISABLED); | |
| 96 | + } else if (intent.getAction().equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { | |
| 97 | + } | |
| 98 | + } | |
| 99 | + }; | |
| 100 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/widget/SelectDialog.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/widget/SelectDialog.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.widget; | |
| 2 | + | |
| 3 | +import android.app.Dialog; | |
| 4 | +import android.content.Context; | |
| 5 | +import android.os.Bundle; | |
| 6 | +import android.support.annotation.NonNull; | |
| 7 | +import android.support.v4.content.ContextCompat; | |
| 8 | +import android.view.LayoutInflater; | |
| 9 | +import android.view.View; | |
| 10 | +import android.view.ViewGroup; | |
| 11 | +import android.view.WindowManager; | |
| 12 | +import android.widget.Button; | |
| 13 | +import android.widget.LinearLayout; | |
| 14 | +import android.widget.TextView; | |
| 15 | + | |
| 16 | +import com.cnlive.strike.xiaojiaspeaker.R; | |
| 17 | + | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * 任务编辑对话框 | |
| 21 | + * | |
| 22 | + * @author ShinnyYang | |
| 23 | + * @date 2019/3/27 14:11 | |
| 24 | + */ | |
| 25 | +public class SelectDialog extends Dialog { | |
| 26 | + private Context context; | |
| 27 | + private TextView tv_dialog_tip; | |
| 28 | + private Button btn_cancel; | |
| 29 | + private Button btn_ok; | |
| 30 | + private LinearLayout ll_child; | |
| 31 | + private View view; | |
| 32 | + private DialogInterface cancelInterface; | |
| 33 | + private DialogInterface okInterface; | |
| 34 | + private LinearLayout.LayoutParams layoutParams; | |
| 35 | + | |
| 36 | + public SelectDialog(@NonNull Context context, String tipText, String btnCancelText, DialogInterface cancelInterface, String btnOkText, DialogInterface okInterface) { | |
| 37 | + super(context, R.style.MyDialog); | |
| 38 | + this.context = context; | |
| 39 | + view = LayoutInflater.from(context).inflate(R.layout.dialog_select, null); | |
| 40 | + initView(view); | |
| 41 | + layoutParams = new LinearLayout.LayoutParams((int) (getScreenWidth(context) * 0.8), ViewGroup.LayoutParams.WRAP_CONTENT); | |
| 42 | + ll_child.setLayoutParams(layoutParams); | |
| 43 | + | |
| 44 | + tv_dialog_tip.setText(tipText); | |
| 45 | + btn_cancel.setText(btnCancelText); | |
| 46 | + btn_ok.setText(btnOkText); | |
| 47 | + this.cancelInterface = cancelInterface; | |
| 48 | + this.okInterface = okInterface; | |
| 49 | + | |
| 50 | + } | |
| 51 | + | |
| 52 | + public void setLeftBtnColor(int textColor) { | |
| 53 | + if (null != btn_cancel && null != cancelInterface) { | |
| 54 | + btn_cancel.setTextColor(ContextCompat.getColor(context, textColor)); | |
| 55 | + } | |
| 56 | + } | |
| 57 | + | |
| 58 | + public void setRightBtnColor(int textColor) { | |
| 59 | + if (null != btn_ok && null != cancelInterface) { | |
| 60 | + btn_ok.setTextColor(ContextCompat.getColor(context, textColor)); | |
| 61 | + } | |
| 62 | + } | |
| 63 | + | |
| 64 | + public void setTipMessage(String message) { | |
| 65 | + tv_dialog_tip.setText(message); | |
| 66 | + } | |
| 67 | + | |
| 68 | + public SelectDialog(@NonNull Context context, View customview, int themeResId) { | |
| 69 | + super(context, themeResId); | |
| 70 | + this.context = context; | |
| 71 | + } | |
| 72 | + | |
| 73 | + | |
| 74 | + @Override | |
| 75 | + protected void onCreate(Bundle savedInstanceState) { | |
| 76 | + super.onCreate(savedInstanceState); | |
| 77 | + | |
| 78 | + | |
| 79 | + //显示视图 | |
| 80 | + this.setContentView(view); | |
| 81 | + } | |
| 82 | + | |
| 83 | + private void initView(View rootView) { | |
| 84 | + this.tv_dialog_tip = (TextView) rootView.findViewById(R.id.tv_dialog_tip); | |
| 85 | + this.btn_cancel = (Button) rootView.findViewById(R.id.btn_cancel); | |
| 86 | + this.btn_ok = (Button) rootView.findViewById(R.id.btn_ok); | |
| 87 | + this.ll_child = (LinearLayout) rootView.findViewById(R.id.ll_child); | |
| 88 | + btn_cancel.setOnClickListener(new View.OnClickListener() { | |
| 89 | + @Override | |
| 90 | + public void onClick(View view) { | |
| 91 | + cancelInterface.onClick(SelectDialog.this); | |
| 92 | + } | |
| 93 | + }); | |
| 94 | + btn_ok.setOnClickListener(new View.OnClickListener() { | |
| 95 | + @Override | |
| 96 | + public void onClick(View view) { | |
| 97 | + | |
| 98 | + okInterface.onClick(SelectDialog.this); | |
| 99 | + } | |
| 100 | + }); | |
| 101 | + } | |
| 102 | + | |
| 103 | + public interface DialogInterface { | |
| 104 | + void onClick(SelectDialog dialog); | |
| 105 | + } | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * 获取屏幕宽度 | |
| 109 | + * | |
| 110 | + * @param context | |
| 111 | + * @return | |
| 112 | + */ | |
| 113 | + public static int getScreenWidth(Context context) { | |
| 114 | + WindowManager wm = (WindowManager) context | |
| 115 | + .getSystemService(Context.WINDOW_SERVICE); | |
| 116 | + int width = wm.getDefaultDisplay().getWidth(); | |
| 117 | + return width; | |
| 118 | + } | |
| 119 | + | |
| 120 | + /** | |
| 121 | + * 获取屏幕高度 | |
| 122 | + * | |
| 123 | + * @param context | |
| 124 | + * @return | |
| 125 | + */ | |
| 126 | + public static int getScreenHeight(Context context) { | |
| 127 | + WindowManager wm = (WindowManager) context | |
| 128 | + .getSystemService(Context.WINDOW_SERVICE); | |
| 129 | + int height = wm.getDefaultDisplay().getHeight(); | |
| 130 | + return height; | |
| 131 | + } | |
| 132 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/widget/WifiPwdDialog.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/ui/widget/WifiPwdDialog.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.ui.widget; | |
| 2 | + | |
| 3 | +import android.app.Dialog; | |
| 4 | +import android.content.Context; | |
| 5 | +import android.os.Bundle; | |
| 6 | +import android.support.annotation.NonNull; | |
| 7 | +import android.text.Editable; | |
| 8 | +import android.text.TextWatcher; | |
| 9 | +import android.view.LayoutInflater; | |
| 10 | +import android.view.View; | |
| 11 | +import android.view.ViewGroup; | |
| 12 | +import android.view.WindowManager; | |
| 13 | +import android.widget.Button; | |
| 14 | +import android.widget.EditText; | |
| 15 | +import android.widget.LinearLayout; | |
| 16 | +import android.widget.TextView; | |
| 17 | + | |
| 18 | +import com.cnlive.strike.xiaojiaspeaker.R; | |
| 19 | + | |
| 20 | + | |
| 21 | +/** | |
| 22 | + * 任务编辑对话框 | |
| 23 | + * | |
| 24 | + * @author ShinnyYang | |
| 25 | + * @date 2019/3/27 14:11 | |
| 26 | + */ | |
| 27 | +public class WifiPwdDialog extends Dialog { | |
| 28 | + private Context context; | |
| 29 | + private TextView tv_dialog_tip; | |
| 30 | + private EditText et_pwd; | |
| 31 | + private Button btn_cancel; | |
| 32 | + private Button btn_ok; | |
| 33 | + private LinearLayout ll_child; | |
| 34 | + private View view; | |
| 35 | + private DialogInterface cancelInterface; | |
| 36 | + private ConnDialogInterface okInterface; | |
| 37 | + private LinearLayout.LayoutParams layoutParams; | |
| 38 | + | |
| 39 | + public WifiPwdDialog(@NonNull Context context, String tipText, String btnCancelText, DialogInterface cancelInterface, String btnOkText, ConnDialogInterface okInterface) { | |
| 40 | + super(context, R.style.MyDialog); | |
| 41 | + this.context = context; | |
| 42 | + view = LayoutInflater.from(context).inflate(R.layout.dialog_wifi_pwd, null); | |
| 43 | + initView(view); | |
| 44 | + layoutParams = new LinearLayout.LayoutParams((int) (getScreenWidth(context) * 0.8), ViewGroup.LayoutParams.WRAP_CONTENT); | |
| 45 | + ll_child.setLayoutParams(layoutParams); | |
| 46 | + tv_dialog_tip.setText(tipText); | |
| 47 | + btn_cancel.setText(btnCancelText); | |
| 48 | + btn_ok.setText(btnOkText); | |
| 49 | + this.cancelInterface = cancelInterface; | |
| 50 | + this.okInterface = okInterface; | |
| 51 | + | |
| 52 | + } | |
| 53 | + | |
| 54 | + public WifiPwdDialog(@NonNull Context context, View customview, int themeResId) { | |
| 55 | + super(context, themeResId); | |
| 56 | + this.context = context; | |
| 57 | + } | |
| 58 | + | |
| 59 | + | |
| 60 | + @Override | |
| 61 | + protected void onCreate(Bundle savedInstanceState) { | |
| 62 | + super.onCreate(savedInstanceState); | |
| 63 | + //显示视图 | |
| 64 | + this.setContentView(view); | |
| 65 | + } | |
| 66 | + | |
| 67 | + private void initView(View rootView) { | |
| 68 | + this.tv_dialog_tip = (TextView) rootView.findViewById(R.id.tv_dialog_tip); | |
| 69 | + this.btn_cancel = (Button) rootView.findViewById(R.id.btn_cancel); | |
| 70 | + this.btn_ok = (Button) rootView.findViewById(R.id.btn_ok); | |
| 71 | + this.ll_child = (LinearLayout) rootView.findViewById(R.id.ll_child); | |
| 72 | + this.et_pwd = (EditText) rootView.findViewById(R.id.et_pwd); | |
| 73 | + btn_ok.setClickable(false); | |
| 74 | + btn_ok.setFocusable(false); | |
| 75 | + btn_ok.setBackground(null); | |
| 76 | + btn_ok.setTextColor(context.getResources().getColor(R.color.line)); | |
| 77 | + this.et_pwd.addTextChangedListener(new TextWatcher() { | |
| 78 | + @Override | |
| 79 | + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { | |
| 80 | + | |
| 81 | + } | |
| 82 | + | |
| 83 | + @Override | |
| 84 | + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { | |
| 85 | + if (charSequence.length() < 8) { | |
| 86 | + btn_ok.setClickable(false); | |
| 87 | + btn_ok.setFocusable(false); | |
| 88 | + btn_ok.setBackground(null); | |
| 89 | + btn_ok.setTextColor(context.getResources().getColor(R.color.line)); | |
| 90 | + } else { | |
| 91 | + btn_ok.setClickable(true); | |
| 92 | + btn_ok.setFocusable(true); | |
| 93 | + btn_ok.setTextColor(context.getResources().getColor(R.color.black)); | |
| 94 | + btn_ok.setBackground(context.getResources().getDrawable(R.drawable.selector_dialog_btn_right)); | |
| 95 | + } | |
| 96 | + } | |
| 97 | + | |
| 98 | + @Override | |
| 99 | + public void afterTextChanged(Editable editable) { | |
| 100 | + | |
| 101 | + } | |
| 102 | + }); | |
| 103 | + btn_cancel.setOnClickListener(new View.OnClickListener() { | |
| 104 | + @Override | |
| 105 | + public void onClick(View view) { | |
| 106 | + if (null != cancelInterface) { | |
| 107 | + cancelInterface.onClick(WifiPwdDialog.this); | |
| 108 | + } | |
| 109 | + } | |
| 110 | + }); | |
| 111 | + btn_ok.setOnClickListener(new View.OnClickListener() { | |
| 112 | + @Override | |
| 113 | + public void onClick(View view) { | |
| 114 | + if (null != okInterface) { | |
| 115 | + okInterface.onClick(WifiPwdDialog.this, et_pwd.getText().toString()); | |
| 116 | + } | |
| 117 | + } | |
| 118 | + }); | |
| 119 | + } | |
| 120 | + | |
| 121 | + public interface DialogInterface { | |
| 122 | + void onClick(WifiPwdDialog dialog); | |
| 123 | + } | |
| 124 | + | |
| 125 | + public interface ConnDialogInterface { | |
| 126 | + void onClick(WifiPwdDialog dialog, String pwd); | |
| 127 | + } | |
| 128 | + | |
| 129 | + /** | |
| 130 | + * 获取屏幕宽度 | |
| 131 | + * | |
| 132 | + * @param context | |
| 133 | + * @return | |
| 134 | + */ | |
| 135 | + public static int getScreenWidth(Context context) { | |
| 136 | + WindowManager wm = (WindowManager) context | |
| 137 | + .getSystemService(Context.WINDOW_SERVICE); | |
| 138 | + int width = wm.getDefaultDisplay().getWidth(); | |
| 139 | + return width; | |
| 140 | + } | |
| 141 | + | |
| 142 | + /** | |
| 143 | + * 获取屏幕高度 | |
| 144 | + * | |
| 145 | + * @param context | |
| 146 | + * @return | |
| 147 | + */ | |
| 148 | + public static int getScreenHeight(Context context) { | |
| 149 | + WindowManager wm = (WindowManager) context | |
| 150 | + .getSystemService(Context.WINDOW_SERVICE); | |
| 151 | + int height = wm.getDefaultDisplay().getHeight(); | |
| 152 | + return height; | |
| 153 | + } | |
| 154 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/util/BlueToothUtil.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/util/BlueToothUtil.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.util; | |
| 2 | + | |
| 3 | +public class BlueToothUtil { | |
| 4 | + public static String getSSIDAndPwd(String ssid, String pwd, String uid) { | |
| 5 | + StringBuilder builder = new StringBuilder(); | |
| 6 | + builder.append("1111("); | |
| 7 | + builder.append("v1"); | |
| 8 | + builder.append('#'); | |
| 9 | + builder.append(encode(ssid)); | |
| 10 | + builder.append('#'); | |
| 11 | + builder.append(encode(pwd)); | |
| 12 | + builder.append('#'); | |
| 13 | + builder.append(encode(uid)); | |
| 14 | + builder.append('#'); | |
| 15 | + builder.append(")2222"); | |
| 16 | + String info = builder.toString(); | |
| 17 | + String infoSend = info.replaceAll("(.{16})", "$1DATA"); | |
| 18 | + return "DATA" + infoSend; | |
| 19 | + } | |
| 20 | + | |
| 21 | + private static String encode(String str) { | |
| 22 | + StringBuilder builder = new StringBuilder(); | |
| 23 | + for (int i = 0; i < str.length(); ++i) { | |
| 24 | + char ch = str.charAt(i); | |
| 25 | + if (ch == '#') { | |
| 26 | + builder.append('\\'); | |
| 27 | + } else if (ch == '\\') { | |
| 28 | + builder.append('\\'); | |
| 29 | + } | |
| 30 | + builder.append(ch); | |
| 31 | + } | |
| 32 | + return builder.toString(); | |
| 33 | + } | |
| 34 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/util/QMUITipDialogUtil.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/util/QMUITipDialogUtil.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.util; | |
| 2 | + | |
| 3 | +import android.content.Context; | |
| 4 | +import android.os.Handler; | |
| 5 | + | |
| 6 | +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * 文 件 名: QMUITipDialogUtil | |
| 10 | + * 创 建 人: 杨帅 | |
| 11 | + * 创建日期: 2018/10/22 18:51 | |
| 12 | + * 描 述: | |
| 13 | + * 修 改 人: | |
| 14 | + * 修改时间: | |
| 15 | + * 修改备注: | |
| 16 | + */ | |
| 17 | +public class QMUITipDialogUtil { | |
| 18 | + private static QMUITipDialog tipDialog; | |
| 19 | + | |
| 20 | + | |
| 21 | + /** | |
| 22 | + * Loading 类型提示框 | |
| 23 | + * | |
| 24 | + * @param context | |
| 25 | + * @param tipStr | |
| 26 | + */ | |
| 27 | + public static void loadingDialog(Context context, String tipStr, boolean isCancel) { | |
| 28 | + try { | |
| 29 | + if (context == null) { | |
| 30 | + return; | |
| 31 | + } | |
| 32 | + if (tipDialog != null && tipDialog.isShowing()) { | |
| 33 | + tipDialog.dismiss(); | |
| 34 | + } | |
| 35 | + tipDialog = new QMUITipDialog.Builder(context) | |
| 36 | + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) | |
| 37 | + .setTipWord(tipStr) | |
| 38 | + .create(); | |
| 39 | + tipDialog.setCanceledOnTouchOutside(isCancel);//屏蔽返回键 | |
| 40 | + tipDialog.setCancelable(isCancel); | |
| 41 | + if (!tipDialog.isShowing()) { | |
| 42 | + tipDialog.show(); | |
| 43 | + } | |
| 44 | + } catch (Exception e) { | |
| 45 | + | |
| 46 | + } | |
| 47 | + | |
| 48 | + } | |
| 49 | + | |
| 50 | + /** | |
| 51 | + * 成功提示类型提示框 | |
| 52 | + * | |
| 53 | + * @param context | |
| 54 | + */ | |
| 55 | + public static void successDialog(final Context context, String tipStr, int second) { | |
| 56 | + try { | |
| 57 | + if (context == null) { | |
| 58 | + return; | |
| 59 | + } | |
| 60 | + | |
| 61 | + if (tipDialog != null && tipDialog.isShowing()) { | |
| 62 | + tipDialog.dismiss(); | |
| 63 | + } | |
| 64 | + tipDialog = new QMUITipDialog.Builder(context) | |
| 65 | + .setIconType(QMUITipDialog.Builder.ICON_TYPE_SUCCESS) | |
| 66 | + .setTipWord(tipStr) | |
| 67 | + .create(); | |
| 68 | + tipDialog.setCanceledOnTouchOutside(false);//屏蔽返回键 | |
| 69 | + if (!tipDialog.isShowing()) { | |
| 70 | + tipDialog.show(); | |
| 71 | + new Handler().postDelayed(new Runnable() { | |
| 72 | + @Override | |
| 73 | + public void run() { | |
| 74 | + if (context == null) { | |
| 75 | + return; | |
| 76 | + } | |
| 77 | + /** | |
| 78 | + * 延时执行的代码 | |
| 79 | + */ | |
| 80 | + if (tipDialog != null && tipDialog.isShowing()) { | |
| 81 | + tipDialog.dismiss(); | |
| 82 | + } | |
| 83 | + } | |
| 84 | + }, second * 1000); // 延时2秒 | |
| 85 | + } | |
| 86 | + } catch (Exception e) { | |
| 87 | + | |
| 88 | + } | |
| 89 | + | |
| 90 | + } | |
| 91 | + | |
| 92 | + /** | |
| 93 | + * 失败提示类型提示框 | |
| 94 | + * | |
| 95 | + * @param context | |
| 96 | + */ | |
| 97 | + public static void failedDialog(final Context context, String tipStr, int second) { | |
| 98 | + try { | |
| 99 | + if (tipDialog != null && tipDialog.isShowing()) { | |
| 100 | + tipDialog.dismiss(); | |
| 101 | + } | |
| 102 | + tipDialog = new QMUITipDialog.Builder(context) | |
| 103 | + .setIconType(QMUITipDialog.Builder.ICON_TYPE_FAIL) | |
| 104 | + .setTipWord(tipStr) | |
| 105 | + .create(); | |
| 106 | + tipDialog.setCanceledOnTouchOutside(false);//屏蔽返回键 | |
| 107 | + if (!tipDialog.isShowing()) { | |
| 108 | + tipDialog.show(); | |
| 109 | + new Handler().postDelayed(new Runnable() { | |
| 110 | + @Override | |
| 111 | + public void run() { | |
| 112 | + if (context == null) { | |
| 113 | + return; | |
| 114 | + } | |
| 115 | + /** | |
| 116 | + * 延时执行的代码 | |
| 117 | + */ | |
| 118 | + if (tipDialog != null && tipDialog.isShowing()) { | |
| 119 | + tipDialog.dismiss(); | |
| 120 | + } | |
| 121 | + } | |
| 122 | + }, second * 1000); // 延时2秒 | |
| 123 | + } | |
| 124 | + } catch (Exception e) { | |
| 125 | + | |
| 126 | + } | |
| 127 | + if (context == null) { | |
| 128 | + return; | |
| 129 | + } | |
| 130 | + | |
| 131 | + | |
| 132 | + } | |
| 133 | + | |
| 134 | + /** | |
| 135 | + * 信息提示类型提示框 | |
| 136 | + * | |
| 137 | + * @param context | |
| 138 | + */ | |
| 139 | + public static void messageDialog(final Context context, String tipStr, int second) { | |
| 140 | + try { | |
| 141 | + if (tipDialog != null && tipDialog.isShowing()) { | |
| 142 | + tipDialog.dismiss(); | |
| 143 | + } | |
| 144 | + tipDialog = new QMUITipDialog.Builder(context) | |
| 145 | + .setIconType(QMUITipDialog.Builder.ICON_TYPE_INFO) | |
| 146 | + .setTipWord(tipStr) | |
| 147 | + .create(); | |
| 148 | + tipDialog.setCanceledOnTouchOutside(false);//屏蔽返回键 | |
| 149 | + if (!tipDialog.isShowing()) { | |
| 150 | + tipDialog.show(); | |
| 151 | + new Handler().postDelayed(new Runnable() { | |
| 152 | + @Override | |
| 153 | + public void run() { | |
| 154 | + if (context == null) { | |
| 155 | + return; | |
| 156 | + } | |
| 157 | + /** | |
| 158 | + * 延时执行的代码 | |
| 159 | + */ | |
| 160 | + tipDialog.dismiss(); | |
| 161 | + } | |
| 162 | + }, second * 1000); // 延时2秒 | |
| 163 | + } | |
| 164 | + } catch (Exception e) { | |
| 165 | + | |
| 166 | + } | |
| 167 | + if (context == null) { | |
| 168 | + return; | |
| 169 | + } | |
| 170 | + | |
| 171 | + } | |
| 172 | + | |
| 173 | + | |
| 174 | + /** | |
| 175 | + * 单独文字类型提示框 | |
| 176 | + * | |
| 177 | + * @param context | |
| 178 | + */ | |
| 179 | + public static void textDialog(final Context context, String tipStr, int second) { | |
| 180 | + try { | |
| 181 | + if (context == null) { | |
| 182 | + return; | |
| 183 | + } | |
| 184 | + if (tipDialog != null && tipDialog.isShowing()) { | |
| 185 | + tipDialog.dismiss(); | |
| 186 | + } | |
| 187 | + tipDialog = new QMUITipDialog.Builder(context) | |
| 188 | + .setTipWord(tipStr) | |
| 189 | + .create(); | |
| 190 | + tipDialog.setCanceledOnTouchOutside(false);//屏蔽返回键 | |
| 191 | + if (!tipDialog.isShowing()) { | |
| 192 | + tipDialog.show(); | |
| 193 | + new Handler().postDelayed(new Runnable() { | |
| 194 | + @Override | |
| 195 | + public void run() { | |
| 196 | + if (context == null) { | |
| 197 | + return; | |
| 198 | + } | |
| 199 | + /** | |
| 200 | + * 延时执行的代码 | |
| 201 | + */ | |
| 202 | + tipDialog.dismiss(); | |
| 203 | + } | |
| 204 | + }, second * 1000); // 延时2秒 | |
| 205 | + } | |
| 206 | + } catch (Exception e) { | |
| 207 | + | |
| 208 | + } | |
| 209 | + | |
| 210 | + } | |
| 211 | + | |
| 212 | + public static void dismessDialog() { | |
| 213 | + try { | |
| 214 | + if (tipDialog != null && tipDialog.isShowing()) { | |
| 215 | + tipDialog.dismiss(); | |
| 216 | + } | |
| 217 | + } catch (Exception e) { | |
| 218 | + | |
| 219 | + } | |
| 220 | + | |
| 221 | + } | |
| 222 | +} | ... | ... |
module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/util/WifiCheckUtil.java
0 → 100644
| 1 | +++ a/module_xiaojiaspeaker/src/main/java/com/cnlive/strike/xiaojiaspeaker/util/WifiCheckUtil.java | |
| 1 | +package com.cnlive.strike.xiaojiaspeaker.util; | |
| 2 | + | |
| 3 | +public class WifiCheckUtil { | |
| 4 | + private static long lastClickTime = 0; | |
| 5 | + private static long DIFF = 1000; | |
| 6 | + private static int lastButtonId = -1; | |
| 7 | + | |
| 8 | + /** | |
| 9 | + * 判断两次点击的间隔,如果小于1000,则认为是多次无效点击 | |
| 10 | + * | |
| 11 | + * @return | |
| 12 | + */ | |
| 13 | + public static boolean isFastOperate() { | |
| 14 | + return isFastDoubleClick(-1, DIFF); | |
| 15 | + } | |
| 16 | + | |
| 17 | + /** | |
| 18 | + * 判断两次点击的间隔,如果小于1000,则认为是多次无效点击 | |
| 19 | + * | |
| 20 | + * @return | |
| 21 | + */ | |
| 22 | + public static boolean isFastDoubleClick(int buttonId) { | |
| 23 | + return isFastDoubleClick(buttonId, DIFF); | |
| 24 | + } | |
| 25 | + | |
| 26 | + /** | |
| 27 | + * 判断两次点击的间隔,如果小于diff,则认为是多次无效点击 | |
| 28 | + * | |
| 29 | + * @param diff | |
| 30 | + * @return | |
| 31 | + */ | |
| 32 | + public static boolean isFastDoubleClick(int buttonId, long diff) { | |
| 33 | + long time = System.currentTimeMillis(); | |
| 34 | + long timeD = time - lastClickTime; | |
| 35 | + if (lastButtonId == buttonId && lastClickTime > 0 && timeD < diff) { | |
| 36 | + return true; | |
| 37 | + } | |
| 38 | + lastClickTime = time; | |
| 39 | + lastButtonId = buttonId; | |
| 40 | + return false; | |
| 41 | + } | |
| 42 | + | |
| 43 | +} | ... | ... |