Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ElMostafaIdrassi/4aab8b2ab510d60a3ae48b8b7856d81c to your computer and use it in GitHub Desktop.
Save ElMostafaIdrassi/4aab8b2ab510d60a3ae48b8b7856d81c to your computer and use it in GitHub Desktop.
diff wiqaytna_android opentrace-android master branches
ATTRIBUTION.md | 43 +-
README.md | 56 +--
app/build.gradle | 74 ++--
app/src/debug/AndroidManifest.xml | 2 +-
app/src/main/AndroidManifest.xml | 73 ++--
.../java/io/bluetrace/opentrace/MainActivity.kt | 91 ++--
.../java/io/bluetrace/opentrace/PeekActivity.kt | 23 +-
.../java/io/bluetrace/opentrace/PlotActivity.kt | 51 ++-
.../main/java/io/bluetrace/opentrace/Preference.kt | 26 +-
.../io/bluetrace/opentrace/RecordListAdapter.kt | 16 +-
.../java/io/bluetrace/opentrace/SplashActivity.kt | 105 ++++-
app/src/main/java/io/bluetrace/opentrace/Utils.kt | 263 +++++++-----
.../bluetrace/opentrace/bluetooth/BLEAdvertiser.kt | 6 +-
.../bluetrace/opentrace/bluetooth/BLEDiscoverer.kt | 10 +-
.../io/bluetrace/opentrace/bluetooth/BLEScanner.kt | 6 +-
.../io/bluetrace/opentrace/bluetooth/gatt/GATT.kt | 4 +-
.../opentrace/bluetooth/gatt/GattServer.kt | 10 +-
.../opentrace/bluetooth/gatt/GattService.kt | 4 +-
.../opentrace/boot/StartOnBootReceiver.kt | 18 +-
.../opentrace/fragment/EnterPinFragment.kt | 280 +++++++++---
.../bluetrace/opentrace/fragment/ForUseFragment.kt | 29 +-
.../bluetrace/opentrace/fragment/HomeFragment.kt | 176 ++++++--
.../opentrace/fragment/UploadCompleteFragment.kt | 18 +-
.../bluetrace/opentrace/idmanager/TempIDManager.kt | 96 +++--
.../bluetrace/opentrace/idmanager/TemporaryID.kt | 4 +-
.../io/bluetrace/opentrace/logging/CentralLog.kt | 4 +-
.../java/io/bluetrace/opentrace/logging/SDLog.kt | 6 +-
.../notifications/NotificationTemplates.kt | 55 ++-
.../bluetrace/opentrace/onboarding/OTPFragment.kt | 235 +++++++----
.../opentrace/onboarding/OnboardingActivity.kt | 467 ++++++++++++---------
.../onboarding/OnboardingFragmentInterface.kt | 6 +-
.../opentrace/onboarding/PreOnboardingActivity.kt | 26 +-
.../opentrace/onboarding/RegisterNumberFragment.kt | 86 +++-
.../opentrace/onboarding/SetupFragment.kt | 45 +-
.../permissions/RequestFileWritePermission.kt | 10 +-
.../io/bluetrace/opentrace/protocol/BlueTrace.kt | 6 +-
.../opentrace/protocol/BlueTraceProtocol.kt | 6 +-
.../bluetrace/opentrace/protocol/v2/BlueTraceV2.kt | 34 +-
.../opentrace/protocol/v2/V2ReadRequestPayload.kt | 4 +-
.../opentrace/protocol/v2/V2WriteRequestPayload.kt | 4 +-
.../opentrace/receivers/UpgradeReceiver.kt | 15 +-
.../io/bluetrace/opentrace/scheduler/Scheduler.kt | 6 +-
.../services/BluetoothMonitoringService.kt | 49 +--
.../bluetrace/opentrace/services/CommandHandler.kt | 2 +-
.../io/bluetrace/opentrace/services/FCMService.kt | 36 +-
.../java/io/bluetrace/opentrace/status/Status.kt | 2 +-
.../opentrace/status/persistence/StatusRecord.kt | 2 +-
.../status/persistence/StatusRecordDao.kt | 2 +-
.../status/persistence/StatusRecordStorage.kt | 44 +-
.../opentrace/streetpass/BlacklistEntry.kt | 2 +-
.../opentrace/streetpass/ConnectablePeripheral.kt | 2 +-
.../bluetrace/opentrace/streetpass/StreetPass.kt | 4 +-
.../opentrace/streetpass/StreetPassScanner.kt | 18 +-
.../opentrace/streetpass/StreetPassServer.kt | 6 +-
.../opentrace/streetpass/StreetPassWorker.kt | 29 +-
.../java/io/bluetrace/opentrace/streetpass/Work.kt | 4 +-
.../streetpass/persistence/StreetPassRecord.kt | 2 +-
.../streetpass/persistence/StreetPassRecordDao.kt | 2 +-
.../persistence/StreetPassRecordDatabase.kt | 14 +-
.../persistence/StreetPassRecordRepository.kt | 11 +-
.../persistence/StreetPassRecordStorage.kt | 41 +-
.../opentrace/streetpass/view/RecordViewModel.kt | 8 +-
.../streetpass/view/StreetPassRecordViewModel.kt | 4 +-
.../io/bluetrace/opentrace/view/CustomViewPager.kt | 6 +-
app/src/main/res/drawable/icon_checkbox.xml | 17 +-
.../main/res/drawable/selector_bottombar_text.xml | 4 +-
app/src/main/res/layout/activity_main_new.xml | 10 +-
app/src/main/res/layout/activity_onboarding.xml | 2 +-
app/src/main/res/layout/activity_splash.xml | 13 +-
app/src/main/res/layout/button_and_progress.xml | 76 ++--
app/src/main/res/layout/database_peek.xml | 4 +-
app/src/main/res/layout/fragment_home.xml | 424 +++----------------
app/src/main/res/layout/fragment_setup.xml | 296 +++++++++----
.../main/res/layout/fragment_upload_enterpin.xml | 448 +++++++++++++++-----
app/src/main/res/layout/fragment_upload_foruse.xml | 101 ++---
.../res/layout/fragment_upload_uploadcomplete.xml | 115 ++---
.../main/res/layout/main_activity_onboarding.xml | 239 ++++++++---
app/src/main/res/layout/recycler_view_item.xml | 28 +-
app/src/main/res/menu/bottom_nav_menu.xml | 9 +-
app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 5184 -> 8153 bytes
app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 3062 -> 6234 bytes
app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 7526 -> 10204 bytes
app/src/main/res/mipmap-xxhdpi/ic_launcher.png | Bin 11811 -> 14805 bytes
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 16596 -> 19424 bytes
app/src/main/res/values/colors.xml | 26 +-
app/src/main/res/values/strings.xml | 241 +++++++----
app/src/main/res/values/styles.xml | 25 +-
build.gradle | 10 +-
settings.gradle | 2 +-
89 files changed, 2986 insertions(+), 1893 deletions(-)
diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md
index df3dfd5..4164e8f 100644
--- a/ATTRIBUTION.md
+++ b/ATTRIBUTION.md
@@ -1,6 +1,11 @@
-## OpenTrace was built using the following:
+## Wiqaytna was built using the following:
-* Fonts - [Muli](https://fonts.google.com/specimen/Muli)
+* [Opentrace](https://github.com/opentrace-community/opentrace-android)
+ Licensed Under GPL3
+
+---
+
+* Fonts - Barlow and Almarai
Licensed under the [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL)
---
@@ -529,16 +534,24 @@
<dt>Copyright © 20xx The original author or authors</dt>
</dl>
+
+* [Calligraphy (3.1.1)](#1934118923)
-* [Collections Kotlin Extensions (1.1.0)](#1934118923)
+ <dl>
+
+ <dt>Copyright © 2013 Christopher Jenkins</dt>
+
+ </dl>
+
+* [Chrome Custom Tabs (28.0.0)](#1934118923)
<dl>
- <dt>Copyright © 2018 The Android Open Source Project</dt>
+ <dt>Copyright © 20xx Google</dt>
</dl>
-* [Core Kotlin Extensions (1.1.0)](#1934118923)
+* [Collections Kotlin Extensions (1.1.0)](#1934118923)
<dl>
@@ -546,11 +559,11 @@
</dl>
-* [CountryCodePicker (2.3.4)](#1934118923)
+* [Core Kotlin Extensions (1.1.0)](#1934118923)
<dl>
- <dt>Copyright © 20xx Harsh Bhakta</dt>
+ <dt>Copyright © 2018 The Android Open Source Project</dt>
</dl>
@@ -778,14 +791,6 @@
</dl>
-* [Lottie (3.4.0)](#1934118923)
-
- <dl>
-
- <dt>Copyright © 20xx Airbnb</dt>
-
- </dl>
-
* [Material Components for Android (1.2.0-alpha04)](#1934118923)
<dl>
@@ -901,6 +906,14 @@
<dt>Copyright © 2018 The Android Open Source Project</dt>
</dl>
+
+* [ViewPump (2.0.3)](#1934118923)
+
+ <dl>
+
+ <dt>Copyright © 2017 InflationX</dt>
+
+ </dl>
<a name="1934118923"></a>
diff --git a/README.md b/README.md
index 26036f1..5f03202 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,9 @@
-# OpenTrace Android app
-
-![alt text](./OpenTrace.png "OpenTrace Logo")
-
-OpenTrace is the open source reference implementation of BlueTrace.
-BlueTrace is a privacy-preserving protocol for community-driven contact tracing across borders. It allows participating devices to log Bluetooth encounters with each other, in order to facilitate epidemiological contact tracing while protecting users’ personal data and privacy. Visit https://bluetrace.io to learn more.
-The OpenTrace reference implementation comprises:
-- Android app: [opentrace-community/opentrace-android](https://github.com/opentrace-community/opentrace-android)
-- iOS app: [opentrace-community/opentrace-ios](https://github.com/opentrace-community/opentrace-ios)
-- Cloud functions: [opentrace-community/opentrace-cloud-functions](https://github.com/opentrace-community/opentrace-cloud-functions)
-- Calibration: [opentrace-community/opentrace-calibration](https://github.com/opentrace-community/opentrace-calibration)
-
-## Setup of the app
-To get started on the app, setup and configure the following:
-1. ./gradle.properties
-2. ./app/build.gradle
-3. Firebase - google-services.json
-4. Remote configs
-5. Protocol version
+# Wiqaytna Android
+
+![alt text](./app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
+ "Wiqaytna Logo")
+
+Wiqaytna is the official Moroccan exposure notification app.
---
@@ -24,16 +11,17 @@ To get started on the app, setup and configure the following:
Sample Configuration
```
-ORG="SG_OTC"
+ORG="MAR"
STORE_URL="<Play store URL>"
PRIVACY_URL="<Privacy policy URL>"
SERVICE_FOREGROUND_NOTIFICATION_ID=771579
-SERVICE_FOREGROUND_CHANNEL_ID="OpenTrace Updates"
-SERVICE_FOREGROUND_CHANNEL_NAME="OpenTrace Foreground Service"
+SERVICE_FOREGROUND_CHANNEL_ID="Wiqaytna Updates"
+SERVICE_FOREGROUND_CHANNEL_NAME="Wiqaytna Foreground Service"
PUSH_NOTIFICATION_ID=771578
-PUSH_NOTIFICATION_CHANNEL_NAME="OpenTrace Notifications"
+PUSH_NOTIFICATION_CHANNEL_NAME="Wiqaytna Notifications"
+ERROR_NOTIFICATION_ID=771580
#service configurations
SCAN_DURATION=8000
@@ -53,12 +41,12 @@ BLACKLIST_DURATION=100000
FIREBASE_REGION = "<Your Firebase region>"
-STAGING_FIREBASE_UPLOAD_BUCKET = "opentrace-app-staging"
+STAGING_FIREBASE_UPLOAD_BUCKET = "wiqayetna-app-staging"
STAGING_SERVICE_UUID = "17E033D3-490E-4BC9-9FE8-2F567643F4D3"
V2_CHARACTERISTIC_ID = "117BDD58-57CE-4E7A-8E87-7CCCDDA2A804"
-PRODUCTION_FIREBASE_UPLOAD_BUCKET = "opentrace-app"
+PRODUCTION_FIREBASE_UPLOAD_BUCKET = "wiqaytna-app"
PRODUCTION_SERVICE_UUID = "B82AB3FC-1595-4F6A-80F0-FE094CC218F9"
android.useAndroidX=true
@@ -82,7 +70,7 @@ buildTypes {
String ssid = STAGING_SERVICE_UUID
versionNameSuffix "-debug-${getGitHash()}-${ssid.substring(ssid.length() - 5,ssid.length() - 1 )}"
- resValue "string", "app_name", "OpenTrace Debug"
+ resValue "string", "app_name", "Wiqaytna"
applicationIdSuffix "stg"
}
```
@@ -129,18 +117,4 @@ For more information visit [https://android-developers.googleblog.com/2020/04/go
---
### Acknowledgements
-OpenTrace uses the following [third party libraries / tools](./ATTRIBUTION.md).
-
----
-
-### ChangeLog
-
-1.0.2
-* Fixed an issue in GattServer.kt where the cached readPayLoad is not cleared properly in some cases
-* Removed Firebase Analytics
-
-1.0.1
-* Updated readme.md to add in two more fields for setup
-
-1.0.0
-* First release of this repo
+Wiqaytna uses the following [third party libraries / tools](./ATTRIBUTION.md).
diff --git a/app/build.gradle b/app/build.gradle
index 733e12c..284cb3f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -3,9 +3,10 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'com.google.gms.google-services'
-apply plugin: 'io.fabric'
apply plugin: 'com.google.firebase.appdistribution'
apply plugin: "com.cookpad.android.plugin.license-tools"
+apply plugin: 'com.google.firebase.crashlytics'
+
apply plugin: 'com.jaredsburrows.license'
buildscript {
@@ -26,17 +27,17 @@ def getGitHash = { ->
}
return stdout.toString().trim()
}
-
+apply plugin: 'com.google.firebase.firebase-perf'
android {
- compileSdkVersion 29
- buildToolsVersion "29.0.2"
+ compileSdkVersion 28
+ buildToolsVersion "28.0.3"
defaultConfig {
- applicationId "io.bluetrace.opentrace"
- resValue "string", "build_config_package", "io.bluetrace.opentrace"
+ applicationId "covid.trace.morocco"
+ resValue "string", "build_config_package", "covid.trace.morocco"
minSdkVersion 22
- targetSdkVersion 29
- versionCode 41
- versionName "1.0.41"
+ targetSdkVersion 28
+ versionCode 70
+ versionName "1.0.70"
buildConfigField "String", "GITHASH", "\"${getGitHash()}\""
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -75,6 +76,7 @@ android {
buildConfigField "long", "ADVERTISING_INTERVAL", ADVERTISING_INTERVAL
buildConfigField "String", "V2_CHARACTERISTIC_ID", V2_CHARACTERISTIC_ID
+ buildConfigField "int", "ERROR_NOTIFICATION_ID", ERROR_NOTIFICATION_ID
}
@@ -85,7 +87,7 @@ android {
String ssid = STAGING_SERVICE_UUID
versionNameSuffix "-debug-${getGitHash()}-${ssid.substring(ssid.length() - 5, ssid.length() - 1)}"
- resValue "string", "app_name", "OpenTrace Debug"
+ resValue "string", "app_name", "Wiqaytna"
applicationIdSuffix "stg"
}
@@ -98,9 +100,10 @@ android {
jniDebuggable false
renderscriptDebuggable false
minifyEnabled false
+
multiDexEnabled false
zipAlignEnabled true
- resValue "string", "app_name", "OpenTrace"
+ resValue "string", "app_name", "Wiqaytna"
lintOptions {
// Ignore lint errors for now
@@ -118,6 +121,19 @@ android {
androidExtensions {
experimental = true
}
+
+ bundle {
+ language {
+ enableSplit = false
+ }
+ density {
+ enableSplit = true
+ }
+ abi {
+ enableSplit = true
+ }
+ }
+
}
@@ -129,19 +145,16 @@ dependencies {
implementation group: 'androidx.localbroadcastmanager', name: 'localbroadcastmanager', version: '1.0.0-alpha3'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'pub.devrel:easypermissions:3.0.0'
- implementation 'com.google.code.gson:gson:2.8.5'
- implementation 'com.google.firebase:firebase-config-ktx:19.1.2'
- implementation 'com.google.firebase:firebase-analytics:17.2.3'
- implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
+ implementation 'com.google.code.gson:gson:2.8.6'
+ implementation 'com.google.firebase:firebase-config-ktx:19.1.4'
implementation 'com.google.firebase:firebase-storage:19.1.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
- implementation 'com.hbb20:ccp:2.3.4'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
// Room components
- def room_version = "2.2.3"
+ def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
@@ -160,7 +173,7 @@ dependencies {
testImplementation "androidx.room:room-testing:$room_version"
implementation 'androidx.recyclerview:recyclerview:1.1.0'
- implementation "com.google.android.material:material:1.2.0-alpha04"
+ implementation "com.google.android.material:material:1.2.0-alpha06"
def archLifecycleVersion = "2.2.0"
// Lifecycle components
@@ -173,20 +186,31 @@ dependencies {
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.17'
- implementation 'com.google.firebase:firebase-analytics:17.2.2'
- implementation 'com.google.firebase:firebase-auth:19.2.0'
+ implementation 'com.google.firebase:firebase-auth:19.3.1'
implementation 'com.google.firebase:firebase-functions:19.0.2'
- implementation 'com.google.firebase:firebase-messaging:20.1.2'
+ implementation 'com.google.firebase:firebase-messaging:20.1.6'
+ // Add the dependency for the Performance Monitoring library
+ implementation 'com.google.firebase:firebase-perf:19.0.7'
//bottom navigation
- implementation 'androidx.navigation:navigation-fragment-ktx:2.2.1'
- implementation 'androidx.navigation:navigation-ui-ktx:2.2.1'
+ implementation 'androidx.navigation:navigation-fragment-ktx:2.2.2'
+ implementation 'androidx.navigation:navigation-ui-ktx:2.2.2'
//cardview
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.guava:guava:28.2-android'
- //Lottie
- implementation 'com.airbnb.android:lottie:3.4.0'
+ //calligraphy
+ implementation 'io.github.inflationx:calligraphy3:3.1.1'
+ implementation 'io.github.inflationx:viewpump:2.0.3'
+
+ // Recommended: Add the Firebase SDK for Google Analytics.
+ implementation 'com.google.firebase:firebase-analytics:17.4.0'
+
+ // Add the Firebase Crashlytics SDK.
+ implementation 'com.google.firebase:firebase-crashlytics:17.0.0'
+ //chrome custom tab
+ implementation 'com.android.support:customtabs:28.0.0'
+
}
diff --git a/app/src/debug/AndroidManifest.xml b/app/src/debug/AndroidManifest.xml
index 3b0d307..b024b77 100644
--- a/app/src/debug/AndroidManifest.xml
+++ b/app/src/debug/AndroidManifest.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="io.bluetrace.opentrace">
+ package="covid.trace.morocco">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 41f7680..946e43d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,31 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="io.bluetrace.opentrace">
+ package="covid.trace.morocco">
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true" />
+ <!--
+ These three permissions are needed for Bluetooth low energy communication, the ACCESS_FINE_LOCATION
+ doesn't give any access to the user's GPS location.
+
+ For more information see:
+ https://developer.android.com/guide/topics/connectivity/bluetooth-le
+
+ -->
+
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
-
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-
+
+ <!--
+ Used by the Boot receiver, we use it to get notified when the phone complets a boot operation,
+ so we can start the Bluetooth monitoring service
+ -->
+
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+
+ <!--
+ Allows a regular application to use Service.startForeground
+ -->
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
-
+
+ <!--
+ Permission an application must hold in order to use Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS.
+ We use it to deactivate Android's battery optimization for the app, so it will continue to work in the background
+ without any issues
+ -->
+
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<application
- android:name=".TracerApp"
+ android:name=".WiqaytnaApp"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
- android:theme="@style/AppTheme.NoActionBar">
-
- <meta-data android:name="firebase_analytics_collection_deactivated" android:value="true" />
+ android:theme="@style/AppTheme.NoActionBar"
+ android:usesCleartextTraffic="true">
+ <activity android:name=".onboarding.TouActivity"></activity>
+
+ <meta-data
+ android:name="firebase_performance_logcat_enabled"
+ android:value="true" />
<provider
android:name="androidx.core.content.FileProvider"
@@ -43,23 +71,19 @@
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
+
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
-
<activity
- android:name=".onboarding.OnboardingActivity"
+ android:name=".onboarding.PersonalInfosActivity"
android:screenOrientation="portrait" />
<activity
- android:name=".onboarding.HowItWorksActivity"
+ android:name=".onboarding.OnboardingActivity"
android:screenOrientation="portrait" />
<activity
android:name=".onboarding.PreOnboardingActivity"
android:screenOrientation="portrait" />
-
- <activity
- android:name=".onboarding.WebViewActivity"
- android:screenOrientation="portrait" />
<activity
android:name=".MainActivity"
android:screenOrientation="portrait" />
@@ -78,14 +102,17 @@
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
-
- <!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
- See README(https://goo.gl/l4GJaQ) for more. -->
+ <!--
+ Set custom default icon. This is used when no icon is set for incoming notification messages.
+ See README(https://goo.gl/l4GJaQ) for more.
+ -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_notification_service" />
- <!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
- notification message. See README(https://goo.gl/6BKBk7) for more. -->
+ <!--
+ Set color used with incoming notification messages. This is used when no color is set for the incoming
+ notification message. See README(https://goo.gl/6BKBk7) for more.
+ -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/notification_tint" />
@@ -95,15 +122,12 @@
android:launchMode="singleTask"
android:theme="@style/Theme.AppCompat.Transparent.NoActionBar" />
- <service
- android:name=".services.BluetoothMonitoringService"
- android:foregroundServiceType="location" />
+ <service android:name=".services.BluetoothMonitoringService" />
<activity
android:name=".PeekActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.DebugNoActionBar" />
-
<activity
android:name=".PlotActivity"
android:screenOrientation="landscape"
@@ -114,7 +138,6 @@
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
-
</application>
</manifest>
diff --git a/app/src/main/java/io/bluetrace/opentrace/MainActivity.kt b/app/src/main/java/io/bluetrace/opentrace/MainActivity.kt
index 102d63a..2e35cb0 100644
--- a/app/src/main/java/io/bluetrace/opentrace/MainActivity.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/MainActivity.kt
@@ -1,22 +1,26 @@
-package io.bluetrace.opentrace
+package covid.trace.morocco
-import android.app.ActivityManager
-import android.content.Context
import android.os.Bundle
-import android.widget.Toast
-import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
+import com.google.android.gms.tasks.Task
import com.google.android.material.bottomnavigation.BottomNavigationView
+import com.google.firebase.crashlytics.FirebaseCrashlytics
+import com.google.firebase.functions.FirebaseFunctions
+import com.google.firebase.functions.HttpsCallableResult
import com.google.firebase.iid.FirebaseInstanceId
+import covid.trace.morocco.base.BaseFragmentActivity
+import covid.trace.morocco.fragment.AdvicesFragment
+import covid.trace.morocco.fragment.ForUseFragment
+import covid.trace.morocco.fragment.HomeFragment
+import covid.trace.morocco.fragment.StatisticsFragment
+import covid.trace.morocco.logging.CentralLog
import kotlinx.android.synthetic.main.activity_main_new.*
-import io.bluetrace.opentrace.fragment.ForUseByOTCFragment
-import io.bluetrace.opentrace.fragment.HomeFragment
-import io.bluetrace.opentrace.logging.CentralLog
-class MainActivity : AppCompatActivity() {
+class MainActivity : BaseFragmentActivity() {
private val TAG = "MainActivity"
+ private var crashlytics = FirebaseCrashlytics.getInstance()
// navigation
private var mNavigationLevel = 0
@@ -38,25 +42,49 @@ class MainActivity : AppCompatActivity() {
if (selected != R.id.navigation_home) {
openFragment(
LAYOUT_MAIN_ID, HomeFragment(),
- HomeFragment::class.java.name, 0
+ HomeFragment::class.java.name
)
}
selected = R.id.navigation_home
return@OnNavigationItemSelectedListener true
}
+
+
+ R.id.navigation_news -> {
+
+ if (selected != R.id.navigation_news) {
+ openFragment(
+ LAYOUT_MAIN_ID, StatisticsFragment(),
+ StatisticsFragment::class.java.name
+ )
+ }
+ selected = R.id.navigation_news
+ return@OnNavigationItemSelectedListener true
+ }
+
+
R.id.navigation_upload -> {
+
if (selected != R.id.navigation_upload) {
openFragment(
- LAYOUT_MAIN_ID, ForUseByOTCFragment(),
- ForUseByOTCFragment::class.java.name, 0
+ LAYOUT_MAIN_ID, ForUseFragment(),
+ ForUseFragment::class.java.name
)
}
selected = R.id.navigation_upload
return@OnNavigationItemSelectedListener true
}
+
R.id.navigation_help -> {
- Toast.makeText(this, "To be implemented", Toast.LENGTH_LONG).show()
+ if (selected != R.id.navigation_help) {
+ openFragment(
+ LAYOUT_MAIN_ID, AdvicesFragment(),
+ AdvicesFragment::class.java.name
+ )
+ }
+ selected = R.id.navigation_help
+ return@OnNavigationItemSelectedListener true
}
}
false
@@ -66,12 +94,25 @@ class MainActivity : AppCompatActivity() {
goToHome()
getFCMToken()
+
+ if (!PreferencesHelper.getBooleanPreference(PreferencesHelper.INFOS_UPDATE, false)) {
+ setUser(PreferencesHelper.getCurrentLanguage())
+ .addOnSuccessListener {
+ CentralLog.d("language upadte", "updated")
+ PreferencesHelper.setPreference(PreferencesHelper.INFOS_UPDATE, true)
+ }.addOnFailureListener { exception ->
+ crashlytics.recordException(exception)
+ crashlytics.setCustomKey("error", "couldn't send choosen language info")
+ CentralLog.d("language upadte", "not updated")
+ PreferencesHelper.setPreference(PreferencesHelper.INFOS_UPDATE, false)
+ }
+ }
}
private fun getFCMToken() {
FirebaseInstanceId.getInstance().instanceId
.addOnCompleteListener { task ->
- if (!task.isSuccessful()) {
+ if (!task.isSuccessful) {
CentralLog.w(TAG, "failed to get fcm token ${task.exception}")
return@addOnCompleteListener
} else {
@@ -85,16 +126,6 @@ class MainActivity : AppCompatActivity() {
}
- private fun isMyServiceRunning(serviceClass: Class<*>): Boolean {
- val manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
- for (service in manager.getRunningServices(Integer.MAX_VALUE)) {
- if (serviceClass.name == service.service.className) {
- return true
- }
- }
- return false
- }
-
fun goToHome() {
nav_view.selectedItemId = R.id.navigation_home
}
@@ -102,8 +133,7 @@ class MainActivity : AppCompatActivity() {
fun openFragment(
containerViewId: Int,
fragment: Fragment,
- tag: String,
- title: Int
+ tag: String
) {
try { // pop all fragments
supportFragmentManager.popBackStackImmediate(
@@ -119,4 +149,13 @@ class MainActivity : AppCompatActivity() {
e.printStackTrace()
}
}
+
+ private fun setUser(lang: String): Task<HttpsCallableResult> {
+ // Create the arguments to the callable function.
+ val data = hashMapOf("lang" to lang)
+ val functions = FirebaseFunctions.getInstance(BuildConfig.FIREBASE_REGION)
+ return functions
+ .getHttpsCallable("updateUser")
+ .call(data)
+ }
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/PeekActivity.kt b/app/src/main/java/io/bluetrace/opentrace/PeekActivity.kt
index a96a1c5..b1f3cc6 100644
--- a/app/src/main/java/io/bluetrace/opentrace/PeekActivity.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/PeekActivity.kt
@@ -1,25 +1,25 @@
-package io.bluetrace.opentrace
+package covid.trace.morocco
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
-import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.firebase.auth.FirebaseAuth
+import covid.trace.morocco.base.BaseActivity
+import covid.trace.morocco.streetpass.persistence.StreetPassRecordStorage
+import covid.trace.morocco.streetpass.view.RecordViewModel
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.database_peek.*
-import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecordStorage
-import io.bluetrace.opentrace.streetpass.view.RecordViewModel
-class PeekActivity : AppCompatActivity() {
+class PeekActivity : BaseActivity() {
private lateinit var viewModel: RecordViewModel
@@ -75,11 +75,11 @@ class PeekActivity : AppCompatActivity() {
.setTitle("Are you sure?")
.setCancelable(false)
.setMessage("Deleting the DB records is irreversible")
- .setPositiveButton("DELETE") { dialog, which ->
+ .setPositiveButton("DELETE") { dialog, _ ->
Observable.create<Boolean> {
- StreetPassRecordStorage(this).nukeDb()
- it.onNext(true)
- }
+ StreetPassRecordStorage(this).nukeDb()
+ it.onNext(true)
+ }
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe { result ->
@@ -90,17 +90,16 @@ class PeekActivity : AppCompatActivity() {
}
}
- .setNegativeButton("DON'T DELETE") { dialog, which ->
+ .setNegativeButton("DON'T DELETE") { dialog, _ ->
view.isEnabled = true
dialog.cancel()
}
val dialog: AlertDialog = builder.create()
dialog.show()
-
}
- plot.setOnClickListener { view ->
+ plot.setOnClickListener {
val intent = Intent(this, PlotActivity::class.java)
intent.putExtra("time_period", nextTimePeriod())
startActivity(intent)
diff --git a/app/src/main/java/io/bluetrace/opentrace/PlotActivity.kt b/app/src/main/java/io/bluetrace/opentrace/PlotActivity.kt
index d48f2c0..549305b 100644
--- a/app/src/main/java/io/bluetrace/opentrace/PlotActivity.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/PlotActivity.kt
@@ -1,26 +1,26 @@
-package io.bluetrace.opentrace
+package covid.trace.morocco
import android.os.Build
import android.os.Bundle
-import android.util.Log
import android.webkit.WebViewClient
import androidx.annotation.RequiresApi
-import androidx.appcompat.app.AppCompatActivity
+import covid.trace.morocco.base.BaseActivity
+import covid.trace.morocco.logging.CentralLog
+import covid.trace.morocco.models.ExportData
+import covid.trace.morocco.status.persistence.StatusRecord
+import covid.trace.morocco.status.persistence.StatusRecordStorage
+import covid.trace.morocco.streetpass.persistence.StreetPassRecord
+import covid.trace.morocco.streetpass.persistence.StreetPassRecordStorage
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.BiFunction
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_plot.*
-import io.bluetrace.opentrace.fragment.ExportData
-import io.bluetrace.opentrace.status.persistence.StatusRecord
-import io.bluetrace.opentrace.status.persistence.StatusRecordStorage
-import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecord
-import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecordStorage
import java.text.SimpleDateFormat
import java.util.*
import kotlin.Comparator
-class PlotActivity : AppCompatActivity() {
+class PlotActivity : BaseActivity() {
private var TAG = "PlotActivity"
@RequiresApi(Build.VERSION_CODES.O)
@@ -34,18 +34,23 @@ class PlotActivity : AppCompatActivity() {
val displayTimePeriod = intent.getIntExtra("time_period", 1) // in hours
- var observableStreetRecords = Observable.create<List<StreetPassRecord>> {
+ val observableStreetRecords = Observable.create<List<StreetPassRecord>> {
val result = StreetPassRecordStorage(this).getAllRecords()
it.onNext(result)
}
- var observableStatusRecords = Observable.create<List<StatusRecord>> {
+ val observableStatusRecords = Observable.create<List<StatusRecord>> {
val result = StatusRecordStorage(this).getAllRecords()
it.onNext(result)
}
val zipResult = Observable.zip(observableStreetRecords, observableStatusRecords,
- BiFunction<List<StreetPassRecord>, List<StatusRecord>, ExportData> { records, status -> ExportData(records, status) }
- )
+ BiFunction<List<StreetPassRecord>, List<StatusRecord>, ExportData> { records, status ->
+ ExportData(
+ records,
+ status
+ )
+ }
+ )
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe { exportedData ->
@@ -54,7 +59,7 @@ class PlotActivity : AppCompatActivity() {
return@subscribe
}
- val dateFormatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
+ val dateFormatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.FRANCE)
// Use the date of the last record as the end time (Epoch time in seconds)
val endTime =
@@ -66,7 +71,7 @@ class PlotActivity : AppCompatActivity() {
val startTimeString = dateFormatter.format(Date(startTime * 1000))
val filteredRecords = exportedData.recordList.filter {
- it.timestamp / 1000 >= startTime && it.timestamp / 1000 <= endTime
+ it.timestamp / 1000 in startTime..endTime
}
if (filteredRecords.isNotEmpty()) {
@@ -75,7 +80,7 @@ class PlotActivity : AppCompatActivity() {
// get all models
val allModelList = dataByModelC.keys union dataByModelP.keys.toList()
- Log.d(TAG, "allModels: ${allModelList}")
+ CentralLog.d(TAG, "allModels: ${allModelList}")
// sort the list by the models that appear the most frequently
val sortedModelList =
@@ -256,10 +261,10 @@ class PlotActivity : AppCompatActivity() {
<body>
<div id='myDiv'></div>
<script>
- ${individualData}
+ $individualData
var data = [];
- ${combinedData}
+ $combinedData
var layout = {
title: 'Activities from <b>${startTimeString.substring(11..15)}</b> to <b>${endTimeString.substring(
@@ -275,8 +280,8 @@ class PlotActivity : AppCompatActivity() {
l: 50,
pad: 0
},
- ${xAxis},
- ${yAxis}
+ $xAxis,
+ $yAxis
};
var config = {
@@ -291,17 +296,17 @@ class PlotActivity : AppCompatActivity() {
</body>
""".trimIndent()
- Log.d(TAG, "customHtml: ${customHtml}")
+ CentralLog.d(TAG, "customHtml: $customHtml")
webView.loadData(customHtml, "text/html", "UTF-8")
} else {
webView.loadData(
- "No data received in the last ${displayTimePeriod} hour(s) or more.",
+ "No data received in the last $displayTimePeriod hour(s) or more.",
"text/html",
"UTF-8"
)
}
}
- Log.d(TAG, "zipResult: ${zipResult}")
+ CentralLog.d(TAG, "zipResult: $zipResult")
webView.loadData("Loading...", "text/html", "UTF-8")
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/Preference.kt b/app/src/main/java/io/bluetrace/opentrace/Preference.kt
index 5eca88e..f5b72bc 100644
--- a/app/src/main/java/io/bluetrace/opentrace/Preference.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/Preference.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace
+package covid.trace.morocco
import android.content.Context
import android.content.SharedPreferences
@@ -23,11 +23,6 @@ object Preference {
.edit().putString(HANDSHAKE_PIN, value).apply()
}
- fun getHandShakePin(context: Context): String {
- return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE)
- .getString(HANDSHAKE_PIN, "AERTVC") ?: "AERTVC"
- }
-
fun putIsOnBoarded(context: Context, value: Boolean) {
context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE)
.edit().putBoolean(IS_ONBOARDED, value).apply()
@@ -43,11 +38,6 @@ object Preference {
.edit().putString(PHONE_NUMBER, value).apply()
}
- fun getPhoneNumber(context: Context): String {
- return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE)
- .getString(PHONE_NUMBER, "") ?: ""
- }
-
fun putCheckpoint(context: Context, value: Int) {
context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE)
.edit().putInt(CHECK_POINT, value).apply()
@@ -58,18 +48,18 @@ object Preference {
.getInt(CHECK_POINT, 0)
}
- fun getLastFetchTimeInMillis(context: Context): Long {
- return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE)
- .getLong(
- LAST_FETCH_TIME, 0
- )
- }
-
fun putLastFetchTimeInMillis(context: Context, time: Long) {
context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE)
.edit().putLong(LAST_FETCH_TIME, time).apply()
}
+ fun getLastFetchTimeInMillis(context: Context): Long {
+ return context.getSharedPreferences(Preference.PREF_ID, Context.MODE_PRIVATE)
+ .getLong(
+ Preference.LAST_FETCH_TIME, 0
+ )
+ }
+
fun putNextFetchTimeInMillis(context: Context, time: Long) {
context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE)
.edit().putLong(NEXT_FETCH_TIME, time).apply()
diff --git a/app/src/main/java/io/bluetrace/opentrace/RecordListAdapter.kt b/app/src/main/java/io/bluetrace/opentrace/RecordListAdapter.kt
index ef017f9..9b1b4f8 100644
--- a/app/src/main/java/io/bluetrace/opentrace/RecordListAdapter.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/RecordListAdapter.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace
+package covid.trace.morocco
import android.content.Context
import android.view.LayoutInflater
@@ -6,9 +6,9 @@ import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
+import covid.trace.morocco.streetpass.persistence.StreetPassRecord
+import covid.trace.morocco.streetpass.view.StreetPassRecordViewModel
import kotlinx.android.synthetic.main.recycler_view_item.view.*
-import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecord
-import io.bluetrace.opentrace.streetpass.view.StreetPassRecordViewModel
class RecordListAdapter internal constructor(context: Context) :
@@ -37,18 +37,22 @@ class RecordListAdapter internal constructor(context: Context) :
val org: TextView = itemView.org
}
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecordViewHolder {
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): RecordListAdapter.RecordViewHolder {
val itemView = inflater.inflate(R.layout.recycler_view_item, parent, false)
return RecordViewHolder(itemView)
}
- override fun onBindViewHolder(holder: RecordViewHolder, position: Int) {
+ override fun onBindViewHolder(holder: RecordListAdapter.RecordViewHolder, position: Int) {
val current = records[position]
holder.msgView.text = current.msg
holder.modelCView.text = current.modelC
holder.modelPView.text = current.modelP
holder.findsView.text = "Detections: ${current.number}"
- val readableDate = Utils.getDate(current.timeStamp)
+ val readableDate =
+ Utils.getDate(current.timeStamp)
holder.timestampView.text = readableDate
holder.version.text = "v: ${current.version}"
holder.org.text = "ORG: ${current.org}"
diff --git a/app/src/main/java/io/bluetrace/opentrace/SplashActivity.kt b/app/src/main/java/io/bluetrace/opentrace/SplashActivity.kt
index 17c170c..4031919 100644
--- a/app/src/main/java/io/bluetrace/opentrace/SplashActivity.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/SplashActivity.kt
@@ -1,24 +1,35 @@
-package io.bluetrace.opentrace
+package covid.trace.morocco
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.Handler
-import androidx.appcompat.app.AppCompatActivity
-import io.bluetrace.opentrace.onboarding.PreOnboardingActivity
+import android.text.TextUtils
+import com.google.android.gms.security.ProviderInstaller
+import com.google.firebase.crashlytics.FirebaseCrashlytics
+import com.google.firebase.functions.FirebaseFunctions
+import com.google.firebase.iid.FirebaseInstanceId
+import com.google.gson.Gson
+import covid.trace.morocco.WiqaytnaApp.Companion.firebaseToken
+import covid.trace.morocco.base.BaseActivity
+import covid.trace.morocco.logging.CentralLog
+import covid.trace.morocco.models.StatisticsResponse
+import covid.trace.morocco.onboarding.PreOnboardingActivity
-class SplashActivity : AppCompatActivity() {
-
- private val SPLASH_TIME: Long = 2000
- var needToUpdateApp = false
+class SplashActivity : BaseActivity(), ProviderInstaller.ProviderInstallListener {
+ private val SPLASH_TIME: Long = 4000
+ private var needToUpdateApp = false
+ private val TAG = "SpalshActivity"
private lateinit var mHandler: Handler
+ private var crashlytics = FirebaseCrashlytics.getInstance()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
mHandler = Handler()
-
+ getFCMToken()
+ ProviderInstaller.installIfNeededAsync(this, this)
//check if the intent was from notification and its a update notification
intent.extras?.let {
val notifEvent: String? = it.getString("event", null)
@@ -26,7 +37,7 @@ class SplashActivity : AppCompatActivity() {
notifEvent?.let {
if (it.equals("update")) {
needToUpdateApp = true
- intent = Intent(Intent.ACTION_VIEW);
+ intent = Intent(Intent.ACTION_VIEW)
//Copy App URL from Google Play Store.
intent.data = Uri.parse(BuildConfig.STORE_URL)
@@ -35,6 +46,27 @@ class SplashActivity : AppCompatActivity() {
}
}
}
+
+ if (TextUtils.isEmpty(
+ PreferencesHelper.getStringPreference(
+ PreferencesHelper.STATS_UPDATE, ""
+ )
+ )
+ ) {
+ getStatistics()
+ } else {
+ val json = PreferencesHelper.getStringPreference(PreferencesHelper.STATS_UPDATE, "")
+ val response = Gson().fromJson(json, StatisticsResponse::class.java)
+ val currentTimeInSeconds = System.currentTimeMillis() / 1000
+ val diff = currentTimeInSeconds - response.data.date._seconds
+ val hoursElapsed = diff / 3600
+ CentralLog.d("response hours elapsed", hoursElapsed.toString())
+ if (hoursElapsed > 2) {
+ getStatistics()
+ } else {
+ WiqaytnaApp.statisticsData = response
+ }
+ }
}
override fun onPause() {
@@ -46,8 +78,13 @@ class SplashActivity : AppCompatActivity() {
super.onResume()
if (!needToUpdateApp) {
mHandler.postDelayed({
- goToNextScreen()
- finish()
+ if (!Utils.isEmulator()) {
+ goToNextScreen()
+ finish()
+ } else {
+ finish()
+ }
+
}, SPLASH_TIME)
}
}
@@ -59,4 +96,50 @@ class SplashActivity : AppCompatActivity() {
startActivity(Intent(this, MainActivity::class.java))
}
}
+
+ private fun getFCMToken() {
+ FirebaseInstanceId.getInstance().instanceId
+ .addOnCompleteListener { task ->
+ if (!task.isSuccessful) {
+ CentralLog.w(TAG, "failed to get fcm token ${task.exception}")
+ return@addOnCompleteListener
+ } else {
+ // Get new Instance ID token
+ val token = task.result?.token
+ firebaseToken = token.toString()
+ // Log and toast
+ CentralLog.d(TAG, "FCM token: $token")
+ }
+ }
+ }
+
+ private fun getStatistics() {
+ FirebaseFunctions.getInstance(BuildConfig.FIREBASE_REGION)
+ .getHttpsCallable("stats")
+ .call()
+ .continueWith { task ->
+ if (task.isSuccessful) {
+ CentralLog.d("response", "${task.result!!.data}")
+ val json: String = Gson().toJson(task.result!!.data)
+ PreferencesHelper.setPreference(PreferencesHelper.STATS_UPDATE, json)
+ val response = Gson().fromJson(json, StatisticsResponse::class.java)
+ WiqaytnaApp.statisticsData = response
+ } else {
+ if (task.exception != null) {
+ crashlytics.recordException(task.exception!!)
+ }
+ crashlytics.setCustomKey("error", "couldn't get the latest stats")
+ CentralLog.d("response", task.exception.toString())
+ }
+ }
+ }
+
+ override fun onProviderInstallFailed(p0: Int, p1: Intent?) {
+ CentralLog.d(TAG, "provider update failed")
+ }
+
+ override fun onProviderInstalled() {
+ CentralLog.d(TAG, "provider update suceeded")
+ }
+
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/Utils.kt b/app/src/main/java/io/bluetrace/opentrace/Utils.kt
index cbd7fe7..9dd4610 100644
--- a/app/src/main/java/io/bluetrace/opentrace/Utils.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/Utils.kt
@@ -1,44 +1,52 @@
-package io.bluetrace.opentrace
+package covid.trace.morocco
import android.Manifest
import android.app.Activity
+import android.app.AlertDialog
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
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.provider.Settings
+import android.view.LayoutInflater
import android.view.View
import android.view.inputmethod.InputMethodManager
+import android.widget.EditText
import androidx.localbroadcastmanager.content.LocalBroadcastManager
-import com.google.android.gms.tasks.Task
-import com.google.firebase.functions.FirebaseFunctions
-import com.google.firebase.functions.HttpsCallableResult
-import io.bluetrace.opentrace.bluetooth.gatt.*
-import io.bluetrace.opentrace.logging.CentralLog
-import io.bluetrace.opentrace.scheduler.Scheduler
-import io.bluetrace.opentrace.services.BluetoothMonitoringService
-import io.bluetrace.opentrace.services.BluetoothMonitoringService.Companion.PENDING_ADVERTISE_REQ_CODE
-import io.bluetrace.opentrace.services.BluetoothMonitoringService.Companion.PENDING_BM_UPDATE
-import io.bluetrace.opentrace.services.BluetoothMonitoringService.Companion.PENDING_HEALTH_CHECK_CODE
-import io.bluetrace.opentrace.services.BluetoothMonitoringService.Companion.PENDING_PURGE_CODE
-import io.bluetrace.opentrace.services.BluetoothMonitoringService.Companion.PENDING_SCAN_REQ_CODE
-import io.bluetrace.opentrace.services.BluetoothMonitoringService.Companion.PENDING_START
-import io.bluetrace.opentrace.status.Status
-import io.bluetrace.opentrace.streetpass.ACTION_DEVICE_SCANNED
-import io.bluetrace.opentrace.streetpass.ConnectablePeripheral
-import io.bluetrace.opentrace.streetpass.ConnectionRecord
-import java.io.BufferedReader
-import java.io.FileInputStream
+import com.google.firebase.analytics.FirebaseAnalytics
+import covid.trace.morocco.bluetooth.gatt.*
+import covid.trace.morocco.logging.CentralLog
+import covid.trace.morocco.scheduler.Scheduler
+import covid.trace.morocco.services.BluetoothMonitoringService
+import covid.trace.morocco.services.BluetoothMonitoringService.Companion.PENDING_ADVERTISE_REQ_CODE
+import covid.trace.morocco.services.BluetoothMonitoringService.Companion.PENDING_BM_UPDATE
+import covid.trace.morocco.services.BluetoothMonitoringService.Companion.PENDING_HEALTH_CHECK_CODE
+import covid.trace.morocco.services.BluetoothMonitoringService.Companion.PENDING_PURGE_CODE
+import covid.trace.morocco.services.BluetoothMonitoringService.Companion.PENDING_SCAN_REQ_CODE
+import covid.trace.morocco.services.BluetoothMonitoringService.Companion.PENDING_START
+import covid.trace.morocco.status.Status
+import covid.trace.morocco.streetpass.ACTION_DEVICE_SCANNED
+import covid.trace.morocco.streetpass.ConnectablePeripheral
+import covid.trace.morocco.streetpass.ConnectionRecord
+import kotlinx.android.synthetic.main.layout_dialog.view.*
+import java.io.IOException
import java.io.InputStreamReader
+import java.lang.StringBuilder
import java.text.SimpleDateFormat
import java.util.*
+
object Utils {
private const val TAG = "Utils"
+ const val faqArURL = "https://www.wiqaytna.ma/Default.aspx#nav-wiqaytna"
+ const val faqFrURL = "https://www.wiqaytna.ma/Default_Fr.aspx#nav-wiqaytna"
+
fun getRequiredPermissions(): Array<String> {
return arrayOf(Manifest.permission.ACCESS_FINE_LOCATION)
}
@@ -143,25 +151,6 @@ object Utils {
context.stopService(intent)
}
- fun scheduleNextScan(context: Context, timeInMillis: Long) {
-
- //cancels any outstanding scan schedules.
- cancelNextScan(context)
-
- val nextIntent = Intent(context, BluetoothMonitoringService::class.java)
- nextIntent.putExtra(
- BluetoothMonitoringService.COMMAND_KEY,
- BluetoothMonitoringService.Command.ACTION_SCAN.index
- )
- //runs every XXX milliseconds
- Scheduler.scheduleServiceIntent(
- PENDING_SCAN_REQ_CODE,
- context,
- nextIntent,
- timeInMillis
- )
- }
-
fun cancelNextScan(context: Context) {
val nextIntent = Intent(context, BluetoothMonitoringService::class.java)
nextIntent.putExtra(
@@ -171,25 +160,6 @@ object Utils {
Scheduler.cancelServiceIntent(PENDING_SCAN_REQ_CODE, context, nextIntent)
}
- fun scheduleNextAdvertise(context: Context, timeToNextAdvertise: Long) {
-
- //cancels any outstanding scan schedules.
- cancelNextAdvertise(context)
-
- val nextIntent = Intent(context, BluetoothMonitoringService::class.java)
- nextIntent.putExtra(
- BluetoothMonitoringService.COMMAND_KEY,
- BluetoothMonitoringService.Command.ACTION_ADVERTISE.index
- )
- //runs every XXX milliseconds
- Scheduler.scheduleServiceIntent(
- PENDING_ADVERTISE_REQ_CODE,
- context,
- nextIntent,
- timeToNextAdvertise
- )
- }
-
fun cancelNextAdvertise(context: Context) {
val nextIntent = Intent(context, BluetoothMonitoringService::class.java)
nextIntent.putExtra(
@@ -217,7 +187,7 @@ object Utils {
)
}
- fun cancelNextHealthCheck(context: Context) {
+ private fun cancelNextHealthCheck(context: Context) {
val nextIntent = Intent(context, BluetoothMonitoringService::class.java)
nextIntent.putExtra(
BluetoothMonitoringService.COMMAND_KEY,
@@ -271,34 +241,6 @@ object Utils {
LocalBroadcastManager.getInstance(context).sendBroadcast(intent)
}
- fun broadcastDeviceDisconnected(context: Context, device: BluetoothDevice) {
- val intent = Intent(ACTION_GATT_DISCONNECTED)
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device)
- LocalBroadcastManager.getInstance(context).sendBroadcast(intent)
- }
-
- fun readFromInternalStorage(context: Context, fileName: String): String {
- CentralLog.d(TAG, "Reading from internal storage")
- val fileInputStream: FileInputStream
- var text: String? = null
- val stringBuilder: StringBuilder = StringBuilder()
- fileInputStream = context.openFileInput(fileName)
- var inputStreamReader: InputStreamReader = InputStreamReader(fileInputStream)
- val bufferedReader: BufferedReader = BufferedReader(inputStreamReader)
- try {
- while ({ text = bufferedReader.readLine(); text }() != null) {
- CentralLog.d(TAG, "Text: " + text)
- stringBuilder.append(text)
- }
-
- bufferedReader.close()
-
- } catch (e: Throwable) {
- CentralLog.e(TAG, "Failed to readFromInternalStorage: ${e.message}")
- }
- return stringBuilder.toString()
- }
-
fun getDateFromUnix(unix_timestamp: Long): String? {
val sdf = SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.ENGLISH)
val date = sdf.format(unix_timestamp)
@@ -315,36 +257,135 @@ object Utils {
imm.hideSoftInputFromWindow(view.windowToken, 0)
}
- fun showKeyboardFrom(
- context: Context,
- view: View?
- ) {
- val imm = context.getSystemService(
- Activity.INPUT_METHOD_SERVICE
- ) as InputMethodManager
- imm.showSoftInput(view, InputMethodManager.SHOW_FORCED)
- }
-
fun isBluetoothAvailable(): Boolean {
val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
return bluetoothAdapter != null &&
bluetoothAdapter.isEnabled && bluetoothAdapter.state == BluetoothAdapter.STATE_ON
}
- fun getHandShakePin(
- context: Context,
- functions: FirebaseFunctions
- ): Task<HttpsCallableResult> {
- return functions
- .getHttpsCallable("getHandshakePin")
- .call()
- .addOnSuccessListener {
- val result: HashMap<String, Any> = it.data as HashMap<String, Any>
- val handShakePin = result["pin"].toString()
- Preference.putHandShakePin(context, handShakePin)
- CentralLog.d(TAG, "Result from handshake pin: " + result.toString())
- }.addOnFailureListener { e ->
- CentralLog.w(TAG, "get handshake pin (failure): ${e.message}")
+ fun spinnerAsAnEditText(
+ title: String?,
+ items: Array<String?>,
+ editText: EditText,
+ context: Context?
+ ) {
+
+ if (items == null || editText == null || context == null) {
+ CentralLog.d("Spinner", "Something is null")
+ return
+ }
+
+ val dialog = AlertDialog.Builder(context)
+ dialog.setTitle(title)
+ dialog.setItems(items) { _, which ->
+ editText.setText(items[which])
+ }
+ dialog.create().show()
+ }
+
+ fun spinnerAsAnEditText(
+ title: String?,
+ items: Array<String?>,
+ editText: EditText,
+ context: Context?,
+ selected: OnRegionSelected
+ ) {
+
+ if (items == null || editText == null || context == null) {
+ CentralLog.d("Spinner", "Something is null")
+ return
+ }
+
+ val dialog = AlertDialog.Builder(context)
+ dialog.setTitle(title)
+ dialog.setItems(items) { _, which ->
+ editText.setText(items[which])
+ selected.runWhenItemSelected(items[which])
+ }
+ dialog.create().show()
+ }
+
+ fun isEmulator(): Boolean {
+ return (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")
+ || Build.FINGERPRINT.startsWith("generic")
+ || Build.FINGERPRINT.startsWith("unknown")
+ || Build.HARDWARE.contains("goldfish")
+ || Build.HARDWARE.contains("ranchu")
+ || Build.MODEL.contains("google_sdk")
+ || Build.MODEL.contains("Emulator")
+ || Build.MODEL.contains("Android SDK built for x86")
+ || Build.MANUFACTURER.contains("Genymotion")
+ || Build.PRODUCT.contains("sdk_google")
+ || Build.PRODUCT.contains("google_sdk")
+ || Build.PRODUCT.contains("sdk")
+ || Build.PRODUCT.contains("sdk_x86")
+ || Build.PRODUCT.contains("vbox86p")
+ || Build.PRODUCT.contains("emulator")
+ || Build.PRODUCT.contains("simulator"))
+ }
+
+ fun firebaseAnalyticsEvent(context: Context, eventName:String, id:String, description:String){
+ val firebaseAnalytics = FirebaseAnalytics.getInstance(context)
+ val bundle = Bundle()
+ bundle.putString(FirebaseAnalytics.Param.ITEM_ID, id)
+ bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, description)
+ CentralLog.d("FirebaseAnalyticsEvent", eventName)
+ firebaseAnalytics.logEvent(eventName, bundle)
+ }
+
+ fun showAlertDialog(
+ message: String,
+ icon: Int,
+ context: Context?,
+ onDialogClick: OnDialogClick?
+ ) {
+ if (context == null) {
+ CentralLog.d(TAG, "context is null")
+ return
+ }
+ val dialogLayout = LayoutInflater.from(context).inflate(R.layout.layout_dialog, null)
+
+ dialogLayout.icon.setImageDrawable(context.getDrawable(icon))
+
+ dialogLayout.cancel.visibility = View.GONE
+
+ dialogLayout.message.text = message
+
+ val dialog = AlertDialog.Builder(context)
+ .setView(dialogLayout)
+ .create()
+
+ dialogLayout.ok.setOnClickListener {
+ onDialogClick?.okClicked()
+ dialog.dismiss()
+ }
+
+ dialog.setCancelable(false)
+ dialog.show()
+ }
+
+ fun getJSONString(context: Context): String {
+ val stringBuilder = StringBuilder()
+ try {
+ val input = context.resources.openRawResource(R.raw.regions)
+ val isr = InputStreamReader(input)
+ val inputBuffer = CharArray(100)
+ var charRead: Int
+ while (isr.read(inputBuffer).also { charRead = it } > 0) {
+ stringBuilder.append(String(inputBuffer, 0, charRead))
}
+ } catch (ioe: IOException) {
+ ioe.printStackTrace()
+ }
+ return stringBuilder.toString()
}
+
+ interface OnRegionSelected {
+ fun runWhenItemSelected(region: String?)
+ }
+
+ interface OnDialogClick {
+ fun okClicked()
+ }
+
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/bluetooth/BLEAdvertiser.kt b/app/src/main/java/io/bluetrace/opentrace/bluetooth/BLEAdvertiser.kt
index 1ed802c..27039f9 100644
--- a/app/src/main/java/io/bluetrace/opentrace/bluetooth/BLEAdvertiser.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/bluetooth/BLEAdvertiser.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.bluetooth
+package covid.trace.morocco.bluetooth
import android.bluetooth.BluetoothAdapter
import android.bluetooth.le.AdvertiseCallback
@@ -7,8 +7,8 @@ import android.bluetooth.le.AdvertiseSettings
import android.bluetooth.le.BluetoothLeAdvertiser
import android.os.Handler
import android.os.ParcelUuid
-import io.bluetrace.opentrace.logging.CentralLog
-import io.bluetrace.opentrace.services.BluetoothMonitoringService.Companion.infiniteAdvertising
+import covid.trace.morocco.logging.CentralLog
+import covid.trace.morocco.services.BluetoothMonitoringService.Companion.infiniteAdvertising
import java.util.*
diff --git a/app/src/main/java/io/bluetrace/opentrace/bluetooth/BLEDiscoverer.kt b/app/src/main/java/io/bluetrace/opentrace/bluetooth/BLEDiscoverer.kt
index cfb87bf..945c265 100644
--- a/app/src/main/java/io/bluetrace/opentrace/bluetooth/BLEDiscoverer.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/bluetooth/BLEDiscoverer.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.bluetooth
+package covid.trace.morocco.bluetooth
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
@@ -11,7 +11,7 @@ import android.content.IntentFilter
import android.os.Build
import android.os.ParcelUuid
import androidx.localbroadcastmanager.content.LocalBroadcastManager
-import io.bluetrace.opentrace.logging.CentralLog
+import covid.trace.morocco.logging.CentralLog
import java.util.*
import kotlin.properties.Delegates
@@ -73,10 +73,6 @@ class BLEDiscoverer constructor(context: Context, serviceUUIDString: String) {
CentralLog.w(TAG, "Nope. No uuids cached for address: " + device.address)
}
-// if(device.uuids.contains(serviceUUID)){
-// Utils.broadcastDeviceAvailable(context, device)
-// }
-
}
BluetoothAdapter.ACTION_DISCOVERY_FINISHED -> {
CentralLog.i(TAG, "Discovery ended")
@@ -105,8 +101,6 @@ class BLEDiscoverer constructor(context: Context, serviceUUIDString: String) {
}
}
-// var connectable = ConnectablePeripheral(txPower, rssi)
-// Utils.broadcastDeviceScanned(context, device, connectable)
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/bluetooth/BLEScanner.kt b/app/src/main/java/io/bluetrace/opentrace/bluetooth/BLEScanner.kt
index 683ea26..885a345 100644
--- a/app/src/main/java/io/bluetrace/opentrace/bluetooth/BLEScanner.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/bluetooth/BLEScanner.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.bluetooth
+package covid.trace.morocco.bluetooth
import android.bluetooth.BluetoothAdapter
import android.bluetooth.le.BluetoothLeScanner
@@ -7,8 +7,8 @@ import android.bluetooth.le.ScanFilter
import android.bluetooth.le.ScanSettings
import android.content.Context
import android.os.ParcelUuid
-import io.bluetrace.opentrace.Utils
-import io.bluetrace.opentrace.logging.CentralLog
+import covid.trace.morocco.Utils
+import covid.trace.morocco.logging.CentralLog
import java.util.*
import kotlin.collections.ArrayList
import kotlin.properties.Delegates
diff --git a/app/src/main/java/io/bluetrace/opentrace/bluetooth/gatt/GATT.kt b/app/src/main/java/io/bluetrace/opentrace/bluetooth/gatt/GATT.kt
index 83d87b7..c465aad 100644
--- a/app/src/main/java/io/bluetrace/opentrace/bluetooth/gatt/GATT.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/bluetooth/gatt/GATT.kt
@@ -1,6 +1,6 @@
-package io.bluetrace.opentrace.bluetooth.gatt
+package covid.trace.morocco.bluetooth.gatt
-import io.bluetrace.opentrace.BuildConfig
+import covid.trace.morocco.BuildConfig
const val ACTION_RECEIVED_STREETPASS =
"${BuildConfig.APPLICATION_ID}.ACTION_RECEIVED_STREETPASS"
diff --git a/app/src/main/java/io/bluetrace/opentrace/bluetooth/gatt/GattServer.kt b/app/src/main/java/io/bluetrace/opentrace/bluetooth/gatt/GattServer.kt
index de2dcb5..25b4792 100644
--- a/app/src/main/java/io/bluetrace/opentrace/bluetooth/gatt/GattServer.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/bluetooth/gatt/GattServer.kt
@@ -1,13 +1,13 @@
-package io.bluetrace.opentrace.bluetooth.gatt
+package covid.trace.morocco.bluetooth.gatt
import android.bluetooth.*
import android.bluetooth.BluetoothGatt.GATT_FAILURE
import android.bluetooth.BluetoothGatt.GATT_SUCCESS
import android.content.Context
-import io.bluetrace.opentrace.Utils
-import io.bluetrace.opentrace.idmanager.TempIDManager
-import io.bluetrace.opentrace.logging.CentralLog
-import io.bluetrace.opentrace.protocol.BlueTrace
+import covid.trace.morocco.Utils
+import covid.trace.morocco.idmanager.TempIDManager
+import covid.trace.morocco.logging.CentralLog
+import covid.trace.morocco.protocol.BlueTrace
import java.util.*
import kotlin.properties.Delegates
diff --git a/app/src/main/java/io/bluetrace/opentrace/bluetooth/gatt/GattService.kt b/app/src/main/java/io/bluetrace/opentrace/bluetooth/gatt/GattService.kt
index dfdbac3..aeedc27 100644
--- a/app/src/main/java/io/bluetrace/opentrace/bluetooth/gatt/GattService.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/bluetooth/gatt/GattService.kt
@@ -1,9 +1,9 @@
-package io.bluetrace.opentrace.bluetooth.gatt
+package covid.trace.morocco.bluetooth.gatt
import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.BluetoothGattService
import android.content.Context
-import io.bluetrace.opentrace.BuildConfig
+import covid.trace.morocco.BuildConfig
import java.util.*
import kotlin.properties.Delegates
diff --git a/app/src/main/java/io/bluetrace/opentrace/boot/StartOnBootReceiver.kt b/app/src/main/java/io/bluetrace/opentrace/boot/StartOnBootReceiver.kt
index b05877d..d336aee 100644
--- a/app/src/main/java/io/bluetrace/opentrace/boot/StartOnBootReceiver.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/boot/StartOnBootReceiver.kt
@@ -1,26 +1,30 @@
-package io.bluetrace.opentrace.boot
+package covid.trace.morocco.boot
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
-import io.bluetrace.opentrace.Utils
-import io.bluetrace.opentrace.logging.CentralLog
+import com.google.firebase.crashlytics.FirebaseCrashlytics
+import covid.trace.morocco.Utils
+import covid.trace.morocco.logging.CentralLog
class StartOnBootReceiver : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- if (Intent.ACTION_BOOT_COMPLETED == intent.action) {
- CentralLog.d("StartOnBootReceiver", "boot completed received")
+ private val crashlytics = FirebaseCrashlytics.getInstance()
+
+ override fun onReceive(context: Context, intent: Intent) {
try {
+ if (Intent.ACTION_BOOT_COMPLETED != intent.action) return
+ CentralLog.d("StartOnBootReceiver", "boot completed received")
//can i try a scheduled service start here?
CentralLog.d("StartOnBootReceiver", "Attempting to start service")
Utils.scheduleStartMonitoringService(context, 500)
} catch (e: Throwable) {
+ crashlytics.recordException(e)
+ crashlytics.setCustomKey("receiver","StartOnBoat receiver")
CentralLog.e("StartOnBootReceiver", e.localizedMessage)
e.printStackTrace()
}
- }
}
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/fragment/EnterPinFragment.kt b/app/src/main/java/io/bluetrace/opentrace/fragment/EnterPinFragment.kt
index d969077..e99cd47 100644
--- a/app/src/main/java/io/bluetrace/opentrace/fragment/EnterPinFragment.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/fragment/EnterPinFragment.kt
@@ -1,38 +1,42 @@
-package io.bluetrace.opentrace.fragment
+package covid.trace.morocco.fragment
+import android.app.AlertDialog
import android.content.Context
+import android.content.DialogInterface
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.text.Editable
+import android.text.TextUtils
import android.text.TextWatcher
-import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.widget.Toast
import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment
import com.google.android.gms.tasks.Task
+import com.google.firebase.auth.FirebaseAuth
+import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.functions.FirebaseFunctions
import com.google.firebase.functions.HttpsCallableResult
import com.google.firebase.storage.FirebaseStorage
import com.google.firebase.storage.UploadTask
import com.google.gson.Gson
+import covid.trace.morocco.*
+import covid.trace.morocco.logging.CentralLog
+import covid.trace.morocco.models.ExportData
+import covid.trace.morocco.notifications.NotificationTemplates
+import covid.trace.morocco.status.persistence.StatusRecord
+import covid.trace.morocco.status.persistence.StatusRecordStorage
+import covid.trace.morocco.streetpass.persistence.StreetPassRecord
+import covid.trace.morocco.streetpass.persistence.StreetPassRecordStorage
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.functions.BiFunction
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.fragment_upload_enterpin.*
-import io.bluetrace.opentrace.BuildConfig
-import io.bluetrace.opentrace.R
-import io.bluetrace.opentrace.TracerApp
-import io.bluetrace.opentrace.Utils
-import io.bluetrace.opentrace.logging.CentralLog
-import io.bluetrace.opentrace.status.persistence.StatusRecord
-import io.bluetrace.opentrace.status.persistence.StatusRecordStorage
-import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecord
-import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecordStorage
import java.io.File
import java.io.FileOutputStream
import java.text.SimpleDateFormat
@@ -41,6 +45,7 @@ import kotlin.collections.HashMap
class EnterPinFragment : Fragment() {
private var TAG = "UploadFragment"
+ private var crashlytics = FirebaseCrashlytics.getInstance()
private var disposeObj: Disposable? = null
@@ -54,36 +59,39 @@ class EnterPinFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
+ context?.let{
+ Utils.firebaseAnalyticsEvent(it, "upload_screen_2", "11", "upload screen 2")
+ }
- enterPinFragmentUploadCode.addTextChangedListener(object : TextWatcher {
- override fun afterTextChanged(s: Editable) {}
- override fun beforeTextChanged(
- s: CharSequence, start: Int,
- count: Int, after: Int
- ) {
- }
+ if (TextUtils.equals(
+ PreferencesHelper.getCurrentLanguage(),
+ PreferencesHelper.ARABIC_LANGUAGE_CODE
+ )
+ ) {
+ back.rotation = 180F
+ }
- override fun onTextChanged(
- s: CharSequence, start: Int,
- before: Int, count: Int
- ) {
- if (s.length == 6) {
- Utils.hideKeyboardFrom(view.context, view)
- }
- }
- })
+ back.setOnClickListener {
+ val parentActivity: MainActivity = activity as MainActivity
+ parentActivity.openFragment(
+ parentActivity.LAYOUT_MAIN_ID,
+ ForUseFragment(),
+ ForUseFragment::class.java.name
+ )
+ }
+
+ editTextsListeners()
enterPinActionButton.setOnClickListener {
enterPinFragmentErrorMessage.visibility = View.INVISIBLE
- var myParentFragment: UploadPageFragment = (parentFragment as UploadPageFragment)
- myParentFragment.turnOnLoadingProgress()
+ turnOnLoadingProgress()
var observableStreetRecords = Observable.create<List<StreetPassRecord>> {
- val result = StreetPassRecordStorage(TracerApp.AppContext).getAllRecords()
+ val result = StreetPassRecordStorage(WiqaytnaApp.AppContext).getAllRecords()
it.onNext(result)
}
var observableStatusRecords = Observable.create<List<StatusRecord>> {
- val result = StatusRecordStorage(TracerApp.AppContext).getAllRecords()
+ val result = StatusRecordStorage(WiqaytnaApp.AppContext).getAllRecords()
it.onNext(result)
}
@@ -100,61 +108,75 @@ class EnterPinFragment : Fragment() {
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe { exportedData ->
- Log.d(TAG, "records: ${exportedData.recordList}")
- Log.d(TAG, "status: ${exportedData.statusList}")
+ CentralLog.d(TAG, "records: ${exportedData.recordList}")
+ CentralLog.d(TAG, "status: ${exportedData.statusList}")
- getUploadToken(enterPinFragmentUploadCode.text.toString()).addOnSuccessListener {
+ getUploadToken(getPin()).addOnSuccessListener {
val response = it.data as HashMap<String, String>
try {
val uploadToken = response["token"]
CentralLog.d(TAG, "uploadToken: $uploadToken")
var task = writeToInternalStorageAndUpload(
- TracerApp.AppContext,
+ WiqaytnaApp.AppContext,
exportedData.recordList,
exportedData.statusList,
uploadToken
)
- task.addOnFailureListener {
+ task.addOnFailureListener { exception ->
+ crashlytics.recordException(exception)
+ crashlytics.setCustomKey("error", "failed to upload")
+ val uid = FirebaseAuth.getInstance().currentUser?.uid
+ crashlytics.setCustomKey("uid", "$uid")
CentralLog.d(TAG, "failed to upload")
- var myParentFragment: UploadPageFragment =
- (parentFragment as UploadPageFragment)
- myParentFragment.turnOffLoadingProgress()
- enterPinFragmentErrorMessage.visibility = View.VISIBLE
+ if (!isDetached) {
+ turnOffLoadingProgress()
+ Toast.makeText(
+ context, resources.getString(R.string.server_problem),
+ Toast.LENGTH_SHORT
+ ).show()
+ }
}.addOnSuccessListener {
CentralLog.d(TAG, "uploaded successfully")
- var myParentFragment: UploadPageFragment =
- (parentFragment as UploadPageFragment)
- myParentFragment.turnOffLoadingProgress()
- myParentFragment.navigateToUploadComplete()
+ if (!isDetached) {
+ turnOffLoadingProgress()
+ navigateToUploadComplete()
+ }
}
} catch (e: Throwable) {
+ crashlytics.recordException(e)
+ crashlytics.setCustomKey("error", "Failed to upload data")
+ val uid = FirebaseAuth.getInstance().currentUser?.uid
+ crashlytics.setCustomKey("uid", "$uid")
+ context?.let {context ->
+ NotificationTemplates.diskFullWarningNotification(
+ context,
+ BuildConfig.SERVICE_FOREGROUND_CHANNEL_ID
+ )
+ }
+
CentralLog.d(TAG, "Failed to upload data: ${e.message}")
- var myParentFragment: UploadPageFragment =
- (parentFragment as UploadPageFragment)
- myParentFragment.turnOffLoadingProgress()
- enterPinFragmentErrorMessage.visibility = View.VISIBLE
+ if (!isDetached) {
+ turnOffLoadingProgress()
+ Toast.makeText(
+ context, resources.getString(R.string.server_problem),
+ Toast.LENGTH_SHORT
+ ).show()
+ }
}
- }.addOnFailureListener {
+ }.addOnFailureListener { exception ->
CentralLog.d(TAG, "Invalid code")
- var myParentFragment: UploadPageFragment =
- (parentFragment as UploadPageFragment)
- myParentFragment.turnOffLoadingProgress()
- enterPinFragmentErrorMessage.visibility = View.VISIBLE
+ crashlytics.recordException(exception)
+ crashlytics.setCustomKey("error", "upload : Invalid code")
+ val uid = FirebaseAuth.getInstance().currentUser?.uid
+ crashlytics.setCustomKey("uid", "$uid")
+ if (!isDetached) {
+ turnOffLoadingProgress()
+ enterPinFragmentErrorMessage?.visibility = View.VISIBLE
+ }
}
}
}
- enterPinFragmentBackButtonLayout.setOnClickListener {
- println("onclick is pressed")
- var myParentFragment: UploadPageFragment = (parentFragment as UploadPageFragment)
- myParentFragment.popStack()
- }
-
- enterPinFragmentBackButton.setOnClickListener {
- println("onclick is pressed")
- var myParentFragment: UploadPageFragment = (parentFragment as UploadPageFragment)
- myParentFragment.popStack()
- }
}
override fun onDestroy() {
@@ -227,7 +249,7 @@ class EnterPinFragment : Fragment() {
val storage = FirebaseStorage.getInstance("gs://${bucketName}")
var storageRef = storage.getReferenceFromUrl("gs://${bucketName}")
- val dateString = SimpleDateFormat("YYYYMMdd").format(Date())
+ val dateString = SimpleDateFormat("yyyyMMdd").format(Date())
var streetPassRecordsRef =
storageRef.child("streetPassRecords/$dateString/${fileToUpload.name}")
@@ -250,4 +272,132 @@ class EnterPinFragment : Fragment() {
return uploadTask
}
+ private fun editTextsListeners() {
+
+ otp1.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+
+ }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
+ }
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+ if (s?.length == 1) otp2?.requestFocus()
+ }
+
+ })
+
+ otp2.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+
+ }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
+ }
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+ if (s?.length == 1) otp3?.requestFocus()
+ if (s?.length == 0) otp1?.requestFocus()
+ }
+
+ })
+
+ otp3.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+
+ }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
+ }
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+ if (s?.length == 1) otp4?.requestFocus()
+ if (s?.length == 0) otp2?.requestFocus()
+ }
+
+ })
+
+ otp4.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+
+ }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
+ }
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+ if (s?.length == 1) otp5?.requestFocus()
+ if (s?.length == 0) otp3?.requestFocus()
+ }
+
+ })
+
+ otp5.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+
+ }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
+ }
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+ if (s?.length == 1) otp6?.requestFocus()
+ if (s?.length == 0) otp4?.requestFocus()
+ }
+
+ })
+
+ otp6.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+
+ }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
+ }
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+ if (s?.length == 0) otp5?.requestFocus()
+ if (getPin().length == 6) {
+ Utils.hideKeyboardFrom(view!!.context, view!!)
+ }
+ }
+
+ })
+ }
+
+ private fun turnOnLoadingProgress() {
+ if (uploadPageFragmentLoadingProgressBarFrame != null)
+ uploadPageFragmentLoadingProgressBarFrame.visibility = View.VISIBLE
+ }
+
+ private fun turnOffLoadingProgress() {
+ if (uploadPageFragmentLoadingProgressBarFrame != null)
+ uploadPageFragmentLoadingProgressBarFrame.visibility = View.INVISIBLE
+ }
+
+ private fun navigateToUploadComplete() {
+ val parentActivity: MainActivity = activity as MainActivity
+ parentActivity.openFragment(
+ parentActivity.LAYOUT_MAIN_ID,
+ UploadCompleteFragment(),
+ UploadCompleteFragment::class.java.name
+ )
+ }
+
+ private fun getPin(): String {
+ return otp1.text.toString() + otp2.text.toString() + otp3.text.toString() + otp4.text.toString() + otp5.text.toString() + otp6.text.toString()
+ }
+
+ private fun showAlertDialog(message: String) {
+ val dialog = AlertDialog.Builder(context)
+ .setMessage(message)
+ .setPositiveButton(
+ "ok",
+ DialogInterface.OnClickListener { dialogInterface: DialogInterface, i: Int ->
+ dialogInterface.dismiss()
+ }).create()
+
+ dialog.show()
+ }
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/fragment/ForUseFragment.kt b/app/src/main/java/io/bluetrace/opentrace/fragment/ForUseFragment.kt
index b5c91ec..ceb4bae 100644
--- a/app/src/main/java/io/bluetrace/opentrace/fragment/ForUseFragment.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/fragment/ForUseFragment.kt
@@ -1,12 +1,16 @@
-package io.bluetrace.opentrace.fragment
+package covid.trace.morocco.fragment
+import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
+import covid.trace.morocco.MainActivity
+import covid.trace.morocco.R
+import covid.trace.morocco.Utils
+import covid.trace.morocco.onboarding.PersonalInfosActivity
import kotlinx.android.synthetic.main.fragment_upload_foruse.*
-import io.bluetrace.opentrace.R
class ForUseFragment : Fragment() {
override fun onCreateView(
@@ -20,9 +24,26 @@ class ForUseFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
+ context?.let {
+ Utils.firebaseAnalyticsEvent(it, "upload_screen_1", "10", "upload screen")
+ }
+
forUseFragmentActionButton.setOnClickListener {
- var myParentFragment: ForUseByOTCFragment = (parentFragment as ForUseByOTCFragment)
- myParentFragment.goToUploadFragment()
+ goToUploadFragment()
+ }
+
+ language.setOnClickListener {
+ startActivity(Intent(context, PersonalInfosActivity::class.java))
}
}
+
+
+ private fun goToUploadFragment() {
+ val parentActivity: MainActivity = activity as MainActivity
+ parentActivity.openFragment(
+ parentActivity.LAYOUT_MAIN_ID,
+ EnterPinFragment(),
+ EnterPinFragment::class.java.name
+ )
+ }
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/fragment/HomeFragment.kt b/app/src/main/java/io/bluetrace/opentrace/fragment/HomeFragment.kt
index b5442e9..2c35627 100644
--- a/app/src/main/java/io/bluetrace/opentrace/fragment/HomeFragment.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/fragment/HomeFragment.kt
@@ -1,13 +1,15 @@
-package io.bluetrace.opentrace.fragment
+package covid.trace.morocco.fragment
import android.app.Activity
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.content.*
+import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.PowerManager
import android.text.Spannable
+import android.text.TextUtils
import android.text.method.LinkMovementMethod
import android.text.style.URLSpan
import android.view.LayoutInflater
@@ -16,24 +18,29 @@ import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
+import androidx.browser.customtabs.CustomTabsIntent
import androidx.core.app.NotificationManagerCompat
+import androidx.core.content.ContextCompat
import androidx.core.text.HtmlCompat
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.Observer
+import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.ktx.Firebase
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.firebase.remoteconfig.ktx.remoteConfig
import com.google.firebase.remoteconfig.ktx.remoteConfigSettings
+import covid.trace.morocco.*
+import covid.trace.morocco.logging.CentralLog
+import covid.trace.morocco.models.StatisticsResponse
+import covid.trace.morocco.onboarding.OnboardingActivity
+import covid.trace.morocco.onboarding.PersonalInfosActivity
import kotlinx.android.synthetic.main.fragment_home.*
+import kotlinx.android.synthetic.main.fragment_new_home.*
+import kotlinx.android.synthetic.main.home_setupe_incomplete.*
import pub.devrel.easypermissions.AfterPermissionGranted
import pub.devrel.easypermissions.EasyPermissions
-import io.bluetrace.opentrace.*
-import io.bluetrace.opentrace.logging.CentralLog
-import io.bluetrace.opentrace.onboarding.OnboardingActivity
-import io.bluetrace.opentrace.status.persistence.StatusRecord
-import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecordDatabase
+import java.text.SimpleDateFormat
+import java.util.*
private const val REQUEST_ENABLE_BT = 123
private const val PERMISSION_REQUEST_ACCESS_LOCATION = 456
@@ -45,25 +52,46 @@ class HomeFragment : Fragment() {
private var counter = 0
private lateinit var remoteConfig: FirebaseRemoteConfig
- private lateinit var lastKnownScanningStarted: LiveData<StatusRecord?>
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- val db = StreetPassRecordDatabase.getDatabase(view.context)
-
- lastKnownScanningStarted = db.statusDao().getMostRecentRecord("Scanning Started")
- lastKnownScanningStarted.observe(viewLifecycleOwner,
- Observer { record ->
- if (record != null) {
- tv_last_update.visibility = View.VISIBLE
- tv_last_update.text = "Last updated: ${Utils.getTime(record.timestamp)}"
- }
- })
showSetup()
- Preference.registerListener(activity!!.applicationContext, listener)
+ Preference.registerListener(requireActivity().applicationContext, listener)
+
showNonEmptyAnnouncement()
+
+ if (WiqaytnaApp.statisticsData != null) {
+ initViews(WiqaytnaApp.statisticsData!!)
+ }
+
+ settings.setOnClickListener {
+ startActivity(Intent(context, PersonalInfosActivity::class.java))
+ }
+
+ faq.setOnClickListener {
+
+ context?.let{
+ Utils.firebaseAnalyticsEvent(it, "open_faq", "13", "open faq")
+ }
+
+ val url = if (TextUtils.equals(
+ PreferencesHelper.getCurrentLanguage(),
+ PreferencesHelper.FRENCH_LANGUAGE_CODE
+ )
+ ) {
+ Utils.faqFrURL
+ } else {
+ Utils.faqArURL
+ }
+ val builder = CustomTabsIntent.Builder()
+ builder.setToolbarColor(ContextCompat.getColor(requireContext(), R.color.new_blue))
+ builder.addDefaultShareMenuItem()
+ val customTabsIntent = builder.build()
+ customTabsIntent.launchUrl(context, Uri.parse(url))
+ }
+
}
override fun onCreateView(
@@ -72,11 +100,35 @@ class HomeFragment : Fragment() {
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_home, container, false)
- Preference.registerListener(activity!!.applicationContext, listener)
+ Preference.registerListener(requireActivity().applicationContext, listener)
return view
}
+ private fun initViews(response: StatisticsResponse) {
+ val data = response.data
+ confirmed_cases.text = data.new_confirmed
+ recovered.text = data.new_recovered
+ deaths.text = data.new_death
+ val timeStamp = response.data.date._seconds * 1000
+ if (TextUtils.equals(
+ PreferencesHelper.getCurrentLanguage(),
+ PreferencesHelper.FRENCH_LANGUAGE_CODE
+ )
+ ) {
+ val dateFormat = SimpleDateFormat("dd MMMM yyyy HH'h00'", Locale.FRANCE)
+ updateDate.text = dateFormat.format(timeStamp)
+ } else {
+ val day = SimpleDateFormat("dd", Locale("ar", "ma")).format(timeStamp)
+ val month = SimpleDateFormat("MMMM", Locale("ar", "ma")).format(timeStamp)
+ val year = SimpleDateFormat("yyyy", Locale("ar", "ma")).format(timeStamp)
+ val hour = SimpleDateFormat("HH", Locale("ar", "ma")).format(timeStamp)
+ CentralLog.d("update time", "$day $month $year الساعة $hour")
+ updateDate.text = "$day $month $year الساعة $hour"
+ }
+
+ }
+
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
@@ -88,6 +140,7 @@ class HomeFragment : Fragment() {
context?.startActivity(intent)
}
}
+ //goes to permissions page
btn_restart_app_setup.setOnClickListener {
var intent = Intent(context, OnboardingActivity::class.java)
intent.putExtra("page", 3)
@@ -117,8 +170,10 @@ class HomeFragment : Fragment() {
private fun isShowRestartSetup(): Boolean {
if (canRequestBatteryOptimizerExemption()) {
+ location_card_view.visibility = if (iv_location.isSelected) View.GONE else View.VISIBLE
if (iv_bluetooth.isSelected && iv_location.isSelected && iv_battery.isSelected) return false
} else {
+ location_card_view.visibility = View.GONE
if (iv_bluetooth.isSelected && iv_location.isSelected) return false
}
return true
@@ -127,14 +182,28 @@ class HomeFragment : Fragment() {
private fun canRequestBatteryOptimizerExemption(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Utils.canHandleIntent(
Utils.getBatteryOptimizerExemptionIntent(
- TracerApp.AppContext.packageName
- ), TracerApp.AppContext.packageManager
+ WiqaytnaApp.AppContext.packageName
+ ), WiqaytnaApp.AppContext.packageManager
)
}
fun showSetup() {
view_setup.isVisible = isShowRestartSetup()
view_complete.isVisible = !isShowRestartSetup()
+ if (view_setup.isVisible) {
+ context?.let{
+ Utils.firebaseAnalyticsEvent(
+ it,
+ "home_screen_setup_incomplete",
+ "7",
+ "home screen setup incomplete"
+ )
+ }
+ } else {
+ context?.let {
+ Utils.firebaseAnalyticsEvent(it, "home_screen", "6", "home screen")
+ }
+ }
}
override fun onResume() {
@@ -143,7 +212,7 @@ class HomeFragment : Fragment() {
// bluetooth on/off
var f = IntentFilter()
f.addAction(BluetoothAdapter.ACTION_STATE_CHANGED)
- activity!!.registerReceiver(mBroadcastListener, f)
+ requireActivity().registerReceiver(mBroadcastListener, f)
mIsBroadcastListenerRegistered = true
}
@@ -152,13 +221,30 @@ class HomeFragment : Fragment() {
val perms = Utils.getRequiredPermissions()
iv_location.isSelected =
EasyPermissions.hasPermissions(activity as MainActivity, *perms)
+ if (iv_location.isSelected) {
+ iv_location.visibility = View.GONE
+ } else {
+ iv_location.visibility = View.VISIBLE
+ }
//push notification
iv_push.isSelected =
NotificationManagerCompat.from(activity as MainActivity).areNotificationsEnabled()
+ if (iv_push.isSelected) {
+ push_card_view.visibility = View.GONE
+ } else {
+ push_card_view.visibility = View.VISIBLE
+ }
+
bluetoothAdapter?.let {
iv_bluetooth.isSelected = !it.isDisabled
+
+ if (iv_bluetooth.isSelected) {
+ bluetooth_card_view.visibility = View.GONE
+ } else {
+ bluetooth_card_view.visibility = View.VISIBLE
+ }
}
//battery ignore list
@@ -170,9 +256,11 @@ class HomeFragment : Fragment() {
battery_card_view.visibility = View.VISIBLE
if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
iv_battery.isSelected = false
+ battery_card_view.visibility = View.VISIBLE
CentralLog.d(TAG, "Not on Battery Optimization whitelist")
} else {
iv_battery.isSelected = true
+ battery_card_view.visibility = View.GONE
CentralLog.d(TAG, "On Battery Optimization whitelist")
}
} else {
@@ -186,18 +274,25 @@ class HomeFragment : Fragment() {
override fun onPause() {
super.onPause()
if (mIsBroadcastListenerRegistered) {
- activity!!.unregisterReceiver(mBroadcastListener)
+ requireActivity().unregisterReceiver(mBroadcastListener)
mIsBroadcastListenerRegistered = false
}
}
override fun onDestroyView() {
super.onDestroyView()
- Preference.unregisterListener(activity!!.applicationContext, listener)
- lastKnownScanningStarted.removeObservers(viewLifecycleOwner)
+ Preference.unregisterListener(requireActivity().applicationContext, listener)
}
private fun shareThisApp() {
+ context?.let {
+ Utils.firebaseAnalyticsEvent(
+ it,
+ FirebaseAnalytics.Event.SHARE,
+ "14",
+ "share the app"
+ )
+ }
var newIntent = Intent(Intent.ACTION_SEND)
newIntent.type = "text/plain"
newIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name))
@@ -213,10 +308,13 @@ class HomeFragment : Fragment() {
var state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1)
if (state == BluetoothAdapter.STATE_OFF) {
iv_bluetooth.isSelected = false
+ bluetooth_card_view.visibility = View.VISIBLE
} else if (state == BluetoothAdapter.STATE_TURNING_OFF) {
iv_bluetooth.isSelected = false
+ bluetooth_card_view.visibility = View.VISIBLE
} else if (state == BluetoothAdapter.STATE_ON) {
iv_bluetooth.isSelected = true
+ bluetooth_card_view.visibility = View.GONE
}
showSetup()
@@ -252,10 +350,12 @@ class HomeFragment : Fragment() {
// Already have permission, do the thing
} else {
// Do not have permissions, request them now
- EasyPermissions.requestPermissions(
- this, getString(R.string.permission_location_rationale),
- PERMISSION_REQUEST_ACCESS_LOCATION, *perms
- )
+ if (!isDetached) {
+ EasyPermissions.requestPermissions(
+ this, getString(R.string.permission_location_rationale),
+ PERMISSION_REQUEST_ACCESS_LOCATION, *perms
+ )
+ }
}
}
}
@@ -264,6 +364,11 @@ class HomeFragment : Fragment() {
// User chose not to enable Bluetooth.
if (requestCode == REQUEST_ENABLE_BT) {
iv_bluetooth.isSelected = resultCode == Activity.RESULT_OK
+ if (iv_bluetooth.isSelected) {
+ bluetooth_card_view.visibility = View.GONE
+ } else {
+ bluetooth_card_view.visibility = View.VISIBLE
+ }
}
showSetup()
super.onActivityResult(requestCode, resultCode, data)
@@ -279,6 +384,11 @@ class HomeFragment : Fragment() {
when (requestCode) {
PERMISSION_REQUEST_ACCESS_LOCATION -> {
iv_location.isSelected = permissions.isNotEmpty()
+ if (iv_location.isSelected) {
+ iv_location.visibility = View.GONE
+ } else {
+ iv_location.visibility = View.VISIBLE
+ }
}
}
@@ -294,11 +404,11 @@ class HomeFragment : Fragment() {
private fun clearAndHideAnnouncement() {
view_announcement.isVisible = false
- Preference.putAnnouncement(activity!!.applicationContext, "")
+ Preference.putAnnouncement(requireActivity().applicationContext, "")
}
private fun showNonEmptyAnnouncement() {
- val new = Preference.getAnnouncement(activity!!.applicationContext)
+ val new = Preference.getAnnouncement(requireActivity().applicationContext)
if (new.isEmpty()) return
CentralLog.d(TAG, "FCM Announcement Changed to $new!")
tv_announcement.text = HtmlCompat.fromHtml(new, HtmlCompat.FROM_HTML_MODE_COMPACT)
diff --git a/app/src/main/java/io/bluetrace/opentrace/fragment/UploadCompleteFragment.kt b/app/src/main/java/io/bluetrace/opentrace/fragment/UploadCompleteFragment.kt
index af6a7f1..c3ad13d 100644
--- a/app/src/main/java/io/bluetrace/opentrace/fragment/UploadCompleteFragment.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/fragment/UploadCompleteFragment.kt
@@ -1,12 +1,14 @@
-package io.bluetrace.opentrace.fragment
+package covid.trace.morocco.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
+import covid.trace.morocco.MainActivity
+import covid.trace.morocco.R
+import covid.trace.morocco.Utils
import kotlinx.android.synthetic.main.fragment_upload_uploadcomplete.*
-import io.bluetrace.opentrace.R
class UploadCompleteFragment : Fragment() {
override fun onCreateView(
@@ -20,9 +22,17 @@ class UploadCompleteFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
+ context?.let{
+ Utils.firebaseAnalyticsEvent(it, "upload_succeeded", "12", "upload succeeded")
+ }
+
uploadCompleteFragmentActionButton.setOnClickListener {
- var myParentFragment: UploadPageFragment = (parentFragment as UploadPageFragment)
- myParentFragment.goBackToHome()
+ goBackToHome()
}
}
+
+ private fun goBackToHome() {
+ var parentActivity = activity as MainActivity
+ parentActivity.goToHome()
+ }
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/idmanager/TempIDManager.kt b/app/src/main/java/io/bluetrace/opentrace/idmanager/TempIDManager.kt
index f597949..d88ee8f 100644
--- a/app/src/main/java/io/bluetrace/opentrace/idmanager/TempIDManager.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/idmanager/TempIDManager.kt
@@ -1,25 +1,41 @@
-package io.bluetrace.opentrace.idmanager
+package covid.trace.morocco.idmanager
import android.content.Context
import com.google.android.gms.tasks.Task
+import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.functions.FirebaseFunctions
import com.google.firebase.functions.HttpsCallableResult
import com.google.gson.Gson
import com.google.gson.GsonBuilder
-import io.bluetrace.opentrace.Preference
-import io.bluetrace.opentrace.logging.CentralLog
-import io.bluetrace.opentrace.services.BluetoothMonitoringService.Companion.bmValidityCheck
+import covid.trace.morocco.BuildConfig
+import covid.trace.morocco.Preference
+import covid.trace.morocco.logging.CentralLog
+import covid.trace.morocco.notifications.NotificationTemplates
+import covid.trace.morocco.services.BluetoothMonitoringService.Companion.bmValidityCheck
import java.io.File
import java.util.*
object TempIDManager {
private const val TAG = "TempIDManager"
+ private val crashlytics = FirebaseCrashlytics.getInstance()
- fun storeTemporaryIDs(context: Context, packet: String) {
+ private fun storeTemporaryIDs(context: Context, packet: String) {
CentralLog.d(TAG, "[TempID] Storing temporary IDs into internal storage...")
- val file = File(context.filesDir, "tempIDs")
- file.writeText(packet)
+ try {
+ val file = File(context.filesDir, "tempIDs")
+ file.writeText(packet)
+ } catch (exception: Throwable) {
+ crashlytics.recordException(exception)
+ crashlytics.setCustomKey("error", "can't store tempIDs")
+ crashlytics.setCustomKey("function", "storeTemporaryIDs")
+ NotificationTemplates.diskFullWarningNotification(
+ context,
+ BuildConfig.SERVICE_FOREGROUND_CHANNEL_ID
+ )
+
+ }
+
}
fun retrieveTemporaryID(context: Context): TemporaryID? {
@@ -46,7 +62,7 @@ object TempIDManager {
private fun getValidOrLastTemporaryID(
context: Context,
tempIDQueue: Queue<TemporaryID>
- ): TemporaryID {
+ ): TemporaryID? {
CentralLog.d(TAG, "[TempID] Retrieving Temporary ID")
var currentTime = System.currentTimeMillis()
@@ -65,47 +81,53 @@ object TempIDManager {
}
var foundTempID = tempIDQueue.peek()
- var foundTempIDStartTime = foundTempID.startTime * 1000
- var foundTempIDExpiryTime = foundTempID.expiryTime * 1000
-
- CentralLog.d(TAG, "[TempID Total number of items in queue: ${tempIDQueue.size}")
- CentralLog.d(TAG, "[TempID Number of items popped from queue: $pop")
- CentralLog.d(TAG, "[TempID] Current time: ${currentTime}")
- CentralLog.d(TAG, "[TempID] Start time: ${foundTempIDStartTime}")
- CentralLog.d(TAG, "[TempID] Expiry time: ${foundTempIDExpiryTime}")
- CentralLog.d(TAG, "[TempID] Updating expiry time")
- Preference.putExpiryTimeInMillis(
- context,
- foundTempIDExpiryTime
- )
+ if (foundTempID != null) {
+ var foundTempIDStartTime = foundTempID.startTime * 1000
+ var foundTempIDExpiryTime = foundTempID.expiryTime * 1000
+
+ CentralLog.d(TAG, "[TempID Total number of items in queue: ${tempIDQueue.size}")
+ CentralLog.d(TAG, "[TempID Number of items popped from queue: $pop")
+ CentralLog.d(TAG, "[TempID] Current time: ${currentTime}")
+ CentralLog.d(TAG, "[TempID] Start time: ${foundTempIDStartTime}")
+ CentralLog.d(TAG, "[TempID] Expiry time: ${foundTempIDExpiryTime}")
+ CentralLog.d(TAG, "[TempID] Updating expiry time")
+ Preference.putExpiryTimeInMillis(
+ context,
+ foundTempIDExpiryTime
+ )
+ }
+
return foundTempID
}
- private fun convertToTemporaryIDs(tempIDString: String): Array<TemporaryID> {
+ private fun convertToTemporaryIDs(tempIDString: String): Array<TemporaryID>? {
val gson: Gson = GsonBuilder().disableHtmlEscaping().create()
val tempIDResult = gson.fromJson(tempIDString, Array<TemporaryID>::class.java)
CentralLog.d(
TAG,
- "[TempID] After GSON conversion: ${tempIDResult[0].tempID} ${tempIDResult[0].startTime}"
+ "[TempID] After GSON conversion: ${tempIDResult?.get(0)?.tempID} ${tempIDResult?.get(0)?.startTime}"
)
+
return tempIDResult
}
- private fun convertToQueue(tempIDArray: Array<TemporaryID>): Queue<TemporaryID> {
- CentralLog.d(TAG, "[TempID] Before Sort: ${tempIDArray[0]}")
+ private fun convertToQueue(tempIDArray: Array<TemporaryID>?): Queue<TemporaryID> {
+ CentralLog.d(TAG, "[TempID] Before Sort: ${tempIDArray?.get(0)}")
//Sort based on start time
- tempIDArray.sortBy {
+ tempIDArray?.sortBy {
return@sortBy it.startTime
}
- CentralLog.d(TAG, "[TempID] After Sort: ${tempIDArray[0]}")
+ CentralLog.d(TAG, "[TempID] After Sort: ${tempIDArray?.get(0)}")
//Preserving order of array which was sorted
var tempIDQueue: Queue<TemporaryID> = LinkedList<TemporaryID>()
- for (tempID in tempIDArray) {
- tempIDQueue.offer(tempID)
+ if (tempIDArray != null) {
+ for (tempID in tempIDArray) {
+ tempIDQueue.offer(tempID)
+ }
}
CentralLog.d(TAG, "[TempID] Retrieving from Queue: ${tempIDQueue.peek()}")
@@ -113,11 +135,16 @@ object TempIDManager {
}
fun getTemporaryIDs(context: Context, functions: FirebaseFunctions): Task<HttpsCallableResult> {
+ CentralLog.d(TAG,"getTemporaryIDs called")
return functions.getHttpsCallable("getTempIDs").call().addOnSuccessListener {
val result: HashMap<String, Any> = it.data as HashMap<String, Any>
val tempIDs = result["tempIDs"]
val status = result["status"].toString()
+
+ CentralLog.d(TAG,"tempIDs: $tempIDs")
+ CentralLog.d(TAG,"status: $status")
+
if (status.toLowerCase().contentEquals("success")) {
CentralLog.w(TAG, "Retrieved Temporary IDs from Server")
val gson: Gson = GsonBuilder().disableHtmlEscaping().create()
@@ -129,18 +156,25 @@ object TempIDManager {
val refreshTime = result["refreshTime"].toString()
var refresh = refreshTime.toLongOrNull() ?: 0
+
Preference.putNextFetchTimeInMillis(
context,
refresh * 1000
)
Preference.putLastFetchTimeInMillis(
context,
- System.currentTimeMillis() * 1000
+ System.currentTimeMillis()
)
+
+ CentralLog.d(TAG,"refresh: ${Preference.getNextFetchTimeInMillis(context)}")
+
+ CentralLog.d(TAG,"lastFetch: ${Preference.getLastFetchTimeInMillis(context)}")
}
- }.addOnFailureListener {
+ }.addOnFailureListener { exception ->
CentralLog.d(TAG, "[TempID] Error getting Temporary IDs")
+ crashlytics.recordException(exception)
+ crashlytics.setCustomKey("error", "couldn't get temporary IDs")
}
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/idmanager/TemporaryID.kt b/app/src/main/java/io/bluetrace/opentrace/idmanager/TemporaryID.kt
index d1cd9e2..cf3f3b1 100644
--- a/app/src/main/java/io/bluetrace/opentrace/idmanager/TemporaryID.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/idmanager/TemporaryID.kt
@@ -1,6 +1,6 @@
-package io.bluetrace.opentrace.idmanager
+package covid.trace.morocco.idmanager
-import io.bluetrace.opentrace.logging.CentralLog
+import covid.trace.morocco.logging.CentralLog
class TemporaryID(
val startTime: Long,
diff --git a/app/src/main/java/io/bluetrace/opentrace/logging/CentralLog.kt b/app/src/main/java/io/bluetrace/opentrace/logging/CentralLog.kt
index 8967043..978fad5 100644
--- a/app/src/main/java/io/bluetrace/opentrace/logging/CentralLog.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/logging/CentralLog.kt
@@ -1,9 +1,9 @@
-package io.bluetrace.opentrace.logging
+package covid.trace.morocco.logging
import android.os.Build
import android.os.PowerManager
import android.util.Log
-import io.bluetrace.opentrace.BuildConfig
+import covid.trace.morocco.BuildConfig
class CentralLog {
diff --git a/app/src/main/java/io/bluetrace/opentrace/logging/SDLog.kt b/app/src/main/java/io/bluetrace/opentrace/logging/SDLog.kt
index e0d1ac4..3e5edfc 100644
--- a/app/src/main/java/io/bluetrace/opentrace/logging/SDLog.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/logging/SDLog.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.logging
+package covid.trace.morocco.logging
import android.os.Environment
import java.io.BufferedWriter
@@ -10,10 +10,10 @@ import java.util.*
object SDLog {
- private const val APP_NAME = "OpenTrace"
+ private const val APP_NAME = "Wiqaytna"
private const val FOLDER = "SDLogging"
private val dateFormat = SimpleDateFormat("yyyyMMdd")
- private val timestampFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS")
+ private val timestampFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.FRANCE)
private var buffer = StringBuffer()
private var lastWrite = 0L
diff --git a/app/src/main/java/io/bluetrace/opentrace/notifications/NotificationTemplates.kt b/app/src/main/java/io/bluetrace/opentrace/notifications/NotificationTemplates.kt
index 8f84863..1c23bbd 100644
--- a/app/src/main/java/io/bluetrace/opentrace/notifications/NotificationTemplates.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/notifications/NotificationTemplates.kt
@@ -1,16 +1,18 @@
-package io.bluetrace.opentrace.notifications
+package covid.trace.morocco.notifications
import android.app.Notification
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
-import io.bluetrace.opentrace.MainActivity
-import io.bluetrace.opentrace.R
-import io.bluetrace.opentrace.onboarding.OnboardingActivity
-import io.bluetrace.opentrace.services.BluetoothMonitoringService.Companion.PENDING_ACTIVITY
-import io.bluetrace.opentrace.services.BluetoothMonitoringService.Companion.PENDING_WIZARD_REQ_CODE
+import covid.trace.morocco.BuildConfig
+import covid.trace.morocco.MainActivity
+import covid.trace.morocco.R
+import covid.trace.morocco.onboarding.OnboardingActivity
+import covid.trace.morocco.services.BluetoothMonitoringService.Companion.PENDING_ACTIVITY
+import covid.trace.morocco.services.BluetoothMonitoringService.Companion.PENDING_WIZARD_REQ_CODE
class NotificationTemplates {
@@ -42,14 +44,17 @@ class NotificationTemplates {
)
val builder = NotificationCompat.Builder(context, channel)
- .setContentTitle(context.getText(R.string.service_ok_title))
- .setContentText(context.getText(R.string.service_ok_body))
+ .setContentTitle(context.resources.getString(R.string.service_ok_title))
+ .setContentText(context.resources.getString(R.string.service_ok_body))
.setOngoing(true)
.setPriority(Notification.PRIORITY_LOW)
.setSmallIcon(R.drawable.ic_notification_service)
.setContentIntent(activityPendingIntent)
- .setTicker(context.getText(R.string.service_ok_body))
- .setStyle(NotificationCompat.BigTextStyle().bigText(context.getText(R.string.service_ok_body)))
+ .setTicker(context.resources.getString(R.string.service_ok_body))
+ .setStyle(
+ NotificationCompat.BigTextStyle()
+ .bigText(context.resources.getString(R.string.service_ok_body))
+ )
.setWhen(System.currentTimeMillis())
.setSound(null)
.setVibrate(null)
@@ -68,15 +73,15 @@ class NotificationTemplates {
)
val builder = NotificationCompat.Builder(context, channel)
- .setContentTitle(context.getText(R.string.service_not_ok_title))
- .setContentText(context.getText(R.string.service_not_ok_body))
+ .setContentText(context.resources.getString(R.string.service_not_ok_title))
+ .setContentTitle(context.resources.getString(R.string.service_not_ok_body))
.setOngoing(true)
.setPriority(Notification.PRIORITY_LOW)
.setSmallIcon(R.drawable.ic_notification_warning)
- .setTicker(context.getText(R.string.service_not_ok_body))
+ .setTicker(context.resources.getString(R.string.service_not_ok_body))
.addAction(
R.drawable.ic_notification_setting,
- context.getText(R.string.service_not_ok_action),
+ context.resources.getString(R.string.service_not_ok_action),
activityPendingIntent
)
.setContentIntent(activityPendingIntent)
@@ -87,5 +92,27 @@ class NotificationTemplates {
return builder.build()
}
+
+
+ fun diskFullWarningNotification(context: Context, channel: String){
+
+ val builder = NotificationCompat.Builder(context, channel)
+ .setContentText(context.resources.getString(R.string.notif_storage_problem_sub))
+ .setContentTitle(context.resources.getString(R.string.notif_storage_problem))
+ .setPriority(Notification.PRIORITY_DEFAULT)
+ .setSmallIcon(R.drawable.ic_notification_warning)
+ .setTicker(context.resources.getString(R.string.notif_storage_problem))
+ .setWhen(System.currentTimeMillis())
+ .setAutoCancel(true)
+ .setSound(null)
+ .setVibrate(null)
+ .setColor(ContextCompat.getColor(context, R.color.notification_tint))
+
+ val notif = builder.build()
+
+ with(NotificationManagerCompat.from(context)) {
+ notify(BuildConfig.ERROR_NOTIFICATION_ID, notif)
+ }
+ }
}
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/onboarding/OTPFragment.kt b/app/src/main/java/io/bluetrace/opentrace/onboarding/OTPFragment.kt
index 80e02b3..a0a02fe 100644
--- a/app/src/main/java/io/bluetrace/opentrace/onboarding/OTPFragment.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/onboarding/OTPFragment.kt
@@ -1,22 +1,21 @@
-package io.bluetrace.opentrace.onboarding
+package covid.trace.morocco.onboarding
import android.content.Context
-import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.CountDownTimer
import android.text.Editable
+import android.text.TextUtils
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.view.inputmethod.EditorInfo
-import androidx.core.text.HtmlCompat
-import kotlinx.android.synthetic.main.fragment_otp.*
-import io.bluetrace.opentrace.Preference
-import io.bluetrace.opentrace.R
-import io.bluetrace.opentrace.Utils
-import io.bluetrace.opentrace.logging.CentralLog
+import covid.trace.morocco.LocaleHelper
+import covid.trace.morocco.PreferencesHelper
+import covid.trace.morocco.R
+import covid.trace.morocco.Utils
+import covid.trace.morocco.logging.CentralLog
+import kotlinx.android.synthetic.main.fragment_otp_new.*
import kotlin.math.floor
private const val ARG_PARAM1 = "param1"
@@ -26,8 +25,6 @@ class OTPFragment : OnboardingFragmentInterface() {
private var param1: String? = null
private var param2: String? = null
private var listener: OnFragmentInteractionListener? = null
- private val TAG: String = "OTPFragment"
- private val COUNTDOWN_DURATION = 60L
private var stopWatch: CountDownTimer? = null
private lateinit var phoneNumber: String
@@ -53,7 +50,7 @@ class OTPFragment : OnboardingFragmentInterface() {
stopWatch?.cancel()
}
- override fun getButtonText(): String = "Verify"
+ override fun getButtonText(): String = resources.getString(R.string.verify)
override fun becomesVisible() {}
@@ -65,79 +62,173 @@ class OTPFragment : OnboardingFragmentInterface() {
onboardActivity.validateOTP(otp)
}
- override fun getProgressValue(): Int = 40
+ override fun getProgressValue(): Int = 2
- private fun getOtp(): String = simpleOTP.text.toString()
+ private fun getOtp(): String {
+ return otp1.text.toString() + otp2.text.toString() + otp3.text.toString() + otp4.text.toString() + otp5.text.toString() + otp6.text.toString()
+ }
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_otp, container, false)
+ return inflater.inflate(R.layout.fragment_otp_new, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- sent_to.text = HtmlCompat.fromHtml(
- getString(
- R.string.otp_sent,
- "<b>${Preference.getPhoneNumber(context!!)}</b>"
- ), HtmlCompat.FROM_HTML_MODE_LEGACY
- )
-
- wrongNumber.setOnClickListener {
- CentralLog.d(TAG, "Wrong number pressed")
- val onboardingActivity = activity as OnboardingActivity
- onboardingActivity.navigateToPreviousPage()
+
+ Utils.firebaseAnalyticsEvent(requireContext(), "otp_screen", "3", "Onboarding third screen")
+
+ resendCode.isEnabled = false
+
+ editTextsListeners()
+
+ val number = PreferencesHelper.getStringPreference("number", "")
+ if (!TextUtils.isEmpty(number)) {
+ CentralLog.d(TAG, "retreived a saved number $number")
+ phoneNumber = number
+ }
+
+ language.setOnClickListener {
+ Utils.firebaseAnalyticsEvent(
+ requireContext(),
+ "otp_screen_change_language",
+ "21",
+ "Onboarding third screen"
+ )
+
+ LocaleHelper.getInstance().switchLocale()
+ requireActivity().recreate()
}
resendCode.setOnClickListener {
- CentralLog.d(TAG, "resend pressed")
+ CentralLog.d(TAG, "resend pressed sent to $phoneNumber")
+
+ Utils.firebaseAnalyticsEvent(
+ requireContext(),
+ "otp_screen_resend_otp",
+ "18",
+ "Onboarding third screen resend otp"
+ )
+
val onboardingActivity = activity as OnboardingActivity
onboardingActivity.resendCode(phoneNumber)
resetTimer()
startTimer()
}
+ }
- simpleOTP.addTextChangedListener(object : TextWatcher {
- override fun afterTextChanged(s: Editable) {}
- override fun beforeTextChanged(
- s: CharSequence, start: Int,
- count: Int, after: Int
- ) {
- }
-
- override fun onTextChanged(
- s: CharSequence, start: Int,
- before: Int, count: Int
- ) {
- onError("")
- if (s.length == 6) {
- Utils.hideKeyboardFrom(view.context, view)
- }
+ private fun editTextsListeners() {
+
+ otp1.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+
+ }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+ if (s?.length == 1) otp2.requestFocus()
+ }
+
})
- simpleOTP.setOnEditorActionListener { _, actionId, _ ->
- if (actionId == EditorInfo.IME_ACTION_GO) {
- Utils.hideKeyboardFrom(view.context, view)
- val otp = getOtp()
- val onboardActivity = context as OnboardingActivity
- onboardActivity.validateOTP(otp)
- true
- } else {
- false
+ otp2.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+
}
- }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
+ }
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+ if (s?.length == 1) otp3.requestFocus()
+ if (s?.length == 0) otp1.requestFocus()
+ }
+ })
+
+ otp3.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+
+ }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
+ }
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+ if (s?.length == 1) otp4.requestFocus()
+ if (s?.length == 0) otp2.requestFocus()
+ }
+ })
+
+ otp4.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+
+ }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
+ }
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+ if (s?.length == 1) otp5.requestFocus()
+ if (s?.length == 0) otp3.requestFocus()
+ }
+ })
+
+ otp5.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+
+ }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
+ }
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+ if (s?.length == 1) otp6.requestFocus()
+ if (s?.length == 0) otp4.requestFocus()
+ }
+ })
+
+ otp6.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+
+ }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
+ }
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+ if (s?.length == 0) otp5.requestFocus()
+ if (getOtp().length == 6) {
+ Utils.hideKeyboardFrom(view!!.context, view!!)
+ }
+ }
+ })
}
override fun onUpdatePhoneNumber(num: String) {
CentralLog.d(TAG, "onUpdatePhoneNumber $num")
- sent_to.text = HtmlCompat.fromHtml(
- getString(R.string.otp_sent, "<b>${num}</b>"),
- HtmlCompat.FROM_HTML_MODE_LEGACY
- )
phoneNumber = num
+ PreferencesHelper.setPreference("number", phoneNumber)
+ }
+
+ override fun onError(error: String) {
+ if (isDetached) return
+
+ Utils.firebaseAnalyticsEvent(requireContext(), "Otp_error", "15", error)
+ tv_error?.text = error
+ tv_error?.visibility = View.VISIBLE
+ }
+
+ override fun onAttach(context: Context) {
+ super.onAttach(context)
+ if (context is OnFragmentInteractionListener) {
+ listener = context
+ } else {
+ throw RuntimeException("$context must implement OnFragmentInteractionListener")
+ }
}
private fun startTimer() {
@@ -154,43 +245,31 @@ class OTPFragment : OnboardingFragmentInterface() {
finalNumberOfSecondsString = "$numberOfSecondsInt"
}
- timer?.text = "$numberOfMinsInt:$finalNumberOfSecondsString"
+// timer?.text = resources.getString(R.string.otp_expiry)+" $numberOfMinsInt:$finalNumberOfSecondsString"
}
override fun onFinish() {
- timer?.text = "0:00"
+// timer?.text = resources.getString(R.string.otp_expiry)+" 0:00"
resendCode.isEnabled = true
- resendCode.setTextColor(Color.parseColor("#003DB5"))
}
}
stopWatch?.start()
- resendCode.isEnabled = false
- resendCode.setTextColor(Color.parseColor("#DDDDDD"))
+ resendCode?.isEnabled = false
}
- override fun onError(error: String) {
- tv_error.text = error
- }
-
- override fun onAttach(context: Context) {
- super.onAttach(context)
- if (context is OnFragmentInteractionListener) {
- listener = context
- } else {
- throw RuntimeException(context.toString() + " must implement OnFragmentInteractionListener")
- }
-
+ override fun onDestroy() {
+ super.onDestroy()
+ stopWatch?.cancel()
}
override fun onDetach() {
super.onDetach()
listener = null
-
}
- override fun onDestroy() {
- super.onDestroy()
- stopWatch?.cancel()
+ companion object {
+ const val COUNTDOWN_DURATION = 120L
+ const val TAG: String = "OTPFragment"
}
interface OnFragmentInteractionListener {
diff --git a/app/src/main/java/io/bluetrace/opentrace/onboarding/OnboardingActivity.kt b/app/src/main/java/io/bluetrace/opentrace/onboarding/OnboardingActivity.kt
index 60d134a..7a12561 100644
--- a/app/src/main/java/io/bluetrace/opentrace/onboarding/OnboardingActivity.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/onboarding/OnboardingActivity.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.onboarding
+package covid.trace.morocco.onboarding
import android.Manifest
import android.app.Activity
@@ -17,177 +17,99 @@ import android.os.PowerManager
import android.provider.Settings
import android.text.TextUtils
import android.view.View
+import android.view.ViewGroup
+import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
-import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import androidx.viewpager.widget.ViewPager
import com.google.android.gms.tasks.Task
-import com.google.firebase.FirebaseException
-import com.google.firebase.FirebaseTooManyRequestsException
-import com.google.firebase.auth.*
+import com.google.firebase.analytics.FirebaseAnalytics
+import com.google.firebase.auth.FirebaseAuth
+import com.google.firebase.auth.FirebaseUser
+import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.functions.FirebaseFunctions
import com.google.firebase.functions.HttpsCallableResult
+import covid.trace.morocco.*
+import covid.trace.morocco.WiqaytnaApp.Companion.firebaseToken
+import covid.trace.morocco.WiqaytnaApp.Companion.uid
+import covid.trace.morocco.base.BaseFragmentActivity
+import covid.trace.morocco.idmanager.TempIDManager
+import covid.trace.morocco.logging.CentralLog
+import covid.trace.morocco.services.BluetoothMonitoringService
import kotlinx.android.synthetic.main.activity_onboarding.*
+import kotlinx.android.synthetic.main.fragment_otp_new.*
import pub.devrel.easypermissions.AfterPermissionGranted
import pub.devrel.easypermissions.EasyPermissions
-import io.bluetrace.opentrace.BuildConfig
-import io.bluetrace.opentrace.Preference
-import io.bluetrace.opentrace.R
-import io.bluetrace.opentrace.Utils
-import io.bluetrace.opentrace.idmanager.TempIDManager
-import io.bluetrace.opentrace.logging.CentralLog
-import io.bluetrace.opentrace.services.BluetoothMonitoringService
-import java.util.concurrent.TimeUnit
-import kotlin.properties.Delegates
private const val REQUEST_ENABLE_BT = 123
private const val PERMISSION_REQUEST_ACCESS_LOCATION = 456
private const val BATTERY_OPTIMISER = 789
-class OnboardingActivity : FragmentActivity(),
+class OnboardingActivity : BaseFragmentActivity(),
SetupFragment.OnFragmentInteractionListener,
- SetupCompleteFragment.OnFragmentInteractionListener,
RegisterNumberFragment.OnFragmentInteractionListener,
- OTPFragment.OnFragmentInteractionListener,
- TOUFragment.OnFragmentInteractionListener {
+ OTPFragment.OnFragmentInteractionListener {
+
+ // [START declare_auth]
+ //private var uid: String = ""
+ private lateinit var auth: FirebaseAuth
+ // [END declare_auth]
+
+ private var crashlytics = FirebaseCrashlytics.getInstance()
private var TAG: String = "OnboardingActivity"
- private var pagerAdapter: ScreenSlidePagerAdapter? = null
+ private lateinit var pagerAdapter: ScreenSlidePagerAdapter
private var bleSupported = false
private var speedUp = false
private var resendingCode = false
private val functions = FirebaseFunctions.getInstance(BuildConfig.FIREBASE_REGION)
- private var credential: PhoneAuthCredential by Delegates.notNull()
- private var verificationId: String by Delegates.notNull()
- private var resendToken: PhoneAuthProvider.ForceResendingToken by Delegates.notNull()
- private val phoneNumberVerificationCallbacks =
- object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
-
- override fun onVerificationCompleted(receivedCredential: PhoneAuthCredential) {
- // This callback will be invoked in two situations:
- // 1 - Instant verification. In some cases the phone number can be instantly
- // verified without needing to send or enter a verification code.
- // 2 - Auto-retrieval. On some devices Google Play services can automatically
- // detect the incoming verification SMS and perform verification without
- // user action.
- CentralLog.d(TAG, "onVerificationCompleted: $receivedCredential")
- credential = receivedCredential
- signInWithPhoneAuthCredential(credential)
- speedUp = true
- }
-
- override fun onVerificationFailed(e: FirebaseException) {
- if (e is FirebaseAuthInvalidCredentialsException) {
- CentralLog.d(TAG, "FirebaseAuthInvalidCredentialsException", e)
-// alertDialog(getString(R.string.verification_failed))
- updatePhoneNumberError(getString(R.string.invalid_number))
- } else if (e is FirebaseTooManyRequestsException) {
- CentralLog.d(TAG, "FirebaseTooManyRequestsException", e)
- alertDialog(getString(R.string.too_many_requests))
- }
-
- enableFragmentbutton()
-
- CentralLog.d(TAG, "On Verification failure: ${e.message}")
- onboardingActivityLoadingProgressBarFrame.visibility = View.GONE
- }
-
- override fun onCodeSent(
- receivedVerificationId: String,
- token: PhoneAuthProvider.ForceResendingToken
- ) {
- // The SMS verification code has been sent to the provided phone number, we
- // now need to ask the user to enter the code and then construct a credential
- // by combining the code with a verification ID.
-
- verificationId = receivedVerificationId
- resendToken = token
-
- CentralLog.d(TAG, "onCodeSent: $receivedVerificationId")
- if (resendingCode) {
+ private fun getTemporaryID(): Task<HttpsCallableResult> {
+ return TempIDManager.getTemporaryIDs(this, functions)
+ .addOnCompleteListener {
+ if (!isFinishing) {
+ CentralLog.d(TAG, "Retrieved Temporary ID successfully")
onboardingActivityLoadingProgressBarFrame.visibility = View.GONE
- } else {
- navigateToNextPage()
+ navigateTo(pager.currentItem + 2)
+ Preference.putHandShakePin(
+ WiqaytnaApp.AppContext,
+ uid.substring(0, 5)
+ )
}
-
- }
- }
-
- private fun enableFragmentbutton() {
- var interfaceObject: OnboardingFragmentInterface? = pagerAdapter?.getItem(pager.currentItem)
- interfaceObject?.enableButton()
- }
-
- private fun alertDialog(desc: String?) {
- val dialogBuilder = AlertDialog.Builder(this)
- dialogBuilder.setMessage(desc)
- .setCancelable(false)
- .setPositiveButton(
- getString(R.string.ok),
- DialogInterface.OnClickListener { dialog, id ->
- dialog.dismiss()
- })
-
- val alert = dialogBuilder.create()
- alert.show()
- }
-
- private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
- FirebaseAuth.getInstance().signInWithCredential(credential)
- .addOnCompleteListener(this) { task ->
- if (task.isSuccessful) {
- // Sign in success, update UI with the signed-in user's information
- CentralLog.d(TAG, "signInWithCredential:success")
-
- val user = task.result?.user
-
- if (BluetoothMonitoringService.broadcastMessage == null || TempIDManager.needToUpdate(
- applicationContext
- )
- ) {
- getTemporaryID()
- }
- } else {
- // Sign in failed, display a message and update the UI
- CentralLog.d(TAG, "signInWithCredential:failure", task.exception)
- if (task.exception is FirebaseAuthInvalidCredentialsException) {
- // The verification code entered was invalid
- onboardingActivityLoadingProgressBarFrame.visibility = View.GONE
- updateOTPError(getString(R.string.invalid_otp))
- } else if (task.exception is FirebaseAuthInvalidUserException) {
- alertDialog(getString(R.string.invalid_user))
- }
+ }.addOnFailureListener { exception ->
+ crashlytics.recordException(exception)
+ crashlytics.setCustomKey("error", "Couldn't Retrieve Temporary ID")
+ if (!isFinishing) {
+ CentralLog.d(TAG, "Couldn't Retrieve Temporary ID")
onboardingActivityLoadingProgressBarFrame.visibility = View.GONE
}
}
}
- private fun getTemporaryID(): Task<HttpsCallableResult> {
- return TempIDManager.getTemporaryIDs(this, functions)
- .addOnCompleteListener {
- CentralLog.d(TAG, "Retrieved Temporary ID successfully")
- Utils.getHandShakePin(this, functions).addOnCompleteListener {
- if (it.isSuccessful) {
- CentralLog.d(TAG, "Retrieved HandShakePin successfully")
- navigateToNextPage()
- } else {
- CentralLog.e(
- TAG,
- "Failed to retrieve HandShakePin ${it.exception?.message}"
- )
- updateOTPError(getString(R.string.verification_failed))
- onboardingActivityLoadingProgressBarFrame.visibility = View.GONE
- }
- }
+ private var mIsOpenSetting = false
+ private var mIsResetup = false
- }
+ // [START on_start_check_user]
+ public override fun onStart() {
+ super.onStart()
+ // Check if user is signed in (non-null) and update UI accordingly.
+ val currentUser = auth.currentUser
+ updateUI(currentUser)
}
- private var mIsOpenSetting = false
- private var mIsResetup = false
+ // [END on_start_check_user]
+ private fun updateUI(user: FirebaseUser?) {
+ val isSignedIn = user != null
+ // Status text
+ if (isSignedIn) {
+ uid = user!!.uid
+ CentralLog.i(TAG, uid)
+ } else {
+ uid = ""
+ }
+ }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -195,6 +117,11 @@ class OnboardingActivity : FragmentActivity(),
pagerAdapter = ScreenSlidePagerAdapter(supportFragmentManager)
pager.adapter = pagerAdapter
+ // [START initialize_auth]
+ // Initialize Firebase Auth
+ auth = FirebaseAuth.getInstance()
+ // [END initialize_auth]
+
tabDots.setupWithViewPager(pager, true)
pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
@@ -213,7 +140,7 @@ class OnboardingActivity : FragmentActivity(),
override fun onPageSelected(position: Int) {
CentralLog.d(TAG, "position: $position")
val onboardingFragment: OnboardingFragmentInterface =
- pagerAdapter!!.getItem(position)
+ pagerAdapter.getItem(position)
onboardingFragment.becomesVisible()
when (position) {
0 -> {
@@ -244,7 +171,6 @@ class OnboardingActivity : FragmentActivity(),
)
}
}
-
}
})
@@ -255,10 +181,10 @@ class OnboardingActivity : FragmentActivity(),
val extras = intent.extras
if (extras != null) {
mIsResetup = true
- var page = extras.getInt("page", 0)
+ val page = extras.getInt("page", 0)
navigateTo(page)
} else {
- var checkPoint = Preference.getCheckpoint(this)
+ val checkPoint = Preference.getCheckpoint(this)
navigateTo(checkPoint)
}
}
@@ -271,6 +197,14 @@ class OnboardingActivity : FragmentActivity(),
}
override fun onBackPressed() {
+
+ // come back to OTP from Setup
+ if (pager.currentItem == 3) {
+ pager.currentItem = pager.currentItem - 2
+ pagerAdapter.notifyDataSetChanged()
+ return
+ }
+
if (pager.currentItem > 0 && pager.currentItem != 2) {
navigateToPreviousPage()
return
@@ -307,7 +241,7 @@ class OnboardingActivity : FragmentActivity(),
fun setupPermissionsAndSettings() {
CentralLog.d(TAG, "[setupPermissionsAndSettings]")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- var perms = Utils.getRequiredPermissions()
+ val perms = Utils.getRequiredPermissions()
if (EasyPermissions.hasPermissions(this, *perms)) {
// Already have permission, do the thing
@@ -315,17 +249,33 @@ class OnboardingActivity : FragmentActivity(),
excludeFromBatteryOptimization()
} else {
// Do not have permissions, request them now
- EasyPermissions.requestPermissions(
- this, getString(R.string.permission_location_rationale),
- PERMISSION_REQUEST_ACCESS_LOCATION, *perms
- )
+ if (!isFinishing) {
+ EasyPermissions.requestPermissions(
+ this, getString(R.string.permission_location_rationale),
+ PERMISSION_REQUEST_ACCESS_LOCATION, *perms
+ )
+ }
}
} else {
initBluetooth()
- navigateToNextPage()
+ goToHomeScreen()
}
}
+ private fun goToHomeScreen() {
+ val firebaseAnalytics = FirebaseAnalytics.getInstance(baseContext)
+ Preference.putCheckpoint(baseContext, 0)
+ Preference.putIsOnBoarded(baseContext, true)
+ val bundle = Bundle()
+ bundle.putString(FirebaseAnalytics.Param.ITEM_ID, "P1234")
+ bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, "Onboard Completed for Android Device")
+ firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SIGN_UP, bundle)
+ val intent = Intent(this, MainActivity::class.java)
+ intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
+ startActivity(intent)
+ finish()
+ }
+
private fun initBluetooth() {
checkBLESupport()
}
@@ -365,11 +315,11 @@ class OnboardingActivity : FragmentActivity(),
)
} else {
//no way of handling battery optimizer
- navigateToNextPage()
+ goToHomeScreen()
}
} else {
CentralLog.d(TAG, "On Battery Optimization whitelist")
- navigateToNextPage()
+ goToHomeScreen()
}
}
}
@@ -379,17 +329,20 @@ class OnboardingActivity : FragmentActivity(),
CentralLog.d(TAG, "requestCode $requestCode resultCode $resultCode")
if (requestCode == REQUEST_ENABLE_BT) {
if (resultCode == Activity.RESULT_CANCELED) {
- finish()
+ CentralLog.d(TAG, "request to enable bluetooth canceled")
+ Toast.makeText(
+ baseContext,
+ resources.getString(R.string.setup_app_permission),
+ Toast.LENGTH_LONG
+ ).show()
return
} else {
setupPermissionsAndSettings()
}
} else if (requestCode == BATTERY_OPTIMISER) {
if (resultCode != Activity.RESULT_CANCELED) {
-
-// Utils.keepServicesInChineseDevices(this)
Handler().postDelayed({
- navigateToNextPage()
+ goToHomeScreen()
}, 1000)
}
}
@@ -405,11 +358,11 @@ class OnboardingActivity : FragmentActivity(),
CentralLog.d(TAG, "[onRequestPermissionsResult] requestCode $requestCode")
when (requestCode) {
PERMISSION_REQUEST_ACCESS_LOCATION -> {
- for (x in 0 until permissions.size) {
- var permission = permissions[x]
+ for (x in permissions.indices) {
+ val permission = permissions[x]
if (grantResults[x] == PackageManager.PERMISSION_DENIED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- var showRationale = shouldShowRequestPermissionRationale(permission)
+ val showRationale = shouldShowRequestPermissionRationale(permission)
if (!showRationale) {
// build alert dialog
@@ -421,13 +374,13 @@ class OnboardingActivity : FragmentActivity(),
// positive button text and action
.setPositiveButton(
getString(R.string.ok),
- DialogInterface.OnClickListener { dialog, id ->
+ DialogInterface.OnClickListener { _, _ ->
CentralLog.d(TAG, "user also CHECKED never ask again")
mIsOpenSetting = true
- var intent =
+ val intent =
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- var uri: Uri =
+ val uri: Uri =
Uri.fromParts("package", packageName, null)
intent.data = uri
startActivity(intent)
@@ -436,16 +389,9 @@ class OnboardingActivity : FragmentActivity(),
// negative button text and action
.setNegativeButton(
getString(R.string.cancel),
- DialogInterface.OnClickListener { dialog, id ->
+ DialogInterface.OnClickListener { dialog, _ ->
dialog.cancel()
- })
-
- // create dialog box
- val alert = dialogBuilder.create()
-
- // show alert dialog
- alert.show()
-
+ }).show()
} else if (Manifest.permission.WRITE_CONTACTS.equals(permission)) {
CentralLog.d(TAG, "user did not CHECKED never ask again")
} else {
@@ -460,54 +406,111 @@ class OnboardingActivity : FragmentActivity(),
}
}
- fun navigateToNextPage() {
+ private fun navigateToNextPage() {
CentralLog.d(TAG, "Navigating to next page")
onboardingActivityLoadingProgressBarFrame.visibility = View.GONE
-
if (!speedUp) {
pager.currentItem = pager.currentItem + 1
- pagerAdapter!!.notifyDataSetChanged()
+ pagerAdapter.notifyDataSetChanged()
} else {
pager.currentItem = pager.currentItem + 2
- pagerAdapter!!.notifyDataSetChanged()
+ pagerAdapter.notifyDataSetChanged()
speedUp = false
}
}
- fun navigateToPreviousPage() {
+ private fun navigateToPreviousPage() {
CentralLog.d(TAG, "Navigating to previous page")
if (mIsResetup) {
if (pager.currentItem >= 4) {
pager.currentItem = pager.currentItem - 1
- pagerAdapter!!.notifyDataSetChanged()
+ pagerAdapter.notifyDataSetChanged()
} else {
finish()
}
} else {
pager.currentItem = pager.currentItem - 1
- pagerAdapter!!.notifyDataSetChanged()
+ pagerAdapter.notifyDataSetChanged()
}
}
private fun navigateTo(page: Int) {
CentralLog.d(TAG, "Navigating to page")
pager.currentItem = page
- pagerAdapter!!.notifyDataSetChanged()
+ pagerAdapter.notifyDataSetChanged()
}
fun requestForOTP(phoneNumber: String) {
onboardingActivityLoadingProgressBarFrame.visibility = View.VISIBLE
speedUp = false
resendingCode = false
- PhoneAuthProvider
- .getInstance()
- .verifyPhoneNumber(
- phoneNumber,
- 60,
- TimeUnit.SECONDS, // Unit of timeout
- this, // Activity (for callback binding)
- phoneNumberVerificationCallbacks
- )
+ auth.signInAnonymously()
+ .addOnCompleteListener(this) { task ->
+ if (task.isSuccessful) {
+ // Sign in success, update UI with the signed-in user's information
+ CentralLog.d(TAG, "signInAnonymously:success")
+ val user = auth.currentUser
+ sendPostRequest(user!!.uid, phoneNumber)
+ .addOnSuccessListener {
+ navigateToNextPage()
+ updateUI(user)
+ }
+ .addOnFailureListener { exception ->
+ crashlytics.recordException(exception)
+ crashlytics.setCustomKey("error", "getOTPCode:failure")
+ crashlytics.setCustomKey("phone", phoneNumber)
+
+ CentralLog.d(TAG, "${exception.message}")
+ onboardingActivityLoadingProgressBarFrame.visibility = View.GONE
+ CentralLog.w("getOTPCode:failure", task.exception.toString())
+ Toast.makeText(
+ baseContext, resources.getString(R.string.server_problem),
+ Toast.LENGTH_SHORT
+ ).show()
+ updateUI(null)
+ }
+ } else {
+ // If sign in fails, display a message to the user.
+ onboardingActivityLoadingProgressBarFrame.visibility = View.GONE
+ CentralLog.w("signInAnonymously:failure", task.exception.toString())
+ task.exception?.let {
+ crashlytics.recordException(it)
+ crashlytics.setCustomKey("error", "signInAnonymously failed")
+ }
+
+ Toast.makeText(
+ baseContext, resources.getString(R.string.server_problem),
+ Toast.LENGTH_SHORT
+ ).show()
+ updateUI(null)
+ }
+ }
+ }
+
+ private fun sendPostRequest(uid: String, phoneNumber: String): Task<HttpsCallableResult> {
+
+ val data = hashMapOf(
+ "phoneNumber" to phoneNumber,
+ "token" to firebaseToken,
+ "os" to "ANDROID"
+ )
+ val functions = FirebaseFunctions.getInstance(BuildConfig.FIREBASE_REGION)
+ return functions
+ .getHttpsCallable("getOTPCode")
+ .call(data)
+ }
+
+ private fun resendPostRequest(uid: String, phoneNumber: String): Task<HttpsCallableResult> {
+
+ val data = hashMapOf(
+ "phoneNumber" to phoneNumber,
+ "token" to firebaseToken,
+ "os" to "ANDROID"
+ )
+ val functions = FirebaseFunctions.getInstance(BuildConfig.FIREBASE_REGION)
+ return functions
+ .getHttpsCallable("resendOTP")
+ .call(data)
}
fun validateOTP(otp: String) {
@@ -517,39 +520,78 @@ class OnboardingActivity : FragmentActivity(),
}
onboardingActivityLoadingProgressBarFrame.visibility = View.VISIBLE
- credential = PhoneAuthProvider.getCredential(
- verificationId,
- otp
+ val data = hashMapOf(
+ "OTP" to otp
)
- signInWithPhoneAuthCredential(credential)
+ val functions = FirebaseFunctions.getInstance(BuildConfig.FIREBASE_REGION)
+ functions
+ .getHttpsCallable("verifyOTP")
+ .call(data)
+ .addOnFailureListener { exception ->
+ crashlytics.recordException(exception)
+ crashlytics.setCustomKey("error", "verifyOTP Failed")
+ if (!isFinishing) {
+ CentralLog.e("FF", exception.toString())
+ onboardingActivityLoadingProgressBarFrame.visibility = View.GONE
+ updateOTPError(getString(R.string.unknown_error))
+ }
+ }
+ .addOnSuccessListener {
+ if (it.data.toString() == "true") {
+ CentralLog.d("VerifyOTP", "Success")
+ tv_error.visibility = View.INVISIBLE
+ if (BluetoothMonitoringService.broadcastMessage == null || TempIDManager.needToUpdate(
+ applicationContext
+ )
+ ) {
+ getTemporaryID()
+ } else {
+ if (!isFinishing) {
+ CentralLog.d(TAG, "Retrieved Temporary ID successfully")
+ onboardingActivityLoadingProgressBarFrame.visibility = View.GONE
+ navigateTo(pager.currentItem + 2)
+ Preference.putHandShakePin(
+ WiqaytnaApp.AppContext,
+ uid.substring(0, 5)
+ )
+ }
+ }
+ } else {
+ if (!isFinishing) {
+ updateOTPError(getString(R.string.invalid_otp))
+ onboardingActivityLoadingProgressBarFrame.visibility = View.GONE
+ CentralLog.d("VERIFYOTP", "VERIFICATION FALSE")
+ }
+ }
+ }
}
fun resendCode(phoneNumber: String) {
onboardingActivityLoadingProgressBarFrame.visibility = View.VISIBLE
speedUp = false
resendingCode = true
- PhoneAuthProvider.getInstance().verifyPhoneNumber(
- phoneNumber, // Phone number to verify
- 60, // Timeout duration
- TimeUnit.SECONDS, // Unit of timeout
- this, // Activity (for callback binding)
- phoneNumberVerificationCallbacks, // OnVerificationStateChangedCallbacks
- resendToken
- ) // ForceResendingToken from callbacks
+ val user = auth.currentUser
+ resendPostRequest(user!!.uid, phoneNumber).addOnSuccessListener {
+ onboardingActivityLoadingProgressBarFrame.visibility = View.GONE
+ }.addOnFailureListener { exception ->
+ crashlytics.recordException(exception)
+ crashlytics.setCustomKey("error", "couldn't resend the OTP")
+ crashlytics.setCustomKey("phone", phoneNumber)
+ Toast.makeText(
+ baseContext, resources.getString(R.string.server_problem),
+ Toast.LENGTH_SHORT
+ ).show()
+ onboardingActivityLoadingProgressBarFrame.visibility = View.GONE
+ }
}
fun updatePhoneNumber(num: String) {
- val onboardingFragment: OnboardingFragmentInterface = pagerAdapter!!.getItem(1)
+ val onboardingFragment: OnboardingFragmentInterface = pagerAdapter.getItem(1)
onboardingFragment.onUpdatePhoneNumber(num)
}
- fun updatePhoneNumberError(error: String) {
- val registerNumberFragment: OnboardingFragmentInterface = pagerAdapter!!.getItem(0)
- registerNumberFragment.onError(error)
- }
-
private fun updateOTPError(error: String) {
- val onboardingFragment: OnboardingFragmentInterface = pagerAdapter!!.getItem(1)
+ val onboardingFragment: OnboardingFragmentInterface = pagerAdapter.getItem(1)
onboardingFragment.onError(error)
}
@@ -558,29 +600,36 @@ class OnboardingActivity : FragmentActivity(),
}
private inner class ScreenSlidePagerAdapter(fm: FragmentManager) :
- FragmentStatePagerAdapter(fm) {
+ FragmentStatePagerAdapter(
+ fm,
+ BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
+ ) {
val fragmentMap: MutableMap<Int, OnboardingFragmentInterface> = HashMap()
override fun getCount(): Int = 5
override fun getItem(position: Int): OnboardingFragmentInterface {
- return fragmentMap.getOrPut(position, { createFragAtIndex(position) })
+ return fragmentMap.getOrPut(position) { createFragAtIndex(position) }
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val fragment = super.instantiateItem(container, position) as OnboardingFragmentInterface
+ fragmentMap[position] = fragment
+ return fragment
}
private fun createFragAtIndex(index: Int): OnboardingFragmentInterface {
return when (index) {
0 -> return RegisterNumberFragment()
1 -> return OTPFragment()
- 2 -> return TOUFragment()
3 -> return SetupFragment()
- 4 -> return SetupCompleteFragment()
else -> {
RegisterNumberFragment()
}
}
}
-
}
}
+
diff --git a/app/src/main/java/io/bluetrace/opentrace/onboarding/OnboardingFragmentInterface.kt b/app/src/main/java/io/bluetrace/opentrace/onboarding/OnboardingFragmentInterface.kt
index c1225f3..172d385 100644
--- a/app/src/main/java/io/bluetrace/opentrace/onboarding/OnboardingFragmentInterface.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/onboarding/OnboardingFragmentInterface.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.onboarding
+package covid.trace.morocco.onboarding
import android.os.Bundle
import android.view.View
@@ -41,7 +41,7 @@ abstract class OnboardingFragmentInterface : Fragment() {
}
private fun setupProgress() {
- pbProgress.progress = getProgressValue()
+ pbProgress.currentProgressDot = getProgressValue()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -49,6 +49,4 @@ abstract class OnboardingFragmentInterface : Fragment() {
setupButton()
setupProgress()
}
-
-
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/onboarding/PreOnboardingActivity.kt b/app/src/main/java/io/bluetrace/opentrace/onboarding/PreOnboardingActivity.kt
index 07e7652..6410d1b 100644
--- a/app/src/main/java/io/bluetrace/opentrace/onboarding/PreOnboardingActivity.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/onboarding/PreOnboardingActivity.kt
@@ -1,18 +1,32 @@
-package io.bluetrace.opentrace.onboarding
+package covid.trace.morocco.onboarding
import android.content.Intent
import android.os.Bundle
-import androidx.fragment.app.FragmentActivity
+import covid.trace.morocco.LocaleHelper
+import covid.trace.morocco.R
+import covid.trace.morocco.Utils
+import covid.trace.morocco.base.BaseFragmentActivity
import kotlinx.android.synthetic.main.main_activity_onboarding.*
-import io.bluetrace.opentrace.R
-class PreOnboardingActivity : FragmentActivity() {
+class PreOnboardingActivity : BaseFragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity_onboarding)
+
+ Utils.firebaseAnalyticsEvent(baseContext, "first_screen", "1", "Onboarding first screen")
+
btn_onboardingStart.setOnClickListener {
- var intent = Intent(this, HowItWorksActivity::class.java)
- startActivity(intent)
+ startActivity(Intent(this, OnboardingActivity::class.java))
+ }
+
+ language.setOnClickListener {
+ Utils.firebaseAnalyticsEvent(baseContext, "first_screen_change_language", "19", "Onboarding third screen resend otp")
+ LocaleHelper.getInstance().switchLocale()
+ recreate()
+ }
+
+ tou.setOnClickListener {
+ startActivity(Intent(this, TouActivity::class.java))
}
}
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/onboarding/RegisterNumberFragment.kt b/app/src/main/java/io/bluetrace/opentrace/onboarding/RegisterNumberFragment.kt
index db5b076..5a364eb 100644
--- a/app/src/main/java/io/bluetrace/opentrace/onboarding/RegisterNumberFragment.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/onboarding/RegisterNumberFragment.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.onboarding
+package covid.trace.morocco.onboarding
import android.content.Context
import android.net.Uri
@@ -9,20 +9,20 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
-import kotlinx.android.synthetic.main.fragment_register_number.*
-import io.bluetrace.opentrace.Preference
-import io.bluetrace.opentrace.R
-import io.bluetrace.opentrace.TracerApp
-import io.bluetrace.opentrace.Utils
-import io.bluetrace.opentrace.logging.CentralLog
+import covid.trace.morocco.*
+import covid.trace.morocco.WiqaytnaApp.Companion.phoneNumber
+import covid.trace.morocco.logging.CentralLog
+import kotlinx.android.synthetic.main.fragment_register_number_new.*
class RegisterNumberFragment : OnboardingFragmentInterface() {
private var listener: OnFragmentInteractionListener? = null
private val TAG: String = "RegisterNumberFragment"
+ private val countryCode = "+212"
+ private val pattern = "[0]*[6-7][0-9]{8}".toRegex()
private var mView: View? = null
- override fun getButtonText(): String = "Get OTP"
+ override fun getButtonText(): String = resources.getString(R.string.get_otp)
override fun becomesVisible() {
CentralLog.d(TAG, "becomes visible")
@@ -32,10 +32,15 @@ class RegisterNumberFragment : OnboardingFragmentInterface() {
override fun onButtonClick(buttonView: View) {
CentralLog.d(TAG, "OnButtonClick")
- disableButtonAndRequestOTP()
+ if (pattern.matches(phone_number.text.toString())) {
+ disableButtonAndRequestOTP()
+ } else {
+ phone_number_error.visibility = View.VISIBLE
+ }
+
}
- override fun getProgressValue(): Int = 20
+ override fun getProgressValue(): Int = 1
private fun disableButtonAndRequestOTP() {
var myactivity = this as OnboardingFragmentInterface
@@ -46,14 +51,24 @@ class RegisterNumberFragment : OnboardingFragmentInterface() {
private fun requestOTP() {
mView?.let { view ->
phone_number_error.visibility = View.INVISIBLE
- var numberText = phone_number.text.toString().trim()
+ var numberText: String
- val fullNumber = "${country_code.selectedCountryCodeWithPlus}${numberText}"
+ if (phone_number.text.toString().length == 10) {
+ numberText = phone_number.text.toString().substring(1)
+ CentralLog.d("used number", "$numberText")
+ } else {
+ numberText = phone_number.text.toString()
+ CentralLog.d("used number", "$numberText")
+ }
+ val fullNumber = "$countryCode${numberText}"
+ phoneNumber = fullNumber
CentralLog.d(TAG, "The value retrieved: ${fullNumber}")
val onboardActivity = context as OnboardingActivity
- Preference.putPhoneNumber(TracerApp.AppContext, fullNumber)
+ Preference.putPhoneNumber(
+ WiqaytnaApp.AppContext, fullNumber
+ )
onboardActivity.updatePhoneNumber(fullNumber)
onboardActivity.requestForOTP(fullNumber)
}
@@ -62,6 +77,17 @@ class RegisterNumberFragment : OnboardingFragmentInterface() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
CentralLog.i(TAG, "View created")
+
+ context?.let{
+ Utils.firebaseAnalyticsEvent(
+ it,
+ "phone_number_screen",
+ "2",
+ "Onboarding second screen"
+ )
+ }
+
+
mView = view
phone_number.addTextChangedListener(object : TextWatcher {
@@ -83,12 +109,30 @@ class RegisterNumberFragment : OnboardingFragmentInterface() {
phone_number.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_GO) {
Utils.hideKeyboardFrom(view.context, view)
- disableButtonAndRequestOTP()
+ if (pattern.matches(phone_number.text.toString())) {
+ disableButtonAndRequestOTP()
+ } else {
+ phone_number_error.visibility = View.VISIBLE
+ }
true
} else {
false
}
}
+
+ language.setOnClickListener {
+ context?.let{
+ Utils.firebaseAnalyticsEvent(
+ it,
+ "phone_number_screen_change_language",
+ "20",
+ "Onboarding second screen"
+ )
+ }
+
+ LocaleHelper.getInstance().switchLocale()
+ requireActivity().recreate()
+ }
}
override fun onCreateView(
@@ -98,22 +142,22 @@ class RegisterNumberFragment : OnboardingFragmentInterface() {
super.onCreateView(inflater, container, savedInstanceState)
CentralLog.i(TAG, "Making view")
// Inflate the layout for this fragment
- return inflater.inflate(R.layout.fragment_register_number, container, false)
+ return inflater.inflate(R.layout.fragment_register_number_new, container, false)
}
-
override fun onUpdatePhoneNumber(num: String) {
CentralLog.d(TAG, "onUpdatePhoneNumber $num")
}
override fun onError(error: String) {
-
- phone_number_error.let {
- phone_number_error.visibility = View.VISIBLE
- phone_number_error.text = error
+ if (!isDetached) {
+ phone_number_error.let {
+ phone_number_error.visibility = View.VISIBLE
+ phone_number_error.text = error
+ }
+ CentralLog.e(TAG, "error: $error")
}
- CentralLog.e(TAG, "error: ${error.toString()}")
}
override fun onAttach(context: Context) {
diff --git a/app/src/main/java/io/bluetrace/opentrace/onboarding/SetupFragment.kt b/app/src/main/java/io/bluetrace/opentrace/onboarding/SetupFragment.kt
index b731539..c4163f5 100644
--- a/app/src/main/java/io/bluetrace/opentrace/onboarding/SetupFragment.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/onboarding/SetupFragment.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.onboarding
+package covid.trace.morocco.onboarding
import android.content.Context
import android.net.Uri
@@ -6,8 +6,11 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import io.bluetrace.opentrace.R
-import io.bluetrace.opentrace.logging.CentralLog
+import covid.trace.morocco.LocaleHelper
+import covid.trace.morocco.R
+import covid.trace.morocco.Utils
+import covid.trace.morocco.logging.CentralLog
+import kotlinx.android.synthetic.main.fragment_setup.*
private const val ARG_PARAM1 = "param1"
@@ -27,7 +30,28 @@ class SetupFragment : OnboardingFragmentInterface() {
}
}
- override fun getButtonText(): String = "Proceed"
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ context?.let {
+ Utils.firebaseAnalyticsEvent(it, "setup_screen", "4", "Onboarding fourth screen")
+ }
+
+ language.setOnClickListener {
+ context?.let {
+ Utils.firebaseAnalyticsEvent(
+ it,
+ "setup_screen_change_language",
+ "22",
+ "Onboarding fourth screen"
+ )
+ }
+
+ LocaleHelper.getInstance().switchLocale()
+ requireActivity().recreate()
+ }
+ }
+
+ override fun getButtonText(): String = resources.getString(R.string.proceed)
override fun onButtonClick(view: View) {
CentralLog.d(TAG, "OnButtonClick 2")
@@ -37,7 +61,7 @@ class SetupFragment : OnboardingFragmentInterface() {
override fun becomesVisible() {}
- override fun getProgressValue(): Int = 80
+ override fun getProgressValue(): Int = 3
override fun onUpdatePhoneNumber(num: String) {}
@@ -72,15 +96,4 @@ class SetupFragment : OnboardingFragmentInterface() {
interface OnFragmentInteractionListener {
fun onFragmentInteraction(uri: Uri)
}
-
- companion object {
- @JvmStatic
- fun newInstance(param1: String, param2: String) =
- SetupFragment().apply {
- arguments = Bundle().apply {
- putString(ARG_PARAM1, param1)
- putString(ARG_PARAM2, param2)
- }
- }
- }
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/permissions/RequestFileWritePermission.kt b/app/src/main/java/io/bluetrace/opentrace/permissions/RequestFileWritePermission.kt
index 44f7f02..06c5a86 100644
--- a/app/src/main/java/io/bluetrace/opentrace/permissions/RequestFileWritePermission.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/permissions/RequestFileWritePermission.kt
@@ -1,14 +1,14 @@
-package io.bluetrace.opentrace.permissions
+package covid.trace.morocco.permissions
import android.Manifest
import android.os.Bundle
-import androidx.appcompat.app.AppCompatActivity
+import covid.trace.morocco.R
+import covid.trace.morocco.Utils
+import covid.trace.morocco.base.BaseActivity
import pub.devrel.easypermissions.AfterPermissionGranted
import pub.devrel.easypermissions.EasyPermissions
-import io.bluetrace.opentrace.R
-import io.bluetrace.opentrace.Utils
-class RequestFileWritePermission : AppCompatActivity() {
+class RequestFileWritePermission : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
diff --git a/app/src/main/java/io/bluetrace/opentrace/protocol/BlueTrace.kt b/app/src/main/java/io/bluetrace/opentrace/protocol/BlueTrace.kt
index cf3b80f..009562b 100644
--- a/app/src/main/java/io/bluetrace/opentrace/protocol/BlueTrace.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/protocol/BlueTrace.kt
@@ -1,7 +1,7 @@
-package io.bluetrace.opentrace.protocol
+package covid.trace.morocco.protocol
-import io.bluetrace.opentrace.BuildConfig
-import io.bluetrace.opentrace.protocol.v2.BlueTraceV2
+import covid.trace.morocco.BuildConfig
+import covid.trace.morocco.protocol.v2.BlueTraceV2
import java.util.*
//we're loosely using the characteristic IDs to indicate the protocol version?
diff --git a/app/src/main/java/io/bluetrace/opentrace/protocol/BlueTraceProtocol.kt b/app/src/main/java/io/bluetrace/opentrace/protocol/BlueTraceProtocol.kt
index cf4bf1c..6274f07 100644
--- a/app/src/main/java/io/bluetrace/opentrace/protocol/BlueTraceProtocol.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/protocol/BlueTraceProtocol.kt
@@ -1,6 +1,6 @@
-package io.bluetrace.opentrace.protocol
+package covid.trace.morocco.protocol
-import io.bluetrace.opentrace.streetpass.ConnectionRecord
+import covid.trace.morocco.streetpass.ConnectionRecord
open class BlueTraceProtocol(
val versionInt: Int,
@@ -10,6 +10,7 @@ open class BlueTraceProtocol(
interface PeripheralInterface {
fun prepareReadRequestData(protocolVersion: Int): ByteArray
+
//needs to be in try-catch in case of parse failure
fun processWriteRequestDataReceived(
dataWritten: ByteArray,
@@ -19,6 +20,7 @@ interface PeripheralInterface {
interface CentralInterface {
fun prepareWriteRequestData(protocolVersion: Int, rssi: Int, txPower: Int?): ByteArray
+
//needs to be in try-catch in case of parse failure
fun processReadRequestDataReceived(
dataRead: ByteArray,
diff --git a/app/src/main/java/io/bluetrace/opentrace/protocol/v2/BlueTraceV2.kt b/app/src/main/java/io/bluetrace/opentrace/protocol/v2/BlueTraceV2.kt
index e426040..0f3da49 100644
--- a/app/src/main/java/io/bluetrace/opentrace/protocol/v2/BlueTraceV2.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/protocol/v2/BlueTraceV2.kt
@@ -1,13 +1,13 @@
-package io.bluetrace.opentrace.protocol.v2
+package covid.trace.morocco.protocol.v2
-import io.bluetrace.opentrace.TracerApp
-import io.bluetrace.opentrace.logging.CentralLog
-import io.bluetrace.opentrace.protocol.BlueTraceProtocol
-import io.bluetrace.opentrace.protocol.CentralInterface
-import io.bluetrace.opentrace.protocol.PeripheralInterface
-import io.bluetrace.opentrace.streetpass.CentralDevice
-import io.bluetrace.opentrace.streetpass.ConnectionRecord
-import io.bluetrace.opentrace.streetpass.PeripheralDevice
+import covid.trace.morocco.WiqaytnaApp
+import covid.trace.morocco.logging.CentralLog
+import covid.trace.morocco.protocol.BlueTraceProtocol
+import covid.trace.morocco.protocol.CentralInterface
+import covid.trace.morocco.protocol.PeripheralInterface
+import covid.trace.morocco.streetpass.CentralDevice
+import covid.trace.morocco.streetpass.ConnectionRecord
+import covid.trace.morocco.streetpass.PeripheralDevice
class BlueTraceV2 : BlueTraceProtocol(
versionInt = 2,
@@ -22,9 +22,9 @@ class V2Peripheral : PeripheralInterface {
override fun prepareReadRequestData(protocolVersion: Int): ByteArray {
return V2ReadRequestPayload(
v = protocolVersion,
- id = TracerApp.thisDeviceMsg(),
- o = TracerApp.ORG,
- peripheral = TracerApp.asPeripheralDevice()
+ id = WiqaytnaApp.thisDeviceMsg(),
+ o = WiqaytnaApp.ORG,
+ peripheral = WiqaytnaApp.asPeripheralDevice()
).getPayload()
}
@@ -42,7 +42,7 @@ class V2Peripheral : PeripheralInterface {
version = dataWritten.v,
msg = dataWritten.id,
org = dataWritten.o,
- peripheral = TracerApp.asPeripheralDevice(),
+ peripheral = WiqaytnaApp.asPeripheralDevice(),
central = CentralDevice(dataWritten.mc, centralAddress),
rssi = dataWritten.rs,
txPower = null
@@ -65,9 +65,9 @@ class V2Central : CentralInterface {
): ByteArray {
return V2WriteRequestPayload(
v = protocolVersion,
- id = TracerApp.thisDeviceMsg(),
- o = TracerApp.ORG,
- central = TracerApp.asCentralDevice(),
+ id = WiqaytnaApp.thisDeviceMsg(),
+ o = WiqaytnaApp.ORG,
+ central = WiqaytnaApp.asCentralDevice(),
rs = rssi
).getPayload()
}
@@ -91,7 +91,7 @@ class V2Central : CentralInterface {
msg = readData.id,
org = readData.o,
peripheral = peripheral,
- central = TracerApp.asCentralDevice(),
+ central = WiqaytnaApp.asCentralDevice(),
rssi = rssi,
txPower = txPower
)
diff --git a/app/src/main/java/io/bluetrace/opentrace/protocol/v2/V2ReadRequestPayload.kt b/app/src/main/java/io/bluetrace/opentrace/protocol/v2/V2ReadRequestPayload.kt
index 575f2d0..b2c86b4 100644
--- a/app/src/main/java/io/bluetrace/opentrace/protocol/v2/V2ReadRequestPayload.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/protocol/v2/V2ReadRequestPayload.kt
@@ -1,8 +1,8 @@
-package io.bluetrace.opentrace.protocol.v2
+package covid.trace.morocco.protocol.v2
import com.google.gson.Gson
import com.google.gson.GsonBuilder
-import io.bluetrace.opentrace.streetpass.PeripheralDevice
+import covid.trace.morocco.streetpass.PeripheralDevice
//acting as peripheral
class V2ReadRequestPayload(
diff --git a/app/src/main/java/io/bluetrace/opentrace/protocol/v2/V2WriteRequestPayload.kt b/app/src/main/java/io/bluetrace/opentrace/protocol/v2/V2WriteRequestPayload.kt
index 5765516..fd89814 100644
--- a/app/src/main/java/io/bluetrace/opentrace/protocol/v2/V2WriteRequestPayload.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/protocol/v2/V2WriteRequestPayload.kt
@@ -1,8 +1,8 @@
-package io.bluetrace.opentrace.protocol.v2
+package covid.trace.morocco.protocol.v2
import com.google.gson.Gson
import com.google.gson.GsonBuilder
-import io.bluetrace.opentrace.streetpass.CentralDevice
+import covid.trace.morocco.streetpass.CentralDevice
class V2WriteRequestPayload(
val v: Int,
diff --git a/app/src/main/java/io/bluetrace/opentrace/receivers/UpgradeReceiver.kt b/app/src/main/java/io/bluetrace/opentrace/receivers/UpgradeReceiver.kt
index 3f26256..32760d4 100644
--- a/app/src/main/java/io/bluetrace/opentrace/receivers/UpgradeReceiver.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/receivers/UpgradeReceiver.kt
@@ -1,23 +1,28 @@
-package io.bluetrace.opentrace.receivers
+package covid.trace.morocco.receivers
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
-import io.bluetrace.opentrace.Utils
-import io.bluetrace.opentrace.logging.CentralLog
+import com.google.firebase.crashlytics.FirebaseCrashlytics
+import covid.trace.morocco.Utils
+import covid.trace.morocco.logging.CentralLog
class UpgradeReceiver : BroadcastReceiver() {
- override fun onReceive(context: Context?, intent: Intent?) {
+ private val crashlytics = FirebaseCrashlytics.getInstance()
+
+ override fun onReceive(context: Context, intent: Intent) {
try {
- if (Intent.ACTION_MY_PACKAGE_REPLACED != intent!!.action) return
+ if (Intent.ACTION_MY_PACKAGE_REPLACED != intent.action) return
// Start your service here.
context?.let {
CentralLog.i("UpgradeReceiver", "Starting service from upgrade receiver")
Utils.startBluetoothMonitoringService(context)
}
} catch (e: Exception) {
+ crashlytics.recordException(e)
+ crashlytics.setCustomKey("receiver","upgrade receiver")
CentralLog.e("UpgradeReceiver", "Unable to handle upgrade: ${e.localizedMessage}")
}
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/scheduler/Scheduler.kt b/app/src/main/java/io/bluetrace/opentrace/scheduler/Scheduler.kt
index f3154ab..42a74dd 100644
--- a/app/src/main/java/io/bluetrace/opentrace/scheduler/Scheduler.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/scheduler/Scheduler.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.scheduler
+package covid.trace.morocco.scheduler
import android.app.AlarmManager
import android.app.PendingIntent
@@ -6,8 +6,8 @@ import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.SystemClock
-import io.bluetrace.opentrace.Preference
-import io.bluetrace.opentrace.logging.CentralLog
+import covid.trace.morocco.Preference
+import covid.trace.morocco.logging.CentralLog
object Scheduler {
const val TAG = "Scheduler"
diff --git a/app/src/main/java/io/bluetrace/opentrace/services/BluetoothMonitoringService.kt b/app/src/main/java/io/bluetrace/opentrace/services/BluetoothMonitoringService.kt
index ee03c79..aade5cd 100644
--- a/app/src/main/java/io/bluetrace/opentrace/services/BluetoothMonitoringService.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/services/BluetoothMonitoringService.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.services
+package covid.trace.morocco.services
import android.Manifest
import android.app.NotificationChannel
@@ -19,33 +19,33 @@ import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.functions.FirebaseFunctions
+import covid.trace.morocco.BuildConfig
+import covid.trace.morocco.Preference
+import covid.trace.morocco.Utils
+import covid.trace.morocco.bluetooth.BLEAdvertiser
+import covid.trace.morocco.bluetooth.gatt.ACTION_RECEIVED_STATUS
+import covid.trace.morocco.bluetooth.gatt.ACTION_RECEIVED_STREETPASS
+import covid.trace.morocco.bluetooth.gatt.STATUS
+import covid.trace.morocco.bluetooth.gatt.STREET_PASS
+import covid.trace.morocco.idmanager.TempIDManager
+import covid.trace.morocco.idmanager.TemporaryID
+import covid.trace.morocco.logging.CentralLog
+import covid.trace.morocco.notifications.NotificationTemplates
+import covid.trace.morocco.permissions.RequestFileWritePermission
+import covid.trace.morocco.status.Status
+import covid.trace.morocco.status.persistence.StatusRecord
+import covid.trace.morocco.status.persistence.StatusRecordStorage
+import covid.trace.morocco.streetpass.ConnectionRecord
+import covid.trace.morocco.streetpass.StreetPassScanner
+import covid.trace.morocco.streetpass.StreetPassServer
+import covid.trace.morocco.streetpass.StreetPassWorker
+import covid.trace.morocco.streetpass.persistence.StreetPassRecord
+import covid.trace.morocco.streetpass.persistence.StreetPassRecordStorage
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import pub.devrel.easypermissions.EasyPermissions
-import io.bluetrace.opentrace.BuildConfig
-import io.bluetrace.opentrace.Preference
-import io.bluetrace.opentrace.Utils
-import io.bluetrace.opentrace.bluetooth.BLEAdvertiser
-import io.bluetrace.opentrace.bluetooth.gatt.ACTION_RECEIVED_STATUS
-import io.bluetrace.opentrace.bluetooth.gatt.ACTION_RECEIVED_STREETPASS
-import io.bluetrace.opentrace.bluetooth.gatt.STATUS
-import io.bluetrace.opentrace.bluetooth.gatt.STREET_PASS
-import io.bluetrace.opentrace.idmanager.TempIDManager
-import io.bluetrace.opentrace.idmanager.TemporaryID
-import io.bluetrace.opentrace.logging.CentralLog
-import io.bluetrace.opentrace.notifications.NotificationTemplates
-import io.bluetrace.opentrace.permissions.RequestFileWritePermission
-import io.bluetrace.opentrace.status.Status
-import io.bluetrace.opentrace.status.persistence.StatusRecord
-import io.bluetrace.opentrace.status.persistence.StatusRecordStorage
-import io.bluetrace.opentrace.streetpass.ConnectionRecord
-import io.bluetrace.opentrace.streetpass.StreetPassScanner
-import io.bluetrace.opentrace.streetpass.StreetPassServer
-import io.bluetrace.opentrace.streetpass.StreetPassWorker
-import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecord
-import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecordStorage
import java.lang.ref.WeakReference
import kotlin.coroutines.CoroutineContext
@@ -643,6 +643,7 @@ class BluetoothMonitoringService : Service(), CoroutineScope {
)
if (connRecord.msg.isNotEmpty()) {
+ //Toast.makeText(TracerApp.AppContext, connRecord.msg, Toast.LENGTH_SHORT).show();
val record = StreetPassRecord(
v = connRecord.version,
msg = connRecord.msg,
@@ -700,7 +701,7 @@ class BluetoothMonitoringService : Service(), CoroutineScope {
}
}
- enum class NOTIFICATION_STATE() {
+ enum class NOTIFICATION_STATE {
RUNNING,
LACKING_THINGS
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/services/CommandHandler.kt b/app/src/main/java/io/bluetrace/opentrace/services/CommandHandler.kt
index 1c4820f..0bd62d6 100644
--- a/app/src/main/java/io/bluetrace/opentrace/services/CommandHandler.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/services/CommandHandler.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.services
+package covid.trace.morocco.services
import android.os.Handler
import android.os.Message
diff --git a/app/src/main/java/io/bluetrace/opentrace/services/FCMService.kt b/app/src/main/java/io/bluetrace/opentrace/services/FCMService.kt
index 393cab1..7513183 100644
--- a/app/src/main/java/io/bluetrace/opentrace/services/FCMService.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/services/FCMService.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.services
+package covid.trace.morocco.services
import android.app.NotificationChannel
import android.app.NotificationManager
@@ -6,24 +6,44 @@ import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.media.RingtoneManager
+import android.net.Uri
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
+import androidx.core.content.FileProvider
+import com.google.android.gms.tasks.Task
+import com.google.firebase.functions.FirebaseFunctions
+import com.google.firebase.functions.HttpsCallableResult
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
-import io.bluetrace.opentrace.BuildConfig
-import io.bluetrace.opentrace.Preference
-import io.bluetrace.opentrace.R
-import io.bluetrace.opentrace.SplashActivity
-import io.bluetrace.opentrace.logging.CentralLog
-import io.bluetrace.opentrace.services.BluetoothMonitoringService.Companion.PUSH_NOTIFICATION_ID
+import com.google.firebase.storage.FirebaseStorage
+import com.google.firebase.storage.UploadTask
+import com.google.gson.Gson
+import covid.trace.morocco.*
+import covid.trace.morocco.logging.CentralLog
+import covid.trace.morocco.models.ExportData
+import covid.trace.morocco.services.BluetoothMonitoringService.Companion.PUSH_NOTIFICATION_ID
+import covid.trace.morocco.status.persistence.StatusRecord
+import covid.trace.morocco.status.persistence.StatusRecordStorage
+import covid.trace.morocco.streetpass.persistence.StreetPassRecord
+import covid.trace.morocco.streetpass.persistence.StreetPassRecordStorage
+import io.reactivex.Observable
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.disposables.Disposable
+import io.reactivex.functions.BiFunction
+import io.reactivex.schedulers.Schedulers
+import java.io.File
+import java.io.FileOutputStream
+import java.text.SimpleDateFormat
+import java.util.*
+import kotlin.collections.HashMap
class FCMService : FirebaseMessagingService() {
private val TAG = "FCMService"
override fun onMessageReceived(remoteMessage: RemoteMessage) {
-
+ CentralLog.d(TAG, "MESSAGE RECEIVED")
CentralLog.d(TAG, "From: ${remoteMessage.from}")
// Check if message contains a data payload.
diff --git a/app/src/main/java/io/bluetrace/opentrace/status/Status.kt b/app/src/main/java/io/bluetrace/opentrace/status/Status.kt
index 5b5a694..c27e996 100644
--- a/app/src/main/java/io/bluetrace/opentrace/status/Status.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/status/Status.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.status
+package covid.trace.morocco.status
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
diff --git a/app/src/main/java/io/bluetrace/opentrace/status/persistence/StatusRecord.kt b/app/src/main/java/io/bluetrace/opentrace/status/persistence/StatusRecord.kt
index e4b8cf7..3305c0c 100644
--- a/app/src/main/java/io/bluetrace/opentrace/status/persistence/StatusRecord.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/status/persistence/StatusRecord.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.status.persistence
+package covid.trace.morocco.status.persistence
import androidx.room.ColumnInfo
import androidx.room.Entity
diff --git a/app/src/main/java/io/bluetrace/opentrace/status/persistence/StatusRecordDao.kt b/app/src/main/java/io/bluetrace/opentrace/status/persistence/StatusRecordDao.kt
index 7fb2e72..6d0cda3 100644
--- a/app/src/main/java/io/bluetrace/opentrace/status/persistence/StatusRecordDao.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/status/persistence/StatusRecordDao.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.status.persistence
+package covid.trace.morocco.status.persistence
import androidx.lifecycle.LiveData
import androidx.room.*
diff --git a/app/src/main/java/io/bluetrace/opentrace/status/persistence/StatusRecordStorage.kt b/app/src/main/java/io/bluetrace/opentrace/status/persistence/StatusRecordStorage.kt
index a51beb4..b851bfc 100644
--- a/app/src/main/java/io/bluetrace/opentrace/status/persistence/StatusRecordStorage.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/status/persistence/StatusRecordStorage.kt
@@ -1,25 +1,55 @@
-package io.bluetrace.opentrace.status.persistence
+package covid.trace.morocco.status.persistence
import android.content.Context
-import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecordDatabase
+import android.database.sqlite.SQLiteException
+import android.database.sqlite.SQLiteFullException
+import com.google.firebase.crashlytics.FirebaseCrashlytics
+import covid.trace.morocco.BuildConfig
+import covid.trace.morocco.notifications.NotificationTemplates
+import covid.trace.morocco.streetpass.persistence.StreetPassRecordDatabase
class StatusRecordStorage(val context: Context) {
- val statusDao = StreetPassRecordDatabase.getDatabase(context).statusDao()
+ private val crashlytics = FirebaseCrashlytics.getInstance()
+ private val statusDao = StreetPassRecordDatabase.getDatabase(context).statusDao()
suspend fun saveRecord(record: StatusRecord) {
- statusDao.insert(record)
+ try {
+ statusDao.insert(record)
+ } catch (exception: Throwable) {
+ if(exception is SQLiteFullException){
+ NotificationTemplates.diskFullWarningNotification(
+ context,
+ BuildConfig.SERVICE_FOREGROUND_CHANNEL_ID
+ )
+ }
+ crashlytics.recordException(exception)
+ }
}
fun nukeDb() {
- statusDao.nukeDb()
+ try {
+ statusDao.nukeDb()
+ } catch (exception: SQLiteException) {
+ crashlytics.recordException(exception)
+ }
+
}
fun getAllRecords(): List<StatusRecord> {
- return statusDao.getCurrentRecords()
+ return try {
+ statusDao.getCurrentRecords()
+ } catch (exception: SQLiteException) {
+ crashlytics.recordException(exception)
+ listOf()
+ }
}
suspend fun purgeOldRecords(before: Long) {
- statusDao.purgeOldRecords(before)
+ try {
+ statusDao.purgeOldRecords(before)
+ } catch (exception: SQLiteException) {
+ crashlytics.recordException(exception)
+ }
}
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/streetpass/BlacklistEntry.kt b/app/src/main/java/io/bluetrace/opentrace/streetpass/BlacklistEntry.kt
index c046fde..b2fcd81 100644
--- a/app/src/main/java/io/bluetrace/opentrace/streetpass/BlacklistEntry.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/streetpass/BlacklistEntry.kt
@@ -1,3 +1,3 @@
-package io.bluetrace.opentrace.streetpass
+package covid.trace.morocco.streetpass
class BlacklistEntry(val uniqueIdentifier: String, val timeEntered: Long)
diff --git a/app/src/main/java/io/bluetrace/opentrace/streetpass/ConnectablePeripheral.kt b/app/src/main/java/io/bluetrace/opentrace/streetpass/ConnectablePeripheral.kt
index 2cdb324..eaa7c57 100644
--- a/app/src/main/java/io/bluetrace/opentrace/streetpass/ConnectablePeripheral.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/streetpass/ConnectablePeripheral.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.streetpass
+package covid.trace.morocco.streetpass
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
diff --git a/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPass.kt b/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPass.kt
index d1ee8ff..7439913 100644
--- a/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPass.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPass.kt
@@ -1,5 +1,5 @@
-package io.bluetrace.opentrace.streetpass
+package covid.trace.morocco.streetpass
-import io.bluetrace.opentrace.BuildConfig
+import covid.trace.morocco.BuildConfig
const val ACTION_DEVICE_SCANNED = "${BuildConfig.APPLICATION_ID}.ACTION_DEVICE_SCANNED"
diff --git a/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPassScanner.kt b/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPassScanner.kt
index 3122a6b..5b9248b 100644
--- a/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPassScanner.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPassScanner.kt
@@ -1,15 +1,15 @@
-package io.bluetrace.opentrace.streetpass
+package covid.trace.morocco.streetpass
import android.bluetooth.le.ScanCallback
import android.bluetooth.le.ScanResult
import android.content.Context
import android.os.Build
import android.os.Handler
-import io.bluetrace.opentrace.Utils
-import io.bluetrace.opentrace.bluetooth.BLEScanner
-import io.bluetrace.opentrace.logging.CentralLog
-import io.bluetrace.opentrace.services.BluetoothMonitoringService.Companion.infiniteScanning
-import io.bluetrace.opentrace.status.Status
+import covid.trace.morocco.Utils
+import covid.trace.morocco.bluetooth.BLEScanner
+import covid.trace.morocco.logging.CentralLog
+import covid.trace.morocco.services.BluetoothMonitoringService.Companion.infiniteScanning
+import covid.trace.morocco.status.Status
import kotlin.properties.Delegates
class StreetPassScanner constructor(
@@ -32,7 +32,11 @@ class StreetPassScanner constructor(
// var discoverer: BLEDiscoverer
init {
- scanner = BLEScanner(context, serviceUUIDString, 0)
+ scanner = BLEScanner(
+ context,
+ serviceUUIDString,
+ 0
+ )
this.context = context
// discoverer = BLEDiscoverer(context, serviceUUIDString)
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPassServer.kt b/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPassServer.kt
index ae70248..d9ead72 100644
--- a/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPassServer.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPassServer.kt
@@ -1,8 +1,8 @@
-package io.bluetrace.opentrace.streetpass
+package covid.trace.morocco.streetpass
import android.content.Context
-import io.bluetrace.opentrace.bluetooth.gatt.GattServer
-import io.bluetrace.opentrace.bluetooth.gatt.GattService
+import covid.trace.morocco.bluetooth.gatt.GattServer
+import covid.trace.morocco.bluetooth.gatt.GattService
class StreetPassServer constructor(val context: Context, val serviceUUIDString: String) {
diff --git a/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPassWorker.kt b/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPassWorker.kt
index 193bfe6..8cd071d 100644
--- a/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPassWorker.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/streetpass/StreetPassWorker.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.streetpass
+package covid.trace.morocco.streetpass
import android.bluetooth.*
import android.content.BroadcastReceiver
@@ -7,24 +7,25 @@ import android.content.Intent
import android.content.IntentFilter
import android.os.Handler
import androidx.localbroadcastmanager.content.LocalBroadcastManager
-import io.bluetrace.opentrace.BuildConfig
-import io.bluetrace.opentrace.Utils
-import io.bluetrace.opentrace.bluetooth.gatt.ACTION_DEVICE_PROCESSED
-import io.bluetrace.opentrace.bluetooth.gatt.CONNECTION_DATA
-import io.bluetrace.opentrace.bluetooth.gatt.DEVICE_ADDRESS
-import io.bluetrace.opentrace.idmanager.TempIDManager
-import io.bluetrace.opentrace.logging.CentralLog
-import io.bluetrace.opentrace.protocol.BlueTrace
-import io.bluetrace.opentrace.services.BluetoothMonitoringService
-import io.bluetrace.opentrace.services.BluetoothMonitoringService.Companion.blacklistDuration
-import io.bluetrace.opentrace.services.BluetoothMonitoringService.Companion.maxQueueTime
-import io.bluetrace.opentrace.services.BluetoothMonitoringService.Companion.useBlacklist
+import covid.trace.morocco.BuildConfig
+import covid.trace.morocco.Utils
+import covid.trace.morocco.bluetooth.gatt.ACTION_DEVICE_PROCESSED
+import covid.trace.morocco.bluetooth.gatt.CONNECTION_DATA
+import covid.trace.morocco.bluetooth.gatt.DEVICE_ADDRESS
+import covid.trace.morocco.idmanager.TempIDManager
+import covid.trace.morocco.logging.CentralLog
+import covid.trace.morocco.protocol.BlueTrace
+import covid.trace.morocco.services.BluetoothMonitoringService
+import covid.trace.morocco.services.BluetoothMonitoringService.Companion.blacklistDuration
+import covid.trace.morocco.services.BluetoothMonitoringService.Companion.maxQueueTime
+import covid.trace.morocco.services.BluetoothMonitoringService.Companion.useBlacklist
import java.util.*
import java.util.concurrent.PriorityBlockingQueue
class StreetPassWorker(val context: Context) {
- private val workQueue: PriorityBlockingQueue<Work> = PriorityBlockingQueue(5, Collections.reverseOrder<Work>())
+ private val workQueue: PriorityBlockingQueue<Work> =
+ PriorityBlockingQueue(5, Collections.reverseOrder<Work>())
private val blacklist: MutableList<BlacklistEntry> = Collections.synchronizedList(ArrayList())
private val scannedDeviceReceiver = ScannedDeviceReceiver()
diff --git a/app/src/main/java/io/bluetrace/opentrace/streetpass/Work.kt b/app/src/main/java/io/bluetrace/opentrace/streetpass/Work.kt
index a70f000..9d42551 100644
--- a/app/src/main/java/io/bluetrace/opentrace/streetpass/Work.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/streetpass/Work.kt
@@ -1,11 +1,11 @@
-package io.bluetrace.opentrace.streetpass
+package covid.trace.morocco.streetpass
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothGatt
import android.content.Context
import android.os.Build
import com.google.gson.Gson
-import io.bluetrace.opentrace.logging.CentralLog
+import covid.trace.morocco.logging.CentralLog
import kotlin.properties.Delegates
class Work constructor(
diff --git a/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecord.kt b/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecord.kt
index b702d24..cf9bff4 100644
--- a/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecord.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecord.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.streetpass.persistence
+package covid.trace.morocco.streetpass.persistence
import androidx.room.ColumnInfo
import androidx.room.Entity
diff --git a/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordDao.kt b/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordDao.kt
index 4ff7a0f..f08a66f 100644
--- a/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordDao.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordDao.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.streetpass.persistence
+package covid.trace.morocco.streetpass.persistence
import androidx.lifecycle.LiveData
import androidx.room.*
diff --git a/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordDatabase.kt b/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordDatabase.kt
index cf34dd8..c6c2dc1 100644
--- a/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordDatabase.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordDatabase.kt
@@ -1,11 +1,11 @@
-package io.bluetrace.opentrace.streetpass.persistence
+package covid.trace.morocco.streetpass.persistence
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
-import io.bluetrace.opentrace.status.persistence.StatusRecord
-import io.bluetrace.opentrace.status.persistence.StatusRecordDao
+import covid.trace.morocco.status.persistence.StatusRecord
+import covid.trace.morocco.status.persistence.StatusRecordDao
@Database(
@@ -31,10 +31,10 @@ abstract class StreetPassRecordDatabase : RoomDatabase() {
}
synchronized(this) {
val instance = Room.databaseBuilder(
- context,
- StreetPassRecordDatabase::class.java,
- "record_database"
- )
+ context,
+ StreetPassRecordDatabase::class.java,
+ "record_database"
+ )
.build()
INSTANCE = instance
return instance
diff --git a/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordRepository.kt b/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordRepository.kt
index 18a0bfe..99179c0 100644
--- a/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordRepository.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordRepository.kt
@@ -1,13 +1,20 @@
-package io.bluetrace.opentrace.streetpass.persistence
+package covid.trace.morocco.streetpass.persistence
+import android.database.sqlite.SQLiteException
import androidx.lifecycle.LiveData
+import com.google.firebase.crashlytics.FirebaseCrashlytics
class StreetPassRecordRepository(private val recordDao: StreetPassRecordDao) {
// Room executes all queries on a separate thread.
// Observed LiveData will notify the observer when the data has changed.
+ private val crashlytics = FirebaseCrashlytics.getInstance()
val allRecords: LiveData<List<StreetPassRecord>> = recordDao.getRecords()
suspend fun insert(word: StreetPassRecord) {
- recordDao.insert(word)
+ try {
+ recordDao.insert(word)
+ } catch (exception: SQLiteException) {
+ crashlytics.recordException(exception)
+ }
}
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordStorage.kt b/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordStorage.kt
index 95176bc..497b543 100644
--- a/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordStorage.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/streetpass/persistence/StreetPassRecordStorage.kt
@@ -1,24 +1,53 @@
-package io.bluetrace.opentrace.streetpass.persistence
+package covid.trace.morocco.streetpass.persistence
import android.content.Context
+import android.database.sqlite.SQLiteException
+import android.database.sqlite.SQLiteFullException
+import com.google.firebase.crashlytics.FirebaseCrashlytics
+import covid.trace.morocco.BuildConfig
+import covid.trace.morocco.notifications.NotificationTemplates
class StreetPassRecordStorage(val context: Context) {
- val recordDao = StreetPassRecordDatabase.getDatabase(context).recordDao()
+ private val crashlytics = FirebaseCrashlytics.getInstance()
+ private val recordDao = StreetPassRecordDatabase.getDatabase(context).recordDao()
suspend fun saveRecord(record: StreetPassRecord) {
- recordDao.insert(record)
+ try {
+ recordDao.insert(record)
+ } catch (exception: Throwable) {
+ if (exception is SQLiteFullException) {
+ NotificationTemplates.diskFullWarningNotification(
+ context,
+ BuildConfig.SERVICE_FOREGROUND_CHANNEL_ID
+ )
+ }
+ crashlytics.recordException(exception)
+ }
}
fun nukeDb() {
- recordDao.nukeDb()
+ try {
+ recordDao.nukeDb()
+ } catch (exception: SQLiteException) {
+ crashlytics.recordException(exception)
+ }
}
fun getAllRecords(): List<StreetPassRecord> {
- return recordDao.getCurrentRecords()
+ return try {
+ recordDao.getCurrentRecords()
+ } catch (exception: SQLiteException) {
+ crashlytics.recordException(exception)
+ listOf()
+ }
}
suspend fun purgeOldRecords(before: Long) {
- recordDao.purgeOldRecords(before)
+ try {
+ recordDao.purgeOldRecords(before)
+ } catch (exception: SQLiteException) {
+ crashlytics.recordException(exception)
+ }
}
}
diff --git a/app/src/main/java/io/bluetrace/opentrace/streetpass/view/RecordViewModel.kt b/app/src/main/java/io/bluetrace/opentrace/streetpass/view/RecordViewModel.kt
index bf8cec6..13826d9 100644
--- a/app/src/main/java/io/bluetrace/opentrace/streetpass/view/RecordViewModel.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/streetpass/view/RecordViewModel.kt
@@ -1,11 +1,11 @@
-package io.bluetrace.opentrace.streetpass.view
+package covid.trace.morocco.streetpass.view
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
-import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecord
-import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecordDatabase
-import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecordRepository
+import covid.trace.morocco.streetpass.persistence.StreetPassRecord
+import covid.trace.morocco.streetpass.persistence.StreetPassRecordDatabase
+import covid.trace.morocco.streetpass.persistence.StreetPassRecordRepository
class RecordViewModel(app: Application) : AndroidViewModel(app) {
diff --git a/app/src/main/java/io/bluetrace/opentrace/streetpass/view/StreetPassRecordViewModel.kt b/app/src/main/java/io/bluetrace/opentrace/streetpass/view/StreetPassRecordViewModel.kt
index e4540f3..084a3c3 100644
--- a/app/src/main/java/io/bluetrace/opentrace/streetpass/view/StreetPassRecordViewModel.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/streetpass/view/StreetPassRecordViewModel.kt
@@ -1,6 +1,6 @@
-package io.bluetrace.opentrace.streetpass.view
+package covid.trace.morocco.streetpass.view
-import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecord
+import covid.trace.morocco.streetpass.persistence.StreetPassRecord
class StreetPassRecordViewModel(record: StreetPassRecord, val number: Int = 1) {
val version = record.v
diff --git a/app/src/main/java/io/bluetrace/opentrace/view/CustomViewPager.kt b/app/src/main/java/io/bluetrace/opentrace/view/CustomViewPager.kt
index fa8e260..acba2cc 100644
--- a/app/src/main/java/io/bluetrace/opentrace/view/CustomViewPager.kt
+++ b/app/src/main/java/io/bluetrace/opentrace/view/CustomViewPager.kt
@@ -1,4 +1,4 @@
-package io.bluetrace.opentrace.view
+package covid.trace.morocco.view
import android.content.Context
import android.util.AttributeSet
@@ -6,9 +6,9 @@ import android.view.MotionEvent
import androidx.viewpager.widget.ViewPager
class CustomViewPager(
- context: Context?,
+ context: Context,
attrs: AttributeSet?
-) : ViewPager(context!!, attrs) {
+) : ViewPager(context, attrs) {
override fun onTouchEvent(event: MotionEvent): Boolean {
return if (isEnabled) {
super.onTouchEvent(event)
diff --git a/app/src/main/res/drawable/icon_checkbox.xml b/app/src/main/res/drawable/icon_checkbox.xml
index b87f5bb..55cca88 100644
--- a/app/src/main/res/drawable/icon_checkbox.xml
+++ b/app/src/main/res/drawable/icon_checkbox.xml
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
- <item android:state_enabled="false" android:drawable="@drawable/small_red_cross" />
- <item android:state_activated="true" android:drawable="@drawable/small_green_tick" />
- <item android:state_selected="true" android:drawable="@drawable/small_green_tick" />
- <item android:state_selected="false" android:drawable="@drawable/small_red_cross" />
- <item android:state_checked="true" android:drawable="@drawable/small_green_tick" />
- <item android:state_pressed="true" android:drawable="@drawable/small_green_tick" />
- <item android:state_focused="true" android:drawable="@drawable/small_green_tick" />
- <item android:drawable="@drawable/small_green_tick" />
+ <item android:state_enabled="false" android:drawable="@drawable/ic_unchecked_option" />
+ <item android:state_activated="true" android:drawable="@drawable/ic_checked" />
+ <item android:state_selected="true" android:drawable="@drawable/ic_checked" />
+ <item android:state_selected="false" android:drawable="@drawable/ic_unchecked_option" />
+ <item android:state_checked="true" android:drawable="@drawable/ic_checked" />
+ <item android:state_checked="false" android:drawable="@drawable/ic_unchecked_option" />
+ <item android:state_pressed="true" android:drawable="@drawable/ic_checked" />
+ <item android:state_focused="true" android:drawable="@drawable/ic_checked" />
+ <item android:drawable="@drawable/ic_checked" />
</selector>
diff --git a/app/src/main/res/drawable/selector_bottombar_text.xml b/app/src/main/res/drawable/selector_bottombar_text.xml
index caff6e1..649ac37 100644
--- a/app/src/main/res/drawable/selector_bottombar_text.xml
+++ b/app/src/main/res/drawable/selector_bottombar_text.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@color/secondary_blue_4" android:state_checked="true" />
- <item android:color="@color/grey_5" android:state_checked="false" />
+ <item android:color="@color/light_blue2" android:state_checked="true" />
+ <item android:color="@color/grey_7" android:state_checked="false" />
</selector>
diff --git a/app/src/main/res/layout/activity_main_new.xml b/app/src/main/res/layout/activity_main_new.xml
index d47ce55..05cc97c 100644
--- a/app/src/main/res/layout/activity_main_new.xml
+++ b/app/src/main/res/layout/activity_main_new.xml
@@ -8,8 +8,8 @@
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/nav_view"
android:layout_weight="1" />
@@ -22,9 +22,11 @@
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintLeft_toLeftOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
app:itemTextColor="@drawable/selector_bottombar_text"
- app:layout_constraintRight_toRightOf="parent"
+ app:labelVisibilityMode="labeled"
+ app:layout_constraintEnd_toEndOf="parent"
app:itemIconTint="@drawable/selector_bottombar_text"
+ app:itemTextAppearanceActive="@style/SelectedItemTitle"
app:menu="@menu/bottom_nav_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/activity_onboarding.xml b/app/src/main/res/layout/activity_onboarding.xml
index 4417ffa..a15f93f 100644
--- a/app/src/main/res/layout/activity_onboarding.xml
+++ b/app/src/main/res/layout/activity_onboarding.xml
@@ -6,7 +6,7 @@
android:layout_height="match_parent"
tools:context=".onboarding.OnboardingActivity">
- <io.bluetrace.opentrace.view.CustomViewPager xmlns:android="http://schemas.android.com/apk/res/android"
+ <covid.trace.morocco.view.CustomViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/app/src/main/res/layout/activity_splash.xml b/app/src/main/res/layout/activity_splash.xml
index 274d0de..3fad3e4 100644
--- a/app/src/main/res/layout/activity_splash.xml
+++ b/app/src/main/res/layout/activity_splash.xml
@@ -5,8 +5,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
- android:background="#ffffff"
- tools:context=".SplashActivity">
+ android:background="@color/white"
+ tools:context="covid.trace.morocco.SplashActivity">
<LinearLayout
android:id="@+id/center"
@@ -14,8 +14,8 @@
android:layout_height="0dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="spread"
app:layout_constraintVertical_weight="5">
@@ -26,10 +26,9 @@
android:layout_height="match_parent" />
<ImageView
- android:layout_width="0dp"
- android:layout_weight="0.7"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:src="@drawable/ic_opentrace_blue_transparent"
+ android:src="@drawable/splash_logo"
app:layout_constraintTop_toTopOf="@+id/center" />
<View
diff --git a/app/src/main/res/layout/button_and_progress.xml b/app/src/main/res/layout/button_and_progress.xml
index fd64535..1ac283f 100644
--- a/app/src/main/res/layout/button_and_progress.xml
+++ b/app/src/main/res/layout/button_and_progress.xml
@@ -2,49 +2,57 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:background="@color/background">
- <ProgressBar
+ <covid.trace.morocco.view.StepProgressBar
android:id="@+id/pbProgress"
style="@style/MyProgressBar"
- android:layout_width="match_parent"
- android:layout_height="30dp"
- android:layout_marginLeft="24dp"
- android:layout_marginRight="24dp"
+ android:layout_marginStart="24dp"
+ android:layout_marginEnd="24dp"
android:indeterminate="false"
- android:progress="33"
- android:scaleY="1.5"
- app:layout_constraintLeft_toLeftOf="@id/onboardingStartHolder"
- app:layout_constraintRight_toRightOf="@id/onboardingStartHolder"
+ android:layout_gravity="center_horizontal"
+ android:layout_height="300dp"
+ android:layout_marginBottom="17dp"
+ android:layout_marginTop="10dp"
+ android:layout_width="match_parent"
+ app:cumulativeDots="true"
+ app:activeDotIndex="1"
+ app:activeDotIcon="@drawable/ic_progress_active"
+ app:inactiveDotIcon="@drawable/ic_progress_inactive"
+ app:numberDots="4"
+ app:spacing="8dp"
+ app:layout_constraintStart_toStartOf="@id/onboardingStartHolder"
+ app:layout_constraintEnd_toEndOf="@id/onboardingStartHolder"
app:layout_constraintBottom_toTopOf="@id/onboardingStartHolder" />
- <FrameLayout
- android:id="@+id/onboardingStartHolder"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="24dp"
- android:layout_marginRight="24dp"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent">
- <Button
- android:id="@+id/buttonProgress"
+ <FrameLayout
+ android:id="@+id/onboardingStartHolder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal|bottom"
- android:layout_marginBottom="30dp"
- android:background="@drawable/gradient"
- android:fontFamily="@font/font"
- android:text="@string/proceed"
- android:textAllCaps="false"
- android:textColor="#fff"
- android:textFontWeight="600"
- android:textSize="18sp"
+ android:layout_marginStart="24dp"
+ android:layout_marginEnd="24dp"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent" />
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <Button
+ android:id="@+id/buttonProgress"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal|bottom"
+ android:layout_marginBottom="30dp"
+ android:background="@drawable/button_background"
+ android:text="@string/proceed"
+ android:textAllCaps="false"
+ android:textColor="#fff"
+ android:textFontWeight="600"
+ android:textSize="18sp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
- </FrameLayout>
+ </FrameLayout>
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
+ </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/database_peek.xml b/app/src/main/res/layout/database_peek.xml
index 2f7faee..2f967c3 100644
--- a/app/src/main/res/layout/database_peek.xml
+++ b/app/src/main/res/layout/database_peek.xml
@@ -12,8 +12,8 @@
android:background="@android:color/darker_gray"
android:backgroundTint="@color/lighter"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="@layout/recycler_view_item" />
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
index af7ee97..18ff644 100644
--- a/app/src/main/res/layout/fragment_home.xml
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -2,17 +2,16 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@color/grey_11">
+ android:background="@color/background">
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
@@ -20,363 +19,64 @@
android:layout_height="wrap_content"
android:orientation="vertical">
- <LinearLayout
- android:id="@+id/view_complete"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="12dp"
- android:orientation="vertical">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/light_blue"
- android:orientation="vertical"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:paddingBottom="20dp"
- android:visibility="visible">
-
- <androidx.appcompat.widget.AppCompatImageView
- android:id="@+id/animation_view"
- android:layout_width="match_parent"
- android:layout_height="250dp"
- android:padding="16dp"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:srcCompat="@drawable/ic_opentrace_blue_transparent"
- />
-
- <androidx.appcompat.widget.AppCompatTextView
- android:id="@+id/tv_last_update"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Last update: X:XX XX"
- android:textColor="@color/blue_update"
- android:textSize="14sp"
- android:textStyle="bold"
- android:visibility="invisible"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- tools:layout_editor_absoluteX="0dp"
- tools:layout_editor_absoluteY="272dp" />
+ <!-- HomePage -->
- </androidx.constraintlayout.widget.ConstraintLayout>
+ <include layout="@layout/fragment_new_home" />
- <androidx.appcompat.widget.AppCompatTextView
- style="@style/OnboardingTitle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/how_to_help" />
+ <!-- revoked permissions page -->
- <androidx.appcompat.widget.AppCompatTextView
- style="@style/OnboardingDesc"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/help_action" />
+ <include layout="@layout/home_setupe_incomplete" />
- </LinearLayout>
+ <!-- share cardview -->
-
- <LinearLayout
- android:id="@+id/view_setup"
+ <androidx.cardview.widget.CardView
+ android:id="@+id/share_card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical"
- android:visibility="gone"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toTopOf="parent">
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ android:layout_marginTop="10dp"
+ app:cardCornerRadius="6dp"
+ card_view:cardUseCompatPadding="true"
+ card_view:contentPadding="0dp">
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/light_yellow"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:gravity="center"
android:orientation="vertical"
- android:paddingLeft="32dp"
- android:paddingRight="32dp"
- android:paddingBottom="20dp">
-
- <ImageView
- android:id="@+id/imv_incomplete"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginTop="25dp"
- android:paddingLeft="66dp"
- android:paddingRight="66dp"
- android:src="@drawable/ic_opentrace_blue_transparent" />
+ android:padding="10dp">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
- android:layout_marginTop="15dp"
android:layout_weight="1"
- android:gravity="center"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:text="@string/setup_incomplete"
- android:textColor="@color/black"
- android:textSize="16sp"
- android:textStyle="bold"
- android:visibility="visible" />
-
- <androidx.appcompat.widget.AppCompatTextView
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
- android:layout_weight="1"
- android:gravity="center"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:text="@string/help_us_identify"
+ android:drawableStart="@drawable/ic_share"
+ android:drawablePadding="10dp"
+ android:gravity="start|center_vertical"
+ android:paddingStart="5dp"
+ android:paddingEnd="16dp"
+ android:text="@string/share_this_app"
android:textColor="@color/black"
- android:textSize="16sp"
- android:textStyle="normal"
+ android:textSize="12sp"
android:visibility="visible" />
- <Button
- android:id="@+id/btn_restart_app_setup"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:layout_marginLeft="10dp"
- android:layout_marginTop="10dp"
- android:layout_marginRight="10dp"
- android:background="@drawable/gradient"
- android:minWidth="200dp"
- android:text="@string/restart_app_setup"
- android:textAllCaps="false"
- android:textColor="#fff"
- android:textFontWeight="600"
- android:textSize="16sp" />
-
</LinearLayout>
- <LinearLayout
- android:id="@+id/permission_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/transparent"
- android:orientation="vertical"
- android:paddingLeft="16dp"
- android:paddingRight="16dp">
-
- <androidx.appcompat.widget.AppCompatTextView
- android:id="@+id/tv_title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="16dp"
- android:layout_marginBottom="12dp"
- android:gravity="left"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:text="@string/app_permission_status"
- android:textColor="@color/grey_2"
- android:textSize="16sp"
- android:textStyle="bold" />
-
- <androidx.cardview.widget.CardView
- android:id="@+id/bluetooth_card_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="0dp"
- android:layout_marginRight="0dp"
- card_view:cardBackgroundColor="@color/white"
- card_view:cardCornerRadius="12dp"
- card_view:cardMaxElevation="2dp"
- card_view:cardPreventCornerOverlap="true"
- card_view:cardUseCompatPadding="true"
- card_view:contentPadding="0dp">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:background="?android:selectableItemBackground"
- android:gravity="center"
- android:orientation="horizontal"
- android:padding="15dp">
-
- <androidx.appcompat.widget.AppCompatTextView
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:layout_weight="1"
-
- android:gravity="left|center_vertical"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:text="@string/bluetooth_on"
- android:textColor="@color/grey_2"
- android:textSize="16sp"
- android:textStyle="normal"
- android:visibility="visible" />
-
- <ImageView
- android:id="@+id/iv_bluetooth"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:background="@drawable/icon_checkbox"
- android:clickable="false" />
-
- </LinearLayout>
-
- </androidx.cardview.widget.CardView>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/location_card_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- card_view:cardBackgroundColor="@color/white"
- card_view:cardCornerRadius="12dp"
- card_view:cardMaxElevation="2dp"
- card_view:cardUseCompatPadding="true"
- card_view:contentPadding="0dp">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:background="?android:selectableItemBackground"
- android:gravity="center"
- android:orientation="horizontal"
- android:padding="15dp">
-
- <androidx.appcompat.widget.AppCompatTextView
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:layout_weight="1"
-
- android:gravity="left|center_vertical"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:text="@string/location_on"
- android:textColor="@color/grey_2"
- android:textSize="16sp"
- android:textStyle="normal"
- android:visibility="visible" />
-
- <ImageView
- android:id="@+id/iv_location"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:clickable="false"
- android:src="@drawable/icon_checkbox" />
-
- </LinearLayout>
-
- </androidx.cardview.widget.CardView>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/battery_card_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:visibility="visible"
- card_view:cardBackgroundColor="@color/white"
- card_view:cardCornerRadius="12dp"
- card_view:cardMaxElevation="2dp"
- card_view:cardUseCompatPadding="true"
- card_view:contentPadding="0dp">
-
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:background="?android:selectableItemBackground"
- android:gravity="center"
- android:orientation="horizontal"
- android:padding="15dp">
-
- <androidx.appcompat.widget.AppCompatTextView
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:layout_weight="1"
-
- android:gravity="left|center_vertical"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:text="@string/battery_optimiser"
- android:textColor="@color/grey_2"
- android:textSize="16sp"
- android:textStyle="normal"
- android:visibility="visible" />
-
- <ImageView
- android:id="@+id/iv_battery"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:clickable="false"
- android:src="@drawable/icon_checkbox" />
-
- </LinearLayout>
-
- </androidx.cardview.widget.CardView>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/push_card_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- card_view:cardBackgroundColor="@color/white"
- card_view:cardCornerRadius="12dp"
- card_view:cardMaxElevation="2dp"
- card_view:cardUseCompatPadding="true"
- card_view:contentPadding="0dp">
-
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:background="?android:selectableItemBackground"
- android:gravity="center"
- android:orientation="horizontal"
- android:padding="15dp">
-
- <androidx.appcompat.widget.AppCompatTextView
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:layout_weight="1"
-
- android:gravity="left|center_vertical"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:text="@string/push_noti"
- android:textColor="@color/grey_2"
- android:textSize="16sp"
- android:textStyle="normal"
- android:visibility="visible" />
-
- <ImageView
- android:id="@+id/iv_push"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:clickable="false"
- android:src="@drawable/icon_checkbox" />
-
- </LinearLayout>
-
- </androidx.cardview.widget.CardView>
-
- </LinearLayout>
-
- </LinearLayout>
+ </androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
- android:id="@+id/share_card_view"
+ android:id="@+id/faq"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginLeft="16dp"
- android:layout_marginRight="16dp"
- card_view:cardBackgroundColor="@color/light_blue"
- card_view:cardCornerRadius="12dp"
- card_view:cardMaxElevation="2dp"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ android:layout_marginTop="3dp"
+ android:layout_marginBottom="10dp"
+ app:cardCornerRadius="6dp"
card_view:cardUseCompatPadding="true"
card_view:contentPadding="0dp">
@@ -384,48 +84,31 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
- android:background="?android:selectableItemBackground"
android:gravity="center"
android:orientation="vertical"
- android:padding="15dp">
+ android:padding="10dp">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_weight="1"
- android:drawableLeft="@drawable/ic_share"
- android:drawablePadding="10dp"
-
- android:gravity="left|center_vertical"
- android:paddingLeft="12dp"
- android:paddingRight="16dp"
- android:text="@string/share_this_app"
- android:textColor="@color/primary_blue_2"
- android:textSize="16sp"
- android:textStyle="bold"
+ android:drawableStart="@drawable/ic_faq"
+ android:drawablePadding="16dp"
+ android:gravity="start|center_vertical"
+ android:paddingStart="5dp"
+ android:paddingEnd="16dp"
+ android:text="@string/faq"
+ android:textColor="@color/black"
+ android:textSize="12sp"
android:visibility="visible" />
- <androidx.appcompat.widget.AppCompatTextView
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="left"
- android:layout_marginLeft="25dp"
- android:layout_weight="1"
- android:gravity="left|center_vertical"
- android:paddingLeft="12dp"
- android:paddingRight="16dp"
- android:text="@string/ask_friend"
- android:textColor="@color/grey_2"
- android:textSize="16sp"
- android:textStyle="normal"
- android:visibility="visible" />
-
</LinearLayout>
</androidx.cardview.widget.CardView>
+
</LinearLayout>
</ScrollView>
@@ -436,10 +119,12 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
- android:background="@drawable/background_purple_gradient"
+ android:background="@drawable/button_background"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
+ <!-- announcement -->
+
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_announcement"
android:layout_width="0dp"
@@ -450,23 +135,24 @@
android:clickable="true"
android:linksClickable="true"
android:textColorLink="@color/white"
- android:paddingLeft="16dp"
+ android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toLeftOf="@id/btn_announcement_close" />
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/btn_announcement_close" />
<ImageButton
android:id="@+id/btn_announcement_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
- android:src="@drawable/ic_cross"
- android:paddingLeft="8dp"
- android:paddingRight="16dp"
+ android:src="@drawable/ic_close_black_24dp"
+ android:visibility="gone"
+ android:paddingStart="8dp"
+ android:paddingEnd="16dp"
android:paddingTop="16dp"
- app:layout_constraintRight_toRightOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/fragment_setup.xml b/app/src/main/res/layout/fragment_setup.xml
index f4e1ad1..a8b1616 100644
--- a/app/src/main/res/layout/fragment_setup.xml
+++ b/app/src/main/res/layout/fragment_setup.xml
@@ -1,119 +1,231 @@
<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:fillViewport="true"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:background="@color/background"
tools:context=".onboarding.OnboardingActivity">
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@id/footer">
-
- <ImageView
- style="@style/OnboardingImage"
- android:id="@+id/on_boarding_banner"
+ <androidx.appcompat.widget.AppCompatTextView
+ android:id="@+id/language"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:src="@drawable/ic_opentrace_blue_transparent"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
+ android:textStyle="bold"
+ android:textColor="@color/new_blue"
+ android:textSize="16sp"
+ android:layout_marginTop="20dp"
+ android:layout_marginStart="20dp"
+ android:text="@string/language_choice"/>
+
<androidx.appcompat.widget.AppCompatTextView
- style="@style/OnboardingTitle"
android:id="@+id/tv_title"
- android:layout_width="0dp"
+ android:textSize="16sp"
+ android:textStyle="bold"
+ android:layout_marginLeft="18dp"
+ android:layout_marginRight="18dp"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:gravity="left"
- android:text="@string/setup_app_permission"
- android:visibility="visible"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/on_boarding_banner" />
+ android:layout_marginTop="35dp"
+ android:gravity="center"
+ android:textColor="@color/new_blue_2"
+ android:text="@string/setup_app_permission" />
- <androidx.appcompat.widget.AppCompatTextView
- android:id="@+id/tv_desc"
- style="@style/OnboardingDesc"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginTop="12dp"
- android:gravity="left"
- android:text="@string/setup_app_permission_title"
- android:visibility="visible"
- app:layout_constraintHorizontal_bias="0.0"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/tv_title" />
- <androidx.appcompat.widget.AppCompatTextView
- style="@style/OnboardingSubDesc"
- android:id="@+id/tv_desc_sub_1"
- android:layout_width="0dp"
+ <androidx.appcompat.widget.AppCompatTextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="16sp"
+ android:textStyle="bold"
+ android:layout_marginLeft="18dp"
+ android:layout_marginRight="18dp"
+ android:layout_marginTop="35dp"
+ android:gravity="center"
+ android:textColor="@color/new_blue_2"
+ android:text="@string/need_bluetooth"/>
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAlignment="center"
+ android:layout_marginTop="20dp"
+ android:layout_marginLeft="18dp"
+ android:layout_marginRight="18dp"
+ android:textColor="@color/new_blue_2"
+ android:text="@string/we_dont_collect_gps_infos"/>
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="12dp"
+ android:layout_alignParentBottom="true"
+ android:orientation="vertical">
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/bluetooth_card_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:cardCornerRadius="6sp"
+ android:layout_marginTop="35dp"
+ android:layout_marginLeft="20dp"
+ android:layout_marginRight="20dp">
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="13dp">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_bluetooth"
+ android:layout_alignParentEnd="true"
+ android:layout_centerVertical="true"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
+ android:text="@string/bluetooth"
+ android:textColor="@color/black"
+ android:textSize="15sp"/>
+
+ <RadioButton
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:layout_alignParentStart="true"
+ android:layout_centerVertical="true"
+ android:buttonTint="@color/grey_7" />
+
+ </RelativeLayout>
+
+
+ </androidx.cardview.widget.CardView>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/battery_card_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:cardCornerRadius="6sp"
+ android:layout_marginRight="20dp"
+ android:layout_marginLeft="20dp"
+ android:layout_marginTop="14dp">
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="13dp">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_battery_optimisation"
+ android:layout_alignParentEnd="true"
+ android:layout_centerVertical="true"
+ />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
+ android:textColor="@color/black"
+ android:textSize="15sp"
+ android:text="@string/battery_optimiser_opt"
+ />
+
+ <RadioButton
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:layout_alignParentStart="true"
+ android:layout_centerVertical="true"
+ android:buttonTint="@color/grey_7"
+ />
+
+ </RelativeLayout>
+
+
+ </androidx.cardview.widget.CardView>
+
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/location_card_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:cardCornerRadius="6sp"
+ android:layout_marginTop="14dp"
+ android:layout_marginLeft="20dp"
+ android:layout_marginRight="20dp">
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="13dp">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_location"
+ android:layout_alignParentEnd="true"
+ android:layout_centerVertical="true"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/location_permissions"
+ android:layout_centerVertical="true"
+ android:layout_centerHorizontal="true"
+ android:textColor="@color/black"
+ android:textSize="15sp"
+ />
+
+ <RadioButton
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:layout_alignParentStart="true"
+ android:layout_centerVertical="true"
+ android:buttonTint="@color/grey_7"
+ />
- android:gravity="left"
- android:text="@string/bluetooth"
- android:visibility="visible"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/tv_desc" />
+ </RelativeLayout>
- <androidx.appcompat.widget.AppCompatTextView
- style="@style/OnboardingSubDesc"
- android:id="@+id/tv_desc_sub_2"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginTop="5dp"
- android:gravity="left"
- android:text="@string/location_permissions"
- android:visibility="visible"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/tv_desc_sub_1" />
- <androidx.appcompat.widget.AppCompatTextView
- style="@style/OnboardingSubDesc"
- android:id="@+id/tv_note_1"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
+ </androidx.cardview.widget.CardView>
- android:gravity="left"
- android:text="@string/notes"
- android:textColor="@color/grey_3"
- android:paddingTop="16dp"
- android:visibility="visible"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/tv_desc_sub_2" />
+ <FrameLayout
+ android:id="@+id/footer"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="20dp">
+
+ <include layout="@layout/button_and_progress" />
+ </FrameLayout>
- <androidx.appcompat.widget.AppCompatTextView
- android:id="@+id/tv_desc_sub_3"
- style="@style/OnboardingSubDesc"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginTop="5dp"
- android:gravity="left"
- android:text="@string/battery_optimiser_opt"
- android:visibility="visible"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/tv_desc_sub_2" />
+ </LinearLayout>
- </androidx.constraintlayout.widget.ConstraintLayout>
- <FrameLayout
- android:id="@+id/footer"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- app:layout_constraintBottom_toBottomOf="parent">
- <include layout="@layout/button_and_progress" />
- </FrameLayout>
+ </RelativeLayout>
+
+
-</androidx.constraintlayout.widget.ConstraintLayout>
+</LinearLayout>
+</ScrollView>
diff --git a/app/src/main/res/layout/fragment_upload_enterpin.xml b/app/src/main/res/layout/fragment_upload_enterpin.xml
index ba91b3c..8c9ca85 100644
--- a/app/src/main/res/layout/fragment_upload_enterpin.xml
+++ b/app/src/main/res/layout/fragment_upload_enterpin.xml
@@ -1,130 +1,378 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@drawable/background_white_radius"
- android:orientation="vertical"
- android:weightSum="6">
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="5"
- android:orientation="vertical"
- tools:ignore="Suspicious0dp">
+ android:layout_height="match_parent"
+ android:background="@color/background"
+ android:orientation="vertical">
- <LinearLayout
+ <ImageView
+ android:id="@+id/back"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="30dp"
+ android:layout_marginStart="18dp"
+ android:src="@drawable/ic_back_button"/>
+
+ <TextView
android:layout_width="match_parent"
- android:layout_height="40dp"
- android:layout_marginLeft="25dp"
- android:layout_marginTop="20dp">
+ android:layout_height="wrap_content"
+ android:layout_marginTop="20dp"
+ android:layout_marginStart="18dp"
+ android:layout_marginEnd="18dp"
+ android:textAlignment="center"
+ android:textSize="16sp"
+ android:textColor="@color/new_blue_2"
+ android:textStyle="bold"
+ android:text="@string/forusermho"/>
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="18dp"
+ android:layout_marginEnd="18dp"
+ android:layout_marginTop="12dp"
+ android:textColor="@color/black"
+ android:textAlignment="center"
+ android:textSize="12sp"
+ android:textStyle="bold"
+ android:text="@string/upload_infos"/>
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dp"
+ android:layout_marginLeft="18dp"
+ android:layout_marginRight="18dp"
+ app:cardUseCompatPadding="true"
+ app:cardElevation="1dp"
+ app:cardCornerRadius="5dp">
<LinearLayout
- android:id="@+id/enterPinFragmentBackButtonLayout"
- android:layout_width="60dp"
- android:layout_height="wrap_content">
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingTop="18dp"
+ android:paddingBottom="18dp"
+ android:orientation="vertical">
- <ImageButton
- android:id="@+id/enterPinFragmentBackButton"
- android:layout_width="wrap_content"
+ <TextView
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="@color/transparent"
- android:scaleX="0.5"
- android:scaleY="0.5"
- android:src="@drawable/back" />
- </LinearLayout>
+ android:layout_marginStart="18dp"
+ android:layout_marginEnd="18dp"
+ android:textAlignment="center"
+ android:textSize="12sp"
+ android:textStyle="bold"
+ android:textColor="@color/black"
+ android:text="@string/enter_pin"/>
- </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
+ android:layout_marginTop="14dp"
+ android:layoutDirection="ltr"
+ android:weightSum="6"
+ android:orientation="horizontal">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginLeft="30dp"
- android:layout_marginRight="30dp"
- android:layout_weight="3"
- android:orientation="vertical">
+ <androidx.cardview.widget.CardView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_marginRight="3dp"
+ app:cardUseCompatPadding="true"
+ app:cardCornerRadius="6dp">
- <androidx.appcompat.widget.AppCompatTextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="15sp"
- android:text="STEP 2" />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
- <androidx.appcompat.widget.AppCompatTextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="10dp"
- android:text="Enter PIN to upload"
- android:textSize="18sp"
- android:textStyle="bold" />
+ <EditText
+ android:id="@+id/otp1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="30sp"
+ tools:text="8"
+ android:maxLength="1"
+ android:textStyle="bold"
+ android:textAlignment="center"
+ android:textColor="@color/sky_blue"
+ android:background="@color/transparent"
+ android:inputType="number" />
- <EditText
- android:id="@+id/enterPinFragmentUploadCode"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:imeOptions="actionGo"
- android:maxLength="6"
- android:textSize="18sp" />
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="4dp"
+ android:background="@drawable/green_line"/>
- <androidx.appcompat.widget.AppCompatTextView
- android:id="@+id/enterPinFragmentErrorMessage"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="5dp"
- android:text="Invalid PIN"
- android:textColor="#C20000"
- android:textSize="16sp"
- android:visibility="invisible" />
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginLeft="30dp"
- android:layout_marginTop="30dp"
- android:layout_marginRight="30dp"
- android:layout_weight="2"
- android:orientation="vertical">
+ </LinearLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
- <androidx.appcompat.widget.AppCompatTextView
- android:textSize="13sp"
- android:layout_marginTop="10dp"
+ </androidx.cardview.widget.CardView>
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ app:cardCornerRadius="6dp"
+ android:layout_marginRight="3dp"
+ android:layout_weight="1"
+ app:cardUseCompatPadding="true">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <EditText
+ android:id="@+id/otp2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="30sp"
+ tools:text="8"
+ android:maxLength="1"
+ android:textStyle="bold"
+ android:textAlignment="center"
+ android:textColor="@color/sky_blue"
+ android:background="@color/transparent"
+ android:inputType="number" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="4dp"
+ android:background="@drawable/green_line"/>
+
+ </LinearLayout>
+
+
+ </androidx.cardview.widget.CardView>
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="3dp"
+ android:layout_weight="1"
+ app:cardCornerRadius="6dp"
+ app:cardUseCompatPadding="true">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <EditText
+ android:id="@+id/otp3"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="30sp"
+ tools:text="8"
+ android:maxLength="1"
+ android:textStyle="bold"
+ android:textAlignment="center"
+ android:textColor="@color/sky_blue"
+ android:background="@color/transparent"
+ android:inputType="number" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="4dp"
+ android:background="@drawable/green_line"/>
+
+ </LinearLayout>
+
+
+ </androidx.cardview.widget.CardView>
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="3dp"
+ android:layout_weight="1"
+ app:cardCornerRadius="6dp"
+ app:cardUseCompatPadding="true">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <EditText
+ android:id="@+id/otp4"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="30sp"
+ tools:text="8"
+ android:maxLength="1"
+ android:textStyle="bold"
+ android:textAlignment="center"
+ android:textColor="@color/sky_blue"
+ android:background="@color/transparent"
+ android:inputType="number" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="4dp"
+ android:background="@drawable/green_line"/>
+
+ </LinearLayout>
+
+
+ </androidx.cardview.widget.CardView>
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="3dp"
+ android:layout_weight="1"
+ app:cardCornerRadius="6dp"
+ app:cardUseCompatPadding="true">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <EditText
+ android:id="@+id/otp5"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="30sp"
+ tools:text="8"
+ android:maxLength="1"
+ android:textStyle="bold"
+ android:textAlignment="center"
+ android:textColor="@color/sky_blue"
+ android:background="@color/transparent"
+ android:inputType="number" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="4dp"
+ android:background="@drawable/green_line"/>
+
+ </LinearLayout>
+
+
+ </androidx.cardview.widget.CardView>
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="3dp"
+ android:layout_weight="1"
+ app:cardCornerRadius="6dp"
+ app:cardUseCompatPadding="true">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <EditText
+ android:id="@+id/otp6"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="30sp"
+ tools:text="8"
+ android:maxLength="1"
+ android:textStyle="bold"
+ android:textAlignment="center"
+ android:textColor="@color/sky_blue"
+ android:background="@color/transparent"
+ android:inputType="number" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="4dp"
+ android:background="@drawable/green_line"/>
+
+ </LinearLayout>
+
+
+ </androidx.cardview.widget.CardView>
+
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/enterPinFragmentErrorMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/upload_agreement" />
+ android:layout_marginStart="18dp"
+ android:textAlignment="center"
+ android:visibility="invisible"
+ android:textColor="@color/new_red"
+ android:text="@string/invalid_otp"/>
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="2dp"
+ android:layout_marginLeft="10dp"
+ android:layout_marginRight="10dp"
+ android:textAlignment="center"
+ android:textStyle="bold"
+ android:textSize="11sp"
+ android:textColor="@color/black"
+ android:text="@string/upload_agreement"/>
+
+
</LinearLayout>
- </LinearLayout>
+ </androidx.cardview.widget.CardView>
- </LinearLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:orientation="vertical"
- tools:ignore="Suspicious0dp">
-
- <Button
- android:id="@+id/enterPinActionButton"
- android:fontFamily="@font/font"
- android:textFontWeight="600"
- android:textSize="18sp"
+ <RelativeLayout
android:layout_width="match_parent"
- android:layout_height="50dp"
- android:layout_marginLeft="30dp"
- android:layout_marginRight="30dp"
- android:background="@drawable/gradient"
- android:text="Upload data"
- android:textAllCaps="false"
- android:textColor="@color/white"
- android:textStyle="normal" />
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="20dp">
+
+ <Button
+ android:id="@+id/enterPinActionButton"
+ android:layout_alignParentBottom="true"
+ android:textFontWeight="600"
+ android:textSize="18sp"
+ android:layout_width="match_parent"
+ android:layout_height="50dp"
+ android:layout_marginStart="30dp"
+ android:layout_marginEnd="30dp"
+ android:background="@drawable/button_background"
+ android:text="@string/upload_data"
+ android:textAllCaps="false"
+ android:textColor="@color/white"
+ android:textStyle="normal" />
+ </RelativeLayout>
+
</LinearLayout>
-</LinearLayout>
+ </ScrollView>
+
+ <FrameLayout
+ android:id="@+id/uploadPageFragmentLoadingProgressBarFrame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:alpha="0.5"
+ android:animateLayoutChanges="true"
+ android:background="#000000"
+ android:visibility="invisible">
+
+ <ProgressBar
+ android:id="@+id/loadingProgressBar"
+ style="?android:attr/progressBarStyleLarge"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center" />
+ </FrameLayout>
+</FrameLayout>
+
diff --git a/app/src/main/res/layout/fragment_upload_foruse.xml b/app/src/main/res/layout/fragment_upload_foruse.xml
index e459eaf..1d31646 100644
--- a/app/src/main/res/layout/fragment_upload_foruse.xml
+++ b/app/src/main/res/layout/fragment_upload_foruse.xml
@@ -1,85 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@drawable/background_white_radius"
+ android:background="@color/background"
android:weightSum="6">
- <LinearLayout
- android:layout_width="match_parent"
- android:orientation="vertical"
- android:layout_height="0dp"
- android:layout_weight="5"
- tools:ignore="Suspicious0dp">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="60dp" />
+ <ImageView
+ android:id="@+id/language"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_marginTop="27dp"
+ android:layout_marginStart="18dp"
+ android:src="@drawable/ic_settings" />
- <LinearLayout
- android:orientation="vertical"
- android:layout_marginLeft="30dp"
- android:layout_marginRight="30dp"
- android:layout_width="match_parent"
- android:gravity="center_horizontal|top"
- android:layout_height="wrap_content">
-
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/ic_opentrace_blue_transparent" />
- </LinearLayout>
-
- <LinearLayout
- android:layout_marginTop="60dp"
- android:orientation="vertical"
- android:layout_weight="2"
- android:layout_width="match_parent"
- android:layout_height="0dp">
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <androidx.appcompat.widget.AppCompatTextView
- android:layout_marginTop="30dp"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="22sp"
- android:textStyle="normal"
- android:textAlignment="textStart"
- android:text="Tap 'Next' only if a contact tracer tells you to do so" />
-
- </LinearLayout>
-
- </LinearLayout>
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="18dp"
+ android:layout_marginEnd="18dp"
+ android:layout_marginTop="80dp"
+ android:textAlignment="center"
+ android:textStyle="bold"
+ android:textSize="18sp"
+ android:textColor="@color/new_blue_2"
+ android:text="@string/forusermho" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="18dp"
+ android:layout_marginEnd="18dp"
+ android:layout_marginTop="30dp"
+ android:textAlignment="center"
+ android:textStyle="bold"
+ android:textColor="@color/black"
+ android:text="@string/upload_screen_next" />
- </LinearLayout>
- <LinearLayout
+ <RelativeLayout
android:layout_width="match_parent"
- android:orientation="vertical"
- android:layout_height="0dp"
- android:layout_weight="1"
- tools:ignore="Suspicious0dp">
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="20dp">
<Button
android:id="@+id/forUseFragmentActionButton"
- android:background="@drawable/gradient"
- android:layout_marginLeft="30dp"
- android:layout_marginRight="30dp"
- android:fontFamily="@font/font"
+ android:background="@drawable/button_background"
+ android:layout_marginStart="30dp"
+ android:layout_marginEnd="30dp"
+ android:layout_alignParentBottom="true"
android:textFontWeight="600"
android:textSize="18sp"
android:layout_width="match_parent"
android:layout_height="50dp"
android:textColor="@color/white"
- android:text="Next"
+ android:text="@string/next"
android:textStyle="normal"
android:textAllCaps="false" />
- </LinearLayout>
+ </RelativeLayout>
</LinearLayout>
diff --git a/app/src/main/res/layout/fragment_upload_uploadcomplete.xml b/app/src/main/res/layout/fragment_upload_uploadcomplete.xml
index 1a5a505..b89e638 100644
--- a/app/src/main/res/layout/fragment_upload_uploadcomplete.xml
+++ b/app/src/main/res/layout/fragment_upload_uploadcomplete.xml
@@ -1,90 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@drawable/background_white_radius"
- android:weightSum="6">
+ android:background="@color/background"
+ android:weightSum="1">
- <LinearLayout
+ <TextView
android:layout_width="match_parent"
- android:orientation="vertical"
- android:layout_height="0dp"
- android:layout_weight="5"
- tools:ignore="Suspicious0dp">
+ android:layout_height="wrap_content"
+ android:layout_marginTop="40dp"
+ android:layout_marginStart="18dp"
+ android:layout_marginEnd="18dp"
+ android:textAlignment="center"
+ android:textSize="18sp"
+ android:textColor="@color/new_blue_2"
+ android:textStyle="bold"
+ android:text="@string/forusermho" />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="60dp"></LinearLayout>
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="18dp"
+ android:layout_marginEnd="18dp"
+ android:layout_marginTop="12dp"
+ android:textAlignment="center"
+ android:textColor="@color/black"
+ android:textStyle="bold"
+ android:text="@string/data_upload" />
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="0.8"
+ android:layout_marginTop="30dp"
+ android:layout_marginLeft="18dp"
+ android:layout_marginRight="18dp"
+ app:cardUseCompatPadding="true"
+ app:cardElevation="1dp"
+ app:cardCornerRadius="5dp">
- <LinearLayout
- android:orientation="vertical"
- android:layout_marginLeft="30dp"
- android:layout_marginRight="30dp"
+ <RelativeLayout
android:layout_width="match_parent"
- android:gravity="center_horizontal|top"
- android:layout_height="wrap_content">
+ android:layout_height="match_parent">
<ImageView
+ android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:src="@drawable/done_icon"></ImageView>
+ android:layout_centerInParent="true"
+ android:src="@drawable/ic_upload_done" />
- <androidx.appcompat.widget.AppCompatTextView
- android:layout_marginLeft="30dp"
- android:layout_marginRight="30dp"
- android:layout_marginTop="30dp"
+ <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textSize="18sp"
- android:textStyle="bold"
+ android:layout_marginLeft="18dp"
+ android:layout_marginRight="18dp"
+ android:layout_centerHorizontal="true"
android:textAlignment="center"
- android:text="Your data has been uploaded to OTC" />
- </LinearLayout>
-
- <LinearLayout
- android:layout_marginTop="60dp"
- android:orientation="vertical"
- android:layout_marginLeft="30dp"
- android:layout_marginRight="30dp"
- android:layout_weight="2"
- android:layout_width="match_parent"
- android:layout_height="0dp">
+ android:textStyle="bold"
+ android:textColor="@color/black"
+ android:layout_marginTop="20dp"
+ android:layout_below="@+id/icon"
+ android:text="@string/uploadedtomho" />
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- </LinearLayout>
+ </RelativeLayout>
- </LinearLayout>
+ </androidx.cardview.widget.CardView>
- </LinearLayout>
- <LinearLayout
+ <RelativeLayout
android:layout_width="match_parent"
- android:orientation="vertical"
android:layout_height="0dp"
- android:layout_weight="1"
- tools:ignore="Suspicious0dp">
+ android:layout_weight="0.2"
+ android:layout_marginBottom="20dp">
<Button
android:id="@+id/uploadCompleteFragmentActionButton"
- android:background="@drawable/gradient"
- android:layout_marginLeft="30dp"
- android:layout_marginRight="30dp"
- android:fontFamily="@font/font"
+ android:layout_alignParentBottom="true"
android:textFontWeight="600"
android:textSize="18sp"
android:layout_width="match_parent"
android:layout_height="50dp"
+ android:layout_marginStart="30dp"
+ android:layout_marginEnd="30dp"
+ android:background="@drawable/button_background"
+ android:text="@string/done"
+ android:textAllCaps="false"
android:textColor="@color/white"
- android:text="Done"
- android:textStyle="normal"
- android:textAllCaps="false" />
- </LinearLayout>
+ android:textStyle="normal" />
+ </RelativeLayout>
</LinearLayout>
diff --git a/app/src/main/res/layout/main_activity_onboarding.xml b/app/src/main/res/layout/main_activity_onboarding.xml
index bf57821..bf8b0c2 100644
--- a/app/src/main/res/layout/main_activity_onboarding.xml
+++ b/app/src/main/res/layout/main_activity_onboarding.xml
@@ -1,25 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
+<ScrollView xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fillViewport="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".onboarding.OnboardingActivity">
-
+ android:background="@color/background">
- <androidx.appcompat.widget.AppCompatImageView
- android:id="@+id/on_boarding_banner"
- style="@style/OnboardingImage"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="50dp"
- android:layout_marginRight="50dp"
- android:adjustViewBounds="true"
- android:scaleType="fitCenter"
- app:srcCompat="@drawable/ic_opentrace_blue_transparent"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
+<androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".onboarding.OnboardingActivity">
<androidx.appcompat.widget.AppCompatTextView
@@ -27,55 +18,201 @@
style="@style/OnboardingTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:gravity="left"
+ android:paddingLeft="30dp"
+ android:paddingRight="30dp"
android:text="@string/tv_onboarding_title"
+ android:textAlignment="center"
+ android:textColor="@color/new_blue_2"
+ android:textSize="24dp"
android:visibility="visible"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/on_boarding_banner" />
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.0"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/imageView" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_desc"
style="@style/OnboardingDesc"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:gravity="left"
+ android:layout_marginTop="16dp"
+ android:paddingLeft="30dp"
+ android:paddingRight="30dp"
android:text="@string/tv_onboarding_desc"
- android:visibility="visible"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
+ android:textAlignment="center"
+ android:textColor="@color/black"
+ android:textSize="19sp"
+ android:visibility="gone"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.0"
+ app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
- <androidx.appcompat.widget.AppCompatTextView
- android:id="@+id/tv_desc_sub"
- style="@style/OnboardingSubDesc"
- android:layout_width="0dp"
+ <TextView
+ android:id="@+id/language"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:gravity="left"
- android:text="@string/tv_onboarding_desc_sub"
- android:visibility="visible"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/tv_desc" />
+ android:text="@string/language_choice"
+ android:textColor="@color/new_blue"
+ android:textSize="18sp"
+ android:textStyle="bold"
+ android:textAlignment="viewStart"
+ android:layout_marginStart="24dp"
+ app:layout_constraintBottom_toTopOf="@+id/tv_title"
+ app:layout_constraintEnd_toStartOf="parent"
+ app:layout_constraintStart_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintVertical_bias="0.169" />
- <Button
- android:id="@+id/btn_onboardingStart"
+ <TextView
+ android:id="@+id/textView7"
android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_gravity="center_horizontal|bottom"
- android:layout_marginBottom="24dp"
- android:background="@drawable/gradient"
- android:layout_marginLeft="24dp"
- android:layout_marginRight="24dp"
- android:textAllCaps="false"
- android:textFontWeight="600"
- android:fontFamily="@font/font"
- android:textSize="18sp"
- android:text="@string/i_want_to_help"
- android:textColor="#fff"
+ android:layout_height="wrap_content"
+ android:paddingLeft="24dp"
+ android:paddingRight="24dp"
+ android:text="@string/conditions"
+ android:textColor="@color/new_blue_2"
+ android:textSize="19sp"
+ android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent" />
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.0"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/tv_desc"
+ app:layout_constraintVertical_bias="0.05" />
+
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/cardView"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="18dp"
+ android:layout_marginRight="18dp"
+ app:cardCornerRadius="6dp"
+ app:cardElevation="1dp"
+ app:cardUseCompatPadding="true"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/textView7">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="10dp"
+ android:paddingBottom="10dp"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/textView8"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:drawableStart="@drawable/ic_bluetooth_condition"
+ android:drawablePadding="10dp"
+ android:paddingLeft="6dp"
+ android:paddingRight="6dp"
+ android:text="@string/conditions_bluetooth"
+ android:textColor="@color/black"
+ android:textSize="16sp" />
+
+ <TextView
+ android:id="@+id/textView9"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:paddingLeft="6dp"
+ android:paddingRight="6dp"
+ android:drawableStart="@drawable/ic_infecter_condition"
+ android:drawablePadding="10dp"
+ android:textSize="16sp"
+ android:textColor="@color/black"
+ android:text="@string/conditions_send_infos" />
+
+ <TextView
+ android:id="@+id/textView10"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:paddingLeft="6dp"
+ android:paddingRight="6dp"
+ android:drawableStart="@drawable/ic_contact_condition"
+ android:drawablePadding="10dp"
+ android:textSize="16sp"
+ android:textColor="@color/black"
+ android:text="@string/conditions_call_you" />
+
+ </LinearLayout>
+
+ </androidx.cardview.widget.CardView>
+
+
+ <ImageView
+ android:id="@+id/imageView"
+ android:layout_width="match_parent"
+ android:layout_height="135dp"
+ android:scaleType="centerCrop"
+ android:src="@drawable/ic_morocco_illustartion_masked"
+ app:layout_constraintBottom_toTopOf="@+id/tv_title"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/language"
+ app:layout_constraintVertical_bias="1.0" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintHorizontal_bias="0.0"
+ app:layout_constraintTop_toBottomOf="@id/cardView"
+ android:orientation="vertical">
+
+ <covid.trace.morocco.view.StepProgressBar
+ android:id="@+id/pbProgress"
+ style="@style/MyProgressBar"
+ android:indeterminate="false"
+ android:layout_gravity="center_horizontal"
+ android:layout_height="300dp"
+ android:layout_marginBottom="17dp"
+ android:layout_marginTop="10dp"
+ android:layout_width="match_parent"
+ app:cumulativeDots="true"
+ app:activeDotIndex="0"
+ app:activeDotIcon="@drawable/ic_progress_active"
+ app:inactiveDotIcon="@drawable/ic_progress_inactive"
+ app:numberDots="4"
+ app:spacing="8dp" />
+
+ <Button
+ android:id="@+id/btn_onboardingStart"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="24dp"
+ android:layout_marginEnd="24dp"
+ android:layout_marginBottom="15dp"
+ android:background="@drawable/button_background"
+ android:text="@string/i_want_to_help"
+ android:textAllCaps="false"
+ android:textColor="#fff"
+ android:textFontWeight="600"
+ android:textSize="18sp"
+ />
+
+ <TextView
+ android:id="@+id/tou"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="24dp"
+ android:textAlignment="center"
+ android:paddingLeft="24dp"
+ android:paddingRight="24dp"
+ android:textSize="14sp"
+ android:textColor="@color/new_blue"
+ android:text="@string/link_conditions" />
+
+
+ </LinearLayout>
+
</androidx.constraintlayout.widget.ConstraintLayout>
+
+</ScrollView>
diff --git a/app/src/main/res/layout/recycler_view_item.xml b/app/src/main/res/layout/recycler_view_item.xml
index 30b53eb..8a20fce 100644
--- a/app/src/main/res/layout/recycler_view_item.xml
+++ b/app/src/main/res/layout/recycler_view_item.xml
@@ -7,9 +7,9 @@
android:layout_margin="8dp"
android:background="@color/dark"
android:orientation="vertical"
- android:paddingLeft="8dp"
+ android:paddingStart="8dp"
android:paddingTop="8dp"
- android:paddingRight="8dp">
+ android:paddingEnd="8dp">
<androidx.appcompat.widget.AppCompatTextView
android:text="Payload:"
@@ -45,8 +45,8 @@
android:layout_height="wrap_content"
android:text="Central"
app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintLeft_toLeftOf="@id/modelc"
- app:layout_constraintRight_toRightOf="@id/modelc" />
+ app:layout_constraintStart_toStartOf="@id/modelc"
+ app:layout_constraintEnd_toEndOf="@id/modelc" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/modelc"
@@ -54,7 +54,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/text_central"
- app:layout_constraintLeft_toLeftOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
android:text="MODEL_C"
android:textSize="16dp"
android:textColor="@color/off_white" />
@@ -66,8 +66,8 @@
android:tint="@color/off_white"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintLeft_toRightOf="@id/modelc"
- app:layout_constraintRight_toLeftOf="@id/modelp" />
+ app:layout_constraintStart_toEndOf="@id/modelc"
+ app:layout_constraintEnd_toStartOf="@id/modelp" />
<androidx.appcompat.widget.AppCompatTextView
@@ -76,8 +76,8 @@
android:layout_height="wrap_content"
android:text="Peripheral"
app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintLeft_toLeftOf="@id/modelp"
- app:layout_constraintRight_toRightOf="@id/modelp" />
+ app:layout_constraintStart_toStartOf="@id/modelp"
+ app:layout_constraintEnd_toEndOf="@id/modelp" />
<androidx.appcompat.widget.AppCompatTextView
@@ -87,7 +87,7 @@
android:textSize="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- app:layout_constraintRight_toRightOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_peri"
android:textColor="@color/off_white" />
@@ -146,8 +146,8 @@
android:layout_height="wrap_content"
android:text="ModelC"
android:textSize="16dp"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toLeftOf="@id/filter_by_modelp"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/filter_by_modelp"
app:layout_constraintTop_toTopOf="parent" />
<Button
@@ -156,8 +156,8 @@
android:layout_height="wrap_content"
android:text="ModelP"
android:textSize="16dp"
- app:layout_constraintLeft_toRightOf="@id/filter_by_modelc"
- app:layout_constraintRight_toRightOf="parent"
+ app:layout_constraintStart_toEndOf="@id/filter_by_modelc"
+ app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml
index ef6aaf9..6a34425 100644
--- a/app/src/main/res/menu/bottom_nav_menu.xml
+++ b/app/src/main/res/menu/bottom_nav_menu.xml
@@ -6,14 +6,19 @@
android:icon="@drawable/ic_home"
android:title="@string/title_home" />
+ <item
+ android:id="@+id/navigation_news"
+ android:icon="@drawable/ic_stats"
+ android:title="@string/title_upload" />
+
<item
android:id="@+id/navigation_upload"
android:icon="@drawable/ic_upload"
- android:title="@string/title_upload" />
+ android:title="@string/title_upload_files" />
<item
android:id="@+id/navigation_help"
- android:icon="@drawable/ic_help"
+ android:icon="@drawable/ic_advices"
android:title="@string/title_help" />
</menu>
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
index 003460a..ac3995c 100644
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
index e0610fb..d1a8bc7 100644
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index 3fdb115..7b9497a 100644
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index dbfd576..6cf44b7 100644
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index 4c982bf..cbf71fe 100644
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8cce4aa..437ba19 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -14,16 +14,16 @@
<color name="transparent">#00000000</color>
<color name="black">#000000</color>
- <color name="primary_blue_1">#0030A1</color>
- <color name="primary_blue_2">#003DB5</color>
- <color name="primary_blue_3">#004AC9</color>
- <color name="primary_blue_4">#0057DD</color>
- <color name="primary_blue_5">#0057DD</color>
+ <color name="primary_blue_1">#B32A33</color>
+ <color name="primary_blue_2">#D8B32A33</color>
+ <color name="primary_blue_3">#BCB32A33</color>
+ <color name="primary_blue_4">#A1B32A33</color>
+ <color name="primary_blue_5">#88B32A33</color>
<color name="secondary_blue_1">#04A5FF</color>
<color name="secondary_blue_2">#0798EB</color>
<color name="secondary_blue_3">#0A83D7</color>
- <color name="secondary_blue_4">#0D6CC3</color>
+ <color name="secondary_blue_4">#00622E</color>
<color name="grey_1">#202020</color>
<color name="grey_2">#383838</color>
@@ -43,8 +43,20 @@
<color name="green">#449D44</color>
<color name="grey">#E5E5E5</color>
- <color name="light_blue">#E6EDF7</color>
+ <color name="light_blue">#1E449D44</color>
<color name="light_yellow">#FFF5DC</color>
<color name="blue_update">#0030A1</color>
+
+
+ <!-- new color -->
+ <color name="light_blue2">#647AE7</color>
+ <color name="light_grey">#EEF1FF</color>
+
+ <color name="new_blue">#157BFF</color>
+ <color name="new_blue_2">#122B4A</color>
+ <color name="new_red">#FF1515</color>
+ <color name="sky_blue">#00E1C5</color>
+ <color name="yellow">#FFC115</color>
+ <color name="background">#F5F7F9</color>
</resources>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d4ba1aa..ff56567 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,91 +1,156 @@
<resources>
- <string name="see_connections">See connections</string>
- <string name="stop">Stop</string>
- <string name="permission_location_rationale">Please allow Location Permissions - Google requires this for your phone to scan for another phone’s Bluetooth. We do not use or store your location.</string>
- <string name="permission_write_rationale">OpenTrace needs save files for logs (Debug builds only)</string>
- <string name="ble_not_supported">This device does not support BLE</string>
-
- <string name="tv_onboarding_title">Help stop the spread of COVID-19 by turning Bluetooth on</string>
- <string name="tv_onboarding_desc">If you had close contact with a COVID-19 case, we help the health authorities call you more quickly, to provide guidance and care.</string>
- <string name="tv_onboarding_desc_sub">To protect those around you, OTC may also ask you to share your data.</string>
- <string name="i_want_to_help">I want to help</string>
-
- <string name="tv_howitworks_title">How OpenTrace works</string>
- <string name="tv_howitworks_explanation_1">We use Bluetooth signals to determine if you are near another OpenTrace user.</string>
- <string name="tv_howitworks_explanation_2">This proximity data is encrypted and stored only on your phone.</string>
- <string name="tv_howitworks_explanation_3">OTC will seek your consent to upload the data, if it\'s needed for contact tracing.</string>
- <string name="mobile_number">Mobile number</string>
- <string name="register_number">Register your mobile number</string>
- <string name="register_number_details">We\'ll contact you if you had close contact with a COVID-19 case.</string>
- <string name="register_number_family">Setting up for your family? \nUse their number instead of yours.</string>
- <string name="invalid_length">Needs to be 8-digits</string>
- <string name="invalid_number">Invalid Mobile Number</string>
-
- <string name="enter_otp">Enter your OTP</string>
- <string name="otp_sent">A 6-digit code has been sent to %s.</string>
- <string name="resend_code"><u>Resend Code</u></string>
-
- <string name="setup_app_permission">\Set up app permissions</string>
- <string name="setup_app_permission_title">Select \'<b>Yes</b>\' or \'<b>Allow</b>\' for the next few screens to set up.</string>
- <string name="bluetooth">1. Bluetooth</string>
- <string name="location_permissions">2. Location Permissions</string>
- <string name="battery_optimiser_opt">3. Battery Optimiser</string>
- <string name="notes">Android needs Location Permissions for Bluetooth to work. We don\'t have access to your physical location.</string>
- <string name="proceed">Proceed</string>
- <string name="continue_">Continue</string>
- <string name="get_otp">Get OTP</string>
- <string name="wrong_number"><u>Wrong Number?</u></string>
- <string name="app_permission_fully_setup">App permissions are fully set up</string>
- <string name="app_permission_fully_setup_desc">Please leave all settings on until the outbreak ends.</string>
-
- <string name="send_otp">We\'ll text you a One-Time Pin (OTP)</string>
-
- <string name="title_home">Home</string>
- <string name="title_upload">Upload</string>
- <string name="title_help">Help</string>
-
- <string name="how_to_help">How you can help stop the spread of COVID-19</string>
- <string name="help_action">Keep app open, and let it run in the background until the end of the outbreak</string>
-
- <string name="app_permission_status">App Permissions Status</string>
- <string name="bluetooth_on">Bluetooth: On</string>
- <string name="location_on">Location Permission: On</string>
- <string name="battery_optimiser">Battery Optimisation: Off</string>
- <string name="push_noti">Push Notification: On</string>
- <string name="share_this_app">Share this app</string>
- <string name="ask_friend">Ask friends and family to help</string>
- <string name="help_us_identify">Help stop the virus spread by allowing all permissions</string>
- <string name="restart_app_setup">Complete app setup</string>
- <string name="upload_data">Upload Data</string>
- <string name="for_official_use">For use by contact tracers</string>
- <string name="data_uploaded">Data has been uploaded to contact tracers</string>
- <string name="upload_agreement">By uploading, you agree to share with OTC your OpenTrace proximity data for the past 21 days. <b>We do not collect any geolocation or personal data.</b></string>
- <string name="enter_code">Enter Code</string>
- <string name="submit">Submit</string>
- <string name="open_location_setting">Application needs location permission in order to work. Do you want to enable location permission?</string>
+ <string name="see_connections">voir les connexions</string>
+ <string name="stop">Arrêtez</string>
+ <string name="permission_location_rationale">Veuillez autoriser la localisation - Google en a besoin pour que votre téléphone recherche le Bluetooth d\'un autre téléphone. Nous n\'utilisons ni stockons votre emplacement.</string>
+ <string name="permission_write_rationale">Wiqaytna a besoin de fichiers de sauvegarde pour les journaux (versions de débogage uniquement)</string>
+ <string name="ble_not_supported">Cet appareil ne prend pas en charge BLE</string>
+ <string name="tv_onboarding_title">Participons tous à la lutte contre la propagation du Coronavirus COVID-19</string>
+ <string name="tv_onboarding_desc">Wiqaytna vous notifie si l\’une des personnes qui s\’est trouvée à proximité de vous récemment est confirmée positive au COVID-19 </string>
+ <string name="tv_onboarding_desc_sub">Pour protéger votre entourage, Le ministère de la santé peut également vous demander de partager vos données.</string>
+ <string name="i_want_to_help">Continuer</string>
+ <string name="tv_howitworks_title">Comment fonctionne Wiqaytna</string>
+ <string name="tv_howitworks_explanation_1">Nous utilisons des signaux Bluetooth pour déterminer si vous êtes près d\'un autre utilisateur de Wiqaytna.</string>
+ <string name="tv_howitworks_explanation_2">Ces données de proximité sont cryptées et stockées uniquement sur votre téléphone.</string>
+ <string name="tv_howitworks_explanation_3">L\'Le ministère de la santé demandera votre consentement pour télécharger les données, si cela est nécessaire pour la recherche des contacts.</string>
+ <string name="mobile_number">Numéro de portable </string>
+ <string name="register_number">Veuillez saisir votre numéro de téléphone </string>
+ <string name="register_number_details">Nous vous contacterons si vous avez été en contact étroit avec une personne infectée par COVID-19.</string>
+ <string name="register_number_family">Vous installez pour votre famille? Utilisez leur numéro au lieu du vôtre.</string>
+ <string name="invalid_length">Doit être composé de 8 chiffres</string>
+ <string name="invalid_number">Numéro de portable invalide</string>
+ <string name="enter_otp">Veuillez saisir le code de confirmation que vous avez reçu par SMS</string>
+ <string name="otp_sent">Un code à 6 chiffres a été envoyé à %s.</string>
+ <string name="resend_code">Renvoyer le code</string>
+ <string name="setup_app_permission">Veuillez accorder les autorisations nécessaires </string>
+ <string name="setup_app_permission_title">Sélectionnez <b>Oui</b> ou <b>Autoriser</b> pour les prochains écrans à configurer.</string>
+ <string name="bluetooth">Activation du Bluetooth</string>
+ <string name="location_permissions">Autorisations de localisation</string>
+ <string name="battery_optimiser_opt">Optimiseur de batterie</string>
+ <string name="notes">Android a besoin des autorisations de localisation pour que le Bluetooth fonctionne. Nous n\'avons pas accès à votre emplacement physique.</string>
+ <string name="proceed">Procéder</string>
+ <string name="continue_">Continuer</string>
+ <string name="get_otp">Confirmer</string>
+ <string name="wrong_number"><u>Mauvais numéro?</u></string>
+ <string name="app_permission_fully_setup">Les autorisations d\'application sont entièrement configurées</string>
+ <string name="app_permission_fully_setup_desc">Veuillez laisser tous les paramètres activés jusqu\'à la fin de l\'épidémie.</string>
+ <string name="send_otp">Vous receverez un code par SMS pour confirmer votre numéro de portable. Le code sera valable pendant 5 minutes.</string>
+ <string name="title_home">Accueil</string>
+ <string name="title_upload">Statistiques</string>
+ <string name="title_upload_files">Téléverser</string>
+ <string name="title_help">Conseils</string>
+ <string name="how_to_help">Comment vous pouvez aider à stopper la propagation de COVID-19</string>
+ <string name="help_action">Maintient l\'application ouverte, et laisse la s\'exécuter en arrière plan, jusqu\'à la fin de l\'epidemie</string>
+ <string name="app_permission_status">État des autorisations de l\'application</string>
+ <string name="bluetooth_on">Bluetooth: Activé</string>
+ <string name="location_on">Autorisation position: Activé</string>
+ <string name="battery_optimiser">Optimisation batterie: Désactivé</string>
+ <string name="push_noti">Notifications push</string>
+ <string name="share_this_app">Partagez l\'application avec votre famille et vos proches.</string>
+ <string name="ask_friend">Demande à vos amis et à votre famille à aider</string>
+ <string name="help_us_identify">Aidez à stopper la propagation du virus en accordant toutes les autorisations</string>
+ <string name="restart_app_setup">Configuration complète de l\'application</string>
+ <string name="upload_data">Envoyer mes données</string>
+ <string name="for_official_use">À utiliser par les traceurs de contact</string>
+ <string name="data_uploaded">Les données ont été envoyées pour contacter les traceurs</string>
+ <string name="upload_agreement">En envoyant, vous acceptez de partager les données Bluetooth anonymes collectées sur les autres smartphones qui se sont trouvés à proximité de vous pendant les 21 derniers jours. Ces données permetteront de notifier les autres utilisateurs au risque d\'exposition au coronavirus COVID-19</string>
+ <string name="enter_code">Entrez le code</string>
+ <string name="submit">Soumettre</string>
+ <string name="open_location_setting">L\'application a besoin d\'une autorisation de localisation pour fonctionner. Voulez-vous activer l\'autorisation de localisation?</string>
<string name="ok">OK</string>
- <string name="cancel">Cancel</string>
- <string name="setup_incomplete">Setup is incomplete!</string>
- <string name="ack_title">Your consent is needed for the following:</string>
- <string name="ack_mobile">To store your mobile number in a secured OpenTrace registry</string>
- <string name="ack_data">To allow OpenTrace users to send OTC information of encounters with you, if they are confirmed or suspected to have COVID-19</string>
- <string name="otp">Please enter the OTP sent to your mobile phone via sms</string>
- <string name="keep_push_on">Keep push notifications on too, so we can alert you if the app is not scanning.</string>
- <string name="verification_failed">Verification failed. Please try again</string>
- <string name="invalid_otp">Wrong OTP entered</string>
- <string name="unknown_error">An error has occurred. Please try again</string>
- <string name="must_be_six_digit">Must be a 6-digit number</string>
- <string name="invalid_user">Your account has been disabled. Please contact support.</string>
- <string name="too_many_requests">Too many requests. Please try again later.</string>
-
- <string name="privacy_safeguards"><u>privacy safeguards</u></string>
-
- <string name="service_ok_title">OpenTrace is scanning to keep you safe! :)</string>
- <string name="service_ok_body">Restart phone if this notification disappears</string>
-
- <string name="service_not_ok_title">Oh no! :(</string>
- <string name="service_not_ok_body">OpenTrace is not scanning.</string>
- <string name="service_not_ok_action">Check app now</string>
-
- <string name="share_message">Join me in stopping the spread of COVID-19! Download OpenTrace. Go to: https://bluetrace.io</string>
+ <string name="cancel">Annuler</string>
+ <string name="setup_incomplete">Wiqaytna est inactive</string>
+ <string name="ack_title">Votre consentement est nécessaire pour les éléments suivants:</string>
+ <string name="ack_mobile">Pour stocker votre numéro de mobile dans un registre Wiqaytna sécurisé</string>
+ <string name="ack_data">Pour permettre aux utilisateurs de Wiqaytna d\'envoyer des informations Le ministère de la santé sur vos rencontres, s\'ils sont confirmés ou soupçonnés d\'avoir COVID-19</string>
+ <string name="otp">Veuillez saisir le code envoyé sur votre téléphone mobile via sms</string>
+ <string name="keep_push_on">Gardez également les notifications push activées, afin que nous puissions vous alerter si l\'application ne scanne pas.</string>
+ <string name="verification_failed">Échec de la vérification. Veuillez réessayer</string>
+ <string name="invalid_otp">Le code de vérification saisi est incorrect</string>
+ <string name="unknown_error">Une erreur est survenue. Veuillez réessayer</string>
+ <string name="must_be_six_digit">Doit être un nombre à 6 chiffres</string>
+ <string name="invalid_user">Votre compte a été désactivé. Veuillez contacter le support.</string>
+ <string name="too_many_requests">Trop de demandes. Veuillez réessayer plus tard.</string>
+ <string name="privacy_safeguards"><u>Garanties de confidentialité</u></string>
+ <string name="service_ok_title">Wiqaytna fonctionne correctement </string>
+ <string name="service_ok_body">L’application est active. </string>
+ <string name="service_not_ok_title">L\’application Wiqaytna est inactive</string>
+ <string name="service_not_ok_body">Wiqaytna n\'analyse pas.</string>
+ <string name="service_not_ok_action">Vérifiez l\'application maintenant</string>
+ <string name="share_message">Rejoignez-moi pour arrêter la propagation de COVID-19! Téléchargez Wiqaytna. Accédez à: www.wiqaytna.ma</string>
+ <string name="forusermho">Utilisez cette interface uniquement si vous êtes contacté par les équipes du Ministère de la Santé.</string>
+ <string name="uploadedtomho">Les données ont été reçues avec succès par les équipes du Ministère de la santé</string>
+ <string name="verify_contact_mho">Vérifiez que le traceur de contact est du ministère de la santé</string>
+ <string name="applicationname">wiqaynta</string>
+ <string name="great">Génial!!!</string>
+ <string name="read_our">Lisez notre </string>
+ <string name="agree">j\'accèpte</string>
+ <string name="upload_screen_next">Appuyer sur suivant uniquement si vous avez reçu un appel du ministère de la santé dont l\'objectif est d\'avoir les données des personnes avec lesquelles vous avez été en contact</string>
+ <string name="next">Suivant</string>
+ <string name="stpe_1">ETAPE 1</string>
+ <string name="stpe_2">ETAPE 2</string>
+ <string name="verification_code">Code de vérification: </string>
+ <string name="make_sure">Assurez-vous qu\'ils vous donnent un code qui correspond à celui ci-dessous.</string>
+ <string name="enter_pin">Merci de saisir le code communiqué par les équipes du Ministère de la Santé pour envoyer les données collectées. </string>
+ <string name="invalid_pin">Code de vérification saisi est incorrect</string>
+ <string name="done">Effectué</string>
+ <string name="last_update">Dernière mise à jour :</string>
+ <string name="ville">Ville</string>
+ <string name="region">Région</string>
+ <string name="age">Tranche d\'âge</string>
+ <string name="woman">Femme</string>
+ <string name="man">Homme</string>
+ <string name="gender">Genre</string>
+ <string name="code_expire">Votre code expirera dans</string>
+ <string name="language_choice">العربية</string>
+ <string name="verify">Vérifier</string>
+ <string name="death">Décès</string>
+ <string name="healing_state">Guéris</string>
+ <string name="confirmed_cases">Cas confirmés</string>
+ <string name="latest_epidemic_statistics">Dernières statistiques</string>
+ <string name="last_update_24_hours_ago">Dernière mise à jour : </string>
+ <string name="sum_cases">Statistiques depuis le début de l\'épidémie</string>
+ <string name="advices">Conseils</string>
+ <string name="language">Langue d\'utilisation de l\'application </string>
+ <string name="arabe">العربية</string>
+ <string name="french">Français</string>
+ <string name="welcome">Wiqaytna est active</string>
+ <string name="thanks_for_help">Merci de votre contribution à la lutte contre la propagation du coronavirus COVID-19.</string>
+ <string name="conditions">Comment ça marche ?</string>
+ <string name="usage">Fonctionnement de l\'application</string>
+ <string name="needed_permissions"> Sehatuna requiert votre acceptation des éléments suivants :\nEnregistrer votre numéro de téléphone dans nos données sécurisées\n\nDans le cas d\'utilisateurs confirmés, envoyez des informations sur les personnes à proximité\n\nVous appeler si vous soupçonnez d\'être infecté après avoir été proche d\'une personne infectée"</string>
+ <string name="conditions_bluetooth">L\’application enregistre sur votre téléphone les identifiants anonymes des portables à proximité de vous</string>
+ <string name="conditions_send_infos">Vous recevrez une notification si vous avez été à proximité d\'une personne confirmée positive au COVID-19</string>
+ <string name="conditions_call_you">Suivez les recommandations du Ministère de la santé qui vous seront notifiées</string>
+ <string name="link_conditions"><u>Conditions générales d\’utilisation</u></string>
+ <string name="first_range">15 à 25 ans</string>
+ <string name="second_range">26 à 40 ans</string>
+ <string name="third_range">41 à 65 ans</string>
+ <string name="fourth_range">66 et plus</string>
+ <string name="save">Sauvegarder</string>
+ <string name="number_confirmes_cases">Répartition par région </string>
+ <string name="country_code">+212</string>
+ <string name="upload_infos">Les données seront envoyées après saisi du code reçu de la part du ministère de la santé</string>
+ <string name="province">Province ou préfecture</string>
+ <string name="confirmation_code">رقم التأكيد</string>
+ <string name="will_receive_code">ستتوصل براسلة قصيرة تحتوي عل رقم التأكيد أو كود</string>
+ <string name="need_bluetooth">Les autorisations suivantes sont nécessaires pour le bon fonctionnement de l\'application</string>
+ <string name="data_upload">Merci de votre geste citoyen!</string>
+ <string name="advice_1">Se laver fréquemment les mains</string>
+ <string name="advice_2">Éviter de se toucher les yeux, le nez et la bouche</string>
+ <string name="advice_3">Éviter les contacts proches</string>
+ <string name="advice_4">Éviter les rassemblements collectifs non indispensables</string>
+ <string name="advice_5">Se couvrir la bouche et le nez avec avec un mouchoir jetable ou le pli du coude en cas de toux ou d’éternuement</string>
+ <string name="advice_7">Se tenir informé et suivre les conseils de votre médecin</string>
+ <string name="advice_8">Appeler le 0801004747, le 141 ou le 300, en cas de fièvre, toux et difficulté respiratoire</string>
+ <string name="advice_9">Porter le masque de protection avant de sortir </string>
+ <string name="infos_sent">Echec de l \'envoi des données</string>
+ <string name="advice_6">Ne pas cracher dans les lieux publics</string>
+ <string name="propagation_stats">Statistiques sur la propagation du virus :</string>
+ <string name="we_dont_collect_gps_infos">L\'autorisation de localisation est nécessaire pour permettre aux téléphones android de communiquer via Bluetooth. Cette autorisation ne permet pas l\'accés à la position GPS</string>
+ <string name="otp_expiry">Votre code de validation va expirer dans</string>
+ <string name="server_problem">Problème de connexion au serveur. Merci de rééssayer plus tard</string>
+ <string name="faq"><b>Foire Aux Questions (FAQ)</b>\nTout ce que vous devez savoir</string>
+ <string name="advice_title">Respectez les conseils suivants pour vous protéger et protéger vos proches</string>
+ <string name="notif_storage_problem">Accès stockage impossible</string>
+ <string name="notif_storage_problem_sub">Merci de vérifier votre espace de stockage</string>
</resources>
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index ec01359..d58fc1f 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -5,27 +5,16 @@
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
- <item name="android:fontFamily">@font/font</item>
- <item name="fontFamily">@font/font</item>
</style>
<style name="AppTheme.DebugNoActionBar" parent="Theme.AppCompat.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
- <item name="android:fontFamily">@font/font</item>
- <item name="fontFamily">@font/font</item>
</style>
- <style name="button" parent="@android:style/Widget.Button">
- <item name="android:fontFamily">@font/font</item>
- <item name="fontFamily">@font/font</item>
- </style>
- <style name="AppFont">
- <item name="android:fontFamily">@font/font</item>
- <item name="fontFamily">@font/font</item>
- </style>
+ <style name="AppFont"></style>
<style name="Theme.AppCompat.Transparent.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
@@ -60,16 +49,20 @@
<item name="android:layout_marginTop">15dp</item>
<item name="android:paddingLeft">24dp</item>
<item name="android:paddingRight">24dp</item>
- <item name="android:textSize">24sp</item>
+ <item name="android:textSize">20sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/grey_2</item>
</style>
+ <style name="SelectedItemTitle">
+ <item name="android:textStyle">bold</item>
+ </style>
+
<style name="OnboardingDesc" parent="AppFont">
<item name="android:layout_marginTop">15dp</item>
<item name="android:paddingLeft">24dp</item>
<item name="android:paddingRight">24dp</item>
- <item name="android:textSize">18sp</item>
+ <item name="android:textSize">16sp</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/grey_3</item>
</style>
@@ -78,7 +71,7 @@
<item name="android:layout_marginTop">15dp</item>
<item name="android:paddingLeft">20dp</item>
<item name="android:paddingRight">24dp</item>
- <item name="android:textSize">18sp</item>
+ <item name="android:textSize">16sp</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/grey_3</item>
</style>
@@ -87,7 +80,7 @@
<item name="android:layout_marginTop">15dp</item>
<item name="android:paddingLeft">0dp</item>
<item name="android:paddingRight">0dp</item>
- <item name="android:textSize">18sp</item>
+ <item name="android:textSize">16sp</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/grey_3</item>
</style>
diff --git a/build.gradle b/build.gradle
index 4eec81e..6acf097 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,10 +6,6 @@ buildscript {
google()
jcenter()
- maven {
- url 'https://maven.fabric.io/public'
- }
-
maven {
url "https://plugins.gradle.org/m2/"
}
@@ -18,9 +14,13 @@ buildscript {
classpath 'com.android.tools.build:gradle:3.5.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.3'
+
+ // Add the dependency for the Performance Monitoring plugin
+ classpath 'com.google.firebase:perf-plugin:1.3.1' // Performance Monitoring plugin
+
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
- classpath 'io.fabric.tools:gradle:1.31.2'
+ classpath 'com.google.firebase:firebase-crashlytics-gradle:2.0.0'
classpath "gradle.plugin.com.cookpad.android.plugin:plugin:1.2.2"
classpath 'com.jaredsburrows:gradle-license-plugin:0.8.70'
}
diff --git a/settings.gradle b/settings.gradle
index ff1bb3e..dd0b217 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,2 +1,2 @@
include ':app'
-rootProject.name='Tracer'
+rootProject.name='Wiqaytna'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment