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 |