Reader App
15
.gitignore
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/caches
|
||||||
|
/.idea/libraries
|
||||||
|
/.idea/modules.xml
|
||||||
|
/.idea/workspace.xml
|
||||||
|
/.idea/navEditor.xml
|
||||||
|
/.idea/assetWizardSettings.xml
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
||||||
|
.cxx
|
||||||
|
local.properties
|
||||||
3
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
1
.idea/.name
generated
Normal file
@@ -0,0 +1 @@
|
|||||||
|
My Application
|
||||||
6
.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<bytecodeTargetLevel target="11" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding">
|
||||||
|
<file url="PROJECT" charset="UTF-8" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
20
.idea/gradle.xml
generated
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
|
<component name="GradleSettings">
|
||||||
|
<option name="linkedExternalProjectsSettings">
|
||||||
|
<GradleProjectSettings>
|
||||||
|
<option name="testRunner" value="PLATFORM" />
|
||||||
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="modules">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
<option value="$PROJECT_DIR$/app" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
<option name="resolveModulePerSourceSet" value="false" />
|
||||||
|
</GradleProjectSettings>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
35
.idea/jarRepositories.xml
generated
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RemoteRepositoriesConfiguration">
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="central" />
|
||||||
|
<option name="name" value="Maven Central repository" />
|
||||||
|
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="jboss.community" />
|
||||||
|
<option name="name" value="JBoss Community repository" />
|
||||||
|
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="MavenRepo" />
|
||||||
|
<option name="name" value="MavenRepo" />
|
||||||
|
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="BintrayJCenter" />
|
||||||
|
<option name="name" value="BintrayJCenter" />
|
||||||
|
<option name="url" value="https://jcenter.bintray.com/" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="Google" />
|
||||||
|
<option name="name" value="Google" />
|
||||||
|
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="maven" />
|
||||||
|
<option name="name" value="maven" />
|
||||||
|
<option name="url" value="https://jitpack.io" />
|
||||||
|
</remote-repository>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
9
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectType">
|
||||||
|
<option name="id" value="Android" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
10
.idea/runConfigurations.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RunConfigurationProducerService">
|
||||||
|
<option name="ignoredProducers">
|
||||||
|
<set>
|
||||||
|
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
2
app/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/build
|
||||||
|
*.iml
|
||||||
128
app/build.gradle
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'com.google.gms.google-services'
|
||||||
|
apply plugin: 'com.google.firebase.crashlytics'
|
||||||
|
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 29
|
||||||
|
buildToolsVersion "29.0.3"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "no.Reader.android.iisc"
|
||||||
|
|
||||||
|
minSdkVersion 18
|
||||||
|
targetSdkVersion 29
|
||||||
|
versionCode 78
|
||||||
|
versionName "2.9.0"
|
||||||
|
resConfigs "en"
|
||||||
|
multiDexEnabled true
|
||||||
|
|
||||||
|
|
||||||
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
debug {
|
||||||
|
minifyEnabled false
|
||||||
|
shrinkResources false
|
||||||
|
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
release {
|
||||||
|
minifyEnabled true
|
||||||
|
shrinkResources true
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||||
|
// nRF Toolbox is using Play Service 10.2.0 in order to make the app working in China:
|
||||||
|
// https://developer.android.com/training/wearables/apps/creating-app-china.html
|
||||||
|
//noinspection GradleDependency
|
||||||
|
implementation 'com.google.android.gms:play-services-wearable:10.2.0'
|
||||||
|
|
||||||
|
implementation 'androidx.appcompat:appcompat:1.3.0-alpha01'
|
||||||
|
implementation 'androidx.preference:preference:1.1.1'
|
||||||
|
implementation 'de.hdodenhof:circleimageview:3.1.0'
|
||||||
|
|
||||||
|
implementation 'no.nordicsemi.android:log:2.2.0'
|
||||||
|
implementation 'no.nordicsemi.android.support.v18:scanner:1.4.3'
|
||||||
|
implementation 'org.apache.poi:poi:4.0.0'
|
||||||
|
implementation 'org.apache.poi:poi-ooxml:4.0.0'
|
||||||
|
implementation 'com.android.support:multidex:1.0.1'
|
||||||
|
|
||||||
|
// The DFU Library is imported automatically from jcenter:
|
||||||
|
implementation 'no.nordicsemi.android:dfu:1.10.3'
|
||||||
|
implementation 'com.github.PhilJay:MPAndroidChart:v2.2.4'
|
||||||
|
|
||||||
|
implementation 'androidx.appcompat:appcompat:1.1.0-alpha04'
|
||||||
|
|
||||||
|
|
||||||
|
implementation 'com.hbb20:ccp:2.4.0'
|
||||||
|
implementation 'androidx.preference:preference:1.1.0-alpha04'
|
||||||
|
implementation 'com.google.android.material:material:1.1.0-alpha05'
|
||||||
|
implementation 'com.google.android.material:material:1.1.0'
|
||||||
|
|
||||||
|
implementation 'com.google.firebase:firebase-database:16.0.4'
|
||||||
|
|
||||||
|
implementation 'androidx.appcompat:appcompat:1.1.0-alpha04'
|
||||||
|
|
||||||
|
implementation 'com.google.firebase:firebase-auth:16.0.5'
|
||||||
|
|
||||||
|
|
||||||
|
implementation 'androidx.preference:preference:1.1.0-alpha04'
|
||||||
|
|
||||||
|
implementation 'no.nordicsemi.android:log:2.2.0'
|
||||||
|
implementation 'com.chaos.view:pinview:1.4.3'
|
||||||
|
implementation "androidx.browser:browser:1.3.0"
|
||||||
|
|
||||||
|
|
||||||
|
implementation 'com.github.bumptech.glide:glide:4.11.0'
|
||||||
|
implementation 'com.firebaseui:firebase-ui-database:7.1.1'
|
||||||
|
implementation 'com.github.PhilJay:MPAndroidChart:v2.2.4'
|
||||||
|
|
||||||
|
implementation 'com.google.firebase:firebase-crashlytics:17.1.1'
|
||||||
|
|
||||||
|
implementation 'com.hbb20:ccp:2.4.0'
|
||||||
|
|
||||||
|
implementation 'com.google.firebase:firebase-auth:20.0.1'
|
||||||
|
|
||||||
|
implementation 'com.google.android.material:material:1.0.0'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
implementation 'com.google.firebase:firebase-storage:16.0.4'
|
||||||
|
|
||||||
|
// if you desire to build the DFU Library, clone the
|
||||||
|
// https://github.com/NordicSemiconductor/Android-DFU-Library project into DFULibrary folder,
|
||||||
|
// add it as a module into the project structure and uncomment the following line
|
||||||
|
// (and also the according lines in the settings.gradle):
|
||||||
|
// implementation project(':dfu')
|
||||||
|
|
||||||
|
// Gson is needed for DFU to work. The DFU library dependency to Gson is internal and would
|
||||||
|
// not be attached to APK.
|
||||||
|
// See: https://github.com/NordicSemiconductor/Android-nRF-Toolbox/issues/86
|
||||||
|
|
||||||
|
// Import the BLE Common Library.
|
||||||
|
// The BLE Common Library depends on BLE Library. It is enough to include the first one.
|
||||||
|
implementation 'no.nordicsemi.android:ble-common:2.1.1'
|
||||||
|
// The BLE Common Library may be included from jcenter. If you want to modify the code,
|
||||||
|
// clone both projects from GitHub and replace the line above with the following
|
||||||
|
// (and also the according lines in the settings.gradle):
|
||||||
|
// implementation project(':ble-common')
|
||||||
|
|
||||||
|
implementation('org.simpleframework:simple-xml:2.7.1') {
|
||||||
|
exclude group: 'stax', module: 'stax-api'
|
||||||
|
exclude group: 'xpp3', module: 'xpp3'
|
||||||
|
}
|
||||||
|
}
|
||||||
48
app/google-services.json
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"project_info": {
|
||||||
|
"project_number": "168819095878",
|
||||||
|
"firebase_url": "https://reader-app-43cb6-default-rtdb.firebaseio.com",
|
||||||
|
"project_id": "reader-app-43cb6",
|
||||||
|
"storage_bucket": "reader-app-43cb6.appspot.com"
|
||||||
|
},
|
||||||
|
"client": [
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:168819095878:android:9d4989cee1616d1a444d47",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "no.Reader.android.iisc"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "168819095878-f1d70oknl1g9l4sbrrlb6eniqchmtgb7.apps.googleusercontent.com",
|
||||||
|
"client_type": 1,
|
||||||
|
"android_info": {
|
||||||
|
"package_name": "no.Reader.android.iisc",
|
||||||
|
"certificate_hash": "cd10342afabfcce43c9dc370cf20c4c2d6e1b1dd"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"client_id": "168819095878-7a1tejv9lv3o144c9v5fj6bls8vi2soc.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyCdG2nyJYp-71n67JtjsfKJCS00XUzKFQk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"appinvite_service": {
|
||||||
|
"other_platform_oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "168819095878-7a1tejv9lv3o144c9v5fj6bls8vi2soc.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configuration_version": "1"
|
||||||
|
}
|
||||||
BIN
app/libs/achartengine-1.2.0.jar
Normal file
81
app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
-optimizationpasses 5
|
||||||
|
-dontusemixedcaseclassnames
|
||||||
|
-dontskipnonpubliclibraryclasses
|
||||||
|
-dontskipnonpubliclibraryclassmembers
|
||||||
|
-dontpreverify
|
||||||
|
-dontshrink
|
||||||
|
-verbose
|
||||||
|
|
||||||
|
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||||
|
|
||||||
|
-keepattributes *Annotation*
|
||||||
|
-keepattributes Signature
|
||||||
|
|
||||||
|
-keepclasseswithmembernames class * {
|
||||||
|
native <methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclasseswithmembers class * {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep public class * extends android.app.Activity
|
||||||
|
-keep public class * extends android.app.Application
|
||||||
|
-keep public class * extends android.app.Service
|
||||||
|
-keep public class * extends android.content.BroadcastReceiver
|
||||||
|
-keep public class * extends android.content.ContentProvider
|
||||||
|
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||||
|
-keep public class * extends android.preference.Preference
|
||||||
|
-keep public class com.android.vending.licensing.ILicensingService
|
||||||
|
|
||||||
|
# The AndroidX library contains references to newer platform versions.
|
||||||
|
# Don't warn about those in case this app is linking against an older platform version.
|
||||||
|
-dontwarn androidx.**
|
||||||
|
|
||||||
|
-keep class com.google.android.gms.**
|
||||||
|
-dontwarn com.google.android.gms.**
|
||||||
|
|
||||||
|
# Java
|
||||||
|
-keep class java.** { *; }
|
||||||
|
-dontnote java.**
|
||||||
|
-dontwarn java.**
|
||||||
|
|
||||||
|
-keep class javax.** { *; }
|
||||||
|
-dontnote javax.**
|
||||||
|
-dontwarn javax.**
|
||||||
|
|
||||||
|
-keep class sun.misc.Unsafe { *; }
|
||||||
|
-dontnote sun.misc.Unsafe
|
||||||
|
|
||||||
|
-keep class javax.xml.stream.XMLOutputFactory { *; }
|
||||||
|
|
||||||
|
# (the rt.jar has them)
|
||||||
|
-dontwarn com.bea.xml.stream.XMLWriterBase
|
||||||
|
-dontwarn javax.xml.stream.events.**
|
||||||
|
-dontwarn javax.xml.stream.**
|
||||||
|
|
||||||
|
# Simple XML
|
||||||
|
-keep public class org.simpleframework.** { *; }
|
||||||
|
-keep class org.simpleframework.xml.** { *; }
|
||||||
|
-keep class org.simpleframework.xml.core.** { *; }
|
||||||
|
-keep class org.simpleframework.xml.util.** { *; }
|
||||||
|
|
||||||
|
-keepattributes ElementList, Root, InnerClasses, LineNumberTable
|
||||||
|
|
||||||
|
-keepclasseswithmembers class * {
|
||||||
|
@org.simpleframework.xml.* <fields>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Chart Engine
|
||||||
|
-keep class org.achartengine.** { *; }
|
||||||
|
-dontnote org.achartengine.**
|
||||||
|
|
||||||
|
# HTTP (might require legacyLibraries) ?
|
||||||
|
-dontnote org.apache.http.params.**
|
||||||
|
-dontnote org.apache.http.conn.scheme.**
|
||||||
|
-dontnote org.apache.http.conn.**
|
||||||
|
-dontnote android.net.http.**
|
||||||
|
|
||||||
|
# DFU Library
|
||||||
|
-keep class no.nordicsemi.android.dfu.** { *; }
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package no.Reader.android.iisc;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.test.ApplicationTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||||
|
*/
|
||||||
|
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||||
|
public ApplicationTest() {
|
||||||
|
super(Application.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
149
app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
package="no.Reader.android.iisc"
|
||||||
|
android:installLocation="auto">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
<uses-permission android:name="android.permission.NFC" />
|
||||||
|
<uses-permission android:name="no.nordicsemi.android.LOG" />
|
||||||
|
|
||||||
|
<uses-feature
|
||||||
|
android:name="android.hardware.bluetooth_le"
|
||||||
|
android:required="true" />
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:name="no.Reader.android.iisc.NotificationData"
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:fullBackupContent="true"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:requestLegacyExternalStorage="true"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
|
android:theme="@style/AppTheme"
|
||||||
|
tools:ignore="GoogleAppIndexingWarning">
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.ViewGraph"
|
||||||
|
android:screenOrientation="landscape"></activity>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.ViewSamples"
|
||||||
|
android:screenOrientation="landscape"/>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.Datashow" />
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
android:authorities="${applicationId}.fileprovider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/file_path" />
|
||||||
|
</provider>
|
||||||
|
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.Try1" />
|
||||||
|
<activity
|
||||||
|
android:name="no.Reader.android.iisc.Reader.check1"
|
||||||
|
android:screenOrientation="portrait" />
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.android.gms.version"
|
||||||
|
android:value="@integer/google_play_services_version" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="no.Reader.android.iisc.SplashscreenActivity"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
|
android:theme="@style/AppTheme.SplashScreen">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="android.app.shortcuts"
|
||||||
|
android:resource="@xml/shortcuts" />
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
|
||||||
|
<data android:mimeType="application/vnd.no.nordicsemi.type.app" />
|
||||||
|
<data android:mimeType="application/vnd.no.nordicsemi.type.address" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name="no.Reader.android.iisc.FeaturesActivity"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:theme="@style/AppTheme.TranslucentStatusBar" />
|
||||||
|
<!--
|
||||||
|
<provider
|
||||||
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
android:authorities="${applicationId}.fileprovider"
|
||||||
|
android:grantUriPermissions="true"
|
||||||
|
android:exported="false">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/provider_paths"/>
|
||||||
|
</provider>
|
||||||
|
-->
|
||||||
|
<!-- Template plugin activities -->
|
||||||
|
<!-- Remember to add your plug-in Activities to the Android Manifest file. -->
|
||||||
|
<activity
|
||||||
|
android:name="no.Reader.android.iisc.Reader.TemplateActivity"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
|
android:icon="@drawable/ic_template_feature"
|
||||||
|
android:label="@string/template_feature_title" />
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.TestDetails" android:screenOrientation="portrait"/>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.About" android:screenOrientation="portrait"/>
|
||||||
|
<activity
|
||||||
|
android:name="no.Reader.android.iisc.Reader.settings.SettingsActivity"
|
||||||
|
android:label="@string/template_settings_title" />
|
||||||
|
|
||||||
|
<service
|
||||||
|
|
||||||
|
android:name="no.Reader.android.iisc.Reader.SPCAService"
|
||||||
|
android:label="@string/template_feature_title" /> <!-- Plug-in activities -->
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.TemplateActivity1"
|
||||||
|
android:screenOrientation="portrait"/>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.TemplateActivity2"
|
||||||
|
android:screenOrientation="portrait"/>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.PositiveResult"
|
||||||
|
android:screenOrientation="portrait"/>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.NegativeResults"
|
||||||
|
android:screenOrientation="portrait"/>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.TemplateActivity3"
|
||||||
|
android:screenOrientation="portrait"/>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.Register"
|
||||||
|
android:screenOrientation="portrait"/>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.CreatePassword"
|
||||||
|
android:screenOrientation="portrait"/>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.ForgetPasswordReset"
|
||||||
|
android:screenOrientation="portrait"/>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.LoginScreen"
|
||||||
|
android:screenOrientation="portrait"/>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.VerifyOTP.VerifyOtpForgetPassword"
|
||||||
|
android:screenOrientation="portrait"/>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.VerifyOTP.VerifyOtp"
|
||||||
|
android:screenOrientation="portrait"/>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.ForgetPassword"
|
||||||
|
android:screenOrientation="portrait"/>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.MainActivity"
|
||||||
|
android:screenOrientation="portrait"/>
|
||||||
|
<activity android:name="no.Reader.android.iisc.Reader.NavigationTop"
|
||||||
|
android:screenOrientation="portrait"/>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
BIN
app/src/main/assets/fa-solid-900.ttf
Normal file
BIN
app/src/main/ic_launcher-playstore.png
Normal file
|
After Width: | Height: | Size: 63 KiB |
50
app/src/main/java/no/Reader/android/iisc/DebugLogger.java
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package no.Reader.android.iisc;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
|
||||||
|
public class DebugLogger {
|
||||||
|
public static void v(final String tag, final String text) {
|
||||||
|
if (BuildConfig.DEBUG)
|
||||||
|
Log.v(tag, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void d(final String tag, final String text) {
|
||||||
|
if (BuildConfig.DEBUG) {
|
||||||
|
Log.d(tag, text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void i(final String tag, final String text) {
|
||||||
|
if (BuildConfig.DEBUG)
|
||||||
|
Log.i(tag, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void w(final String tag, final String text) {
|
||||||
|
if (BuildConfig.DEBUG) {
|
||||||
|
Log.w(tag, text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void e(final String tag, final String text) {
|
||||||
|
if (BuildConfig.DEBUG)
|
||||||
|
Log.e(tag, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void e(final String tag, final String text, final Throwable e) {
|
||||||
|
if (BuildConfig.DEBUG)
|
||||||
|
Log.e(tag, text, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void wtf(final String tag, final String text) {
|
||||||
|
if (BuildConfig.DEBUG) {
|
||||||
|
Log.wtf(tag, text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void wtf(final String tag, final String text, final Throwable e) {
|
||||||
|
if (BuildConfig.DEBUG) {
|
||||||
|
Log.wtf(tag, text, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
169
app/src/main/java/no/Reader/android/iisc/FeaturesActivity.java
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
package no.Reader.android.iisc;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.core.view.GravityCompat;
|
||||||
|
import androidx.drawerlayout.widget.DrawerLayout;
|
||||||
|
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.GridView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.adapter.AppAdapter;
|
||||||
|
|
||||||
|
public class FeaturesActivity extends AppCompatActivity {
|
||||||
|
private static final String NRF_CONNECT_CATEGORY = "no.Reader.android.iisc.LAUNCHER";
|
||||||
|
private static final String UTILS_CATEGORY = "no.Reader.android.iisc.UTILS";
|
||||||
|
private static final String NRF_CONNECT_PACKAGE = "no.nordicsemi.android.mcp";
|
||||||
|
private static final String NRF_CONNECT_CLASS = NRF_CONNECT_PACKAGE + ".DeviceListActivity";
|
||||||
|
private static final String NRF_CONNECT_MARKET_URI = "market://details?id=no.nordicsemi.android.mcp";
|
||||||
|
|
||||||
|
// Extras that can be passed from NFC (see SplashscreenActivity)
|
||||||
|
public static final String EXTRA_APP = "application/vnd.no.nordicsemi.type.app";
|
||||||
|
public static final String EXTRA_ADDRESS = "application/vnd.no.nordicsemi.type.address";
|
||||||
|
|
||||||
|
private DrawerLayout mDrawerLayout;
|
||||||
|
private ActionBarDrawerToggle mDrawerToggle;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_features);
|
||||||
|
|
||||||
|
final Toolbar toolbar = findViewById(R.id.toolbar_actionbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
// ensure that Bluetooth exists
|
||||||
|
if (!ensureBLEExists())
|
||||||
|
finish();
|
||||||
|
|
||||||
|
final DrawerLayout drawer = mDrawerLayout = findViewById(R.id.drawer_layout);
|
||||||
|
drawer.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
|
||||||
|
|
||||||
|
// Set the drawer toggle as the DrawerListener
|
||||||
|
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.drawer_open, R.string.drawer_close) {
|
||||||
|
@Override
|
||||||
|
public void onDrawerSlide(final View drawerView, final float slideOffset) {
|
||||||
|
// Disable the Hamburger icon animation
|
||||||
|
super.onDrawerSlide(drawerView, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
drawer.addDrawerListener(mDrawerToggle);
|
||||||
|
|
||||||
|
// setup plug-ins in the drawer
|
||||||
|
//setupPluginsInDrawer(drawer.findViewById(R.id.plugin_container));
|
||||||
|
|
||||||
|
// configure the app grid
|
||||||
|
final GridView grid = findViewById(R.id.grid);
|
||||||
|
grid.setAdapter(new AppAdapter(this));
|
||||||
|
grid.setEmptyView(findViewById(android.R.id.empty));
|
||||||
|
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
|
||||||
|
final Intent intent = getIntent();
|
||||||
|
if (intent.hasExtra(EXTRA_APP) && intent.hasExtra(EXTRA_ADDRESS)) {
|
||||||
|
final String app = intent.getStringExtra(EXTRA_APP);
|
||||||
|
switch (app) {
|
||||||
|
/*case "HRM":
|
||||||
|
final Intent newIntent = new Intent(this, HRSActivity.class);
|
||||||
|
newIntent.putExtra(EXTRA_ADDRESS, intent.getByteArrayExtra(EXTRA_ADDRESS));
|
||||||
|
newIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||||
|
startActivity(newIntent);
|
||||||
|
break;*/
|
||||||
|
default:
|
||||||
|
// other are not supported yet
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onPostCreate(savedInstanceState);
|
||||||
|
// Sync the toggle state after onRestoreInstanceState has occurred.
|
||||||
|
mDrawerToggle.syncState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConfigurationChanged(@NonNull final Configuration newConfig) {
|
||||||
|
super.onConfigurationChanged(newConfig);
|
||||||
|
mDrawerToggle.onConfigurationChanged(newConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
private void setupPluginsInDrawer(final ViewGroup container) {
|
||||||
|
final LayoutInflater inflater = LayoutInflater.from(this);
|
||||||
|
final PackageManager pm = getPackageManager();
|
||||||
|
|
||||||
|
// look for nRF Connect
|
||||||
|
final Intent nrfConnectIntent = new Intent(Intent.ACTION_MAIN);
|
||||||
|
nrfConnectIntent.addCategory(NRF_CONNECT_CATEGORY);
|
||||||
|
nrfConnectIntent.setClassName(NRF_CONNECT_PACKAGE, NRF_CONNECT_CLASS);
|
||||||
|
final ResolveInfo nrfConnectInfo = pm.resolveActivity(nrfConnectIntent, 0);
|
||||||
|
|
||||||
|
// configure link to nRF Connect
|
||||||
|
final TextView nrfConnectItem = container.findViewById(R.id.link_mcp);
|
||||||
|
if (nrfConnectInfo == null) {
|
||||||
|
nrfConnectItem.setTextColor(Color.GRAY);
|
||||||
|
final ColorMatrix grayscale = new ColorMatrix();
|
||||||
|
grayscale.setSaturation(0.0f);
|
||||||
|
nrfConnectItem.getCompoundDrawables()[0].mutate().setColorFilter(new ColorMatrixColorFilter(grayscale));
|
||||||
|
}
|
||||||
|
nrfConnectItem.setOnClickListener(v -> {
|
||||||
|
Intent action = nrfConnectIntent;
|
||||||
|
if (nrfConnectInfo == null)
|
||||||
|
action = new Intent(Intent.ACTION_VIEW, Uri.parse(NRF_CONNECT_MARKET_URI));
|
||||||
|
action.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||||
|
action.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
try {
|
||||||
|
startActivity(action);
|
||||||
|
} catch (final ActivityNotFoundException e) {
|
||||||
|
Toast.makeText(FeaturesActivity.this, R.string.no_application_play, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
mDrawerLayout.closeDrawers();
|
||||||
|
});
|
||||||
|
|
||||||
|
// look for other plug-ins
|
||||||
|
final Intent utilsIntent = new Intent(Intent.ACTION_MAIN);
|
||||||
|
utilsIntent.addCategory(UTILS_CATEGORY);
|
||||||
|
|
||||||
|
final List<ResolveInfo> appList = pm.queryIntentActivities(utilsIntent, 0);
|
||||||
|
for (final ResolveInfo info : appList) {
|
||||||
|
final View item = inflater.inflate(R.layout.drawer_plugin, container, false);
|
||||||
|
final ImageView icon = item.findViewById(android.R.id.icon);
|
||||||
|
final TextView label = item.findViewById(android.R.id.text1);
|
||||||
|
|
||||||
|
label.setText(info.loadLabel(pm));
|
||||||
|
icon.setImageDrawable(info.loadIcon(pm));
|
||||||
|
item.setOnClickListener(v -> {
|
||||||
|
final Intent intent = new Intent();
|
||||||
|
intent.setComponent(new ComponentName(info.activityInfo.packageName, info.activityInfo.name));
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
startActivity(intent);
|
||||||
|
mDrawerLayout.closeDrawers();
|
||||||
|
});
|
||||||
|
container.addView(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
private boolean ensureBLEExists() {
|
||||||
|
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
|
||||||
|
Toast.makeText(this, R.string.no_ble, Toast.LENGTH_LONG).show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
35
app/src/main/java/no/Reader/android/iisc/FontAwesome.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package no.Reader.android.iisc;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
|
import androidx.appcompat.widget.AppCompatTextView;
|
||||||
|
|
||||||
|
public class FontAwesome extends AppCompatTextView {
|
||||||
|
|
||||||
|
|
||||||
|
public FontAwesome(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FontAwesome(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FontAwesome(Context context) {
|
||||||
|
super(context);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
|
||||||
|
Typeface tf = Typeface.createFromAsset(getContext().getAssets(),
|
||||||
|
"fa-solid-900.ttf");
|
||||||
|
setTypeface(tf);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Nordic Semiconductor
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package no.Reader.android.iisc;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.dfu.DfuServiceInitiator;
|
||||||
|
|
||||||
|
public class NotificationData extends Application {
|
||||||
|
public static final String CONNECTED_DEVICE_CHANNEL = "connected_device_channel";
|
||||||
|
public static final String FILE_SAVED_CHANNEL = "file_saved_channel";
|
||||||
|
public static final String PROXIMITY_WARNINGS_CHANNEL = "proximity_warnings_channel";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
|
||||||
|
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
DfuServiceInitiator.createDfuNotificationChannel(this);
|
||||||
|
|
||||||
|
final NotificationChannel channel = new NotificationChannel(CONNECTED_DEVICE_CHANNEL, getString(R.string.channel_connected_devices_title), NotificationManager.IMPORTANCE_LOW);
|
||||||
|
channel.setDescription(getString(R.string.channel_connected_devices_description));
|
||||||
|
channel.setShowBadge(false);
|
||||||
|
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
|
||||||
|
|
||||||
|
final NotificationChannel fileChannel = new NotificationChannel(FILE_SAVED_CHANNEL, getString(R.string.channel_files_title), NotificationManager.IMPORTANCE_LOW);
|
||||||
|
fileChannel.setDescription(getString(R.string.channel_files_description));
|
||||||
|
fileChannel.setShowBadge(false);
|
||||||
|
fileChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
|
||||||
|
|
||||||
|
final NotificationChannel proximityChannel = new NotificationChannel(PROXIMITY_WARNINGS_CHANNEL, getString(R.string.channel_proximity_warnings_title), NotificationManager.IMPORTANCE_LOW);
|
||||||
|
proximityChannel.setDescription(getString(R.string.channel_proximity_warnings_description));
|
||||||
|
proximityChannel.setShowBadge(false);
|
||||||
|
proximityChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
|
||||||
|
|
||||||
|
final NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
notificationManager.createNotificationChannel(channel);
|
||||||
|
notificationManager.createNotificationChannel(fileChannel);
|
||||||
|
notificationManager.createNotificationChannel(proximityChannel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package no.Reader.android.iisc;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
|
|
||||||
|
public class PermissionRationaleFragment extends DialogFragment {
|
||||||
|
private static final String ARG_PERMISSION = "ARG_PERMISSION";
|
||||||
|
private static final String ARG_TEXT = "ARG_TEXT";
|
||||||
|
|
||||||
|
private PermissionDialogListener mListener;
|
||||||
|
|
||||||
|
public interface PermissionDialogListener {
|
||||||
|
void onRequestPermission(final String permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(final Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
|
||||||
|
if (context instanceof PermissionDialogListener) {
|
||||||
|
mListener = (PermissionDialogListener) context;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("The parent activity must impelemnt PermissionDialogListener");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetach() {
|
||||||
|
super.onDetach();
|
||||||
|
mListener = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PermissionRationaleFragment getInstance(final int aboutResId, final String permission) {
|
||||||
|
final PermissionRationaleFragment fragment = new PermissionRationaleFragment();
|
||||||
|
|
||||||
|
final Bundle args = new Bundle();
|
||||||
|
args.putInt(ARG_TEXT, aboutResId);
|
||||||
|
args.putString(ARG_PERMISSION, permission);
|
||||||
|
fragment.setArguments(args);
|
||||||
|
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NonNull
|
||||||
|
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||||
|
final Bundle args = getArguments();
|
||||||
|
final StringBuilder text = new StringBuilder(getString(args.getInt(ARG_TEXT)));
|
||||||
|
return new AlertDialog.Builder(getActivity()).setTitle(R.string.permission_title).setMessage(text)
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.setPositiveButton(R.string.ok, (dialog, which) -> mListener.onRequestPermission(args.getString(ARG_PERMISSION))).create();
|
||||||
|
}
|
||||||
|
}
|
||||||
24
app/src/main/java/no/Reader/android/iisc/Reader/About.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
|
||||||
|
public class About extends NavigationTop {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
LayoutInflater inflater = (LayoutInflater) this
|
||||||
|
.getSystemService(LAYOUT_INFLATER_SERVICE);
|
||||||
|
View contentView = inflater.inflate(R.layout.activity_about, null, false);
|
||||||
|
draw.addView(contentView, 0);
|
||||||
|
/* LayoutInflater inflater = (LayoutInflater) this
|
||||||
|
.getSystemService(LAYOUT_INFLATER_SERVICE);
|
||||||
|
View contentView = inflater.inflate(R.layout.activity_about, null, false);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.google.firebase.database.DatabaseReference;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.Reader.Model.RegisterHelper;
|
||||||
|
|
||||||
|
|
||||||
|
public class CreatePassword extends AppCompatActivity {
|
||||||
|
private Button next;
|
||||||
|
|
||||||
|
String name,phonenumber,num1,num2;
|
||||||
|
private EditText passworddata;
|
||||||
|
private EditText ConfirmPassword;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_create__password);
|
||||||
|
passworddata=findViewById(R.id.password);
|
||||||
|
ConfirmPassword=findViewById(R.id.confirmpassword);
|
||||||
|
next=findViewById(R.id.next);
|
||||||
|
|
||||||
|
next.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
num1 = ConfirmPassword.getText().toString();
|
||||||
|
num2 = passworddata.getText().toString();
|
||||||
|
if (!isOnline()) {
|
||||||
|
//Create an alertdialog
|
||||||
|
AlertDialog.Builder Checkbuilder = new AlertDialog.Builder(CreatePassword.this);
|
||||||
|
Checkbuilder.setTitle("No Internet Connection !");
|
||||||
|
Checkbuilder.setMessage("Check Your Internet Connection.");
|
||||||
|
//Builder Retry Button
|
||||||
|
|
||||||
|
Checkbuilder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Checkbuilder.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AlertDialog alert = Checkbuilder.create();
|
||||||
|
alert.show();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
|
||||||
|
if (num1.equals(num2)) {
|
||||||
|
Intent intent = new Intent(CreatePassword.this, LoginScreen.class);
|
||||||
|
name = getIntent().getStringExtra("username");
|
||||||
|
|
||||||
|
String phonenumberk = getIntent().getStringExtra("mobile");
|
||||||
|
phonenumber = phonenumberk;
|
||||||
|
|
||||||
|
FirebaseDatabase rootNode = FirebaseDatabase.getInstance();
|
||||||
|
DatabaseReference reference = rootNode.getReference("USERS");
|
||||||
|
RegisterHelper addNewUser = new RegisterHelper(name, phonenumber, num1);
|
||||||
|
|
||||||
|
reference.child(phonenumber).setValue(addNewUser);
|
||||||
|
intent.putExtra("mobile", phonenumber);
|
||||||
|
intent.putExtra("username", name);
|
||||||
|
|
||||||
|
Toast.makeText(CreatePassword.this, "You are Registered Successfully ", Toast.LENGTH_SHORT).show();
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ConfirmPassword.setError("Password does not match");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public boolean isOnline() {
|
||||||
|
ConnectivityManager connMgr = (ConnectivityManager)
|
||||||
|
getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
|
||||||
|
return (networkInfo != null && networkInfo.isConnected());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
103
app/src/main/java/no/Reader/android/iisc/Reader/Datashow.java
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.google.firebase.database.DataSnapshot;
|
||||||
|
import com.google.firebase.database.DatabaseError;
|
||||||
|
import com.google.firebase.database.DatabaseReference;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
import com.google.firebase.database.ValueEventListener;
|
||||||
|
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.Reader.Model.Tests;
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
|
||||||
|
public class Datashow extends NavigationTop {
|
||||||
|
private ImageView Imageview1;
|
||||||
|
TextView patient_id,patient_dob,patientnikshayid,agepatient,patientgender,patientsample,validatyd,spintubeid,nirtlab,dated,timed,resultd;
|
||||||
|
|
||||||
|
String date,time,number;
|
||||||
|
|
||||||
|
private String TestID = "";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
LayoutInflater inflater = (LayoutInflater) this
|
||||||
|
.getSystemService(LAYOUT_INFLATER_SERVICE);
|
||||||
|
View contentView = inflater.inflate(R.layout.activity_datashow, null, false);
|
||||||
|
draw.addView(contentView, 0);
|
||||||
|
|
||||||
|
patient_id=findViewById(R.id.patient_idr);
|
||||||
|
patient_dob=findViewById(R.id.patien_dobr);
|
||||||
|
patientnikshayid=findViewById(R.id.patient_nikshayidr);
|
||||||
|
SharedPreferences preferences6 = getSharedPreferences("PhoneBook_number", MODE_PRIVATE);
|
||||||
|
|
||||||
|
number = preferences6.getString("Phone", null);
|
||||||
|
|
||||||
|
agepatient=findViewById(R.id.patient_ager);
|
||||||
|
date = String.valueOf(android.text.format.DateFormat.format("dd-MM-yyyy", new java.util.Date()));
|
||||||
|
DateFormat df = new SimpleDateFormat("h:mm a");
|
||||||
|
time = df.format(Calendar.getInstance().getTime());
|
||||||
|
|
||||||
|
patientgender=findViewById(R.id.patient_genderr);
|
||||||
|
patientsample=findViewById(R.id.patient_typesampler);
|
||||||
|
validatyd=findViewById(R.id.patient_tubevisibler);
|
||||||
|
spintubeid=findViewById(R.id.patient_spintuber);
|
||||||
|
nirtlab=findViewById(R.id.patient_nirtr);
|
||||||
|
timed=findViewById(R.id.timer);
|
||||||
|
resultd=findViewById(R.id.patient_resultr);
|
||||||
|
dated=findViewById(R.id.dater);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TestID = getIntent().getStringExtra("pid");
|
||||||
|
|
||||||
|
Log.e("main", "error id "+TestID);
|
||||||
|
|
||||||
|
|
||||||
|
getTestDetails(TestID);
|
||||||
|
}
|
||||||
|
private void getTestDetails(String TestID)
|
||||||
|
{
|
||||||
|
DatabaseReference productsRef = FirebaseDatabase.getInstance().getReference().child("Test_Data").child(number);
|
||||||
|
|
||||||
|
productsRef.child(TestID).addValueEventListener(new ValueEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onDataChange(DataSnapshot dataSnapshot)
|
||||||
|
{
|
||||||
|
if (dataSnapshot.exists())
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Tests products = dataSnapshot.getValue(Tests.class);
|
||||||
|
patient_id.setText(products.getTest_Id());
|
||||||
|
patient_dob.setText(products.getSample_Date());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelled(DatabaseError databaseError) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
|
import androidx.appcompat.widget.AppCompatTextView;
|
||||||
|
|
||||||
|
public class FontAwesome extends AppCompatTextView {
|
||||||
|
|
||||||
|
|
||||||
|
public FontAwesome(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FontAwesome(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FontAwesome(Context context) {
|
||||||
|
super(context);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
|
||||||
|
Typeface tf = Typeface.createFromAsset(getContext().getAssets(),
|
||||||
|
"fa-solid-900.ttf");
|
||||||
|
setTypeface(tf);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,260 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.chaos.view.PinView;
|
||||||
|
import com.google.android.gms.tasks.OnCompleteListener;
|
||||||
|
import com.google.android.gms.tasks.Task;
|
||||||
|
import com.google.android.gms.tasks.TaskExecutors;
|
||||||
|
import com.google.firebase.FirebaseException;
|
||||||
|
import com.google.firebase.auth.AuthResult;
|
||||||
|
import com.google.firebase.auth.FirebaseAuth;
|
||||||
|
import com.google.firebase.auth.PhoneAuthCredential;
|
||||||
|
import com.google.firebase.auth.PhoneAuthProvider;
|
||||||
|
import com.google.firebase.database.DataSnapshot;
|
||||||
|
import com.google.firebase.database.DatabaseError;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
import com.google.firebase.database.Query;
|
||||||
|
import com.google.firebase.database.ValueEventListener;
|
||||||
|
import com.hbb20.CountryCodePicker;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.Reader.VerifyOTP.VerifyOtpForgetPassword;
|
||||||
|
|
||||||
|
|
||||||
|
public class ForgetPassword extends AppCompatActivity {
|
||||||
|
|
||||||
|
private String verificationid;
|
||||||
|
private FirebaseAuth mAuth;
|
||||||
|
private int code = 91;
|
||||||
|
private Button nextactivity;
|
||||||
|
private ProgressBar progressBar;
|
||||||
|
CountryCodePicker ccp;
|
||||||
|
PinView pinFromUser;
|
||||||
|
String mobile;
|
||||||
|
|
||||||
|
private EditText editTextnumber;
|
||||||
|
String codeBySystem;
|
||||||
|
boolean exists;
|
||||||
|
String address,name, state , city ,pincode,phonenumber,password2,num1,phonenum;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_forget__password);
|
||||||
|
editTextnumber=findViewById(R.id.editTextMobile);
|
||||||
|
ccp=findViewById(R.id.ccp);
|
||||||
|
ccp.registerCarrierNumberEditText(editTextnumber);
|
||||||
|
// nextactivity = findViewById(R.id.buttonSignIn);
|
||||||
|
|
||||||
|
mAuth = FirebaseAuth.getInstance();
|
||||||
|
|
||||||
|
|
||||||
|
findViewById(R.id.buttonSignIn).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (!isOnline()) {
|
||||||
|
//Create an alertdialog
|
||||||
|
AlertDialog.Builder Checkbuilder = new AlertDialog.Builder(ForgetPassword.this);
|
||||||
|
Checkbuilder.setTitle("No Internet Connection !");
|
||||||
|
Checkbuilder.setMessage("Check Your Internet Connection.");
|
||||||
|
//Builder Retry Button
|
||||||
|
|
||||||
|
Checkbuilder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
/* //Restart The Activity
|
||||||
|
Intent intent = getIntent();
|
||||||
|
finish();
|
||||||
|
startActivity(intent);*/
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Checkbuilder.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AlertDialog alert = Checkbuilder.create();
|
||||||
|
alert.show();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
mobile = editTextnumber.getText().toString().trim();
|
||||||
|
mobile = mobile.replaceAll("[^0-9]", "");
|
||||||
|
|
||||||
|
|
||||||
|
phonenum = ccp.getFullNumberWithPlus();
|
||||||
|
if(mobile.equals(""))
|
||||||
|
{
|
||||||
|
editTextnumber.setError("Enter the contact number");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Query chekuser = FirebaseDatabase.getInstance().getReference("USERS").orderByChild("number").equalTo(mobile);
|
||||||
|
chekuser.addListenerForSingleValueEvent(new ValueEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
|
||||||
|
if (dataSnapshot.exists()) {
|
||||||
|
Intent intent = new Intent(ForgetPassword.this, VerifyOtpForgetPassword.class);
|
||||||
|
Toast.makeText(ForgetPassword.this, "We Have Sent the OTP to your mentioned Number", Toast.LENGTH_SHORT).show();
|
||||||
|
intent.putExtra("mobilecode", phonenum);
|
||||||
|
intent.putExtra("mobile", mobile);
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Toast.makeText(ForgetPassword.this,phonenum,Toast.LENGTH_SHORT).show();
|
||||||
|
editTextnumber.setError("No Such User Exists");
|
||||||
|
|
||||||
|
// Toast.makeText(ForgetPassword.this,"NO such user exists",Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelled(@NonNull DatabaseError databaseError) {
|
||||||
|
Log.e("Raman", "Received an exception check chexk " + databaseError.getMessage());
|
||||||
|
|
||||||
|
// Toast.makeText(ForgetPassword.this,databaseError.getMessage(),Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
private void verifyCode(String code){
|
||||||
|
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationid, code);
|
||||||
|
signInWithCredential(credential);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void signInWithCredential(PhoneAuthCredential credential) {
|
||||||
|
mAuth.signInWithCredential(credential)
|
||||||
|
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(@NonNull Task<AuthResult> task) {
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
|
||||||
|
Intent intent = new Intent(ForgetPassword.this, ForgetPasswordReset.class);
|
||||||
|
intent.putExtra("mobile", mobile);
|
||||||
|
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Toast.makeText(ForgetPassword.this, task.getException().getMessage(), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendVerificationCode(String number){
|
||||||
|
|
||||||
|
PhoneAuthProvider.getInstance().verifyPhoneNumber(
|
||||||
|
number,
|
||||||
|
60,
|
||||||
|
TimeUnit.SECONDS,
|
||||||
|
(Activity) TaskExecutors.MAIN_THREAD,
|
||||||
|
mCallBack
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PhoneAuthProvider.OnVerificationStateChangedCallbacks
|
||||||
|
mCallBack = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCodeSent(String s, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
|
||||||
|
super.onCodeSent(s, forceResendingToken);
|
||||||
|
verificationid = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
|
||||||
|
String code = phoneAuthCredential.getSmsCode();
|
||||||
|
if (code != null){
|
||||||
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
|
pinFromUser.setText(code);
|
||||||
|
verifyCode(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVerificationFailed(FirebaseException e) {
|
||||||
|
Toast.makeText(ForgetPassword.this, e.getMessage(), Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void checkuserexist(String number)
|
||||||
|
{
|
||||||
|
Query chekuser= FirebaseDatabase.getInstance().getReference("USERS").orderByChild("number").equalTo(number);
|
||||||
|
chekuser.addListenerForSingleValueEvent(new ValueEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
|
||||||
|
if(dataSnapshot.exists())
|
||||||
|
{
|
||||||
|
exists= true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
exists=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelled(@NonNull DatabaseError databaseError) {
|
||||||
|
Toast.makeText(ForgetPassword.this,databaseError.getMessage(), Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public boolean isOnline() {
|
||||||
|
ConnectivityManager connMgr = (ConnectivityManager)
|
||||||
|
getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
|
||||||
|
return (networkInfo != null && networkInfo.isConnected());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.google.firebase.database.DatabaseReference;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
public class ForgetPasswordReset extends AppCompatActivity {
|
||||||
|
private Button next;
|
||||||
|
|
||||||
|
String phonenumber,num1,num2;
|
||||||
|
private EditText passworddata;
|
||||||
|
private EditText ConfirmPassword;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_create__password);
|
||||||
|
passworddata=findViewById(R.id.password);
|
||||||
|
ConfirmPassword=findViewById(R.id.confirmpassword);
|
||||||
|
next=findViewById(R.id.next);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
next.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
num1 = ConfirmPassword.getText().toString();
|
||||||
|
num2=passworddata.getText().toString();
|
||||||
|
if(num1.equals(num2)) {
|
||||||
|
|
||||||
|
Intent intent = new Intent(ForgetPasswordReset.this, LoginScreen.class);
|
||||||
|
|
||||||
|
String phonenumberk = getIntent().getStringExtra("mobile");
|
||||||
|
phonenumber = phonenumberk;
|
||||||
|
|
||||||
|
FirebaseDatabase rootNode = FirebaseDatabase.getInstance();
|
||||||
|
DatabaseReference reference = rootNode.getReference("USERS");
|
||||||
|
|
||||||
|
|
||||||
|
reference.child(phonenumber).child("password").setValue(num1);
|
||||||
|
Toast.makeText(ForgetPasswordReset.this, "Password Reset Successfully ", Toast.LENGTH_SHORT).show();
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConfirmPassword.setError("Password does not match");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package no.Reader.android.iisc.Reader.Interface;
|
||||||
|
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
public interface ItemClickListner
|
||||||
|
{
|
||||||
|
void onClick(View view, int position, boolean isLongClick);
|
||||||
|
}
|
||||||
250
app/src/main/java/no/Reader/android/iisc/Reader/LoginScreen.java
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.method.HideReturnsTransformationMethod;
|
||||||
|
import android.text.method.PasswordTransformationMethod;
|
||||||
|
import android.util.Patterns;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.animation.Animation;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.AppCompatCheckBox;
|
||||||
|
|
||||||
|
import com.google.firebase.database.DataSnapshot;
|
||||||
|
import com.google.firebase.database.DatabaseError;
|
||||||
|
import com.google.firebase.database.DatabaseReference;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
import com.google.firebase.database.Query;
|
||||||
|
import com.google.firebase.database.ValueEventListener;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
|
||||||
|
public class LoginScreen extends AppCompatActivity {
|
||||||
|
|
||||||
|
private TextView createaccount, forgetpassword;
|
||||||
|
private Button login;
|
||||||
|
private DatabaseReference databaseReference;
|
||||||
|
private EditText phonenumber, password;
|
||||||
|
String passworddata, phonenum, phonenumbers, name;
|
||||||
|
private ProgressDialog loadingBar;
|
||||||
|
public static final String Name = "nameKey";
|
||||||
|
public static final String Phone = "phoneKey";
|
||||||
|
private ImageButton close;
|
||||||
|
Animation btnAnim ;
|
||||||
|
|
||||||
|
private AppCompatCheckBox checkbox;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_login__screen);
|
||||||
|
createaccount = findViewById(R.id.createaccount);
|
||||||
|
phonenumber = findViewById(R.id.contactnumber);
|
||||||
|
checkbox = (AppCompatCheckBox) findViewById(R.id.showpassword);
|
||||||
|
|
||||||
|
password = findViewById(R.id.password);
|
||||||
|
checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
|
||||||
|
if (isChecked) {
|
||||||
|
// show password
|
||||||
|
password.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
|
||||||
|
} else {
|
||||||
|
// hide password
|
||||||
|
password.setTransformationMethod(PasswordTransformationMethod.getInstance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Paper.init(this);
|
||||||
|
loadingBar = new ProgressDialog(this);
|
||||||
|
// Paper.init(this);
|
||||||
|
|
||||||
|
login = findViewById(R.id.login);
|
||||||
|
forgetpassword = findViewById(R.id.forgetpassword);
|
||||||
|
forgetpassword.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent intent = new Intent(LoginScreen.this, ForgetPassword.class);
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
login.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (!isOnline()) {
|
||||||
|
//Create an alertdialog
|
||||||
|
AlertDialog.Builder Checkbuilder = new AlertDialog.Builder(LoginScreen.this);
|
||||||
|
Checkbuilder.setTitle("No Internet Connection !");
|
||||||
|
Checkbuilder.setMessage("Check Your Internet Connection.");
|
||||||
|
//Builder Retry Button
|
||||||
|
|
||||||
|
Checkbuilder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Checkbuilder.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AlertDialog alert = Checkbuilder.create();
|
||||||
|
alert.show();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
String mobile = phonenumber.getText().toString().trim();
|
||||||
|
phonenum = mobile;
|
||||||
|
final String passwordj = password.getText().toString().trim();
|
||||||
|
|
||||||
|
|
||||||
|
if (mobile.equals("") || passwordj.equals("")) {
|
||||||
|
Toast.makeText(LoginScreen.this, "Please enter all the required fields", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
} else if (!Patterns.PHONE.matcher(mobile).matches()) {
|
||||||
|
|
||||||
|
phonenumber.setError("Enter a valid number");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
loadingBar.setTitle("Login Account");
|
||||||
|
loadingBar.setMessage("Please wait, while we are checking the credentials.");
|
||||||
|
loadingBar.setCanceledOnTouchOutside(false);
|
||||||
|
loadingBar.show();
|
||||||
|
|
||||||
|
Query chekuser = FirebaseDatabase.getInstance().getReference("USERS").orderByChild("number").equalTo(phonenum);
|
||||||
|
chekuser.addListenerForSingleValueEvent(new ValueEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
|
||||||
|
if (dataSnapshot.exists()) {
|
||||||
|
String systempassword = dataSnapshot.child(phonenum).child("password").getValue(String.class);
|
||||||
|
|
||||||
|
if (systempassword.equals(passwordj)) {
|
||||||
|
|
||||||
|
Toast.makeText(LoginScreen.this, "logged in Successfully...", Toast.LENGTH_SHORT).show();
|
||||||
|
loadingBar.dismiss();
|
||||||
|
String name = dataSnapshot.child(phonenum).child("name").getValue(String.class);
|
||||||
|
|
||||||
|
|
||||||
|
SharedPreferences preferences = getSharedPreferences("PhoneBook_number", MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
|
|
||||||
|
// editor.putString(Name, phonenum);
|
||||||
|
editor.putString("Phone", phonenum);
|
||||||
|
editor.putString("Name", name);
|
||||||
|
|
||||||
|
|
||||||
|
editor.commit();
|
||||||
|
|
||||||
|
|
||||||
|
Intent intent = new Intent(LoginScreen.this, MainActivity.class);
|
||||||
|
|
||||||
|
|
||||||
|
intent.putExtra("mobile", phonenum);
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
loadingBar.dismiss();
|
||||||
|
|
||||||
|
Toast.makeText(LoginScreen.this, "Wrong Password", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
loadingBar.dismiss();
|
||||||
|
|
||||||
|
Toast.makeText(LoginScreen.this, "No such user exists", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelled(@NonNull DatabaseError databaseError) {
|
||||||
|
Toast.makeText(LoginScreen.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
createaccount.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent intent = new Intent(LoginScreen.this, Register.class);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void finishQuiz() {
|
||||||
|
if (!isOnline()) {
|
||||||
|
|
||||||
|
AlertDialog.Builder Checkbuilder = new AlertDialog.Builder(LoginScreen.this);
|
||||||
|
Checkbuilder.setTitle("Error!");
|
||||||
|
Checkbuilder.setMessage("Enable your internet connection and Retry ");
|
||||||
|
|
||||||
|
Checkbuilder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
|
||||||
|
dialog.cancel();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Checkbuilder.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
AlertDialog alert = Checkbuilder.create();
|
||||||
|
alert.show();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
|
||||||
|
finishAffinity();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOnline() {
|
||||||
|
ConnectivityManager connMgr = (ConnectivityManager)
|
||||||
|
getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
|
||||||
|
return (networkInfo != null && networkInfo.isConnected());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,255 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.SearchView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.firebase.ui.database.FirebaseRecyclerAdapter;
|
||||||
|
import com.firebase.ui.database.FirebaseRecyclerOptions;
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
import com.google.firebase.database.DatabaseReference;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
import com.google.firebase.database.Query;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.Reader.Model.Tests;
|
||||||
|
|
||||||
|
|
||||||
|
public class MainActivity extends NavigationTop {
|
||||||
|
private DatabaseReference TestRef;
|
||||||
|
private RecyclerView recyclerView;
|
||||||
|
|
||||||
|
private TextView info;
|
||||||
|
FloatingActionButton fasbs;
|
||||||
|
|
||||||
|
String number;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
LayoutInflater inflater = (LayoutInflater) this
|
||||||
|
.getSystemService(LAYOUT_INFLATER_SERVICE);
|
||||||
|
View contentView = inflater.inflate(R.layout.activity_main, null, false);
|
||||||
|
draw.addView(contentView, 0);
|
||||||
|
|
||||||
|
SharedPreferences preferences6 = getSharedPreferences("PhoneBook_number", MODE_PRIVATE);
|
||||||
|
|
||||||
|
number = preferences6.getString("Phone", null);
|
||||||
|
fasbs=findViewById(R.id.fab);
|
||||||
|
info=findViewById(R.id.info);
|
||||||
|
info.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
Log.e("main", "error "+number);
|
||||||
|
TestRef = FirebaseDatabase.getInstance().getReference().child("Test_Data").child(number);
|
||||||
|
recyclerView = findViewById(R.id.recycler_view);
|
||||||
|
fasbs.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent intent=new Intent(MainActivity.this, TestDetails.class);
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
LinearLayoutManager layoutManager1=new LinearLayoutManager(this);
|
||||||
|
|
||||||
|
recyclerView.setLayoutManager(new GridLayoutManager(this, 1));
|
||||||
|
|
||||||
|
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||||
|
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
||||||
|
int height = displayMetrics.heightPixels / 8;
|
||||||
|
int spaceInPixel = 4;
|
||||||
|
recyclerView.addItemDecoration(new SpaceDecoration(spaceInPixel));
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void onStart()
|
||||||
|
{
|
||||||
|
super.onStart();
|
||||||
|
|
||||||
|
|
||||||
|
FirebaseRecyclerOptions<Tests> options =
|
||||||
|
new FirebaseRecyclerOptions.Builder<Tests>()
|
||||||
|
.setQuery(TestRef, Tests.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
FirebaseRecyclerAdapter<Tests, TestViewHolder> adapter =
|
||||||
|
new FirebaseRecyclerAdapter<Tests, TestViewHolder>(options) {
|
||||||
|
@Override
|
||||||
|
protected void onBindViewHolder(@NonNull TestViewHolder holder, int position, @NonNull final Tests model)
|
||||||
|
{
|
||||||
|
if(model.getInternal().contains("Yes") || model.getInternal().contains("No"))
|
||||||
|
{
|
||||||
|
info.setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
|
}
|
||||||
|
if(model.getInternal().contains("Yes") )
|
||||||
|
{
|
||||||
|
holder.iconfinder.setBackgroundResource(R.drawable.green_circle);
|
||||||
|
holder.iconfinder.setText("I");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
holder.txtpatientid.setText("User Name :"+model.getUser_Name());
|
||||||
|
holder.txtsampletype.setText("Test Id :" +model.getTest_Id());
|
||||||
|
holder.nikshay.setText("Volume :"+model.getSample_volume());
|
||||||
|
holder.txttimestamp.setText(model.getSample_Date());
|
||||||
|
|
||||||
|
//holder.txtProductDescription.setText(model.getSample());
|
||||||
|
|
||||||
|
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent intent=new Intent(MainActivity.this, ViewSamples.class);
|
||||||
|
Log.e("main", "error id"+model.getTest_Id());
|
||||||
|
Log.e("main", "TestID"+model.getTest_Id());
|
||||||
|
|
||||||
|
intent.putExtra("pid",model.getTest_Id());
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public TestViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
|
||||||
|
{
|
||||||
|
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
|
||||||
|
TestViewHolder holder = new TestViewHolder(view);
|
||||||
|
return holder;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
adapter.startListening();
|
||||||
|
}
|
||||||
|
private void firebasesearch(String data)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Query firebaseSearchQuery = TestRef.orderByChild("Test_Id").startAt(data).endAt(data + "\uf8ff");
|
||||||
|
FirebaseRecyclerOptions<Tests> options =
|
||||||
|
new FirebaseRecyclerOptions.Builder<Tests>()
|
||||||
|
.setQuery(firebaseSearchQuery, Tests.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
FirebaseRecyclerAdapter<Tests, TestViewHolder> adapter =
|
||||||
|
new FirebaseRecyclerAdapter<Tests, TestViewHolder>(options) {
|
||||||
|
@Override
|
||||||
|
protected void onBindViewHolder(@NonNull final TestViewHolder holder, int position, @NonNull final Tests model)
|
||||||
|
{
|
||||||
|
if(model.getInternal().contains("Yes") || model.getInternal().contains("No"))
|
||||||
|
{
|
||||||
|
info.setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
|
}
|
||||||
|
if(model.getInternal().contains("Yes") )
|
||||||
|
{
|
||||||
|
holder.iconfinder.setBackgroundResource(R.drawable.green_circle);
|
||||||
|
holder.iconfinder.setText("I");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.txtpatientid.setText("User Name :"+model.getUser_Name());
|
||||||
|
holder.txtsampletype.setText("Test Id :" +model.getTest_Id());
|
||||||
|
holder.nikshay.setText("Volume :"+model.getSample_volume());
|
||||||
|
holder.txttimestamp.setText(model.getSample_Date());
|
||||||
|
|
||||||
|
//holder.txtProductDescription.setText(model.getSample());
|
||||||
|
|
||||||
|
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent intent=new Intent(MainActivity.this, ViewSamples.class);
|
||||||
|
Log.e("main", "error id"+model.getTest_Id());
|
||||||
|
Log.e("main", "TestID"+model.getTest_Id());
|
||||||
|
|
||||||
|
intent.putExtra("pid",model.getTest_Id());
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public TestViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
|
||||||
|
{
|
||||||
|
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
|
||||||
|
TestViewHolder holder = new TestViewHolder(view);
|
||||||
|
return holder;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
adapter.startListening();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
MenuInflater inflater=getMenuInflater();
|
||||||
|
inflater.inflate(R.menu.searchmenu,menu);
|
||||||
|
MenuItem item = menu.findItem(R.id.search);
|
||||||
|
SearchView searchView = (SearchView) item.getActionView();
|
||||||
|
//searchView.setIconified(false);
|
||||||
|
//searchView.setIconifiedByDefault(false);
|
||||||
|
searchView.setQueryHint("Search Test ID");
|
||||||
|
|
||||||
|
|
||||||
|
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onQueryTextSubmit(String query) {
|
||||||
|
query=query.toLowerCase();
|
||||||
|
|
||||||
|
firebasesearch(query);
|
||||||
|
// processsearch(query);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onQueryTextChange(String newText) {
|
||||||
|
newText=newText.toLowerCase();
|
||||||
|
|
||||||
|
firebasesearch(newText);
|
||||||
|
|
||||||
|
// processsearch(query);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return super.onCreateOptionsMenu(menu);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
|
||||||
|
finishAffinity();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package no.Reader.android.iisc.Reader.Model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class RegisterHelper implements Serializable {
|
||||||
|
|
||||||
|
public String name, number, password;
|
||||||
|
|
||||||
|
public RegisterHelper(String name, String number, String password) {
|
||||||
|
this.name = name;
|
||||||
|
this.number = number;
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
public RegisterHelper() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumber(String number) {
|
||||||
|
this.number = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package no.Reader.android.iisc.Reader.Model;
|
||||||
|
|
||||||
|
public class Tests {
|
||||||
|
|
||||||
|
private String Test_Id, Time, User_Name, Sample_volume, Sample_Date, Percentage, Internal;
|
||||||
|
|
||||||
|
public Tests() {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tests(String test_Id, String time, String user_Name, String sample_volume, String sample_Date, String percentage, String internal) {
|
||||||
|
Test_Id = test_Id;
|
||||||
|
Time = time;
|
||||||
|
User_Name = user_Name;
|
||||||
|
Sample_volume = sample_volume;
|
||||||
|
Sample_Date = sample_Date;
|
||||||
|
Percentage = percentage;
|
||||||
|
Internal = internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTest_Id() {
|
||||||
|
return Test_Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTest_Id(String test_Id) {
|
||||||
|
Test_Id = test_Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTime() {
|
||||||
|
return Time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(String time) {
|
||||||
|
Time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUser_Name() {
|
||||||
|
return User_Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser_Name(String user_Name) {
|
||||||
|
User_Name = user_Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSample_volume() {
|
||||||
|
return Sample_volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSample_volume(String sample_volume) {
|
||||||
|
Sample_volume = sample_volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSample_Date() {
|
||||||
|
return Sample_Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSample_Date(String sample_Date) {
|
||||||
|
Sample_Date = sample_Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPercentage() {
|
||||||
|
return Percentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPercentage(String percentage) {
|
||||||
|
Percentage = percentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInternal() {
|
||||||
|
return Internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInternal(String internal) {
|
||||||
|
Internal = internal;
|
||||||
|
}
|
||||||
|
}
|
||||||
140
app/src/main/java/no/Reader/android/iisc/Reader/Nav_Two.java
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import androidx.core.content.FileProvider;
|
||||||
|
import androidx.drawerlayout.widget.DrawerLayout;
|
||||||
|
|
||||||
|
import com.google.android.material.navigation.NavigationView;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
public class Nav_Two extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
|
||||||
|
|
||||||
|
protected DrawerLayout draw;
|
||||||
|
private LinearLayout line;
|
||||||
|
private Toolbar tool;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
|
||||||
|
switch (menuItem.getItemId())
|
||||||
|
{
|
||||||
|
|
||||||
|
case R.id.nav_contact_us:
|
||||||
|
Intent intent1=new Intent(this,About.class);
|
||||||
|
startActivity(intent1);
|
||||||
|
break;
|
||||||
|
case R.id.nav_result:
|
||||||
|
Intent intent2=new Intent(this, MainActivity.class);
|
||||||
|
startActivity(intent2);
|
||||||
|
break;
|
||||||
|
case R.id.nav_add_Test:
|
||||||
|
Intent intent3=new Intent(this, TestDetails.class);
|
||||||
|
startActivity(intent3);
|
||||||
|
break;
|
||||||
|
case R.id.nav_sample:
|
||||||
|
Intent intent6=new Intent(this, TemplateActivity2.class);
|
||||||
|
startActivity(intent6);
|
||||||
|
break;
|
||||||
|
case R.id.nav_negative:
|
||||||
|
Intent intent4=new Intent(this, NegativeResults.class);
|
||||||
|
startActivity(intent4);
|
||||||
|
break;
|
||||||
|
case R.id.nav_positive:
|
||||||
|
Intent intent5=new Intent(this, PositiveResult.class);
|
||||||
|
startActivity(intent5);
|
||||||
|
break;
|
||||||
|
case R.id.nav_logout:
|
||||||
|
Intent intent8=new Intent(this, LoginScreen.class);
|
||||||
|
SharedPreferences preferences = getSharedPreferences("PhoneBook_number", MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
|
|
||||||
|
// editor.putString(Name, phonenum);
|
||||||
|
editor.putString("Phone", null);
|
||||||
|
editor.putString("Name",null);
|
||||||
|
|
||||||
|
|
||||||
|
editor.commit();
|
||||||
|
|
||||||
|
startActivity(intent8);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
|
||||||
|
setContentView(R.layout.nav_two);
|
||||||
|
|
||||||
|
|
||||||
|
draw = findViewById(R.id.Drawer);
|
||||||
|
line = findViewById(R.id.line);
|
||||||
|
tool = findViewById(R.id.tollbar);
|
||||||
|
NavigationView navigationView = findViewById(R.id.navigation);
|
||||||
|
navigationView.setNavigationItemSelectedListener(this);
|
||||||
|
|
||||||
|
setSupportActionBar(tool);
|
||||||
|
|
||||||
|
Window window = getWindow();
|
||||||
|
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
|
||||||
|
|
||||||
|
|
||||||
|
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, draw, tool, R.string.open_navigation_drawer, R.string.close_navigation_drawer) {
|
||||||
|
@Override
|
||||||
|
public void onDrawerSlide(View drawerView, float slideOffset) {
|
||||||
|
super.onDrawerSlide(drawerView, slideOffset);
|
||||||
|
float sidebar = drawerView.getWidth() * slideOffset;
|
||||||
|
line.setTranslationX(sidebar);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
draw.addDrawerListener(toggle);
|
||||||
|
toggle.syncState();
|
||||||
|
View headerView = navigationView.getHeaderView(0);
|
||||||
|
TextView textView=headerView.findViewById(R.id.text);
|
||||||
|
TextView textView1=headerView.findViewById(R.id.not_sign_in);
|
||||||
|
|
||||||
|
SharedPreferences preferences=getSharedPreferences("PhoneBook_number",MODE_PRIVATE);
|
||||||
|
|
||||||
|
String string1 = preferences.getString("Phone", null);
|
||||||
|
String string2 = preferences.getString("Name", null);
|
||||||
|
textView.setText(string2);
|
||||||
|
textView1.setText(string1);
|
||||||
|
|
||||||
|
}
|
||||||
|
public void shared( String testid) {
|
||||||
|
String directory_path = Environment.getExternalStorageDirectory().getPath() + "/Test Report/";
|
||||||
|
String pat= directory_path + "Report_" + testid + ".xls";
|
||||||
|
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
File file = new File(pat);
|
||||||
|
Uri path = FileProvider.getUriForFile(getApplicationContext(), "no.Reader.android.iisc.fileprovider", file);
|
||||||
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
intent.setDataAndType(path, "application/vnd.ms-excel");
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import androidx.drawerlayout.widget.DrawerLayout;
|
||||||
|
|
||||||
|
import com.google.android.material.navigation.NavigationView;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
|
||||||
|
public class NavigationTop extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
|
||||||
|
|
||||||
|
protected DrawerLayout draw;
|
||||||
|
private LinearLayout line;
|
||||||
|
private Toolbar tool;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
|
||||||
|
switch (menuItem.getItemId())
|
||||||
|
{
|
||||||
|
|
||||||
|
case R.id.nav_contact_us:
|
||||||
|
Intent intent1=new Intent(this,About.class);
|
||||||
|
startActivity(intent1);
|
||||||
|
break;
|
||||||
|
case R.id.nav_result:
|
||||||
|
Intent intent2=new Intent(this, MainActivity.class);
|
||||||
|
startActivity(intent2);
|
||||||
|
break;
|
||||||
|
case R.id.nav_add_Test:
|
||||||
|
Intent intent3=new Intent(this, TestDetails.class);
|
||||||
|
startActivity(intent3);
|
||||||
|
break;
|
||||||
|
case R.id.nav_sample:
|
||||||
|
Intent intent6=new Intent(this, TemplateActivity2.class);
|
||||||
|
startActivity(intent6);
|
||||||
|
break;
|
||||||
|
case R.id.nav_negative:
|
||||||
|
Intent intent4=new Intent(this, NegativeResults.class);
|
||||||
|
startActivity(intent4);
|
||||||
|
break;
|
||||||
|
case R.id.nav_positive:
|
||||||
|
Intent intent5=new Intent(this, PositiveResult.class);
|
||||||
|
startActivity(intent5);
|
||||||
|
break;
|
||||||
|
case R.id.nav_logout:
|
||||||
|
Intent intent8=new Intent(this, LoginScreen.class);
|
||||||
|
SharedPreferences preferences = getSharedPreferences("PhoneBook_number", MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
|
|
||||||
|
// editor.putString(Name, phonenum);
|
||||||
|
editor.putString("Phone", null);
|
||||||
|
editor.putString("Name",null);
|
||||||
|
|
||||||
|
|
||||||
|
editor.commit();
|
||||||
|
|
||||||
|
startActivity(intent8);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_navigation__top);
|
||||||
|
|
||||||
|
|
||||||
|
draw = findViewById(R.id.Drawer);
|
||||||
|
line = findViewById(R.id.line);
|
||||||
|
tool = findViewById(R.id.tollbar);
|
||||||
|
NavigationView navigationView = findViewById(R.id.navigation);
|
||||||
|
navigationView.setNavigationItemSelectedListener(this);
|
||||||
|
|
||||||
|
setSupportActionBar(tool);
|
||||||
|
|
||||||
|
Window window = getWindow();
|
||||||
|
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
|
||||||
|
|
||||||
|
|
||||||
|
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, draw, tool, R.string.open_navigation_drawer, R.string.close_navigation_drawer) {
|
||||||
|
@Override
|
||||||
|
public void onDrawerSlide(View drawerView, float slideOffset) {
|
||||||
|
super.onDrawerSlide(drawerView, slideOffset);
|
||||||
|
float sidebar = drawerView.getWidth() * slideOffset;
|
||||||
|
line.setTranslationX(sidebar);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
draw.addDrawerListener(toggle);
|
||||||
|
toggle.syncState();
|
||||||
|
View headerView = navigationView.getHeaderView(0);
|
||||||
|
TextView textView=headerView.findViewById(R.id.text);
|
||||||
|
TextView textView1=headerView.findViewById(R.id.not_sign_in);
|
||||||
|
|
||||||
|
SharedPreferences preferences=getSharedPreferences("PhoneBook_number",MODE_PRIVATE);
|
||||||
|
|
||||||
|
String string1 = preferences.getString("Phone", null);
|
||||||
|
String string2 = preferences.getString("Name", null);
|
||||||
|
textView.setText(string2);
|
||||||
|
textView1.setText(string1);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,200 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.firebase.ui.database.FirebaseRecyclerAdapter;
|
||||||
|
import com.firebase.ui.database.FirebaseRecyclerOptions;
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
import com.google.firebase.database.DatabaseReference;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
import com.google.firebase.database.Query;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.Reader.Model.Tests;
|
||||||
|
|
||||||
|
|
||||||
|
public class NegativeResults extends NavigationTop {
|
||||||
|
private DatabaseReference TestRef;
|
||||||
|
private RecyclerView recyclerView;
|
||||||
|
|
||||||
|
private TextView info;
|
||||||
|
|
||||||
|
FloatingActionButton fasbs;
|
||||||
|
|
||||||
|
String number;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
LayoutInflater inflater = (LayoutInflater) this
|
||||||
|
.getSystemService(LAYOUT_INFLATER_SERVICE);
|
||||||
|
View contentView = inflater.inflate(R.layout.activity_main, null, false);
|
||||||
|
draw.addView(contentView, 0);
|
||||||
|
|
||||||
|
SharedPreferences preferences6 = getSharedPreferences("PhoneBook_number", MODE_PRIVATE);
|
||||||
|
|
||||||
|
number = preferences6.getString("Phone", null);
|
||||||
|
fasbs=findViewById(R.id.fab);
|
||||||
|
info=findViewById(R.id.info);
|
||||||
|
info.setText("No Results ");
|
||||||
|
info.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
|
||||||
|
Log.e("main", "error "+number);
|
||||||
|
TestRef = FirebaseDatabase.getInstance().getReference().child("Test_Data").child(number);
|
||||||
|
recyclerView = findViewById(R.id.recycler_view);
|
||||||
|
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fasbs.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent intent=new Intent(NegativeResults.this, TemplateActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
LinearLayoutManager layoutManager1=new LinearLayoutManager(this);
|
||||||
|
|
||||||
|
recyclerView.setLayoutManager(new GridLayoutManager(this, 1));
|
||||||
|
|
||||||
|
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||||
|
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
||||||
|
int height = displayMetrics.heightPixels / 8;
|
||||||
|
int spaceInPixel = 4;
|
||||||
|
recyclerView.addItemDecoration(new SpaceDecoration(spaceInPixel));
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void onStart()
|
||||||
|
{
|
||||||
|
super.onStart();
|
||||||
|
|
||||||
|
|
||||||
|
FirebaseRecyclerOptions<Tests> options =
|
||||||
|
new FirebaseRecyclerOptions.Builder<Tests>()
|
||||||
|
.setQuery(TestRef.orderByChild("Internal").equalTo("No"), Tests.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
FirebaseRecyclerAdapter<Tests, TestViewHolder> adapter =
|
||||||
|
new FirebaseRecyclerAdapter<Tests, TestViewHolder>(options) {
|
||||||
|
@Override
|
||||||
|
protected void onBindViewHolder(@NonNull TestViewHolder holder, int position, @NonNull final Tests model)
|
||||||
|
{
|
||||||
|
// holder.txtProductName.setText(model.getPatientid());
|
||||||
|
if(model.getInternal().contains("Yes") || model.getInternal().contains("No"))
|
||||||
|
{
|
||||||
|
info.setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
holder.txtpatientid.setText("User Name :"+model.getSample_volume());
|
||||||
|
holder.txtsampletype.setText("Test Id :" +model.getTest_Id());
|
||||||
|
holder.nikshay.setText("Volume :"+model.getSample_volume());
|
||||||
|
holder.txttimestamp.setText(model.getSample_Date());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//holder.txtProductDescription.setText(model.getSample());
|
||||||
|
|
||||||
|
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent intent=new Intent(NegativeResults.this, ViewSamples.class);
|
||||||
|
|
||||||
|
intent.putExtra("pid",model.getTest_Id());
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public TestViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
|
||||||
|
{
|
||||||
|
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
|
||||||
|
TestViewHolder holder = new TestViewHolder(view);
|
||||||
|
return holder;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
adapter.startListening();
|
||||||
|
}
|
||||||
|
private void firebasesearch(String data)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Query firebaseSearchQuery = TestRef.orderByChild("Test_Id").startAt(data).endAt(data + "\uf8ff") ;
|
||||||
|
FirebaseRecyclerOptions<Tests> options =
|
||||||
|
new FirebaseRecyclerOptions.Builder<Tests>()
|
||||||
|
.setQuery(firebaseSearchQuery, Tests.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
FirebaseRecyclerAdapter<Tests, TestViewHolder> adapter =
|
||||||
|
new FirebaseRecyclerAdapter<Tests, TestViewHolder>(options) {
|
||||||
|
@Override
|
||||||
|
protected void onBindViewHolder(@NonNull final TestViewHolder holder, int position, @NonNull final Tests model)
|
||||||
|
{
|
||||||
|
|
||||||
|
holder.txtpatientid.setText("User Name :"+model.getSample_volume());
|
||||||
|
holder.txtsampletype.setText("Test Id :" +model.getTest_Id());
|
||||||
|
holder.nikshay.setText("Volume :"+model.getSample_volume());
|
||||||
|
holder.txttimestamp.setText(model.getSample_Date());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
Intent intent=new Intent(NegativeResults.this, ViewSamples.class);
|
||||||
|
intent.putExtra("pid",model.getTest_Id());
|
||||||
|
startActivity(intent);
|
||||||
|
Log.e("main", "TestID"+model.getTest_Id());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public TestViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
|
||||||
|
{
|
||||||
|
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
|
||||||
|
TestViewHolder holder = new TestViewHolder(view);
|
||||||
|
return holder;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
adapter.startListening();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,203 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.firebase.ui.database.FirebaseRecyclerAdapter;
|
||||||
|
import com.firebase.ui.database.FirebaseRecyclerOptions;
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
import com.google.firebase.database.DatabaseReference;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
import com.google.firebase.database.Query;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.Reader.Model.Tests;
|
||||||
|
|
||||||
|
|
||||||
|
public class PositiveResult extends NavigationTop {
|
||||||
|
private DatabaseReference TestRef;
|
||||||
|
private RecyclerView recyclerView ;
|
||||||
|
FloatingActionButton fasbs;
|
||||||
|
private TextView info;
|
||||||
|
|
||||||
|
|
||||||
|
String number;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
LayoutInflater inflater = (LayoutInflater) this
|
||||||
|
.getSystemService(LAYOUT_INFLATER_SERVICE);
|
||||||
|
View contentView = inflater.inflate(R.layout.activity_main, null, false);
|
||||||
|
draw.addView(contentView, 0);
|
||||||
|
info=findViewById(R.id.info);
|
||||||
|
|
||||||
|
SharedPreferences preferences6 = getSharedPreferences("PhoneBook_number", MODE_PRIVATE);
|
||||||
|
info.setText("No Results ");
|
||||||
|
info.setVisibility(View.VISIBLE);
|
||||||
|
number = preferences6.getString("Phone", null);
|
||||||
|
fasbs=findViewById(R.id.fab);
|
||||||
|
|
||||||
|
|
||||||
|
Log.e("main", "error "+number);
|
||||||
|
TestRef = FirebaseDatabase.getInstance().getReference().child("Test_Data").child(number);
|
||||||
|
recyclerView = findViewById(R.id.recycler_view);
|
||||||
|
|
||||||
|
fasbs.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent intent=new Intent(PositiveResult.this, TestDetails.class);
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
LinearLayoutManager layoutManager1=new LinearLayoutManager(this);
|
||||||
|
/* layoutManager1.setOrientation(LinearLayoutManager.HORIZONTAL);
|
||||||
|
cA
|
||||||
|
layoutManager = new LinearLayoutManager(this);
|
||||||
|
recyclerView.setLayoutManager(layoutManager);
|
||||||
|
*/ // recyclerView.setHasFixedSize(true);
|
||||||
|
recyclerView.setLayoutManager(new GridLayoutManager(this, 1));
|
||||||
|
|
||||||
|
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||||
|
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
||||||
|
int height = displayMetrics.heightPixels / 8;
|
||||||
|
int spaceInPixel = 4;
|
||||||
|
recyclerView.addItemDecoration(new SpaceDecoration(spaceInPixel));
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void onStart()
|
||||||
|
{
|
||||||
|
super.onStart();
|
||||||
|
|
||||||
|
FirebaseRecyclerOptions<Tests> options =
|
||||||
|
new FirebaseRecyclerOptions.Builder<Tests>()
|
||||||
|
.setQuery(TestRef.orderByChild("Internal").equalTo("Yes"), Tests.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
FirebaseRecyclerAdapter<Tests, TestViewHolder> adapter =
|
||||||
|
new FirebaseRecyclerAdapter<Tests, TestViewHolder>(options) {
|
||||||
|
@Override
|
||||||
|
protected void onBindViewHolder(@NonNull TestViewHolder holder, int position, @NonNull final Tests model)
|
||||||
|
{
|
||||||
|
if(model.getInternal().contains("Yes") || model.getInternal().contains("No"))
|
||||||
|
{
|
||||||
|
info.setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
|
}
|
||||||
|
// holder.txtProductName.setText(model.getPatientid());
|
||||||
|
|
||||||
|
holder.iconfinder.setBackgroundResource(R.drawable.green_circle);
|
||||||
|
holder.iconfinder.setText("I");
|
||||||
|
holder.txtpatientid.setText("User Name :"+model.getSample_volume());
|
||||||
|
holder.txtsampletype.setText("Test Id :" +model.getTest_Id());
|
||||||
|
holder.nikshay.setText("Volume :"+model.getSample_volume());
|
||||||
|
holder.txttimestamp.setText(model.getSample_Date());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//holder.txtProductDescription.setText(model.getSample());
|
||||||
|
|
||||||
|
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent intent=new Intent(PositiveResult.this, ViewSamples.class);
|
||||||
|
Log.e("main", "TestID"+model.getTest_Id());
|
||||||
|
|
||||||
|
intent.putExtra("pid",model.getTest_Id());
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public TestViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
|
||||||
|
{
|
||||||
|
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
|
||||||
|
TestViewHolder holder = new TestViewHolder(view);
|
||||||
|
return holder;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
adapter.startListening();
|
||||||
|
}
|
||||||
|
private void firebasesearch(String data)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Query firebaseSearchQuery = TestRef.orderByChild("Patient_Id").startAt(data).endAt(data + "\uf8ff") ;
|
||||||
|
FirebaseRecyclerOptions<Tests> options =
|
||||||
|
new FirebaseRecyclerOptions.Builder<Tests>()
|
||||||
|
.setQuery(firebaseSearchQuery, Tests.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
FirebaseRecyclerAdapter<Tests, TestViewHolder> adapter =
|
||||||
|
new FirebaseRecyclerAdapter<Tests, TestViewHolder>(options) {
|
||||||
|
@Override
|
||||||
|
protected void onBindViewHolder(@NonNull final TestViewHolder holder, int position, @NonNull final Tests model)
|
||||||
|
{
|
||||||
|
|
||||||
|
holder.txtpatientid.setText("User Name :"+model.getSample_volume());
|
||||||
|
holder.txtsampletype.setText("Test Id :" +model.getTest_Id());
|
||||||
|
holder.nikshay.setText("Volume :"+model.getSample_volume());
|
||||||
|
holder.txttimestamp.setText(model.getSample_Date());
|
||||||
|
|
||||||
|
holder.iconfinder.setBackgroundResource(R.drawable.green_circle);
|
||||||
|
holder.iconfinder.setText("I");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
Intent intent=new Intent(PositiveResult.this, ViewSamples.class);
|
||||||
|
intent.putExtra("pid",model.getTest_Id());
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public TestViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
|
||||||
|
{
|
||||||
|
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
|
||||||
|
TestViewHolder holder = new TestViewHolder(view);
|
||||||
|
return holder;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
adapter.startListening();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
54
app/src/main/java/no/Reader/android/iisc/Reader/Readme.txt
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
nRF Toolbox demonstrates how to implement the Bluetooth Smart features in an Android application.
|
||||||
|
It consists of number of profiles, like Heart Rate, Blood Pressure etc. that may be use as is to communicate with real devices.
|
||||||
|
They use the Bluetooth SIG adopted profiles, that may be found here: https://developer.bluetooth.org/gatt/profiles/Pages/ProfilesHome.aspx
|
||||||
|
|
||||||
|
The Template Profile has been created to give a quick start with implementing proprietary services. Just start modifying 4 classes inside
|
||||||
|
the template package to implement features you need.
|
||||||
|
|
||||||
|
Below you will find a short step-by-step tutorial:
|
||||||
|
|
||||||
|
1. The template consists of the following files:
|
||||||
|
- TemplateActivity - the main class that is responsible for managing the view of your profile
|
||||||
|
- TemplateService - the service that is started whenever you connect to a device. I handles the Bluetooth Smart communication using the...
|
||||||
|
- TemplateManager - the manager that handles all the BLE logic required to communicate with the device. The TemplateManager derives from
|
||||||
|
the BleManager which handles most of the event itself and propagates the data-relevant to deriving class. You don't
|
||||||
|
have to, or even shouldn't modify the BleManager (unless you want to change the default behaviour).
|
||||||
|
- TemplateManagerCallbacks - the interface with a list of callbacks that the TemplateManager can call. Each method is usually related to one
|
||||||
|
BLE event, e.g. receiving a new value of the characteristic.\
|
||||||
|
- TemplateParser - an optional class in the .parser package that is responsible for converting the characteristic value to String.
|
||||||
|
This is used only for debugging. The String returned by the parse(..) method is then logged into the nRF Logger application
|
||||||
|
(if such installed).
|
||||||
|
- /settings/SettingsActivity and /settings/SettingsFragment - classes used to present user preferences. A stub implementation in the template.
|
||||||
|
- /res/layout/activity_feature_template.xml - the layout file for the TemplateActivity
|
||||||
|
- /res/values/strings_template.xml - a set of strings used in the layout file
|
||||||
|
- /res/xml/settings/template.xml - the user settings configuration
|
||||||
|
- /res/drawable/(x)hdpi/ic_template_feature.png - the template profile icon (HDPI, XHDPI). Please, keep the files size.
|
||||||
|
- /res/drawable/(x)hdpi/ic_stat_notify_template - the icon that is used in the notification
|
||||||
|
|
||||||
|
2. The communication between the components goes as follows:
|
||||||
|
- User clicks the CONNECT button and selects a target device on TemplateActivity.
|
||||||
|
- The base class of the TemplateActivity starts the service given by getServiceClass() method.
|
||||||
|
- The service starts and initializes the TemplateManager. TemplateActivity binds to the service and is being given the TemplateBinder object (the service API) as a result.
|
||||||
|
- The manager connects to the device using Bluetooth Smart and discovers its services.
|
||||||
|
- The manager initializes the device. Initialization is done using the list of actions given by the initGatt(..) method in the TemplateManager.
|
||||||
|
Initialization usually contains enabling notifications, writing some initial values etc.
|
||||||
|
- When initialization is complete the manager calls the onDeviceReady() callback.
|
||||||
|
- The service sends the BROADCAST_DEVICE_READY broadcast to the activity. Communication from the Service to the Activity is always done using the LocalBroadcastManager broadcasts.
|
||||||
|
- The base class of the TemplateActivity listens to the broadcasts and calls appropriate methods.
|
||||||
|
|
||||||
|
- When a custom event occurs, for example a notification is received, the manager parses the incoming data and calls the proper callback.
|
||||||
|
- The callback implementation in the TemplateService sends a broadcast message with values given in parameters.
|
||||||
|
- The TemplateActivity, which had registered a broadcast receiver before, listens to the broadcasts, reads the values and present them to users.
|
||||||
|
|
||||||
|
- Communication Activity->Service is done using the API in the TemplateBinder. You may find the example of how to use it in the ProximityActivity.
|
||||||
|
|
||||||
|
3. Please read the files listed above and the TODO messages for more information what to modify in the files.
|
||||||
|
|
||||||
|
4. Remember to add your activities and the service in the AndroidManifest.xml file. The nRF Toolbox lists all activities with the following intent filter:
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="no.Reader.android.iisc.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
5. Feel free to rename the nRF Toolbox application (/res/values/strings.xml ->app_name), change the toolbar colors (/res/values/color.xml -> actionBarColor, actionBarColorDark).
|
||||||
|
In order to remove unused profiles from the main FeaturesActivity just comment out their intent-filter tags in the AndroidManifest.xml file.
|
||||||
200
app/src/main/java/no/Reader/android/iisc/Reader/Register.java
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.Patterns;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.google.firebase.database.DataSnapshot;
|
||||||
|
import com.google.firebase.database.DatabaseError;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
import com.google.firebase.database.Query;
|
||||||
|
import com.google.firebase.database.ValueEventListener;
|
||||||
|
import com.hbb20.CountryCodePicker;
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.Reader.VerifyOTP.VerifyOtp;
|
||||||
|
|
||||||
|
|
||||||
|
public class Register extends AppCompatActivity {
|
||||||
|
String numberwithcode;
|
||||||
|
private Button next;
|
||||||
|
private EditText editTextMobile;
|
||||||
|
private ProgressDialog loadingBar;
|
||||||
|
|
||||||
|
private TextView login;
|
||||||
|
CountryCodePicker ccp;
|
||||||
|
String mobile,name;
|
||||||
|
|
||||||
|
private EditText editTextname;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_register);
|
||||||
|
next=findViewById(R.id.buttonContinue);
|
||||||
|
editTextMobile = findViewById(R.id.editTextMobile);
|
||||||
|
|
||||||
|
ccp=findViewById(R.id.ccp);
|
||||||
|
|
||||||
|
ccp.registerCarrierNumberEditText(editTextMobile);
|
||||||
|
loadingBar = new ProgressDialog(this);
|
||||||
|
login=findViewById(R.id.login_account);
|
||||||
|
login.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent intent = new Intent(Register.this, LoginScreen.class);
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
editTextname=findViewById(R.id.editTextName);
|
||||||
|
|
||||||
|
next.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
mobile = editTextMobile.getText().toString().trim();
|
||||||
|
mobile = mobile.replaceAll("[^0-9]", "");
|
||||||
|
|
||||||
|
name = editTextname.getText().toString().trim();
|
||||||
|
|
||||||
|
|
||||||
|
if (!isOnline()) {
|
||||||
|
//Create an alertdialog
|
||||||
|
AlertDialog.Builder Checkbuilder = new AlertDialog.Builder(Register.this);
|
||||||
|
Checkbuilder.setTitle("No Internet Connection !");
|
||||||
|
Checkbuilder.setMessage("Check Your Internet Connection.");
|
||||||
|
|
||||||
|
Checkbuilder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Checkbuilder.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AlertDialog alert = Checkbuilder.create();
|
||||||
|
alert.show();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
if (mobile.equals("") || name.equals("")) {
|
||||||
|
Toast.makeText(Register.this, "please enter all the required fields", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
} else if (!Patterns.PHONE.matcher(mobile).matches()) {
|
||||||
|
editTextMobile.setError("Enter a valid Phone ");
|
||||||
|
// Toast.makeText(Consumer_register.this, "Please Enter a valid email", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (mobile.length() <9 ) {
|
||||||
|
Toast.makeText(Register.this, "Enter a valid Phone", Toast.LENGTH_SHORT).show();
|
||||||
|
// Toast.makeText(Consumer_register.this, "Please Enter a valid email", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (mobile.length() >=11 ) {
|
||||||
|
Toast.makeText(Register.this, "Enter a valid Phone", Toast.LENGTH_SHORT).show();
|
||||||
|
// Toast.makeText(Consumer_register.this, "Please Enter a valid email", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
}else {
|
||||||
|
|
||||||
|
Query chekuser = FirebaseDatabase.getInstance().getReference("USERS").orderByChild("number").equalTo(mobile);
|
||||||
|
chekuser.addListenerForSingleValueEvent(new ValueEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
|
||||||
|
if (dataSnapshot.exists()) {
|
||||||
|
Toast.makeText(Register.this, "User Already Exist", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
// editTextMobile.setError("User Already Exist");
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Intent intent = new Intent(Register.this, VerifyOtp.class);
|
||||||
|
Log.e("main", "error " + mobile);
|
||||||
|
|
||||||
|
numberwithcode = ccp.getFullNumberWithPlus();
|
||||||
|
Log.e("main", "error " + numberwithcode);
|
||||||
|
|
||||||
|
if (mobile.equals("") || name.equals("")) {
|
||||||
|
Toast.makeText(Register.this, "please enter all the required fields", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
} else if (!Patterns.PHONE.matcher(mobile).matches()) {
|
||||||
|
editTextMobile.setError("Enter a valid Phone ");
|
||||||
|
// Toast.makeText(Consumer_register.this, "Please Enter a valid email", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
loadingBar.setTitle("Create Account");
|
||||||
|
loadingBar.setMessage("Please wait ");
|
||||||
|
loadingBar.setCanceledOnTouchOutside(false);
|
||||||
|
loadingBar.show();
|
||||||
|
|
||||||
|
|
||||||
|
intent.putExtra("numberwithcode", numberwithcode);
|
||||||
|
|
||||||
|
intent.putExtra("mobile", mobile);
|
||||||
|
intent.putExtra("username", name);
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelled(@NonNull DatabaseError databaseError) {
|
||||||
|
Log.e("Raman", "Received an exception check chexk " + databaseError.getMessage());
|
||||||
|
|
||||||
|
// Toast.makeText(ForgetPassword.this,databaseError.getMessage(),Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
|
||||||
|
Intent intent = new Intent(Register.this, LoginScreen.class);
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
public boolean isOnline() {
|
||||||
|
ConnectivityManager connMgr = (ConnectivityManager)
|
||||||
|
getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
|
||||||
|
return (networkInfo != null && networkInfo.isConnected());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.Reader.callback.SPCACharacteristicCallback;
|
||||||
|
import no.Reader.android.iisc.battery.BatteryManagerCallbacks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface {@link SPCAManagerCallbacks} must be implemented by {@link SPCAService}
|
||||||
|
* in order to receive callbacks from {@link TemplateManager}
|
||||||
|
*/
|
||||||
|
interface SPCAManagerCallbacks extends BatteryManagerCallbacks, SPCACharacteristicCallback {
|
||||||
|
|
||||||
|
// Callbacks are called when a data has been received/written to a remote device.
|
||||||
|
// This is the way how the manager notifies the activity about this event.
|
||||||
|
|
||||||
|
// TODO add more callbacks.
|
||||||
|
// If you need, create more ...Callback interfaces and extend this interface with them.
|
||||||
|
}
|
||||||
204
app/src/main/java/no/Reader/android/iisc/Reader/SPCAService.java
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.core.app.NotificationCompat;
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.log.Logger;
|
||||||
|
import no.Reader.android.iisc.FeaturesActivity;
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.NotificationData;
|
||||||
|
import no.Reader.android.iisc.profile.BleProfileService;
|
||||||
|
import no.Reader.android.iisc.profile.LoggableBleManager;
|
||||||
|
|
||||||
|
public class SPCAService extends BleProfileService implements SPCAManagerCallbacks {
|
||||||
|
public static final String BROADCAST_TEMPLATE_MEASUREMENT = "no.Reader.android.iisc.template.BROADCAST_MEASUREMENT";
|
||||||
|
public static final String EXTRA_DATA = "no.Reader.android.iisc.template.EXTRA_DATA";
|
||||||
|
|
||||||
|
public static final String BROADCAST_BATTERY_LEVEL = "no.Reader.android.iisc.BROADCAST_BATTERY_LEVEL";
|
||||||
|
public static final String EXTRA_BATTERY_LEVEL = "no.Reader.android.iisc.EXTRA_BATTERY_LEVEL";
|
||||||
|
|
||||||
|
private final static String ACTION_DISCONNECT = "no.Reader.android.iisc.template.ACTION_DISCONNECT";
|
||||||
|
|
||||||
|
private final static int NOTIFICATION_ID = 864;
|
||||||
|
private final static int OPEN_ACTIVITY_REQ = 0;
|
||||||
|
private final static int DISCONNECT_REQ = 1;
|
||||||
|
|
||||||
|
private TemplateManager mManager;
|
||||||
|
|
||||||
|
private final LocalBinder mBinder = new TemplateBinder();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This local binder is an interface for the bound activity to operate with the sensor.
|
||||||
|
*/
|
||||||
|
class TemplateBinder extends LocalBinder {
|
||||||
|
// TODO Define service API that may be used by a bound Activity
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends some important data to the device.
|
||||||
|
*
|
||||||
|
* @param parameter some parameter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void heatingSwitch(int state){
|
||||||
|
mManager.heatingSwitch(state);
|
||||||
|
}
|
||||||
|
public void sendDTemp(int d_temp) {
|
||||||
|
mManager.sendDTemp(d_temp);
|
||||||
|
}
|
||||||
|
public void sendATemp(int a_temp) {
|
||||||
|
mManager.sendATemp(a_temp);
|
||||||
|
}
|
||||||
|
public void sendETemp(int e_temp) {
|
||||||
|
mManager.sendETemp(e_temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendLTemp(int l_temp) {
|
||||||
|
mManager.sendLTemp(l_temp);
|
||||||
|
}
|
||||||
|
public void sendOTemp(int o_temp) {
|
||||||
|
mManager.sendOTemp(o_temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void sendDTime(int d_time) {
|
||||||
|
mManager.sendDTime(d_time);
|
||||||
|
}
|
||||||
|
public void sendATime(int a_time) {
|
||||||
|
mManager.sendATime(a_time);
|
||||||
|
}
|
||||||
|
public void sendETime(int e_time) {
|
||||||
|
mManager.sendETime(e_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendLTime(int l_time) {
|
||||||
|
mManager.sendLTime(l_time);
|
||||||
|
}
|
||||||
|
public void sendOTime(int o_time) { mManager.sendOTime(o_time); }
|
||||||
|
|
||||||
|
|
||||||
|
public void sendNPcrN(int n_pcr_c) {
|
||||||
|
mManager.sendNPcrC(n_pcr_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LocalBinder getBinder() {
|
||||||
|
return mBinder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LoggableBleManager<SPCAManagerCallbacks> initializeManager() {
|
||||||
|
return mManager = new TemplateManager(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
|
||||||
|
final IntentFilter filter = new IntentFilter();
|
||||||
|
filter.addAction(ACTION_DISCONNECT);
|
||||||
|
registerReceiver(mDisconnectActionBroadcastReceiver, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
// when user has disconnected from the sensor, we have to cancel the notification that we've created some milliseconds before using unbindService
|
||||||
|
cancelNotification();
|
||||||
|
unregisterReceiver(mDisconnectActionBroadcastReceiver);
|
||||||
|
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRebind() {
|
||||||
|
// when the activity rebinds to the service, remove the notification
|
||||||
|
cancelNotification();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onUnbind() {
|
||||||
|
// when the activity closes we need to show the notification that user is connected to the sensor
|
||||||
|
createNotification(R.string.template_notification_connected_message, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSampleValueReceived(@NonNull final BluetoothDevice device, final int value) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_TEMPLATE_MEASUREMENT);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, getBluetoothDevice());
|
||||||
|
broadcast.putExtra(EXTRA_DATA, value);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
|
||||||
|
if (!mBound) {
|
||||||
|
// Here we may update the notification to display the current value.
|
||||||
|
// TODO modify the notification here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBatteryLevelChanged(@NonNull final BluetoothDevice device, final int batteryLevel) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the notification.
|
||||||
|
*
|
||||||
|
* @param messageResId message resource id. The message must have one String parameter,<br />
|
||||||
|
* f.e. <code><string name="name">%s is connected</string></code>
|
||||||
|
* @param defaults signals that will be used to notify the user
|
||||||
|
*/
|
||||||
|
private void createNotification(final int messageResId, final int defaults) {
|
||||||
|
final Intent parentIntent = new Intent(this, FeaturesActivity.class);
|
||||||
|
parentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
final Intent targetIntent = new Intent(this, TemplateActivity.class);
|
||||||
|
|
||||||
|
final Intent disconnect = new Intent(ACTION_DISCONNECT);
|
||||||
|
final PendingIntent disconnectAction = PendingIntent.getBroadcast(this, DISCONNECT_REQ, disconnect, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
|
// both activities above have launchMode="singleTask" in the AndroidManifest.xml file, so if the task is already running, it will be resumed
|
||||||
|
final PendingIntent pendingIntent = PendingIntent.getActivities(this, OPEN_ACTIVITY_REQ, new Intent[]{parentIntent, targetIntent}, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
final NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NotificationData.CONNECTED_DEVICE_CHANNEL);
|
||||||
|
builder.setContentIntent(pendingIntent);
|
||||||
|
builder.setContentTitle(getString(R.string.app_name)).setContentText(getString(messageResId, getDeviceName()));
|
||||||
|
builder.setSmallIcon(R.drawable.ic_stat_notify_template);
|
||||||
|
builder.setShowWhen(defaults != 0).setDefaults(defaults).setAutoCancel(true).setOngoing(true);
|
||||||
|
builder.addAction(new NotificationCompat.Action(R.drawable.ic_action_bluetooth, getString(R.string.template_notification_action_disconnect), disconnectAction));
|
||||||
|
|
||||||
|
final Notification notification = builder.build();
|
||||||
|
final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
nm.notify(NOTIFICATION_ID, notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels the existing notification. If there is no active notification this method does nothing
|
||||||
|
*/
|
||||||
|
private void cancelNotification() {
|
||||||
|
final NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||||
|
nm.cancel(NOTIFICATION_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This broadcast receiver listens for {@link #ACTION_DISCONNECT} that may be fired by pressing Disconnect action button on the notification.
|
||||||
|
*/
|
||||||
|
private final BroadcastReceiver mDisconnectActionBroadcastReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
|
Logger.i(getLogSession(), "[Notification] Disconnect action pressed");
|
||||||
|
if (isConnected())
|
||||||
|
getBinder().disconnect();
|
||||||
|
else
|
||||||
|
stopSelf();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
public class SpaceDecoration extends RecyclerView.ItemDecoration {
|
||||||
|
private int space;
|
||||||
|
|
||||||
|
public SpaceDecoration(int space) {
|
||||||
|
this.space = space;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
|
||||||
|
outRect.left=outRect.bottom=outRect.right=outRect.top=space;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,527 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.Switch;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.profile.BleProfileService;
|
||||||
|
import no.Reader.android.iisc.profile.BleProfileServiceReadyActivity;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify the Template Activity to match your needs.
|
||||||
|
*/
|
||||||
|
public class TemplateActivity extends BleProfileServiceReadyActivity<SPCAService.TemplateBinder> {
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final String TAG = "TemplateActivity";
|
||||||
|
|
||||||
|
// TODO change view references to match your need
|
||||||
|
private TextView mValueView;
|
||||||
|
private TextView mHeatingStatusView;
|
||||||
|
|
||||||
|
private Switch mHeatingState ;
|
||||||
|
|
||||||
|
int p ,q,r;
|
||||||
|
int count =0;
|
||||||
|
int love=0;
|
||||||
|
int love1=0;
|
||||||
|
int love2=0;
|
||||||
|
int love3=0;
|
||||||
|
private TextView mClockView;
|
||||||
|
int act1_1=0;
|
||||||
|
int act1_2=0;
|
||||||
|
int act1_3=0;
|
||||||
|
private Button d,connect;
|
||||||
|
|
||||||
|
/*private EditText mDTimeValueView;
|
||||||
|
private Integer mDSetTime ;
|
||||||
|
private EditText mLTimeValueView;
|
||||||
|
private Integer mLSetTime ;
|
||||||
|
private EditText mOTimeValueView;
|
||||||
|
private Integer mOSetTime ;
|
||||||
|
|
||||||
|
private TextView mClockView;
|
||||||
|
|
||||||
|
private EditText mATimeValueView;
|
||||||
|
private Integer mASetTime ;
|
||||||
|
private EditText mETimeValueView;
|
||||||
|
private Integer mESetTime ;
|
||||||
|
|
||||||
|
private EditText mDTempValueView;
|
||||||
|
private Integer mDSetTemp ;
|
||||||
|
private EditText mATempValueView;
|
||||||
|
private Integer mASetTemp ;
|
||||||
|
private EditText mETempValueView;
|
||||||
|
private Integer mESetTemp ;
|
||||||
|
|
||||||
|
private EditText mLTempValueView;
|
||||||
|
private Integer mLSetTemp ;
|
||||||
|
private EditText mOTempValueView;
|
||||||
|
private Integer mOSetTemp ;
|
||||||
|
|
||||||
|
private EditText mNPcrCView;
|
||||||
|
private Integer mNPcrC ;
|
||||||
|
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void onCreateView(final Bundle savedInstanceState) {
|
||||||
|
// TODO modify the layout file(s). By default the activity shows only one field - the Heart Rate value as a sample
|
||||||
|
setContentView(R.layout.activity_feature_template);
|
||||||
|
BottomNavigationView bottomNav = findViewById(R.id.bottom_navigation);
|
||||||
|
bottomNav.setOnNavigationItemSelectedListener(navListener);
|
||||||
|
|
||||||
|
setGUI();
|
||||||
|
connect=findViewById(R.id.action_connect);
|
||||||
|
d.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
|
||||||
|
SharedPreferences preferences = getSharedPreferences("PhoneBook_adc1", MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
|
|
||||||
|
// editor.putString(Name, phonenum);
|
||||||
|
|
||||||
|
mHeatingState.setChecked(false);
|
||||||
|
editor.putString("act1_1", String.valueOf(act1_1));
|
||||||
|
editor.putString("act1_2", String.valueOf(act1_2));
|
||||||
|
editor.putString("act1_3", String.valueOf(act1_3));
|
||||||
|
|
||||||
|
|
||||||
|
Log.d("Addact11", String.valueOf(act1_1));
|
||||||
|
Log.d("Addact12", String.valueOf(act1_2));
|
||||||
|
Log.d("Addact13", String.valueOf(act1_3));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
editor.commit();
|
||||||
|
|
||||||
|
|
||||||
|
Intent intent = new Intent(TemplateActivity.this, TemplateActivity1.class);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void setGUI() {
|
||||||
|
// mClockView=findViewById(R.id.RemTime_Value);
|
||||||
|
|
||||||
|
// TODO assign your views to fields
|
||||||
|
mValueView = findViewById(R.id.Temp_Value);
|
||||||
|
d=findViewById(R.id.next);
|
||||||
|
/*mDTempValueView = findViewById(R.id.D_Temp_Set);
|
||||||
|
mDTimeValueView = findViewById(R.id.D_Time_Set);
|
||||||
|
mATempValueView = findViewById(R.id.A_Temp_Set);
|
||||||
|
mATimeValueView = findViewById(R.id.A_Time_Set);
|
||||||
|
mETempValueView = findViewById(R.id.E_Temp_Set);
|
||||||
|
mETimeValueView = findViewById(R.id.E_Time_Set);
|
||||||
|
mLTempValueView=findViewById(R.id.L_Temp_Set);
|
||||||
|
mOTempValueView=findViewById(R.id.O_Temp_Set);
|
||||||
|
mLTimeValueView = findViewById(R.id.L_Time_Set);
|
||||||
|
|
||||||
|
mOTimeValueView = findViewById(R.id.O_Time_Set);
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
mNPcrCView = findViewById(R.id.N_Pcr_C);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
mHeatingState = findViewById(R.id.heating_state);
|
||||||
|
mHeatingStatusView= findViewById(R.id.heating_status_text);
|
||||||
|
|
||||||
|
mHeatingState.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
|
if(connect.getText().equals("CONNECT"))
|
||||||
|
{
|
||||||
|
Toast.makeText(TemplateActivity.this, "Please connect to device", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (isChecked) {
|
||||||
|
|
||||||
|
|
||||||
|
getService().heatingSwitch(1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* mDSetTemp = Integer.parseInt(mDTempValueView.getText().toString());
|
||||||
|
getService().sendDTemp(mDSetTemp);
|
||||||
|
mDSetTime = Integer.parseInt(mDTimeValueView.getText().toString());
|
||||||
|
getService().sendDTime(mDSetTime);
|
||||||
|
|
||||||
|
mLSetTemp = Integer.parseInt(mLTempValueView.getText().toString());
|
||||||
|
getService().sendLTemp(mLSetTemp);
|
||||||
|
mLSetTime = Integer.parseInt(mLTimeValueView.getText().toString());
|
||||||
|
getService().sendLTime(mLSetTime);
|
||||||
|
|
||||||
|
mOSetTemp = Integer.parseInt(mOTempValueView.getText().toString());
|
||||||
|
getService().sendOTemp(mOSetTemp);
|
||||||
|
mOSetTime = Integer.parseInt(mOTimeValueView.getText().toString());
|
||||||
|
getService().sendOTime(mOSetTime);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Log.d("Add", String.valueOf(m));
|
||||||
|
|
||||||
|
mASetTemp = Integer.parseInt(mATempValueView.getText().toString());
|
||||||
|
getService().sendATemp(mASetTemp);
|
||||||
|
mASetTime = Integer.parseInt(mATimeValueView.getText().toString());
|
||||||
|
getService().sendATime(mASetTime);
|
||||||
|
|
||||||
|
mESetTemp = Integer.parseInt(mETempValueView.getText().toString());
|
||||||
|
getService().sendETemp(mESetTemp);
|
||||||
|
mESetTime = Integer.parseInt(mETimeValueView.getText().toString());
|
||||||
|
getService().sendETime(mESetTime);
|
||||||
|
|
||||||
|
mNPcrC = Integer.parseInt(mNPcrCView.getText().toString());
|
||||||
|
getService().sendNPcrN(mNPcrC);
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
getService().heatingSwitch(0);
|
||||||
|
}
|
||||||
|
mHeatingStatusView.setText(isChecked ? R.string.Heating_block_on : R.string.Heating_block_off);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/*findViewById(R.id.time_set_button).setOnClickListener(v -> {
|
||||||
|
if (isDeviceConnected()) {
|
||||||
|
|
||||||
|
mSetTime = Integer.parseInt(mTimeValueView.getText().toString());
|
||||||
|
getService().sendTimeDuration(mSetTime);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
findViewById(R.id.temp_set_button).setOnClickListener(v -> {
|
||||||
|
if (isDeviceConnected()) {
|
||||||
|
mSetTemp = Integer.parseInt(mTempValueView.getText().toString());
|
||||||
|
getService().sendTemp(mSetTemp);
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onInitialize(final Bundle savedInstanceState) {
|
||||||
|
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, makeIntentFilter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
LocalBroadcastManager.getInstance(this).unregisterReceiver(mBroadcastReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setDefaultUI() {
|
||||||
|
// TODO clear your UI
|
||||||
|
mValueView.setText(R.string.not_available_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getLoggerProfileTitle() {
|
||||||
|
return R.string.template_feature_title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@Override
|
||||||
|
protected void getAboutTextId() {
|
||||||
|
Intent intent =new Intent (TemplateActivity.this,About.class);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/*@Override
|
||||||
|
public boolean onCreateOptionsMenu(final Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.menu, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onOptionsItemSelected(final int itemId) {
|
||||||
|
switch (itemId) {
|
||||||
|
case R.id.action_about:
|
||||||
|
Intent intent =new Intent (TemplateActivity.this,About.class);
|
||||||
|
startActivity(intent);
|
||||||
|
break;
|
||||||
|
*//*case R.id.action_settings:
|
||||||
|
final Intent intent = new Intent(this, SettingsActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
break;*//*
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected int getDefaultDeviceName() {
|
||||||
|
return R.string.template_default_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected UUID getFilterUUID() {
|
||||||
|
// TODO this method may return the UUID of the service that is required to be in the advertisement packet of a device in order to be listed on the Scanner dialog.
|
||||||
|
// If null is returned no filtering is done.
|
||||||
|
return TemplateManager.SERVICE_UUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<? extends BleProfileService> getServiceClass() {
|
||||||
|
return SPCAService.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onServiceBound(final SPCAService.TemplateBinder binder) {
|
||||||
|
// not used
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onServiceUnbound() {
|
||||||
|
// not used
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServicesDiscovered(final BluetoothDevice device, final boolean optionalServicesFound) {
|
||||||
|
// this may notify user or show some views
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceDisconnected(final BluetoothDevice device) {
|
||||||
|
super.onDeviceDisconnected(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handling updates from the device
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private void setValueOnView(@NonNull final BluetoothDevice device, final int value) {
|
||||||
|
// TODO assign the value to a view
|
||||||
|
mValueView.setText(String.valueOf(value));
|
||||||
|
|
||||||
|
if(mHeatingState.isChecked())
|
||||||
|
{
|
||||||
|
d.postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
d.setEnabled(true);
|
||||||
|
Log.d(TAG, "resend1");
|
||||||
|
}
|
||||||
|
}, 7000);
|
||||||
|
d.postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
act1_1=value;
|
||||||
|
mValueView.setText(String.valueOf(act1_1));
|
||||||
|
Log.d(TAG, "resend1");
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
d.postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
act1_2=value;
|
||||||
|
mValueView.setText(String.valueOf(act1_2));
|
||||||
|
Log.d(TAG, "resend1");
|
||||||
|
}
|
||||||
|
}, 6000);
|
||||||
|
d.postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
act1_3=value;
|
||||||
|
mValueView.setText(String.valueOf(act1_3));
|
||||||
|
Log.d(TAG, "resend1");
|
||||||
|
}
|
||||||
|
}, 7000);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/*else if (!mHeatingState.isChecked() && count ==1) {
|
||||||
|
|
||||||
|
love=1;
|
||||||
|
count=2;
|
||||||
|
Log.d("check1", String.valueOf(love));
|
||||||
|
|
||||||
|
mValueView.setText("_");
|
||||||
|
Log.d("love", String.valueOf(love));
|
||||||
|
Log.d("love", String.valueOf(p));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if ( mHeatingState.isChecked() && love ==1 )
|
||||||
|
{
|
||||||
|
q=value;
|
||||||
|
final int d=value;
|
||||||
|
Log.d("Addq", String.valueOf(q));
|
||||||
|
|
||||||
|
mValueView.setText(String.valueOf(d));
|
||||||
|
love1=1;
|
||||||
|
}
|
||||||
|
else if(!mHeatingState.isChecked() && love1 ==1)
|
||||||
|
{
|
||||||
|
love3=1;
|
||||||
|
mValueView.setText("_");
|
||||||
|
Log.d("check1", String.valueOf(love));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(mHeatingState.isChecked() && love3 ==1)
|
||||||
|
{
|
||||||
|
r=value;
|
||||||
|
mValueView.setText(String.valueOf(value));
|
||||||
|
Log.d("Addr", String.valueOf(r));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mValueView.setText("_");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public void onBatteryLevelChanged(@NonNull final BluetoothDevice device, final int value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
|
final String action = intent.getAction();
|
||||||
|
final BluetoothDevice device = intent.getParcelableExtra(SPCAService.EXTRA_DEVICE);
|
||||||
|
|
||||||
|
if (SPCAService.BROADCAST_TEMPLATE_MEASUREMENT.equals(action)) {
|
||||||
|
final int value = intent.getIntExtra(SPCAService.EXTRA_DATA, 0);
|
||||||
|
// Update GUI
|
||||||
|
setValueOnView(device, value);
|
||||||
|
} else if (SPCAService.BROADCAST_BATTERY_LEVEL.equals(action)) {
|
||||||
|
final int batteryLevel = intent.getIntExtra(SPCAService.EXTRA_BATTERY_LEVEL, 0);
|
||||||
|
// Update GUI
|
||||||
|
onBatteryLevelChanged(device, batteryLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static IntentFilter makeIntentFilter() {
|
||||||
|
final IntentFilter intentFilter = new IntentFilter();
|
||||||
|
intentFilter.addAction(SPCAService.BROADCAST_TEMPLATE_MEASUREMENT);
|
||||||
|
intentFilter.addAction(SPCAService.BROADCAST_BATTERY_LEVEL);
|
||||||
|
return intentFilter;
|
||||||
|
}
|
||||||
|
private BottomNavigationView.OnNavigationItemSelectedListener navListener =
|
||||||
|
new BottomNavigationView.OnNavigationItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
||||||
|
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.nav_home:
|
||||||
|
Intent intent = new Intent(TemplateActivity.this, MainActivity.class);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
case R.id.nav_addtest:
|
||||||
|
Intent intent2 = new Intent(TemplateActivity.this, TestDetails.class);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent2);
|
||||||
|
break;
|
||||||
|
case R.id.nav_add_sample:
|
||||||
|
Intent intent3 = new Intent(TemplateActivity.this, TemplateActivity2.class);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
//super.onBackPressed();
|
||||||
|
IsFinish("Want to exit Test ?");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void IsFinish(String alertmessage) {
|
||||||
|
|
||||||
|
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
|
||||||
|
switch (which) {
|
||||||
|
case DialogInterface.BUTTON_POSITIVE:
|
||||||
|
Intent intent = new Intent(TemplateActivity.this, TestDetails.class);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent); // This above line close correctly
|
||||||
|
//finish();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DialogInterface.BUTTON_NEGATIVE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
|
builder.setMessage(alertmessage)
|
||||||
|
.setPositiveButton("Yes", dialogClickListener)
|
||||||
|
.setNegativeButton("No", dialogClickListener).show();
|
||||||
|
AlertDialog alertDialog = builder.create();
|
||||||
|
alertDialog.show();
|
||||||
|
alertDialog.getButton(Dialog.BUTTON_NEGATIVE).setTextColor(Color.BLACK);
|
||||||
|
alertDialog.getButton(Dialog.BUTTON_POSITIVE).setTextColor(Color.BLACK);
|
||||||
|
|
||||||
|
alertDialog.getButton(Dialog.BUTTON_NEGATIVE).
|
||||||
|
setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
alertDialog.getButton(Dialog.BUTTON_POSITIVE).
|
||||||
|
setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,528 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.Switch;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.profile.BleProfileService;
|
||||||
|
import no.Reader.android.iisc.profile.BleProfileServiceReadyActivity;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify the Template Activity to match your needs.
|
||||||
|
*/
|
||||||
|
public class TemplateActivity1 extends BleProfileServiceReadyActivity<SPCAService.TemplateBinder> {
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final String TAG = "TemplateActivity";
|
||||||
|
|
||||||
|
// TODO change view references to match your need
|
||||||
|
private TextView mValueView;
|
||||||
|
private TextView mHeatingStatusView;
|
||||||
|
|
||||||
|
private Switch mHeatingState ;
|
||||||
|
int p ,q,r;
|
||||||
|
int count =0;
|
||||||
|
int love=0;
|
||||||
|
int love1=0;
|
||||||
|
int act2_1=0;
|
||||||
|
int act2_2=0;
|
||||||
|
int act2_3=0;
|
||||||
|
int love2=0;
|
||||||
|
int love3=0;
|
||||||
|
private TextView mClockView;
|
||||||
|
int act2=0;
|
||||||
|
private Button d,connect;
|
||||||
|
|
||||||
|
|
||||||
|
/*private EditText mDTimeValueView;
|
||||||
|
private Integer mDSetTime ;
|
||||||
|
private EditText mLTimeValueView;
|
||||||
|
private Integer mLSetTime ;
|
||||||
|
private EditText mOTimeValueView;
|
||||||
|
private Integer mOSetTime ;
|
||||||
|
|
||||||
|
private TextView mClockView;
|
||||||
|
|
||||||
|
private EditText mATimeValueView;
|
||||||
|
private Integer mASetTime ;
|
||||||
|
private EditText mETimeValueView;
|
||||||
|
private Integer mESetTime ;
|
||||||
|
|
||||||
|
private EditText mDTempValueView;
|
||||||
|
private Integer mDSetTemp ;
|
||||||
|
private EditText mATempValueView;
|
||||||
|
private Integer mASetTemp ;
|
||||||
|
private EditText mETempValueView;
|
||||||
|
private Integer mESetTemp ;
|
||||||
|
|
||||||
|
private EditText mLTempValueView;
|
||||||
|
private Integer mLSetTemp ;
|
||||||
|
private EditText mOTempValueView;
|
||||||
|
private Integer mOSetTemp ;
|
||||||
|
|
||||||
|
private EditText mNPcrCView;
|
||||||
|
private Integer mNPcrC ;
|
||||||
|
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void onCreateView(final Bundle savedInstanceState) {
|
||||||
|
// TODO modify the layout file(s). By default the activity shows only one field - the Heart Rate value as a sample
|
||||||
|
setContentView(R.layout.activity_feature_template1);
|
||||||
|
BottomNavigationView bottomNav = findViewById(R.id.bottom_navigation);
|
||||||
|
bottomNav.setOnNavigationItemSelectedListener(navListener);
|
||||||
|
setGUI();
|
||||||
|
|
||||||
|
connect=findViewById(R.id.action_connect);
|
||||||
|
|
||||||
|
d.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
if(ContextCompat.checkSelfPermission(TemplateActivity1.this, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
|
||||||
|
{
|
||||||
|
|
||||||
|
ActivityCompat.requestPermissions(TemplateActivity1.this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},23);
|
||||||
|
}
|
||||||
|
SharedPreferences preferences = getSharedPreferences("PhoneBook_adc2", MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
|
|
||||||
|
// editor.putString(Name, phonenum);
|
||||||
|
|
||||||
|
editor.putString("act2_1", String.valueOf(act2_1));
|
||||||
|
editor.putString("act2_2", String.valueOf(act2_2));
|
||||||
|
editor.putString("act2_3", String.valueOf(act2_3));
|
||||||
|
|
||||||
|
|
||||||
|
Log.d("Addact21", String.valueOf(act2_1));
|
||||||
|
Log.d("Addact22", String.valueOf(act2_2));
|
||||||
|
Log.d("Addact23", String.valueOf(act2_3));
|
||||||
|
|
||||||
|
editor.commit();
|
||||||
|
mHeatingState.setChecked(false);
|
||||||
|
|
||||||
|
|
||||||
|
Intent intent = new Intent(TemplateActivity1.this, TemplateActivity2.class);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private BottomNavigationView.OnNavigationItemSelectedListener navListener =
|
||||||
|
new BottomNavigationView.OnNavigationItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
||||||
|
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.nav_home:
|
||||||
|
Intent intent = new Intent(TemplateActivity1.this, MainActivity.class);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
case R.id.nav_addtest:
|
||||||
|
Intent intent2 = new Intent(TemplateActivity1.this, TestDetails.class);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent2);
|
||||||
|
break;
|
||||||
|
case R.id.nav_add_sample:
|
||||||
|
Intent intent3 = new Intent(TemplateActivity1.this, TemplateActivity2.class);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void setGUI() {
|
||||||
|
// mClockView=findViewById(R.id.RemTime_Value);
|
||||||
|
|
||||||
|
// TODO assign your views to fields
|
||||||
|
mValueView = findViewById(R.id.Temp_Value);
|
||||||
|
d=findViewById(R.id.next);
|
||||||
|
/*mDTempValueView = findViewById(R.id.D_Temp_Set);
|
||||||
|
mDTimeValueView = findViewById(R.id.D_Time_Set);
|
||||||
|
mATempValueView = findViewById(R.id.A_Temp_Set);
|
||||||
|
mATimeValueView = findViewById(R.id.A_Time_Set);
|
||||||
|
mETempValueView = findViewById(R.id.E_Temp_Set);
|
||||||
|
mETimeValueView = findViewById(R.id.E_Time_Set);
|
||||||
|
mLTempValueView=findViewById(R.id.L_Temp_Set);
|
||||||
|
mOTempValueView=findViewById(R.id.O_Temp_Set);
|
||||||
|
mLTimeValueView = findViewById(R.id.L_Time_Set);
|
||||||
|
|
||||||
|
mOTimeValueView = findViewById(R.id.O_Time_Set);
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
mNPcrCView = findViewById(R.id.N_Pcr_C);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
mHeatingState = findViewById(R.id.heating_state);
|
||||||
|
mHeatingStatusView= findViewById(R.id.heating_status_text);
|
||||||
|
|
||||||
|
mHeatingState.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
|
if(connect.getText().equals("CONNECT"))
|
||||||
|
{
|
||||||
|
Toast.makeText(TemplateActivity1.this, "Please connect to device", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (isChecked) {
|
||||||
|
getService().heatingSwitch(1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* mDSetTemp = Integer.parseInt(mDTempValueView.getText().toString());
|
||||||
|
getService().sendDTemp(mDSetTemp);
|
||||||
|
mDSetTime = Integer.parseInt(mDTimeValueView.getText().toString());
|
||||||
|
getService().sendDTime(mDSetTime);
|
||||||
|
|
||||||
|
mLSetTemp = Integer.parseInt(mLTempValueView.getText().toString());
|
||||||
|
getService().sendLTemp(mLSetTemp);
|
||||||
|
mLSetTime = Integer.parseInt(mLTimeValueView.getText().toString());
|
||||||
|
getService().sendLTime(mLSetTime);
|
||||||
|
|
||||||
|
mOSetTemp = Integer.parseInt(mOTempValueView.getText().toString());
|
||||||
|
getService().sendOTemp(mOSetTemp);
|
||||||
|
mOSetTime = Integer.parseInt(mOTimeValueView.getText().toString());
|
||||||
|
getService().sendOTime(mOSetTime);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Log.d("Add", String.valueOf(m));
|
||||||
|
|
||||||
|
mASetTemp = Integer.parseInt(mATempValueView.getText().toString());
|
||||||
|
getService().sendATemp(mASetTemp);
|
||||||
|
mASetTime = Integer.parseInt(mATimeValueView.getText().toString());
|
||||||
|
getService().sendATime(mASetTime);
|
||||||
|
|
||||||
|
mESetTemp = Integer.parseInt(mETempValueView.getText().toString());
|
||||||
|
getService().sendETemp(mESetTemp);
|
||||||
|
mESetTime = Integer.parseInt(mETimeValueView.getText().toString());
|
||||||
|
getService().sendETime(mESetTime);
|
||||||
|
|
||||||
|
mNPcrC = Integer.parseInt(mNPcrCView.getText().toString());
|
||||||
|
getService().sendNPcrN(mNPcrC);
|
||||||
|
*/
|
||||||
|
|
||||||
|
} else {
|
||||||
|
getService().heatingSwitch(0);
|
||||||
|
}
|
||||||
|
mHeatingStatusView.setText(isChecked ? R.string.Heating_block_on : R.string.Heating_block_off);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/*findViewById(R.id.time_set_button).setOnClickListener(v -> {
|
||||||
|
if (isDeviceConnected()) {
|
||||||
|
|
||||||
|
mSetTime = Integer.parseInt(mTimeValueView.getText().toString());
|
||||||
|
getService().sendTimeDuration(mSetTime);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
findViewById(R.id.temp_set_button).setOnClickListener(v -> {
|
||||||
|
if (isDeviceConnected()) {
|
||||||
|
mSetTemp = Integer.parseInt(mTempValueView.getText().toString());
|
||||||
|
getService().sendTemp(mSetTemp);
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onInitialize(final Bundle savedInstanceState) {
|
||||||
|
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, makeIntentFilter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
LocalBroadcastManager.getInstance(this).unregisterReceiver(mBroadcastReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setDefaultUI() {
|
||||||
|
// TODO clear your UI
|
||||||
|
mValueView.setText(R.string.not_available_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getLoggerProfileTitle() {
|
||||||
|
return R.string.template_feature_title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@Override
|
||||||
|
protected void getAboutTextId() {
|
||||||
|
Intent =new Intent (TemplateActivity1.this,About.class);
|
||||||
|
startActivity(intent);
|
||||||
|
}*/
|
||||||
|
/* @Override
|
||||||
|
public boolean onCreateOptionsMenu(final Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.settings_and_about, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onOptionsItemSelected(final int itemId) {
|
||||||
|
switch (itemId) {
|
||||||
|
*//*case R.id.action_settings:
|
||||||
|
final Intent intent = new Intent(this, SettingsActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
break;*//*
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getDefaultDeviceName() {
|
||||||
|
return R.string.template_default_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected UUID getFilterUUID() {
|
||||||
|
// TODO this method may return the UUID of the service that is required to be in the advertisement packet of a device in order to be listed on the Scanner dialog.
|
||||||
|
// If null is returned no filtering is done.
|
||||||
|
return TemplateManager.SERVICE_UUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<? extends BleProfileService> getServiceClass() {
|
||||||
|
return SPCAService.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onServiceBound(final SPCAService.TemplateBinder binder) {
|
||||||
|
// not used
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onServiceUnbound() {
|
||||||
|
// not used
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServicesDiscovered(final BluetoothDevice device, final boolean optionalServicesFound) {
|
||||||
|
// this may notify user or show some views
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceDisconnected(final BluetoothDevice device) {
|
||||||
|
super.onDeviceDisconnected(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handling updates from the device
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private void setValueOnView(@NonNull final BluetoothDevice device, final int value) {
|
||||||
|
// TODO assign the value to a view
|
||||||
|
if(mHeatingState.isChecked())
|
||||||
|
{
|
||||||
|
mValueView.setText(String.valueOf(value));
|
||||||
|
|
||||||
|
d.postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
d.setEnabled(true);
|
||||||
|
Log.d(TAG, "resend1");
|
||||||
|
}
|
||||||
|
}, 7000);
|
||||||
|
d.postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
act2_1=value;
|
||||||
|
mValueView.setText(String.valueOf(act2_1));
|
||||||
|
Log.d(TAG, "resend1");
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
d.postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
act2_2=value;
|
||||||
|
mValueView.setText(String.valueOf(act2_2));
|
||||||
|
Log.d(TAG, "resend1");
|
||||||
|
}
|
||||||
|
}, 6000);
|
||||||
|
d.postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
act2_3=value;
|
||||||
|
mValueView.setText(String.valueOf(act2_3));
|
||||||
|
Log.d(TAG, "resend1");
|
||||||
|
}
|
||||||
|
}, 7000);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/*else if (!mHeatingState.isChecked() && count ==1) {
|
||||||
|
|
||||||
|
love=1;
|
||||||
|
count=2;
|
||||||
|
Log.d("check1", String.valueOf(love));
|
||||||
|
|
||||||
|
mValueView.setText("_");
|
||||||
|
Log.d("love", String.valueOf(love));
|
||||||
|
Log.d("love", String.valueOf(p));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if ( mHeatingState.isChecked() && love ==1 )
|
||||||
|
{
|
||||||
|
q=value;
|
||||||
|
final int d=value;
|
||||||
|
Log.d("Addq", String.valueOf(q));
|
||||||
|
|
||||||
|
mValueView.setText(String.valueOf(d));
|
||||||
|
love1=1;
|
||||||
|
}
|
||||||
|
else if(!mHeatingState.isChecked() && love1 ==1)
|
||||||
|
{
|
||||||
|
love3=1;
|
||||||
|
mValueView.setText("_");
|
||||||
|
Log.d("check1", String.valueOf(love));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(mHeatingState.isChecked() && love3 ==1)
|
||||||
|
{
|
||||||
|
r=value;
|
||||||
|
mValueView.setText(String.valueOf(value));
|
||||||
|
Log.d("Addr", String.valueOf(r));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mValueView.setText("_");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public void onBatteryLevelChanged(@NonNull final BluetoothDevice device, final int value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
|
final String action = intent.getAction();
|
||||||
|
final BluetoothDevice device = intent.getParcelableExtra(SPCAService.EXTRA_DEVICE);
|
||||||
|
|
||||||
|
if (SPCAService.BROADCAST_TEMPLATE_MEASUREMENT.equals(action)) {
|
||||||
|
final int value = intent.getIntExtra(SPCAService.EXTRA_DATA, 0);
|
||||||
|
// Update GUI
|
||||||
|
setValueOnView(device, value);
|
||||||
|
} else if (SPCAService.BROADCAST_BATTERY_LEVEL.equals(action)) {
|
||||||
|
final int batteryLevel = intent.getIntExtra(SPCAService.EXTRA_BATTERY_LEVEL, 0);
|
||||||
|
// Update GUI
|
||||||
|
onBatteryLevelChanged(device, batteryLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static IntentFilter makeIntentFilter() {
|
||||||
|
final IntentFilter intentFilter = new IntentFilter();
|
||||||
|
intentFilter.addAction(SPCAService.BROADCAST_TEMPLATE_MEASUREMENT);
|
||||||
|
intentFilter.addAction(SPCAService.BROADCAST_BATTERY_LEVEL);
|
||||||
|
return intentFilter;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
//super.onBackPressed();
|
||||||
|
IsFinish("Want to exit Test ?");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void IsFinish(String alertmessage) {
|
||||||
|
|
||||||
|
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
|
||||||
|
switch (which) {
|
||||||
|
case DialogInterface.BUTTON_POSITIVE:
|
||||||
|
Intent intent = new Intent(TemplateActivity1.this, TestDetails.class);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent); // This above line close correctly
|
||||||
|
//finish();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DialogInterface.BUTTON_NEGATIVE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
|
builder.setMessage(alertmessage)
|
||||||
|
.setPositiveButton("Yes", dialogClickListener)
|
||||||
|
.setNegativeButton("No", dialogClickListener).show();
|
||||||
|
AlertDialog alertDialog = builder.create();
|
||||||
|
alertDialog.show();
|
||||||
|
alertDialog.getButton(Dialog.BUTTON_NEGATIVE).setTextColor(Color.BLACK);
|
||||||
|
alertDialog.getButton(Dialog.BUTTON_POSITIVE).setTextColor(Color.BLACK);
|
||||||
|
|
||||||
|
alertDialog.getButton(Dialog.BUTTON_NEGATIVE).
|
||||||
|
setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
alertDialog.getButton(Dialog.BUTTON_POSITIVE).
|
||||||
|
setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,529 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.Switch;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.profile.BleProfileService;
|
||||||
|
import no.Reader.android.iisc.profile.BleProfileServiceReadyActivity;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify the Template Activity to match your needs.
|
||||||
|
*/
|
||||||
|
public class TemplateActivity2 extends BleProfileServiceReadyActivity<SPCAService.TemplateBinder> {
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final String TAG = "TemplateActivity";
|
||||||
|
|
||||||
|
// TODO change view references to match your need
|
||||||
|
private TextView mValueView;
|
||||||
|
private TextView mHeatingStatusView;
|
||||||
|
|
||||||
|
private Switch mHeatingState ;
|
||||||
|
int p ,q,r;
|
||||||
|
private EditText sampledata;
|
||||||
|
int act3_1=0;
|
||||||
|
int act3_2=0;
|
||||||
|
int act3_3=0;
|
||||||
|
int count =0;
|
||||||
|
int love=0;
|
||||||
|
int love1=0;
|
||||||
|
int love2=0;
|
||||||
|
int love3=0;
|
||||||
|
private TextView mClockView;
|
||||||
|
int act3=0;
|
||||||
|
private Button d,connect;
|
||||||
|
|
||||||
|
|
||||||
|
/*private EditText mDTimeValueView;
|
||||||
|
private Integer mDSetTime ;
|
||||||
|
private EditText mLTimeValueView;
|
||||||
|
private Integer mLSetTime ;
|
||||||
|
private EditText mOTimeValueView;
|
||||||
|
private Integer mOSetTime ;
|
||||||
|
|
||||||
|
private TextView mClockView;
|
||||||
|
|
||||||
|
private EditText mATimeValueView;
|
||||||
|
private Integer mASetTime ;
|
||||||
|
private EditText mETimeValueView;
|
||||||
|
private Integer mESetTime ;
|
||||||
|
|
||||||
|
private EditText mDTempValueView;
|
||||||
|
private Integer mDSetTemp ;
|
||||||
|
private EditText mATempValueView;
|
||||||
|
private Integer mASetTemp ;
|
||||||
|
private EditText mETempValueView;
|
||||||
|
private Integer mESetTemp ;
|
||||||
|
|
||||||
|
private EditText mLTempValueView;
|
||||||
|
private Integer mLSetTemp ;
|
||||||
|
private EditText mOTempValueView;
|
||||||
|
private Integer mOSetTemp ;
|
||||||
|
|
||||||
|
private EditText mNPcrCView;
|
||||||
|
private Integer mNPcrC ;
|
||||||
|
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void onCreateView(final Bundle savedInstanceState) {
|
||||||
|
// TODO modify the layout file(s). By default the activity shows only one field - the Heart Rate value as a sample
|
||||||
|
setContentView(R.layout.activity_feature_template2);
|
||||||
|
sampledata=findViewById(R.id.samplename);
|
||||||
|
BottomNavigationView bottomNav = findViewById(R.id.bottom_navigation);
|
||||||
|
bottomNav.setOnNavigationItemSelectedListener(navListener);
|
||||||
|
|
||||||
|
|
||||||
|
setGUI();
|
||||||
|
connect=findViewById(R.id.action_connect);
|
||||||
|
|
||||||
|
d.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
SharedPreferences preferences = getSharedPreferences("PhoneBook_adc3", MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
|
|
||||||
|
// editor.putString(Name, phonenum);
|
||||||
|
|
||||||
|
|
||||||
|
/* editor.putString("act3", String.valueOf(act3));
|
||||||
|
Log.d("Addact1", String.valueOf(act3));
|
||||||
|
|
||||||
|
editor.commit();
|
||||||
|
*/
|
||||||
|
editor.putString("act3_1", String.valueOf(act3_1));
|
||||||
|
editor.putString("act3_2", String.valueOf(act3_2));
|
||||||
|
editor.putString("act3_3", String.valueOf(act3_3));
|
||||||
|
editor.putString("samplename", String.valueOf(sampledata.getText()));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Log.d("Addact21", String.valueOf(act3_1));
|
||||||
|
Log.d("Addact22", String.valueOf(act3_2));
|
||||||
|
Log.d("Addact23", String.valueOf(act3_3));
|
||||||
|
|
||||||
|
editor.commit();
|
||||||
|
mHeatingState.setChecked(false);
|
||||||
|
|
||||||
|
|
||||||
|
Intent intent = new Intent(TemplateActivity2.this, check1.class);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void setGUI() {
|
||||||
|
// mClockView=findViewById(R.id.RemTime_Value);
|
||||||
|
|
||||||
|
// TODO assign your views to fields
|
||||||
|
mValueView = findViewById(R.id.Temp_Value);
|
||||||
|
d=findViewById(R.id.next);
|
||||||
|
/*mDTempValueView = findViewById(R.id.D_Temp_Set);
|
||||||
|
mDTimeValueView = findViewById(R.id.D_Time_Set);
|
||||||
|
mATempValueView = findViewById(R.id.A_Temp_Set);
|
||||||
|
mATimeValueView = findViewById(R.id.A_Time_Set);
|
||||||
|
mETempValueView = findViewById(R.id.E_Temp_Set);
|
||||||
|
mETimeValueView = findViewById(R.id.E_Time_Set);
|
||||||
|
mLTempValueView=findViewById(R.id.L_Temp_Set);
|
||||||
|
mOTempValueView=findViewById(R.id.O_Temp_Set);
|
||||||
|
mLTimeValueView = findViewById(R.id.L_Time_Set);
|
||||||
|
|
||||||
|
mOTimeValueView = findViewById(R.id.O_Time_Set);
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
mNPcrCView = findViewById(R.id.N_Pcr_C);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
mHeatingState = findViewById(R.id.heating_state);
|
||||||
|
mHeatingStatusView= findViewById(R.id.heating_status_text);
|
||||||
|
|
||||||
|
mHeatingState.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
|
if(connect.getText().equals("CONNECT"))
|
||||||
|
{
|
||||||
|
Toast.makeText(TemplateActivity2.this, "Please connect to device", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (isChecked) {
|
||||||
|
getService().heatingSwitch(1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* mDSetTemp = Integer.parseInt(mDTempValueView.getText().toString());
|
||||||
|
getService().sendDTemp(mDSetTemp);
|
||||||
|
mDSetTime = Integer.parseInt(mDTimeValueView.getText().toString());
|
||||||
|
getService().sendDTime(mDSetTime);
|
||||||
|
|
||||||
|
mLSetTemp = Integer.parseInt(mLTempValueView.getText().toString());
|
||||||
|
getService().sendLTemp(mLSetTemp);
|
||||||
|
mLSetTime = Integer.parseInt(mLTimeValueView.getText().toString());
|
||||||
|
getService().sendLTime(mLSetTime);
|
||||||
|
|
||||||
|
mOSetTemp = Integer.parseInt(mOTempValueView.getText().toString());
|
||||||
|
getService().sendOTemp(mOSetTemp);
|
||||||
|
mOSetTime = Integer.parseInt(mOTimeValueView.getText().toString());
|
||||||
|
getService().sendOTime(mOSetTime);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Log.d("Add", String.valueOf(m));
|
||||||
|
|
||||||
|
mASetTemp = Integer.parseInt(mATempValueView.getText().toString());
|
||||||
|
getService().sendATemp(mASetTemp);
|
||||||
|
mASetTime = Integer.parseInt(mATimeValueView.getText().toString());
|
||||||
|
getService().sendATime(mASetTime);
|
||||||
|
|
||||||
|
mESetTemp = Integer.parseInt(mETempValueView.getText().toString());
|
||||||
|
getService().sendETemp(mESetTemp);
|
||||||
|
mESetTime = Integer.parseInt(mETimeValueView.getText().toString());
|
||||||
|
getService().sendETime(mESetTime);
|
||||||
|
|
||||||
|
mNPcrC = Integer.parseInt(mNPcrCView.getText().toString());
|
||||||
|
getService().sendNPcrN(mNPcrC);
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
getService().heatingSwitch(0);
|
||||||
|
}
|
||||||
|
mHeatingStatusView.setText(isChecked ? R.string.Heating_block_on : R.string.Heating_block_off);
|
||||||
|
}});
|
||||||
|
|
||||||
|
|
||||||
|
/*findViewById(R.id.time_set_button).setOnClickListener(v -> {
|
||||||
|
if (isDeviceConnected()) {
|
||||||
|
|
||||||
|
mSetTime = Integer.parseInt(mTimeValueView.getText().toString());
|
||||||
|
getService().sendTimeDuration(mSetTime);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
findViewById(R.id.temp_set_button).setOnClickListener(v -> {
|
||||||
|
if (isDeviceConnected()) {
|
||||||
|
mSetTemp = Integer.parseInt(mTempValueView.getText().toString());
|
||||||
|
getService().sendTemp(mSetTemp);
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onInitialize(final Bundle savedInstanceState) {
|
||||||
|
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, makeIntentFilter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
LocalBroadcastManager.getInstance(this).unregisterReceiver(mBroadcastReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setDefaultUI() {
|
||||||
|
// TODO clear your UI
|
||||||
|
mValueView.setText(R.string.not_available_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getLoggerProfileTitle() {
|
||||||
|
return R.string.template_feature_title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@Override
|
||||||
|
protected void getAboutTextId() {
|
||||||
|
Intent intent =new Intent (TemplateActivity2.this,About.class);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(final Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.settings_and_about, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onOptionsItemSelected(final int itemId) {
|
||||||
|
switch (itemId) {
|
||||||
|
*//*case R.id.action_settings:
|
||||||
|
final Intent intent = new Intent(this, SettingsActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
break;*//*
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected int getDefaultDeviceName() {
|
||||||
|
return R.string.template_default_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected UUID getFilterUUID() {
|
||||||
|
// TODO this method may return the UUID of the service that is required to be in the advertisement packet of a device in order to be listed on the Scanner dialog.
|
||||||
|
// If null is returned no filtering is done.
|
||||||
|
return TemplateManager.SERVICE_UUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<? extends BleProfileService> getServiceClass() {
|
||||||
|
return SPCAService.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onServiceBound(final SPCAService.TemplateBinder binder) {
|
||||||
|
// not used
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onServiceUnbound() {
|
||||||
|
// not used
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServicesDiscovered(final BluetoothDevice device, final boolean optionalServicesFound) {
|
||||||
|
// this may notify user or show some views
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceDisconnected(final BluetoothDevice device) {
|
||||||
|
super.onDeviceDisconnected(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handling updates from the device
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private void setValueOnView(@NonNull final BluetoothDevice device, final int value) {
|
||||||
|
mValueView.setText(String.valueOf(value));
|
||||||
|
|
||||||
|
// TODO assign the value to a view
|
||||||
|
if(mHeatingState.isChecked())
|
||||||
|
{
|
||||||
|
d.postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
d.setEnabled(true);
|
||||||
|
Log.d(TAG, "resend1");
|
||||||
|
}
|
||||||
|
}, 7000);
|
||||||
|
d.postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
act3_1=value;
|
||||||
|
mValueView.setText(String.valueOf(act3_1));
|
||||||
|
Log.d(TAG, "resend1");
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
d.postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
act3_2=value;
|
||||||
|
mValueView.setText(String.valueOf(act3_2));
|
||||||
|
Log.d(TAG, "resend1");
|
||||||
|
}
|
||||||
|
}, 6000);
|
||||||
|
d.postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
act3_3=value;
|
||||||
|
mValueView.setText(String.valueOf(act3_3));
|
||||||
|
Log.d(TAG, "resend1");
|
||||||
|
}
|
||||||
|
}, 7000);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/*else if (!mHeatingState.isChecked() && count ==1) {
|
||||||
|
|
||||||
|
love=1;
|
||||||
|
count=2;
|
||||||
|
Log.d("check1", String.valueOf(love));
|
||||||
|
|
||||||
|
mValueView.setText("_");
|
||||||
|
Log.d("love", String.valueOf(love));
|
||||||
|
Log.d("love", String.valueOf(p));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if ( mHeatingState.isChecked() && love ==1 )
|
||||||
|
{
|
||||||
|
q=value;
|
||||||
|
final int d=value;
|
||||||
|
Log.d("Addq", String.valueOf(q));
|
||||||
|
|
||||||
|
mValueView.setText(String.valueOf(d));
|
||||||
|
love1=1;
|
||||||
|
}
|
||||||
|
else if(!mHeatingState.isChecked() && love1 ==1)
|
||||||
|
{
|
||||||
|
love3=1;
|
||||||
|
mValueView.setText("_");
|
||||||
|
Log.d("check1", String.valueOf(love));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(mHeatingState.isChecked() && love3 ==1)
|
||||||
|
{
|
||||||
|
r=value;
|
||||||
|
mValueView.setText(String.valueOf(value));
|
||||||
|
Log.d("Addr", String.valueOf(r));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mValueView.setText("_");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public void onBatteryLevelChanged(@NonNull final BluetoothDevice device, final int value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
|
final String action = intent.getAction();
|
||||||
|
final BluetoothDevice device = intent.getParcelableExtra(SPCAService.EXTRA_DEVICE);
|
||||||
|
|
||||||
|
if (SPCAService.BROADCAST_TEMPLATE_MEASUREMENT.equals(action)) {
|
||||||
|
final int value = intent.getIntExtra(SPCAService.EXTRA_DATA, 0);
|
||||||
|
// Update GUI
|
||||||
|
setValueOnView(device, value);
|
||||||
|
} else if (SPCAService.BROADCAST_BATTERY_LEVEL.equals(action)) {
|
||||||
|
final int batteryLevel = intent.getIntExtra(SPCAService.EXTRA_BATTERY_LEVEL, 0);
|
||||||
|
// Update GUI
|
||||||
|
onBatteryLevelChanged(device, batteryLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static IntentFilter makeIntentFilter() {
|
||||||
|
final IntentFilter intentFilter = new IntentFilter();
|
||||||
|
intentFilter.addAction(SPCAService.BROADCAST_TEMPLATE_MEASUREMENT);
|
||||||
|
intentFilter.addAction(SPCAService.BROADCAST_BATTERY_LEVEL);
|
||||||
|
return intentFilter;
|
||||||
|
}
|
||||||
|
private BottomNavigationView.OnNavigationItemSelectedListener navListener =
|
||||||
|
new BottomNavigationView.OnNavigationItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
||||||
|
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.nav_home:
|
||||||
|
Intent intent = new Intent(TemplateActivity2.this, MainActivity.class);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
case R.id.nav_addtest:
|
||||||
|
Intent intent2 = new Intent(TemplateActivity2.this, TestDetails.class);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent2);
|
||||||
|
break;
|
||||||
|
case R.id.nav_add_sample:
|
||||||
|
Intent intent3 = new Intent(TemplateActivity2.this, TemplateActivity2.class);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
//super.onBackPressed();
|
||||||
|
IsFinish("Want to exit Test ?");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void IsFinish(String alertmessage) {
|
||||||
|
|
||||||
|
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
|
||||||
|
switch (which) {
|
||||||
|
case DialogInterface.BUTTON_POSITIVE:
|
||||||
|
Intent intent = new Intent(TemplateActivity2.this, TestDetails.class);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DialogInterface.BUTTON_NEGATIVE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
|
builder.setMessage(alertmessage)
|
||||||
|
.setPositiveButton("Yes", dialogClickListener)
|
||||||
|
.setNegativeButton("No", dialogClickListener).show();
|
||||||
|
AlertDialog alertDialog = builder.create();
|
||||||
|
alertDialog.show();
|
||||||
|
alertDialog.getButton(Dialog.BUTTON_NEGATIVE).setTextColor(Color.BLACK);
|
||||||
|
alertDialog.getButton(Dialog.BUTTON_POSITIVE).setTextColor(Color.BLACK);
|
||||||
|
|
||||||
|
alertDialog.getButton(Dialog.BUTTON_NEGATIVE).
|
||||||
|
setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
alertDialog.getButton(Dialog.BUTTON_POSITIVE).
|
||||||
|
setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,391 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.Switch;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.profile.BleProfileService;
|
||||||
|
import no.Reader.android.iisc.profile.BleProfileServiceReadyActivity;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify the Template Activity to match your needs.
|
||||||
|
*/
|
||||||
|
public class TemplateActivity3 extends BleProfileServiceReadyActivity<SPCAService.TemplateBinder> {
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final String TAG = "TemplateActivity";
|
||||||
|
|
||||||
|
// TODO change view references to match your need
|
||||||
|
private TextView mValueView;
|
||||||
|
private TextView mHeatingStatusView;
|
||||||
|
|
||||||
|
private Switch mHeatingState ;
|
||||||
|
int p ,q,r;
|
||||||
|
int count =0;
|
||||||
|
int love=0;
|
||||||
|
int love1=0;
|
||||||
|
int love2=0;
|
||||||
|
int love3=0;
|
||||||
|
private TextView mClockView;
|
||||||
|
int act1=0;
|
||||||
|
private Button d,next;
|
||||||
|
String value1,value2,value3;
|
||||||
|
|
||||||
|
/*private EditText mDTimeValueView;
|
||||||
|
private Integer mDSetTime ;
|
||||||
|
private EditText mLTimeValueView;
|
||||||
|
private Integer mLSetTime ;
|
||||||
|
private EditText mOTimeValueView;
|
||||||
|
private Integer mOSetTime ;
|
||||||
|
|
||||||
|
private TextView mClockView;
|
||||||
|
|
||||||
|
private EditText mATimeValueView;
|
||||||
|
private Integer mASetTime ;
|
||||||
|
private EditText mETimeValueView;
|
||||||
|
private Integer mESetTime ;
|
||||||
|
|
||||||
|
private EditText mDTempValueView;
|
||||||
|
private Integer mDSetTemp ;
|
||||||
|
private EditText mATempValueView;
|
||||||
|
private Integer mASetTemp ;
|
||||||
|
private EditText mETempValueView;
|
||||||
|
private Integer mESetTemp ;
|
||||||
|
|
||||||
|
private EditText mLTempValueView;
|
||||||
|
private Integer mLSetTemp ;
|
||||||
|
private EditText mOTempValueView;
|
||||||
|
private Integer mOSetTemp ;
|
||||||
|
|
||||||
|
private EditText mNPcrCView;
|
||||||
|
private Integer mNPcrC ;
|
||||||
|
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void onCreateView(final Bundle savedInstanceState) {
|
||||||
|
// TODO modify the layout file(s). By default the activity shows only one field - the Heart Rate value as a sample
|
||||||
|
setContentView(R.layout.activity_feature_template3);
|
||||||
|
setGUI();
|
||||||
|
SharedPreferences preferences6 = getSharedPreferences("PhoneBook", MODE_PRIVATE);
|
||||||
|
|
||||||
|
value1 = preferences6.getString("act1", null);
|
||||||
|
SharedPreferences preferences7 = getSharedPreferences("PhoneBook1", MODE_PRIVATE);
|
||||||
|
value2 = preferences7.getString("act2", null);
|
||||||
|
|
||||||
|
SharedPreferences preferences8 = getSharedPreferences("PhoneBook2", MODE_PRIVATE);
|
||||||
|
|
||||||
|
value3 = preferences8.getString("act3", null);
|
||||||
|
next.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
|
||||||
|
Intent intent =new Intent (TemplateActivity3.this,TemplateActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Log.d("value1", String.valueOf(value1));
|
||||||
|
Log.d("value2", String.valueOf(value2));
|
||||||
|
|
||||||
|
Log.d("value3", String.valueOf(value3));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void setGUI() {
|
||||||
|
// mClockView=findViewById(R.id.RemTime_Value);
|
||||||
|
|
||||||
|
// TODO assign your views to fields
|
||||||
|
// mValueView = findViewById(R.id.Temp_Value);
|
||||||
|
// d=findViewById(R.id.next);
|
||||||
|
/*mDTempValueView = findViewById(R.id.D_Temp_Set);
|
||||||
|
mDTimeValueView = findViewById(R.id.D_Time_Set);
|
||||||
|
mATempValueView = findViewById(R.id.A_Temp_Set);
|
||||||
|
mATimeValueView = findViewById(R.id.A_Time_Set);
|
||||||
|
mETempValueView = findViewById(R.id.E_Temp_Set);
|
||||||
|
mETimeValueView = findViewById(R.id.E_Time_Set);
|
||||||
|
mLTempValueView=findViewById(R.id.L_Temp_Set);
|
||||||
|
mOTempValueView=findViewById(R.id.O_Temp_Set);
|
||||||
|
mLTimeValueView = findViewById(R.id.L_Time_Set);
|
||||||
|
|
||||||
|
mOTimeValueView = findViewById(R.id.O_Time_Set);
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
mNPcrCView = findViewById(R.id.N_Pcr_C);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
mHeatingState = findViewById(R.id.heating_state);
|
||||||
|
mHeatingStatusView= findViewById(R.id.heating_status_text);
|
||||||
|
next=findViewById(R.id.next);
|
||||||
|
|
||||||
|
mHeatingState.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
|
if (isChecked) {
|
||||||
|
getService().heatingSwitch(1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* mDSetTemp = Integer.parseInt(mDTempValueView.getText().toString());
|
||||||
|
getService().sendDTemp(mDSetTemp);
|
||||||
|
mDSetTime = Integer.parseInt(mDTimeValueView.getText().toString());
|
||||||
|
getService().sendDTime(mDSetTime);
|
||||||
|
|
||||||
|
mLSetTemp = Integer.parseInt(mLTempValueView.getText().toString());
|
||||||
|
getService().sendLTemp(mLSetTemp);
|
||||||
|
mLSetTime = Integer.parseInt(mLTimeValueView.getText().toString());
|
||||||
|
getService().sendLTime(mLSetTime);
|
||||||
|
|
||||||
|
mOSetTemp = Integer.parseInt(mOTempValueView.getText().toString());
|
||||||
|
getService().sendOTemp(mOSetTemp);
|
||||||
|
mOSetTime = Integer.parseInt(mOTimeValueView.getText().toString());
|
||||||
|
getService().sendOTime(mOSetTime);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Log.d("Add", String.valueOf(m));
|
||||||
|
|
||||||
|
mASetTemp = Integer.parseInt(mATempValueView.getText().toString());
|
||||||
|
getService().sendATemp(mASetTemp);
|
||||||
|
mASetTime = Integer.parseInt(mATimeValueView.getText().toString());
|
||||||
|
getService().sendATime(mASetTime);
|
||||||
|
|
||||||
|
mESetTemp = Integer.parseInt(mETempValueView.getText().toString());
|
||||||
|
getService().sendETemp(mESetTemp);
|
||||||
|
mESetTime = Integer.parseInt(mETimeValueView.getText().toString());
|
||||||
|
getService().sendETime(mESetTime);
|
||||||
|
|
||||||
|
mNPcrC = Integer.parseInt(mNPcrCView.getText().toString());
|
||||||
|
getService().sendNPcrN(mNPcrC);
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
getService().heatingSwitch(0);
|
||||||
|
}
|
||||||
|
mHeatingStatusView.setText(isChecked ? R.string.Heating_block_on : R.string.Heating_block_off);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/*findViewById(R.id.time_set_button).setOnClickListener(v -> {
|
||||||
|
if (isDeviceConnected()) {
|
||||||
|
|
||||||
|
mSetTime = Integer.parseInt(mTimeValueView.getText().toString());
|
||||||
|
getService().sendTimeDuration(mSetTime);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
findViewById(R.id.temp_set_button).setOnClickListener(v -> {
|
||||||
|
if (isDeviceConnected()) {
|
||||||
|
mSetTemp = Integer.parseInt(mTempValueView.getText().toString());
|
||||||
|
getService().sendTemp(mSetTemp);
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onInitialize(final Bundle savedInstanceState) {
|
||||||
|
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, makeIntentFilter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
LocalBroadcastManager.getInstance(this).unregisterReceiver(mBroadcastReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setDefaultUI() {
|
||||||
|
// TODO clear your UI
|
||||||
|
mValueView.setText(R.string.not_available_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getLoggerProfileTitle() {
|
||||||
|
return R.string.template_feature_title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@Override
|
||||||
|
protected void getAboutTextId() {
|
||||||
|
Intent intent =new Intent (TemplateActivity3.this,About.class);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(final Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.settings_and_about, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onOptionsItemSelected(final int itemId) {
|
||||||
|
switch (itemId) {
|
||||||
|
*//*case R.id.action_settings:
|
||||||
|
final Intent intent = new Intent(this, SettingsActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
break;*//*
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected int getDefaultDeviceName() {
|
||||||
|
return R.string.template_default_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected UUID getFilterUUID() {
|
||||||
|
// TODO this method may return the UUID of the service that is required to be in the advertisement packet of a device in order to be listed on the Scanner dialog.
|
||||||
|
// If null is returned no filtering is done.
|
||||||
|
return TemplateManager.SERVICE_UUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<? extends BleProfileService> getServiceClass() {
|
||||||
|
return SPCAService.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onServiceBound(final SPCAService.TemplateBinder binder) {
|
||||||
|
// not used
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onServiceUnbound() {
|
||||||
|
// not used
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServicesDiscovered(final BluetoothDevice device, final boolean optionalServicesFound) {
|
||||||
|
// this may notify user or show some views
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceDisconnected(final BluetoothDevice device) {
|
||||||
|
super.onDeviceDisconnected(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handling updates from the device
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private void setValueOnView(@NonNull final BluetoothDevice device, final int value) {
|
||||||
|
// TODO assign the value to a view
|
||||||
|
if(mHeatingState.isChecked())
|
||||||
|
{
|
||||||
|
act1=value;
|
||||||
|
mValueView.setText(String.valueOf(act1));
|
||||||
|
|
||||||
|
}
|
||||||
|
/*else if (!mHeatingState.isChecked() && count ==1) {
|
||||||
|
|
||||||
|
love=1;
|
||||||
|
count=2;
|
||||||
|
Log.d("check1", String.valueOf(love));
|
||||||
|
|
||||||
|
mValueView.setText("_");
|
||||||
|
Log.d("love", String.valueOf(love));
|
||||||
|
Log.d("love", String.valueOf(p));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if ( mHeatingState.isChecked() && love ==1 )
|
||||||
|
{
|
||||||
|
q=value;
|
||||||
|
final int d=value;
|
||||||
|
Log.d("Addq", String.valueOf(q));
|
||||||
|
|
||||||
|
mValueView.setText(String.valueOf(d));
|
||||||
|
love1=1;
|
||||||
|
}
|
||||||
|
else if(!mHeatingState.isChecked() && love1 ==1)
|
||||||
|
{
|
||||||
|
love3=1;
|
||||||
|
mValueView.setText("_");
|
||||||
|
Log.d("check1", String.valueOf(love));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(mHeatingState.isChecked() && love3 ==1)
|
||||||
|
{
|
||||||
|
r=value;
|
||||||
|
mValueView.setText(String.valueOf(value));
|
||||||
|
Log.d("Addr", String.valueOf(r));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mValueView.setText("_");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public void onBatteryLevelChanged(@NonNull final BluetoothDevice device, final int value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
|
final String action = intent.getAction();
|
||||||
|
final BluetoothDevice device = intent.getParcelableExtra(SPCAService.EXTRA_DEVICE);
|
||||||
|
|
||||||
|
if (SPCAService.BROADCAST_TEMPLATE_MEASUREMENT.equals(action)) {
|
||||||
|
final int value = intent.getIntExtra(SPCAService.EXTRA_DATA, 0);
|
||||||
|
// Update GUI
|
||||||
|
setValueOnView(device, value);
|
||||||
|
} else if (SPCAService.BROADCAST_BATTERY_LEVEL.equals(action)) {
|
||||||
|
final int batteryLevel = intent.getIntExtra(SPCAService.EXTRA_BATTERY_LEVEL, 0);
|
||||||
|
// Update GUI
|
||||||
|
onBatteryLevelChanged(device, batteryLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static IntentFilter makeIntentFilter() {
|
||||||
|
final IntentFilter intentFilter = new IntentFilter();
|
||||||
|
intentFilter.addAction(SPCAService.BROADCAST_TEMPLATE_MEASUREMENT);
|
||||||
|
intentFilter.addAction(SPCAService.BROADCAST_BATTERY_LEVEL);
|
||||||
|
return intentFilter;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,959 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.bluetooth.BluetoothGatt;
|
||||||
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
|
import android.bluetooth.BluetoothGattService;
|
||||||
|
import android.content.Context;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.ble.BleManager;
|
||||||
|
import no.nordicsemi.android.ble.data.Data;
|
||||||
|
import no.nordicsemi.android.log.LogContract;
|
||||||
|
import no.Reader.android.iisc.battery.BatteryManager;
|
||||||
|
import no.Reader.android.iisc.parser.SPCAParser;
|
||||||
|
import no.Reader.android.iisc.Reader.callback.SPCADataCallback;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify to template manager to match your requirements.
|
||||||
|
* The TemplateManager extends {@link BatteryManager}, but it may easily extend {@link BleManager}
|
||||||
|
* instead if you don't need Battery Service support. If not, also modify the
|
||||||
|
* {@link SPCAManagerCallbacks} to extend {@link no.nordicsemi.android.ble.BleManagerCallbacks}
|
||||||
|
* and replace BatteryManagerGattCallback to BleManagerGattCallback in this class.
|
||||||
|
*/
|
||||||
|
public class TemplateManager extends BatteryManager<SPCAManagerCallbacks> {
|
||||||
|
// TODO Replace the services and characteristics below to match your device.
|
||||||
|
/**
|
||||||
|
* The service UUID.
|
||||||
|
*/
|
||||||
|
/*static final UUID SERVICE_UUID = UUID.fromString("00001500-1212-efde-1523-785feabcd123"); // Heart Rate service
|
||||||
|
*//**
|
||||||
|
* A UUID of a characteristic with notify property.
|
||||||
|
*//*
|
||||||
|
//private static final UUID MEASUREMENT_CHARACTERISTIC_UUID = UUID.fromString("00001501-1212-efde-1523-785feabcd123"); // Heart Rate Measurement
|
||||||
|
//private static final UUID TEMPERATURE_CHARACTERISTIC_UUID = UUID.fromString("00001501-1212-efde-1523-785feabcd123"); // Heart Rate Measurement
|
||||||
|
*//**
|
||||||
|
* A UUID of a characteristic with read property.
|
||||||
|
*//*
|
||||||
|
//private static final UUID READABLE_CHARACTERISTIC_UUID = UUID.fromString("00001502-1212-efde-1523-785feabcd123"); // Body Sensor Location
|
||||||
|
private static final UUID TEMP_READABLE_CHARACTERISTIC_UUID = UUID.fromString("00001501-1212-efde-1523-785feabcd123"); // Body Sensor Location
|
||||||
|
|
||||||
|
*//**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*//*
|
||||||
|
private static final UUID D_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001503-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID A_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001504-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID E_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001505-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID L_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001514-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID O_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001502-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
|
||||||
|
*//**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*//*
|
||||||
|
private static final UUID D_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001509-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID A_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001510-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID E_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001511-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID L_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001515-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID O_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001508-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
|
||||||
|
private static final UUID N_PCR_C_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001512-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
*//**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*//*
|
||||||
|
private static final UUID AMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001513-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
*//**
|
||||||
|
* Some other service UUID.
|
||||||
|
*//*
|
||||||
|
private static final UUID OTHER_SERVICE_UUID = UUID.fromString("00001800-0000-1000-8000-00805f9b34fb"); // Generic Access service
|
||||||
|
*//**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*//*
|
||||||
|
private static final UUID READABLE_CHARACTERISTIC_UUID = UUID.fromString("00001801-0000-1000-8000-00805f9b34fb"); // Device Name
|
||||||
|
*/
|
||||||
|
|
||||||
|
static final UUID SERVICE_UUID = UUID.fromString("00001600-1212-efde-1523-785feabcd123"); // Heart Rate service
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with notify property.
|
||||||
|
*/
|
||||||
|
//private static final UUID MEASUREMENT_CHARACTERISTIC_UUID = UUID.fromString("00001501-1212-efde-1523-785feabcd123"); // Heart Rate Measurement
|
||||||
|
//private static final UUID TEMPERATURE_CHARACTERISTIC_UUID = UUID.fromString("00001501-1212-efde-1523-785feabcd123"); // Heart Rate Measurement
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with read property.
|
||||||
|
*/
|
||||||
|
//private static final UUID READABLE_CHARACTERISTIC_UUID = UUID.fromString("00001502-1212-efde-1523-785feabcd123"); // Body Sensor Location
|
||||||
|
private static final UUID TEMP_READABLE_CHARACTERISTIC_UUID = UUID.fromString("00001601-1212-efde-1523-785feabcd123"); // Body Sensor Location
|
||||||
|
private static final UUID CLOCK_READABLE_CHARACTERISTIC_UUID = UUID.fromString("00001604-1212-efde-1523-785feabcd123"); // Body Sensor Location
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*/
|
||||||
|
private static final UUID D_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001604-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID A_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001604-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID E_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001604-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID L_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001604-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID O_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001604-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID S_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001604-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*/
|
||||||
|
private static final UUID D_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001604-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID A_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001604-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID E_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001604-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID L_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001604-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID O_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001604-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
private static final UUID S_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001604-1212-efde-1523-785feabcd123"); // Device Name00001604-1212-efde-1523-785feabcd123
|
||||||
|
|
||||||
|
private static final UUID N_PCR_C_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001604-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*/
|
||||||
|
private static final UUID AMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001604-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some other service UUID.
|
||||||
|
*/
|
||||||
|
private static final UUID OTHER_SERVICE_UUID = UUID.fromString("00001800-0000-1000-8000-00805f9b34fb"); // Generic Access service
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*/
|
||||||
|
private static final UUID READABLE_CHARACTERISTIC_UUID = UUID.fromString("00001801-0000-1000-8000-00805f9b34fb"); // Device Name
|
||||||
|
|
||||||
|
// TODO Add more services and characteristics references.
|
||||||
|
|
||||||
|
private BluetoothGattCharacteristic mReadBlockTempCharacteristic, mSetDTempCharacteristic, mSetDTimeCharacteristic, mSetATempCharacteristic, mSetATimeCharacteristic, mSetETempCharacteristic, mSetETimeCharacteristic, mSetNPcrCCharacteristic, mAmpStartStopCharacteristic, mDeviceNameCharacteristic, mRequiredCharacteristic, mOptionalCharacteristic
|
||||||
|
,mSetLTempCharacteristic,mSetOTempCharacteristic,mSetLTimeCharacteristic,mSetOTimeCharacteristic;
|
||||||
|
|
||||||
|
public TemplateManager(final Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
protected BatteryManagerGattCallback getGattCallback() {
|
||||||
|
return mGattCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BluetoothGatt callbacks for connection/disconnection, service discovery,
|
||||||
|
* receiving indication, etc.
|
||||||
|
*/
|
||||||
|
private final BatteryManagerGattCallback mGattCallback = new BatteryManagerGattCallback() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initialize() {
|
||||||
|
// Initialize the Battery Manager. It will enable Battery Level notifications.
|
||||||
|
// Remove it if you don't need this feature.
|
||||||
|
super.initialize();
|
||||||
|
|
||||||
|
// TODO Initialize your manager here.
|
||||||
|
// Initialization is done once, after the device is connected. Usually it should
|
||||||
|
// enable notifications or indications on some characteristics, write some data or
|
||||||
|
// read some features / version.
|
||||||
|
// After the initialization is complete, the onDeviceReady(...) method will be called.
|
||||||
|
|
||||||
|
// Increase the MTU
|
||||||
|
requestMtu(43)//requestMtu(43)
|
||||||
|
.with((device, mtu) -> log(LogContract.Log.Level.APPLICATION, "MTU changed to " + mtu))
|
||||||
|
.done(device -> {
|
||||||
|
// You may do some logic in here that should be done when the request finished successfully.
|
||||||
|
// In case of MTU this method is called also when the MTU hasn't changed, or has changed
|
||||||
|
// to a different (lower) value. Use .with(...) to get the MTU value.
|
||||||
|
})
|
||||||
|
.fail((device, status) -> log(Log.WARN, "MTU change not supported"))
|
||||||
|
.enqueue();
|
||||||
|
|
||||||
|
// Set notification callback
|
||||||
|
setNotificationCallback(mReadBlockTempCharacteristic)
|
||||||
|
// This callback will be called each time the notification is received
|
||||||
|
.with(new SPCADataCallback() {
|
||||||
|
@Override
|
||||||
|
public void onDataReceived(@NonNull final BluetoothDevice device, @NonNull final Data data) {
|
||||||
|
if(data!=null) {
|
||||||
|
log(LogContract.Log.Level.APPLICATION, SPCAParser.parse(data));
|
||||||
|
|
||||||
|
super.onDataReceived(device, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSampleValueReceived(@NonNull final BluetoothDevice device, final int value) {
|
||||||
|
// Let's lass received data to the service
|
||||||
|
mCallbacks.onSampleValueReceived(device, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInvalidDataReceived(@NonNull final BluetoothDevice device, @NonNull final Data data) {
|
||||||
|
log(Log.WARN, "Invalid data received: " + data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Enable notifications
|
||||||
|
enableNotifications(mReadBlockTempCharacteristic)
|
||||||
|
// Method called after the data were sent (data will contain 0x0100 in this case)
|
||||||
|
.with((device, data) -> log(Log.DEBUG, "Data sent: " + data))
|
||||||
|
// Method called when the request finished successfully. This will be called after .with(..) callback
|
||||||
|
.done(device -> log(LogContract.Log.Level.APPLICATION, "Notifications enabled successfully"))
|
||||||
|
// Methods called in case of an error, for example when the characteristic does not have Notify property
|
||||||
|
.fail((device, status) -> log(Log.WARN, "Failed to enable notifications"))
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isRequiredServiceSupported(@NonNull final BluetoothGatt gatt) {
|
||||||
|
// TODO Initialize required characteristics.
|
||||||
|
// It should return true if all has been discovered (that is that device is supported).
|
||||||
|
final BluetoothGattService service = gatt.getService(SERVICE_UUID);
|
||||||
|
if (service != null) {
|
||||||
|
mReadBlockTempCharacteristic = service.getCharacteristic(TEMP_READABLE_CHARACTERISTIC_UUID);
|
||||||
|
|
||||||
|
mSetDTempCharacteristic = service.getCharacteristic(D_TEMP_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetDTimeCharacteristic = service.getCharacteristic(D_TIME_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetATempCharacteristic = service.getCharacteristic(A_TEMP_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetATimeCharacteristic = service.getCharacteristic(A_TIME_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetETempCharacteristic = service.getCharacteristic(E_TEMP_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetETimeCharacteristic = service.getCharacteristic(E_TIME_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
|
||||||
|
mSetLTempCharacteristic = service.getCharacteristic(L_TEMP_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetLTimeCharacteristic = service.getCharacteristic(L_TIME_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetOTempCharacteristic = service.getCharacteristic(O_TEMP_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetOTimeCharacteristic = service.getCharacteristic(O_TIME_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
|
||||||
|
|
||||||
|
mSetNPcrCCharacteristic = service.getCharacteristic(N_PCR_C_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
|
||||||
|
mAmpStartStopCharacteristic = service.getCharacteristic(AMP_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
}
|
||||||
|
final BluetoothGattService otherService = gatt.getService(OTHER_SERVICE_UUID);
|
||||||
|
if (otherService != null) {
|
||||||
|
mDeviceNameCharacteristic = otherService.getCharacteristic(READABLE_CHARACTERISTIC_UUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mReadBlockTempCharacteristic != null && mSetDTempCharacteristic != null && mSetDTimeCharacteristic!= null && mSetATempCharacteristic != null && mSetATimeCharacteristic!= null && mSetETempCharacteristic != null && mSetLTempCharacteristic != null && mSetETimeCharacteristic!= null && mSetOTempCharacteristic != null && mSetLTimeCharacteristic!= null && mSetOTimeCharacteristic!= null && mSetNPcrCCharacteristic!= null && mAmpStartStopCharacteristic != null ;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isOptionalServiceSupported(@NonNull final BluetoothGatt gatt) {
|
||||||
|
// Initialize Battery characteristic
|
||||||
|
super.isOptionalServiceSupported(gatt);
|
||||||
|
|
||||||
|
// TODO If there are some optional characteristics, initialize them there.
|
||||||
|
final BluetoothGattService service = gatt.getService(SERVICE_UUID);
|
||||||
|
if (service != null) {
|
||||||
|
mOptionalCharacteristic = service.getCharacteristic(READABLE_CHARACTERISTIC_UUID);
|
||||||
|
}
|
||||||
|
return mOptionalCharacteristic != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDeviceDisconnected() {
|
||||||
|
// Release Battery Service
|
||||||
|
super.onDeviceDisconnected();
|
||||||
|
|
||||||
|
// TODO Release references to your characteristics.
|
||||||
|
mRequiredCharacteristic = null;
|
||||||
|
mDeviceNameCharacteristic = null;
|
||||||
|
mOptionalCharacteristic = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDeviceReady() {
|
||||||
|
super.onDeviceReady();
|
||||||
|
|
||||||
|
// Initialization is now ready.
|
||||||
|
// The service or activity has been notified with no.nordicsemi.android.ble.BatteryManagerCallbacks#onDeviceReady().
|
||||||
|
// TODO Do some extra logic here, of remove onDeviceReady().
|
||||||
|
|
||||||
|
// Device is ready, let's read something here. Usually there is nothing else to be done
|
||||||
|
// here, as all had been done during initialization.
|
||||||
|
readCharacteristic(mReadBlockTempCharacteristic)
|
||||||
|
.with((device, data) -> {
|
||||||
|
// Characteristic value has been read
|
||||||
|
// Let's do some magic with it.
|
||||||
|
if (data.size() > 0) {
|
||||||
|
final Integer value = data.getIntValue(Data.FORMAT_UINT8, 0);
|
||||||
|
log(LogContract.Log.Level.APPLICATION, "Value '" + value + "' has been read!");
|
||||||
|
} else {
|
||||||
|
log(Log.WARN, "Value is empty!");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO Define manager's API
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will write important data to the device.
|
||||||
|
*
|
||||||
|
* @param parameter parameter to be written.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//Heating Switch
|
||||||
|
void heatingSwitch(int state) {
|
||||||
|
log(Log.WARN, "Write time duration \"" + state + "\"");
|
||||||
|
//final byte time_in_byte = time_duration.getBytes()[0];
|
||||||
|
final byte state_in_byte = (byte) state;
|
||||||
|
writeCharacteristic(mAmpStartStopCharacteristic, Data.opCode(state_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Heating State"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set Time
|
||||||
|
void sendDTime(int d_time) {
|
||||||
|
log(Log.WARN, "Write D Time Duration \"" + d_time + "\"");
|
||||||
|
final byte d_time_in_byte = (byte) d_time;
|
||||||
|
writeCharacteristic(mSetDTimeCharacteristic, Data.opCode(d_time_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Time"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
void sendATime(int a_time) {
|
||||||
|
log(Log.WARN, "Write A Time Duration \"" + a_time + "\"");
|
||||||
|
final byte a_time_in_byte = (byte) a_time;
|
||||||
|
writeCharacteristic(mSetATimeCharacteristic, Data.opCode(a_time_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Time"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendLTime(int l_time) {
|
||||||
|
log(Log.WARN, "Write A Time Duration \"" + l_time + "\"");
|
||||||
|
final byte l_time_in_byte = (byte) l_time;
|
||||||
|
writeCharacteristic(mSetLTimeCharacteristic, Data.opCode(l_time_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Time"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
void sendOTime(int o_time) {
|
||||||
|
log(Log.WARN, "Write A Time Duration \"" + o_time + "\"");
|
||||||
|
final byte a_time_in_byte = (byte) o_time;
|
||||||
|
writeCharacteristic(mSetOTimeCharacteristic, Data.opCode(a_time_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Time"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void sendETime(int e_time) {
|
||||||
|
log(Log.WARN, "Write E Time Duration \"" + e_time + "\"");
|
||||||
|
final byte e_time_in_byte = (byte) e_time;
|
||||||
|
writeCharacteristic(mSetETimeCharacteristic, Data.opCode(e_time_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Time"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Set Temp
|
||||||
|
void sendDTemp(int d_temp) {
|
||||||
|
log(Log.WARN, "Write D temp \"" + d_temp + "\"");
|
||||||
|
final byte d_temp_in_byte = (byte) d_temp;
|
||||||
|
writeCharacteristic(mSetDTempCharacteristic, Data.opCode(d_temp_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Temp"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
void sendLTemp(int l_temp) {
|
||||||
|
log(Log.WARN, "Write D temp \"" + l_temp + "\"");
|
||||||
|
final byte d_temp_in_byte = (byte) l_temp;
|
||||||
|
writeCharacteristic(mSetLTempCharacteristic, Data.opCode(d_temp_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Temp"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendOTemp(int o_temp) {
|
||||||
|
log(Log.WARN, "Write D temp \"" + o_temp + "\"");
|
||||||
|
final byte d_temp_in_byte = (byte) o_temp;
|
||||||
|
writeCharacteristic(mSetOTempCharacteristic, Data.opCode(d_temp_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Temp"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void sendATemp(int a_temp) {
|
||||||
|
log(Log.WARN, "Write A temp \"" + a_temp + "\"");
|
||||||
|
final byte a_temp_in_byte = (byte) a_temp;
|
||||||
|
writeCharacteristic(mSetATempCharacteristic, Data.opCode(a_temp_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Temp"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
void sendETemp(int e_temp) {
|
||||||
|
log(Log.WARN, "Write E temp \"" + e_temp + "\"");
|
||||||
|
final byte e_temp_in_byte = (byte) e_temp;
|
||||||
|
writeCharacteristic(mSetETempCharacteristic, Data.opCode(e_temp_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Temp"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendNPcrC(int n_pcr_c) {
|
||||||
|
log(Log.WARN, "Write E temp \"" + n_pcr_c + "\"");
|
||||||
|
final byte n_pcr_c_in_byte = (byte) n_pcr_c;
|
||||||
|
writeCharacteristic(mSetNPcrCCharacteristic, Data.opCode(n_pcr_c_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Temp"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015, Nordic Semiconductor
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*//*
|
||||||
|
|
||||||
|
package no.Reader.android.iisc.template;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.bluetooth.BluetoothGatt;
|
||||||
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
|
import android.bluetooth.BluetoothGattService;
|
||||||
|
import android.content.Context;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.ble.BleManager;
|
||||||
|
import no.nordicsemi.android.ble.data.Data;
|
||||||
|
import no.nordicsemi.android.log.LogContract;
|
||||||
|
import no.Reader.android.iisc.battery.BatteryManager;
|
||||||
|
import no.Reader.android.iisc.parser.SPCAParser;
|
||||||
|
import no.Reader.android.iisc.template.callback.SPCADataCallback;
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Modify to template manager to match your requirements.
|
||||||
|
* The TemplateManager extends {@link BatteryManager}, but it may easily extend {@link BleManager}
|
||||||
|
* instead if you don't need Battery Service support. If not, also modify the
|
||||||
|
* {@link TemplateManagerCallbacks} to extend {@link no.nordicsemi.android.ble.BleManagerCallbacks}
|
||||||
|
* and replace BatteryManagerGattCallback to BleManagerGattCallback in this class.
|
||||||
|
*//*
|
||||||
|
|
||||||
|
public class TemplateManager extends BatteryManager<SPCAManagerCallbacks> {
|
||||||
|
// TODO Replace the services and characteristics below to match your device.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* The service UUID.
|
||||||
|
*//*
|
||||||
|
|
||||||
|
*/
|
||||||
|
/*static final UUID SERVICE_UUID = UUID.fromString("00001500-1212-efde-1523-785feabcd123"); // Heart Rate service
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with notify property.
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
//private static final UUID MEASUREMENT_CHARACTERISTIC_UUID = UUID.fromString("00001501-1212-efde-1523-785feabcd123"); // Heart Rate Measurement
|
||||||
|
//private static final UUID TEMPERATURE_CHARACTERISTIC_UUID = UUID.fromString("00001501-1212-efde-1523-785feabcd123"); // Heart Rate Measurement
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with read property.
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
//private static final UUID READABLE_CHARACTERISTIC_UUID = UUID.fromString("00001502-1212-efde-1523-785feabcd123"); // Body Sensor Location
|
||||||
|
private static final UUID TEMP_READABLE_CHARACTERISTIC_UUID = UUID.fromString("00001501-1212-efde-1523-785feabcd123"); // Body Sensor Location
|
||||||
|
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
private static final UUID D_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001503-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID A_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001504-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID E_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001505-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID L_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001514-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID O_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001502-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
private static final UUID D_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001509-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID A_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001510-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID E_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001511-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID L_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001515-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID O_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001508-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
|
||||||
|
private static final UUID N_PCR_C_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001512-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
private static final UUID AMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001513-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Some other service UUID.
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
private static final UUID OTHER_SERVICE_UUID = UUID.fromString("00001800-0000-1000-8000-00805f9b34fb"); // Generic Access service
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
private static final UUID READABLE_CHARACTERISTIC_UUID = UUID.fromString("00001801-0000-1000-8000-00805f9b34fb"); // Device Name
|
||||||
|
*//*
|
||||||
|
|
||||||
|
|
||||||
|
static final UUID SERVICE_UUID = UUID.fromString("00001500-1212-efde-1523-785feabcd123"); // Heart Rate service
|
||||||
|
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with notify property.
|
||||||
|
*//*
|
||||||
|
|
||||||
|
//private static final UUID MEASUREMENT_CHARACTERISTIC_UUID = UUID.fromString("00001501-1212-efde-1523-785feabcd123"); // Heart Rate Measurement
|
||||||
|
//private static final UUID TEMPERATURE_CHARACTERISTIC_UUID = UUID.fromString("00001501-1212-efde-1523-785feabcd123"); // Heart Rate Measurement
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with read property.
|
||||||
|
*//*
|
||||||
|
|
||||||
|
//private static final UUID READABLE_CHARACTERISTIC_UUID = UUID.fromString("00001502-1212-efde-1523-785feabcd123"); // Body Sensor Location
|
||||||
|
private static final UUID TEMP_READABLE_CHARACTERISTIC_UUID = UUID.fromString("00001514-1212-efde-1523-785feabcd123"); // Body Sensor Location
|
||||||
|
private static final UUID CLOCK_READABLE_CHARACTERISTIC_UUID = UUID.fromString("00001514-1212-efde-1523-785feabcd123"); // Body Sensor Location
|
||||||
|
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*//*
|
||||||
|
|
||||||
|
private static final UUID D_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001504-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID A_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001506-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID E_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001508-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID L_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001515-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID O_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001502-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID S_TEMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001510-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*//*
|
||||||
|
|
||||||
|
private static final UUID D_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001505-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID A_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001507-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID E_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001509-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID L_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001516-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
private static final UUID O_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001503-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
private static final UUID S_TIME_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001511-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
private static final UUID N_PCR_C_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001512-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*//*
|
||||||
|
|
||||||
|
private static final UUID AMP_WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00001513-1212-efde-1523-785feabcd123"); // Device Name
|
||||||
|
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Some other service UUID.
|
||||||
|
*//*
|
||||||
|
|
||||||
|
private static final UUID OTHER_SERVICE_UUID = UUID.fromString("00001800-0000-1000-8000-00805f9b34fb"); // Generic Access service
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* A UUID of a characteristic with write property.
|
||||||
|
*//*
|
||||||
|
|
||||||
|
private static final UUID READABLE_CHARACTERISTIC_UUID = UUID.fromString("00001801-0000-1000-8000-00805f9b34fb"); // Device Name
|
||||||
|
|
||||||
|
// TODO Add more services and characteristics references.
|
||||||
|
|
||||||
|
private BluetoothGattCharacteristic mReadBlockTempCharacteristic, mSetDTempCharacteristic, mSetDTimeCharacteristic, mSetATempCharacteristic, mSetATimeCharacteristic, mSetETempCharacteristic, mSetETimeCharacteristic, mSetNPcrCCharacteristic, mAmpStartStopCharacteristic, mDeviceNameCharacteristic, mRequiredCharacteristic, mOptionalCharacteristic
|
||||||
|
,mSetLTempCharacteristic,mSetOTempCharacteristic,mSetLTimeCharacteristic,mSetOTimeCharacteristic;
|
||||||
|
|
||||||
|
public TemplateManager(final Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
protected BatteryManagerGattCallback getGattCallback() {
|
||||||
|
return mGattCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* BluetoothGatt callbacks for connection/disconnection, service discovery,
|
||||||
|
* receiving indication, etc.
|
||||||
|
*//*
|
||||||
|
|
||||||
|
private final BatteryManagerGattCallback mGattCallback = new BatteryManagerGattCallback() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initialize() {
|
||||||
|
// Initialize the Battery Manager. It will enable Battery Level notifications.
|
||||||
|
// Remove it if you don't need this feature.
|
||||||
|
super.initialize();
|
||||||
|
|
||||||
|
// TODO Initialize your manager here.
|
||||||
|
// Initialization is done once, after the device is connected. Usually it should
|
||||||
|
// enable notifications or indications on some characteristics, write some data or
|
||||||
|
// read some features / version.
|
||||||
|
// After the initialization is complete, the onDeviceReady(...) method will be called.
|
||||||
|
|
||||||
|
// Increase the MTU
|
||||||
|
requestMtu(43)//requestMtu(43)
|
||||||
|
.with((device, mtu) -> log(LogContract.Log.Level.APPLICATION, "MTU changed to " + mtu))
|
||||||
|
.done(device -> {
|
||||||
|
// You may do some logic in here that should be done when the request finished successfully.
|
||||||
|
// In case of MTU this method is called also when the MTU hasn't changed, or has changed
|
||||||
|
// to a different (lower) value. Use .with(...) to get the MTU value.
|
||||||
|
})
|
||||||
|
.fail((device, status) -> log(Log.WARN, "MTU change not supported"))
|
||||||
|
.enqueue();
|
||||||
|
|
||||||
|
// Set notification callback
|
||||||
|
setNotificationCallback(mReadBlockTempCharacteristic)
|
||||||
|
// This callback will be called each time the notification is received
|
||||||
|
.with(new SPCADataCallback() {
|
||||||
|
@Override
|
||||||
|
public void onDataReceived(@NonNull final BluetoothDevice device, @NonNull final Data data) {
|
||||||
|
log(LogContract.Log.Level.APPLICATION, SPCAParser.parse(data));
|
||||||
|
super.onDataReceived(device, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSampleValueReceived(@NonNull final BluetoothDevice device, final int value) {
|
||||||
|
// Let's lass received data to the service
|
||||||
|
mCallbacks.onSampleValueReceived(device, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInvalidDataReceived(@NonNull final BluetoothDevice device, @NonNull final Data data) {
|
||||||
|
log(Log.WARN, "Invalid data received: " + data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Enable notifications
|
||||||
|
enableNotifications(mReadBlockTempCharacteristic)
|
||||||
|
// Method called after the data were sent (data will contain 0x0100 in this case)
|
||||||
|
.with((device, data) -> log(Log.DEBUG, "Data sent: " + data))
|
||||||
|
// Method called when the request finished successfully. This will be called after .with(..) callback
|
||||||
|
.done(device -> log(LogContract.Log.Level.APPLICATION, "Notifications enabled successfully"))
|
||||||
|
// Methods called in case of an error, for example when the characteristic does not have Notify property
|
||||||
|
.fail((device, status) -> log(Log.WARN, "Failed to enable notifications"))
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isRequiredServiceSupported(@NonNull final BluetoothGatt gatt) {
|
||||||
|
// TODO Initialize required characteristics.
|
||||||
|
// It should return true if all has been discovered (that is that device is supported).
|
||||||
|
final BluetoothGattService service = gatt.getService(SERVICE_UUID);
|
||||||
|
if (service != null) {
|
||||||
|
mReadBlockTempCharacteristic = service.getCharacteristic(TEMP_READABLE_CHARACTERISTIC_UUID);
|
||||||
|
|
||||||
|
mSetDTempCharacteristic = service.getCharacteristic(D_TEMP_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetDTimeCharacteristic = service.getCharacteristic(D_TIME_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetATempCharacteristic = service.getCharacteristic(A_TEMP_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetATimeCharacteristic = service.getCharacteristic(A_TIME_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetETempCharacteristic = service.getCharacteristic(E_TEMP_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetETimeCharacteristic = service.getCharacteristic(E_TIME_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
|
||||||
|
mSetLTempCharacteristic = service.getCharacteristic(L_TEMP_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetLTimeCharacteristic = service.getCharacteristic(L_TIME_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetOTempCharacteristic = service.getCharacteristic(O_TEMP_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
mSetOTimeCharacteristic = service.getCharacteristic(O_TIME_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
|
||||||
|
|
||||||
|
mSetNPcrCCharacteristic = service.getCharacteristic(N_PCR_C_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
|
||||||
|
mAmpStartStopCharacteristic = service.getCharacteristic(AMP_WRITABLE_CHARACTERISTIC_UUID);
|
||||||
|
}
|
||||||
|
final BluetoothGattService otherService = gatt.getService(OTHER_SERVICE_UUID);
|
||||||
|
if (otherService != null) {
|
||||||
|
mDeviceNameCharacteristic = otherService.getCharacteristic(READABLE_CHARACTERISTIC_UUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mReadBlockTempCharacteristic != null && mSetDTempCharacteristic != null && mSetDTimeCharacteristic!= null && mSetATempCharacteristic != null && mSetATimeCharacteristic!= null && mSetETempCharacteristic != null && mSetLTempCharacteristic != null && mSetETimeCharacteristic!= null && mSetOTempCharacteristic != null && mSetLTimeCharacteristic!= null && mSetOTimeCharacteristic!= null && mSetNPcrCCharacteristic!= null && mAmpStartStopCharacteristic != null ;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isOptionalServiceSupported(@NonNull final BluetoothGatt gatt) {
|
||||||
|
// Initialize Battery characteristic
|
||||||
|
super.isOptionalServiceSupported(gatt);
|
||||||
|
|
||||||
|
// TODO If there are some optional characteristics, initialize them there.
|
||||||
|
final BluetoothGattService service = gatt.getService(SERVICE_UUID);
|
||||||
|
if (service != null) {
|
||||||
|
mOptionalCharacteristic = service.getCharacteristic(READABLE_CHARACTERISTIC_UUID);
|
||||||
|
}
|
||||||
|
return mOptionalCharacteristic != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDeviceDisconnected() {
|
||||||
|
// Release Battery Service
|
||||||
|
super.onDeviceDisconnected();
|
||||||
|
|
||||||
|
// TODO Release references to your characteristics.
|
||||||
|
mRequiredCharacteristic = null;
|
||||||
|
mDeviceNameCharacteristic = null;
|
||||||
|
mOptionalCharacteristic = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDeviceReady() {
|
||||||
|
super.onDeviceReady();
|
||||||
|
|
||||||
|
// Initialization is now ready.
|
||||||
|
// The service or activity has been notified with no.nordicsemi.android.ble.BatteryManagerCallbacks#onDeviceReady().
|
||||||
|
// TODO Do some extra logic here, of remove onDeviceReady().
|
||||||
|
|
||||||
|
// Device is ready, let's read something here. Usually there is nothing else to be done
|
||||||
|
// here, as all had been done during initialization.
|
||||||
|
readCharacteristic(mReadBlockTempCharacteristic)
|
||||||
|
.with((device, data) -> {
|
||||||
|
// Characteristic value has been read
|
||||||
|
// Let's do some magic with it.
|
||||||
|
if (data.size() > 0) {
|
||||||
|
final Integer value = data.getIntValue(Data.FORMAT_UINT8, 0);
|
||||||
|
log(LogContract.Log.Level.APPLICATION, "Value '" + value + "' has been read!");
|
||||||
|
} else {
|
||||||
|
log(Log.WARN, "Value is empty!");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO Define manager's API
|
||||||
|
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* This method will write important data to the device.
|
||||||
|
*
|
||||||
|
* @param parameter parameter to be written.
|
||||||
|
*//*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Heating Switch
|
||||||
|
void heatingSwitch(int state) {
|
||||||
|
log(Log.WARN, "Write time duration \"" + state + "\"");
|
||||||
|
//final byte time_in_byte = time_duration.getBytes()[0];
|
||||||
|
final byte state_in_byte = (byte) state;
|
||||||
|
writeCharacteristic(mAmpStartStopCharacteristic, Data.opCode(state_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Heating State"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set Time
|
||||||
|
void sendDTime(int d_time) {
|
||||||
|
log(Log.WARN, "Write D Time Duration \"" + d_time + "\"");
|
||||||
|
final byte d_time_in_byte = (byte) d_time;
|
||||||
|
writeCharacteristic(mSetDTimeCharacteristic, Data.opCode(d_time_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Time"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
void sendATime(int a_time) {
|
||||||
|
log(Log.WARN, "Write A Time Duration \"" + a_time + "\"");
|
||||||
|
final byte a_time_in_byte = (byte) a_time;
|
||||||
|
writeCharacteristic(mSetATimeCharacteristic, Data.opCode(a_time_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Time"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendLTime(int l_time) {
|
||||||
|
log(Log.WARN, "Write A Time Duration \"" + l_time + "\"");
|
||||||
|
final byte a_time_in_byte = (byte) l_time;
|
||||||
|
writeCharacteristic(mSetLTimeCharacteristic, Data.opCode(a_time_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Time"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
void sendOTime(int o_time) {
|
||||||
|
log(Log.WARN, "Write A Time Duration \"" + o_time + "\"");
|
||||||
|
final byte a_time_in_byte = (byte) o_time;
|
||||||
|
writeCharacteristic(mSetOTimeCharacteristic, Data.opCode(a_time_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Time"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void sendETime(int e_time) {
|
||||||
|
log(Log.WARN, "Write E Time Duration \"" + e_time + "\"");
|
||||||
|
final byte e_time_in_byte = (byte) e_time;
|
||||||
|
writeCharacteristic(mSetETimeCharacteristic, Data.opCode(e_time_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Time"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Set Temp
|
||||||
|
void sendDTemp(int d_temp) {
|
||||||
|
log(Log.WARN, "Write D temp \"" + d_temp + "\"");
|
||||||
|
final byte d_temp_in_byte = (byte) d_temp;
|
||||||
|
writeCharacteristic(mSetDTempCharacteristic, Data.opCode(d_temp_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Temp"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
void sendLTemp(int l_temp) {
|
||||||
|
log(Log.WARN, "Write D temp \"" + l_temp + "\"");
|
||||||
|
final byte d_temp_in_byte = (byte) l_temp;
|
||||||
|
writeCharacteristic(mSetLTempCharacteristic, Data.opCode(d_temp_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Temp"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendOTemp(int o_temp) {
|
||||||
|
log(Log.WARN, "Write D temp \"" + o_temp + "\"");
|
||||||
|
final byte d_temp_in_byte = (byte) o_temp;
|
||||||
|
writeCharacteristic(mSetOTempCharacteristic, Data.opCode(d_temp_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Temp"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void sendATemp(int a_temp) {
|
||||||
|
log(Log.WARN, "Write A temp \"" + a_temp + "\"");
|
||||||
|
final byte a_temp_in_byte = (byte) a_temp;
|
||||||
|
writeCharacteristic(mSetATempCharacteristic, Data.opCode(a_temp_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Temp"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
void sendETemp(int e_temp) {
|
||||||
|
log(Log.WARN, "Write E temp \"" + e_temp + "\"");
|
||||||
|
final byte e_temp_in_byte = (byte) e_temp;
|
||||||
|
writeCharacteristic(mSetETempCharacteristic, Data.opCode(e_temp_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Temp"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendNPcrC(int n_pcr_c) {
|
||||||
|
log(Log.WARN, "Write E temp \"" + n_pcr_c + "\"");
|
||||||
|
final byte n_pcr_c_in_byte = (byte) n_pcr_c;
|
||||||
|
writeCharacteristic(mSetNPcrCCharacteristic, Data.opCode(n_pcr_c_in_byte))
|
||||||
|
.with((device, data) -> log(LogContract.Log.Level.APPLICATION,
|
||||||
|
"\"" + data.size() + "\" Set Temp"))
|
||||||
|
.split()
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
150
app/src/main/java/no/Reader/android/iisc/Reader/TestDetails.java
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.appcompat.widget.AppCompatCheckBox;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
|
||||||
|
public class TestDetails extends NavigationTop {
|
||||||
|
private EditText user_name,test_id, per,volume;
|
||||||
|
private Button Createtest;
|
||||||
|
int i=0;
|
||||||
|
File filePath=null;
|
||||||
|
|
||||||
|
private AppCompatCheckBox checkbox;
|
||||||
|
String flag="false",username,testid,percentage,vol;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
LayoutInflater inflater = (LayoutInflater) this
|
||||||
|
.getSystemService(LAYOUT_INFLATER_SERVICE);
|
||||||
|
View contentView = inflater.inflate(R.layout.testdetails, null, false);
|
||||||
|
draw.addView(contentView, 0);
|
||||||
|
|
||||||
|
/* LayoutInflater inflater = (LayoutInflater) this
|
||||||
|
.getSystemService(LAYOUT_INFLATER_SERVICE);
|
||||||
|
View contentView = inflater.inflate(R.layout.activity_about, null, false);
|
||||||
|
*/
|
||||||
|
// setContentView(R.layout.testdetails);
|
||||||
|
if(ContextCompat.checkSelfPermission(TestDetails.this, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
|
||||||
|
{
|
||||||
|
|
||||||
|
ActivityCompat.requestPermissions(TestDetails.this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},23);
|
||||||
|
}
|
||||||
|
user_name=findViewById(R.id.username);
|
||||||
|
test_id=findViewById(R.id.test_id);
|
||||||
|
per=findViewById(R.id.percent);
|
||||||
|
volume=findViewById(R.id.volume);
|
||||||
|
Createtest=findViewById(R.id.createtest);
|
||||||
|
checkbox = (AppCompatCheckBox) findViewById(R.id.positivesample);
|
||||||
|
checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
|
||||||
|
if (isChecked) {
|
||||||
|
i=1;
|
||||||
|
flag="true";
|
||||||
|
// show password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Createtest.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
if (ContextCompat.checkSelfPermission(TestDetails.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
|
||||||
|
ActivityCompat.requestPermissions(TestDetails.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 23);
|
||||||
|
}
|
||||||
|
username = user_name.getText().toString();
|
||||||
|
percentage = per.getText().toString();
|
||||||
|
|
||||||
|
testid = test_id.getText().toString();
|
||||||
|
File filePath1 = new File(Environment.getExternalStorageDirectory() + "/" + testid + ".xls");
|
||||||
|
|
||||||
|
vol = volume.getText().toString();
|
||||||
|
|
||||||
|
if (username.equals("") || percentage.equals("") || testid.equals("") || vol.equals("")) {
|
||||||
|
Toast.makeText(TestDetails.this, "Please fill all fields", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
} else if (Integer.parseInt(String.valueOf(percentage)) > 100 || Integer.parseInt(String.valueOf(percentage)) < 1) {
|
||||||
|
|
||||||
|
|
||||||
|
Toast.makeText(TestDetails.this, "Enter a valid Percentage Data", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
|
||||||
|
} else if (Integer.parseInt(String.valueOf(percentage)) > 100 || Integer.parseInt(String.valueOf(percentage)) < 1) {
|
||||||
|
|
||||||
|
|
||||||
|
Toast.makeText(TestDetails.this, "Enter a valid Percentage Data", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
|
||||||
|
} else if (filePath1.exists()) {
|
||||||
|
Toast.makeText(TestDetails.this, "File With this testid already exists please fill other test id", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
|
||||||
|
if (i == 1) {
|
||||||
|
Intent intent = new Intent(TestDetails.this, TemplateActivity.class);
|
||||||
|
SharedPreferences preferences = getSharedPreferences("TestEntry", MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
|
|
||||||
|
// editor.putString(Name, phonenum);
|
||||||
|
editor.putString("testid", testid);
|
||||||
|
editor.putString("username", username);
|
||||||
|
editor.putString("percentage", percentage);
|
||||||
|
editor.putString("internal", flag);
|
||||||
|
|
||||||
|
editor.putString("volume", vol);
|
||||||
|
|
||||||
|
|
||||||
|
editor.commit();
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Intent intent = new Intent(TestDetails.this, TemplateActivity1.class);
|
||||||
|
SharedPreferences preferences = getSharedPreferences("TestEntry", MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
|
|
||||||
|
// editor.putString(Name, phonenum);
|
||||||
|
editor.putString("testid", testid);
|
||||||
|
editor.putString("username", username);
|
||||||
|
editor.putString("percentage", percentage);
|
||||||
|
editor.putString("internal", flag);
|
||||||
|
editor.putString("volume", vol);
|
||||||
|
|
||||||
|
|
||||||
|
editor.commit();
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.Reader.Interface.ItemClickListner;
|
||||||
|
|
||||||
|
|
||||||
|
public class TestViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
|
||||||
|
{
|
||||||
|
public TextView txtpatientid, txttimestamp,nikshay,iconfinder,txtsampletype;
|
||||||
|
public ImageView imageView;
|
||||||
|
public ItemClickListner listner;
|
||||||
|
|
||||||
|
|
||||||
|
public TestViewHolder(View itemView)
|
||||||
|
{
|
||||||
|
super(itemView);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
imageView = (ImageView) itemView.findViewById(R.id.icon_profile);
|
||||||
|
iconfinder=(TextView) itemView.findViewById(R.id.icon_text);
|
||||||
|
|
||||||
|
txtpatientid = (TextView) itemView.findViewById(R.id.patient_Id);
|
||||||
|
txtsampletype = (TextView) itemView.findViewById(R.id.sample_type);
|
||||||
|
txttimestamp=itemView.findViewById(R.id.timestamp);
|
||||||
|
nikshay=itemView.findViewById(R.id.nikshayid);
|
||||||
|
|
||||||
|
//txtProductDescription= (TextView) itemView.findViewById(R.id.switch_toggle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItemClickListner(ItemClickListner listner)
|
||||||
|
{
|
||||||
|
this.listner = listner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View view)
|
||||||
|
{
|
||||||
|
listner.onClick(view, getAdapterPosition(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
293
app/src/main/java/no/Reader/android/iisc/Reader/Try1.java
Normal file
@@ -0,0 +1,293 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
import com.github.mikephil.charting.charts.BarChart;
|
||||||
|
import com.github.mikephil.charting.data.BarData;
|
||||||
|
import com.github.mikephil.charting.data.BarDataSet;
|
||||||
|
import com.github.mikephil.charting.data.BarEntry;
|
||||||
|
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||||
|
|
||||||
|
import org.apache.poi.EncryptedDocumentException;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.apache.poi.ss.usermodel.WorkbookFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class Try1 extends AppCompatActivity {
|
||||||
|
String TAG ="main";
|
||||||
|
private TextView textView;
|
||||||
|
BarChart barChart;
|
||||||
|
ArrayList<String> adcVal;
|
||||||
|
ArrayList<String> samplelabel;
|
||||||
|
ArrayList<BarEntry> entries = new ArrayList<>();
|
||||||
|
ArrayList<String> labels = new ArrayList<String>();
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_try1);
|
||||||
|
textView = findViewById(R.id.textview);
|
||||||
|
barChart = (BarChart) findViewById(R.id.barchart);
|
||||||
|
|
||||||
|
if(ContextCompat.checkSelfPermission(Try1.this, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
|
||||||
|
{
|
||||||
|
|
||||||
|
ActivityCompat.requestPermissions(Try1.this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},23);
|
||||||
|
}
|
||||||
|
readExcelFileFromAssets();
|
||||||
|
}
|
||||||
|
public void readExcelFileFromAssets() {
|
||||||
|
if(ContextCompat.checkSelfPermission(Try1.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
|
||||||
|
{
|
||||||
|
|
||||||
|
ActivityCompat.requestPermissions(Try1.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},23);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
|
||||||
|
InputStream myInput;
|
||||||
|
Context context = null;
|
||||||
|
File filePath1 = new File(Environment.getExternalStorageDirectory() + "/" +"do.xls");
|
||||||
|
File file = new File(getApplicationContext().getExternalFilesDir(null), "do.xls");
|
||||||
|
/* fis = new FileInputStream(file);
|
||||||
|
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
|
||||||
|
|
||||||
|
File sdcard = Environment.getExternalStorageDirectory();
|
||||||
|
File file = new File("/sdcard/Demo.xls");
|
||||||
|
if(file.exists()){
|
||||||
|
|
||||||
|
*/
|
||||||
|
if(filePath1.exists()){
|
||||||
|
|
||||||
|
Toast.makeText(Try1.this, "id exist", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Toast.makeText(Try1.this, "nooo", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
myInput = new FileInputStream(filePath1);
|
||||||
|
|
||||||
|
|
||||||
|
// initialize asset manager
|
||||||
|
/* AssetManager assetManager = getAssets();
|
||||||
|
// open excel sheet
|
||||||
|
myInput = assetManager.open("file_example_XLS_50.xls");
|
||||||
|
*/ // Create a POI File System object
|
||||||
|
POIFSFileSystem myFileSystem = new POIFSFileSystem(myInput);
|
||||||
|
// Create a workbook using the File System
|
||||||
|
HSSFWorkbook myWorkBook = new HSSFWorkbook(myFileSystem);
|
||||||
|
// Get the first sheet from workbook
|
||||||
|
HSSFSheet mySheet = myWorkBook.getSheetAt(0);
|
||||||
|
int rowCount = mySheet.getLastRowNum();
|
||||||
|
|
||||||
|
// We now need something to iterate through the cells.
|
||||||
|
Iterator<Row> rowIter = mySheet.rowIterator();
|
||||||
|
int[][] arr = new int[0][];
|
||||||
|
|
||||||
|
for(int i=11;i<=rowCount;i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
Row row = mySheet.getRow(i);
|
||||||
|
|
||||||
|
//Create a loop to print cell values in a row
|
||||||
|
|
||||||
|
int j =1;
|
||||||
|
|
||||||
|
//Print Excel data in console
|
||||||
|
labels.add(String.valueOf(row.getCell(j).getStringCellValue()));
|
||||||
|
|
||||||
|
samplelabel.add(String.valueOf(row.getCell(j).getStringCellValue()));
|
||||||
|
int k=3;
|
||||||
|
entries.add(new BarEntry(Float.parseFloat(String.valueOf(i)), i-11));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BarDataSet bardataset = new BarDataSet(entries, "Result");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BarData data = new BarData(labels, bardataset);
|
||||||
|
barChart.setData(data); // set the data and list of labels into chart
|
||||||
|
barChart.setDescription("Bar Graph for Result"); // set the description
|
||||||
|
bardataset.setColors(ColorTemplate.COLORFUL_COLORS);
|
||||||
|
barChart.animateY(1000);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* int rowno =0;
|
||||||
|
textView.append("\n");
|
||||||
|
while (rowIter.hasNext()) {
|
||||||
|
Log.e(TAG, " row no "+ rowno );
|
||||||
|
HSSFRow myRow = (HSSFRow) rowIter.next();
|
||||||
|
if(rowno !=0) {
|
||||||
|
Iterator<Cell> cellIter = myRow.cellIterator();
|
||||||
|
Log.e(TAG, " Cell "+ myRow.cellIterator() );
|
||||||
|
|
||||||
|
int colno =0;
|
||||||
|
String sno="";
|
||||||
|
String date="";
|
||||||
|
String det="";
|
||||||
|
int value = 0;
|
||||||
|
while (cellIter.hasNext()) {
|
||||||
|
HSSFCell myCell = (HSSFCell) cellIter.next();
|
||||||
|
if (colno==0){
|
||||||
|
value= Integer.parseInt(String.valueOf(myCell));
|
||||||
|
Log.e(TAG, " Cell value 1 "+ value );
|
||||||
|
|
||||||
|
}
|
||||||
|
if (colno==1){
|
||||||
|
sno = myCell.toString();
|
||||||
|
Log.e(TAG, " Cell value 2 "+ sno );
|
||||||
|
|
||||||
|
}else if (colno==2){
|
||||||
|
date = myCell.toString();
|
||||||
|
Log.e(TAG, " Cell value 3 "+ date );
|
||||||
|
|
||||||
|
}
|
||||||
|
colno++;
|
||||||
|
Log.e(TAG, " Index :" + myCell.getColumnIndex() + " -- " + myCell.toString());
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "error "+ e.toString());
|
||||||
|
}
|
||||||
|
change();
|
||||||
|
}
|
||||||
|
private void change()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
InputStream myInput;
|
||||||
|
File filePath1 = new File(Environment.getExternalStorageDirectory() + "/" +"file_example_XLS_50.xls");
|
||||||
|
|
||||||
|
myInput = new FileInputStream(filePath1);
|
||||||
|
|
||||||
|
Workbook workbook = WorkbookFactory.create(myInput);
|
||||||
|
|
||||||
|
Sheet sheet = workbook.getSheetAt(0);
|
||||||
|
|
||||||
|
Object[][] bookData = {
|
||||||
|
|
||||||
|
{51,"love1", "Chad Fowler", "Chad Fowler","Chad Fowler",45,"fff",5555},
|
||||||
|
{51,"love2", "Chad Fowler", "Chad Fowler","Chad Fowler",45,"fff",5555},
|
||||||
|
{51,"Thggggg", "Chad Fowler", "Chad Fowler","Chad Fowler",45,"fff",5555},
|
||||||
|
{51,"The Passionate Program", "Chad Fowler", "Chad Fowler","Chad Fowler",45,"fff",5555},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
int rowCount = sheet.getLastRowNum();
|
||||||
|
|
||||||
|
for (Object[] aBook : bookData) {
|
||||||
|
Row row = sheet.createRow(++rowCount);
|
||||||
|
|
||||||
|
int columnCount = 0;
|
||||||
|
|
||||||
|
Cell cell = row.createCell(columnCount);
|
||||||
|
cell.setCellValue(rowCount);
|
||||||
|
|
||||||
|
for (Object field : aBook) {
|
||||||
|
cell = row.createCell(++columnCount);
|
||||||
|
if (field instanceof String) {
|
||||||
|
cell.setCellValue((String) field);
|
||||||
|
} else if (field instanceof Integer) {
|
||||||
|
cell.setCellValue((Integer) field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
myInput.close();
|
||||||
|
|
||||||
|
FileOutputStream outputStream = new FileOutputStream(filePath1);
|
||||||
|
workbook.write(outputStream);
|
||||||
|
workbook.close();
|
||||||
|
outputStream.close();
|
||||||
|
|
||||||
|
} catch (IOException | EncryptedDocumentException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
package no.Reader.android.iisc.Reader.VerifyOTP;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.chaos.view.PinView;
|
||||||
|
import com.google.android.gms.tasks.OnCompleteListener;
|
||||||
|
import com.google.android.gms.tasks.Task;
|
||||||
|
import com.google.firebase.FirebaseException;
|
||||||
|
import com.google.firebase.auth.AuthResult;
|
||||||
|
import com.google.firebase.auth.FirebaseAuth;
|
||||||
|
import com.google.firebase.auth.PhoneAuthCredential;
|
||||||
|
import com.google.firebase.auth.PhoneAuthOptions;
|
||||||
|
import com.google.firebase.auth.PhoneAuthProvider;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.Reader.CreatePassword;
|
||||||
|
|
||||||
|
|
||||||
|
public class VerifyOtp extends AppCompatActivity {
|
||||||
|
|
||||||
|
private String verificationid;
|
||||||
|
private FirebaseAuth mAuth;
|
||||||
|
private Button nextactivity;
|
||||||
|
private ProgressBar progressBar;
|
||||||
|
PinView pinFromUser;
|
||||||
|
private EditText editText;
|
||||||
|
String codeBySystem;
|
||||||
|
String address,name, state , city ,pincode,phonenumber,password2,num1,phonenumberke;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_verify__o_t_p);
|
||||||
|
pinFromUser = findViewById(R.id.firstPinView);
|
||||||
|
nextactivity = findViewById(R.id.buttonSignIn);
|
||||||
|
|
||||||
|
mAuth = FirebaseAuth.getInstance();
|
||||||
|
|
||||||
|
|
||||||
|
String phonenumberk = getIntent().getStringExtra("numberwithcode");
|
||||||
|
phonenumberke = getIntent().getStringExtra("mobile");
|
||||||
|
|
||||||
|
phonenumber = phonenumberk;
|
||||||
|
|
||||||
|
name = getIntent().getStringExtra("username");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sendVerificationCode(phonenumber);
|
||||||
|
findViewById(R.id.buttonSignIn).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
String code = pinFromUser.getText().toString().trim();
|
||||||
|
|
||||||
|
if ((code.isEmpty() || code.length() < 6)) {
|
||||||
|
|
||||||
|
editText.setError("Enter code...");
|
||||||
|
editText.requestFocus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
verifyCode(code);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
private void verifyCode(String code){
|
||||||
|
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationid, code);
|
||||||
|
signInWithCredential(credential);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void signInWithCredential(PhoneAuthCredential credential) {
|
||||||
|
mAuth.signInWithCredential(credential)
|
||||||
|
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(@NonNull Task<AuthResult> task) {
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
|
||||||
|
Intent intent = new Intent(VerifyOtp.this, CreatePassword.class);
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
|
intent.putExtra("mobile", phonenumberke);
|
||||||
|
intent.putExtra("username", name);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Toast.makeText(VerifyOTP.this, task.getException().getMessage(), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendVerificationCode(String number){
|
||||||
|
|
||||||
|
PhoneAuthOptions options =
|
||||||
|
PhoneAuthOptions.newBuilder(mAuth)
|
||||||
|
.setPhoneNumber(number) // Phone number to verify
|
||||||
|
.setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
|
||||||
|
.setActivity(this) // Activity (for callback binding)
|
||||||
|
.setCallbacks(mCallBack) // OnVerificationStateChangedCallbacks
|
||||||
|
.build();
|
||||||
|
PhoneAuthProvider.verifyPhoneNumber(options);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private PhoneAuthProvider.OnVerificationStateChangedCallbacks
|
||||||
|
mCallBack = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCodeSent(String s, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
|
||||||
|
super.onCodeSent(s, forceResendingToken);
|
||||||
|
verificationid = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
|
||||||
|
String code = phoneAuthCredential.getSmsCode();
|
||||||
|
if (code != null){
|
||||||
|
// progressBar.setVisibility(View.VISIBLE);
|
||||||
|
pinFromUser.setText(code);
|
||||||
|
verifyCode(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVerificationFailed(FirebaseException e) {
|
||||||
|
Toast.makeText(VerifyOtp.this, e.getMessage(),Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
package no.Reader.android.iisc.Reader.VerifyOTP;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.chaos.view.PinView;
|
||||||
|
import com.google.android.gms.tasks.OnCompleteListener;
|
||||||
|
import com.google.android.gms.tasks.Task;
|
||||||
|
import com.google.firebase.FirebaseException;
|
||||||
|
import com.google.firebase.auth.AuthResult;
|
||||||
|
import com.google.firebase.auth.FirebaseAuth;
|
||||||
|
import com.google.firebase.auth.PhoneAuthCredential;
|
||||||
|
import com.google.firebase.auth.PhoneAuthOptions;
|
||||||
|
import com.google.firebase.auth.PhoneAuthProvider;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.Reader.ForgetPassword;
|
||||||
|
import no.Reader.android.iisc.Reader.ForgetPasswordReset;
|
||||||
|
|
||||||
|
|
||||||
|
public class VerifyOtpForgetPassword extends AppCompatActivity {
|
||||||
|
|
||||||
|
private String verificationid;
|
||||||
|
private FirebaseAuth mAuth;
|
||||||
|
private Button nextactivity;
|
||||||
|
private ProgressBar progressBar;
|
||||||
|
PinView pinFromUser;
|
||||||
|
private EditText editText;
|
||||||
|
String codeBySystem;
|
||||||
|
String address,name, state , city ,pincode,phonenumber,password2,num1,mobile;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_verify__o_t_p);
|
||||||
|
pinFromUser = findViewById(R.id.firstPinView);
|
||||||
|
nextactivity = findViewById(R.id.buttonSignIn);
|
||||||
|
|
||||||
|
mAuth = FirebaseAuth.getInstance();
|
||||||
|
|
||||||
|
|
||||||
|
String phonenumberk = getIntent().getStringExtra("mobilecode");
|
||||||
|
phonenumber = phonenumberk;
|
||||||
|
mobile= getIntent().getStringExtra("mobile");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sendVerificationCode(phonenumber);
|
||||||
|
findViewById(R.id.buttonSignIn).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
String code = pinFromUser.getText().toString().trim();
|
||||||
|
|
||||||
|
if ((code.isEmpty() || code.length() < 6)) {
|
||||||
|
|
||||||
|
editText.setError("Enter code...");
|
||||||
|
editText.requestFocus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
verifyCode(code);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
private void verifyCode(String code){
|
||||||
|
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationid, code);
|
||||||
|
signInWithCredential(credential);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void signInWithCredential(PhoneAuthCredential credential) {
|
||||||
|
mAuth.signInWithCredential(credential)
|
||||||
|
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(@NonNull Task<AuthResult> task) {
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
|
||||||
|
Intent intent = new Intent(VerifyOtpForgetPassword.this, ForgetPasswordReset.class);
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
|
intent.putExtra("mobile", mobile);
|
||||||
|
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Toast.makeText(VerifyOtpForgetPassword.this, task.getException().getMessage(), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendVerificationCode(String number){
|
||||||
|
PhoneAuthOptions options =
|
||||||
|
PhoneAuthOptions.newBuilder(mAuth)
|
||||||
|
.setPhoneNumber(number) // Phone number to verify
|
||||||
|
.setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
|
||||||
|
.setActivity(this) // Activity (for callback binding)
|
||||||
|
.setCallbacks(mCallBack) // OnVerificationStateChangedCallbacks
|
||||||
|
.build();
|
||||||
|
PhoneAuthProvider.verifyPhoneNumber(options);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private PhoneAuthProvider.OnVerificationStateChangedCallbacks
|
||||||
|
mCallBack = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCodeSent(String s, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
|
||||||
|
super.onCodeSent(s, forceResendingToken);
|
||||||
|
verificationid = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
|
||||||
|
String code = phoneAuthCredential.getSmsCode();
|
||||||
|
if (code != null){
|
||||||
|
// progressBar.setVisibility(View.VISIBLE);
|
||||||
|
pinFromUser.setText(code);
|
||||||
|
verifyCode(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVerificationFailed(FirebaseException e) {
|
||||||
|
Toast.makeText(VerifyOtpForgetPassword.this, e.getMessage(),Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
|
||||||
|
Intent intent = new Intent(VerifyOtpForgetPassword.this, ForgetPassword.class);
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
429
app/src/main/java/no/Reader/android/iisc/Reader/ViewGraph.java
Normal file
@@ -0,0 +1,429 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.core.content.FileProvider;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.os.StrictMode;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.github.mikephil.charting.charts.BarChart;
|
||||||
|
import com.github.mikephil.charting.data.BarData;
|
||||||
|
import com.github.mikephil.charting.data.BarDataSet;
|
||||||
|
import com.github.mikephil.charting.data.BarEntry;
|
||||||
|
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||||
|
import com.google.firebase.database.DatabaseReference;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
|
||||||
|
public class ViewGraph extends AppCompatActivity {
|
||||||
|
private TextView result, textadc;
|
||||||
|
String value1_1, value1_2, value1_3, value2_1, value2_2, value2_3, value3_1, value3_2, value3_3, testid, username, percentage, internal, samplename, volume;
|
||||||
|
BarChart barChart;
|
||||||
|
BarData barData;
|
||||||
|
String string1,string2,string3,string4,string5,string6,string7,string8,string9,number,logi,lati;
|
||||||
|
|
||||||
|
private ProgressDialog loadingBar;
|
||||||
|
private String TestRandomKey, downloadImageUrl1,saveCurrentDate, saveCurrentTime;
|
||||||
|
Uri path;
|
||||||
|
|
||||||
|
File filePath3 = null;
|
||||||
|
private DatabaseReference TestRef;
|
||||||
|
|
||||||
|
File filePath1 = null;
|
||||||
|
File filePath = null;
|
||||||
|
String directory_path;
|
||||||
|
int love = 0;
|
||||||
|
BarDataSet barDataSet;
|
||||||
|
ArrayList barEntries;
|
||||||
|
int positive, negative, sample, positive_value, negative_value, sample_value, sampleraw, sampleraw1, sampleraw2;
|
||||||
|
int delta = 0;
|
||||||
|
String resultdata;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
ImageButton dowbloadd;
|
||||||
|
ImageButton save;
|
||||||
|
|
||||||
|
|
||||||
|
String date, time;
|
||||||
|
private String TestID = "";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_view_graph);
|
||||||
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
/* BottomNavigationView bottomNav = findViewById(R.id.bottom_navigation);
|
||||||
|
bottomNav.setOnNavigationItemSelectedListener(navListener);
|
||||||
|
*/ StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
|
||||||
|
StrictMode.setVmPolicy(builder.build());
|
||||||
|
builder.detectFileUriExposure();
|
||||||
|
barChart = (BarChart) findViewById(R.id.barchart);
|
||||||
|
loadingBar = new ProgressDialog(this);
|
||||||
|
textadc = findViewById(R.id.textadc);
|
||||||
|
testid = getIntent().getStringExtra("pid");
|
||||||
|
|
||||||
|
Log.e("main", "error id "+TestID);
|
||||||
|
SharedPreferences preferences689 = getSharedPreferences("PhoneBook_number", MODE_PRIVATE);
|
||||||
|
|
||||||
|
number = preferences689.getString("Phone", null);
|
||||||
|
Log.e("main", "error "+number);
|
||||||
|
TestRef = FirebaseDatabase.getInstance().getReference().child("Test_Data").child(number);
|
||||||
|
|
||||||
|
|
||||||
|
/* LayoutInflater inflater = (LayoutInflater) this
|
||||||
|
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
View contentView = inflater.inflate(R.layout.activity_feature_template3, null, false);
|
||||||
|
draw.addView(contentView, 0);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (ContextCompat.checkSelfPermission(ViewGraph.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
|
||||||
|
ActivityCompat.requestPermissions(ViewGraph.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 23);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
readExcelFileFromAssets();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* private BottomNavigationView.OnNavigationItemSelectedListener navListener =
|
||||||
|
new BottomNavigationView.OnNavigationItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
||||||
|
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.nav_result:
|
||||||
|
Intent intent=new Intent(ViewGraph.this, ViewSamples.class);
|
||||||
|
|
||||||
|
intent.putExtra("pid",testid);
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
case R.id.nav_home:
|
||||||
|
Intent intent2 = new Intent(ViewGraph.this, MainActivity.class);
|
||||||
|
|
||||||
|
startActivity(intent2);
|
||||||
|
break;
|
||||||
|
case R.id.nav_excel:
|
||||||
|
shared();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
public void readExcelFileFromAssets() {
|
||||||
|
if (ContextCompat.checkSelfPermission(ViewGraph.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
|
||||||
|
ActivityCompat.requestPermissions(ViewGraph.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 23);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
|
||||||
|
InputStream myInput;
|
||||||
|
Context context = null;
|
||||||
|
|
||||||
|
String directory_path = Environment.getExternalStorageDirectory().getPath() + "/Test Report/";
|
||||||
|
|
||||||
|
|
||||||
|
String targetPdf = directory_path + "Report_" + testid + ".xls";
|
||||||
|
filePath1 = new File(targetPdf);
|
||||||
|
|
||||||
|
|
||||||
|
if (filePath1.exists()) {
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Toast.makeText(ViewGraph.this, "nooo", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
myInput = new FileInputStream(filePath1);
|
||||||
|
|
||||||
|
|
||||||
|
POIFSFileSystem myFileSystem = new POIFSFileSystem(myInput);
|
||||||
|
// Create a workbook using the File System
|
||||||
|
HSSFWorkbook myWorkBook = new HSSFWorkbook(myFileSystem);
|
||||||
|
|
||||||
|
|
||||||
|
ArrayList<BarEntry> entries = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
BarDataSet bardataset = new BarDataSet(entries, "Result");
|
||||||
|
|
||||||
|
ArrayList<String> labels = new ArrayList<String>();
|
||||||
|
|
||||||
|
|
||||||
|
// Get the first sheet from workbook
|
||||||
|
HSSFSheet mySheet = myWorkBook.getSheetAt(0);
|
||||||
|
|
||||||
|
// We now need something to iterate through the cells.
|
||||||
|
Iterator<Row> rowIter = mySheet.rowIterator();
|
||||||
|
int rowCount = mySheet.getLastRowNum();
|
||||||
|
|
||||||
|
|
||||||
|
int rowno = 0;
|
||||||
|
while (rowIter.hasNext()) {
|
||||||
|
HSSFRow myRow = (HSSFRow) rowIter.next();
|
||||||
|
|
||||||
|
// 5
|
||||||
|
if (rowno != 0 && rowno > 5) {
|
||||||
|
|
||||||
|
|
||||||
|
if (rowno == rowCount - 1) {
|
||||||
|
|
||||||
|
|
||||||
|
Iterator<Cell> cellIter = myRow.cellIterator();
|
||||||
|
int colno = 0;
|
||||||
|
String sno = "", date = "", det = "", vald = "", adcvals = "", result = "";
|
||||||
|
while (cellIter.hasNext()) {
|
||||||
|
HSSFCell myCell = (HSSFCell) cellIter.next();
|
||||||
|
if (colno == 0) {
|
||||||
|
sno = myCell.toString();
|
||||||
|
} else if (colno == 1) {
|
||||||
|
date = myCell.toString();
|
||||||
|
} else if (colno == 2) {
|
||||||
|
adcvals = myCell.toString();
|
||||||
|
} else if (colno == 3) {
|
||||||
|
det = myCell.toString();
|
||||||
|
} else if (colno == 4) {
|
||||||
|
vald = myCell.toString();
|
||||||
|
} else if (colno == 5) {
|
||||||
|
result = myCell.toString();
|
||||||
|
}
|
||||||
|
colno++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result.contains("Positive")) {
|
||||||
|
|
||||||
|
// Toast.makeText(ViewGraph.this, "positive " + result + " File ", Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Toast.makeText(ViewGraph.this, "positive " + result + " File ", Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
|
bardataset.setColors(ColorTemplate.COLORFUL_COLORS);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!det.equals("-")) {
|
||||||
|
|
||||||
|
entries.add(new BarEntry(Float.parseFloat((det)), rowno - 6));
|
||||||
|
labels.add(date + "(" + result + ")");
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
entries.add(new BarEntry(Float.parseFloat(String.valueOf((0))), rowno - 6));
|
||||||
|
labels.add(date + "(" + result + ")");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
textadc.append("Test ID : " +testid+ "\n");
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Iterator<Cell> cellIter = myRow.cellIterator();
|
||||||
|
int colno = 0;
|
||||||
|
String sno = "", date = "", det = "", result1 = "";
|
||||||
|
while (cellIter.hasNext()) {
|
||||||
|
HSSFCell myCell = (HSSFCell) cellIter.next();
|
||||||
|
if (colno == 0) {
|
||||||
|
sno = myCell.toString();
|
||||||
|
} else if (colno == 1) {
|
||||||
|
date = myCell.toString();
|
||||||
|
} else if (colno == 3) {
|
||||||
|
det = myCell.toString();
|
||||||
|
|
||||||
|
} else if (colno == 5) {
|
||||||
|
result1 = myCell.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
colno++;
|
||||||
|
}
|
||||||
|
if (!det.equals("-")) {
|
||||||
|
|
||||||
|
entries.add(new BarEntry(Float.parseFloat((det)), rowno - 6));
|
||||||
|
labels.add(date + "(" + result1 + ")");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
entries.add(new BarEntry(Float.parseFloat(String.valueOf((0))), rowno - 6));
|
||||||
|
|
||||||
|
labels.add(date + "(" + result1 + ")");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
rowno++;
|
||||||
|
|
||||||
|
}
|
||||||
|
BarData data = new BarData(labels, bardataset);
|
||||||
|
barChart.setData(data); // set the data and list of labels into chart
|
||||||
|
barChart.setDescription("Bar Graph for Result"); // set the description
|
||||||
|
barChart.animateY(1000);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
MenuInflater inflater = getMenuInflater();
|
||||||
|
inflater.inflate(R.menu.menu1, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.nav_samples:
|
||||||
|
Intent intent=new Intent(ViewGraph.this, ViewSamples.class);
|
||||||
|
|
||||||
|
intent.putExtra("pid",testid);
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
case R.id.nav_home:
|
||||||
|
Intent intent2 = new Intent(ViewGraph.this, MainActivity.class);
|
||||||
|
|
||||||
|
startActivity(intent2);
|
||||||
|
return true;
|
||||||
|
case R.id.nav_excel:
|
||||||
|
shared();
|
||||||
|
return true;
|
||||||
|
case R.id.nav_share:
|
||||||
|
srk();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void srk()
|
||||||
|
{
|
||||||
|
if(ContextCompat.checkSelfPermission(ViewGraph.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
|
||||||
|
{
|
||||||
|
|
||||||
|
ActivityCompat.requestPermissions(ViewGraph.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},23);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String directory_path = Environment.getExternalStorageDirectory().getPath() + "/Test Report/";
|
||||||
|
String pat= directory_path + "Report_" + testid + ".xls";
|
||||||
|
|
||||||
|
File file = new File(pat);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Intent intent=new Intent(Intent.ACTION_SEND);
|
||||||
|
intent.putExtra(Intent.EXTRA_TEXT,"Report");
|
||||||
|
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N) {
|
||||||
|
Uri path= FileProvider.getUriForFile(ViewGraph.this,"no.Reader.android.iisc.fileprovider",file);
|
||||||
|
intent.putExtra(Intent.EXTRA_STREAM,path);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
intent.putExtra(Intent.EXTRA_STREAM,Uri.fromFile(file));
|
||||||
|
}
|
||||||
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
intent.setDataAndType(path, "application/vnd.ms-excel");
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void shared() {
|
||||||
|
String directory_path = Environment.getExternalStorageDirectory().getPath() + "/Test Report/";
|
||||||
|
String pat= directory_path + "Report_" + testid + ".xls";
|
||||||
|
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
File file = new File(pat);
|
||||||
|
Uri path = FileProvider.getUriForFile(getApplicationContext(), "no.Reader.android.iisc.fileprovider", file);
|
||||||
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
intent.setDataAndType(path, "application/vnd.ms-excel");
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
548
app/src/main/java/no/Reader/android/iisc/Reader/ViewSamples.java
Normal file
@@ -0,0 +1,548 @@
|
|||||||
|
package no.Reader.android.iisc.Reader;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.core.content.FileProvider;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.os.StrictMode;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.TableLayout;
|
||||||
|
import android.widget.TableRow;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.github.mikephil.charting.charts.BarChart;
|
||||||
|
import com.github.mikephil.charting.data.BarData;
|
||||||
|
import com.github.mikephil.charting.data.BarDataSet;
|
||||||
|
import com.google.firebase.database.DatabaseReference;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
|
||||||
|
public class ViewSamples extends AppCompatActivity {
|
||||||
|
private TextView result, textadc;
|
||||||
|
String value1_1, value1_2, value1_3, value2_1, value2_2, value2_3, value3_1, value3_2, value3_3, testid, username, percentage, internal, samplename, volume;
|
||||||
|
BarChart barChart;
|
||||||
|
Uri path;
|
||||||
|
BarData barData;
|
||||||
|
String string1,string2,string3,string4,string5,string6,string7,string8,string9,number,logi,lati;
|
||||||
|
|
||||||
|
private ProgressDialog loadingBar;
|
||||||
|
private String TestRandomKey, downloadImageUrl1,saveCurrentDate, saveCurrentTime;
|
||||||
|
|
||||||
|
|
||||||
|
File filePath3 = null;
|
||||||
|
private DatabaseReference TestRef;
|
||||||
|
|
||||||
|
File filePath1 = null;
|
||||||
|
File filePath = null;
|
||||||
|
String directory_path;
|
||||||
|
int love = 0;
|
||||||
|
BarDataSet barDataSet;
|
||||||
|
ArrayList barEntries;
|
||||||
|
int positive, negative, sample, positive_value, negative_value, sample_value, sampleraw, sampleraw1, sampleraw2;
|
||||||
|
int delta = 0;
|
||||||
|
String resultdata;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
ImageButton dowbloadd;
|
||||||
|
ImageButton share;
|
||||||
|
|
||||||
|
|
||||||
|
String date, time;
|
||||||
|
private String TestID = "";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_view_samples);
|
||||||
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
// BottomNavigationView bottomNav = findViewById(R.id.bottom_navigation);
|
||||||
|
// bottomNav.setOnNavigationItemSelectedListener(navListener);
|
||||||
|
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
|
||||||
|
StrictMode.setVmPolicy(builder.build());
|
||||||
|
builder.detectFileUriExposure();
|
||||||
|
loadingBar = new ProgressDialog(this);
|
||||||
|
testid = getIntent().getStringExtra("pid");
|
||||||
|
Log.e("TestIdll",testid);
|
||||||
|
textadc = findViewById(R.id.textadc);
|
||||||
|
/* share=findViewById(R.id.share);
|
||||||
|
share.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if(ContextCompat.checkSelfPermission(ViewSamples.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
|
||||||
|
{
|
||||||
|
|
||||||
|
ActivityCompat.requestPermissions(ViewSamples.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},23);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String directory_path = Environment.getExternalStorageDirectory().getPath() + "/Test Report/";
|
||||||
|
String pat= directory_path + "Report_" + testid + ".xls";
|
||||||
|
|
||||||
|
File file = new File(pat);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Intent intent=new Intent(Intent.ACTION_SEND);
|
||||||
|
intent.putExtra(Intent.EXTRA_TEXT,"Report");
|
||||||
|
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N) {
|
||||||
|
Uri path= FileProvider.getUriForFile(ViewSamples.this,"no.Reader.android.iisc.fileprovider",file);
|
||||||
|
intent.putExtra(Intent.EXTRA_STREAM,path);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
intent.putExtra(Intent.EXTRA_STREAM,Uri.fromFile(file));
|
||||||
|
}
|
||||||
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
intent.setDataAndType(path, "application/vnd.ms-excel");
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
*/ textadc.append("Test ID : " +testid+ "\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* LayoutInflater inflater = (LayoutInflater) this
|
||||||
|
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
View contentView = inflater.inflate(R.layout.activity_feature_template3, null, false);
|
||||||
|
draw.addView(contentView, 0);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(ContextCompat.checkSelfPermission(ViewSamples.this, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
|
||||||
|
{
|
||||||
|
|
||||||
|
ActivityCompat.requestPermissions(ViewSamples.this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},23);
|
||||||
|
}
|
||||||
|
// init("1","1","1","1","1","1");
|
||||||
|
readExcelFileFromAssets();
|
||||||
|
}
|
||||||
|
public void readExcelFileFromAssets() {
|
||||||
|
if(ContextCompat.checkSelfPermission(ViewSamples.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
|
||||||
|
{
|
||||||
|
|
||||||
|
ActivityCompat.requestPermissions(ViewSamples.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},23);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
|
||||||
|
InputStream myInput;
|
||||||
|
Context context = null;
|
||||||
|
String directory_path = Environment.getExternalStorageDirectory().getPath() + "/Test Report/";
|
||||||
|
|
||||||
|
String targetPdf = directory_path + "Report_" +testid+".xls";
|
||||||
|
filePath1 = new File(targetPdf);
|
||||||
|
File file = new File(getApplicationContext().getExternalFilesDir(null), "78.xls");
|
||||||
|
/* fis = new FileInputStream(file);
|
||||||
|
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
|
||||||
|
|
||||||
|
File sdcard = Environment.getExternalStorageDirectory();
|
||||||
|
File file = new File("/sdcard/Demo.xls");
|
||||||
|
if(file.exists()){
|
||||||
|
|
||||||
|
*/
|
||||||
|
if(filePath1.exists()){
|
||||||
|
|
||||||
|
// Toast.makeText(ViewSamples.this, "id exist", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Toast.makeText(ViewSamples.this, "nooo", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
myInput = new FileInputStream(filePath1);
|
||||||
|
|
||||||
|
|
||||||
|
// initialize asset manager
|
||||||
|
/* AssetManager assetManager = getAssets();
|
||||||
|
// open excel sheet
|
||||||
|
myInput = assetManager.open("file_example_XLS_50.xls");
|
||||||
|
*/ // Create a POI File System object
|
||||||
|
POIFSFileSystem myFileSystem = new POIFSFileSystem(myInput);
|
||||||
|
// Create a workbook using the File System
|
||||||
|
HSSFWorkbook myWorkBook = new HSSFWorkbook(myFileSystem);
|
||||||
|
// Get the first sheet from workbook
|
||||||
|
HSSFSheet mySheet = myWorkBook.getSheetAt(0);
|
||||||
|
// We now need something to iterate through the cells.
|
||||||
|
Iterator<Row> rowIter = mySheet.rowIterator();
|
||||||
|
int rowno =0;
|
||||||
|
// textView.append("\n");
|
||||||
|
while (rowIter.hasNext()) {
|
||||||
|
HSSFRow myRow = (HSSFRow) rowIter.next();
|
||||||
|
if(rowno !=0) {
|
||||||
|
Iterator<Cell> cellIter = myRow.cellIterator();
|
||||||
|
int colno =0;
|
||||||
|
String sno="", sampletype="", adcval="",delta="",result="",avgadc="";
|
||||||
|
while (cellIter.hasNext()) {
|
||||||
|
HSSFCell myCell = (HSSFCell) cellIter.next();
|
||||||
|
if (colno==0){
|
||||||
|
sno = myCell.toString();
|
||||||
|
}else if (colno==1){
|
||||||
|
sampletype = myCell.toString();
|
||||||
|
}else if (colno==2){
|
||||||
|
adcval= myCell.toString();
|
||||||
|
}
|
||||||
|
else if (colno==3){
|
||||||
|
avgadc= myCell.toString();
|
||||||
|
}
|
||||||
|
else if (colno==4){
|
||||||
|
delta= myCell.toString();
|
||||||
|
}
|
||||||
|
else if (colno==5){
|
||||||
|
result= myCell.toString();
|
||||||
|
}
|
||||||
|
colno++;
|
||||||
|
}
|
||||||
|
// init1(sno);
|
||||||
|
Log.e("s",sno);
|
||||||
|
init(sno,sampletype,adcval,avgadc,delta,result);
|
||||||
|
// textView.append( sno + " "+ sampletype+" "+ adcval+" "+avgadc+" "+delta+" "+result+ " "+"\n");
|
||||||
|
}
|
||||||
|
rowno++;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void init(String sno ,String sampletype,String adcval,String avgadc ,String delta,String result) {
|
||||||
|
|
||||||
|
TableLayout stk = (TableLayout) findViewById(R.id.table_main);
|
||||||
|
|
||||||
|
/* TableRow tbrow0 = new TableRow(this);
|
||||||
|
TextView tv0 = new TextView(this);
|
||||||
|
tv0.setText(" Sl.No ");
|
||||||
|
tv0.setTextColor(Color.WHITE);
|
||||||
|
tbrow0.addView(tv0);
|
||||||
|
TextView tv1 = new TextView(this);
|
||||||
|
tv1.setText(" Product ");
|
||||||
|
tv1.setTextColor(Color.WHITE);
|
||||||
|
tbrow0.addView(tv1);
|
||||||
|
TextView tv2 = new TextView(this);
|
||||||
|
tv2.setText(" Unit Price ");
|
||||||
|
tv2.setTextColor(Color.WHITE);
|
||||||
|
tbrow0.addView(tv2);
|
||||||
|
TextView tv3 = new TextView(this);
|
||||||
|
tv3.setText(" Stock Remaining ");
|
||||||
|
tv3.setTextColor(Color.WHITE);
|
||||||
|
tbrow0.addView(tv3);
|
||||||
|
stk.addView(tbrow0);*/
|
||||||
|
TableRow tbrow = new TableRow(this);
|
||||||
|
TextView t1v = new TextView(this);
|
||||||
|
t1v.setText("" + sno +" ");
|
||||||
|
t1v.setGravity(Gravity.CENTER);
|
||||||
|
tbrow.addView(t1v);
|
||||||
|
TextView t2v = new TextView(this);
|
||||||
|
t2v.setText(sampletype+" ");
|
||||||
|
t2v.setGravity(Gravity.CENTER);
|
||||||
|
tbrow.addView(t2v);
|
||||||
|
TextView t3v = new TextView(this);
|
||||||
|
t3v.setText(adcval+" ");
|
||||||
|
t3v.setGravity(Gravity.CENTER);
|
||||||
|
tbrow.addView(t3v);
|
||||||
|
TextView t4v = new TextView(this);
|
||||||
|
t4v.setText(avgadc+" ");
|
||||||
|
t4v.setGravity(Gravity.CENTER);
|
||||||
|
tbrow.addView(t4v);
|
||||||
|
|
||||||
|
TextView t5v = new TextView(this);
|
||||||
|
t5v.setText(delta+" ");
|
||||||
|
t5v.setGravity(Gravity.CENTER);
|
||||||
|
tbrow.addView(t5v);
|
||||||
|
|
||||||
|
|
||||||
|
TextView t6v = new TextView(this);
|
||||||
|
t6v.setText(" "+result);
|
||||||
|
t6v.setGravity(Gravity.CENTER);
|
||||||
|
|
||||||
|
tbrow.addView(t6v);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
stk.addView(tbrow);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* TableRow tbrow0 = new TableRow(this);
|
||||||
|
TextView tv0 = new TextView(this);
|
||||||
|
tv0.setText(" Sl.No ");
|
||||||
|
tv0.setTextColor(Color.WHITE);
|
||||||
|
tbrow0.addView(tv0);
|
||||||
|
TextView tv1 = new TextView(this);
|
||||||
|
tv1.setText(" Product ");
|
||||||
|
tv1.setTextColor(Color.WHITE);
|
||||||
|
tbrow0.addView(tv1);
|
||||||
|
TextView tv2 = new TextView(this);
|
||||||
|
tv2.setText(" Unit Price ");
|
||||||
|
tv2.setTextColor(Color.WHITE);
|
||||||
|
tbrow0.addView(tv2);
|
||||||
|
TextView tv3 = new TextView(this);
|
||||||
|
tv3.setText(" Stock Remaining ");
|
||||||
|
tv3.setTextColor(Color.WHITE);
|
||||||
|
tbrow0.addView(tv3);
|
||||||
|
stk.addView(tbrow0);*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void init1(String sno ) {
|
||||||
|
|
||||||
|
TableLayout stk = (TableLayout) findViewById(R.id.table_main);
|
||||||
|
|
||||||
|
TableRow tbrow0 = new TableRow(this);
|
||||||
|
TextView tv0 = new TextView(this);
|
||||||
|
tv0.setText(" Sl.No ");
|
||||||
|
tbrow0.addView(tv0);
|
||||||
|
TextView tv1 = new TextView(this);
|
||||||
|
tv1.setText(" Product ");
|
||||||
|
tbrow0.addView(tv1);
|
||||||
|
TextView tv2 = new TextView(this);
|
||||||
|
tv2.setText(" Unit Price ");
|
||||||
|
tbrow0.addView(tv2);
|
||||||
|
TextView tv3 = new TextView(this);
|
||||||
|
tv3.setText(" Stock Remaining ");
|
||||||
|
tbrow0.addView(tv3);
|
||||||
|
stk.addView(tbrow0);
|
||||||
|
TableRow tbrow = new TableRow(this);
|
||||||
|
TextView t1v = new TextView(this);
|
||||||
|
t1v.setText("" + sno);
|
||||||
|
t1v.setGravity(Gravity.CENTER);
|
||||||
|
tbrow.addView(t1v);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
stk.addView(tbrow);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* TableRow tbrow0 = new TableRow(this);
|
||||||
|
TextView tv0 = new TextView(this);
|
||||||
|
tv0.setText(" Sl.No ");
|
||||||
|
tv0.setTextColor(Color.WHITE);
|
||||||
|
tbrow0.addView(tv0);
|
||||||
|
TextView tv1 = new TextView(this);
|
||||||
|
tv1.setText(" Product ");
|
||||||
|
tv1.setTextColor(Color.WHITE);
|
||||||
|
tbrow0.addView(tv1);
|
||||||
|
TextView tv2 = new TextView(this);
|
||||||
|
tv2.setText(" Unit Price ");
|
||||||
|
tv2.setTextColor(Color.WHITE);
|
||||||
|
tbrow0.addView(tv2);
|
||||||
|
TextView tv3 = new TextView(this);
|
||||||
|
tv3.setText(" Stock Remaining ");
|
||||||
|
tv3.setTextColor(Color.WHITE);
|
||||||
|
tbrow0.addView(tv3);
|
||||||
|
stk.addView(tbrow0);*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
MenuInflater inflater = getMenuInflater();
|
||||||
|
inflater.inflate(R.menu.menu2, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.nav_graph:
|
||||||
|
startActivity(new Intent(this, ViewGraph.class));
|
||||||
|
return true;
|
||||||
|
*/
|
||||||
|
/* return true;
|
||||||
|
case R.id.help:
|
||||||
|
startActivity(new Intent(this, Help.class));
|
||||||
|
return true;*//*
|
||||||
|
|
||||||
|
default:
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* private BottomNavigationView.OnNavigationItemSelectedListener navListener =
|
||||||
|
new BottomNavigationView.OnNavigationItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
||||||
|
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.nav_graph:
|
||||||
|
Intent intent=new Intent(ViewSamples.this, ViewGraph.class);
|
||||||
|
|
||||||
|
intent.putExtra("pid",testid);
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
case R.id.nav_home:
|
||||||
|
Intent intent2 = new Intent(ViewSamples.this, MainActivity.class);
|
||||||
|
|
||||||
|
startActivity(intent2);
|
||||||
|
break;
|
||||||
|
case R.id.nav_excel:
|
||||||
|
shared();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
public void shared() {
|
||||||
|
String directory_path = Environment.getExternalStorageDirectory().getPath() + "/Test Report/";
|
||||||
|
String pat= directory_path + "Report_" + testid + ".xls";
|
||||||
|
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
File file = new File(pat);
|
||||||
|
Uri path = FileProvider.getUriForFile(getApplicationContext(), "no.Reader.android.iisc.fileprovider", file);
|
||||||
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
intent.setDataAndType(path, "application/vnd.ms-excel");
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
MenuInflater inflater = getMenuInflater();
|
||||||
|
inflater.inflate(R.menu.menu2, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.nav_graph:
|
||||||
|
Intent intent=new Intent(ViewSamples.this, ViewGraph.class);
|
||||||
|
|
||||||
|
intent.putExtra("pid",testid);
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
case R.id.nav_home:
|
||||||
|
Intent intent2 = new Intent(ViewSamples.this, MainActivity.class);
|
||||||
|
|
||||||
|
startActivity(intent2);
|
||||||
|
return true;
|
||||||
|
case R.id.nav_excel:
|
||||||
|
shared();
|
||||||
|
return true;
|
||||||
|
case R.id.nav_share:
|
||||||
|
srk();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void srk()
|
||||||
|
{
|
||||||
|
if(ContextCompat.checkSelfPermission(ViewSamples.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
|
||||||
|
{
|
||||||
|
|
||||||
|
ActivityCompat.requestPermissions(ViewSamples.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},23);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String directory_path = Environment.getExternalStorageDirectory().getPath() + "/Test Report/";
|
||||||
|
String pat= directory_path + "Report_" + testid + ".xls";
|
||||||
|
|
||||||
|
File file = new File(pat);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Intent intent=new Intent(Intent.ACTION_SEND);
|
||||||
|
intent.putExtra(Intent.EXTRA_TEXT,"Report");
|
||||||
|
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N) {
|
||||||
|
Uri path= FileProvider.getUriForFile(ViewSamples.this,"no.Reader.android.iisc.fileprovider",file);
|
||||||
|
intent.putExtra(Intent.EXTRA_STREAM,path);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
intent.putExtra(Intent.EXTRA_STREAM,Uri.fromFile(file));
|
||||||
|
}
|
||||||
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
intent.setDataAndType(path, "application/vnd.ms-excel");
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package no.Reader.android.iisc.Reader.callback;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class defines your characteristic API.
|
||||||
|
* In this example (that is the HRM characteristic, which the template is based on), is notifying
|
||||||
|
* with a value (Heart Rate). The single method just returns the value and ignores other
|
||||||
|
* optional data from Heart Rate Measurement characteristic for simplicity.
|
||||||
|
*/
|
||||||
|
public interface SPCACharacteristicCallback {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a value is received.
|
||||||
|
*
|
||||||
|
* @param device a device from which the value was obtained.
|
||||||
|
* @param value the new value.
|
||||||
|
*/
|
||||||
|
void onSampleValueReceived(@NonNull final BluetoothDevice device, int value);
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package no.Reader.android.iisc.Reader.callback;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.ble.callback.profile.ProfileDataCallback;
|
||||||
|
import no.nordicsemi.android.ble.data.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a sample data callback, that's based on Heart Rate Measurement characteristic.
|
||||||
|
* It parses the HR value and ignores other optional data for simplicity.
|
||||||
|
* Check {@link no.nordicsemi.android.ble.common.callback.hr.HeartRateMeasurementDataCallback}
|
||||||
|
* for full implementation.
|
||||||
|
*
|
||||||
|
* TODO Modify the content to parse your data.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
public abstract class SPCADataCallback implements ProfileDataCallback, SPCACharacteristicCallback {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDataReceived(@NonNull final BluetoothDevice device, @NonNull final Data data) {
|
||||||
|
if (data.size() < 2) {
|
||||||
|
onInvalidDataReceived(device, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read flags
|
||||||
|
int offset = 0;
|
||||||
|
final int flags = data.getIntValue(Data.FORMAT_UINT8, offset);
|
||||||
|
final int hearRateType = (flags & 0x01) == 0 ? Data.FORMAT_UINT8 : Data.FORMAT_UINT16;
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
// Validate packet length. The type's lower nibble is its length.
|
||||||
|
if (data.size() < 1 + (hearRateType & 0x0F)) {
|
||||||
|
onInvalidDataReceived(device, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int value = data.getIntValue(hearRateType, offset);
|
||||||
|
// offset += hearRateType & 0xF;
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// Report the parsed value(s)
|
||||||
|
onSampleValueReceived(device, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
1654
app/src/main/java/no/Reader/android/iisc/Reader/check1.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package no.Reader.android.iisc.Reader.settings;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
public class SettingsActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_settings);
|
||||||
|
|
||||||
|
final Toolbar toolbar = findViewById(R.id.toolbar_actionbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
|
||||||
|
// Display the fragment as the main content.
|
||||||
|
getSupportFragmentManager().beginTransaction().replace(R.id.content, new SettingsFragment()).commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case android.R.id.home:
|
||||||
|
onBackPressed();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package no.Reader.android.iisc.Reader.settings;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.preference.PreferenceFragmentCompat;
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
public class SettingsFragment extends PreferenceFragmentCompat {
|
||||||
|
public static final String SETTINGS_DATA = "settings_template_data"; // TODO values matching those in settings_template.xml file in /res/xml
|
||||||
|
public static final int SETTINGS_VARIANT_A = 0;
|
||||||
|
public static final int SETTINGS_VARIANT_B = 1;
|
||||||
|
public static final int SETTINGS_VARIANT_DEFAULT = SETTINGS_VARIANT_A;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
|
||||||
|
addPreferencesFromResource(R.xml.settings_template);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
package no.Reader.android.iisc;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.nfc.NdefMessage;
|
||||||
|
import android.nfc.NdefRecord;
|
||||||
|
import android.nfc.NfcAdapter;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.animation.Animation;
|
||||||
|
import android.view.animation.AnimationUtils;
|
||||||
|
import android.widget.Button;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.Reader.LoginScreen;
|
||||||
|
import no.Reader.android.iisc.Reader.MainActivity;
|
||||||
|
|
||||||
|
public class SplashscreenActivity extends Activity {
|
||||||
|
/** Splash screen duration time inew n milliseconds */
|
||||||
|
private static final int DELAY = 1000;
|
||||||
|
Animation btnAnim ;
|
||||||
|
Button btnGetStarted;
|
||||||
|
private static int SPLASH_TIME_OUT=3000;
|
||||||
|
String number;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_splashscreen);
|
||||||
|
SharedPreferences preferences6 = getSharedPreferences("PhoneBook_number", MODE_PRIVATE);
|
||||||
|
|
||||||
|
number = preferences6.getString("Phone", null);
|
||||||
|
|
||||||
|
btnGetStarted=findViewById(R.id.started);
|
||||||
|
btnGetStarted.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
|
||||||
|
if (number == null ) {
|
||||||
|
|
||||||
|
|
||||||
|
Intent home = new Intent(SplashscreenActivity.this, LoginScreen.class);
|
||||||
|
startActivity(home);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final Intent newIntent = new Intent(SplashscreenActivity.this, MainActivity.class);
|
||||||
|
newIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||||
|
btnGetStarted.setAnimation(btnAnim);
|
||||||
|
|
||||||
|
|
||||||
|
// Handle NFC message, if app was opened using NFC AAR record
|
||||||
|
final Intent intent = getIntent();
|
||||||
|
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
|
||||||
|
final Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
|
||||||
|
if (rawMsgs != null) {
|
||||||
|
for (Parcelable rawMsg : rawMsgs) {
|
||||||
|
final NdefMessage msg = (NdefMessage) rawMsg;
|
||||||
|
final NdefRecord[] records = msg.getRecords();
|
||||||
|
|
||||||
|
for (NdefRecord record : records) {
|
||||||
|
if (record.getTnf() == NdefRecord.TNF_MIME_MEDIA) {
|
||||||
|
switch (record.toMimeType()) {
|
||||||
|
case FeaturesActivity.EXTRA_APP:
|
||||||
|
newIntent.putExtra(FeaturesActivity.EXTRA_APP, new String(record.getPayload()));
|
||||||
|
break;
|
||||||
|
case FeaturesActivity.EXTRA_ADDRESS:
|
||||||
|
newIntent.putExtra(FeaturesActivity.EXTRA_ADDRESS, invertEndianness(record.getPayload()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startActivity(newIntent);
|
||||||
|
finish();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnAnim = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.button_animation);
|
||||||
|
btnGetStarted.setAnimation(btnAnim);
|
||||||
|
|
||||||
|
|
||||||
|
// Jump to SensorsActivity after DELAY milliseconds
|
||||||
|
/*
|
||||||
|
new Handler().postDelayed(() -> {
|
||||||
|
final Intent newIntent = new Intent(SplashscreenActivity.this, TemplateActivity.class);
|
||||||
|
newIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||||
|
|
||||||
|
|
||||||
|
// Handle NFC message, if app was opened using NFC AAR record
|
||||||
|
final Intent intent = getIntent();
|
||||||
|
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
|
||||||
|
final Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
|
||||||
|
if (rawMsgs != null) {
|
||||||
|
for (Parcelable rawMsg : rawMsgs) {
|
||||||
|
final NdefMessage msg = (NdefMessage) rawMsg;
|
||||||
|
final NdefRecord[] records = msg.getRecords();
|
||||||
|
|
||||||
|
for (NdefRecord record : records) {
|
||||||
|
if (record.getTnf() == NdefRecord.TNF_MIME_MEDIA) {
|
||||||
|
switch (record.toMimeType()) {
|
||||||
|
case FeaturesActivity.EXTRA_APP:
|
||||||
|
newIntent.putExtra(FeaturesActivity.EXTRA_APP, new String(record.getPayload()));
|
||||||
|
break;
|
||||||
|
case FeaturesActivity.EXTRA_ADDRESS:
|
||||||
|
newIntent.putExtra(FeaturesActivity.EXTRA_ADDRESS, invertEndianness(record.getPayload()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startActivity(newIntent);
|
||||||
|
finish();
|
||||||
|
}, DELAY);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
// do nothing. Protect from exiting the application when splash screen is shown
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inverts endianness of the byte array.
|
||||||
|
* @param bytes input byte array
|
||||||
|
* @return byte array in opposite order
|
||||||
|
*/
|
||||||
|
private byte[] invertEndianness(final byte[] bytes) {
|
||||||
|
if (bytes == null)
|
||||||
|
return null;
|
||||||
|
final int length = bytes.length;
|
||||||
|
final byte[] result = new byte[length];
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
result[i] = bytes[length - i - 1];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
100
app/src/main/java/no/Reader/android/iisc/adapter/AppAdapter.java
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
package no.Reader.android.iisc.adapter;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
|
||||||
|
public class AppAdapter extends BaseAdapter {
|
||||||
|
private static final String CATEGORY = "no.Reader.android.iisc.LAUNCHER";
|
||||||
|
private static final String NRF_CONNECT_PACKAGE = "no.nordicsemi.android.mcp";
|
||||||
|
|
||||||
|
private final Context mContext;
|
||||||
|
private final PackageManager mPackageManager;
|
||||||
|
private final LayoutInflater mInflater;
|
||||||
|
private final List<ResolveInfo> mApplications;
|
||||||
|
|
||||||
|
public AppAdapter(final Context context) {
|
||||||
|
mContext = context;
|
||||||
|
mInflater = LayoutInflater.from(context);
|
||||||
|
|
||||||
|
// get nRF installed app plugins from package manager
|
||||||
|
final PackageManager pm = mPackageManager = context.getPackageManager();
|
||||||
|
final Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||||
|
intent.addCategory(CATEGORY);
|
||||||
|
|
||||||
|
final List<ResolveInfo> appList = mApplications = pm.queryIntentActivities(intent, 0);
|
||||||
|
// TODO remove the following loop after some time, when there will be no more MCP 1.1 at the market.
|
||||||
|
for (final ResolveInfo info : appList) {
|
||||||
|
if (NRF_CONNECT_PACKAGE.equals(info.activityInfo.packageName)) {
|
||||||
|
appList.remove(info);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.sort(appList, new ResolveInfo.DisplayNameComparator(pm));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return mApplications.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getItem(int position) {
|
||||||
|
return mApplications.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
View view = convertView;
|
||||||
|
if (view == null) {
|
||||||
|
view = mInflater.inflate(R.layout.feature_icon, parent, false);
|
||||||
|
|
||||||
|
final ViewHolder holder = new ViewHolder();
|
||||||
|
holder.view = view;
|
||||||
|
holder.icon = view.findViewById(R.id.icon);
|
||||||
|
holder.label = view.findViewById(R.id.label);
|
||||||
|
view.setTag(holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ResolveInfo info = mApplications.get(position);
|
||||||
|
final PackageManager pm = mPackageManager;
|
||||||
|
|
||||||
|
final ViewHolder holder = (ViewHolder) view.getTag();
|
||||||
|
holder.icon.setImageDrawable(info.loadIcon(pm));
|
||||||
|
holder.label.setText(info.loadLabel(pm).toString().toUpperCase(Locale.US));
|
||||||
|
holder.view.setOnClickListener(v -> {
|
||||||
|
final Intent intent = new Intent();
|
||||||
|
intent.setComponent(new ComponentName(info.activityInfo.packageName, info.activityInfo.name));
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||||
|
mContext.startActivity(intent);
|
||||||
|
});
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ViewHolder {
|
||||||
|
private View view;
|
||||||
|
private ImageView icon;
|
||||||
|
private TextView label;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,300 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2006 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package no.Reader.android.iisc.app;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import android.view.ContextMenu;
|
||||||
|
import android.view.ContextMenu.ContextMenuInfo;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnCreateContextMenuListener;
|
||||||
|
import android.widget.ExpandableListAdapter;
|
||||||
|
import android.widget.ExpandableListView;
|
||||||
|
import android.widget.SimpleCursorTreeAdapter;
|
||||||
|
import android.widget.SimpleExpandableListAdapter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An activity that displays an expandable list of items by binding to a data source implementing the ExpandableListAdapter, and exposes event handlers when the
|
||||||
|
* user selects an item.
|
||||||
|
* <p>
|
||||||
|
* ExpandableListActivity hosts a {@link android.widget.ExpandableListView ExpandableListView} object that can be bound to different data sources that provide a
|
||||||
|
* two-levels of data (the top-level is group, and below each group are children). Binding, screen layout, and row layout are discussed in the following
|
||||||
|
* sections.
|
||||||
|
* <p>
|
||||||
|
* <strong>Screen Layout</strong>
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* ExpandableListActivity has a default layout that consists of a single, full-screen, centered expandable list. However, if you desire, you can customize the
|
||||||
|
* screen layout by setting your own view layout with setContentView() in onCreate(). To do this, your own view MUST contain an ExpandableListView object with
|
||||||
|
* the id "@android:id/list" (or {@link android.R.id#list} if it's in code)
|
||||||
|
* <p>
|
||||||
|
* Optionally, your custom view can contain another view object of any type to display when the list view is empty. This "empty list" notifier must have an id
|
||||||
|
* "android:empty". Note that when an empty view is present, the expandable list view will be hidden when there is no data to display.
|
||||||
|
* <p>
|
||||||
|
* The following code demonstrates an (ugly) custom screen layout. It has a list with a green background, and an alternate red "no data" message.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* <?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
* <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
* android:orientation="vertical"
|
||||||
|
* android:layout_width="match_parent"
|
||||||
|
* android:layout_height="match_parent"
|
||||||
|
* android:paddingLeft="8dp"
|
||||||
|
* android:paddingRight="8dp">
|
||||||
|
*
|
||||||
|
* <ExpandableListView android:id="@id/android:list"
|
||||||
|
* android:layout_width="match_parent"
|
||||||
|
* android:layout_height="match_parent"
|
||||||
|
* android:background="#00FF00"
|
||||||
|
* android:layout_weight="1"
|
||||||
|
* android:drawSelectorOnTop="false"/>
|
||||||
|
*
|
||||||
|
* <TextView android:id="@id/android:empty"
|
||||||
|
* android:layout_width="match_parent"
|
||||||
|
* android:layout_height="match_parent"
|
||||||
|
* android:background="#FF0000"
|
||||||
|
* android:text="No data"/>
|
||||||
|
* </LinearLayout>
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* <strong>Row Layout</strong>
|
||||||
|
* </p>
|
||||||
|
* The {@link ExpandableListAdapter} set in the {@link ExpandableListActivity} via {@link #setListAdapter(ExpandableListAdapter)} provides the {@link View}s for
|
||||||
|
* each row. This adapter has separate methods for providing the group {@link View}s and child {@link View}s. There are a couple provided
|
||||||
|
* {@link ExpandableListAdapter}s that simplify use of adapters: {@link SimpleCursorTreeAdapter} and {@link SimpleExpandableListAdapter}.
|
||||||
|
* <p>
|
||||||
|
* With these, you can specify the layout of individual rows for groups and children in the list. These constructor takes a few parameters that specify layout
|
||||||
|
* resources for groups and children. It also has additional parameters that let you specify which data field to associate with which object in the row layout
|
||||||
|
* resource. The {@link SimpleCursorTreeAdapter} fetches data from {@link Cursor}s and the {@link SimpleExpandableListAdapter} fetches data from {@link List}s
|
||||||
|
* of {@link Map}s.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Android provides some standard row layout resources. These are in the {@link android.R.layout} class, and have names such as simple_list_item_1,
|
||||||
|
* simple_list_item_2, and two_line_list_item. The following layout XML is the source for the resource two_line_list_item, which displays two data fields,one
|
||||||
|
* above the other, for each list row.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* <?xml version="1.0" encoding="utf-8"?>
|
||||||
|
* <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
* android:layout_width="match_parent"
|
||||||
|
* android:layout_height="wrap_content"
|
||||||
|
* android:orientation="vertical">
|
||||||
|
*
|
||||||
|
* <TextView android:id="@+id/text1"
|
||||||
|
* android:textSize="16sp"
|
||||||
|
* android:textStyle="bold"
|
||||||
|
* android:layout_width="match_parent"
|
||||||
|
* android:layout_height="wrap_content"/>
|
||||||
|
*
|
||||||
|
* <TextView android:id="@+id/text2"
|
||||||
|
* android:textSize="16sp"
|
||||||
|
* android:layout_width="match_parent"
|
||||||
|
* android:layout_height="wrap_content"/>
|
||||||
|
* </LinearLayout>
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* You must identify the data bound to each TextView object in this layout. The syntax for this is discussed in the next section.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* <strong>Binding to Data</strong>
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* You bind the ExpandableListActivity's ExpandableListView object to data using a class that implements the {@link android.widget.ExpandableListAdapter
|
||||||
|
* ExpandableListAdapter} interface. Android provides two standard list adapters: {@link android.widget.SimpleExpandableListAdapter SimpleExpandableListAdapter}
|
||||||
|
* for static data (Maps), and {@link android.widget.SimpleCursorTreeAdapter SimpleCursorTreeAdapter} for Cursor query results.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @see #setListAdapter
|
||||||
|
* @see android.widget.ExpandableListView
|
||||||
|
*/
|
||||||
|
public class ExpandableListActivity extends AppCompatActivity implements
|
||||||
|
OnCreateContextMenuListener,
|
||||||
|
ExpandableListView.OnChildClickListener, ExpandableListView.OnGroupCollapseListener,
|
||||||
|
ExpandableListView.OnGroupExpandListener {
|
||||||
|
ExpandableListAdapter mAdapter;
|
||||||
|
ExpandableListView mList;
|
||||||
|
boolean mFinishedStart = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this to populate the context menu when an item is long pressed. menuInfo will contain an
|
||||||
|
* {@link android.widget.ExpandableListView.ExpandableListContextMenuInfo} whose packedPosition is a packed position that should be used with
|
||||||
|
* {@link ExpandableListView#getPackedPositionType(long)} and the other similar methods.
|
||||||
|
* <p>
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this for receiving callbacks when a child has been clicked.
|
||||||
|
* <p>
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
|
||||||
|
int childPosition, long id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this for receiving callbacks when a group has been collapsed.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onGroupCollapse(int groupPosition) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this for receiving callbacks when a group has been expanded.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onGroupExpand(int groupPosition) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures the expandable list view has been created before Activity restores all of the view states.
|
||||||
|
*
|
||||||
|
* @see Activity#onRestoreInstanceState(Bundle)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void onRestoreInstanceState(@NonNull Bundle state) {
|
||||||
|
ensureList();
|
||||||
|
super.onRestoreInstanceState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the screen state (current list and other views) when the content changes.
|
||||||
|
*
|
||||||
|
* @see androidx.appcompat.app.AppCompatActivity#onContentChanged()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onContentChanged() {
|
||||||
|
super.onContentChanged();
|
||||||
|
View emptyView = findViewById(R.id.empty);
|
||||||
|
mList = findViewById(R.id.list);
|
||||||
|
if (mList == null) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"Your content must have a ExpandableListView whose id attribute is " +
|
||||||
|
"'R.id.list'");
|
||||||
|
}
|
||||||
|
if (emptyView != null) {
|
||||||
|
mList.setEmptyView(emptyView);
|
||||||
|
}
|
||||||
|
mList.setOnChildClickListener(this);
|
||||||
|
mList.setOnGroupExpandListener(this);
|
||||||
|
mList.setOnGroupCollapseListener(this);
|
||||||
|
|
||||||
|
if (mFinishedStart) {
|
||||||
|
setListAdapter(mAdapter);
|
||||||
|
}
|
||||||
|
mFinishedStart = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide the adapter for the expandable list.
|
||||||
|
*/
|
||||||
|
public void setListAdapter(ExpandableListAdapter adapter) {
|
||||||
|
synchronized (this) {
|
||||||
|
ensureList();
|
||||||
|
mAdapter = adapter;
|
||||||
|
mList.setAdapter(adapter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the activity's expandable list view widget. This can be used to get the selection, set the selection, and many other useful functions.
|
||||||
|
*
|
||||||
|
* @see ExpandableListView
|
||||||
|
*/
|
||||||
|
public ExpandableListView getExpandableListView() {
|
||||||
|
ensureList();
|
||||||
|
return mList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the ExpandableListAdapter associated with this activity's ExpandableListView.
|
||||||
|
*/
|
||||||
|
public ExpandableListAdapter getExpandableListAdapter() {
|
||||||
|
return mAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureList() {
|
||||||
|
if (mList != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setContentView(R.layout.expandable_list_content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ID of the currently selected group or child.
|
||||||
|
*
|
||||||
|
* @return The ID of the currently selected group or child.
|
||||||
|
*/
|
||||||
|
public long getSelectedId() {
|
||||||
|
return mList.getSelectedId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the position (in packed position representation) of the currently selected group or child. Use {@link ExpandableListView#getPackedPositionType},
|
||||||
|
* {@link ExpandableListView#getPackedPositionGroup}, and {@link ExpandableListView#getPackedPositionChild} to unpack the returned packed position.
|
||||||
|
*
|
||||||
|
* @return A packed position representation containing the currently selected group or child's position and type.
|
||||||
|
*/
|
||||||
|
public long getSelectedPosition() {
|
||||||
|
return mList.getSelectedPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the selection to the specified child. If the child is in a collapsed group, the group will only be expanded and child subsequently selected if
|
||||||
|
* shouldExpandGroup is set to true, otherwise the method will return false.
|
||||||
|
*
|
||||||
|
* @param groupPosition
|
||||||
|
* The position of the group that contains the child.
|
||||||
|
* @param childPosition
|
||||||
|
* The position of the child within the group.
|
||||||
|
* @param shouldExpandGroup
|
||||||
|
* Whether the child's group should be expanded if it is collapsed.
|
||||||
|
* @return Whether the selection was successfully set on the child.
|
||||||
|
*/
|
||||||
|
public boolean setSelectedChild(int groupPosition, int childPosition, boolean shouldExpandGroup) {
|
||||||
|
return mList.setSelectedChild(groupPosition, childPosition, shouldExpandGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the selection to the specified group.
|
||||||
|
*
|
||||||
|
* @param groupPosition
|
||||||
|
* The position of the group that should be selected.
|
||||||
|
*/
|
||||||
|
public void setSelectedGroup(int groupPosition) {
|
||||||
|
mList.setSelectedGroup(groupPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
package no.Reader.android.iisc.battery;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.bluetooth.BluetoothGatt;
|
||||||
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
|
import android.bluetooth.BluetoothGattService;
|
||||||
|
import android.content.Context;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.ble.BleManager;
|
||||||
|
import no.nordicsemi.android.ble.callback.DataReceivedCallback;
|
||||||
|
import no.nordicsemi.android.ble.common.callback.battery.BatteryLevelDataCallback;
|
||||||
|
import no.nordicsemi.android.ble.data.Data;
|
||||||
|
import no.nordicsemi.android.log.LogContract;
|
||||||
|
import no.Reader.android.iisc.profile.LoggableBleManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Ble Manager with Battery Service support.
|
||||||
|
*
|
||||||
|
* @param <T> The profile callbacks type.
|
||||||
|
* @see BleManager
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public abstract class BatteryManager<T extends BatteryManagerCallbacks> extends LoggableBleManager<T> {
|
||||||
|
/** Battery Service UUID. */
|
||||||
|
private final static UUID BATTERY_SERVICE_UUID = UUID.fromString("0000180F-0000-1000-8000-00805f9b34fb");
|
||||||
|
/** Battery Level characteristic UUID. */
|
||||||
|
private final static UUID BATTERY_LEVEL_CHARACTERISTIC_UUID = UUID.fromString("00002A19-0000-1000-8000-00805f9b34fb");
|
||||||
|
|
||||||
|
private BluetoothGattCharacteristic mBatteryLevelCharacteristic;
|
||||||
|
/** Last received Battery Level value. */
|
||||||
|
private Integer mBatteryLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The manager constructor.
|
||||||
|
*
|
||||||
|
* @param context context.
|
||||||
|
*/
|
||||||
|
public BatteryManager(final Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DataReceivedCallback mBatteryLevelDataCallback = new BatteryLevelDataCallback() {
|
||||||
|
@Override
|
||||||
|
public void onBatteryLevelChanged(@NonNull final BluetoothDevice device, final int batteryLevel) {
|
||||||
|
log(LogContract.Log.Level.APPLICATION,"Battery Level received: " + batteryLevel + "%");
|
||||||
|
mBatteryLevel = batteryLevel;
|
||||||
|
mCallbacks.onBatteryLevelChanged(device, batteryLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInvalidDataReceived(@NonNull final BluetoothDevice device, final @NonNull Data data) {
|
||||||
|
log(Log.WARN, "Invalid Battery Level data received: " + data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public void readBatteryLevelCharacteristic() {
|
||||||
|
if (isConnected()) {
|
||||||
|
readCharacteristic(mBatteryLevelCharacteristic)
|
||||||
|
.with(mBatteryLevelDataCallback)
|
||||||
|
.fail((device, status) -> log(Log.WARN,"Battery Level characteristic not found"))
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enableBatteryLevelCharacteristicNotifications() {
|
||||||
|
if (isConnected()) {
|
||||||
|
// If the Battery Level characteristic is null, the request will be ignored
|
||||||
|
setNotificationCallback(mBatteryLevelCharacteristic)
|
||||||
|
.with(mBatteryLevelDataCallback);
|
||||||
|
enableNotifications(mBatteryLevelCharacteristic)
|
||||||
|
.done(device -> log(Log.INFO, "Battery Level notifications enabled"))
|
||||||
|
.fail((device, status) -> log(Log.WARN, "Battery Level characteristic not found"))
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables Battery Level notifications on the Server.
|
||||||
|
*/
|
||||||
|
public void disableBatteryLevelCharacteristicNotifications() {
|
||||||
|
if (isConnected()) {
|
||||||
|
disableNotifications(mBatteryLevelCharacteristic)
|
||||||
|
.done(device -> log(Log.INFO, "Battery Level notifications disabled"))
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the last received Battery Level value.
|
||||||
|
* The value is set to null when the device disconnects.
|
||||||
|
* @return Battery Level value, in percent.
|
||||||
|
*/
|
||||||
|
public Integer getBatteryLevel() {
|
||||||
|
return mBatteryLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract class BatteryManagerGattCallback extends BleManagerGattCallback {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initialize() {
|
||||||
|
readBatteryLevelCharacteristic();
|
||||||
|
enableBatteryLevelCharacteristicNotifications();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isOptionalServiceSupported(@NonNull final BluetoothGatt gatt) {
|
||||||
|
final BluetoothGattService service = gatt.getService(BATTERY_SERVICE_UUID);
|
||||||
|
if (service != null) {
|
||||||
|
mBatteryLevelCharacteristic = service.getCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID);
|
||||||
|
}
|
||||||
|
return mBatteryLevelCharacteristic != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDeviceDisconnected() {
|
||||||
|
mBatteryLevelCharacteristic = null;
|
||||||
|
mBatteryLevel = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package no.Reader.android.iisc.battery;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.ble.BleManagerCallbacks;
|
||||||
|
import no.nordicsemi.android.ble.common.profile.battery.BatteryLevelCallback;
|
||||||
|
|
||||||
|
public interface BatteryManagerCallbacks extends BleManagerCallbacks, BatteryLevelCallback {
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package no.Reader.android.iisc.parser;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.ble.data.Data;
|
||||||
|
|
||||||
|
// TODO this method may be used for developing purposes to log the data from your device using the nRF Logger application.
|
||||||
|
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
public class SPCAParser {
|
||||||
|
// TODO add some flags, if needed
|
||||||
|
private static final byte HEART_RATE_VALUE_FORMAT = 0x01; // 1 bit
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method converts the value of the characteristic to the String. The String is then logged in the nRF logger log session
|
||||||
|
* @param data the characteristic data to be parsed
|
||||||
|
* @return human readable value of the characteristic
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("UnusedAssignment")
|
||||||
|
public static String parse(final Data data) {
|
||||||
|
int offset = 0;
|
||||||
|
int flags = 0;
|
||||||
|
int value=0;
|
||||||
|
if(data.getIntValue(Data.FORMAT_UINT8, offset++)!=null) {
|
||||||
|
flags = data.getIntValue(Data.FORMAT_UINT8, offset++);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In the template we are using the HRM values as an example.
|
||||||
|
* false Heart Rate Value Format is set to UINT8. Units: beats per minute (bpm)
|
||||||
|
* true Heart Rate Value Format is set to UINT16. Units: beats per minute (bpm)
|
||||||
|
*/
|
||||||
|
final boolean value16bit = (flags & HEART_RATE_VALUE_FORMAT) > 0;
|
||||||
|
|
||||||
|
// heart rate value is 8 or 16 bit long
|
||||||
|
if((data.getIntValue(value16bit ? Data.FORMAT_UINT16 : Data.FORMAT_UINT8, offset++)!=null))
|
||||||
|
{
|
||||||
|
value = data.getIntValue(value16bit ? Data.FORMAT_UINT16 : Data.FORMAT_UINT8, offset++); // bits per minute
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value16bit)
|
||||||
|
offset++;
|
||||||
|
|
||||||
|
// TODO parse more data
|
||||||
|
|
||||||
|
return "Template Measurement: " + value + " bpm";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,398 @@
|
|||||||
|
package no.Reader.android.iisc.profile;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.bluetooth.BluetoothManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.ble.BleManagerCallbacks;
|
||||||
|
import no.nordicsemi.android.log.ILogSession;
|
||||||
|
import no.nordicsemi.android.log.LocalLogSession;
|
||||||
|
import no.nordicsemi.android.log.Logger;
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.scanner.ScannerFragment;
|
||||||
|
import no.Reader.android.iisc.DebugLogger;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public abstract class BleProfileActivity extends AppCompatActivity implements BleManagerCallbacks, ScannerFragment.OnDeviceSelectedListener {
|
||||||
|
private static final String TAG = "BaseProfileActivity";
|
||||||
|
|
||||||
|
private static final String SIS_CONNECTION_STATUS = "connection_status";
|
||||||
|
private static final String SIS_DEVICE_NAME = "device_name";
|
||||||
|
protected static final int REQUEST_ENABLE_BT = 2;
|
||||||
|
|
||||||
|
private LoggableBleManager<? extends BleManagerCallbacks> mBleManager;
|
||||||
|
|
||||||
|
private TextView mDeviceNameView;
|
||||||
|
private Button mConnectButton;
|
||||||
|
private ILogSession mLogSession;
|
||||||
|
|
||||||
|
private boolean mDeviceConnected = false;
|
||||||
|
private String mDeviceName;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
ensureBLESupported();
|
||||||
|
if (!isBLEEnabled()) {
|
||||||
|
showBLEDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We use the managers using a singleton pattern. It's not recommended for the Android, because the singleton instance remains after Activity has been
|
||||||
|
* destroyed but it's simple and is used only for this demo purpose. In final application Managers should be created as a non-static objects in
|
||||||
|
* Services. The Service should implement ManagerCallbacks interface. The application Activity may communicate with such Service using binding,
|
||||||
|
* broadcast listeners, local broadcast listeners (see support.v4 library), or messages. See the Proximity profile for Service approach.
|
||||||
|
*/
|
||||||
|
mBleManager = initializeManager();
|
||||||
|
|
||||||
|
// In onInitialize method a final class may register local broadcast receivers that will listen for events from the service
|
||||||
|
onInitialize(savedInstanceState);
|
||||||
|
// The onCreateView class should... create the view
|
||||||
|
onCreateView(savedInstanceState);
|
||||||
|
|
||||||
|
final Toolbar toolbar = findViewById(R.id.toolbar_actionbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
// Common nRF Toolbox view references are obtained here
|
||||||
|
setUpView();
|
||||||
|
// View is ready to be used
|
||||||
|
onViewCreated(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* You may do some initialization here. This method is called from {@link #onCreate(Bundle)} before the view was created.
|
||||||
|
*/
|
||||||
|
protected void onInitialize(final Bundle savedInstanceState) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called from {@link #onCreate(Bundle)}. This method should build the activity UI, i.e. using {@link #setContentView(int)}.
|
||||||
|
* Use to obtain references to views. Connect/Disconnect button and the device name view are manager automatically.
|
||||||
|
*
|
||||||
|
* @param savedInstanceState contains the data it most recently supplied in {@link #onSaveInstanceState(Bundle)}.
|
||||||
|
* Note: <b>Otherwise it is null</b>.
|
||||||
|
*/
|
||||||
|
protected abstract void onCreateView(final Bundle savedInstanceState);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after the view has been created.
|
||||||
|
*
|
||||||
|
* @param savedInstanceState contains the data it most recently supplied in {@link #onSaveInstanceState(Bundle)}.
|
||||||
|
* Note: <b>Otherwise it is null</b>.
|
||||||
|
*/
|
||||||
|
protected void onViewCreated(final Bundle savedInstanceState) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after the view and the toolbar has been created.
|
||||||
|
*/
|
||||||
|
protected final void setUpView() {
|
||||||
|
// set GUI
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
mConnectButton = findViewById(R.id.action_connect);
|
||||||
|
mDeviceNameView = findViewById(R.id.device_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
mBleManager.disconnect().enqueue();
|
||||||
|
super.onBackPressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSaveInstanceState(final Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
outState.putBoolean(SIS_CONNECTION_STATUS, mDeviceConnected);
|
||||||
|
outState.putString(SIS_DEVICE_NAME, mDeviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestoreInstanceState(final @NonNull Bundle savedInstanceState) {
|
||||||
|
super.onRestoreInstanceState(savedInstanceState);
|
||||||
|
mDeviceConnected = savedInstanceState.getBoolean(SIS_CONNECTION_STATUS);
|
||||||
|
mDeviceName = savedInstanceState.getString(SIS_DEVICE_NAME);
|
||||||
|
|
||||||
|
if (mDeviceConnected) {
|
||||||
|
mConnectButton.setText(R.string.action_disconnect);
|
||||||
|
} else {
|
||||||
|
mConnectButton.setText(R.string.action_connect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this method to handle menu actions other than home and about.
|
||||||
|
*
|
||||||
|
* @param itemId the menu item id
|
||||||
|
* @return <code>true</code> if action has been handled
|
||||||
|
*/
|
||||||
|
protected boolean onOptionsItemSelected(final int itemId) {
|
||||||
|
// Overwrite when using menu other than R.menu.help
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when user press CONNECT or DISCONNECT button. See layout files -> onClick attribute.
|
||||||
|
*/
|
||||||
|
public void onConnectClicked(final View view) {
|
||||||
|
if (isBLEEnabled()) {
|
||||||
|
if (!mDeviceConnected) {
|
||||||
|
setDefaultUI();
|
||||||
|
showDeviceScanningDialog(getFilterUUID());
|
||||||
|
} else {
|
||||||
|
mBleManager.disconnect().enqueue();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showBLEDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the title resource id that will be used to create logger session. If 0 is returned (default) logger will not be used.
|
||||||
|
*
|
||||||
|
* @return the title resource id
|
||||||
|
*/
|
||||||
|
protected int getLoggerProfileTitle() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method may return the local log content provider authority if local log sessions are supported.
|
||||||
|
*
|
||||||
|
* @return local log session content provider URI
|
||||||
|
*/
|
||||||
|
protected Uri getLocalAuthorityLogger() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns whether autoConnect option should be used.
|
||||||
|
*
|
||||||
|
* @return true to use autoConnect feature, false (default) otherwise.
|
||||||
|
*/
|
||||||
|
protected boolean shouldAutoConnect() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceSelected(final BluetoothDevice device, final String name) {
|
||||||
|
final int titleId = getLoggerProfileTitle();
|
||||||
|
if (titleId > 0) {
|
||||||
|
mLogSession = Logger.newSession(getApplicationContext(), getString(titleId), device.getAddress(), name);
|
||||||
|
// If nRF Logger is not installed we may want to use local logger
|
||||||
|
if (mLogSession == null && getLocalAuthorityLogger() != null) {
|
||||||
|
mLogSession = LocalLogSession.newSession(getApplicationContext(), getLocalAuthorityLogger(), device.getAddress(), name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mDeviceName = name;
|
||||||
|
mBleManager.setLogger(mLogSession);
|
||||||
|
mBleManager.connect(device)
|
||||||
|
.useAutoConnect(shouldAutoConnect())
|
||||||
|
.retry(3, 100)
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDialogCanceled() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceConnecting(@NonNull final BluetoothDevice device) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
mDeviceNameView.setText(mDeviceName != null ? mDeviceName : getString(R.string.not_available));
|
||||||
|
mConnectButton.setText(R.string.action_connecting);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceConnected(@NonNull final BluetoothDevice device) {
|
||||||
|
mDeviceConnected = true;
|
||||||
|
runOnUiThread(() -> mConnectButton.setText(R.string.action_disconnect));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceDisconnecting(@NonNull final BluetoothDevice device) {
|
||||||
|
runOnUiThread(() -> mConnectButton.setText(R.string.action_disconnecting));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceDisconnected(@NonNull final BluetoothDevice device) {
|
||||||
|
mDeviceConnected = false;
|
||||||
|
mBleManager.close();
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
mConnectButton.setText(R.string.action_connect);
|
||||||
|
mDeviceNameView.setText(getDefaultDeviceName());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLinkLossOccurred(@NonNull final BluetoothDevice device) {
|
||||||
|
mDeviceConnected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServicesDiscovered(@NonNull final BluetoothDevice device, boolean optionalServicesFound) {
|
||||||
|
// this may notify user or show some views
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceReady(@NonNull final BluetoothDevice device) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBondingRequired(@NonNull final BluetoothDevice device) {
|
||||||
|
showToast(R.string.bonding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBonded(@NonNull final BluetoothDevice device) {
|
||||||
|
showToast(R.string.bonded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBondingFailed(@NonNull final BluetoothDevice device) {
|
||||||
|
showToast(R.string.bonding_failed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(@NonNull final BluetoothDevice device, @NonNull final String message, final int errorCode) {
|
||||||
|
DebugLogger.e(TAG, "Error occurred: " + message + ", error code: " + errorCode);
|
||||||
|
showToast(message + " (" + errorCode + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceNotSupported(@NonNull final BluetoothDevice device) {
|
||||||
|
showToast(R.string.not_supported);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a message as a Toast notification. This method is thread safe, you can call it from any thread
|
||||||
|
*
|
||||||
|
* @param message a message to be shown
|
||||||
|
*/
|
||||||
|
protected void showToast(final String message) {
|
||||||
|
runOnUiThread(() -> Toast.makeText(BleProfileActivity.this, message, Toast.LENGTH_SHORT).show());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a message as a Toast notification. This method is thread safe, you can call it from any thread
|
||||||
|
*
|
||||||
|
* @param messageResId an resource id of the message to be shown
|
||||||
|
*/
|
||||||
|
protected void showToast(final int messageResId) {
|
||||||
|
runOnUiThread(() -> Toast.makeText(BleProfileActivity.this, messageResId, Toast.LENGTH_SHORT).show());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if the device is connected. Services may not have been discovered yet.
|
||||||
|
*/
|
||||||
|
protected boolean isDeviceConnected() {
|
||||||
|
return mDeviceConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the device that the phone is currently connected to or was connected last time
|
||||||
|
*/
|
||||||
|
protected String getDeviceName() {
|
||||||
|
return mDeviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the Bluetooth Low Energy manager. A manager is used to communicate with profile's services.
|
||||||
|
*
|
||||||
|
* @return the manager that was created
|
||||||
|
*/
|
||||||
|
protected abstract LoggableBleManager<? extends BleManagerCallbacks> initializeManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the default UI before reconnecting
|
||||||
|
*/
|
||||||
|
protected abstract void setDefaultUI();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default device name resource id. The real device name is obtained when connecting to the device. This one is used when device has
|
||||||
|
* disconnected.
|
||||||
|
*
|
||||||
|
* @return the default device name resource id
|
||||||
|
*/
|
||||||
|
protected abstract int getDefaultDeviceName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the string resource id that will be shown in About box
|
||||||
|
*
|
||||||
|
* @return the about resource id
|
||||||
|
*/
|
||||||
|
protected abstract int getAboutTextId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The UUID filter is used to filter out available devices that does not have such UUID in their advertisement packet. See also:
|
||||||
|
* {@link #isChangingConfigurations()}.
|
||||||
|
*
|
||||||
|
* @return the required UUID or <code>null</code>
|
||||||
|
*/
|
||||||
|
protected abstract UUID getFilterUUID();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the scanner fragment.
|
||||||
|
*
|
||||||
|
* @param filter the UUID filter used to filter out available devices. The fragment will always show all bonded devices as there is no information about their
|
||||||
|
* services
|
||||||
|
* @see #getFilterUUID()
|
||||||
|
*/
|
||||||
|
private void showDeviceScanningDialog(final UUID filter) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
final ScannerFragment dialog = ScannerFragment.getInstance(filter);
|
||||||
|
dialog.show(getSupportFragmentManager(), "scan_fragment");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the log session. Log session is created when the device was selected using the {@link ScannerFragment} and released when user press DISCONNECT.
|
||||||
|
*
|
||||||
|
* @return the logger session or <code>null</code>
|
||||||
|
*/
|
||||||
|
protected ILogSession getLogSession() {
|
||||||
|
return mLogSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureBLESupported() {
|
||||||
|
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
|
||||||
|
Toast.makeText(this, R.string.no_ble, Toast.LENGTH_LONG).show();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isBLEEnabled() {
|
||||||
|
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
|
||||||
|
final BluetoothAdapter adapter = bluetoothManager.getAdapter();
|
||||||
|
return adapter != null && adapter.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void showBLEDialog() {
|
||||||
|
final Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
|
||||||
|
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,401 @@
|
|||||||
|
package no.Reader.android.iisc.profile;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.bluetooth.BluetoothManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.ble.BleManagerCallbacks;
|
||||||
|
import no.nordicsemi.android.log.ILogSession;
|
||||||
|
import no.nordicsemi.android.log.LocalLogSession;
|
||||||
|
import no.nordicsemi.android.log.Logger;
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.app.ExpandableListActivity;
|
||||||
|
import no.Reader.android.iisc.scanner.ScannerFragment;
|
||||||
|
import no.Reader.android.iisc.DebugLogger;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public abstract class BleProfileExpandableListActivity extends ExpandableListActivity implements BleManagerCallbacks, ScannerFragment.OnDeviceSelectedListener {
|
||||||
|
private static final String TAG = "BaseProfileActivity";
|
||||||
|
|
||||||
|
private static final String SIS_CONNECTION_STATUS = "connection_status";
|
||||||
|
private static final String SIS_DEVICE_NAME = "device_name";
|
||||||
|
protected static final int REQUEST_ENABLE_BT = 2;
|
||||||
|
|
||||||
|
private LoggableBleManager<? extends BleManagerCallbacks> mBleManager;
|
||||||
|
|
||||||
|
private TextView mDeviceNameView;
|
||||||
|
private Button mConnectButton;
|
||||||
|
private ILogSession mLogSession;
|
||||||
|
|
||||||
|
private boolean mDeviceConnected = false;
|
||||||
|
private String mDeviceName;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
ensureBLESupported();
|
||||||
|
if (!isBLEEnabled()) {
|
||||||
|
showBLEDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We use the managers using a singleton pattern. It's not recommended for the Android, because the singleton instance remains after Activity has been
|
||||||
|
* destroyed but it's simple and is used only for this demo purpose. In final application Managers should be created as a non-static objects in
|
||||||
|
* Services. The Service should implement ManagerCallbacks interface. The application Activity may communicate with such Service using binding,
|
||||||
|
* broadcast listeners, local broadcast listeners (see support.v4 library), or messages. See the Proximity profile for Service approach.
|
||||||
|
*/
|
||||||
|
mBleManager = initializeManager();
|
||||||
|
|
||||||
|
// In onInitialize method a final class may register local broadcast receivers that will listen for events from the service
|
||||||
|
onInitialize(savedInstanceState);
|
||||||
|
// The onCreateView class should... create the view
|
||||||
|
onCreateView(savedInstanceState);
|
||||||
|
|
||||||
|
final Toolbar toolbar = findViewById(R.id.toolbar_actionbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
// Common nRF Toolbox view references are obtained here
|
||||||
|
setUpView();
|
||||||
|
// View is ready to be used
|
||||||
|
onViewCreated(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* You may do some initialization here. This method is called from {@link #onCreate(Bundle)} before the view was created.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
protected void onInitialize(final Bundle savedInstanceState) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called from {@link #onCreate(Bundle)}. This method should build the activity UI, i.e. using {@link #setContentView(int)}.
|
||||||
|
* Use to obtain references to views. Connect/Disconnect button and the device name view are manager automatically.
|
||||||
|
*
|
||||||
|
* @param savedInstanceState contains the data it most recently supplied in {@link #onSaveInstanceState(Bundle)}.
|
||||||
|
* Note: <b>Otherwise it is null</b>.
|
||||||
|
*/
|
||||||
|
protected abstract void onCreateView(final Bundle savedInstanceState);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after the view has been created.
|
||||||
|
*
|
||||||
|
* @param savedInstanceState contains the data it most recently supplied in {@link #onSaveInstanceState(Bundle)}.
|
||||||
|
* Note: <b>Otherwise it is null</b>.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
protected void onViewCreated(final Bundle savedInstanceState) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after the view and the toolbar has been created.
|
||||||
|
*/
|
||||||
|
protected final void setUpView() {
|
||||||
|
// set GUI
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
mConnectButton = findViewById(R.id.action_connect);
|
||||||
|
mDeviceNameView = findViewById(R.id.device_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
mBleManager.disconnect().enqueue();
|
||||||
|
super.onBackPressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSaveInstanceState(final Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
outState.putBoolean(SIS_CONNECTION_STATUS, mDeviceConnected);
|
||||||
|
outState.putString(SIS_DEVICE_NAME, mDeviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestoreInstanceState(final @NonNull Bundle savedInstanceState) {
|
||||||
|
super.onRestoreInstanceState(savedInstanceState);
|
||||||
|
mDeviceConnected = savedInstanceState.getBoolean(SIS_CONNECTION_STATUS);
|
||||||
|
mDeviceName = savedInstanceState.getString(SIS_DEVICE_NAME);
|
||||||
|
|
||||||
|
if (mDeviceConnected) {
|
||||||
|
mConnectButton.setText(R.string.action_disconnect);
|
||||||
|
} else {
|
||||||
|
mConnectButton.setText(R.string.action_connect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this method to handle menu actions other than home and about.
|
||||||
|
*
|
||||||
|
* @param itemId the menu item id
|
||||||
|
* @return <code>true</code> if action has been handled
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
protected boolean onOptionsItemSelected(final int itemId) {
|
||||||
|
// Overwrite when using menu other than R.menu.help
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when user press CONNECT or DISCONNECT button. See layout files -> onClick attribute.
|
||||||
|
*/
|
||||||
|
public void onConnectClicked(final View view) {
|
||||||
|
if (isBLEEnabled()) {
|
||||||
|
if (!mDeviceConnected) {
|
||||||
|
setDefaultUI();
|
||||||
|
showDeviceScanningDialog(getFilterUUID());
|
||||||
|
} else {
|
||||||
|
mBleManager.disconnect().enqueue();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showBLEDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the title resource id that will be used to create logger session. If 0 is returned (default) logger will not be used.
|
||||||
|
*
|
||||||
|
* @return the title resource id
|
||||||
|
*/
|
||||||
|
protected int getLoggerProfileTitle() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method may return the local log content provider authority if local log sessions are supported.
|
||||||
|
*
|
||||||
|
* @return local log session content provider URI
|
||||||
|
*/
|
||||||
|
protected Uri getLocalAuthorityLogger() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns whether autoConnect option should be used.
|
||||||
|
*
|
||||||
|
* @return true to use autoConnect feature, false (default) otherwise.
|
||||||
|
*/
|
||||||
|
protected boolean shouldAutoConnect() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceSelected(final BluetoothDevice device, final String name) {
|
||||||
|
final int titleId = getLoggerProfileTitle();
|
||||||
|
if (titleId > 0) {
|
||||||
|
mLogSession = Logger.newSession(getApplicationContext(), getString(titleId), device.getAddress(), name);
|
||||||
|
// If nRF Logger is not installed we may want to use local logger
|
||||||
|
if (mLogSession == null && getLocalAuthorityLogger() != null) {
|
||||||
|
mLogSession = LocalLogSession.newSession(getApplicationContext(), getLocalAuthorityLogger(), device.getAddress(), name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mDeviceName = name;
|
||||||
|
mBleManager.setLogger(mLogSession);
|
||||||
|
mBleManager.connect(device)
|
||||||
|
.useAutoConnect(shouldAutoConnect())
|
||||||
|
.retry(3, 100)
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDialogCanceled() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceConnecting(@NonNull final BluetoothDevice device) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
mDeviceNameView.setText(mDeviceName != null ? mDeviceName : getString(R.string.not_available));
|
||||||
|
mConnectButton.setText(R.string.action_connecting);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceConnected(@NonNull final BluetoothDevice device) {
|
||||||
|
mDeviceConnected = true;
|
||||||
|
runOnUiThread(() -> mConnectButton.setText(R.string.action_disconnect));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceDisconnecting(@NonNull final BluetoothDevice device) {
|
||||||
|
runOnUiThread(() -> mConnectButton.setText(R.string.action_disconnecting));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceDisconnected(@NonNull final BluetoothDevice device) {
|
||||||
|
mDeviceConnected = false;
|
||||||
|
mBleManager.close();
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
mConnectButton.setText(R.string.action_connect);
|
||||||
|
mDeviceNameView.setText(getDefaultDeviceName());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLinkLossOccurred(@NonNull final BluetoothDevice device) {
|
||||||
|
mDeviceConnected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServicesDiscovered(@NonNull final BluetoothDevice device, boolean optionalServicesFound) {
|
||||||
|
// this may notify user or show some views
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceReady(@NonNull final BluetoothDevice device) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBondingRequired(@NonNull final BluetoothDevice device) {
|
||||||
|
showToast(R.string.bonding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBonded(@NonNull final BluetoothDevice device) {
|
||||||
|
showToast(R.string.bonded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBondingFailed(@NonNull final BluetoothDevice device) {
|
||||||
|
showToast(R.string.bonding_failed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(@NonNull final BluetoothDevice device, @NonNull final String message, final int errorCode) {
|
||||||
|
DebugLogger.e(TAG, "Error occurred: " + message + ", error code: " + errorCode);
|
||||||
|
showToast(message + " (" + errorCode + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceNotSupported(@NonNull final BluetoothDevice device) {
|
||||||
|
showToast(R.string.not_supported);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a message as a Toast notification. This method is thread safe, you can call it from any thread
|
||||||
|
*
|
||||||
|
* @param message a message to be shown
|
||||||
|
*/
|
||||||
|
protected void showToast(final String message) {
|
||||||
|
runOnUiThread(() -> Toast.makeText(BleProfileExpandableListActivity.this, message, Toast.LENGTH_SHORT).show());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a message as a Toast notification. This method is thread safe, you can call it from any thread
|
||||||
|
*
|
||||||
|
* @param messageResId an resource id of the message to be shown
|
||||||
|
*/
|
||||||
|
protected void showToast(final int messageResId) {
|
||||||
|
runOnUiThread(() -> Toast.makeText(BleProfileExpandableListActivity.this, messageResId, Toast.LENGTH_SHORT).show());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if the device is connected. Services may not have been discovered yet.
|
||||||
|
*/
|
||||||
|
protected boolean isDeviceConnected() {
|
||||||
|
return mDeviceConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the device that the phone is currently connected to or was connected last time
|
||||||
|
*/
|
||||||
|
protected String getDeviceName() {
|
||||||
|
return mDeviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the Bluetooth Low Energy manager. A manager is used to communicate with profile's services.
|
||||||
|
*
|
||||||
|
* @return the manager that was created
|
||||||
|
*/
|
||||||
|
protected abstract LoggableBleManager<? extends BleManagerCallbacks> initializeManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the default UI before reconnecting
|
||||||
|
*/
|
||||||
|
protected abstract void setDefaultUI();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default device name resource id. The real device name is obtained when connecting to the device. This one is used when device has
|
||||||
|
* disconnected.
|
||||||
|
*
|
||||||
|
* @return the default device name resource id
|
||||||
|
*/
|
||||||
|
protected abstract int getDefaultDeviceName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the string resource id that will be shown in About box
|
||||||
|
*
|
||||||
|
* @return the about resource id
|
||||||
|
*/
|
||||||
|
protected abstract int getAboutTextId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The UUID filter is used to filter out available devices that does not have such UUID in their advertisement packet. See also:
|
||||||
|
* {@link #isChangingConfigurations()}.
|
||||||
|
*
|
||||||
|
* @return the required UUID or <code>null</code>
|
||||||
|
*/
|
||||||
|
protected abstract UUID getFilterUUID();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the scanner fragment.
|
||||||
|
*
|
||||||
|
* @param filter the UUID filter used to filter out available devices. The fragment will always show all bonded devices as there is no information about their
|
||||||
|
* services
|
||||||
|
* @see #getFilterUUID()
|
||||||
|
*/
|
||||||
|
private void showDeviceScanningDialog(final UUID filter) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
final ScannerFragment dialog = ScannerFragment.getInstance(filter);
|
||||||
|
dialog.show(getSupportFragmentManager(), "scan_fragment");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the log session. Log session is created when the device was selected using the {@link ScannerFragment} and released when user press DISCONNECT.
|
||||||
|
*
|
||||||
|
* @return the logger session or <code>null</code>
|
||||||
|
*/
|
||||||
|
protected ILogSession getLogSession() {
|
||||||
|
return mLogSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureBLESupported() {
|
||||||
|
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
|
||||||
|
Toast.makeText(this, R.string.no_ble, Toast.LENGTH_LONG).show();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isBLEEnabled() {
|
||||||
|
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
|
||||||
|
final BluetoothAdapter adapter = bluetoothManager.getAdapter();
|
||||||
|
return adapter != null && adapter.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void showBLEDialog() {
|
||||||
|
final Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
|
||||||
|
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,582 @@
|
|||||||
|
package no.Reader.android.iisc.profile;
|
||||||
|
|
||||||
|
import android.app.Service;
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.bluetooth.BluetoothGatt;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Binder;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.StringRes;
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.ble.BleManager;
|
||||||
|
import no.nordicsemi.android.ble.BleManagerCallbacks;
|
||||||
|
import no.nordicsemi.android.ble.utils.ILogger;
|
||||||
|
import no.nordicsemi.android.log.ILogSession;
|
||||||
|
import no.nordicsemi.android.log.Logger;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public abstract class BleProfileService extends Service implements BleManagerCallbacks {
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static final String TAG = "BleProfileService";
|
||||||
|
|
||||||
|
public static final String BROADCAST_CONNECTION_STATE = "no.Reader.android.iisc.BROADCAST_CONNECTION_STATE";
|
||||||
|
public static final String BROADCAST_SERVICES_DISCOVERED = "no.Reader.android.iisc.BROADCAST_SERVICES_DISCOVERED";
|
||||||
|
public static final String BROADCAST_DEVICE_READY = "no.Reader.android.iisc.DEVICE_READY";
|
||||||
|
public static final String BROADCAST_BOND_STATE = "no.Reader.android.iisc.BROADCAST_BOND_STATE";
|
||||||
|
@Deprecated
|
||||||
|
public static final String BROADCAST_BATTERY_LEVEL = "no.Reader.android.iisc.BROADCAST_BATTERY_LEVEL";
|
||||||
|
public static final String BROADCAST_ERROR = "no.Reader.android.iisc.BROADCAST_ERROR";
|
||||||
|
|
||||||
|
/** The parameter passed when creating the service. Must contain the address of the sensor that we want to connect to */
|
||||||
|
public static final String EXTRA_DEVICE_ADDRESS = "no.Reader.android.iisc.EXTRA_DEVICE_ADDRESS";
|
||||||
|
/** The key for the device name that is returned in {@link #BROADCAST_CONNECTION_STATE} with state {@link #STATE_CONNECTED}. */
|
||||||
|
public static final String EXTRA_DEVICE_NAME = "no.Reader.android.iisc.EXTRA_DEVICE_NAME";
|
||||||
|
public static final String EXTRA_DEVICE = "no.Reader.android.iisc.EXTRA_DEVICE";
|
||||||
|
public static final String EXTRA_LOG_URI = "no.Reader.android.iisc.EXTRA_LOG_URI";
|
||||||
|
public static final String EXTRA_CONNECTION_STATE = "no.Reader.android.iisc.EXTRA_CONNECTION_STATE";
|
||||||
|
public static final String EXTRA_BOND_STATE = "no.Reader.android.iisc.EXTRA_BOND_STATE";
|
||||||
|
public static final String EXTRA_SERVICE_PRIMARY = "no.Reader.android.iisc.EXTRA_SERVICE_PRIMARY";
|
||||||
|
public static final String EXTRA_SERVICE_SECONDARY = "no.Reader.android.iisc.EXTRA_SERVICE_SECONDARY";
|
||||||
|
@Deprecated
|
||||||
|
public static final String EXTRA_BATTERY_LEVEL = "no.Reader.android.iisc.EXTRA_BATTERY_LEVEL";
|
||||||
|
public static final String EXTRA_ERROR_MESSAGE = "no.Reader.android.iisc.EXTRA_ERROR_MESSAGE";
|
||||||
|
public static final String EXTRA_ERROR_CODE = "no.Reader.android.iisc.EXTRA_ERROR_CODE";
|
||||||
|
|
||||||
|
public static final int STATE_LINK_LOSS = -1;
|
||||||
|
public static final int STATE_DISCONNECTED = 0;
|
||||||
|
public static final int STATE_CONNECTED = 1;
|
||||||
|
public static final int STATE_CONNECTING = 2;
|
||||||
|
public static final int STATE_DISCONNECTING = 3;
|
||||||
|
|
||||||
|
private LoggableBleManager<BleManagerCallbacks> mBleManager;
|
||||||
|
private Handler mHandler;
|
||||||
|
|
||||||
|
protected boolean mBound;
|
||||||
|
private boolean mActivityIsChangingConfiguration;
|
||||||
|
private BluetoothDevice mBluetoothDevice;
|
||||||
|
private String mDeviceName;
|
||||||
|
private ILogSession mLogSession;
|
||||||
|
|
||||||
|
private final BroadcastReceiver mBluetoothStateBroadcastReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
|
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF);
|
||||||
|
final ILogger logger = getBinder();
|
||||||
|
|
||||||
|
final String stateString = "[Broadcast] Action received: " + BluetoothAdapter.ACTION_STATE_CHANGED + ", state changed to " + state2String(state);
|
||||||
|
logger.log(Log.DEBUG, stateString);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case BluetoothAdapter.STATE_ON:
|
||||||
|
onBluetoothEnabled();
|
||||||
|
break;
|
||||||
|
case BluetoothAdapter.STATE_TURNING_OFF:
|
||||||
|
case BluetoothAdapter.STATE_OFF:
|
||||||
|
onBluetoothDisabled();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String state2String(final int state) {
|
||||||
|
switch (state) {
|
||||||
|
case BluetoothAdapter.STATE_TURNING_ON:
|
||||||
|
return "TURNING ON";
|
||||||
|
case BluetoothAdapter.STATE_ON:
|
||||||
|
return "ON";
|
||||||
|
case BluetoothAdapter.STATE_TURNING_OFF:
|
||||||
|
return "TURNING OFF";
|
||||||
|
case BluetoothAdapter.STATE_OFF:
|
||||||
|
return "OFF";
|
||||||
|
default:
|
||||||
|
return "UNKNOWN (" + state + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public class LocalBinder extends Binder implements ILogger {
|
||||||
|
/**
|
||||||
|
* Disconnects from the sensor.
|
||||||
|
*/
|
||||||
|
public final void disconnect() {
|
||||||
|
final int state = mBleManager.getConnectionState();
|
||||||
|
if (state == BluetoothGatt.STATE_DISCONNECTED || state == BluetoothGatt.STATE_DISCONNECTING) {
|
||||||
|
mBleManager.close();
|
||||||
|
onDeviceDisconnected(mBluetoothDevice);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mBleManager.disconnect().enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the bound activity if changing configuration or not.
|
||||||
|
* If <code>false</code>, we will turn off battery level notifications in onUnbind(..) method below.
|
||||||
|
* @param changing true if the bound activity is finishing
|
||||||
|
*/
|
||||||
|
public void setActivityIsChangingConfiguration(final boolean changing) {
|
||||||
|
mActivityIsChangingConfiguration = changing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the device address
|
||||||
|
*
|
||||||
|
* @return device address
|
||||||
|
*/
|
||||||
|
public String getDeviceAddress() {
|
||||||
|
return mBluetoothDevice.getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the device name
|
||||||
|
*
|
||||||
|
* @return the device name
|
||||||
|
*/
|
||||||
|
public String getDeviceName() {
|
||||||
|
return mDeviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Bluetooth device
|
||||||
|
*
|
||||||
|
* @return the Bluetooth device
|
||||||
|
*/
|
||||||
|
public BluetoothDevice getBluetoothDevice() {
|
||||||
|
return mBluetoothDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if the device is connected to the sensor.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if device is connected to the sensor, <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean isConnected() {
|
||||||
|
return mBleManager.isConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the connection state of given device.
|
||||||
|
* @return the connection state, as in {@link BleManager#getConnectionState()}.
|
||||||
|
*/
|
||||||
|
public int getConnectionState() {
|
||||||
|
return mBleManager.getConnectionState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the log session that can be used to append log entries.
|
||||||
|
* The log session is created when the service is being created.
|
||||||
|
* The method returns <code>null</code> if the nRF Logger app was not installed.
|
||||||
|
*
|
||||||
|
* @return the log session
|
||||||
|
*/
|
||||||
|
public ILogSession getLogSession() {
|
||||||
|
return mLogSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(final int level, @NonNull final String message) {
|
||||||
|
Logger.log(mLogSession, level, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(final int level, final @StringRes int messageRes, final Object... params) {
|
||||||
|
Logger.log(mLogSession, level, messageRes, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a handler that is created in onCreate().
|
||||||
|
* The handler may be used to postpone execution of some operations or to run them in UI thread.
|
||||||
|
*/
|
||||||
|
protected Handler getHandler() {
|
||||||
|
return mHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the binder implementation. This must return class implementing the additional manager interface that may be used in the bound activity.
|
||||||
|
*
|
||||||
|
* @return the service binder
|
||||||
|
*/
|
||||||
|
protected LocalBinder getBinder() {
|
||||||
|
// default implementation returns the basic binder. You can overwrite the LocalBinder with your own, wider implementation
|
||||||
|
return new LocalBinder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(final Intent intent) {
|
||||||
|
mBound = true;
|
||||||
|
return getBinder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void onRebind(final Intent intent) {
|
||||||
|
mBound = true;
|
||||||
|
|
||||||
|
if (!mActivityIsChangingConfiguration)
|
||||||
|
onRebind();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the activity has rebound to the service after being recreated.
|
||||||
|
* This method is not called when the activity was killed to be recreated when the phone orientation changed
|
||||||
|
* if prior to being killed called {@link BleProfileService.LocalBinder#setActivityIsChangingConfiguration(boolean)} with parameter true.
|
||||||
|
*/
|
||||||
|
protected void onRebind() {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean onUnbind(final Intent intent) {
|
||||||
|
mBound = false;
|
||||||
|
|
||||||
|
if (!mActivityIsChangingConfiguration)
|
||||||
|
onUnbind();
|
||||||
|
|
||||||
|
// We want the onRebind method be called if anything else binds to it again
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the activity has unbound from the service before being finished.
|
||||||
|
* This method is not called when the activity is killed to be recreated when the phone orientation changed.
|
||||||
|
*/
|
||||||
|
protected void onUnbind() {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
|
||||||
|
mHandler = new Handler();
|
||||||
|
|
||||||
|
// Initialize the manager
|
||||||
|
mBleManager = initializeManager();
|
||||||
|
mBleManager.setGattCallbacks(this);
|
||||||
|
|
||||||
|
// Register broadcast receivers
|
||||||
|
registerReceiver(mBluetoothStateBroadcastReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
|
||||||
|
|
||||||
|
// Service has now been created
|
||||||
|
onServiceCreated();
|
||||||
|
|
||||||
|
// Call onBluetoothEnabled if Bluetooth enabled
|
||||||
|
final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||||
|
if (bluetoothAdapter.isEnabled()) {
|
||||||
|
onBluetoothEnabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the service has been created, before the {@link #onBluetoothEnabled()} is called.
|
||||||
|
*/
|
||||||
|
protected void onServiceCreated() {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the Ble Manager responsible for connecting to a single device.
|
||||||
|
* @return a new BleManager object
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
protected abstract LoggableBleManager initializeManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns whether autoConnect option should be used.
|
||||||
|
*
|
||||||
|
* @return true to use autoConnect feature, false (default) otherwise.
|
||||||
|
*/
|
||||||
|
protected boolean shouldAutoConnect() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int onStartCommand(final Intent intent, final int flags, final int startId) {
|
||||||
|
if (intent == null || !intent.hasExtra(EXTRA_DEVICE_ADDRESS))
|
||||||
|
throw new UnsupportedOperationException("No device address at EXTRA_DEVICE_ADDRESS key");
|
||||||
|
|
||||||
|
final Uri logUri = intent.getParcelableExtra(EXTRA_LOG_URI);
|
||||||
|
mLogSession = Logger.openSession(getApplicationContext(), logUri);
|
||||||
|
mDeviceName = intent.getStringExtra(EXTRA_DEVICE_NAME);
|
||||||
|
|
||||||
|
Logger.i(mLogSession, "Service started");
|
||||||
|
|
||||||
|
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||||
|
final String deviceAddress = intent.getStringExtra(EXTRA_DEVICE_ADDRESS);
|
||||||
|
mBluetoothDevice = adapter.getRemoteDevice(deviceAddress);
|
||||||
|
|
||||||
|
mBleManager.setLogger(mLogSession);
|
||||||
|
onServiceStarted();
|
||||||
|
mBleManager.connect(mBluetoothDevice)
|
||||||
|
.useAutoConnect(shouldAutoConnect())
|
||||||
|
.retry(3, 100)
|
||||||
|
.enqueue();
|
||||||
|
return START_REDELIVER_INTENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the service has been started. The device name and address are set.
|
||||||
|
* The BLE Manager will try to connect to the device after this method finishes.
|
||||||
|
*/
|
||||||
|
protected void onServiceStarted() {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTaskRemoved(final Intent rootIntent) {
|
||||||
|
super.onTaskRemoved(rootIntent);
|
||||||
|
// This method is called when user removed the app from Recents.
|
||||||
|
// By default, the service will be killed and recreated immediately after that.
|
||||||
|
// However, all managed devices will be lost and devices will be disconnected.
|
||||||
|
stopSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
// Unregister broadcast receivers
|
||||||
|
unregisterReceiver(mBluetoothStateBroadcastReceiver);
|
||||||
|
|
||||||
|
// shutdown the manager
|
||||||
|
mBleManager.close();
|
||||||
|
Logger.i(mLogSession, "Service destroyed");
|
||||||
|
mBleManager = null;
|
||||||
|
mBluetoothDevice = null;
|
||||||
|
mDeviceName = null;
|
||||||
|
mLogSession = null;
|
||||||
|
mHandler = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method called when Bluetooth Adapter has been disabled.
|
||||||
|
*/
|
||||||
|
protected void onBluetoothDisabled() {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called when Bluetooth Adapter has been enabled and
|
||||||
|
* after the service was created if Bluetooth Adapter was enabled at that moment.
|
||||||
|
* This method could initialize all Bluetooth related features, for example open the GATT server.
|
||||||
|
*/
|
||||||
|
protected void onBluetoothEnabled() {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceConnecting(@NonNull final BluetoothDevice device) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_CONNECTION_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, mBluetoothDevice);
|
||||||
|
broadcast.putExtra(EXTRA_CONNECTION_STATE, STATE_CONNECTING);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceConnected(@NonNull final BluetoothDevice device) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_CONNECTION_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_CONNECTION_STATE, STATE_CONNECTED);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, mBluetoothDevice);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE_NAME, mDeviceName);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceDisconnecting(@NonNull final BluetoothDevice device) {
|
||||||
|
// Notify user about changing the state to DISCONNECTING
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_CONNECTION_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, mBluetoothDevice);
|
||||||
|
broadcast.putExtra(EXTRA_CONNECTION_STATE, STATE_DISCONNECTING);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method should return false if the service needs to do some asynchronous work after if has disconnected from the device.
|
||||||
|
* In that case the {@link #stopService()} method must be called when done.
|
||||||
|
* @return true (default) to automatically stop the service when device is disconnected. False otherwise.
|
||||||
|
*/
|
||||||
|
protected boolean stopWhenDisconnected() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceDisconnected(@NonNull final BluetoothDevice device) {
|
||||||
|
// Note 1: Do not use the device argument here unless you change calling onDeviceDisconnected from the binder above
|
||||||
|
|
||||||
|
// Note 2: if BleManager#shouldAutoConnect() for this device returned true, this callback will be
|
||||||
|
// invoked ONLY when user requested disconnection (using Disconnect button). If the device
|
||||||
|
// disconnects due to a link loss, the onLinkLossOccurred(BluetoothDevice) method will be called instead.
|
||||||
|
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_CONNECTION_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, mBluetoothDevice);
|
||||||
|
broadcast.putExtra(EXTRA_CONNECTION_STATE, STATE_DISCONNECTED);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
|
||||||
|
if (stopWhenDisconnected())
|
||||||
|
stopService();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopService() {
|
||||||
|
// user requested disconnection. We must stop the service
|
||||||
|
Logger.v(mLogSession, "Stopping service...");
|
||||||
|
stopSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLinkLossOccurred(@NonNull final BluetoothDevice device) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_CONNECTION_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, mBluetoothDevice);
|
||||||
|
broadcast.putExtra(EXTRA_CONNECTION_STATE, STATE_LINK_LOSS);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServicesDiscovered(@NonNull final BluetoothDevice device, final boolean optionalServicesFound) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_SERVICES_DISCOVERED);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, mBluetoothDevice);
|
||||||
|
broadcast.putExtra(EXTRA_SERVICE_PRIMARY, true);
|
||||||
|
broadcast.putExtra(EXTRA_SERVICE_SECONDARY, optionalServicesFound);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceReady(@NonNull final BluetoothDevice device) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_DEVICE_READY);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, mBluetoothDevice);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceNotSupported(@NonNull final BluetoothDevice device) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_SERVICES_DISCOVERED);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, mBluetoothDevice);
|
||||||
|
broadcast.putExtra(EXTRA_SERVICE_PRIMARY, false);
|
||||||
|
broadcast.putExtra(EXTRA_SERVICE_SECONDARY, false);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
|
||||||
|
// no need for disconnecting, it will be disconnected by the manager automatically
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBatteryValueReceived(@NonNull final BluetoothDevice device, final int value) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_BATTERY_LEVEL);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, mBluetoothDevice);
|
||||||
|
broadcast.putExtra(EXTRA_BATTERY_LEVEL, value);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBondingRequired(@NonNull final BluetoothDevice device) {
|
||||||
|
showToast(no.Reader.android.iisc.R.string.bonding);
|
||||||
|
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_BOND_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, mBluetoothDevice);
|
||||||
|
broadcast.putExtra(EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDING);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBonded(@NonNull final BluetoothDevice device) {
|
||||||
|
showToast(no.Reader.android.iisc.R.string.bonding);
|
||||||
|
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_BOND_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, mBluetoothDevice);
|
||||||
|
broadcast.putExtra(EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDED);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBondingFailed(@NonNull final BluetoothDevice device) {
|
||||||
|
showToast(no.Reader.android.iisc.R.string.bonding_failed);
|
||||||
|
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_BOND_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, mBluetoothDevice);
|
||||||
|
broadcast.putExtra(EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(@NonNull final BluetoothDevice device, @NonNull final String message, final int errorCode) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_ERROR);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, mBluetoothDevice);
|
||||||
|
broadcast.putExtra(EXTRA_ERROR_MESSAGE, message);
|
||||||
|
broadcast.putExtra(EXTRA_ERROR_CODE, errorCode);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a message as a Toast notification. This method is thread safe, you can call it from any thread
|
||||||
|
*
|
||||||
|
* @param messageResId
|
||||||
|
* an resource id of the message to be shown
|
||||||
|
*/
|
||||||
|
protected void showToast(final int messageResId) {
|
||||||
|
mHandler.post(() -> Toast.makeText(BleProfileService.this, messageResId, Toast.LENGTH_SHORT).show());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a message as a Toast notification. This method is thread safe, you can call it from any thread
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* a message to be shown
|
||||||
|
*/
|
||||||
|
protected void showToast(final String message) {
|
||||||
|
mHandler.post(() -> Toast.makeText(BleProfileService.this, message, Toast.LENGTH_SHORT).show());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the log session that can be used to append log entries. The method returns <code>null</code> if the nRF Logger app was not installed. It is safe to use logger when
|
||||||
|
* {@link #onServiceStarted()} has been called.
|
||||||
|
*
|
||||||
|
* @return the log session
|
||||||
|
*/
|
||||||
|
protected ILogSession getLogSession() {
|
||||||
|
return mLogSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the device address
|
||||||
|
*
|
||||||
|
* @return device address
|
||||||
|
*/
|
||||||
|
protected String getDeviceAddress() {
|
||||||
|
return mBluetoothDevice.getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Bluetooth device object
|
||||||
|
*
|
||||||
|
* @return bluetooth device
|
||||||
|
*/
|
||||||
|
protected BluetoothDevice getBluetoothDevice() {
|
||||||
|
return mBluetoothDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the device name
|
||||||
|
*
|
||||||
|
* @return the device name
|
||||||
|
*/
|
||||||
|
protected String getDeviceName() {
|
||||||
|
return mDeviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if the device is connected to the sensor.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if device is connected to the sensor, <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
protected boolean isConnected() {
|
||||||
|
return mBleManager != null && mBleManager.isConnected();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,626 @@
|
|||||||
|
package no.Reader.android.iisc.profile;
|
||||||
|
|
||||||
|
import android.app.Service;
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.bluetooth.BluetoothManager;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.content.ServiceConnection;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.ble.BleManagerCallbacks;
|
||||||
|
import no.nordicsemi.android.log.ILogSession;
|
||||||
|
import no.nordicsemi.android.log.LocalLogSession;
|
||||||
|
import no.nordicsemi.android.log.Logger;
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.scanner.ScannerFragment;
|
||||||
|
import no.Reader.android.iisc.DebugLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* The {@link BleProfileServiceReadyActivity} activity is designed to be the base class for profile activities that uses services in order to connect to the
|
||||||
|
* device. When user press CONNECT button a service is created and the activity binds to it. The service tries to connect to the service and notifies the
|
||||||
|
* activity using Local Broadcasts ({@link LocalBroadcastManager}). See {@link BleProfileService} for messages. If the device is not in range it will listen for
|
||||||
|
* it and connect when it become visible. The service exists until user will press DISCONNECT button.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* When user closes the activity (f.e. by pressing Back button) while being connected, the Service remains working. It's still connected to the device or still
|
||||||
|
* listens for it. When entering back to the activity, activity will to bind to the service and refresh UI.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public abstract class BleProfileServiceReadyActivity<E extends BleProfileService.LocalBinder> extends AppCompatActivity implements
|
||||||
|
ScannerFragment.OnDeviceSelectedListener, BleManagerCallbacks {
|
||||||
|
private static final String TAG = "BleProfileServiceReadyActivity";
|
||||||
|
|
||||||
|
private static final String SIS_DEVICE_NAME = "device_name";
|
||||||
|
private static final String SIS_DEVICE = "device";
|
||||||
|
private static final String LOG_URI = "log_uri";
|
||||||
|
protected static final int REQUEST_ENABLE_BT = 2;
|
||||||
|
|
||||||
|
private E mService;
|
||||||
|
|
||||||
|
private TextView mDeviceNameView;
|
||||||
|
private Button mConnectButton;
|
||||||
|
|
||||||
|
private ILogSession mLogSession;
|
||||||
|
private BluetoothDevice mBluetoothDevice;
|
||||||
|
private String mDeviceName;
|
||||||
|
|
||||||
|
private final BroadcastReceiver mCommonBroadcastReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
|
// Check if the broadcast applies the connected device
|
||||||
|
if (!isBroadcastForThisDevice(intent))
|
||||||
|
return;
|
||||||
|
|
||||||
|
final BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BleProfileService.EXTRA_DEVICE);
|
||||||
|
final String action = intent.getAction();
|
||||||
|
switch (action) {
|
||||||
|
case BleProfileService.BROADCAST_CONNECTION_STATE: {
|
||||||
|
final int state = intent.getIntExtra(BleProfileService.EXTRA_CONNECTION_STATE, BleProfileService.STATE_DISCONNECTED);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case BleProfileService.STATE_CONNECTED: {
|
||||||
|
mDeviceName = intent.getStringExtra(BleProfileService.EXTRA_DEVICE_NAME);
|
||||||
|
onDeviceConnected(bluetoothDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleProfileService.STATE_DISCONNECTED: {
|
||||||
|
onDeviceDisconnected(bluetoothDevice);
|
||||||
|
mDeviceName = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleProfileService.STATE_LINK_LOSS: {
|
||||||
|
onLinkLossOccurred(bluetoothDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleProfileService.STATE_CONNECTING: {
|
||||||
|
onDeviceConnecting(bluetoothDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleProfileService.STATE_DISCONNECTING: {
|
||||||
|
onDeviceDisconnecting(bluetoothDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// there should be no other actions
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleProfileService.BROADCAST_SERVICES_DISCOVERED: {
|
||||||
|
final boolean primaryService = intent.getBooleanExtra(BleProfileService.EXTRA_SERVICE_PRIMARY, false);
|
||||||
|
final boolean secondaryService = intent.getBooleanExtra(BleProfileService.EXTRA_SERVICE_SECONDARY, false);
|
||||||
|
|
||||||
|
if (primaryService) {
|
||||||
|
onServicesDiscovered(bluetoothDevice, secondaryService);
|
||||||
|
} else {
|
||||||
|
onDeviceNotSupported(bluetoothDevice);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleProfileService.BROADCAST_DEVICE_READY: {
|
||||||
|
onDeviceReady(bluetoothDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleProfileService.BROADCAST_BOND_STATE: {
|
||||||
|
final int state = intent.getIntExtra(BleProfileService.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
|
||||||
|
switch (state) {
|
||||||
|
case BluetoothDevice.BOND_BONDING:
|
||||||
|
onBondingRequired(bluetoothDevice);
|
||||||
|
break;
|
||||||
|
case BluetoothDevice.BOND_BONDED:
|
||||||
|
onBonded(bluetoothDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleProfileService.BROADCAST_ERROR: {
|
||||||
|
final String message = intent.getStringExtra(BleProfileService.EXTRA_ERROR_MESSAGE);
|
||||||
|
final int errorCode = intent.getIntExtra(BleProfileService.EXTRA_ERROR_CODE, 0);
|
||||||
|
onError(bluetoothDevice, message, errorCode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private ServiceConnection mServiceConnection = new ServiceConnection() {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected(final ComponentName name, final IBinder service) {
|
||||||
|
final E bleService = mService = (E) service;
|
||||||
|
mBluetoothDevice = bleService.getBluetoothDevice();
|
||||||
|
mLogSession = mService.getLogSession();
|
||||||
|
Logger.d(mLogSession, "Activity bound to the service");
|
||||||
|
onServiceBound(bleService);
|
||||||
|
|
||||||
|
// Update UI
|
||||||
|
mDeviceName = bleService.getDeviceName();
|
||||||
|
mDeviceNameView.setText(mDeviceName);
|
||||||
|
mConnectButton.setText(R.string.action_disconnect);
|
||||||
|
|
||||||
|
// And notify user if device is connected
|
||||||
|
if (bleService.isConnected()) {
|
||||||
|
onDeviceConnected(mBluetoothDevice);
|
||||||
|
} else {
|
||||||
|
// If the device is not connected it means that either it is still connecting,
|
||||||
|
// or the link was lost and service is trying to connect to it (autoConnect=true).
|
||||||
|
onDeviceConnecting(mBluetoothDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected(final ComponentName name) {
|
||||||
|
// Note: this method is called only when the service is killed by the system,
|
||||||
|
// not when it stops itself or is stopped by the activity.
|
||||||
|
// It will be called only when there is critically low memory, in practice never
|
||||||
|
// when the activity is in foreground.
|
||||||
|
Logger.d(mLogSession, "Activity disconnected from the service");
|
||||||
|
mDeviceNameView.setText(getDefaultDeviceName());
|
||||||
|
mConnectButton.setText(R.string.action_connect);
|
||||||
|
|
||||||
|
mService = null;
|
||||||
|
mDeviceName = null;
|
||||||
|
mBluetoothDevice = null;
|
||||||
|
mLogSession = null;
|
||||||
|
onServiceUnbound();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
ensureBLESupported();
|
||||||
|
if (!isBLEEnabled()) {
|
||||||
|
showBLEDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore the old log session
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
final Uri logUri = savedInstanceState.getParcelable(LOG_URI);
|
||||||
|
mLogSession = Logger.openSession(getApplicationContext(), logUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
// In onInitialize method a final class may register local broadcast receivers that will listen for events from the service
|
||||||
|
onInitialize(savedInstanceState);
|
||||||
|
// The onCreateView class should... create the view
|
||||||
|
onCreateView(savedInstanceState);
|
||||||
|
|
||||||
|
/*final Toolbar toolbar = findViewById(R.id.toolbar_actionbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
*/
|
||||||
|
// Common nRF Toolbox view references are obtained here
|
||||||
|
setUpView();
|
||||||
|
// View is ready to be used
|
||||||
|
onViewCreated(savedInstanceState);
|
||||||
|
|
||||||
|
LocalBroadcastManager.getInstance(this).registerReceiver(mCommonBroadcastReceiver, makeIntentFilter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the service has not been started before, the following lines will not start it.
|
||||||
|
* However, if it's running, the Activity will bind to it and notified via mServiceConnection.
|
||||||
|
*/
|
||||||
|
final Intent service = new Intent(this, getServiceClass());
|
||||||
|
// We pass 0 as a flag so the service will not be created if not exists.
|
||||||
|
bindService(service, mServiceConnection, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When user exited the UARTActivity while being connected, the log session is kept in
|
||||||
|
* the service. We may not get it before binding to it so in this case this event will
|
||||||
|
* not be logged (mLogSession is null until onServiceConnected(..) is called).
|
||||||
|
* It will, however, be logged after the orientation changes.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// We don't want to perform some operations (e.g. disable Battery Level notifications)
|
||||||
|
// in the service if we are just rotating the screen. However, when the activity will
|
||||||
|
// disappear, we may want to disable some device features to reduce the battery
|
||||||
|
// consumption.
|
||||||
|
if (mService != null)
|
||||||
|
mService.setActivityIsChangingConfiguration(isChangingConfigurations());
|
||||||
|
|
||||||
|
unbindService(mServiceConnection);
|
||||||
|
mService = null;
|
||||||
|
|
||||||
|
Logger.d(mLogSession, "Activity unbound from the service");
|
||||||
|
onServiceUnbound();
|
||||||
|
mDeviceName = null;
|
||||||
|
mBluetoothDevice = null;
|
||||||
|
mLogSession = null;
|
||||||
|
} catch (final IllegalArgumentException e) {
|
||||||
|
// do nothing, we were not connected to the sensor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
|
||||||
|
LocalBroadcastManager.getInstance(this).unregisterReceiver(mCommonBroadcastReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IntentFilter makeIntentFilter() {
|
||||||
|
final IntentFilter intentFilter = new IntentFilter();
|
||||||
|
intentFilter.addAction(BleProfileService.BROADCAST_CONNECTION_STATE);
|
||||||
|
intentFilter.addAction(BleProfileService.BROADCAST_SERVICES_DISCOVERED);
|
||||||
|
intentFilter.addAction(BleProfileService.BROADCAST_DEVICE_READY);
|
||||||
|
intentFilter.addAction(BleProfileService.BROADCAST_BOND_STATE);
|
||||||
|
intentFilter.addAction(BleProfileService.BROADCAST_ERROR);
|
||||||
|
return intentFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when activity binds to the service. The parameter is the object returned in {@link Service#onBind(Intent)} method in your service. The method is
|
||||||
|
* called when device gets connected or is created while sensor was connected before. You may use the binder as a sensor interface.
|
||||||
|
*/
|
||||||
|
protected abstract void onServiceBound(E binder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when activity unbinds from the service. You may no longer use this binder because the sensor was disconnected. This method is also called when you
|
||||||
|
* leave the activity being connected to the sensor in the background.
|
||||||
|
*/
|
||||||
|
protected abstract void onServiceUnbound();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the service class for sensor communication. The service class must derive from {@link BleProfileService} in order to operate with this class.
|
||||||
|
*
|
||||||
|
* @return the service class
|
||||||
|
*/
|
||||||
|
protected abstract Class<? extends BleProfileService> getServiceClass();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the service interface that may be used to communicate with the sensor. This will return <code>null</code> if the device is disconnected from the
|
||||||
|
* sensor.
|
||||||
|
*
|
||||||
|
* @return the service binder or <code>null</code>
|
||||||
|
*/
|
||||||
|
protected E getService() {
|
||||||
|
return mService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* You may do some initialization here. This method is called from {@link #onCreate(Bundle)} before the view was created.
|
||||||
|
*/
|
||||||
|
protected void onInitialize(final Bundle savedInstanceState) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called from {@link #onCreate(Bundle)}. This method should build the activity UI, i.e. using {@link #setContentView(int)}.
|
||||||
|
* Use to obtain references to views. Connect/Disconnect button, the device name view are manager automatically.
|
||||||
|
*
|
||||||
|
* @param savedInstanceState contains the data it most recently supplied in {@link #onSaveInstanceState(Bundle)}.
|
||||||
|
* Note: <b>Otherwise it is null</b>.
|
||||||
|
*/
|
||||||
|
protected abstract void onCreateView(final Bundle savedInstanceState);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after the view has been created.
|
||||||
|
*
|
||||||
|
* @param savedInstanceState contains the data it most recently supplied in {@link #onSaveInstanceState(Bundle)}.
|
||||||
|
* Note: <b>Otherwise it is null</b>.
|
||||||
|
*/
|
||||||
|
protected void onViewCreated(final Bundle savedInstanceState) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after the view and the toolbar has been created.
|
||||||
|
*/
|
||||||
|
protected final void setUpView() {
|
||||||
|
// set GUI
|
||||||
|
// getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
mConnectButton = findViewById(R.id.action_connect);
|
||||||
|
mDeviceNameView = findViewById(R.id.device_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSaveInstanceState(final Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
outState.putString(SIS_DEVICE_NAME, mDeviceName);
|
||||||
|
outState.putParcelable(SIS_DEVICE, mBluetoothDevice);
|
||||||
|
if (mLogSession != null)
|
||||||
|
outState.putParcelable(LOG_URI, mLogSession.getSessionUri());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestoreInstanceState(final @NonNull Bundle savedInstanceState) {
|
||||||
|
super.onRestoreInstanceState(savedInstanceState);
|
||||||
|
mDeviceName = savedInstanceState.getString(SIS_DEVICE_NAME);
|
||||||
|
mBluetoothDevice = savedInstanceState.getParcelable(SIS_DEVICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this method to handle menu actions other than home and about.
|
||||||
|
*
|
||||||
|
* @param itemId the menu item id
|
||||||
|
* @return <code>true</code> if action has been handled
|
||||||
|
*/
|
||||||
|
protected boolean onOptionsItemSelected(final int itemId) {
|
||||||
|
// Overwrite when using menu other than R.menu.help
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when user press CONNECT or DISCONNECT button. See layout files -> onClick attribute.
|
||||||
|
*/
|
||||||
|
public void onConnectClicked(final View view) {
|
||||||
|
if (isBLEEnabled()) {
|
||||||
|
if (mService == null) {
|
||||||
|
setDefaultUI();
|
||||||
|
showDeviceScanningDialog(getFilterUUID());
|
||||||
|
} else {
|
||||||
|
mService.disconnect();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showBLEDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the title resource id that will be used to create logger session. If 0 is returned (default) logger will not be used.
|
||||||
|
*
|
||||||
|
* @return the title resource id
|
||||||
|
*/
|
||||||
|
protected int getLoggerProfileTitle() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method may return the local log content provider authority if local log sessions are supported.
|
||||||
|
*
|
||||||
|
* @return local log session content provider URI
|
||||||
|
*/
|
||||||
|
protected Uri getLocalAuthorityLogger() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceSelected(final BluetoothDevice device, final String name) {
|
||||||
|
final int titleId = getLoggerProfileTitle();
|
||||||
|
if (titleId > 0) {
|
||||||
|
mLogSession = Logger.newSession(getApplicationContext(), getString(titleId), device.getAddress(), name);
|
||||||
|
// If nRF Logger is not installed we may want to use local logger
|
||||||
|
if (mLogSession == null && getLocalAuthorityLogger() != null) {
|
||||||
|
mLogSession = LocalLogSession.newSession(getApplicationContext(), getLocalAuthorityLogger(), device.getAddress(), name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mBluetoothDevice = device;
|
||||||
|
mDeviceName = name;
|
||||||
|
|
||||||
|
// The device may not be in the range but the service will try to connect to it if it reach it
|
||||||
|
Logger.d(mLogSession, "Creating service...");
|
||||||
|
final Intent service = new Intent(this, getServiceClass());
|
||||||
|
service.putExtra(BleProfileService.EXTRA_DEVICE_ADDRESS, device.getAddress());
|
||||||
|
service.putExtra(BleProfileService.EXTRA_DEVICE_NAME, name);
|
||||||
|
if (mLogSession != null)
|
||||||
|
service.putExtra(BleProfileService.EXTRA_LOG_URI, mLogSession.getSessionUri());
|
||||||
|
startService(service);
|
||||||
|
Logger.d(mLogSession, "Binding to the service...");
|
||||||
|
bindService(service, mServiceConnection, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDialogCanceled() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceConnecting(final BluetoothDevice device) {
|
||||||
|
mDeviceNameView.setText(mDeviceName != null ? mDeviceName : getString(R.string.not_available));
|
||||||
|
mConnectButton.setText(R.string.action_connecting);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceConnected(final BluetoothDevice device) {
|
||||||
|
mDeviceNameView.setText(mDeviceName);
|
||||||
|
mConnectButton.setText(R.string.action_disconnect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceDisconnecting(final BluetoothDevice device) {
|
||||||
|
mConnectButton.setText(R.string.action_disconnecting);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceDisconnected(final BluetoothDevice device) {
|
||||||
|
mConnectButton.setText(R.string.action_connect);
|
||||||
|
mDeviceNameView.setText(getDefaultDeviceName());
|
||||||
|
|
||||||
|
try {
|
||||||
|
Logger.d(mLogSession, "Unbinding from the service...");
|
||||||
|
unbindService(mServiceConnection);
|
||||||
|
mService = null;
|
||||||
|
|
||||||
|
Logger.d(mLogSession, "Activity unbound from the service");
|
||||||
|
onServiceUnbound();
|
||||||
|
mDeviceName = null;
|
||||||
|
mBluetoothDevice = null;
|
||||||
|
mLogSession = null;
|
||||||
|
} catch (final IllegalArgumentException e) {
|
||||||
|
// do nothing. This should never happen but does...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLinkLossOccurred(final BluetoothDevice device) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServicesDiscovered(final BluetoothDevice device, final boolean optionalServicesFound) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceReady(final BluetoothDevice device) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBondingRequired(final BluetoothDevice device) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBonded(final BluetoothDevice device) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBondingFailed(final BluetoothDevice device) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(final BluetoothDevice device, final String message, final int errorCode) {
|
||||||
|
DebugLogger.e(TAG, "Error occurred: " + message + ", error code: " + errorCode);
|
||||||
|
showToast(message + " (" + errorCode + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceNotSupported(final BluetoothDevice device) {
|
||||||
|
showToast(R.string.not_supported);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a message as a Toast notification. This method is thread safe, you can call it from any thread
|
||||||
|
*
|
||||||
|
* @param message a message to be shown
|
||||||
|
*/
|
||||||
|
protected void showToast(final String message) {
|
||||||
|
runOnUiThread(() -> Toast.makeText(BleProfileServiceReadyActivity.this, message, Toast.LENGTH_LONG).show());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a message as a Toast notification. This method is thread safe, you can call it from any thread
|
||||||
|
*
|
||||||
|
* @param messageResId an resource id of the message to be shown
|
||||||
|
*/
|
||||||
|
protected void showToast(final int messageResId) {
|
||||||
|
runOnUiThread(() -> Toast.makeText(BleProfileServiceReadyActivity.this, messageResId, Toast.LENGTH_SHORT).show());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if the device is connected. Services may not have been discovered yet.
|
||||||
|
*/
|
||||||
|
protected boolean isDeviceConnected() {
|
||||||
|
return mService != null && mService.isConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the device that the phone is currently connected to or was connected last time
|
||||||
|
*/
|
||||||
|
protected String getDeviceName() {
|
||||||
|
return mDeviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the default UI before reconnecting
|
||||||
|
*/
|
||||||
|
protected abstract void setDefaultUI();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default device name resource id. The real device name is obtained when connecting to the device. This one is used when device has
|
||||||
|
* disconnected.
|
||||||
|
*
|
||||||
|
* @return the default device name resource id
|
||||||
|
*/
|
||||||
|
protected abstract int getDefaultDeviceName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the string resource id that will be shown in About box
|
||||||
|
*
|
||||||
|
* @return the about resource id
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The UUID filter is used to filter out available devices that does not have such UUID in their advertisement packet. See also:
|
||||||
|
* {@link #isChangingConfigurations()}.
|
||||||
|
*
|
||||||
|
* @return the required UUID or <code>null</code>
|
||||||
|
*/
|
||||||
|
protected abstract UUID getFilterUUID();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the {@link BleProfileService#EXTRA_DEVICE} in the given intent and compares it with the connected BluetoothDevice object.
|
||||||
|
* @param intent intent received via a broadcast from the service
|
||||||
|
* @return true if the data in the intent apply to the connected device, false otherwise
|
||||||
|
*/
|
||||||
|
protected boolean isBroadcastForThisDevice(final Intent intent) {
|
||||||
|
final BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BleProfileService.EXTRA_DEVICE);
|
||||||
|
return mBluetoothDevice != null && mBluetoothDevice.equals(bluetoothDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the scanner fragment.
|
||||||
|
*
|
||||||
|
* @param filter the UUID filter used to filter out available devices. The fragment will always show all bonded devices as there is no information about their
|
||||||
|
* services
|
||||||
|
* @see #getFilterUUID()
|
||||||
|
*/
|
||||||
|
private void showDeviceScanningDialog(final UUID filter) {
|
||||||
|
final ScannerFragment dialog = ScannerFragment.getInstance(filter);
|
||||||
|
dialog.show(getSupportFragmentManager(), "scan_fragment");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the log session. Log session is created when the device was selected using the {@link ScannerFragment} and released when user press DISCONNECT.
|
||||||
|
*
|
||||||
|
* @return the logger session or <code>null</code>
|
||||||
|
*/
|
||||||
|
protected ILogSession getLogSession() {
|
||||||
|
return mLogSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureBLESupported() {
|
||||||
|
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
|
||||||
|
Toast.makeText(this, R.string.no_ble, Toast.LENGTH_LONG).show();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isBLEEnabled() {
|
||||||
|
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
|
||||||
|
final BluetoothAdapter adapter = bluetoothManager.getAdapter();
|
||||||
|
return adapter != null && adapter.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void showBLEDialog() {
|
||||||
|
final Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
|
||||||
|
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package no.Reader.android.iisc.profile;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.ble.BleManager;
|
||||||
|
import no.nordicsemi.android.ble.BleManagerCallbacks;
|
||||||
|
import no.nordicsemi.android.log.ILogSession;
|
||||||
|
import no.nordicsemi.android.log.LogContract;
|
||||||
|
import no.nordicsemi.android.log.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The manager that logs to nRF Logger. If nRF Logger is not installed, logs are ignored.
|
||||||
|
*
|
||||||
|
* @param <T> the callbacks class.
|
||||||
|
*/
|
||||||
|
public abstract class LoggableBleManager<T extends BleManagerCallbacks> extends BleManager<T> {
|
||||||
|
private ILogSession mLogSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The manager constructor.
|
||||||
|
* <p>
|
||||||
|
* After constructing the manager, the callbacks object must be set with
|
||||||
|
* {@link #setGattCallbacks(BleManagerCallbacks)}.
|
||||||
|
*
|
||||||
|
* @param context the context.
|
||||||
|
*/
|
||||||
|
public LoggableBleManager(@NonNull final Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the log session to log into.
|
||||||
|
*
|
||||||
|
* @param session nRF Logger log session to log inti, or null, if nRF Logger is not installed.
|
||||||
|
*/
|
||||||
|
public void setLogger(@Nullable final ILogSession session) {
|
||||||
|
mLogSession = session;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(final int priority, @NonNull final String message) {
|
||||||
|
Logger.log(mLogSession, LogContract.Log.Level.fromPriority(priority), message);
|
||||||
|
Log.println(priority, "BleManager", message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,615 @@
|
|||||||
|
package no.Reader.android.iisc.profile.multiconnect;
|
||||||
|
|
||||||
|
import android.app.Service;
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.bluetooth.BluetoothGatt;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.os.Binder;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.StringRes;
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.profile.LoggableBleManager;
|
||||||
|
import no.nordicsemi.android.ble.BleManager;
|
||||||
|
import no.nordicsemi.android.ble.BleManagerCallbacks;
|
||||||
|
import no.nordicsemi.android.ble.utils.ILogger;
|
||||||
|
import no.nordicsemi.android.log.ILogSession;
|
||||||
|
|
||||||
|
public abstract class BleMulticonnectProfileService extends Service implements BleManagerCallbacks {
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static final String TAG = "BleMultiProfileService";
|
||||||
|
|
||||||
|
public static final String BROADCAST_CONNECTION_STATE = "no.Reader.android.iisc.BROADCAST_CONNECTION_STATE";
|
||||||
|
public static final String BROADCAST_SERVICES_DISCOVERED = "no.Reader.android.iisc.BROADCAST_SERVICES_DISCOVERED";
|
||||||
|
public static final String BROADCAST_DEVICE_READY = "no.Reader.android.iisc.DEVICE_READY";
|
||||||
|
public static final String BROADCAST_BOND_STATE = "no.Reader.android.iisc.BROADCAST_BOND_STATE";
|
||||||
|
@Deprecated
|
||||||
|
public static final String BROADCAST_BATTERY_LEVEL = "no.Reader.android.iisc.BROADCAST_BATTERY_LEVEL";
|
||||||
|
public static final String BROADCAST_ERROR = "no.Reader.android.iisc.BROADCAST_ERROR";
|
||||||
|
|
||||||
|
public static final String EXTRA_DEVICE = "no.Reader.android.iisc.EXTRA_DEVICE";
|
||||||
|
public static final String EXTRA_CONNECTION_STATE = "no.Reader.android.iisc.EXTRA_CONNECTION_STATE";
|
||||||
|
public static final String EXTRA_BOND_STATE = "no.Reader.android.iisc.EXTRA_BOND_STATE";
|
||||||
|
public static final String EXTRA_SERVICE_PRIMARY = "no.Reader.android.iisc.EXTRA_SERVICE_PRIMARY";
|
||||||
|
public static final String EXTRA_SERVICE_SECONDARY = "no.Reader.android.iisc.EXTRA_SERVICE_SECONDARY";
|
||||||
|
@Deprecated
|
||||||
|
public static final String EXTRA_BATTERY_LEVEL = "no.Reader.android.iisc.EXTRA_BATTERY_LEVEL";
|
||||||
|
public static final String EXTRA_ERROR_MESSAGE = "no.Reader.android.iisc.EXTRA_ERROR_MESSAGE";
|
||||||
|
public static final String EXTRA_ERROR_CODE = "no.Reader.android.iisc.EXTRA_ERROR_CODE";
|
||||||
|
|
||||||
|
public static final int STATE_LINK_LOSS = -1;
|
||||||
|
public static final int STATE_DISCONNECTED = 0;
|
||||||
|
public static final int STATE_CONNECTED = 1;
|
||||||
|
public static final int STATE_CONNECTING = 2;
|
||||||
|
public static final int STATE_DISCONNECTING = 3;
|
||||||
|
|
||||||
|
private HashMap<BluetoothDevice, LoggableBleManager<BleManagerCallbacks>> bleManagers;
|
||||||
|
private List<BluetoothDevice> managedDevices;
|
||||||
|
private Handler handler;
|
||||||
|
|
||||||
|
protected boolean bound;
|
||||||
|
private boolean activityIsChangingConfiguration;
|
||||||
|
|
||||||
|
private final BroadcastReceiver bluetoothStateBroadcastReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
|
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF);
|
||||||
|
final int previousState = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, BluetoothAdapter.STATE_OFF);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case BluetoothAdapter.STATE_ON:
|
||||||
|
// On older phones (tested on Nexus 4 with Android 5.0.1) the Bluetooth requires some time
|
||||||
|
// after it has been enabled before some operations can start. Starting the GATT server here
|
||||||
|
// without a delay is very likely to cause a DeadObjectException from BluetoothManager#openGattServer(...).
|
||||||
|
handler.postDelayed(() -> onBluetoothEnabled(), 600);
|
||||||
|
break;
|
||||||
|
case BluetoothAdapter.STATE_TURNING_OFF:
|
||||||
|
case BluetoothAdapter.STATE_OFF:
|
||||||
|
if (previousState != BluetoothAdapter.STATE_TURNING_OFF && previousState != BluetoothAdapter.STATE_OFF)
|
||||||
|
onBluetoothDisabled();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public class LocalBinder extends Binder implements ILogger, IDeviceLogger {
|
||||||
|
/**
|
||||||
|
* Returns an unmodifiable list of devices managed by the service.
|
||||||
|
* The returned devices do not need to be connected at tha moment. Each of them was however created
|
||||||
|
* using {@link #connect(BluetoothDevice)} method so they might have been connected before and disconnected.
|
||||||
|
* @return unmodifiable list of devices managed by the service
|
||||||
|
*/
|
||||||
|
public final List<BluetoothDevice> getManagedDevices() {
|
||||||
|
return Collections.unmodifiableList(managedDevices);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects to the given device. If the device is already connected this method does nothing.
|
||||||
|
* @param device target Bluetooth device
|
||||||
|
*/
|
||||||
|
public void connect(final BluetoothDevice device) {
|
||||||
|
connect(device, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the given device to managed and stars connecting to it. If the device is already connected this method does nothing.
|
||||||
|
* @param device target Bluetooth device
|
||||||
|
* @param session log session that has to be used by the device
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void connect(final BluetoothDevice device, final ILogSession session) {
|
||||||
|
// If a device is in managed devices it means that it's already connected, or was connected
|
||||||
|
// using autoConnect and the link was lost but Android is already trying to connect to it.
|
||||||
|
if (managedDevices.contains(device))
|
||||||
|
return;
|
||||||
|
managedDevices.add(device);
|
||||||
|
|
||||||
|
LoggableBleManager<BleManagerCallbacks> manager = bleManagers.get(device);
|
||||||
|
if (manager == null) {
|
||||||
|
bleManagers.put(device, manager = initializeManager());
|
||||||
|
manager.setGattCallbacks(BleMulticonnectProfileService.this);
|
||||||
|
}
|
||||||
|
manager.setLogger(session);
|
||||||
|
manager.connect(device)
|
||||||
|
.retry(2, 100)
|
||||||
|
.useAutoConnect(shouldAutoConnect())
|
||||||
|
.timeout(10000)
|
||||||
|
.fail((d, status) -> {
|
||||||
|
managedDevices.remove(device);
|
||||||
|
bleManagers.remove(device);
|
||||||
|
})
|
||||||
|
.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects the given device and removes the associated BleManager object.
|
||||||
|
* If the list of BleManagers is empty while the last activity unbinds from the service,
|
||||||
|
* the service will stop itself.
|
||||||
|
* @param device target device to disconnect and forget
|
||||||
|
*/
|
||||||
|
public void disconnect(final BluetoothDevice device) {
|
||||||
|
final BleManager manager = bleManagers.get(device);
|
||||||
|
if (manager != null && manager.isConnected()) {
|
||||||
|
manager.disconnect().enqueue();
|
||||||
|
}
|
||||||
|
managedDevices.remove(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if the device is connected to the sensor.
|
||||||
|
* @param device the target device
|
||||||
|
* @return <code>true</code> if device is connected to the sensor, <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public final boolean isConnected(final BluetoothDevice device) {
|
||||||
|
final BleManager manager = bleManagers.get(device);
|
||||||
|
return manager != null && manager.isConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if the device has finished initializing.
|
||||||
|
* @param device the target device
|
||||||
|
* @return <code>true</code> if device is connected to the sensor and has finished
|
||||||
|
* initializing. False otherwise.
|
||||||
|
*/
|
||||||
|
public final boolean isReady(final BluetoothDevice device) {
|
||||||
|
final BleManager manager = bleManagers.get(device);
|
||||||
|
return manager != null && manager.isReady();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the connection state of given device.
|
||||||
|
* @param device the target device
|
||||||
|
* @return the connection state, as in {@link BleManager#getConnectionState()}.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final int getConnectionState(final BluetoothDevice device) {
|
||||||
|
final BleManager manager = bleManagers.get(device);
|
||||||
|
return manager != null ? manager.getConnectionState() : BluetoothGatt.STATE_DISCONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the last received battery level value.
|
||||||
|
* @param device the device of which battery level should be returned
|
||||||
|
* @return battery value or -1 if no value was received or Battery Level characteristic was not found
|
||||||
|
* @deprecated Keep battery value in your manager instead.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Deprecated
|
||||||
|
public int getBatteryValue(final BluetoothDevice device) {
|
||||||
|
final BleManager manager = bleManagers.get(device);
|
||||||
|
if (manager != null)
|
||||||
|
return manager.getBatteryValue();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the bound activity if changing configuration or not.
|
||||||
|
* If <code>false</code>, we will turn off battery level notifications in onUnbind(..) method below.
|
||||||
|
* @param changing true if the bound activity is finishing
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public final void setActivityIsChangingConfiguration(final boolean changing) {
|
||||||
|
activityIsChangingConfiguration = changing;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(@NonNull final BluetoothDevice device, final int level, final String message) {
|
||||||
|
final BleManager manager = bleManagers.get(device);
|
||||||
|
if (manager != null)
|
||||||
|
manager.log(level, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(@NonNull final BluetoothDevice device, final int level, @StringRes final int messageRes, final Object... params) {
|
||||||
|
final BleManager manager = bleManagers.get(device);
|
||||||
|
if (manager != null)
|
||||||
|
manager.log(level, messageRes, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(final int level, @NonNull final String message) {
|
||||||
|
for (final BleManager manager : bleManagers.values())
|
||||||
|
manager.log(level, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(final int level, @StringRes final int messageRes, final Object... params) {
|
||||||
|
for (final BleManager manager : bleManagers.values())
|
||||||
|
manager.log(level, messageRes, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a handler that is created in onCreate().
|
||||||
|
* The handler may be used to postpone execution of some operations or to run them in UI thread.
|
||||||
|
*/
|
||||||
|
protected Handler getHandler() {
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns whether autoConnect option should be used.
|
||||||
|
*
|
||||||
|
* @return true to use autoConnect feature, false (default) otherwise.
|
||||||
|
*/
|
||||||
|
protected boolean shouldAutoConnect() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the binder implementation. This must return class implementing the additional manager interface that may be used in the bound activity.
|
||||||
|
*
|
||||||
|
* @return the service binder
|
||||||
|
*/
|
||||||
|
protected LocalBinder getBinder() {
|
||||||
|
// default implementation returns the basic binder. You can overwrite the LocalBinder with your own, wider implementation
|
||||||
|
return new LocalBinder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(final Intent intent) {
|
||||||
|
bound = true;
|
||||||
|
return getBinder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void onRebind(final Intent intent) {
|
||||||
|
bound = true;
|
||||||
|
|
||||||
|
if (!activityIsChangingConfiguration) {
|
||||||
|
onRebind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the activity has rebound to the service after being recreated.
|
||||||
|
* This method is not called when the activity was killed to be recreated when the phone orientation changed
|
||||||
|
* if prior to being killed called {@link LocalBinder#setActivityIsChangingConfiguration(boolean)} with parameter true.
|
||||||
|
*/
|
||||||
|
protected void onRebind() {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean onUnbind(final Intent intent) {
|
||||||
|
bound = false;
|
||||||
|
|
||||||
|
if (!activityIsChangingConfiguration) {
|
||||||
|
if (!managedDevices.isEmpty()) {
|
||||||
|
onUnbind();
|
||||||
|
} else {
|
||||||
|
// The last activity has disconnected from the service and there are no devices to manage. The service may be stopped.
|
||||||
|
stopSelf();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We want the onRebind method be called if anything else binds to it again
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the activity has unbound from the service before being finished.
|
||||||
|
* This method is not called when the activity is killed to be recreated when the phone orientation changed.
|
||||||
|
*/
|
||||||
|
protected void onUnbind() {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
|
||||||
|
handler = new Handler();
|
||||||
|
|
||||||
|
// Initialize the map of BLE managers
|
||||||
|
bleManagers = new HashMap<>();
|
||||||
|
managedDevices = new ArrayList<>();
|
||||||
|
|
||||||
|
// Register broadcast receivers
|
||||||
|
registerReceiver(bluetoothStateBroadcastReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
|
||||||
|
|
||||||
|
// Service has now been created
|
||||||
|
onServiceCreated();
|
||||||
|
|
||||||
|
// Call onBluetoothEnabled if Bluetooth enabled
|
||||||
|
final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||||
|
if (bluetoothAdapter.isEnabled()) {
|
||||||
|
onBluetoothEnabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the service has been created, before the {@link #onBluetoothEnabled()} is called.
|
||||||
|
*/
|
||||||
|
protected void onServiceCreated() {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the Ble Manager responsible for connecting to a single device.
|
||||||
|
* @return a new BleManager object
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
protected abstract LoggableBleManager initializeManager();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int onStartCommand(final Intent intent, final int flags, final int startId) {
|
||||||
|
onServiceStarted();
|
||||||
|
// The service does not save addresses of managed devices.
|
||||||
|
// A bound activity will be required to add connections again.
|
||||||
|
return START_NOT_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the service has been started.
|
||||||
|
*/
|
||||||
|
protected void onServiceStarted() {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTaskRemoved(final Intent rootIntent) {
|
||||||
|
super.onTaskRemoved(rootIntent);
|
||||||
|
// This method is called when user removed the app from Recents.
|
||||||
|
// By default, the service will be killed and recreated immediately after that.
|
||||||
|
// However, all managed devices will be lost and devices will be disconnected.
|
||||||
|
stopSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
onServiceStopped();
|
||||||
|
handler = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the service has been stopped.
|
||||||
|
*/
|
||||||
|
protected void onServiceStopped() {
|
||||||
|
// Unregister broadcast receivers
|
||||||
|
unregisterReceiver(bluetoothStateBroadcastReceiver);
|
||||||
|
|
||||||
|
// The managers map may not be empty if the service was killed by the system
|
||||||
|
for (final BleManager manager : bleManagers.values()) {
|
||||||
|
// Service is being destroyed, no need to disconnect manually.
|
||||||
|
manager.close();
|
||||||
|
manager.log(Log.INFO, "Service destroyed");
|
||||||
|
}
|
||||||
|
bleManagers.clear();
|
||||||
|
managedDevices.clear();
|
||||||
|
bleManagers = null;
|
||||||
|
managedDevices = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method called when Bluetooth Adapter has been disabled.
|
||||||
|
*/
|
||||||
|
protected void onBluetoothDisabled() {
|
||||||
|
// do nothing, BleManagers have their own Bluetooth State broadcast received and will close themselves
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called when Bluetooth Adapter has been enabled. It is also called
|
||||||
|
* after the service was created if Bluetooth Adapter was enabled at that moment.
|
||||||
|
* This method could initialize all Bluetooth related features, for example open the GATT server.
|
||||||
|
* Make sure you call <code>super.onBluetoothEnabled()</code> at this methods reconnects to
|
||||||
|
* devices that were connected before the Bluetooth was turned off.
|
||||||
|
*/
|
||||||
|
protected void onBluetoothEnabled() {
|
||||||
|
for (final BluetoothDevice device : managedDevices) {
|
||||||
|
final BleManager manager = bleManagers.get(device);
|
||||||
|
if (manager != null && !manager.isConnected())
|
||||||
|
manager.connect(device).enqueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceConnecting(@NonNull final BluetoothDevice device) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_CONNECTION_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, device);
|
||||||
|
broadcast.putExtra(EXTRA_CONNECTION_STATE, STATE_CONNECTING);
|
||||||
|
LocalBroadcastManager.getInstance(BleMulticonnectProfileService.this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceConnected(@NonNull final BluetoothDevice device) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_CONNECTION_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, device);
|
||||||
|
broadcast.putExtra(EXTRA_CONNECTION_STATE, STATE_CONNECTED);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceDisconnecting(@NonNull final BluetoothDevice device) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_CONNECTION_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, device);
|
||||||
|
broadcast.putExtra(EXTRA_CONNECTION_STATE, STATE_DISCONNECTING);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceDisconnected(@NonNull final BluetoothDevice device) {
|
||||||
|
// Note: if BleManager#shouldAutoConnect() for this device returned true, this callback will be
|
||||||
|
// invoked ONLY when user requested disconnection (using Disconnect button). If the device
|
||||||
|
// disconnects due to a link loss, the onLinkLossOccurred(BluetoothDevice) method will be called instead.
|
||||||
|
|
||||||
|
// We no longer want to keep the device in the service
|
||||||
|
managedDevices.remove(device);
|
||||||
|
// The BleManager is not removed from the HashMap in order to keep the device's log session.
|
||||||
|
// bleManagers.remove(device);
|
||||||
|
|
||||||
|
// Do not use the device argument here unless you change calling onDeviceDisconnected from the binder above
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_CONNECTION_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, device);
|
||||||
|
broadcast.putExtra(EXTRA_CONNECTION_STATE, STATE_DISCONNECTED);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
|
||||||
|
// When user disconnected the last device while the activity was not bound the service can be stopped
|
||||||
|
if (!bound && managedDevices.isEmpty()) {
|
||||||
|
stopSelf();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLinkLossOccurred(@NonNull final BluetoothDevice device) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_CONNECTION_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, device);
|
||||||
|
broadcast.putExtra(EXTRA_CONNECTION_STATE, STATE_LINK_LOSS);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServicesDiscovered(@NonNull final BluetoothDevice device, final boolean optionalServicesFound) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_SERVICES_DISCOVERED);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, device);
|
||||||
|
broadcast.putExtra(EXTRA_SERVICE_PRIMARY, true);
|
||||||
|
broadcast.putExtra(EXTRA_SERVICE_SECONDARY, optionalServicesFound);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceReady(@NonNull final BluetoothDevice device) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_DEVICE_READY);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, device);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceNotSupported(@NonNull final BluetoothDevice device) {
|
||||||
|
// We don't like this device, remove it from both collections
|
||||||
|
managedDevices.remove(device);
|
||||||
|
bleManagers.remove(device);
|
||||||
|
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_SERVICES_DISCOVERED);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, device);
|
||||||
|
broadcast.putExtra(EXTRA_SERVICE_PRIMARY, false);
|
||||||
|
broadcast.putExtra(EXTRA_SERVICE_SECONDARY, false);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
|
||||||
|
// no need for disconnecting, it will be disconnected by the manager automatically
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public void onBatteryValueReceived(@NonNull final BluetoothDevice device, final int value) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_BATTERY_LEVEL);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, device);
|
||||||
|
broadcast.putExtra(EXTRA_BATTERY_LEVEL, value);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBondingRequired(@NonNull final BluetoothDevice device) {
|
||||||
|
showToast("bonding ");
|
||||||
|
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_BOND_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, device);
|
||||||
|
broadcast.putExtra(EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDING);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBonded(@NonNull final BluetoothDevice device) {
|
||||||
|
showToast(" bonded ");
|
||||||
|
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_BOND_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, device);
|
||||||
|
broadcast.putExtra(EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDED);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBondingFailed(@NonNull final BluetoothDevice device) {
|
||||||
|
showToast(" bonding_failed ");
|
||||||
|
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_BOND_STATE);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, device);
|
||||||
|
broadcast.putExtra(EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(@NonNull final BluetoothDevice device, @NonNull final String message, final int errorCode) {
|
||||||
|
final Intent broadcast = new Intent(BROADCAST_ERROR);
|
||||||
|
broadcast.putExtra(EXTRA_DEVICE, device);
|
||||||
|
broadcast.putExtra(EXTRA_ERROR_MESSAGE, message);
|
||||||
|
broadcast.putExtra(EXTRA_ERROR_CODE, errorCode);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a message as a Toast notification. This method is thread safe, you can call it from any thread
|
||||||
|
*
|
||||||
|
* @param messageResId
|
||||||
|
* an resource id of the message to be shown
|
||||||
|
*/
|
||||||
|
protected void showToast(final int messageResId) {
|
||||||
|
handler.post(() -> Toast.makeText(BleMulticonnectProfileService.this, messageResId, Toast.LENGTH_SHORT).show());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a message as a Toast notification. This method is thread safe, you can call it from any thread
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* a message to be shown
|
||||||
|
*/
|
||||||
|
protected void showToast(final String message) {
|
||||||
|
handler.post(() -> Toast.makeText(BleMulticonnectProfileService.this, message, Toast.LENGTH_SHORT).show());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link BleManager} object associated with given device, or null if such has not been created.
|
||||||
|
* To create a BleManager call the {@link LocalBinder#connect(BluetoothDevice)} method must be called.
|
||||||
|
* @param device the target device
|
||||||
|
* @return the BleManager or null
|
||||||
|
*/
|
||||||
|
protected BleManager getBleManager(final BluetoothDevice device) {
|
||||||
|
return bleManagers.get(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns unmodifiable list of all managed devices. They don't have to be connected at the moment.
|
||||||
|
* @return list of managed devices
|
||||||
|
*/
|
||||||
|
protected List<BluetoothDevice> getManagedDevices() {
|
||||||
|
return Collections.unmodifiableList(managedDevices);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of those managed devices that are connected at the moment.
|
||||||
|
* @return list of connected devices
|
||||||
|
*/
|
||||||
|
protected List<BluetoothDevice> getConnectedDevices() {
|
||||||
|
final List<BluetoothDevice> list = new ArrayList<>();
|
||||||
|
for (BluetoothDevice device : managedDevices) {
|
||||||
|
final BleManager manager = bleManagers.get(device);
|
||||||
|
if (manager != null && manager.isConnected())
|
||||||
|
list.add(device);
|
||||||
|
}
|
||||||
|
return Collections.unmodifiableList(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if the device is connected to the sensor.
|
||||||
|
* @param device the target device
|
||||||
|
* @return <code>true</code> if device is connected to the sensor, <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
protected boolean isConnected(final BluetoothDevice device) {
|
||||||
|
final BleManager manager = bleManagers.get(device);
|
||||||
|
return manager != null && manager.isConnected();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,502 @@
|
|||||||
|
package no.Reader.android.iisc.profile.multiconnect;
|
||||||
|
|
||||||
|
import android.app.Service;
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.bluetooth.BluetoothManager;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.content.ServiceConnection;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.ble.BleManagerCallbacks;
|
||||||
|
import no.nordicsemi.android.log.ILogSession;
|
||||||
|
import no.nordicsemi.android.log.LocalLogSession;
|
||||||
|
import no.nordicsemi.android.log.Logger;
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
import no.Reader.android.iisc.scanner.ScannerFragment;
|
||||||
|
import no.Reader.android.iisc.DebugLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* The {@link BleMulticonnectProfileServiceReadyActivity} activity is designed to be the base class for profile activities that uses services in order to connect
|
||||||
|
* more than one device at the same time. A service extending {@link BleMulticonnectProfileService} is created when the activity is created, and the activity binds to it.
|
||||||
|
* The service returns a binder that may be used to connect, disconnect or manage devices, and notifies the
|
||||||
|
* activity using Local Broadcasts ({@link LocalBroadcastManager}). See {@link BleMulticonnectProfileService} for messages. If the device is not in range it will listen for
|
||||||
|
* it and connect when it become visible. The service exists until all managed devices have been disconnected and unmanaged and the last activity unbinds from it.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* When user closes the activity (e.g. by pressing Back button) while being connected, the Service remains working. It's remains connected to the devices or still
|
||||||
|
* listens for updates from them. When entering back to the activity, activity will to bind to the service and refresh UI.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public abstract class BleMulticonnectProfileServiceReadyActivity<E extends BleMulticonnectProfileService.LocalBinder> extends AppCompatActivity implements
|
||||||
|
ScannerFragment.OnDeviceSelectedListener, BleManagerCallbacks {
|
||||||
|
private static final String TAG = "BleMulticonnectProfileServiceReadyActivity";
|
||||||
|
|
||||||
|
protected static final int REQUEST_ENABLE_BT = 2;
|
||||||
|
|
||||||
|
private E mService;
|
||||||
|
private List<BluetoothDevice> mManagedDevices;
|
||||||
|
|
||||||
|
private final BroadcastReceiver mCommonBroadcastReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
|
final BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BleMulticonnectProfileService.EXTRA_DEVICE);
|
||||||
|
final String action = intent.getAction();
|
||||||
|
switch (action) {
|
||||||
|
case BleMulticonnectProfileService.BROADCAST_CONNECTION_STATE: {
|
||||||
|
final int state = intent.getIntExtra(BleMulticonnectProfileService.EXTRA_CONNECTION_STATE, BleMulticonnectProfileService.STATE_DISCONNECTED);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case BleMulticonnectProfileService.STATE_CONNECTED: {
|
||||||
|
onDeviceConnected(bluetoothDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleMulticonnectProfileService.STATE_DISCONNECTED: {
|
||||||
|
onDeviceDisconnected(bluetoothDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleMulticonnectProfileService.STATE_LINK_LOSS: {
|
||||||
|
onLinkLossOccurred(bluetoothDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleMulticonnectProfileService.STATE_CONNECTING: {
|
||||||
|
onDeviceConnecting(bluetoothDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleMulticonnectProfileService.STATE_DISCONNECTING: {
|
||||||
|
onDeviceDisconnecting(bluetoothDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// there should be no other actions
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleMulticonnectProfileService.BROADCAST_SERVICES_DISCOVERED: {
|
||||||
|
final boolean primaryService = intent.getBooleanExtra(BleMulticonnectProfileService.EXTRA_SERVICE_PRIMARY, false);
|
||||||
|
final boolean secondaryService = intent.getBooleanExtra(BleMulticonnectProfileService.EXTRA_SERVICE_SECONDARY, false);
|
||||||
|
|
||||||
|
if (primaryService) {
|
||||||
|
onServicesDiscovered(bluetoothDevice, secondaryService);
|
||||||
|
} else {
|
||||||
|
onDeviceNotSupported(bluetoothDevice);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleMulticonnectProfileService.BROADCAST_DEVICE_READY: {
|
||||||
|
onDeviceReady(bluetoothDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleMulticonnectProfileService.BROADCAST_BOND_STATE: {
|
||||||
|
final int state = intent.getIntExtra(BleMulticonnectProfileService.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
|
||||||
|
switch (state) {
|
||||||
|
case BluetoothDevice.BOND_BONDING:
|
||||||
|
onBondingRequired(bluetoothDevice);
|
||||||
|
break;
|
||||||
|
case BluetoothDevice.BOND_BONDED:
|
||||||
|
onBonded(bluetoothDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleMulticonnectProfileService.BROADCAST_BATTERY_LEVEL: {
|
||||||
|
final int value = intent.getIntExtra(BleMulticonnectProfileService.EXTRA_BATTERY_LEVEL, -1);
|
||||||
|
if (value > 0)
|
||||||
|
onBatteryValueReceived(bluetoothDevice, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BleMulticonnectProfileService.BROADCAST_ERROR: {
|
||||||
|
final String message = intent.getStringExtra(BleMulticonnectProfileService.EXTRA_ERROR_MESSAGE);
|
||||||
|
final int errorCode = intent.getIntExtra(BleMulticonnectProfileService.EXTRA_ERROR_CODE, 0);
|
||||||
|
onError(bluetoothDevice, message, errorCode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private ServiceConnection mServiceConnection = new ServiceConnection() {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected(final ComponentName name, final IBinder service) {
|
||||||
|
final E bleService = mService = (E) service;
|
||||||
|
bleService.log(Log.DEBUG, "Activity bound to the service");
|
||||||
|
mManagedDevices.addAll(bleService.getManagedDevices());
|
||||||
|
onServiceBound(bleService);
|
||||||
|
|
||||||
|
// and notify user if device is connected
|
||||||
|
for (final BluetoothDevice device : mManagedDevices) {
|
||||||
|
if (bleService.isConnected(device))
|
||||||
|
onDeviceConnected(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected(final ComponentName name) {
|
||||||
|
mService = null;
|
||||||
|
onServiceUnbound();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
mManagedDevices = new ArrayList<>();
|
||||||
|
|
||||||
|
ensureBLESupported();
|
||||||
|
if (!isBLEEnabled()) {
|
||||||
|
showBLEDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
// In onInitialize method a final class may register local broadcast receivers that will listen for events from the service
|
||||||
|
onInitialize(savedInstanceState);
|
||||||
|
// The onCreateView class should... create the view
|
||||||
|
onCreateView(savedInstanceState);
|
||||||
|
|
||||||
|
final Toolbar toolbar = findViewById(R.id.toolbar_actionbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
// Common nRF Toolbox view references are obtained here
|
||||||
|
setUpView();
|
||||||
|
// View is ready to be used
|
||||||
|
onViewCreated(savedInstanceState);
|
||||||
|
|
||||||
|
LocalBroadcastManager.getInstance(this).registerReceiver(mCommonBroadcastReceiver, makeIntentFilter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In comparison to BleProfileServiceReadyActivity this activity always starts the service when started.
|
||||||
|
* Connecting to a device is done by calling mService.connect(BluetoothDevice) method, not startService(...) like there.
|
||||||
|
* The service will stop itself when all devices it manages were disconnected and unmanaged and the last activity unbinds from it.
|
||||||
|
*/
|
||||||
|
final Intent service = new Intent(this, getServiceClass());
|
||||||
|
startService(service);
|
||||||
|
bindService(service, mServiceConnection, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
|
||||||
|
if (mService != null) {
|
||||||
|
// We don't want to perform some operations (e.g. disable Battery Level notifications) in the service if we are just rotating the screen.
|
||||||
|
// However, when the activity will disappear, we may want to disable some device features to reduce the battery consumption.
|
||||||
|
mService.setActivityIsChangingConfiguration(isChangingConfigurations());
|
||||||
|
// Log it here as there is no callback when the service gets unbound
|
||||||
|
// and the mService will not be available later (the activity doesn't keep log sessions)
|
||||||
|
mService.log(Log.DEBUG, "Activity unbound from the service");
|
||||||
|
}
|
||||||
|
|
||||||
|
unbindService(mServiceConnection);
|
||||||
|
mService = null;
|
||||||
|
|
||||||
|
onServiceUnbound();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
|
||||||
|
LocalBroadcastManager.getInstance(this).unregisterReceiver(mCommonBroadcastReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IntentFilter makeIntentFilter() {
|
||||||
|
final IntentFilter intentFilter = new IntentFilter();
|
||||||
|
intentFilter.addAction(BleMulticonnectProfileService.BROADCAST_CONNECTION_STATE);
|
||||||
|
intentFilter.addAction(BleMulticonnectProfileService.BROADCAST_SERVICES_DISCOVERED);
|
||||||
|
intentFilter.addAction(BleMulticonnectProfileService.BROADCAST_DEVICE_READY);
|
||||||
|
intentFilter.addAction(BleMulticonnectProfileService.BROADCAST_BOND_STATE);
|
||||||
|
intentFilter.addAction(BleMulticonnectProfileService.BROADCAST_BATTERY_LEVEL);
|
||||||
|
intentFilter.addAction(BleMulticonnectProfileService.BROADCAST_ERROR);
|
||||||
|
return intentFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when activity binds to the service. The parameter is the object returned in {@link Service#onBind(Intent)} method in your service.
|
||||||
|
* It is safe to obtain managed devices now.
|
||||||
|
*/
|
||||||
|
protected abstract void onServiceBound(E binder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when activity unbinds from the service. You may no longer use this binder methods.
|
||||||
|
*/
|
||||||
|
protected abstract void onServiceUnbound();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the service class for sensor communication. The service class must derive from {@link BleMulticonnectProfileService} in order to operate with this class.
|
||||||
|
*
|
||||||
|
* @return the service class
|
||||||
|
*/
|
||||||
|
protected abstract Class<? extends BleMulticonnectProfileService> getServiceClass();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the service interface that may be used to communicate with the sensor. This will return <code>null</code> if the device is disconnected from the
|
||||||
|
* sensor.
|
||||||
|
*
|
||||||
|
* @return the service binder or <code>null</code>
|
||||||
|
*/
|
||||||
|
protected E getService() {
|
||||||
|
return mService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* You may do some initialization here. This method is called from {@link #onCreate(Bundle)} before the view was created.
|
||||||
|
*/
|
||||||
|
protected void onInitialize(final Bundle savedInstanceState) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called from {@link #onCreate(Bundle)}. This method should build the activity UI, i.e. using {@link #setContentView(int)}.
|
||||||
|
* Use to obtain references to views. Connect/Disconnect button and the device name view are manager automatically.
|
||||||
|
*
|
||||||
|
* @param savedInstanceState contains the data it most recently supplied in {@link #onSaveInstanceState(Bundle)}.
|
||||||
|
* Note: <b>Otherwise it is null</b>.
|
||||||
|
*/
|
||||||
|
protected abstract void onCreateView(final Bundle savedInstanceState);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after the view has been created.
|
||||||
|
*
|
||||||
|
* @param savedInstanceState contains the data it most recently supplied in {@link #onSaveInstanceState(Bundle)}.
|
||||||
|
* Note: <b>Otherwise it is null</b>.
|
||||||
|
*/
|
||||||
|
protected void onViewCreated(final Bundle savedInstanceState) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after the view and the toolbar has been created.
|
||||||
|
*/
|
||||||
|
protected final void setUpView() {
|
||||||
|
// set GUI
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this method to handle menu actions other than home and about.
|
||||||
|
*
|
||||||
|
* @param itemId the menu item id
|
||||||
|
* @return <code>true</code> if action has been handled
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when user press ADD DEVICE button. See layout files -> onClick attribute.
|
||||||
|
*/
|
||||||
|
public void onAddDeviceClicked(final View view) {
|
||||||
|
if (isBLEEnabled()) {
|
||||||
|
showDeviceScanningDialog(getFilterUUID());
|
||||||
|
} else {
|
||||||
|
showBLEDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the title resource id that will be used to create logger session. If 0 is returned (default) logger will not be used.
|
||||||
|
*
|
||||||
|
* @return the title resource id
|
||||||
|
*/
|
||||||
|
protected int getLoggerProfileTitle() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method may return the local log content provider authority if local log sessions are supported.
|
||||||
|
*
|
||||||
|
* @return local log session content provider URI
|
||||||
|
*/
|
||||||
|
protected Uri getLocalAuthorityLogger() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceSelected(final BluetoothDevice device, final String name) {
|
||||||
|
final int titleId = getLoggerProfileTitle();
|
||||||
|
ILogSession logSession = null;
|
||||||
|
if (titleId > 0) {
|
||||||
|
logSession = Logger.newSession(getApplicationContext(), getString(titleId), device.getAddress(), name);
|
||||||
|
// If nRF Logger is not installed we may want to use local logger
|
||||||
|
if (logSession == null && getLocalAuthorityLogger() != null) {
|
||||||
|
logSession = LocalLogSession.newSession(getApplicationContext(), getLocalAuthorityLogger(), device.getAddress(), name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mService.connect(device, logSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDialogCanceled() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceConnecting(final BluetoothDevice device) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceDisconnecting(final BluetoothDevice device) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLinkLossOccurred(final BluetoothDevice device) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServicesDiscovered(final BluetoothDevice device, final boolean optionalServicesFound) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceReady(final BluetoothDevice device) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBondingRequired(final BluetoothDevice device) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBonded(final BluetoothDevice device) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBondingFailed(final BluetoothDevice device) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeviceNotSupported(final BluetoothDevice device) {
|
||||||
|
showToast(R.string.not_supported);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean shouldEnableBatteryLevelNotifications(final BluetoothDevice device) {
|
||||||
|
// This method will never be called.
|
||||||
|
// Please see BleMulticonnectProfileService#shouldEnableBatteryLevelNotifications(BluetoothDevice) instead.
|
||||||
|
throw new UnsupportedOperationException("This method should not be called");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBatteryValueReceived(final BluetoothDevice device, final int value) {
|
||||||
|
// empty default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(final BluetoothDevice device, final String message, final int errorCode) {
|
||||||
|
DebugLogger.e(TAG, "Error occurred: " + message + ", error code: " + errorCode);
|
||||||
|
showToast(message + " (" + errorCode + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a message as a Toast notification. This method is thread safe, you can call it from any thread
|
||||||
|
*
|
||||||
|
* @param message a message to be shown
|
||||||
|
*/
|
||||||
|
protected void showToast(final String message) {
|
||||||
|
runOnUiThread(() -> Toast.makeText(BleMulticonnectProfileServiceReadyActivity.this, message, Toast.LENGTH_LONG).show());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a message as a Toast notification. This method is thread safe, you can call it from any thread
|
||||||
|
*
|
||||||
|
* @param messageResId an resource id of the message to be shown
|
||||||
|
*/
|
||||||
|
protected void showToast(final int messageResId) {
|
||||||
|
runOnUiThread(() -> Toast.makeText(BleMulticonnectProfileServiceReadyActivity.this, messageResId, Toast.LENGTH_SHORT).show());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the string resource id that will be shown in About box
|
||||||
|
*
|
||||||
|
* @return the about resource id
|
||||||
|
*/
|
||||||
|
protected abstract int getAboutTextId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The UUID filter is used to filter out available devices that does not have such UUID in their advertisement packet. See also:
|
||||||
|
* {@link #isChangingConfigurations()}.
|
||||||
|
*
|
||||||
|
* @return the required UUID or <code>null</code>
|
||||||
|
*/
|
||||||
|
protected abstract UUID getFilterUUID();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns unmodifiable list of managed devices. Managed device is a device the was selected on ScannerFragment until it's removed from the managed list.
|
||||||
|
* It does not have to be connected at that moment.
|
||||||
|
* @return unmodifiable list of managed devices
|
||||||
|
*/
|
||||||
|
protected List<BluetoothDevice> getManagedDevices() {
|
||||||
|
return Collections.unmodifiableList(mManagedDevices);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if the device is connected. Services may not have been discovered yet.
|
||||||
|
* @param device the device to check if it's connected
|
||||||
|
*/
|
||||||
|
protected boolean isDeviceConnected(final BluetoothDevice device) {
|
||||||
|
return mService != null && mService.isConnected(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the scanner fragment.
|
||||||
|
*
|
||||||
|
* @param filter the UUID filter used to filter out available devices. The fragment will always show all bonded devices as there is no information about their
|
||||||
|
* services
|
||||||
|
* @see #getFilterUUID()
|
||||||
|
*/
|
||||||
|
private void showDeviceScanningDialog(final UUID filter) {
|
||||||
|
final ScannerFragment dialog = ScannerFragment.getInstance(filter);
|
||||||
|
dialog.show(getSupportFragmentManager(), "scan_fragment");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureBLESupported() {
|
||||||
|
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
|
||||||
|
Toast.makeText(this, R.string.no_ble, Toast.LENGTH_LONG).show();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isBLEEnabled() {
|
||||||
|
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
|
||||||
|
final BluetoothAdapter adapter = bluetoothManager.getAdapter();
|
||||||
|
return adapter != null && adapter.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void showBLEDialog() {
|
||||||
|
final Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
|
||||||
|
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016, Nordic Semiconductor
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package no.Reader.android.iisc.profile.multiconnect;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import androidx.annotation.StringRes;
|
||||||
|
|
||||||
|
public interface IDeviceLogger {
|
||||||
|
/**
|
||||||
|
* Logs the given message with given log level into the device's log session.
|
||||||
|
* @param device the target device
|
||||||
|
* @param level the log level
|
||||||
|
* @param message the message to be logged
|
||||||
|
*/
|
||||||
|
void log(final BluetoothDevice device, final int level, final String message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs the given message with given log level into the device's log session.
|
||||||
|
* @param device the target device
|
||||||
|
* @param level the log level
|
||||||
|
* @param messageRes string resource id
|
||||||
|
* @param params additional (optional) parameters used to fill the message
|
||||||
|
*/
|
||||||
|
void log(final BluetoothDevice device, final int level, @StringRes final int messageRes, final Object... params);
|
||||||
|
}
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
package no.Reader.android.iisc.scanner;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.support.v18.scanner.ScanResult;
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DeviceListAdapter class is list adapter for showing scanned Devices name, address and RSSI image based on RSSI values.
|
||||||
|
*/
|
||||||
|
public class DeviceListAdapter extends BaseAdapter {
|
||||||
|
private static final int TYPE_TITLE = 0;
|
||||||
|
private static final int TYPE_ITEM = 1;
|
||||||
|
private static final int TYPE_EMPTY = 2;
|
||||||
|
|
||||||
|
private final ArrayList<ExtendedBluetoothDevice> mListBondedValues = new ArrayList<>();
|
||||||
|
private final ArrayList<ExtendedBluetoothDevice> mListValues = new ArrayList<>();
|
||||||
|
private final Context mContext;
|
||||||
|
|
||||||
|
public DeviceListAdapter(final Context context) {
|
||||||
|
mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a list of bonded devices.
|
||||||
|
* @param devices list of bonded devices.
|
||||||
|
*/
|
||||||
|
public void addBondedDevices(final Set<BluetoothDevice> devices) {
|
||||||
|
final List<ExtendedBluetoothDevice> bondedDevices = mListBondedValues;
|
||||||
|
for (BluetoothDevice device : devices) {
|
||||||
|
bondedDevices.add(new ExtendedBluetoothDevice(device));
|
||||||
|
}
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the list of not bonded devices.
|
||||||
|
* @param results list of results from the scanner
|
||||||
|
*/
|
||||||
|
public void update(final List<ScanResult> results) {
|
||||||
|
for (final ScanResult result : results) {
|
||||||
|
final ExtendedBluetoothDevice device = findDevice(result);
|
||||||
|
if (device == null) {
|
||||||
|
mListValues.add(new ExtendedBluetoothDevice(result));
|
||||||
|
} else {
|
||||||
|
device.name = result.getScanRecord() != null ? result.getScanRecord().getDeviceName() : null;
|
||||||
|
device.rssi = result.getRssi();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExtendedBluetoothDevice findDevice(final ScanResult result) {
|
||||||
|
for (final ExtendedBluetoothDevice device : mListBondedValues)
|
||||||
|
if (device.matches(result))
|
||||||
|
return device;
|
||||||
|
for (final ExtendedBluetoothDevice device : mListValues)
|
||||||
|
if (device.matches(result))
|
||||||
|
return device;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearDevices() {
|
||||||
|
mListValues.clear();
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
final int bondedCount = mListBondedValues.size() + 1; // 1 for the title
|
||||||
|
final int availableCount = mListValues.isEmpty() ? 2 : mListValues.size() + 1; // 1 for title, 1 for empty text
|
||||||
|
if (bondedCount == 1)
|
||||||
|
return availableCount;
|
||||||
|
return bondedCount + availableCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getItem(int position) {
|
||||||
|
final int bondedCount = mListBondedValues.size() + 1; // 1 for the title
|
||||||
|
if (mListBondedValues.isEmpty()) {
|
||||||
|
if (position == 0)
|
||||||
|
return R.string.scanner_subtitle_not_bonded;
|
||||||
|
else
|
||||||
|
return mListValues.get(position - 1);
|
||||||
|
} else {
|
||||||
|
if (position == 0)
|
||||||
|
return R.string.scanner_subtitle_bonded;
|
||||||
|
if (position < bondedCount)
|
||||||
|
return mListBondedValues.get(position - 1);
|
||||||
|
if (position == bondedCount)
|
||||||
|
return R.string.scanner_subtitle_not_bonded;
|
||||||
|
return mListValues.get(position - bondedCount - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getViewTypeCount() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areAllItemsEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled(int position) {
|
||||||
|
return getItemViewType(position) == TYPE_ITEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
if (position == 0)
|
||||||
|
return TYPE_TITLE;
|
||||||
|
|
||||||
|
if (!mListBondedValues.isEmpty() && position == mListBondedValues.size() + 1)
|
||||||
|
return TYPE_TITLE;
|
||||||
|
|
||||||
|
if (position == getCount() - 1 && mListValues.isEmpty())
|
||||||
|
return TYPE_EMPTY;
|
||||||
|
|
||||||
|
return TYPE_ITEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View oldView, ViewGroup parent) {
|
||||||
|
final LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||||
|
final int type = getItemViewType(position);
|
||||||
|
|
||||||
|
View view = oldView;
|
||||||
|
switch (type) {
|
||||||
|
case TYPE_EMPTY:
|
||||||
|
if (view == null) {
|
||||||
|
view = inflater.inflate(R.layout.device_list_empty, parent, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_TITLE:
|
||||||
|
if (view == null) {
|
||||||
|
view = inflater.inflate(R.layout.device_list_title, parent, false);
|
||||||
|
}
|
||||||
|
final TextView title = (TextView) view;
|
||||||
|
title.setText((Integer) getItem(position));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (view == null) {
|
||||||
|
view = inflater.inflate(R.layout.device_list_row, parent, false);
|
||||||
|
final ViewHolder holder = new ViewHolder();
|
||||||
|
holder.name = view.findViewById(R.id.name);
|
||||||
|
holder.address = view.findViewById(R.id.address);
|
||||||
|
holder.rssi = view.findViewById(R.id.rssi);
|
||||||
|
view.setTag(holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ExtendedBluetoothDevice device = (ExtendedBluetoothDevice) getItem(position);
|
||||||
|
final ViewHolder holder = (ViewHolder) view.getTag();
|
||||||
|
final String name = device.name;
|
||||||
|
holder.name.setText(name != null ? name : mContext.getString(R.string.not_available));
|
||||||
|
holder.address.setText(device.device.getAddress());
|
||||||
|
if (!device.isBonded || device.rssi != ExtendedBluetoothDevice.NO_RSSI) {
|
||||||
|
final int rssiPercent = (int) (100.0f * (127.0f + device.rssi) / (127.0f + 20.0f));
|
||||||
|
holder.rssi.setImageLevel(rssiPercent);
|
||||||
|
holder.rssi.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
holder.rssi.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ViewHolder {
|
||||||
|
private TextView name;
|
||||||
|
private TextView address;
|
||||||
|
private ImageView rssi;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package no.Reader.android.iisc.scanner;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.support.v18.scanner.ScanResult;
|
||||||
|
|
||||||
|
public class ExtendedBluetoothDevice {
|
||||||
|
/* package */ static final int NO_RSSI = -1000;
|
||||||
|
public final BluetoothDevice device;
|
||||||
|
/** The name is not parsed by some Android devices, f.e. Sony Xperia Z1 with Android 4.3 (C6903). It needs to be parsed manually. */
|
||||||
|
public String name;
|
||||||
|
public int rssi;
|
||||||
|
public boolean isBonded;
|
||||||
|
|
||||||
|
public ExtendedBluetoothDevice(final ScanResult scanResult) {
|
||||||
|
this.device = scanResult.getDevice();
|
||||||
|
this.name = scanResult.getScanRecord() != null ? scanResult.getScanRecord().getDeviceName() : null;
|
||||||
|
this.rssi = scanResult.getRssi();
|
||||||
|
this.isBonded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedBluetoothDevice(final BluetoothDevice device) {
|
||||||
|
this.device = device;
|
||||||
|
this.name = device.getName();
|
||||||
|
this.rssi = NO_RSSI;
|
||||||
|
this.isBonded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean matches(final ScanResult scanResult) {
|
||||||
|
return device.getAddress().equals(scanResult.getDevice().getAddress());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,268 @@
|
|||||||
|
package no.Reader.android.iisc.scanner;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.bluetooth.BluetoothManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.ParcelUuid;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerCompat;
|
||||||
|
import no.nordicsemi.android.support.v18.scanner.ScanCallback;
|
||||||
|
import no.nordicsemi.android.support.v18.scanner.ScanFilter;
|
||||||
|
import no.nordicsemi.android.support.v18.scanner.ScanResult;
|
||||||
|
import no.nordicsemi.android.support.v18.scanner.ScanSettings;
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ScannerFragment class scan required BLE devices and shows them in a list. This class scans and filter
|
||||||
|
* devices with standard BLE Service UUID and devices with custom BLE Service UUID. It contains a
|
||||||
|
* list and a button to scan/cancel. There is a interface {@link OnDeviceSelectedListener} which is
|
||||||
|
* implemented by activity in order to receive selected device. The scanning will continue to scan
|
||||||
|
* for 5 seconds and then stop.
|
||||||
|
*/
|
||||||
|
public class ScannerFragment extends DialogFragment {
|
||||||
|
private final static String TAG = "ScannerFragment";
|
||||||
|
|
||||||
|
private final static String PARAM_UUID = "param_uuid";
|
||||||
|
private final static long SCAN_DURATION = 5000;
|
||||||
|
|
||||||
|
private final static int REQUEST_PERMISSION_REQ_CODE = 34; // any 8-bit number
|
||||||
|
|
||||||
|
private BluetoothAdapter mBluetoothAdapter;
|
||||||
|
private OnDeviceSelectedListener mListener;
|
||||||
|
private DeviceListAdapter mAdapter;
|
||||||
|
private final Handler mHandler = new Handler();
|
||||||
|
private Button mScanButton;
|
||||||
|
|
||||||
|
private View mPermissionRationale;
|
||||||
|
|
||||||
|
private ParcelUuid mUuid;
|
||||||
|
|
||||||
|
private boolean mIsScanning = false;
|
||||||
|
|
||||||
|
public static ScannerFragment getInstance(final UUID uuid) {
|
||||||
|
final ScannerFragment fragment = new ScannerFragment();
|
||||||
|
|
||||||
|
final Bundle args = new Bundle();
|
||||||
|
if (uuid != null)
|
||||||
|
args.putParcelable(PARAM_UUID, new ParcelUuid(uuid));
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface required to be implemented by activity.
|
||||||
|
*/
|
||||||
|
public interface OnDeviceSelectedListener {
|
||||||
|
/**
|
||||||
|
* Fired when user selected the device.
|
||||||
|
*
|
||||||
|
* @param device
|
||||||
|
* the device to connect to
|
||||||
|
* @param name
|
||||||
|
* the device name. Unfortunately on some devices {@link BluetoothDevice#getName()}
|
||||||
|
* always returns <code>null</code>, i.e. Sony Xperia Z1 (C6903) with Android 4.3.
|
||||||
|
* The name has to be parsed manually form the Advertisement packet.
|
||||||
|
*/
|
||||||
|
void onDeviceSelected(final BluetoothDevice device, final String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired when scanner dialog has been cancelled without selecting a device.
|
||||||
|
*/
|
||||||
|
void onDialogCanceled();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will make sure that {@link OnDeviceSelectedListener} interface is implemented by activity.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onAttach(final Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
try {
|
||||||
|
this.mListener = (OnDeviceSelectedListener) context;
|
||||||
|
} catch (final ClassCastException e) {
|
||||||
|
throw new ClassCastException(context.toString() + " must implement OnDeviceSelectedListener");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
final Bundle args = getArguments();
|
||||||
|
if (args != null && args.containsKey(PARAM_UUID)) {
|
||||||
|
mUuid = args.getParcelable(PARAM_UUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
final BluetoothManager manager = (BluetoothManager) requireContext().getSystemService(Context.BLUETOOTH_SERVICE);
|
||||||
|
if (manager != null) {
|
||||||
|
mBluetoothAdapter = manager.getAdapter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
stopScan();
|
||||||
|
super.onDestroyView();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||||
|
final AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
|
||||||
|
final View dialogView = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_device_selection, null);
|
||||||
|
final ListView listview = dialogView.findViewById(android.R.id.list);
|
||||||
|
|
||||||
|
listview.setEmptyView(dialogView.findViewById(android.R.id.empty));
|
||||||
|
listview.setAdapter(mAdapter = new DeviceListAdapter(getActivity()));
|
||||||
|
|
||||||
|
builder.setTitle(R.string.scanner_title);
|
||||||
|
final AlertDialog dialog = builder.setView(dialogView).create();
|
||||||
|
listview.setOnItemClickListener((parent, view, position, id) -> {
|
||||||
|
stopScan();
|
||||||
|
dialog.dismiss();
|
||||||
|
final ExtendedBluetoothDevice d = (ExtendedBluetoothDevice) mAdapter.getItem(position);
|
||||||
|
mListener.onDeviceSelected(d.device, d.name);
|
||||||
|
});
|
||||||
|
|
||||||
|
mPermissionRationale = dialogView.findViewById(R.id.permission_rationale); // this is not null only on API23+
|
||||||
|
|
||||||
|
mScanButton = dialogView.findViewById(R.id.action_cancel);
|
||||||
|
mScanButton.setOnClickListener(v -> {
|
||||||
|
if (v.getId() == R.id.action_cancel) {
|
||||||
|
if (mIsScanning) {
|
||||||
|
dialog.cancel();
|
||||||
|
} else {
|
||||||
|
startScan();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
addBoundDevices();
|
||||||
|
if (savedInstanceState == null)
|
||||||
|
startScan();
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancel(DialogInterface dialog) {
|
||||||
|
super.onCancel(dialog);
|
||||||
|
|
||||||
|
mListener.onDialogCanceled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(final int requestCode, final @NonNull String[] permissions, final @NonNull int[] grantResults) {
|
||||||
|
switch (requestCode) {
|
||||||
|
case REQUEST_PERMISSION_REQ_CODE: {
|
||||||
|
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
// We have been granted the Manifest.permission.ACCESS_COARSE_LOCATION permission. Now we may proceed with scanning.
|
||||||
|
startScan();
|
||||||
|
} else {
|
||||||
|
mPermissionRationale.setVisibility(View.VISIBLE);
|
||||||
|
Toast.makeText(getActivity(), R.string.no_required_permission, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scan for 5 seconds and then stop scanning when a BluetoothLE device is found then mLEScanCallback
|
||||||
|
* is activated This will perform regular scan for custom BLE Service UUID and then filter out.
|
||||||
|
* using class ScannerServiceParser
|
||||||
|
*/
|
||||||
|
private void startScan() {
|
||||||
|
// Since Android 6.0 we need to obtain either Manifest.permission.ACCESS_COARSE_LOCATION or Manifest.permission.ACCESS_FINE_LOCATION to be able to scan for
|
||||||
|
// Bluetooth LE devices. This is related to beacons as proximity devices.
|
||||||
|
// On API older than Marshmallow the following code does nothing.
|
||||||
|
if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
// When user pressed Deny and still wants to use this functionality, show the rationale
|
||||||
|
if (ActivityCompat.shouldShowRequestPermissionRationale(requireActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) && mPermissionRationale.getVisibility() == View.GONE) {
|
||||||
|
mPermissionRationale.setVisibility(View.VISIBLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_PERMISSION_REQ_CODE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide the rationale message, we don't need it anymore.
|
||||||
|
if (mPermissionRationale != null)
|
||||||
|
mPermissionRationale.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
mAdapter.clearDevices();
|
||||||
|
mScanButton.setText(R.string.scanner_action_cancel);
|
||||||
|
|
||||||
|
final BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
|
||||||
|
final ScanSettings settings = new ScanSettings.Builder()
|
||||||
|
.setLegacy(false)
|
||||||
|
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).setReportDelay(1000).setUseHardwareBatchingIfSupported(false).build();
|
||||||
|
final List<ScanFilter> filters = new ArrayList<>();
|
||||||
|
filters.add(new ScanFilter.Builder().setServiceUuid(mUuid).build());
|
||||||
|
scanner.startScan(filters, settings, scanCallback);
|
||||||
|
mIsScanning = true;
|
||||||
|
mHandler.postDelayed(() -> {
|
||||||
|
if (mIsScanning) {
|
||||||
|
stopScan();
|
||||||
|
}
|
||||||
|
}, SCAN_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop scan if user tap Cancel button
|
||||||
|
*/
|
||||||
|
private void stopScan() {
|
||||||
|
if (mIsScanning) {
|
||||||
|
mScanButton.setText(R.string.scanner_action_scan);
|
||||||
|
|
||||||
|
final BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
|
||||||
|
scanner.stopScan(scanCallback);
|
||||||
|
|
||||||
|
mIsScanning = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScanCallback scanCallback = new ScanCallback() {
|
||||||
|
@Override
|
||||||
|
public void onScanResult(final int callbackType, final ScanResult result) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBatchScanResults(final List<ScanResult> results) {
|
||||||
|
mAdapter.update(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScanFailed(final int errorCode) {
|
||||||
|
// should never be called
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void addBoundDevices() {
|
||||||
|
final Set<BluetoothDevice> devices = mBluetoothAdapter.getBondedDevices();
|
||||||
|
mAdapter.addBondedDevices(devices);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
/*************************************************************************************************************************************************
|
||||||
|
* Copyright (c) 2015, Nordic Semiconductor
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
************************************************************************************************************************************************/
|
||||||
|
|
||||||
|
package no.Reader.android.iisc.widget;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.graphics.drawable.NinePatchDrawable;
|
||||||
|
import android.os.Build;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
|
||||||
|
import no.Reader.android.iisc.R;
|
||||||
|
|
||||||
|
|
||||||
|
public class ForegroundRelativeLayout extends RelativeLayout {
|
||||||
|
|
||||||
|
private Drawable mForegroundSelector;
|
||||||
|
private Rect mRectPadding;
|
||||||
|
private boolean mUseBackgroundPadding = false;
|
||||||
|
|
||||||
|
public ForegroundRelativeLayout(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ForegroundRelativeLayout(Context context, AttributeSet attrs) {
|
||||||
|
this(context, attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ForegroundRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
|
||||||
|
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ForegroundRelativeLayout,
|
||||||
|
defStyle, 0);
|
||||||
|
|
||||||
|
final Drawable d = a.getDrawable(R.styleable.ForegroundRelativeLayout_foreground);
|
||||||
|
if (d != null) {
|
||||||
|
setForeground(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
a.recycle();
|
||||||
|
|
||||||
|
if (this.getBackground() instanceof NinePatchDrawable) {
|
||||||
|
final NinePatchDrawable npd = (NinePatchDrawable) this.getBackground();
|
||||||
|
mRectPadding = new Rect();
|
||||||
|
if (npd.getPadding(mRectPadding)) {
|
||||||
|
mUseBackgroundPadding = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawableStateChanged() {
|
||||||
|
super.drawableStateChanged();
|
||||||
|
|
||||||
|
if (mForegroundSelector != null && mForegroundSelector.isStateful()) {
|
||||||
|
mForegroundSelector.setState(getDrawableState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||||
|
super.onSizeChanged(w, h, oldw, oldh);
|
||||||
|
|
||||||
|
if (mForegroundSelector != null) {
|
||||||
|
if (mUseBackgroundPadding) {
|
||||||
|
mForegroundSelector.setBounds(mRectPadding.left, mRectPadding.top, w - mRectPadding.right, h - mRectPadding.bottom);
|
||||||
|
} else {
|
||||||
|
mForegroundSelector.setBounds(0, 0, w, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void dispatchDraw(@NonNull Canvas canvas) {
|
||||||
|
super.dispatchDraw(canvas);
|
||||||
|
|
||||||
|
if (mForegroundSelector != null) {
|
||||||
|
mForegroundSelector.draw(canvas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean verifyDrawable(Drawable who) {
|
||||||
|
return super.verifyDrawable(who) || (who == mForegroundSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void jumpDrawablesToCurrentState() {
|
||||||
|
super.jumpDrawablesToCurrentState();
|
||||||
|
if (mForegroundSelector != null) mForegroundSelector.jumpToCurrentState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setForeground(Drawable drawable) {
|
||||||
|
if (mForegroundSelector != drawable) {
|
||||||
|
if (mForegroundSelector != null) {
|
||||||
|
mForegroundSelector.setCallback(null);
|
||||||
|
unscheduleDrawable(mForegroundSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
mForegroundSelector = drawable;
|
||||||
|
|
||||||
|
if (drawable != null) {
|
||||||
|
setWillNotDraw(false);
|
||||||
|
drawable.setCallback(this);
|
||||||
|
if (drawable.isStateful()) {
|
||||||
|
drawable.setState(getDrawableState());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setWillNotDraw(true);
|
||||||
|
}
|
||||||
|
requestLayout();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
@Override
|
||||||
|
public void drawableHotspotChanged(float x, float y) {
|
||||||
|
super.drawableHotspotChanged(x, y);
|
||||||
|
if (mForegroundSelector != null) {
|
||||||
|
mForegroundSelector.setHotspot(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
app/src/main/res/anim/bottom_animation.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<translate
|
||||||
|
android:duration="1500"
|
||||||
|
android:fromXDelta="0%"
|
||||||
|
android:fromYDelta="100%" />
|
||||||
|
<alpha
|
||||||
|
android:duration="1500"
|
||||||
|
android:fromAlpha="0.1"
|
||||||
|
android:toAlpha="1.0" />
|
||||||
|
</set>
|
||||||
16
app/src/main/res/anim/button_animation.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<alpha
|
||||||
|
android:fromAlpha="0.0"
|
||||||
|
android:toAlpha="1.0"
|
||||||
|
android:duration="500" />
|
||||||
|
|
||||||
|
<translate
|
||||||
|
android:fromYDelta="-100%"
|
||||||
|
android:toYDelta="0%"
|
||||||
|
android:duration="700" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</set>
|
||||||
10
app/src/main/res/anim/top_animation.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<translate
|
||||||
|
android:duration="2000"
|
||||||
|
android:fromXDelta="0%"
|
||||||
|
android:fromYDelta="-50%" />
|
||||||
|
<alpha
|
||||||
|
android:duration="1500"
|
||||||
|
android:fromAlpha="0.1"
|
||||||
|
android:toAlpha="1.0" />
|
||||||
|
</set>
|
||||||
5
app/src/main/res/color/button_color.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:color="@color/nordicLake" android:state_enabled="true"/>
|
||||||
|
<item android:color="#c4cbcc"/>
|
||||||
|
</selector>
|
||||||
26
app/src/main/res/color/menu_text.xml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
~ Copyright (c) 2015, Nordic Semiconductor
|
||||||
|
~ All rights reserved.
|
||||||
|
~
|
||||||
|
~ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
~
|
||||||
|
~ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
~
|
||||||
|
~ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||||
|
~ documentation and/or other materials provided with the distribution.
|
||||||
|
~
|
||||||
|
~ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||||
|
~ software without specific prior written permission.
|
||||||
|
~
|
||||||
|
~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
~ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
~ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
~ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
~ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_selected="true" android:color="@color/actionBarColorDark" />
|
||||||
|
<item android:color="#FF212121"/>
|
||||||
|
</selector>
|
||||||
BIN
app/src/main/res/drawable-hdpi/battery.png
Normal file
|
After Width: | Height: | Size: 392 B |
BIN
app/src/main/res/drawable-hdpi/download.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable-hdpi/drawer_shadow.9.png
Normal file
|
After Width: | Height: | Size: 161 B |
BIN
app/src/main/res/drawable-hdpi/dst_logo.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
app/src/main/res/drawable-hdpi/finalback.png
Normal file
|
After Width: | Height: | Size: 325 KiB |
BIN
app/src/main/res/drawable-hdpi/ic_action_bluetooth.png
Normal file
|
After Width: | Height: | Size: 307 B |
BIN
app/src/main/res/drawable-hdpi/ic_action_disconnect.png
Normal file
|
After Width: | Height: | Size: 332 B |
BIN
app/src/main/res/drawable-hdpi/ic_cgms_feature.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-hdpi/ic_rssi_0_bar.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
app/src/main/res/drawable-hdpi/ic_rssi_1_bar.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/drawable-hdpi/ic_rssi_2_bars.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/drawable-hdpi/ic_rssi_3_bars.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/drawable-hdpi/ic_stat_notify_template.png
Normal file
|
After Width: | Height: | Size: 546 B |
BIN
app/src/main/res/drawable-hdpi/ic_template_feature.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/drawable-hdpi/iisc_logo.png
Normal file
|
After Width: | Height: | Size: 224 KiB |
BIN
app/src/main/res/drawable-hdpi/negative.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |