diff --git a/.github/workflows/build-iOS.yml b/.github/workflows/build-iOS.yml index 9961522cab..bc7f17f7ba 100644 --- a/.github/workflows/build-iOS.yml +++ b/.github/workflows/build-iOS.yml @@ -10,12 +10,12 @@ jobs: runs-on: macOS-latest strategy: matrix: - destination: ['platform=iOS Simulator,OS=13.7,name=iPhone 11'] + destination: ['platform=iOS Simulator,OS=15.0,name=iPhone 11'] steps: - name: Checkout uses: actions/checkout@v2 - - name: Force XCode 11.7 - run: sudo xcode-select -switch /Applications/Xcode_11.7.app + - name: Force XCode 13.0 + run: sudo xcode-select -switch /Applications/Xcode_13.0.app - name: Build run: | cd iOS/MyStudies diff --git a/.github/workflows/lint-android.yml b/.github/workflows/lint-android.yml index 5fcd980282..90b0a746df 100644 --- a/.github/workflows/lint-android.yml +++ b/.github/workflows/lint-android.yml @@ -15,7 +15,7 @@ jobs: - name: Checkout uses: actions/checkout@v2 - name: Run check style - uses: nikitasavinov/checkstyle-action@master + uses: naveenr-btc/checkstyle-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }} reporter: 'github-pr-check' diff --git a/Android/.idea/runConfigurations.xml b/Android/.idea/runConfigurations.xml deleted file mode 100644 index 7f68460d8b..0000000000 --- a/Android/.idea/runConfigurations.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/Android/app/build.gradle b/Android/app/build.gradle index 19d48858b3..999d3bbc1a 100644 --- a/Android/app/build.gradle +++ b/Android/app/build.gradle @@ -15,13 +15,13 @@ android { } } - compileSdkVersion 29 + compileSdkVersion 31 buildToolsVersion "28.0.3" defaultConfig { - minSdkVersion 19 - targetSdkVersion 29 - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + minSdkVersion 21 + targetSdkVersion 31 + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' multiDexEnabled true buildConfigField("String", "API_KEY", apikeyProperties['API_KEY']) buildConfigField("String", "BASE_URL_STUDY_DATASTORE", apikeyProperties['BASE_URL_STUDY_DATASTORE']) @@ -69,12 +69,12 @@ android { } dependencies { - implementation 'com.android.support.constraint:constraint-layout:1.1.3' - implementation 'com.android.support:appcompat-v7:28.0.0' - implementation 'com.android.support:design:28.0.0' - implementation 'com.android.support:support-v4:28.0.0' - implementation 'com.android.support:recyclerview-v7:28.0.0' - implementation 'com.android.support:multidex:1.0.3' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'androidx.appcompat:appcompat:1.0.0' + implementation 'com.google.android.material:material:1.0.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'androidx.recyclerview:recyclerview:1.0.0' + implementation 'androidx.multidex:multidex:2.0.0' implementation 'com.google.firebase:firebase-messaging:17.4.0' implementation 'com.google.firebase:firebase-core:16.0.7' implementation 'com.google.code.gson:gson:2.8.2' @@ -83,23 +83,23 @@ dependencies { implementation 'de.greenrobot:eventbus:2.4.0' implementation 'org.researchstack:backbone:1.1.1' implementation 'com.github.bumptech.glide:glide:4.8.0' - implementation 'com.github.barteksc:android-pdf-viewer:2.4.0' implementation 'com.kovachcode:timePickerWithSeconds:1.0.1' implementation 'com.tom_roush:pdfbox-android:1.8.10.1' - implementation 'com.android.support:customtabs:28.0.0' + implementation 'androidx.browser:browser:1.0.0' implementation 'junit:junit:4.13' - //please remove these 2 dependencies for release build - implementation 'com.facebook.stetho:stetho:1.5.0' - implementation 'com.uphyca:stetho_realm:2.1.0' implementation 'com.github.LucasFsc:Html2Pdf:0.2-beta' + implementation 'com.github.naveenr-btc:RangeSeekBar:3.0.2' - androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { + implementation 'com.github.chrisbanes:PhotoView:2.3.0' + + androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', { exclude group: 'com.android.support', module: 'support-annotations' }) androidTestImplementation "com.squareup.okhttp3:mockwebserver:4.4.0" testImplementation 'org.mockito:mockito-android:2.11.0' + androidTestImplementation 'androidx.test:rules:1.2.0' testImplementation 'junit:junit:4.12' } apply plugin: 'com.google.gms.google-services' diff --git a/Android/app/src/androidTest/java/com/harvard/AppFirebaseMessagingServiceTest.java b/Android/app/src/androidTest/java/com/harvard/AppFirebaseMessagingServiceTest.java index f13c728e9d..0d948d78f2 100644 --- a/Android/app/src/androidTest/java/com/harvard/AppFirebaseMessagingServiceTest.java +++ b/Android/app/src/androidTest/java/com/harvard/AppFirebaseMessagingServiceTest.java @@ -10,7 +10,7 @@ import android.content.Context; import android.os.Bundle; -import android.support.test.InstrumentationRegistry; +import androidx.test.platform.app.InstrumentationRegistry; import com.google.firebase.messaging.RemoteMessage; import com.harvard.storagemodule.DbServiceSubscriber; import com.harvard.studyappmodule.studymodel.Study; @@ -70,9 +70,9 @@ public class AppFirebaseMessagingServiceTest { @Before public void setUp() { - realm = AppController.getRealmobj(InstrumentationRegistry.getTargetContext()); + realm = AppController.getRealmobj(InstrumentationRegistry.getInstrumentation().getTargetContext()); dbServiceSubscriber = new DbServiceSubscriber(); - context = InstrumentationRegistry.getTargetContext(); + context = InstrumentationRegistry.getInstrumentation().getTargetContext(); } @Test @@ -144,7 +144,6 @@ public void execute(Realm realm) { private Study getstudy() { StudyList studyList = new StudyList(); - studyList.setBookmarked(STUDYLISTBOOKMARKED); studyList.setCategory(STUDYLISTCATEGORY); studyList.setLogo(STUDYLISTLOGO); studyList.setPdfPath(STUDYLISTPDFPATH); @@ -166,7 +165,6 @@ private Study getstudy() { private StudyData getStudyData() { Studies studies = new Studies(); - studies.setBookmarked(false); studies.setSiteId(SITEID); studies.setEnrolledDate(ENROLLEDDATE); studies.setParticipantId(PARTICIPANTID); diff --git a/Android/app/src/androidTest/java/com/harvard/ExampleInstrumentedTest.java b/Android/app/src/androidTest/java/com/harvard/ExampleInstrumentedTest.java index 912debb176..979fb2b14d 100644 --- a/Android/app/src/androidTest/java/com/harvard/ExampleInstrumentedTest.java +++ b/Android/app/src/androidTest/java/com/harvard/ExampleInstrumentedTest.java @@ -1,8 +1,8 @@ package com.harvard; import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; @@ -16,11 +16,11 @@ */ @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { - @Test - public void useAppContext() { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); - assertEquals("com.harvard", appContext.getPackageName()); - } + assertEquals("com.harvard", appContext.getPackageName()); + } } diff --git a/Android/app/src/androidTest/java/com/harvard/FdaApplicationTest.java b/Android/app/src/androidTest/java/com/harvard/FdaApplicationTest.java index 50aecca4a6..d1d95399e6 100644 --- a/Android/app/src/androidTest/java/com/harvard/FdaApplicationTest.java +++ b/Android/app/src/androidTest/java/com/harvard/FdaApplicationTest.java @@ -11,7 +11,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.runner.AndroidJUnit4; + import org.junit.Test; import org.junit.runner.RunWith; diff --git a/Android/app/src/androidTest/java/com/harvard/storagemodule/DbServiceSubscriberTest.java b/Android/app/src/androidTest/java/com/harvard/storagemodule/DbServiceSubscriberTest.java index 683b46ce13..23250ef748 100644 --- a/Android/app/src/androidTest/java/com/harvard/storagemodule/DbServiceSubscriberTest.java +++ b/Android/app/src/androidTest/java/com/harvard/storagemodule/DbServiceSubscriberTest.java @@ -11,7 +11,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import android.support.test.InstrumentationRegistry; +import androidx.test.platform.app.InstrumentationRegistry; import com.harvard.studyappmodule.activitylistmodel.ActivitiesWS; import com.harvard.studyappmodule.activitylistmodel.ActivityListData; import com.harvard.studyappmodule.activitylistmodel.AnchorDate; @@ -56,7 +56,7 @@ public class DbServiceSubscriberTest { @Before public void setUp() { - realm = AppController.getRealmobj(InstrumentationRegistry.getTargetContext()); + realm = AppController.getRealmobj(InstrumentationRegistry.getInstrumentation().getTargetContext()); dbServiceSubscriber = new DbServiceSubscriber(); } @@ -155,7 +155,8 @@ private ActivitiesWS getactivitieswsdata() { AnchorRuns anchorRuns = new AnchorRuns(); anchorRuns.setEndDays(TEST_END_DAYS); anchorRuns.setStartDays(TEST_START_DAYS); - anchorRuns.setTime(TEST_TIME); + anchorRuns.setStartTime(TEST_TIME); + anchorRuns.setEndTime(TEST_TIME); RealmList runslist = new RealmList<>(); runslist.add(frequencyRuns); RealmList anchorRunslist = new RealmList<>(); diff --git a/Android/app/src/androidTest/java/com/harvard/studyappmodule/SurveyActivitiesFragmentTest.java b/Android/app/src/androidTest/java/com/harvard/studyappmodule/SurveyActivitiesFragmentTest.java index c7064193f9..01756d4a2b 100644 --- a/Android/app/src/androidTest/java/com/harvard/studyappmodule/SurveyActivitiesFragmentTest.java +++ b/Android/app/src/androidTest/java/com/harvard/studyappmodule/SurveyActivitiesFragmentTest.java @@ -13,7 +13,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; -import android.support.test.InstrumentationRegistry; +import androidx.test.platform.app.InstrumentationRegistry; import com.harvard.storagemodule.DbServiceSubscriber; import com.harvard.studyappmodule.surveyscheduler.SurveyScheduler; import com.harvard.usermodule.webservicemodel.Studies; @@ -50,7 +50,7 @@ public class SurveyActivitiesFragmentTest { @Before public void setUp() { - realm = AppController.getRealmobj(InstrumentationRegistry.getTargetContext()); + realm = AppController.getRealmobj(InstrumentationRegistry.getInstrumentation().getTargetContext()); dbServiceSubscriber = new DbServiceSubscriber(); } @@ -106,7 +106,6 @@ private Studies getStudies() { studies.setStatus(TEST_STATUS); studies.setSiteId(TEST_SITE_ID); studies.setEnrolledDate(TEST_ENROLLMENTDATE); - studies.setBookmarked(TEST_BOOKMARKED); studies.setParticipantId(TEST_PARTICIPANT_ID); studies.setCompletion(TEST_COMPLETION); studies.setAdherence(TEST_ADHERENCE); diff --git a/Android/app/src/androidTest/java/com/harvard/studyappmodule/SurveyActivitiesListAdapterTest.java b/Android/app/src/androidTest/java/com/harvard/studyappmodule/SurveyActivitiesListAdapterTest.java index 1e0c3e65be..f52d88b208 100644 --- a/Android/app/src/androidTest/java/com/harvard/studyappmodule/SurveyActivitiesListAdapterTest.java +++ b/Android/app/src/androidTest/java/com/harvard/studyappmodule/SurveyActivitiesListAdapterTest.java @@ -11,7 +11,7 @@ import static junit.framework.TestCase.assertTrue; import static junit.framework.TestCase.fail; -import android.support.test.InstrumentationRegistry; +import androidx.test.platform.app.InstrumentationRegistry; import com.harvard.studyappmodule.activitylistmodel.ActivitiesWS; import com.harvard.studyappmodule.activitylistmodel.AnchorRuns; import com.harvard.studyappmodule.activitylistmodel.Frequency; @@ -80,7 +80,7 @@ public void getDatesAdapterTest() { TEST_POSITION, joiningdate, startDate, - InstrumentationRegistry.getTargetContext(), status); + InstrumentationRegistry.getInstrumentation().getTargetContext(), status); assertTrue(anchordate.toLowerCase().contains(TEST_RESULT_ONE.toLowerCase())); String regular = @@ -90,7 +90,7 @@ public void getDatesAdapterTest() { TEST_POSITION, startDate, joiningdate, - InstrumentationRegistry.getTargetContext(), status); + InstrumentationRegistry.getInstrumentation().getTargetContext(), status); assertTrue(regular.toLowerCase().contains(TEST_RESULT_TWO.toLowerCase())); String studyLifeTime = @@ -100,7 +100,7 @@ public void getDatesAdapterTest() { TEST_POSITION, startDate, joiningdate, - InstrumentationRegistry.getTargetContext(), status); + InstrumentationRegistry.getInstrumentation().getTargetContext(), status); assertTrue(studyLifeTime.toLowerCase().contains(TEST_RESULT_THREE.toLowerCase())); } @@ -111,7 +111,8 @@ private ActivitiesWS getactivitieswsdata() { AnchorRuns anchorRuns = new AnchorRuns(); anchorRuns.setEndDays(TEST_END_DAYS); anchorRuns.setStartDays(TEST_START_DAYS); - anchorRuns.setTime(TEST_TIME); + anchorRuns.setStartTime(TEST_TIME); + anchorRuns.setEndTime(TEST_TIME); RealmList runslist = new RealmList<>(); runslist.add(frequencyRuns); RealmList anchorRunslist = new RealmList<>(); diff --git a/Android/app/src/androidTest/java/com/harvard/studyappmodule/surveyscheduler/SurveySchedulerTest.java b/Android/app/src/androidTest/java/com/harvard/studyappmodule/surveyscheduler/SurveySchedulerTest.java index 3f0afbb45f..ee15a81968 100644 --- a/Android/app/src/androidTest/java/com/harvard/studyappmodule/surveyscheduler/SurveySchedulerTest.java +++ b/Android/app/src/androidTest/java/com/harvard/studyappmodule/surveyscheduler/SurveySchedulerTest.java @@ -14,7 +14,7 @@ import static org.hamcrest.Matchers.equalTo; import android.content.Context; -import android.support.test.InstrumentationRegistry; +import androidx.test.platform.app.InstrumentationRegistry; import com.google.gson.Gson; import com.harvard.R; import com.harvard.storagemodule.DbServiceSubscriber; diff --git a/Android/app/src/androidTest/java/com/harvard/usermodule/AuthServerWebServiceTest.java b/Android/app/src/androidTest/java/com/harvard/usermodule/AuthServerWebServiceTest.java index deed02c0ee..19c7a65ee2 100644 --- a/Android/app/src/androidTest/java/com/harvard/usermodule/AuthServerWebServiceTest.java +++ b/Android/app/src/androidTest/java/com/harvard/usermodule/AuthServerWebServiceTest.java @@ -11,8 +11,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; import com.google.gson.Gson; import com.harvard.usermodule.webservicemodel.ChangePasswordData; import com.harvard.usermodule.webservicemodel.LoginData; @@ -96,7 +96,7 @@ public MockResponse dispatch(@NotNull RecordedRequest recordedRequest) e.printStackTrace(); } async = new ApiCallSyncronizer(); - ApiCall apiCall = new ApiCall(InstrumentationRegistry.getTargetContext()); + ApiCall apiCall = new ApiCall(InstrumentationRegistry.getInstrumentation().getTargetContext()); apiCall.apiCallPostJson( url.toString(), new HashMap(), @@ -149,7 +149,7 @@ public MockResponse dispatch(@NotNull RecordedRequest recordedRequest) JSONObject params = new JSONObject(); URL url = mockWebServer.url(studyListUrl.toString()).url(); async = new ApiCallSyncronizer(); - ApiCall apiCall = new ApiCall(InstrumentationRegistry.getTargetContext()); + ApiCall apiCall = new ApiCall(InstrumentationRegistry.getInstrumentation().getTargetContext()); apiCall.apiCallPostJson( url.toString(), new HashMap(), @@ -210,7 +210,7 @@ public MockResponse dispatch(@NotNull RecordedRequest recordedRequest) } URL url = mockWebServer.url(studyListUrl.toString()).url(); async = new ApiCallSyncronizer(); - ApiCall apiCall = new ApiCall(InstrumentationRegistry.getTargetContext()); + ApiCall apiCall = new ApiCall(InstrumentationRegistry.getInstrumentation().getTargetContext()); apiCall.apiCallPostJson( url.toString(), new HashMap(), @@ -268,7 +268,7 @@ public MockResponse dispatch(@NotNull RecordedRequest recordedRequest) e.printStackTrace(); } async = new ApiCallSyncronizer(); - ApiCall apiCall = new ApiCall(InstrumentationRegistry.getTargetContext()); + ApiCall apiCall = new ApiCall(InstrumentationRegistry.getInstrumentation().getTargetContext()); apiCall.apiCallPutJson( url.toString(), new HashMap(), diff --git a/Android/app/src/androidTest/java/com/harvard/usermodule/ErrorTest.java b/Android/app/src/androidTest/java/com/harvard/usermodule/ErrorTest.java index e0d3f1ccf2..da487c5a45 100644 --- a/Android/app/src/androidTest/java/com/harvard/usermodule/ErrorTest.java +++ b/Android/app/src/androidTest/java/com/harvard/usermodule/ErrorTest.java @@ -8,17 +8,18 @@ package com.harvard.usermodule; -import static android.support.test.InstrumentationRegistry.getTargetContext; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; import android.content.Intent; import android.net.Uri; -import android.support.test.rule.ActivityTestRule; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.rule.ActivityTestRule; +import androidx.test.runner.AndroidJUnit4; + import com.harvard.AppConfig; import com.harvard.BuildConfig; import com.harvard.R; @@ -38,7 +39,7 @@ public void errorTest() { AppConfig.AppType = BuildConfig.APP_TYPE; Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(URL)) - .setPackage(getTargetContext().getPackageName()); + .setPackage(InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName()); activityRule.launchActivity(intent); onView(withId(R.id.activity_gateway)).check(matches(isDisplayed())); onView(withId(R.id.mNewUserButton)).check(matches(withText(R.string.new_user))); diff --git a/Android/app/src/androidTest/java/com/harvard/usermodule/FileReader.java b/Android/app/src/androidTest/java/com/harvard/usermodule/FileReader.java index d5af50906b..1481a3aa9d 100644 --- a/Android/app/src/androidTest/java/com/harvard/usermodule/FileReader.java +++ b/Android/app/src/androidTest/java/com/harvard/usermodule/FileReader.java @@ -10,7 +10,7 @@ import android.app.Application; import android.content.Context; -import android.support.test.InstrumentationRegistry; +import androidx.test.platform.app.InstrumentationRegistry; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; diff --git a/Android/app/src/androidTest/java/com/harvard/usermodule/ForgotPasswordActivityTest.java b/Android/app/src/androidTest/java/com/harvard/usermodule/ForgotPasswordActivityTest.java index 45599dd439..255145d3cf 100644 --- a/Android/app/src/androidTest/java/com/harvard/usermodule/ForgotPasswordActivityTest.java +++ b/Android/app/src/androidTest/java/com/harvard/usermodule/ForgotPasswordActivityTest.java @@ -8,17 +8,18 @@ package com.harvard.usermodule; -import static android.support.test.InstrumentationRegistry.getTargetContext; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; import android.content.Intent; import android.net.Uri; -import android.support.test.rule.ActivityTestRule; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.rule.ActivityTestRule; +import androidx.test.runner.AndroidJUnit4; + import com.harvard.R; import org.junit.Rule; import org.junit.Test; @@ -37,7 +38,7 @@ public class ForgotPasswordActivityTest { public void launchForgotPasswordActivity() { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(URL)) - .setPackage(getTargetContext().getPackageName()); + .setPackage(InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName()); activityRule.launchActivity(intent); onView(withId(R.id.activity_sign_in)).check(matches(isDisplayed())); onView(withId(R.id.email_text)).check(matches(withText(R.string.forgot_password_text))); diff --git a/Android/app/src/androidTest/java/com/harvard/usermodule/LoginCallbackActivityTest.java b/Android/app/src/androidTest/java/com/harvard/usermodule/LoginCallbackActivityTest.java index 4a138f56ac..bc4dabd902 100644 --- a/Android/app/src/androidTest/java/com/harvard/usermodule/LoginCallbackActivityTest.java +++ b/Android/app/src/androidTest/java/com/harvard/usermodule/LoginCallbackActivityTest.java @@ -8,17 +8,18 @@ package com.harvard.usermodule; -import static android.support.test.InstrumentationRegistry.getTargetContext; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; import android.content.Intent; import android.net.Uri; -import android.support.test.rule.ActivityTestRule; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.rule.ActivityTestRule; +import androidx.test.runner.AndroidJUnit4; + import com.harvard.R; import org.junit.Rule; import org.junit.Test; @@ -36,7 +37,7 @@ public class LoginCallbackActivityTest { public void loginCallbackhandleIntent() { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(URL)) - .setPackage(getTargetContext().getPackageName()); + .setPackage(InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName()); activityRule.launchActivity(intent); onView(withId(R.id.activity_verification_step)).check(matches(isDisplayed())); onView(withId(R.id.verification_steps_label)) diff --git a/Android/app/src/androidTest/java/com/harvard/usermodule/SignupActivityTest.java b/Android/app/src/androidTest/java/com/harvard/usermodule/SignupActivityTest.java index 80e4df79d9..94159fab51 100644 --- a/Android/app/src/androidTest/java/com/harvard/usermodule/SignupActivityTest.java +++ b/Android/app/src/androidTest/java/com/harvard/usermodule/SignupActivityTest.java @@ -8,17 +8,18 @@ package com.harvard.usermodule; -import static android.support.test.InstrumentationRegistry.getTargetContext; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; import android.content.Intent; import android.net.Uri; -import android.support.test.rule.ActivityTestRule; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.rule.ActivityTestRule; +import androidx.test.runner.AndroidJUnit4; + import com.harvard.R; import org.junit.Rule; import org.junit.Test; @@ -36,7 +37,7 @@ public class SignupActivityTest { public void launchForgotPasswordActivity() { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(URL)) - .setPackage(getTargetContext().getPackageName()); + .setPackage(InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName()); activityRule.launchActivity(intent); onView(withId(R.id.activity_signup)).check(matches(isDisplayed())); onView(withId(R.id.email_label)).check(matches(withText(R.string.email_id))); diff --git a/Android/app/src/androidTest/java/com/harvard/usermodule/TermsPrivacyPolicyActivityTest.java b/Android/app/src/androidTest/java/com/harvard/usermodule/TermsPrivacyPolicyActivityTest.java index 8d01b23959..d6062b21b8 100644 --- a/Android/app/src/androidTest/java/com/harvard/usermodule/TermsPrivacyPolicyActivityTest.java +++ b/Android/app/src/androidTest/java/com/harvard/usermodule/TermsPrivacyPolicyActivityTest.java @@ -8,16 +8,17 @@ package com.harvard.usermodule; -import static android.support.test.InstrumentationRegistry.getTargetContext; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; import android.content.Intent; import android.net.Uri; -import android.support.test.rule.ActivityTestRule; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.rule.ActivityTestRule; + import com.harvard.R; import org.junit.Rule; import org.junit.Test; @@ -40,7 +41,7 @@ public class TermsPrivacyPolicyActivityTest { public void termsTest() { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(TERMS_URL)) - .setPackage(getTargetContext().getPackageName()); + .setPackage(InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName()); intent.putExtra(INTENT_TITLE_KEY, INTENT_TITLE_TERMS_VALUE); intent.putExtra(INTENT_URL_KEY, INTENT_URL_TERMS_VALUE); activityRule.launchActivity(intent); @@ -52,7 +53,7 @@ public void termsTest() { public void privacyPolicyTest() { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(PRIVACY_POLICY_URL)) - .setPackage(getTargetContext().getPackageName()); + .setPackage(InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName()); intent.putExtra(INTENT_TITLE_KEY, INTENT_TITLE_PRIVACY_POLICY_VALUE); intent.putExtra(INTENT_URL_KEY, INTENT_URL_PRIVACY_POLICY_VALUE); activityRule.launchActivity(intent); diff --git a/Android/app/src/androidTest/java/com/harvard/webservicemodule/apihelper/ApiCallTest.java b/Android/app/src/androidTest/java/com/harvard/webservicemodule/apihelper/ApiCallTest.java index 1d915ab7b6..33928c0a64 100644 --- a/Android/app/src/androidTest/java/com/harvard/webservicemodule/apihelper/ApiCallTest.java +++ b/Android/app/src/androidTest/java/com/harvard/webservicemodule/apihelper/ApiCallTest.java @@ -10,8 +10,9 @@ import static org.junit.Assert.assertNotNull; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + import com.harvard.studyappmodule.studymodel.Study; import com.harvard.usermodule.webservicemodel.ForgotPasswordData; import com.harvard.utils.Urls; @@ -38,7 +39,7 @@ public void apiCallGetTest() { studyListUrl.append(Urls.BASE_URL_STUDY_DATASTORE); studyListUrl.append(Urls.STUDY_LIST); async = new ApiCallSyncronizer(); - ApiCall apiCall = new ApiCall(InstrumentationRegistry.getTargetContext()); + ApiCall apiCall = new ApiCall(InstrumentationRegistry.getInstrumentation().getTargetContext()); apiCall.apiCallGet( studyListUrl.toString(), new HashMap(), @@ -72,7 +73,7 @@ public void apiCallPostHashmapTest() { HashMap params = new HashMap<>(); params.put(PARAMS_EMAIL_KEY, PARAMS_EMAIL_VALUE); params.put(PARAMS_APPID_KEY, PARAMS_APPID_VALUE); - ApiCall apiCall = new ApiCall(InstrumentationRegistry.getTargetContext()); + ApiCall apiCall = new ApiCall(InstrumentationRegistry.getInstrumentation().getTargetContext()); apiCall.apiCallPostHashmap( forgotPasswordUrl.toString(), new HashMap(), @@ -109,7 +110,7 @@ public void apiCallPostJsonTest() { } catch (JSONException e) { e.printStackTrace(); } - ApiCall apiCall = new ApiCall(InstrumentationRegistry.getTargetContext()); + ApiCall apiCall = new ApiCall(InstrumentationRegistry.getInstrumentation().getTargetContext()); apiCall.apiCallPostJson( forgotPasswordUrl.toString(), new HashMap(), diff --git a/Android/app/src/androidTest/java/com/harvard/webservicemodule/apihelper/HttpRequestInstrumentedTest.java b/Android/app/src/androidTest/java/com/harvard/webservicemodule/apihelper/HttpRequestInstrumentedTest.java index 8e99ea8bba..896ccec247 100644 --- a/Android/app/src/androidTest/java/com/harvard/webservicemodule/apihelper/HttpRequestInstrumentedTest.java +++ b/Android/app/src/androidTest/java/com/harvard/webservicemodule/apihelper/HttpRequestInstrumentedTest.java @@ -11,7 +11,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.runner.AndroidJUnit4; + import com.harvard.utils.Urls; import java.util.HashMap; import org.json.JSONException; diff --git a/Android/app/src/androidTest/java/com/harward/fda/ExampleInstrumentedTest.java b/Android/app/src/androidTest/java/com/harward/fda/ExampleInstrumentedTest.java index 15cd39ee5a..391f7e5b59 100644 --- a/Android/app/src/androidTest/java/com/harward/fda/ExampleInstrumentedTest.java +++ b/Android/app/src/androidTest/java/com/harward/fda/ExampleInstrumentedTest.java @@ -15,14 +15,13 @@ package com.harward.fda; import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; import static junit.framework.Assert.assertEquals; -import static org.junit.Assert.*; /** * Instrumentation test, which will execute on an Android device. @@ -31,11 +30,11 @@ */ @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { - @Test - public void useAppContext() throws Exception { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); - assertEquals("com.harward.fda", appContext.getPackageName()); - } + assertEquals("com.harward.fda", appContext.getPackageName()); + } } diff --git a/Android/app/src/fda/java/com/harvard/gatewaymodule/GatewayPagerAdapter.java b/Android/app/src/fda/java/com/harvard/gatewaymodule/GatewayPagerAdapter.java index c117497a3b..4cc450ae9b 100644 --- a/Android/app/src/fda/java/com/harvard/gatewaymodule/GatewayPagerAdapter.java +++ b/Android/app/src/fda/java/com/harvard/gatewaymodule/GatewayPagerAdapter.java @@ -18,17 +18,20 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; -import android.support.v4.view.PagerAdapter; -import android.support.v7.widget.AppCompatImageView; -import android.support.v7.widget.AppCompatTextView; +import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.viewpager.widget.PagerAdapter; import com.harvard.R; import com.harvard.storagemodule.DbServiceSubscriber; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; + import io.realm.Realm; public class GatewayPagerAdapter extends PagerAdapter { @@ -40,6 +43,7 @@ public class GatewayPagerAdapter extends PagerAdapter { private AppCompatTextView desc; private AppCompatTextView watchVideoLabel; private Context context; + private CustomFirebaseAnalytics analyticsInstance; public GatewayPagerAdapter() { size = 2; @@ -69,6 +73,7 @@ public Object instantiateItem(ViewGroup collection, int position) { final LayoutInflater inflater = (LayoutInflater) collection.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); context = inflater.getContext(); + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); switch (position) { case 0: View view = inflater.inflate(R.layout.gateway_item1, null); @@ -119,6 +124,12 @@ private void initializeXmlId(int pos, View view) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.watch_video)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent intent = new Intent( Intent.ACTION_VIEW, Uri.parse("https://www.youtube.com/watch?v=6FGGquOrVic")); @@ -136,12 +147,19 @@ public void onClick(View v) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.app_website)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); DbServiceSubscriber dbServiceSubscriber = new DbServiceSubscriber(); Realm realm = AppController.getRealmobj(context); if (!dbServiceSubscriber.getApps(realm).getAppWebsite().equalsIgnoreCase("")) { Intent browserIntent = new Intent( - Intent.ACTION_VIEW, Uri.parse(dbServiceSubscriber.getApps(realm).getAppWebsite())); + Intent.ACTION_VIEW, + Uri.parse(dbServiceSubscriber.getApps(realm).getAppWebsite())); context.startActivity(browserIntent); } } diff --git a/Android/app/src/fda/java/com/harvard/studyappmodule/StudyActivity.java b/Android/app/src/fda/java/com/harvard/studyappmodule/StudyActivity.java index dae2ea204a..d99774e2c8 100644 --- a/Android/app/src/fda/java/com/harvard/studyappmodule/StudyActivity.java +++ b/Android/app/src/fda/java/com/harvard/studyappmodule/StudyActivity.java @@ -31,15 +31,6 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.support.customtabs.CustomTabsIntent; -import android.support.v4.app.NotificationManagerCompat; -import android.support.v4.view.GravityCompat; -import android.support.v4.widget.DrawerLayout; -import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatEditText; -import android.support.v7.widget.AppCompatImageView; -import android.support.v7.widget.AppCompatTextView; import android.text.Editable; import android.text.TextWatcher; import android.view.KeyEvent; @@ -50,6 +41,15 @@ import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatEditText; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.browser.customtabs.CustomTabsIntent; +import androidx.core.app.NotificationManagerCompat; +import androidx.core.view.GravityCompat; +import androidx.drawerlayout.widget.DrawerLayout; import com.harvard.AppConfig; import com.harvard.AppFirebaseMessagingService; import com.harvard.BuildConfig; @@ -62,11 +62,11 @@ import com.harvard.studyappmodule.studymodel.Study; import com.harvard.studyappmodule.studymodel.StudyList; import com.harvard.usermodule.UserModulePresenter; -import com.harvard.usermodule.VerificationStepActivity; import com.harvard.usermodule.event.LogoutEvent; import com.harvard.usermodule.model.Apps; import com.harvard.usermodule.webservicemodel.LoginData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SetDialogHelper; import com.harvard.utils.SharedPreferenceHelper; @@ -93,6 +93,7 @@ public class StudyActivity extends AppCompatActivity private AppCompatTextView titleFdaListens; private AppCompatTextView title; private AppCompatTextView sidebarTitle; + private CustomFirebaseAnalytics analyticsInstance; private LinearLayout homeLayout; private AppCompatTextView homeLabel; private LinearLayout resourcesLayout; @@ -137,6 +138,7 @@ public class StudyActivity extends AppCompatActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); if (AppConfig.AppType.equalsIgnoreCase(getString(R.string.app_gateway))) { isExit = false; setContentView(R.layout.activity_study); @@ -253,7 +255,10 @@ public void checkForNotification(Intent intent1) { .equalsIgnoreCase("")) { if (type != null) { if (type.equalsIgnoreCase("Gateway")) { - if (subType.equalsIgnoreCase("Study")) { + if (subType.equalsIgnoreCase("Study") + || subType.equalsIgnoreCase("Activity") + || subType.equalsIgnoreCase("Announcement") + || subType.equalsIgnoreCase("studyEvent")) { Study study = dbServiceSubscriber.getStudyListFromDB(realm); if (study != null) { RealmList studyListArrayList = study.getStudies(); @@ -492,6 +497,12 @@ private void initializeXmlId() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_side_menu)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); checkSignOrSignOutScenario(); openDrawer(); try { @@ -505,6 +516,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.filter_clicked)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent intent = new Intent(StudyActivity.this, FilterActivity.class); startActivityForResult(intent, 999); } @@ -513,6 +530,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_search)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); toolBarLayout.setVisibility(View.GONE); searchToolBarLayout.setVisibility(View.VISIBLE); drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); @@ -580,6 +603,12 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_search_clear)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); searchEditText.setText(""); clearLayout.setVisibility(View.INVISIBLE); studyFragment.setStudyFilteredStudyList(); @@ -590,6 +619,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_search_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); searchEditText.setText(""); setToolBarEnable(); hideKeyboard(); @@ -601,6 +636,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_notification)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent intent = new Intent(StudyActivity.this, NotificationActivity.class); startActivityForResult(intent, NOTIFICATION_RESULT); } @@ -626,6 +667,11 @@ public void onDrawerStateChanged(int newState) {} new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, getString(R.string.study_info)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); SetDialogHelper.setNeutralDialog( StudyActivity.this, getResources().getString(R.string.registration_message), @@ -637,14 +683,7 @@ public void onClick(View view) { } public void setVersion(TextView version) { - try { - PackageInfo info = - getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA); - version.append("" + info.versionName); - } catch (PackageManager.NameNotFoundException e) { - Logger.log(e); - version.setText(""); - } + version.append(BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")"); } private void hideKeyboard() { @@ -724,8 +763,12 @@ private void checkSignOrSignOutScenario() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); switch (view.getId()) { case R.id.mHomeLayout: + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, getString(R.string.study_side_home)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); previousValue = R.id.mHomeLayout; titleFdaListens.setText(getResources().getString(R.string.app_name)); title.setText(""); @@ -759,6 +802,10 @@ public void onClick(View view) { break; case R.id.mResourcesLayout: + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_side_resources)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (previousValue == R.id.mResourcesLayout) { closeDrawer(); } else { @@ -778,6 +825,10 @@ public void onClick(View view) { break; case R.id.mReachoutLayout: + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_side_reachout)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); reachoutMenuClicked(); break; @@ -785,6 +836,11 @@ public void onClick(View view) { if (AppController.getHelperSharedPreference() .readPreference(StudyActivity.this, getString(R.string.userid), "") .equalsIgnoreCase("")) { + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_side_sign_in)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); closeDrawer(); SharedPreferenceHelper.writePreference( StudyActivity.this, getString(R.string.loginflow), "SideMenu"); @@ -814,6 +870,11 @@ public void onClick(View view) { closeDrawer(); } else { previousValue = R.id.mSignInProfileLayout; + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_side_my_account)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); titleFdaListens.setText(""); title.setText(getResources().getString(R.string.profile)); editBtnLayout.setVisibility(View.VISIBLE); @@ -827,6 +888,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_edit)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (editTxt .getText() .toString() @@ -855,6 +922,11 @@ public void onClick(View view) { if (AppController.getHelperSharedPreference() .readPreference(StudyActivity.this, getString(R.string.userid), "") .equalsIgnoreCase("")) { + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_side_sign_up)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); titleFdaListens.setText(""); title.setText(getResources().getString(R.string.signup)); editBtnLayout.setVisibility(View.GONE); @@ -869,10 +941,19 @@ public void onClick(View view) { .commit(); } else { // SignOut Reach out menu click + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_side_reachout)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); reachoutMenuClicked(); } break; case R.id.mSignOutLayout: + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_side_sign_out)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); closeDrawer(); logout(); break; @@ -940,7 +1021,12 @@ private void logout() { getResources().getString(R.string.sign_out), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_side_sign_out_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); AppController.getHelperProgressDialog() .showProgress(StudyActivity.this, "", "", false); HashMap params = new HashMap<>(); @@ -982,6 +1068,12 @@ StudyActivity.this, getString(R.string.userid), "") getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_side_sign_out_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); } }); @@ -1025,8 +1117,7 @@ public void asyncResponse(T response, int responseCode) { if (responseCode == LOGOUT_REPSONSE_CODE) { Toast.makeText(this, getResources().getString(R.string.signed_out), Toast.LENGTH_SHORT) .show(); - SharedPreferences settings = SharedPreferenceHelper.getPreferences(StudyActivity.this); - settings.edit().clear().apply(); + SharedPreferenceHelper.deletePreferences(this); // delete passcode from keystore String pass = AppController.refreshKeys("passcode"); if (pass != null) { @@ -1149,10 +1240,16 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { "ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_update_next_time_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); } - }).show(); - + }) + .show(); } } } @@ -1317,6 +1414,12 @@ public void isUpgrade(boolean b, String latestVersion, final boolean force) { positiveButton, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_upgrade_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); startActivityForResult( new Intent(Intent.ACTION_VIEW, Uri.parse(VersionChecker.PLAY_STORE_URL)), RESULT_CODE_UPGRADE); @@ -1327,12 +1430,18 @@ public void onClick(DialogInterface dialog, int id) { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_upgrade_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); if (force) { Toast.makeText( - StudyActivity.this, - "Please update the app to continue using", - Toast.LENGTH_SHORT) + StudyActivity.this, + "Please update the app to continue using", + Toast.LENGTH_SHORT) .show(); moveTaskToBack(true); if (Build.VERSION.SDK_INT < 21) { diff --git a/Android/app/src/main/AndroidManifest.xml b/Android/app/src/main/AndroidManifest.xml index 3fabeabb03..eb1b2241dd 100644 --- a/Android/app/src/main/AndroidManifest.xml +++ b/Android/app/src/main/AndroidManifest.xml @@ -15,10 +15,12 @@ + @@ -70,6 +73,7 @@ android:configChanges="screenLayout|orientation" android:screenOrientation="portrait" android:theme="@style/AppThemeNoActionBar" + android:exported="true" android:windowSoftInputMode="stateHidden|adjustPan"> @@ -88,6 +92,7 @@ android:configChanges="screenLayout|orientation" android:screenOrientation="portrait" android:theme="@style/AppThemeNoActionBar" + android:exported="true" android:windowSoftInputMode="stateHidden|adjustPan"> @@ -116,6 +121,7 @@ android:name=".usermodule.AuthServerErrorHandler" android:configChanges="screenLayout|orientation" android:screenOrientation="portrait" + android:exported="true" android:theme="@style/AppThemeNoActionBar" android:windowSoftInputMode="stateHidden|adjustPan"> @@ -151,6 +157,7 @@ android:name=".usermodule.ForgotPasswordActivity" android:configChanges="screenLayout|orientation" android:screenOrientation="portrait" + android:exported="true" android:theme="@style/AppThemeNoActionBar" android:windowSoftInputMode="adjustResize|stateHidden"> @@ -212,6 +219,7 @@ android:configChanges="screenLayout|orientation" android:screenOrientation="portrait" android:theme="@style/AppThemeNoActionBar" + android:exported="true" android:windowSoftInputMode="stateHidden"> @@ -337,12 +345,14 @@ android:theme="@style/AppThemeNoActionBar" android:windowSoftInputMode="stateHidden|adjustResize" /> - + - + @@ -361,7 +371,8 @@ android:theme="@style/Theme.BackboneApp" android:windowSoftInputMode="stateHidden" /> - + @@ -376,7 +387,8 @@ android:syncable="true" tools:replace="android:authorities" /> - + @@ -387,8 +399,7 @@ + android:exported="true"> @@ -397,11 +408,13 @@ android:name="android.content.SyncAdapter" android:resource="@xml/syncadapter" /> - + + @@ -412,7 +425,8 @@ android:theme="@style/Theme.BackboneApp" android:windowSoftInputMode="stateHidden" /> - + diff --git a/Android/app/src/main/java/com/harvard/AppFirebaseMessagingService.java b/Android/app/src/main/java/com/harvard/AppFirebaseMessagingService.java index 93788113b3..ed402567b1 100644 --- a/Android/app/src/main/java/com/harvard/AppFirebaseMessagingService.java +++ b/Android/app/src/main/java/com/harvard/AppFirebaseMessagingService.java @@ -26,8 +26,8 @@ import android.media.RingtoneManager; import android.net.Uri; import android.os.Build; -import android.support.v4.app.NotificationCompat; -import android.support.v4.app.NotificationManagerCompat; +import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; import com.harvard.storagemodule.DbServiceSubscriber; @@ -196,9 +196,14 @@ public void setNotification( notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); Random random = new Random(); int m = random.nextInt(9999 - 1000) + 1000; - PendingIntent contentIntent = - PendingIntent.getActivity( - context, m, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent contentIntent; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + contentIntent = PendingIntent.getActivity( + context, m, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + contentIntent = PendingIntent.getActivity( + context, m, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + } if (type.equalsIgnoreCase(NOTIFICATION_TYPE)) { Study study = dbServiceSubscriber.getStudyListFromDB(realm); StudyData studyData = dbServiceSubscriber.getStudyPreferencesListFromDB(realm); diff --git a/Android/app/src/main/java/com/harvard/FdaApplication.java b/Android/app/src/main/java/com/harvard/FdaApplication.java index 5d5cc0564d..b7285f95f8 100644 --- a/Android/app/src/main/java/com/harvard/FdaApplication.java +++ b/Android/app/src/main/java/com/harvard/FdaApplication.java @@ -21,18 +21,17 @@ import android.content.Context; import android.content.Intent; import android.os.Build; -import android.support.multidex.MultiDex; +import androidx.multidex.MultiDex; import android.util.Base64; -import com.facebook.stetho.Stetho; + import com.harvard.passcodemodule.PasscodeSetupActivity; import com.harvard.studyappmodule.StudyModuleSubscriber; import com.harvard.usermodule.UserModuleSubscriber; import com.harvard.utils.AppController; import com.harvard.utils.AppVisibilityDetector; import com.harvard.utils.Logger; -import com.harvard.utils.realm.RealmEncryptionHelper; import com.harvard.webservicemodule.WebserviceSubscriber; -import com.uphyca.stetho_realm.RealmInspectorModulesProvider; + import io.realm.Realm; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; @@ -90,20 +89,6 @@ public void onAppGotoBackground() { private void dbInitialize() { Realm.init(this); - RealmEncryptionHelper realmEncryptionHelper = - RealmEncryptionHelper.initHelper(this, getString(R.string.app_name)); - byte[] key = realmEncryptionHelper.getEncryptKey(); - - // Remove for release builds - Stetho.initialize( - Stetho.newInitializerBuilder(this) - .enableDumpapp(Stetho.defaultDumperPluginsProvider(this)) - .enableWebKitInspector( - RealmInspectorModulesProvider.builder(this) - .withLimit(10000) - .withDefaultEncryptionKey(key) - .build()) - .build()); } private void startEventProcessing() { diff --git a/Android/app/src/main/java/com/harvard/SplashActivity.java b/Android/app/src/main/java/com/harvard/SplashActivity.java index 47897b0753..7169c13b03 100644 --- a/Android/app/src/main/java/com/harvard/SplashActivity.java +++ b/Android/app/src/main/java/com/harvard/SplashActivity.java @@ -15,20 +15,17 @@ package com.harvard; -import android.app.Activity; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.content.SharedPreferences; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; -import android.util.Log; import android.widget.Toast; - +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; import com.harvard.gatewaymodule.GatewayActivity; import com.harvard.offlinemodule.auth.SyncAdapterManager; import com.harvard.storagemodule.DbServiceSubscriber; @@ -38,17 +35,17 @@ import com.harvard.usermodule.UserModulePresenter; import com.harvard.usermodule.event.RegisterUserEvent; import com.harvard.usermodule.model.Apps; -import com.harvard.usermodule.webservicemodel.RegistrationData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; -import com.harvard.utils.realm.RealmEncryptionHelper; import com.harvard.utils.version.Version; import com.harvard.utils.version.VersionChecker; import com.harvard.webservicemodule.apihelper.ApiCall; import com.harvard.webservicemodule.events.ParticipantDatastoreConfigEvent; import java.util.HashMap; + public class SplashActivity extends AppCompatActivity implements ApiCall.OnAsyncRequestComplete { private static final int PASSCODE_RESPONSE = 101; @@ -57,37 +54,44 @@ public class SplashActivity extends AppCompatActivity implements ApiCall.OnAsync private boolean force = false; private static final int RESULT_CODE_UPGRADE = 102; private Apps apps; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); - RealmEncryptionHelper realmEncryptionHelper = RealmEncryptionHelper.getInstance(); - byte[] key = realmEncryptionHelper.getEncryptKey(); - String s = bytesToHex(key); - Log.e("realm key", "" + s); - - // sync registration - SyncAdapterManager.init(this); AppController.keystoreInitilize(SplashActivity.this); - getAppsInfo(); - - AppController.getHelperSharedPreference() - .writePreference(SplashActivity.this, getString(R.string.json_object_filter), ""); + new checkAndMigrate(this).execute(); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); } - private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); + private class checkAndMigrate extends AsyncTask { + Context context; - public static String bytesToHex(byte[] bytes) { - char[] hexChars = new char[bytes.length * 2]; - for (int j = 0; j < bytes.length; j++) { - int v = bytes[j] & 0xFF; - hexChars[j * 2] = HEX_ARRAY[v >>> 4]; - hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; + public checkAndMigrate(Context context) { + this.context = context; } - return new String(hexChars); + + @Override + protected String doInBackground(String... params) { + AppController.checkIfAppNameChangeAndMigrate(context); + return ""; + } + + @Override + protected void onPostExecute(String result) { + // sync registration + SyncAdapterManager.init(context); + getAppsInfo(); + + AppController.getHelperSharedPreference() + .writePreference(SplashActivity.this, getString(R.string.json_object_filter), ""); + } + + @Override + protected void onPreExecute() {} } private void getAppsInfo() { @@ -152,6 +156,12 @@ private void retryAlert() { getResources().getString(R.string.retry), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.splash_retry)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); getAppsInfo(); } }) @@ -159,6 +169,12 @@ public void onClick(DialogInterface dialog, int id) { getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.splash_retry_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); finish(); } @@ -192,9 +208,7 @@ SplashActivity.this, getResources().getString(R.string.verified), "") startActivity(intent); } } else { - SharedPreferences settings = - SharedPreferenceHelper.getPreferences(SplashActivity.this); - settings.edit().clear().apply(); + SharedPreferenceHelper.deletePreferences(SplashActivity.this); // delete passcode from keystore String pass = AppController.refreshKeys("passcode"); if (pass != null) { @@ -246,10 +260,16 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { "ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_update_next_time_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); proceedToApp(); } - }).show(); - + }) + .show(); } } } else if (requestCode == PASSCODE_RESPONSE) { @@ -314,6 +334,12 @@ public void isUpgrade(boolean b, String newVersion, final boolean force) { positiveButton, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_upgrade_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); startActivityForResult( new Intent(Intent.ACTION_VIEW, Uri.parse(VersionChecker.PLAY_STORE_URL)), RESULT_CODE_UPGRADE); @@ -324,12 +350,18 @@ public void onClick(DialogInterface dialog, int id) { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_upgrade_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); if (force) { Toast.makeText( - SplashActivity.this, - "Please update the app to continue using", - Toast.LENGTH_SHORT) + SplashActivity.this, + "Please update the app to continue using", + Toast.LENGTH_SHORT) .show(); moveTaskToBack(true); if (Build.VERSION.SDK_INT < 21) { diff --git a/Android/app/src/main/java/com/harvard/VersionCheckerService.java b/Android/app/src/main/java/com/harvard/VersionCheckerService.java index 26302e7f27..6f594e78b5 100644 --- a/Android/app/src/main/java/com/harvard/VersionCheckerService.java +++ b/Android/app/src/main/java/com/harvard/VersionCheckerService.java @@ -15,14 +15,8 @@ package com.harvard; import android.app.Service; -import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; -import android.net.Uri; import android.os.IBinder; -import android.support.v7.app.AlertDialog; -import android.util.Log; -import android.widget.Toast; import com.harvard.storagemodule.DbServiceSubscriber; import com.harvard.usermodule.UserModulePresenter; import com.harvard.usermodule.event.RegisterUserEvent; @@ -30,10 +24,9 @@ import com.harvard.utils.AppController; import com.harvard.utils.Logger; import com.harvard.utils.Urls; -import com.harvard.utils.version.Version; -import com.harvard.utils.version.VersionChecker; import com.harvard.webservicemodule.apihelper.ApiCall; import com.harvard.webservicemodule.events.ParticipantDatastoreConfigEvent; + import java.util.HashMap; public class VersionCheckerService extends Service implements ApiCall.OnAsyncRequestComplete { diff --git a/Android/app/src/main/java/com/harvard/WebViewActivity.java b/Android/app/src/main/java/com/harvard/WebViewActivity.java index 669cb60105..e6aa9bb810 100644 --- a/Android/app/src/main/java/com/harvard/WebViewActivity.java +++ b/Android/app/src/main/java/com/harvard/WebViewActivity.java @@ -17,18 +17,21 @@ import android.os.Build; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.text.Html; import android.view.View; import android.webkit.WebView; import android.widget.RelativeLayout; +import com.harvard.utils.CustomFirebaseAnalytics; public class WebViewActivity extends AppCompatActivity { + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_web_view); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); WebView webView = (WebView) findViewById(R.id.webView); webView.getSettings().setLoadsImagesAutomatically(true); webView.getSettings().setJavaScriptEnabled(true); @@ -47,6 +50,12 @@ protected void onCreate(Bundle savedInstanceState) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.webview_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }); diff --git a/Android/app/src/main/java/com/harvard/base/BaseEventReportingActivity.java b/Android/app/src/main/java/com/harvard/base/BaseEventReportingActivity.java index d6530f2daf..2b14f20756 100644 --- a/Android/app/src/main/java/com/harvard/base/BaseEventReportingActivity.java +++ b/Android/app/src/main/java/com/harvard/base/BaseEventReportingActivity.java @@ -15,7 +15,7 @@ package com.harvard.base; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import com.harvard.FdaEventBus; import com.harvard.FdaEventBusRegistry; diff --git a/Android/app/src/main/java/com/harvard/eligibilitymodule/ComprehensionFailureActivity.java b/Android/app/src/main/java/com/harvard/eligibilitymodule/ComprehensionFailureActivity.java index 239b202c8f..479a46d412 100644 --- a/Android/app/src/main/java/com/harvard/eligibilitymodule/ComprehensionFailureActivity.java +++ b/Android/app/src/main/java/com/harvard/eligibilitymodule/ComprehensionFailureActivity.java @@ -20,7 +20,7 @@ import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.view.View; import android.widget.TextView; import com.harvard.AppConfig; @@ -34,6 +34,8 @@ import com.harvard.studyappmodule.consent.model.Consent; import com.harvard.studyappmodule.consent.model.EligibilityConsent; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; + import io.realm.Realm; import java.util.List; import org.researchstack.backbone.step.Step; @@ -46,11 +48,13 @@ public class ComprehensionFailureActivity extends AppCompatActivity { private DbServiceSubscriber dbServiceSubscriber; private EligibilityConsent eligibilityConsent; private Realm realm; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_comprehension_failure); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); TextView retrybutton = findViewById(R.id.retrybutton); dbServiceSubscriber = new DbServiceSubscriber(); @@ -59,6 +63,12 @@ protected void onCreate(Bundle savedInstanceState) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.eligibility_failure_message)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); eligibilityConsent = dbServiceSubscriber.getConsentMetadata( getIntent().getStringExtra("studyId"), realm); diff --git a/Android/app/src/main/java/com/harvard/eligibilitymodule/ComprehensionSuccessActivity.java b/Android/app/src/main/java/com/harvard/eligibilitymodule/ComprehensionSuccessActivity.java index 8650b8c941..b1c1f1dace 100644 --- a/Android/app/src/main/java/com/harvard/eligibilitymodule/ComprehensionSuccessActivity.java +++ b/Android/app/src/main/java/com/harvard/eligibilitymodule/ComprehensionSuccessActivity.java @@ -1,5 +1,6 @@ /* * Copyright © 2017-2019 Harvard Pilgrim Health Care Institute (HPHCI) and its Contributors. + * Copyright 2020 Google LLC * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * associated documentation files (the "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: @@ -16,23 +17,32 @@ import android.content.Intent; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.view.View; import android.widget.TextView; import com.harvard.R; +import com.harvard.utils.CustomFirebaseAnalytics; public class ComprehensionSuccessActivity extends AppCompatActivity { + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_comprehension_success); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); TextView continueButton = findViewById(R.id.continueButton); continueButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.eligibility_sucess_message)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent intent = new Intent(); setResult(RESULT_OK, intent); finish(); diff --git a/Android/app/src/main/java/com/harvard/eligibilitymodule/CustomViewTaskActivity.java b/Android/app/src/main/java/com/harvard/eligibilitymodule/CustomViewTaskActivity.java index fc6317643b..6e9db8b991 100644 --- a/Android/app/src/main/java/com/harvard/eligibilitymodule/CustomViewTaskActivity.java +++ b/Android/app/src/main/java/com/harvard/eligibilitymodule/CustomViewTaskActivity.java @@ -23,11 +23,11 @@ import android.content.Intent; import android.graphics.Color; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import android.text.SpannableString; import android.text.style.ForegroundColorSpan; import android.view.Menu; @@ -38,6 +38,7 @@ import com.harvard.studyappmodule.consent.model.CorrectAnswers; import com.harvard.studyappmodule.custom.StepSwitcherCustom; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import java.lang.reflect.Constructor; import java.util.ArrayList; @@ -72,6 +73,7 @@ public class CustomViewTaskActivity extends AppCompatActivity implements StepCal private String pdfTitle; private TaskResult taskResult; private ArrayList correctAnswers; + private CustomFirebaseAnalytics analyticsInstance; public static Intent newIntent( Context context, @@ -104,6 +106,7 @@ public static Intent newIntent( protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setResult(RESULT_CANCELED); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); super.setContentView(R.layout.stepswitchercustom); Toolbar toolbar = findViewById(org.researchstack.backbone.R.id.toolbar); setSupportActionBar(toolbar); @@ -150,6 +153,11 @@ public boolean onCreateOptionsMenu(Menu menu) { } protected void showNextStep() { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_view_task_next)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); boolean eligible = checkStepResult(currentStep, taskResult); Step nextStep; if (eligible || currentStep.getIdentifier().equalsIgnoreCase("Eligibility Test")) { @@ -203,6 +211,11 @@ private boolean checkStepResult(Step currentStep, TaskResult taskResult) { } protected void showPreviousStep() { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_view_task_back)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Step previousStep = task.getStepBeforeStep(currentStep, taskResult); if (previousStep == null) { finish(); @@ -283,6 +296,11 @@ public boolean onOptionsItemSelected(MenuItem item) { notifyStepOfBackPress(); return true; } else if (item.getItemId() == R.id.action_settings) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_view_task_exit)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); return true; } @@ -359,10 +377,28 @@ private void showConfirmExitDialog() { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_view_task_edit_task)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }) - .setNegativeButton(R.string.cancel, null) + .setNegativeButton( + R.string.cancel, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_view_task_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + } + }) .create(); alertDialog.show(); } diff --git a/Android/app/src/main/java/com/harvard/eligibilitymodule/EligibleActivity.java b/Android/app/src/main/java/com/harvard/eligibilitymodule/EligibleActivity.java index 2cf3a92e32..7a50506b9f 100644 --- a/Android/app/src/main/java/com/harvard/eligibilitymodule/EligibleActivity.java +++ b/Android/app/src/main/java/com/harvard/eligibilitymodule/EligibleActivity.java @@ -21,7 +21,7 @@ import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.view.View; import android.widget.TextView; import com.harvard.AppConfig; @@ -39,6 +39,7 @@ import com.harvard.usermodule.event.UpdatePreferenceEvent; import com.harvard.usermodule.webservicemodel.LoginData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.Urls; import com.harvard.webservicemodule.apihelper.ApiCall; @@ -59,6 +60,7 @@ public class EligibleActivity extends AppCompatActivity implements ApiCall.OnAsy private EligibilityConsent eligibilityConsent; private DbServiceSubscriber dbServiceSubscriber; private static final int UPDATE_USER_PREFERENCE_RESPONSE_CODE = 200; + private CustomFirebaseAnalytics analyticsInstance; private Realm realm; @Override @@ -67,12 +69,19 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_eligible); dbServiceSubscriber = new DbServiceSubscriber(); realm = AppController.getRealmobj(this); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); TextView button = (TextView) findViewById(R.id.continueButton); button.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.eligiblity_confirmation_message)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); eligibilityConsent = dbServiceSubscriber.getConsentMetadata( getIntent().getStringExtra("studyId"), realm); diff --git a/Android/app/src/main/java/com/harvard/eligibilitymodule/NotEligibleActivity.java b/Android/app/src/main/java/com/harvard/eligibilitymodule/NotEligibleActivity.java index 6d657c5ef7..440f545568 100644 --- a/Android/app/src/main/java/com/harvard/eligibilitymodule/NotEligibleActivity.java +++ b/Android/app/src/main/java/com/harvard/eligibilitymodule/NotEligibleActivity.java @@ -17,7 +17,7 @@ package com.harvard.eligibilitymodule; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.view.View; import android.widget.TextView; import com.harvard.R; @@ -27,6 +27,7 @@ import com.harvard.usermodule.event.UpdatePreferenceEvent; import com.harvard.usermodule.webservicemodel.LoginData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.Urls; import com.harvard.webservicemodule.apihelper.ApiCall; @@ -39,18 +40,26 @@ public class NotEligibleActivity extends AppCompatActivity implements ApiCall.OnAsyncRequestComplete { private static final int UPDATE_USERPREFERENCE_RESPONSECODE = 200; + private CustomFirebaseAnalytics analyticsInstance; DbServiceSubscriber dbServiceSubscriber; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_not_eligible); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); dbServiceSubscriber = new DbServiceSubscriber(); TextView textView = (TextView) findViewById(R.id.notEligibleOK); textView.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.not_eligible)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }); diff --git a/Android/app/src/main/java/com/harvard/gatewaymodule/CircleIndicator.java b/Android/app/src/main/java/com/harvard/gatewaymodule/CircleIndicator.java index 01e973afb5..32e435ca68 100644 --- a/Android/app/src/main/java/com/harvard/gatewaymodule/CircleIndicator.java +++ b/Android/app/src/main/java/com/harvard/gatewaymodule/CircleIndicator.java @@ -15,7 +15,7 @@ package com.harvard.gatewaymodule; -import static android.support.v4.view.ViewPager.OnPageChangeListener; +import static androidx.viewpager.widget.ViewPager.OnPageChangeListener; import android.animation.Animator; import android.animation.AnimatorInflater; @@ -24,9 +24,9 @@ import android.content.res.TypedArray; import android.database.DataSetObserver; import android.os.Build; -import android.support.annotation.AnimatorRes; -import android.support.annotation.DrawableRes; -import android.support.v4.view.ViewPager; +import androidx.annotation.AnimatorRes; +import androidx.annotation.DrawableRes; +import androidx.viewpager.widget.ViewPager; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; diff --git a/Android/app/src/main/java/com/harvard/gatewaymodule/GatewayActivity.java b/Android/app/src/main/java/com/harvard/gatewaymodule/GatewayActivity.java index 39d69692a7..e3a317c7a1 100644 --- a/Android/app/src/main/java/com/harvard/gatewaymodule/GatewayActivity.java +++ b/Android/app/src/main/java/com/harvard/gatewaymodule/GatewayActivity.java @@ -24,29 +24,26 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.support.customtabs.CustomTabsIntent; -import android.support.v4.view.ViewPager; -import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatTextView; -import android.util.Log; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.browser.customtabs.CustomTabsIntent; +import androidx.viewpager.widget.ViewPager; + import android.view.View; import android.widget.RelativeLayout; import android.widget.Toast; - import com.harvard.AppConfig; import com.harvard.BuildConfig; import com.harvard.R; -import com.harvard.SplashActivity; import com.harvard.gatewaymodule.events.GetStartedEvent; import com.harvard.storagemodule.DbServiceSubscriber; import com.harvard.studyappmodule.StandaloneActivity; import com.harvard.studyappmodule.StudyActivity; -import com.harvard.studyappmodule.SurveyActivity; import com.harvard.usermodule.SignupActivity; -import com.harvard.usermodule.VerificationStepActivity; import com.harvard.usermodule.model.Apps; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; @@ -70,11 +67,13 @@ public class GatewayActivity extends AppCompatActivity { private String latestVersion; private boolean force = false; AlertDialog.Builder alertDialogBuilder; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_gateway); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); setFont(); bindEvents(); @@ -168,6 +167,11 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, getString(R.string.new_user)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent intent = new Intent(GatewayActivity.this, SignupActivity.class); startActivity(intent); } @@ -177,6 +181,11 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, getString(R.string.sign_in_btn)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); loadLogin(); } }); @@ -185,6 +194,11 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, getString(R.string.get_started)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); GetStartedEvent getStartedEvent = new GetStartedEvent(); getStartedEvent.setCommingFrom(COMMING_FROM); onEvent(getStartedEvent); @@ -272,10 +286,16 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { "ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_update_next_time_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); } - }).show(); - + }) + .show(); } } } @@ -334,6 +354,12 @@ public void isUpgrade(boolean b, String latestVersion, final boolean force) { positiveButton, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_upgrade_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); startActivityForResult( new Intent(Intent.ACTION_VIEW, Uri.parse(VersionChecker.PLAY_STORE_URL)), RESULT_CODE_UPGRADE); @@ -344,12 +370,18 @@ public void onClick(DialogInterface dialog, int id) { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_upgrade_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); if (force) { Toast.makeText( - GatewayActivity.this, - "Please update the app to continue using", - Toast.LENGTH_SHORT) + GatewayActivity.this, + "Please update the app to continue using", + Toast.LENGTH_SHORT) .show(); moveTaskToBack(true); if (Build.VERSION.SDK_INT < 21) { diff --git a/Android/app/src/main/java/com/harvard/notificationmodule/AlarmReceiver.java b/Android/app/src/main/java/com/harvard/notificationmodule/AlarmReceiver.java index bcc58d815f..bdf80dcf06 100644 --- a/Android/app/src/main/java/com/harvard/notificationmodule/AlarmReceiver.java +++ b/Android/app/src/main/java/com/harvard/notificationmodule/AlarmReceiver.java @@ -28,8 +28,8 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Build; -import android.support.v4.app.NotificationCompat; -import android.support.v4.app.NotificationManagerCompat; +import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; import com.harvard.AppConfig; import com.harvard.FdaApplication; import com.harvard.R; @@ -120,9 +120,18 @@ private void showLocalNotification(Context context, Intent intent) { .putExtra(TITLE, title) .putExtra(MESSAGE, description) .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); - contentIntent = - PendingIntent.getActivity( - context, notificationId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + contentIntent = + PendingIntent.getActivity( + context, + notificationId, + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + contentIntent = + PendingIntent.getActivity( + context, notificationId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + } } int notifyIcon = R.mipmap.ic_launcher; @@ -280,12 +289,22 @@ private void notificationForTodayAnd24HrAlarm(Context context) { .addCategory("android.intent.category.DEFAULT") .putExtra("pendingIntentId", REQUEST_CODE_24HR_NOTIFICATION); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - PendingIntent broadcast = - PendingIntent.getBroadcast( - context, - REQUEST_CODE_24HR_NOTIFICATION, - notificationIntent, - PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent broadcast; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + broadcast = + PendingIntent.getBroadcast( + context, + REQUEST_CODE_24HR_NOTIFICATION, + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + broadcast = + PendingIntent.getBroadcast( + context, + REQUEST_CODE_24HR_NOTIFICATION, + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { alarmManager.setExactAndAllowWhileIdle( AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), broadcast); diff --git a/Android/app/src/main/java/com/harvard/notificationmodule/NotificationModuleSubscriber.java b/Android/app/src/main/java/com/harvard/notificationmodule/NotificationModuleSubscriber.java index 3f1ca7f846..e52c8b55c1 100644 --- a/Android/app/src/main/java/com/harvard/notificationmodule/NotificationModuleSubscriber.java +++ b/Android/app/src/main/java/com/harvard/notificationmodule/NotificationModuleSubscriber.java @@ -183,12 +183,22 @@ private void set24hourScheduler(Context context) { .addCategory("android.intent.category.DEFAULT") .putExtra("pendingIntentId", REQUEST_CODE_24HR_NOTIFICATION); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - PendingIntent broadcast = - PendingIntent.getBroadcast( - context, - REQUEST_CODE_24HR_NOTIFICATION, - notificationIntent, - PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent broadcast; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + broadcast = + PendingIntent.getBroadcast( + context, + REQUEST_CODE_24HR_NOTIFICATION, + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + broadcast = + PendingIntent.getBroadcast( + context, + REQUEST_CODE_24HR_NOTIFICATION, + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { alarmManager.setExactAndAllowWhileIdle( AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), broadcast); @@ -245,9 +255,19 @@ public void setAlarm( notificationIntent.putExtra("pendingIntentId", pendingIntentId); - PendingIntent broadcast = - PendingIntent.getBroadcast( - context, pendingIntentId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent broadcast; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + broadcast = + PendingIntent.getBroadcast( + context, + pendingIntentId, + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + broadcast = + PendingIntent.getBroadcast( + context, pendingIntentId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + } PendingIntents pendingIntents = new PendingIntents(); pendingIntents.setActivityId(activityId); pendingIntents.setStudyId(studyId); @@ -283,9 +303,19 @@ public void generateTwoWeekNotification(Date date, Context context) { .putExtra("type", NO_USE_NOTIFICATION) .putExtra("date", AppController.getDateFormatForApi().format(calendar.getTime())); - PendingIntent broadcast = - PendingIntent.getBroadcast( - context, pendingId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent broadcast; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + broadcast = + PendingIntent.getBroadcast( + context, + pendingId, + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + broadcast = + PendingIntent.getBroadcast( + context, pendingId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { alarmManager.setExactAndAllowWhileIdle( AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), broadcast); @@ -306,9 +336,19 @@ public void cancelTwoWeekNotification(Context context) { .putExtra( "description", context.getResources().getString(R.string.studie_your_enrolled)) .putExtra("type", NO_USE_NOTIFICATION); - PendingIntent broadcast = - PendingIntent.getBroadcast( - context, pendingId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent broadcast; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + broadcast = + PendingIntent.getBroadcast( + context, + pendingId, + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + broadcast = + PendingIntent.getBroadcast( + context, pendingId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + } broadcast.cancel(); alarmManager.cancel(broadcast); } @@ -332,9 +372,19 @@ public void generateNotificationTurnOffNotification(Date date, Context context) .putExtra("type", NOTIFICATION_TURN_OFF_NOTIFICATION) .putExtra("date", AppController.getDateFormatForApi().format(calendar.getTime())); - PendingIntent broadcast = - PendingIntent.getBroadcast( - context, pendingId1, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent broadcast; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + broadcast = + PendingIntent.getBroadcast( + context, + pendingId1, + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + broadcast = + PendingIntent.getBroadcast( + context, pendingId1, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { alarmManager.setExactAndAllowWhileIdle( AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), broadcast); @@ -356,9 +406,19 @@ public void cancelNotificationTurnOffNotification(Context context) { "description", context.getResources().getString(R.string.notificatinturnoffnotification)) .putExtra("type", NOTIFICATION_TURN_OFF_NOTIFICATION); - PendingIntent broadcast = - PendingIntent.getBroadcast( - context, pendingId1, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent broadcast; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + broadcast = + PendingIntent.getBroadcast( + context, + pendingId1, + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + broadcast = + PendingIntent.getBroadcast( + context, pendingId1, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + } broadcast.cancel(); alarmManager.cancel(broadcast); } @@ -435,9 +495,19 @@ public void generateAnchorDateLocalNotification( context, context.getResources().getString(R.string.pendingCountResources), "" + pendingIntentId); - PendingIntent broadcast = - PendingIntent.getBroadcast( - context, pendingIntentId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent broadcast; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + broadcast = + PendingIntent.getBroadcast( + context, + pendingIntentId, + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + broadcast = + PendingIntent.getBroadcast( + context, pendingIntentId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + } PendingIntentsResources pendingIntents = new PendingIntentsResources(); pendingIntents.setActivityId(activityId); pendingIntents.setStudyId(studyId); @@ -476,12 +546,22 @@ public void cancleResourcesLocalNotification(Context context) { .putExtra("studyId", pendingIntentsResources.getStudyId()) .putExtra("activityId", pendingIntentsResources.getActivityId()) .putExtra("notificationId", pendingIntentsResources.getNotificationId()); - PendingIntent broadcast = - PendingIntent.getBroadcast( - context, - pendingIntentsResources.getPendingIntentId(), - notificationIntent, - PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent broadcast; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + broadcast = + PendingIntent.getBroadcast( + context, + pendingIntentsResources.getPendingIntentId(), + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + broadcast = + PendingIntent.getBroadcast( + context, + pendingIntentsResources.getPendingIntentId(), + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + } broadcast.cancel(); alarmManager.cancel(broadcast); } @@ -508,12 +588,22 @@ public void cancleResourcesLocalNotificationByIds( .putExtra("studyId", pendingIntentsResources.getStudyId()) .putExtra("activityId", pendingIntentsResources.getActivityId()) .putExtra("notificationId", pendingIntentsResources.getNotificationId()); - PendingIntent broadcast = - PendingIntent.getBroadcast( - context, - pendingIntentsResources.getPendingIntentId(), - notificationIntent, - PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent broadcast; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + broadcast = + PendingIntent.getBroadcast( + context, + pendingIntentsResources.getPendingIntentId(), + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + broadcast = + PendingIntent.getBroadcast( + context, + pendingIntentsResources.getPendingIntentId(), + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + } broadcast.cancel(); alarmManager.cancel(broadcast); } @@ -539,12 +629,22 @@ public void cancleActivityLocalNotificationByIds( .putExtra("studyId", pendingIntents.getStudyId()) .putExtra("activityId", pendingIntents.getActivityId()) .putExtra("notificationId", pendingIntents.getNotificationId()); - PendingIntent broadcast = - PendingIntent.getBroadcast( - context, - pendingIntents.getPendingIntentId(), - notificationIntent, - PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent broadcast; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + broadcast = + PendingIntent.getBroadcast( + context, + pendingIntents.getPendingIntentId(), + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + broadcast = + PendingIntent.getBroadcast( + context, + pendingIntents.getPendingIntentId(), + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + } broadcast.cancel(); alarmManager.cancel(broadcast); } @@ -567,12 +667,22 @@ public void cancleActivityLocalNotification(Context context) { .putExtra("studyId", pendingIntents.getStudyId()) .putExtra("activityId", pendingIntents.getActivityId()) .putExtra("notificationId", pendingIntents.getNotificationId()); - PendingIntent broadcast = - PendingIntent.getBroadcast( - context, - pendingIntents.getPendingIntentId(), - notificationIntent, - PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent broadcast; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + broadcast = + PendingIntent.getBroadcast( + context, + pendingIntents.getPendingIntentId(), + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + broadcast = + PendingIntent.getBroadcast( + context, + pendingIntents.getPendingIntentId(), + notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + } broadcast.cancel(); alarmManager.cancel(broadcast); } diff --git a/Android/app/src/main/java/com/harvard/offlinemodule/auth/StubContentProvider.java b/Android/app/src/main/java/com/harvard/offlinemodule/auth/StubContentProvider.java index 153353e5ab..299ac8cb1c 100644 --- a/Android/app/src/main/java/com/harvard/offlinemodule/auth/StubContentProvider.java +++ b/Android/app/src/main/java/com/harvard/offlinemodule/auth/StubContentProvider.java @@ -18,7 +18,7 @@ import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; -import android.support.annotation.Nullable; +import androidx.annotation.Nullable; /** * Stub content provider. We will not use ContentProvider, but it is mandatory for having diff --git a/Android/app/src/main/java/com/harvard/passcodemodule/PasscodeSetupActivity.java b/Android/app/src/main/java/com/harvard/passcodemodule/PasscodeSetupActivity.java index 32a839afc4..1512d1f297 100644 --- a/Android/app/src/main/java/com/harvard/passcodemodule/PasscodeSetupActivity.java +++ b/Android/app/src/main/java/com/harvard/passcodemodule/PasscodeSetupActivity.java @@ -15,17 +15,15 @@ package com.harvard.passcodemodule; -import android.content.ComponentName; import android.content.DialogInterface; import android.content.Intent; -import android.content.SharedPreferences; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatTextView; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; @@ -33,15 +31,13 @@ import android.widget.Toast; import com.harvard.AppConfig; import com.harvard.R; -import com.harvard.SplashActivity; -import com.harvard.gatewaymodule.GatewayActivity; import com.harvard.storagemodule.DbServiceSubscriber; import com.harvard.usermodule.UserModulePresenter; import com.harvard.usermodule.event.RegisterUserEvent; import com.harvard.usermodule.model.Apps; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; -import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; import com.harvard.utils.version.Version; import com.harvard.utils.version.VersionChecker; @@ -64,12 +60,14 @@ public class PasscodeSetupActivity extends AppCompatActivity implements ApiCall. private static final int RESULT_CODE_UPGRADE = 102; private String newVersion; private boolean force = false; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_passcode_setup); getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); dbServiceSubscriber = new DbServiceSubscriber(); initializeXmlId(); setTextForView(); @@ -123,7 +121,13 @@ public void run() { new View.OnClickListener() { @Override public void onClick(View v) { - getAppsInfo(); + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.forgot_passcode_message)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + forgotSignin(); } }); @@ -158,6 +162,12 @@ private void forgotSignin() { getResources().getString(R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.passcode_setup_signout_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); AppController.forceSignout(PasscodeSetupActivity.this); } }); @@ -166,6 +176,12 @@ public void onClick(DialogInterface dialog, int which) { getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.passcode_setup_signout_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); } }); @@ -244,6 +260,12 @@ private void retryAlert() { getResources().getString(R.string.retry), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.passcode_setup_retry)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); getAppsInfo(); } }); @@ -276,6 +298,12 @@ public void isUpgrade(boolean b, String newVersion, final boolean force) { positiveButton, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_upgrade_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); startActivityForResult( new Intent(Intent.ACTION_VIEW, Uri.parse(VersionChecker.PLAY_STORE_URL)), RESULT_CODE_UPGRADE); @@ -286,11 +314,17 @@ public void onClick(DialogInterface dialog, int id) { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_upgrade_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (force) { Toast.makeText( - PasscodeSetupActivity.this, - "Please update the app to continue using", - Toast.LENGTH_SHORT) + PasscodeSetupActivity.this, + "Please update the app to continue using", + Toast.LENGTH_SHORT) .show(); moveTaskToBack(true); if (Build.VERSION.SDK_INT < 21) { @@ -351,9 +385,16 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten "ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_update_next_time_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); forgotSignin(); } - }).show(); + }) + .show(); } } } diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/CalculateRunHoldService.java b/Android/app/src/main/java/com/harvard/studyappmodule/CalculateRunHoldService.java new file mode 100644 index 0000000000..e74a558a80 --- /dev/null +++ b/Android/app/src/main/java/com/harvard/studyappmodule/CalculateRunHoldService.java @@ -0,0 +1,94 @@ +/* + * Copyright 2020 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + */ + +package com.harvard.studyappmodule; + +import android.app.Notification; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.IBinder; +import android.os.PowerManager; +import android.util.Log; + +import androidx.annotation.Nullable; +import androidx.core.app.NotificationCompat; + +import com.harvard.FdaApplication; +import com.harvard.R; +import com.harvard.utils.AppController; + +public class CalculateRunHoldService extends Service { + PowerManager.WakeLock wakeLock; + private Thread thread; + Context context; + + @Override + public void onCreate() { + super.onCreate(); + PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); + wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getPackageName()); + wakeLock.acquire(); + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + context = this; + Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); + Notification notification = + new NotificationCompat.Builder(this) + .setContentTitle(getResources().getString(R.string.app_name)) + .setTicker("Study Setup") + .setContentText("Setting up study content for you") + .setChannelId(FdaApplication.NOTIFICATION_CHANNEL_ID_SERVICE) + .setSmallIcon(R.mipmap.ic_launcher) + .setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false)) + .setOngoing(true) + .build(); + + startForeground(103, notification); + + Runnable r = + new Runnable() { + public void run() { + while (true) { + if (AppController.getHelperSharedPreference() + .readPreference(getApplicationContext(), "runsCalculating", "false") + .equalsIgnoreCase("false")) { + Log.e("runsCalculating", "done"); + stopSelf(); + break; + } + } + } + }; + thread = new Thread(r); + thread.start(); + + return Service.START_NOT_STICKY; + } + + + @Override + public void onDestroy() { + if (wakeLock.isHeld()) + wakeLock.release(); + if (thread != null && thread.isAlive()) { + thread.interrupt(); + } + super.onDestroy(); + } +} diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/ChangePasswordActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/ChangePasswordActivity.java index ce65e7373f..843fad9ebb 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/ChangePasswordActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/ChangePasswordActivity.java @@ -18,12 +18,11 @@ import android.content.ComponentName; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Bundle; import android.os.Handler; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatEditText; -import android.support.v7.widget.AppCompatTextView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatEditText; +import androidx.appcompat.widget.AppCompatTextView; import android.view.View; import android.widget.RelativeLayout; import android.widget.Toast; @@ -36,6 +35,7 @@ import com.harvard.usermodule.event.ChangePasswordEvent; import com.harvard.usermodule.webservicemodel.ChangePasswordData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; @@ -66,6 +66,7 @@ public class ChangePasswordActivity extends AppCompatActivity private boolean isVerified; private String emailId; private boolean clicked; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { @@ -73,6 +74,7 @@ protected void onCreate(Bundle savedInstanceState) { userId = getIntent().getStringExtra("userid"); auth = getIntent().getStringExtra("auth"); isVerified = getIntent().getBooleanExtra("verified", false); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); emailId = getIntent().getStringExtra("email"); try { password = getIntent().getStringExtra("password"); @@ -137,6 +139,12 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.change_password_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); onBackPressed(); } }); @@ -167,6 +175,12 @@ public void onFocusChange(View v, boolean hasFocus) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.change_password_submit)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (!clicked) { newPassword.clearFocus(); confirmPassword.clearFocus(); @@ -191,7 +205,10 @@ public void onClick(View view) { getResources().getString(R.string.password_new_empty), Toast.LENGTH_SHORT) .show(); - } else if (!newPassword.getText().toString().matches(AppController.PASSWORD_PATTERN)) { + } else if (!newPassword + .getText() + .toString() + .matches(AppController.PASSWORD_PATTERN)) { newPassword.setError(getResources().getString(R.string.password_validation)); } else if (checkPasswordContainsEmailID(newPassword.getText().toString())) { Toast.makeText( @@ -321,9 +338,7 @@ public void onBackPressed() { if (from != null && from.equalsIgnoreCase("ProfileFragment")) { finish(); } else { - SharedPreferences settings = - SharedPreferenceHelper.getPreferences(ChangePasswordActivity.this); - settings.edit().clear().apply(); + SharedPreferenceHelper.deletePreferences(this); // delete passcode from keystore String pass = AppController.refreshKeys("passcode"); if (pass != null) { diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/ChartActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/ChartActivity.java index ffde9c25bb..5848204157 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/ChartActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/ChartActivity.java @@ -28,10 +28,6 @@ import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.Environment; -import android.support.annotation.NonNull; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.FileProvider; -import android.support.v7.app.AppCompatActivity; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; @@ -40,6 +36,10 @@ import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.FileProvider; import com.github.mikephil.charting.charts.LineChart; import com.github.mikephil.charting.data.Entry; import com.harvard.R; @@ -51,6 +51,7 @@ import com.harvard.studyappmodule.studymodel.DashboardData; import com.harvard.studyappmodule.studymodel.RunChart; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.CustomMarkerView; import com.harvard.utils.Logger; import com.harvard.utils.TempGraphHelper; @@ -96,6 +97,7 @@ public class ChartActivity extends AppCompatActivity { private DbServiceSubscriber dbServiceSubscriber; private Realm realm; private static final int PERMISSION_REQUEST_CODE = 2000; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { @@ -103,6 +105,7 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_chart); dbServiceSubscriber = new DbServiceSubscriber(); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); realm = AppController.getRealmobj(this); dashboardData = dbServiceSubscriber.getDashboardDataFromDB(getIntent().getStringExtra("studyId"), realm); @@ -113,6 +116,12 @@ protected void onCreate(Bundle savedInstanceState) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.chart_actvity_share)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); screenshotWritingPermission(); } }); @@ -120,6 +129,12 @@ public void onClick(View v) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.chart_actvity_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }); @@ -691,6 +706,12 @@ private void addTimeLayoutRuns( new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.chart_actvity_left_arrow)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (Integer.parseInt("" + textView1.getTag(R.string.runchartindex)) > 0) { textView1.setTag( R.string.runchartindex, @@ -712,6 +733,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.chart_actvity_right_arrow)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (Integer.parseInt("" + textView1.getTag(R.string.runchartindex)) < Integer.parseInt("" + textView1.getTag(R.string.runchartmaxindex))) { textView1.setTag( @@ -820,7 +847,12 @@ public void addTimeLayout( new View.OnClickListener() { @Override public void onClick(View view) { - + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.chart_actvity_left_arrow)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (dateTypeArray.get((int) leftArrow.getTag()).equalsIgnoreCase(DAY)) { try { SimpleDateFormat simpleDateFormat = AppController.getDateFormatForApi(); @@ -969,7 +1001,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { - + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.chart_actvity_right_arrow)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (dateTypeArray.get((int) rightArrow.getTag()).equalsIgnoreCase(DAY)) { try { SimpleDateFormat simpleDateFormat = diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/ConsentCompletedActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/ConsentCompletedActivity.java index 94f81f6457..295d509d11 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/ConsentCompletedActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/ConsentCompletedActivity.java @@ -25,21 +25,21 @@ import android.os.Bundle; import android.os.Environment; import android.os.Handler; -import android.support.annotation.NonNull; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.FileProvider; -import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; import android.widget.Toast; -import com.github.barteksc.pdfviewer.PDFView; -import com.github.barteksc.pdfviewer.scroll.DefaultScrollHandle; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.FileProvider; import com.harvard.R; import com.harvard.storagemodule.DbServiceSubscriber; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; +import com.harvard.utils.PdfViewerView; import io.realm.Realm; import java.io.File; import java.io.FileInputStream; @@ -63,6 +63,7 @@ public class ConsentCompletedActivity extends AppCompatActivity { private String comingFrom = ""; private DbServiceSubscriber dbServiceSubscriber; private Realm realm; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { @@ -70,6 +71,7 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_consent_completed); dbServiceSubscriber = new DbServiceSubscriber(); realm = AppController.getRealmobj(this); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); try { @@ -88,6 +90,12 @@ && getIntent() new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.consent_complete_viewPdf)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if ((ActivityCompat.checkSelfPermission( ConsentCompletedActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) @@ -114,6 +122,12 @@ public void onClick(View v) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.consent_complete_done)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (click) { click = false; new Handler() @@ -200,7 +214,7 @@ private void displayPdf() { if (sharingFile != null && sharingFile.exists()) { LayoutInflater li = LayoutInflater.from(ConsentCompletedActivity.this); View promptsView = li.inflate(R.layout.pdfdisplayview, null); - PDFView pdfView = (PDFView) promptsView.findViewById(R.id.pdf); + PdfViewerView pdfView = (PdfViewerView) promptsView.findViewById(R.id.pdfViewer); TextView share = (TextView) promptsView.findViewById(R.id.share); AlertDialog.Builder db = new AlertDialog.Builder(ConsentCompletedActivity.this); db.setView(promptsView); @@ -209,6 +223,12 @@ private void displayPdf() { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.consent_complete_share)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setData(Uri.parse("mailto:")); shareIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.signed_consent)); @@ -223,13 +243,8 @@ public void onClick(View v) { startActivity(shareIntent); } }); - pdfView.documentFitsView(); - pdfView.useBestQuality(true); - pdfView - .fromFile(file) - .enableAnnotationRendering(true) - .scrollHandle(new DefaultScrollHandle(this)) - .load(); + pdfView.setVisibility(View.VISIBLE); + pdfView.setPdf(sharingFile); db.show(); } else { Toast.makeText(this, R.string.consentPdfNotAvailable, Toast.LENGTH_SHORT).show(); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/ContactUsActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/ContactUsActivity.java index baa8ac65d3..122a48b87e 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/ContactUsActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/ContactUsActivity.java @@ -17,9 +17,9 @@ import android.app.Activity; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatEditText; -import android.support.v7.widget.AppCompatTextView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatEditText; +import androidx.appcompat.widget.AppCompatTextView; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.RelativeLayout; @@ -28,6 +28,7 @@ import com.harvard.studyappmodule.events.ContactUsEvent; import com.harvard.studyappmodule.studymodel.ReachOut; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.Urls; import com.harvard.webservicemodule.apihelper.ApiCall; @@ -48,11 +49,13 @@ public class ContactUsActivity extends AppCompatActivity implements ApiCall.OnAs private AppCompatEditText firstName; private static final int CONTACT_US = 15; private AppCompatTextView submitButton; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_contact_us); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); setFont(); bindEvents(); @@ -102,6 +105,12 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.contact_us_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); try { InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE); @@ -116,6 +125,12 @@ public void onClick(View v) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.contact_us_submit)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (firstName.getText().toString().equalsIgnoreCase("") && email.getText().toString().equalsIgnoreCase("") && subject.getText().toString().equalsIgnoreCase("") diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/CustomActivitiesDailyDialogClass.java b/Android/app/src/main/java/com/harvard/studyappmodule/CustomActivitiesDailyDialogClass.java index f6646aa55d..c66daeaea0 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/CustomActivitiesDailyDialogClass.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/CustomActivitiesDailyDialogClass.java @@ -20,7 +20,7 @@ import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; -import android.support.v7.widget.LinearLayoutCompat; +import androidx.appcompat.widget.LinearLayoutCompat; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; @@ -30,6 +30,7 @@ import android.widget.TextView; import com.harvard.R; import com.harvard.studyappmodule.surveyscheduler.model.ActivityStatus; +import com.harvard.utils.CustomFirebaseAnalytics; import java.util.ArrayList; public class CustomActivitiesDailyDialogClass extends Dialog implements View.OnClickListener { @@ -43,6 +44,7 @@ public class CustomActivitiesDailyDialogClass extends Dialog implements View.OnC private DialogClick dialogClick; private String status; private ActivityStatus activityStatus; + private CustomFirebaseAnalytics analyticsInstance; CustomActivitiesDailyDialogClass( Context context, @@ -65,6 +67,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_cutom_activities_daily_dialog); + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); // for dialog screen to get full width using this getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); @@ -97,6 +100,19 @@ protected void onCreate(Bundle savedInstanceState) { new View.OnClickListener() { @Override public void onClick(View v) { + String name = ""; + if (finalI == 0) { + name = "all"; + } else if (finalI == 1) { + name = "surveys"; + } else { + name = "tasks"; + } + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, name + " selected"); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialogClick.clicked(finalI); dismiss(); } @@ -108,6 +124,11 @@ public void onClick(View v) { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_activities_dialog_close)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dismiss(); } diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/CustomDialogClass.java b/Android/app/src/main/java/com/harvard/studyappmodule/CustomDialogClass.java index 806f0d3e55..3cdf087380 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/CustomDialogClass.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/CustomDialogClass.java @@ -18,11 +18,12 @@ import android.app.Activity; import android.app.Dialog; import android.os.Bundle; -import android.support.v7.widget.AppCompatTextView; +import androidx.appcompat.widget.AppCompatTextView; import android.view.View; import android.view.Window; import android.widget.NumberPicker; import com.harvard.R; +import com.harvard.utils.CustomFirebaseAnalytics; public class CustomDialogClass extends Dialog implements View.OnClickListener { @@ -31,7 +32,7 @@ public class CustomDialogClass extends Dialog implements View.OnClickListener private AppCompatTextView doneBtn; private final ProfileFragment profileFragment; private final String[] mins15 = {"00", "15", "30", "45"}; - + private CustomFirebaseAnalytics analyticsInstance; CustomDialogClass(Activity a, ProfileFragment profileFragment) { super(a); this.profileFragment = profileFragment; @@ -46,6 +47,7 @@ protected void onCreate(Bundle savedInstanceState) { minPicker = (NumberPicker) findViewById(R.id.picker_min); doneBtn = (AppCompatTextView) findViewById(R.id.doneBtn); doneBtn.setOnClickListener(this); + analyticsInstance = CustomFirebaseAnalytics.getInstance(getContext()); // if hr=24 then setvalue 1 means min arrays 0'th pos value minPicker.setOnValueChangedListener( new NumberPicker.OnValueChangeListener() { @@ -88,6 +90,11 @@ private void setMinsPicker() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getContext().getString(R.string.custom_dialog_done)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); String selectedValue = hourPicker.getValue() + ":" + mins15[minPicker.getValue() - 1]; profileFragment.updatePickerTime(selectedValue); dismiss(); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/DeleteAccountActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/DeleteAccountActivity.java index ba3b9a364e..d385659bfa 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/DeleteAccountActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/DeleteAccountActivity.java @@ -17,12 +17,10 @@ package com.harvard.studyappmodule; import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Resources; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatCheckBox; -import android.support.v7.widget.AppCompatTextView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatCheckBox; +import androidx.appcompat.widget.AppCompatTextView; import android.view.View; import android.widget.LinearLayout; import android.widget.RelativeLayout; @@ -31,20 +29,18 @@ import com.harvard.R; import com.harvard.storagemodule.DbServiceSubscriber; import com.harvard.studyappmodule.events.DeleteAccountEvent; -import com.harvard.studyappmodule.events.GetUserStudyInfoEvent; import com.harvard.studyappmodule.studymodel.DeleteAccountData; -import com.harvard.studyappmodule.studymodel.StudyHome; -import com.harvard.studyappmodule.studymodel.StudyList; import com.harvard.usermodule.UserModulePresenter; import com.harvard.usermodule.webservicemodel.LoginData; import com.harvard.usermodule.webservicemodel.Studies; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; import com.harvard.webservicemodule.apihelper.ApiCall; import com.harvard.webservicemodule.events.ParticipantDatastoreConfigEvent; -import com.harvard.webservicemodule.events.StudyDatastoreConfigEvent; + import io.realm.Realm; import io.realm.RealmResults; import java.util.ArrayList; @@ -66,6 +62,7 @@ public class DeleteAccountActivity extends AppCompatActivity private ArrayList studyIdList = new ArrayList<>(); private DbServiceSubscriber dbServiceSubscriber; private Realm realm; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { @@ -73,6 +70,7 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_delete_account); dbServiceSubscriber = new DbServiceSubscriber(); realm = AppController.getRealmobj(this); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); setTextForView(); setFont(); @@ -110,6 +108,12 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.delete_account_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }); @@ -118,6 +122,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.delete_account_disagree)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }); @@ -126,9 +136,15 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { - AppController.getHelperProgressDialog() - .showProgress(DeleteAccountActivity.this, "", "", false); - deactivateAccount(); + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.delete_account_agree)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + AppController.getHelperProgressDialog() + .showProgress(DeleteAccountActivity.this, "", "", false); + deactivateAccount(); } }); } @@ -164,9 +180,7 @@ public void asyncResponse(T response, int responseCode) { getResources().getString(R.string.account_deletion), Toast.LENGTH_SHORT) .show(); - SharedPreferences settings = - SharedPreferenceHelper.getPreferences(DeleteAccountActivity.this); - settings.edit().clear().apply(); + SharedPreferenceHelper.deletePreferences(this); // delete passcode from keystore String pass = AppController.refreshKeys("passcode"); if (pass != null) { diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/EligibilityEnrollmentActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/EligibilityEnrollmentActivity.java index d337d6f030..9796b6379f 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/EligibilityEnrollmentActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/EligibilityEnrollmentActivity.java @@ -18,8 +18,8 @@ import android.content.Intent; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatTextView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; import android.view.View; import android.widget.EditText; import android.widget.RelativeLayout; @@ -29,6 +29,7 @@ import com.harvard.studyappmodule.enroll.EnrollData; import com.harvard.studyappmodule.events.VerifyEnrollmentIdEvent; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; @@ -47,11 +48,13 @@ public class EligibilityEnrollmentActivity extends AppCompatActivity private EditText enrollmentID; private TextView submit; private String enteredId; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_eligibility_enrollment); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); setTextForView(); setFont(); @@ -97,6 +100,12 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.eligibility_enroll_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }); @@ -104,6 +113,12 @@ public void onClick(View v) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.eligibility_enroll_submit)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (!enrollmentID.getText().toString().trim().equalsIgnoreCase("")) { callValidateEnrollmentId(); } else { diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/EnrollmentValidatedActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/EnrollmentValidatedActivity.java index 588cf11b93..a760099c0f 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/EnrollmentValidatedActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/EnrollmentValidatedActivity.java @@ -19,8 +19,8 @@ import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatTextView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; import android.view.View; import com.harvard.AppConfig; import com.harvard.R; @@ -33,6 +33,7 @@ import com.harvard.usermodule.event.UpdatePreferenceEvent; import com.harvard.usermodule.webservicemodel.LoginData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.Urls; import com.harvard.webservicemodule.apihelper.ApiCall; @@ -59,6 +60,7 @@ public class EnrollmentValidatedActivity extends AppCompatActivity private DbServiceSubscriber dbServiceSubscriber; private Realm realm; private static final int UPDATE_USER_PREFERENCE_RESPONSE_CODE = 200; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { @@ -66,13 +68,19 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_enrollment_validated); dbServiceSubscriber = new DbServiceSubscriber(); realm = AppController.getRealmobj(this); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); setFont(); continueButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { - + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.enrollment_validated_continue)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); eligibilityConsent = dbServiceSubscriber.getConsentMetadata( getIntent().getStringExtra("studyId"), realm); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/FeedbackActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/FeedbackActivity.java index e52945ecb4..41d22a8556 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/FeedbackActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/FeedbackActivity.java @@ -17,9 +17,9 @@ import android.app.Activity; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatEditText; -import android.support.v7.widget.AppCompatTextView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatEditText; +import androidx.appcompat.widget.AppCompatTextView; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.RelativeLayout; @@ -28,6 +28,7 @@ import com.harvard.studyappmodule.events.ContactUsEvent; import com.harvard.studyappmodule.studymodel.ReachOut; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.Urls; import com.harvard.webservicemodule.apihelper.ApiCall; @@ -42,11 +43,13 @@ public class FeedbackActivity extends AppCompatActivity implements ApiCall.OnAsy private RelativeLayout backBtn; private AppCompatTextView submitButton; private static final int FEEDBACK = 16; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_feedback); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); setFont(); bindEvents(); @@ -78,6 +81,12 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.feedback_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); try { InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE); @@ -92,6 +101,12 @@ public void onClick(View v) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.feedback_submit)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (subject.getText().toString().equalsIgnoreCase("")) { Toast.makeText( FeedbackActivity.this, diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/FilterActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/FilterActivity.java index 919c807cd0..d4c9f47268 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/FilterActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/FilterActivity.java @@ -18,9 +18,9 @@ import android.graphics.drawable.GradientDrawable; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatCheckBox; -import android.support.v7.widget.AppCompatTextView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatCheckBox; +import androidx.appcompat.widget.AppCompatTextView; import android.view.View; import android.widget.RelativeLayout; import android.widget.Toast; @@ -32,6 +32,7 @@ import com.harvard.studyappmodule.studymodel.ParticipationStatus; import com.harvard.studyappmodule.studymodel.StudyStatus; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import org.json.JSONException; import org.json.JSONObject; @@ -65,11 +66,13 @@ public class FilterActivity extends AppCompatActivity { private AppCompatCheckBox pausedSelectBtn; private AppCompatTextView pausedLabel; private String userId; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_filter); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); userId = AppController.getHelperSharedPreference() @@ -186,6 +189,12 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.filter_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }); @@ -193,7 +202,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { - + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.filter_apply)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); StudyStatus studyStatus = new StudyStatus(); ParticipationStatus participationStatus = new ParticipationStatus(); @@ -257,7 +271,6 @@ public void onClick(View view) { flag1 = false; } - if (userId.equalsIgnoreCase("")) { if (flag1) { Toast.makeText( diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/GatewayResourcesListAdapter.java b/Android/app/src/main/java/com/harvard/studyappmodule/GatewayResourcesListAdapter.java index b2caac175b..4813eb8bd8 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/GatewayResourcesListAdapter.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/GatewayResourcesListAdapter.java @@ -17,8 +17,9 @@ import android.content.Context; import android.content.Intent; -import android.support.v7.widget.AppCompatTextView; -import android.support.v7.widget.RecyclerView; +import android.os.Bundle; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.recyclerview.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -26,6 +27,7 @@ import com.harvard.R; import com.harvard.studyappmodule.studymodel.Resource; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import io.realm.RealmList; import java.util.ArrayList; @@ -34,7 +36,7 @@ public class GatewayResourcesListAdapter extends RecyclerView.Adapter { private final Context context; private final ArrayList items = new ArrayList<>(); - + private CustomFirebaseAnalytics analyticsInstance; GatewayResourcesListAdapter(Context context, RealmList items) { this.context = context; this.items.addAll(items); @@ -45,6 +47,7 @@ public Holder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.resources_list_item, parent, false); + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); return new Holder(v); } @@ -87,6 +90,12 @@ public void onBindViewHolder(final Holder holder, final int position) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.gateway_resource_list)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (items.get(i).getType() != null && items.get(i).getContent() != null) { Intent intent = new Intent(context, GatewayResourcesWebViewActivity.class); intent.putExtra("title", "" + items.get(i).getTitle().toString()); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/GatewayResourcesWebViewActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/GatewayResourcesWebViewActivity.java index 59f6368bae..aa96eaac9b 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/GatewayResourcesWebViewActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/GatewayResourcesWebViewActivity.java @@ -24,21 +24,22 @@ import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.Environment; -import android.support.annotation.NonNull; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.FileProvider; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatTextView; +import androidx.annotation.NonNull; import android.view.View; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.RelativeLayout; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.core.app.ActivityCompat; +import androidx.core.content.FileProvider; import android.widget.Toast; -import com.github.barteksc.pdfviewer.PDFView; -import com.github.barteksc.pdfviewer.scroll.DefaultScrollHandle; import com.harvard.R; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; +import com.harvard.utils.PdfViewerView; + import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -51,16 +52,18 @@ public class GatewayResourcesWebViewActivity extends AppCompatActivity { private RelativeLayout backBtn; private WebView webView; private RelativeLayout shareBtn; - private PDFView pdfView; + private PdfViewerView pdfView; private static final int PERMISSION_REQUEST_CODE = 1000; private String intentTitle; private String intentType; private File finalSharingFile; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_resources_web_view); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); intentTitle = getIntent().getStringExtra("title"); @@ -74,6 +77,12 @@ protected void onCreate(Bundle savedInstanceState) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.gateway_resource_webview_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }); @@ -81,6 +90,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.gateway_resource_webview_share)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); try { Intent shareIntent = new Intent(Intent.ACTION_SEND); @@ -181,7 +196,7 @@ private void initializeXmlId() { title = (AppCompatTextView) findViewById(R.id.title); webView = (WebView) findViewById(R.id.webView); shareBtn = (RelativeLayout) findViewById(R.id.shareBtn); - pdfView = (PDFView) findViewById(R.id.pdfView); + pdfView = (PdfViewerView) findViewById(R.id.pdfViewer); } private void setFont() { @@ -243,16 +258,7 @@ protected void onDestroy() { private void displayPdfView(String filePath) { pdfView.setVisibility(View.VISIBLE); - try { - pdfView - .fromFile(new File(filePath)) - .defaultPage(0) - .enableAnnotationRendering(true) - .scrollHandle(new DefaultScrollHandle(GatewayResourcesWebViewActivity.this)) - .load(); - } catch (Exception e) { - Logger.log(e); - } + pdfView.setPdf(new File(filePath)); } public File getAssetsPdfPath() { diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/NotificationActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/NotificationActivity.java index edae357fd5..00872ba991 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/NotificationActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/NotificationActivity.java @@ -16,10 +16,10 @@ package com.harvard.studyappmodule; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatTextView; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import android.view.View; import android.widget.RelativeLayout; import android.widget.Toast; @@ -34,6 +34,7 @@ import com.harvard.studyappmodule.studymodel.StudyList; import com.harvard.usermodule.webservicemodel.UserProfileData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.Urls; import com.harvard.webservicemodule.apihelper.ApiCall; @@ -56,6 +57,7 @@ public class NotificationActivity extends AppCompatActivity private AppCompatTextView title; private DbServiceSubscriber dbServiceSubscriber; private Realm realm; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { @@ -64,6 +66,7 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_notification); dbServiceSubscriber = new DbServiceSubscriber(); realm = AppController.getRealmobj(this); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); AppController.getHelperSharedPreference() .writePreference(this, getString(R.string.notification), "false"); initializeXmlId(); @@ -96,6 +99,12 @@ private void bindEvent() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.notification_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/NotificationListAdapter.java b/Android/app/src/main/java/com/harvard/studyappmodule/NotificationListAdapter.java index 6ba6e3f1d8..7e38368479 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/NotificationListAdapter.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/NotificationListAdapter.java @@ -19,8 +19,9 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; -import android.support.v7.widget.AppCompatTextView; -import android.support.v7.widget.RecyclerView; +import android.os.Bundle; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.recyclerview.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -32,6 +33,7 @@ import com.harvard.studyappmodule.studymodel.Study; import com.harvard.studyappmodule.studymodel.StudyList; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import io.realm.Realm; import io.realm.RealmList; @@ -41,6 +43,7 @@ public class NotificationListAdapter extends RecyclerView.Adapter items; private DbServiceSubscriber dbServiceSubscriber; private Realm realm; + private CustomFirebaseAnalytics analyticsInstance; NotificationListAdapter(Context context, RealmList notifications, Realm realm) { this.context = context; @@ -54,6 +57,7 @@ public Holder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.notification_list_item, parent, false); + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); return new Holder(v); } @@ -104,6 +108,12 @@ public void onBindViewHolder(final Holder holder, final int position) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.notification_list)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (!AppController.getHelperSharedPreference() .readPreference(context, context.getResources().getString(R.string.userid), "") .equalsIgnoreCase("")) { @@ -111,7 +121,16 @@ public void onClick(View view) { if (items .get(holder.getAdapterPosition()) .getSubtype() - .equalsIgnoreCase("Study")) { + .equalsIgnoreCase("Study") + || items + .get(holder.getAdapterPosition()) + .getSubtype().equalsIgnoreCase("Activity") + || items + .get(holder.getAdapterPosition()) + .getSubtype().equalsIgnoreCase("Announcement") + || items + .get(holder.getAdapterPosition()) + .getSubtype().equalsIgnoreCase("studyEvent")) { Study study = dbServiceSubscriber.getStudyListFromDB(realm); if (study != null) { diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/PdfDisplayActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/PdfDisplayActivity.java index 726a1e8498..1f7b53ca45 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/PdfDisplayActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/PdfDisplayActivity.java @@ -24,17 +24,15 @@ import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.Environment; -import android.support.annotation.NonNull; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.FileProvider; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatTextView; import android.util.Base64; import android.view.View; import android.widget.RelativeLayout; import android.widget.Toast; -import com.github.barteksc.pdfviewer.PDFView; -import com.github.barteksc.pdfviewer.scroll.DefaultScrollHandle; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.core.app.ActivityCompat; +import androidx.core.content.FileProvider; import com.harvard.R; import com.harvard.storagemodule.DbServiceSubscriber; import com.harvard.studyappmodule.events.ConsentPdfEvent; @@ -42,7 +40,9 @@ import com.harvard.studyappmodule.studymodel.ConsentPdfData; import com.harvard.usermodule.UserModulePresenter; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; +import com.harvard.utils.PdfViewerView; import com.harvard.utils.Urls; import com.harvard.webservicemodule.apihelper.ApiCall; import com.harvard.webservicemodule.events.ParticipantConsentDatastoreConfigEvent; @@ -56,7 +56,6 @@ public class PdfDisplayActivity extends AppCompatActivity implements ApiCall.OnAsyncRequestComplete { private static final int CONSENTPDF = 7; - private PDFView pdfView; private String studyId; private String sharePdfFilePath; private static final int PERMISSION_REQUEST_CODE = 1000; @@ -64,6 +63,8 @@ public class PdfDisplayActivity extends AppCompatActivity private DbServiceSubscriber db; private Realm realm; private String title; + private CustomFirebaseAnalytics analyticsInstance; + PdfViewerView pdfViewer; @Override protected void onCreate(Bundle savedInstanceState) { @@ -71,7 +72,11 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_pdfdisplay); db = new DbServiceSubscriber(); realm = AppController.getRealmobj(this); - pdfView = (PDFView) findViewById(R.id.pdfView); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); + + + + pdfViewer = findViewById(R.id.pdfViewer); AppCompatTextView titletxt = (AppCompatTextView) findViewById(R.id.title); titletxt.setText(getResources().getString(R.string.consent_pdf1)); @@ -90,7 +95,7 @@ protected void onCreate(Bundle savedInstanceState) { AppController.generateDecryptedConsentPdf(studies.getPdfPath().toString()); // we will get byte array pass to pdf view bytesArray = AppController.cipherInputStreamConvertToByte(cis); - setPdfView(); + setPdfView(bytesArray, file.getName()); } else { callGetConsentPdfWebservice(); } @@ -104,6 +109,12 @@ protected void onCreate(Bundle savedInstanceState) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.pdf_display_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }); @@ -111,24 +122,30 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.pdf_display_share)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); // checking the permissions if ((ActivityCompat.checkSelfPermission( - PdfDisplayActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) + PdfDisplayActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) || (ActivityCompat.checkSelfPermission( - PdfDisplayActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED)) { + PdfDisplayActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED)) { String[] permission = - new String[] { - Manifest.permission.READ_EXTERNAL_STORAGE, - Manifest.permission.WRITE_EXTERNAL_STORAGE + new String[]{ + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE }; if (!hasPermissions(permission)) { // just checking is it already denied? Toast.makeText( - PdfDisplayActivity.this, - getResources().getString(R.string.permission_enable_message), - Toast.LENGTH_LONG) + PdfDisplayActivity.this, + getResources().getString(R.string.permission_enable_message), + Toast.LENGTH_LONG) .show(); } else { sharePdf(); @@ -168,7 +185,7 @@ private void callGetConsentPdfWebservice() { "Authorization", "Bearer " + AppController.getHelperSharedPreference() - .readPreference(this, getResources().getString(R.string.auth), "")); + .readPreference(this, getResources().getString(R.string.auth), "")); header.put( "userId", AppController.getHelperSharedPreference() @@ -192,28 +209,24 @@ private void callGetConsentPdfWebservice() { userModulePresenter.performConsentPdf(consentPdfEvent); } - private void setPdfView() { + private void setPdfView(byte[] bytesArray, String name) { // before writing pdf check permission pdfWritingPermission(); - pdfView - .fromBytes(bytesArray) - .defaultPage(0) - .enableAnnotationRendering(true) - .scrollHandle(new DefaultScrollHandle(this)) - .load(); + pdfViewer.setVisibility(View.VISIBLE); + pdfViewer.setPdfFromBytes(bytesArray, "temp.pdf"); } private void pdfWritingPermission() { // checking the permissions if ((ActivityCompat.checkSelfPermission( - PdfDisplayActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) + PdfDisplayActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) || (ActivityCompat.checkSelfPermission( - PdfDisplayActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED)) { + PdfDisplayActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED)) { String[] permission = - new String[] { - Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE + new String[]{ + Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; if (!hasPermissions(permission)) { ActivityCompat.requestPermissions( @@ -247,9 +260,9 @@ public void onRequestPermissionsResult( case PERMISSION_REQUEST_CODE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_DENIED) { Toast.makeText( - PdfDisplayActivity.this, - getResources().getString(R.string.permission_enable_message), - Toast.LENGTH_LONG) + PdfDisplayActivity.this, + getResources().getString(R.string.permission_enable_message), + Toast.LENGTH_LONG) .show(); } else { sharePdfCreation(); @@ -298,11 +311,10 @@ public void asyncResponse(T response, int responseCode) { } catch (Exception e) { Logger.log(e); } - setPdfView(); + setPdfView(bytesArray, consentPdfData.getStudyId()); try { - consentPdfData.setStudyId(studyId); - db.saveConsentPdf(this, consentPdfData); + db.saveConsentPdf(PdfDisplayActivity.this, consentPdfData); } catch (Exception e) { Logger.log(e); } @@ -328,7 +340,7 @@ public void asyncResponseFailure(int responseCode, String errormsg, String statu } catch (Exception e) { Logger.log(e); } - setPdfView(); + setPdfView(bytesArray, consentPdfData.getStudyId()); } else { Toast.makeText(PdfDisplayActivity.this, errormsg, Toast.LENGTH_SHORT).show(); } diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/ProfileFragment.java b/Android/app/src/main/java/com/harvard/studyappmodule/ProfileFragment.java index 929c4577e4..43bd5f6360 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/ProfileFragment.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/ProfileFragment.java @@ -22,9 +22,6 @@ import android.content.SharedPreferences; import android.graphics.Color; import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v7.widget.AppCompatEditText; -import android.support.v7.widget.AppCompatTextView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -33,6 +30,9 @@ import android.widget.Switch; import android.widget.TextView; import android.widget.Toast; +import androidx.appcompat.widget.AppCompatEditText; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.fragment.app.Fragment; import com.google.gson.Gson; import com.harvard.AppConfig; import com.harvard.BuildConfig; @@ -53,6 +53,7 @@ import com.harvard.usermodule.webservicemodel.UpdateUserProfileData; import com.harvard.usermodule.webservicemodel.UserProfileData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; @@ -104,6 +105,7 @@ public class ProfileFragment extends Fragment private int deleteIndexNumberDb; private DbServiceSubscriber dbServiceSubscriber; private Realm realm; + private CustomFirebaseAnalytics analyticsInstance; @Override public void onAttach(Context context) { @@ -116,6 +118,7 @@ public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_profile, container, false); dbServiceSubscriber = new DbServiceSubscriber(); + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); realm = AppController.getRealmobj(context); initializeXmlId(view); setFont(); @@ -214,6 +217,12 @@ public void onClick(View view) { if (switchRecvStdyRemindr.isChecked()) { CustomDialogClass cdd = new CustomDialogClass(((Activity) context), ProfileFragment.this); + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.profile_fragment_reminders)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); cdd.show(); } else { Toast.makeText(context, R.string.remainder_settings, Toast.LENGTH_SHORT).show(); @@ -225,6 +234,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.profile_fragment_password)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent intent = new Intent(context, ChangePasswordActivity.class); intent.putExtra("from", "ProfileFragment"); @@ -252,7 +267,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View v) { - + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.profile_fragment_passcode_btn)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent intent = new Intent(context, PasscodeSetupActivity.class); intent.putExtra("from", "profile"); startActivityForResult(intent, PASSCODE_CHANGE_REPSONSE); @@ -263,14 +283,39 @@ public void onClick(View v) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.profile_fragment_notification)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); callUpdateUserProfileWebService(true, "mSwitchRecvPushNotifctn"); } }); + switchUsePasscode.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.profile_fragment_passcode)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + } + }); + switchRecvStdyRemindr.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.profile_fragment_reminder_sty)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); callUpdateUserProfileWebService(true, "mSwitchRecvStdyRemindr"); } }); @@ -301,6 +346,12 @@ public void onClick(View v) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.profile_fragment_signout)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (signOutButton .getText() .toString() @@ -319,6 +370,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.profile_fragment_delete_acc)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent intent = new Intent(context, DeleteAccountActivity.class); startActivityForResult(intent, DELETE_ACCOUNT); } @@ -480,8 +537,7 @@ context, getResources().getString(R.string.profile_updated), Toast.LENGTH_SHORT) NotificationModuleSubscriber notificationModuleSubscriber = new NotificationModuleSubscriber(dbServiceSubscriber, realm); notificationModuleSubscriber.cancelNotificationTurnOffNotification(context); - SharedPreferences settings = SharedPreferenceHelper.getPreferences(context); - settings.edit().clear().apply(); + SharedPreferenceHelper.deletePreferences(context); // delete passcode from keystore String pass = AppController.refreshKeys("passcode"); AppController.deleteKey("passcode_" + pass); @@ -500,8 +556,7 @@ context, getResources().getString(R.string.profile_updated), Toast.LENGTH_SHORT) Toast.makeText( context, getResources().getString(R.string.account_deletion), Toast.LENGTH_SHORT) .show(); - SharedPreferences settings = SharedPreferenceHelper.getPreferences(context); - settings.edit().clear().apply(); + SharedPreferenceHelper.deletePreferences(context); // delete passcode from keystore String pass = AppController.refreshKeys("passcode"); if (pass != null) { diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/ReachoutFragment.java b/Android/app/src/main/java/com/harvard/studyappmodule/ReachoutFragment.java index da41f4d374..98af377005 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/ReachoutFragment.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/ReachoutFragment.java @@ -17,9 +17,9 @@ import android.content.Context; import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/ReachoutListAdapter.java b/Android/app/src/main/java/com/harvard/studyappmodule/ReachoutListAdapter.java index 1100c58af8..436e6c5e96 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/ReachoutListAdapter.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/ReachoutListAdapter.java @@ -15,10 +15,12 @@ package com.harvard.studyappmodule; +import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; -import android.support.v7.widget.AppCompatTextView; -import android.support.v7.widget.RecyclerView; +import android.os.Bundle; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.recyclerview.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -26,12 +28,14 @@ import android.widget.Toast; import com.harvard.R; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import java.util.ArrayList; public class ReachoutListAdapter extends RecyclerView.Adapter { private final Context context; private final ArrayList items = new ArrayList<>(); + private CustomFirebaseAnalytics analyticsInstance; ReachoutListAdapter(Context context, ArrayList items) { this.context = context; @@ -43,6 +47,7 @@ public Holder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.reachout_list_item, parent, false); + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); return new Holder(v); } @@ -77,7 +82,7 @@ private void setFont() { } @Override - public void onBindViewHolder(final Holder holder, final int position) { + public void onBindViewHolder(final Holder holder, @SuppressLint("RecyclerView") final int position) { final int i = holder.getAdapterPosition(); try { holder.reachoutTitle.setText(items.get(position)); @@ -86,6 +91,12 @@ public void onBindViewHolder(final Holder holder, final int position) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.reachout_list)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Toast.makeText(context, "GOTO Resources Details Screen " + i, Toast.LENGTH_LONG) .show(); } @@ -97,10 +108,26 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.reachout_list)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (position == 0) { + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.reachout_list_feedback)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent intent = new Intent(context, FeedbackActivity.class); context.startActivity(intent); } else { + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.reachout_list_contact_us)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent intent = new Intent(context, ContactUsActivity.class); context.startActivity(intent); } diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/ResourcesFragment.java b/Android/app/src/main/java/com/harvard/studyappmodule/ResourcesFragment.java index 30e7e7e00b..5e4265c5b4 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/ResourcesFragment.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/ResourcesFragment.java @@ -17,9 +17,9 @@ import android.content.Context; import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/ResourcesListAdapter.java b/Android/app/src/main/java/com/harvard/studyappmodule/ResourcesListAdapter.java index ab1e941462..19ef1ea139 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/ResourcesListAdapter.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/ResourcesListAdapter.java @@ -18,20 +18,22 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.support.v4.app.Fragment; -import android.support.v7.app.AlertDialog; -import android.support.v7.widget.AppCompatTextView; -import android.support.v7.widget.RecyclerView; +import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.RecyclerView; import com.harvard.AppConfig; import com.harvard.R; import com.harvard.storagemodule.DbServiceSubscriber; import com.harvard.studyappmodule.studymodel.Resource; import com.harvard.usermodule.TermsPrivacyPolicyActivity; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import io.realm.Realm; import io.realm.RealmList; @@ -43,6 +45,7 @@ public class ResourcesListAdapter extends RecyclerView.Adapter items = new ArrayList<>(); private Fragment fragment; + private CustomFirebaseAnalytics analyticsInstance; ResourcesListAdapter(Context context, RealmList items, Fragment fragment) { this.context = context; @@ -55,6 +58,7 @@ public Holder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.resources_list_item, parent, false); + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); return new Holder(v); } @@ -140,6 +144,12 @@ public int compare(final Resource o1, final Resource o2) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.resources_list)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); DbServiceSubscriber dbServiceSubscriber = new DbServiceSubscriber(); Realm realm = AppController.getRealmobj(context); if (items.get(i).getType() != null) { @@ -181,9 +191,9 @@ public void onClick(View view) { .getTitle() .equalsIgnoreCase(view.getResources().getString(R.string.resourceTerms))) { try { - Intent termsIntent = - new Intent(context, TermsPrivacyPolicyActivity.class); - termsIntent.putExtra("title", context.getResources().getString(R.string.resourceTerms)); + Intent termsIntent = new Intent(context, TermsPrivacyPolicyActivity.class); + termsIntent.putExtra( + "title", context.getResources().getString(R.string.resourceTerms)); termsIntent.putExtra("url", dbServiceSubscriber.getApps(realm).getTermsUrl()); context.startActivity(termsIntent); } catch (Exception e) { @@ -194,10 +204,11 @@ public void onClick(View view) { .getTitle() .equalsIgnoreCase(view.getResources().getString(R.string.resourcePolicy))) { try { - Intent termsIntent = - new Intent(context, TermsPrivacyPolicyActivity.class); - termsIntent.putExtra("title", context.getResources().getString(R.string.resourcePolicy)); - termsIntent.putExtra("url", dbServiceSubscriber.getApps(realm).getPrivacyPolicyUrl()); + Intent termsIntent = new Intent(context, TermsPrivacyPolicyActivity.class); + termsIntent.putExtra( + "title", context.getResources().getString(R.string.resourcePolicy)); + termsIntent.putExtra( + "url", dbServiceSubscriber.getApps(realm).getPrivacyPolicyUrl()); context.startActivity(termsIntent); } catch (Exception e) { Logger.log(e); @@ -212,7 +223,8 @@ public void onClick(View view) { .get(i) .getTitle() .equalsIgnoreCase(context.getResources().getString(R.string.leave_study)) - && AppConfig.AppType.equalsIgnoreCase(context.getString(R.string.app_standalone))) { + && AppConfig.AppType.equalsIgnoreCase( + context.getString(R.string.app_standalone))) { message = context.getString(R.string.leaveStudyDeleteAccount); } else { message = context.getString(R.string.leaveStudy); @@ -226,6 +238,12 @@ public void onClick(View view) { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.resources_list_leave_study_yes)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); ((SurveyResourcesFragment) fragment).responseServerWithdrawFromStudy(); } }); @@ -235,6 +253,12 @@ public void onClick(DialogInterface dialog, int which) { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.resources_list_leave_study_no)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.cancel(); } }); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/ResourcesWebViewActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/ResourcesWebViewActivity.java index 7e39684ddb..db60313796 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/ResourcesWebViewActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/ResourcesWebViewActivity.java @@ -27,44 +27,40 @@ import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.Environment; -import android.support.annotation.NonNull; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.FileProvider; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatTextView; import android.text.Html; import android.util.Base64; import android.view.View; import android.webkit.WebView; import android.widget.RelativeLayout; import android.widget.Toast; -import com.github.barteksc.pdfviewer.PDFView; -import com.github.barteksc.pdfviewer.scroll.DefaultScrollHandle; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.core.app.ActivityCompat; +import androidx.core.content.FileProvider; import com.harvard.R; import com.harvard.storagemodule.DbServiceSubscriber; import com.harvard.studyappmodule.studymodel.Resource; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; +import com.harvard.utils.PdfViewerView; import com.harvard.webservicemodule.apihelper.ConnectionDetector; -import java.io.BufferedInputStream; +import io.realm.Realm; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.URL; -import java.net.URLConnection; import javax.crypto.CipherInputStream; -import io.realm.Realm; public class ResourcesWebViewActivity extends AppCompatActivity { private AppCompatTextView titleTv; private RelativeLayout backBtn; private WebView webView; private RelativeLayout shareBtn; - private PDFView pdfView; private String CreateFilePath; private String fileName; private static final int PERMISSION_REQUEST_CODE = 1000; @@ -78,11 +74,15 @@ public class ResourcesWebViewActivity extends AppCompatActivity { private DbServiceSubscriber dbServiceSubscriber; String resourceId; Resource resource; + private CustomFirebaseAnalytics analyticsInstance; + PdfViewerView pdfViewer; @Override protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); setContentView(R.layout.activity_resources_web_view); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); CreateFilePath = "/data/data/" + getPackageName() + "/files/"; initializeXmlId(); @@ -99,6 +99,7 @@ protected void onCreate(Bundle savedInstanceState) { // removing space b/w the string : name of the pdf try { title = intentTitle.replaceAll("\\s+", ""); + title = title.replace("/", "\u2215"); } catch (Exception e) { title = intentTitle; Logger.log(e); @@ -150,6 +151,12 @@ protected void onCreate(Bundle savedInstanceState) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.resources_webview_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }); @@ -157,6 +164,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.resources_webview_share)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); try { Intent shareIntent = new Intent(Intent.ACTION_SEND); @@ -177,9 +190,12 @@ public void onClick(View v) { shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri); } } else { - shareIntent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(intentContent)); + shareIntent.setType("text/html"); + shareIntent.putExtra( + Intent.EXTRA_TEXT,Html.fromHtml(resource.getContent()).toString()); + shareIntent.putExtra( + Intent.EXTRA_HTML_TEXT, Html.fromHtml(resource.getContent()).toString()); } - startActivity(shareIntent); } catch (Exception e) { Logger.log(e); @@ -218,7 +234,7 @@ private void initializeXmlId() { titleTv = (AppCompatTextView) findViewById(R.id.title); webView = (WebView) findViewById(R.id.webView); shareBtn = (RelativeLayout) findViewById(R.id.shareBtn); - pdfView = (PDFView) findViewById(R.id.pdfView); + pdfViewer = (PdfViewerView) findViewById(R.id.pdfViewer); } private void setTextForView() { @@ -228,12 +244,17 @@ private void setTextForView() { webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setDefaultTextEncodingName("utf-8"); webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); - String webData = resource.getContent();; + String webData = resource.getContent(); if (Build.VERSION.SDK_INT >= 24) { - webView.loadDataWithBaseURL(null, - Html.fromHtml((webData), Html.FROM_HTML_MODE_LEGACY).toString(), "text/html", "UTF-8", null); + webView.loadDataWithBaseURL( + null, + Html.fromHtml((webData), Html.FROM_HTML_MODE_LEGACY).toString(), + "text/html", + "UTF-8", + null); } else { - webView.loadDataWithBaseURL(null, Html.fromHtml((webData)).toString(), "text/html", "UTF-8", null); + webView.loadDataWithBaseURL( + null, Html.fromHtml((webData)).toString(), "text/html", "UTF-8", null); } } @@ -344,6 +365,7 @@ protected String doInBackground(String... url1) { Logger.log(e1); } } + AppController.generateEncryptedConsentPdf(filePath, fileName); return null; } @@ -356,7 +378,6 @@ protected void onPostExecute(String url) { // downlaod success mean file exist else check offline file File file = new File(filePath + fileName + ".pdf"); if (file.exists()) { - AppController.generateEncryptedConsentPdf(filePath, fileName); displayPdfView(filePath + fileName + ".pdf"); } else { // offline functionality @@ -414,16 +435,7 @@ private File getEncryptedFilePath(String filePath) { } private void displayPdfView(String filePath) { - pdfView.setVisibility(View.VISIBLE); - try { - pdfView - .fromFile(new File(filePath)) - .defaultPage(0) - .enableAnnotationRendering(true) - .scrollHandle(new DefaultScrollHandle(ResourcesWebViewActivity.this)) - .load(); - } catch (Exception e) { - Logger.log(e); - } + pdfViewer.setVisibility(View.VISIBLE); + pdfViewer.setPdf(new File(filePath)); } } diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/SignupFragment.java b/Android/app/src/main/java/com/harvard/studyappmodule/SignupFragment.java index eeb7c1494b..35e97d0e2a 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/SignupFragment.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/SignupFragment.java @@ -23,11 +23,6 @@ import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; -import android.support.v4.app.Fragment; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.AppCompatCheckBox; -import android.support.v7.widget.AppCompatEditText; -import android.support.v7.widget.AppCompatTextView; import android.text.SpannableStringBuilder; import android.text.TextPaint; import android.text.method.LinkMovementMethod; @@ -39,12 +34,16 @@ import android.widget.CompoundButton; import android.widget.TextView; import android.widget.Toast; +import androidx.appcompat.widget.AppCompatCheckBox; +import androidx.appcompat.widget.AppCompatEditText; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; import com.google.firebase.iid.FirebaseInstanceId; import com.harvard.AppConfig; import com.harvard.BuildConfig; import com.harvard.R; import com.harvard.storagemodule.DbServiceSubscriber; -import com.harvard.usermodule.SignupActivity; import com.harvard.usermodule.TermsPrivacyPolicyActivity; import com.harvard.usermodule.UserModulePresenter; import com.harvard.usermodule.VerificationStepActivity; @@ -54,8 +53,8 @@ import com.harvard.usermodule.webservicemodel.RegistrationData; import com.harvard.usermodule.webservicemodel.UpdateUserProfileData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; -import com.harvard.utils.SetDialogHelper; import com.harvard.utils.Urls; import com.harvard.webservicemodule.apihelper.ApiCall; import com.harvard.webservicemodule.events.ParticipantDatastoreConfigEvent; @@ -88,6 +87,7 @@ public class SignupFragment extends Fragment implements ApiCall.OnAsyncRequestCo private String userAuth; private String userID; private RegistrationData registrationData; + private CustomFirebaseAnalytics analyticsInstance; @Override public void onAttach(Context context) { @@ -100,6 +100,7 @@ public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.content_signup, container, false); + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); clicked = false; initializeXmlId(view); customTextView(agreeLabel); @@ -152,8 +153,14 @@ public void updateDrawState(TextPaint ds) { @Override public void onClick(View widget) { + Bundle eventProperties = new Bundle(); if (termsAndConditionData != null && !termsAndConditionData.getTerms().equalsIgnoreCase("")) { + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.signup_fragment_terms)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent termsIntent = new Intent(context, TermsPrivacyPolicyActivity.class); termsIntent.putExtra("title", getResources().getString(R.string.terms)); termsIntent.putExtra("url", termsAndConditionData.getTerms()); @@ -186,6 +193,12 @@ public void updateDrawState(TextPaint ds) { @Override public void onClick(View widget) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.signup_fragment_privacy_policy)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (termsAndConditionData != null && !termsAndConditionData.getPrivacy().isEmpty()) { Intent termsIntent = new Intent(context, TermsPrivacyPolicyActivity.class); termsIntent.putExtra("title", getResources().getString(R.string.privacy_policy)); @@ -231,6 +244,12 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.signup_fragment_submit)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (clicked == false) { clicked = true; password.clearFocus(); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/StandaloneActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/StandaloneActivity.java index 7d6c724a56..e3c69dc373 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/StandaloneActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/StandaloneActivity.java @@ -21,7 +21,7 @@ import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.widget.Toast; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/StandaloneStudyInfoActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/StandaloneStudyInfoActivity.java index 0267633b13..fab11378e7 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/StandaloneStudyInfoActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/StandaloneStudyInfoActivity.java @@ -26,17 +26,16 @@ import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.customtabs.CustomTabsIntent; -import android.support.v4.view.ViewPager; -import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatImageView; -import android.support.v7.widget.AppCompatTextView; import android.view.View; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.Toast; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.browser.customtabs.CustomTabsIntent; +import androidx.viewpager.widget.ViewPager; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; import com.google.gson.Gson; @@ -48,7 +47,6 @@ import com.harvard.AppConfig; import com.harvard.BuildConfig; import com.harvard.R; -import com.harvard.WebViewActivity; import com.harvard.eligibilitymodule.CustomViewTaskActivity; import com.harvard.eligibilitymodule.StepsBuilder; import com.harvard.gatewaymodule.CircleIndicator; @@ -63,12 +61,12 @@ import com.harvard.studyappmodule.studymodel.StudyHome; import com.harvard.studyappmodule.studymodel.StudyList; import com.harvard.usermodule.UserModulePresenter; -import com.harvard.usermodule.VerificationStepActivity; import com.harvard.usermodule.event.GetPreferenceEvent; import com.harvard.usermodule.model.Apps; import com.harvard.usermodule.webservicemodel.Studies; import com.harvard.usermodule.webservicemodel.StudyData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; @@ -115,11 +113,13 @@ public class StandaloneStudyInfoActivity extends AppCompatActivity private String latestVersion; private boolean force = false; AlertDialog.Builder alertDialogBuilder; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_standalone_study_info); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); dbServiceSubscriber = new DbServiceSubscriber(); realm = AppController.getRealmobj(this); @@ -175,6 +175,11 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, getString(R.string.join_study)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (SharedPreferenceHelper.readPreference( StandaloneStudyInfoActivity.this, getString(R.string.userid), "") .equalsIgnoreCase("")) { @@ -205,11 +210,13 @@ StandaloneStudyInfoActivity.this, getString(R.string.userid), "") R.anim.slide_out_right) .build(); Apps apps = dbServiceSubscriber.getApps(realm); - customTabsIntent.intent.setData(Uri.parse(Urls.LOGIN_URL - .replace("$FromEmail", apps.getFromEmail()) - .replace("$SupportEmail", apps.getSupportEmail()) - .replace("$AppName", apps.getAppName()) - .replace("$ContactEmail", apps.getContactUsEmail()))); + customTabsIntent.intent.setData( + Uri.parse( + Urls.LOGIN_URL + .replace("$FromEmail", apps.getFromEmail()) + .replace("$SupportEmail", apps.getSupportEmail()) + .replace("$AppName", apps.getAppName()) + .replace("$ContactEmail", apps.getContactUsEmail()))); startActivity(customTabsIntent.intent); } else { loginCallback(); @@ -702,10 +709,16 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten "ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_update_next_time_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); } - }).show(); - + }) + .show(); } } } @@ -727,6 +740,12 @@ private void getStudyWebsiteNull() { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.visit_website)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(studyHome.getStudyWebsite())); startActivity(browserIntent); @@ -738,14 +757,21 @@ public void onClick(View v) { } else if (!studyHome.getStudyWebsite().equalsIgnoreCase("")) { bottombar1.setVisibility(View.VISIBLE); consentLayButton.setText(getResources().getString(R.string.visit_website)); - consentLay.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent browserIntent = + consentLay.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.visit_website)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(studyHome.getStudyWebsite())); - startActivity(browserIntent); - } - }); + startActivity(browserIntent); + } + }); } else { bottombar1.setVisibility(View.INVISIBLE); } @@ -906,6 +932,12 @@ public void isUpgrade(boolean b, String latestVersion, final boolean force) { positiveButton, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_upgrade_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); startActivityForResult( new Intent(Intent.ACTION_VIEW, Uri.parse(VersionChecker.PLAY_STORE_URL)), RESULT_CODE_UPGRADE); @@ -916,12 +948,18 @@ public void onClick(DialogInterface dialog, int id) { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_upgrade_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); if (force) { Toast.makeText( - StandaloneStudyInfoActivity.this, - "Please update the app to continue using", - Toast.LENGTH_SHORT) + StandaloneStudyInfoActivity.this, + "Please update the app to continue using", + Toast.LENGTH_SHORT) .show(); moveTaskToBack(true); if (Build.VERSION.SDK_INT < 21) { diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/StudyFragment.java b/Android/app/src/main/java/com/harvard/studyappmodule/StudyFragment.java index 989cd83dec..3f818d46fe 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/StudyFragment.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/StudyFragment.java @@ -20,15 +20,15 @@ import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.widget.AppCompatTextView; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Toast; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; import com.google.gson.Gson; diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/StudyInfoActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/StudyInfoActivity.java index bcc309dd5b..41f3444bfe 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/StudyInfoActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/StudyInfoActivity.java @@ -23,15 +23,14 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; -import android.support.customtabs.CustomTabsIntent; -import android.support.v4.view.ViewPager; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatImageView; -import android.support.v7.widget.AppCompatTextView; import android.view.View; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.Toast; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.browser.customtabs.CustomTabsIntent; +import androidx.viewpager.widget.ViewPager; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; import com.google.gson.Gson; @@ -56,7 +55,6 @@ import com.harvard.studyappmodule.studymodel.StudyHome; import com.harvard.studyappmodule.studymodel.StudyList; import com.harvard.usermodule.UserModulePresenter; -import com.harvard.usermodule.VerificationStepActivity; import com.harvard.usermodule.event.GetPreferenceEvent; import com.harvard.usermodule.event.UpdatePreferenceEvent; import com.harvard.usermodule.model.Apps; @@ -64,6 +62,7 @@ import com.harvard.usermodule.webservicemodel.Studies; import com.harvard.usermodule.webservicemodel.StudyData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; @@ -112,6 +111,7 @@ public class StudyInfoActivity extends AppCompatActivity implements ApiCall.OnAs private Realm realm; private EligibilityConsent eligibilityConsent; private RealmList userPreferenceStudies; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { @@ -119,6 +119,7 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_study_info); dbServiceSubscriber = new DbServiceSubscriber(); realm = AppController.getRealmobj(this); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); setFont(); @@ -171,6 +172,12 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.study_info_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); backClicked(); } }); @@ -179,7 +186,11 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { - + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, getString(R.string.join_study)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (AppController.getHelperSharedPreference() .readPreference( StudyInfoActivity.this, getResources().getString(R.string.userid), "") @@ -234,11 +245,13 @@ StudyInfoActivity.this, getResources().getString(R.string.userid), "") StudyInfoActivity.this, R.anim.slide_in_left, R.anim.slide_out_right) .build(); Apps apps = dbServiceSubscriber.getApps(realm); - customTabsIntent.intent.setData(Uri.parse(Urls.LOGIN_URL - .replace("$FromEmail", apps.getFromEmail()) - .replace("$SupportEmail", apps.getSupportEmail()) - .replace("$AppName", apps.getAppName()) - .replace("$ContactEmail", apps.getContactUsEmail()))); + customTabsIntent.intent.setData( + Uri.parse( + Urls.LOGIN_URL + .replace("$FromEmail", apps.getFromEmail()) + .replace("$SupportEmail", apps.getSupportEmail()) + .replace("$AppName", apps.getAppName()) + .replace("$ContactEmail", apps.getContactUsEmail()))); startActivity(customTabsIntent.intent); } else { new CallConsentMetaData(true).execute(); @@ -250,6 +263,12 @@ StudyInfoActivity.this, getResources().getString(R.string.userid), "") new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.visit_website)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); try { Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(studyHome.getStudyWebsite())); @@ -263,6 +282,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.view_consent)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); try { Intent intent = new Intent(StudyInfoActivity.this, WebViewActivity.class); intent.putExtra("consent", consentDocumentData.getConsent().getContent()); @@ -694,6 +719,12 @@ private void getStudyWebsiteNull() { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.view_consent)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(studyHome.getStudyWebsite())); startActivity(browserIntent); @@ -711,6 +742,12 @@ public void onClick(View v) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.view_consent)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); try { Intent intent = new Intent(StudyInfoActivity.this, WebViewActivity.class); intent.putExtra("consent", consentDocumentData.getConsent().getContent()); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/StudyInfoPagerAdapter.java b/Android/app/src/main/java/com/harvard/studyappmodule/StudyInfoPagerAdapter.java index 29d185d293..26ae9f4ee8 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/StudyInfoPagerAdapter.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/StudyInfoPagerAdapter.java @@ -20,14 +20,15 @@ import android.graphics.Color; import android.net.Uri; import android.os.Build; -import android.support.v4.view.PagerAdapter; -import android.support.v7.widget.AppCompatImageView; -import android.support.v7.widget.AppCompatTextView; +import android.os.Bundle; import android.text.Html; import android.util.Base64; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.viewpager.widget.PagerAdapter; import android.webkit.WebView; import android.widget.RelativeLayout; import com.bumptech.glide.Glide; @@ -36,6 +37,7 @@ import com.harvard.R; import com.harvard.studyappmodule.studymodel.StudyInfo; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import io.realm.RealmList; @@ -49,6 +51,7 @@ public class StudyInfoPagerAdapter extends PagerAdapter { private Context context; private RealmList info; private AppCompatImageView bgImg; + private CustomFirebaseAnalytics analyticsInstance; StudyInfoPagerAdapter(Context context, RealmList info, String studyId) { size = info.size(); @@ -75,6 +78,7 @@ public void destroyItem(ViewGroup view, int position, Object object) { public Object instantiateItem(ViewGroup collection, int position) { LayoutInflater inflater = (LayoutInflater) collection.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); if (info.get(position).getType().equalsIgnoreCase("video")) { View view = inflater.inflate(R.layout.study_info_item1, null); initializeXmlId(position, view); @@ -160,6 +164,12 @@ private void bindEvents(final int pos) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.watch_video)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(info.get(pos).getLink())); context.startActivity(intent); } diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/StudyListAdapter.java b/Android/app/src/main/java/com/harvard/studyappmodule/StudyListAdapter.java index 193b9b3951..d1392e2d21 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/StudyListAdapter.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/StudyListAdapter.java @@ -16,23 +16,21 @@ package com.harvard.studyappmodule; -import android.app.Activity; -import android.app.Fragment; +import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; -import android.graphics.Bitmap; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; +import android.os.Bundle; import android.os.Handler; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v7.widget.AppCompatImageView; -import android.support.v7.widget.AppCompatTextView; -import android.support.v7.widget.RecyclerView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.recyclerview.widget.RecyclerView; import android.text.Html; import android.util.Base64; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -42,17 +40,14 @@ import com.bumptech.glide.load.DataSource; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.GlideException; -import com.bumptech.glide.request.Request; import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.RequestOptions; -import com.bumptech.glide.request.target.BitmapImageViewTarget; -import com.bumptech.glide.request.target.SizeReadyCallback; import com.bumptech.glide.request.target.Target; -import com.bumptech.glide.request.transition.Transition; import com.harvard.R; import com.harvard.studyappmodule.studymodel.StudyList; import com.harvard.studyappmodule.surveyscheduler.model.CompletionAdherence; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import io.realm.RealmList; import java.util.ArrayList; @@ -63,6 +58,7 @@ public class StudyListAdapter extends RecyclerView.Adapter completionAdherenceCalcs; private boolean click = true; + private CustomFirebaseAnalytics analyticsInstance; StudyListAdapter( Context context, @@ -79,6 +75,7 @@ public class StudyListAdapter extends RecyclerView.Adapter new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.study_list)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (click) { click = false; new Handler() diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/StudySignInActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/StudySignInActivity.java index fe6ba3ad75..815a8fe4f1 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/StudySignInActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/StudySignInActivity.java @@ -17,16 +17,17 @@ import android.content.Intent; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatTextView; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import android.view.View; import android.widget.RelativeLayout; import android.widget.Toast; import com.harvard.R; import com.harvard.gatewaymodule.GatewayActivity; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import java.util.ArrayList; @@ -37,11 +38,13 @@ public class StudySignInActivity extends AppCompatActivity { private RelativeLayout filterBtn; private RelativeLayout resourceBtn; private AppCompatTextView signInButton; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sign_in_study); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); setTextForView(); setFont(); @@ -78,6 +81,12 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.filter_clicked)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Toast.makeText( StudySignInActivity.this, getResources().getString(R.string.filter_clicked), @@ -89,6 +98,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.resource_btn_clicked)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Toast.makeText( StudySignInActivity.this, getResources().getString(R.string.resource_btn_clicked), @@ -100,6 +115,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.sign_in_btn_clicked)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Toast.makeText( StudySignInActivity.this, getResources().getString(R.string.sign_in_btn_clicked), diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/StudySignInListAdapter.java b/Android/app/src/main/java/com/harvard/studyappmodule/StudySignInListAdapter.java index 1f2e07f4e4..bebea65a41 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/StudySignInListAdapter.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/StudySignInListAdapter.java @@ -17,9 +17,10 @@ import android.content.Context; import android.graphics.drawable.GradientDrawable; -import android.support.v7.widget.AppCompatImageView; -import android.support.v7.widget.AppCompatTextView; -import android.support.v7.widget.RecyclerView; +import android.os.Bundle; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.recyclerview.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -27,12 +28,14 @@ import android.widget.Toast; import com.harvard.R; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import java.util.ArrayList; public class StudySignInListAdapter extends RecyclerView.Adapter { private final Context context; private ArrayList items = new ArrayList<>(); + private CustomFirebaseAnalytics analyticsInstance; StudySignInListAdapter(Context context, ArrayList items) { this.context = context; @@ -44,6 +47,7 @@ public Holder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.study_sign_in_list_item, parent, false); + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); return new Holder(v); } @@ -126,6 +130,12 @@ public void onBindViewHolder(final Holder holder, final int position) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.study_signup_list)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Toast.makeText(context, "GOTO Details Screen", Toast.LENGTH_LONG).show(); } }); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/SurveyActivitiesFragment.java b/Android/app/src/main/java/com/harvard/studyappmodule/SurveyActivitiesFragment.java index eddfd1b456..15b1a88fde 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/SurveyActivitiesFragment.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/SurveyActivitiesFragment.java @@ -25,19 +25,19 @@ import android.os.AsyncTask; import android.os.Build.VERSION_CODES; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v4.app.ActivityCompat; -import android.support.v4.app.Fragment; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.widget.AppCompatImageView; -import android.support.v7.widget.AppCompatTextView; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.core.app.ActivityCompat; +import androidx.fragment.app.Fragment; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; import com.google.gson.Gson; @@ -94,6 +94,7 @@ import com.harvard.usermodule.webservicemodel.Studies; import com.harvard.usermodule.webservicemodel.StudyData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SetDialogHelper; import com.harvard.utils.SharedPreferenceHelper; @@ -152,6 +153,7 @@ public class SurveyActivitiesFragment extends Fragment private String activityId; // activityId for webservice on click of activity private boolean branching; // branching for webservice on click of activity private String activityVersion; // activityVersion for webservice on click of activity + private CustomFirebaseAnalytics analyticsInstance; private static final int ACTIVTTYLIST_RESPONSECODE = 100; private static final int ACTIVTTYINFO_RESPONSECODE = 101; @@ -190,6 +192,7 @@ public class SurveyActivitiesFragment extends Fragment private ArrayList arrayList; private ActivityData activityDataDB; String title = ""; + Intent calculateRunHoldServiceeintent; @Override public void onAttach(Context context) { @@ -202,6 +205,7 @@ public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_survey_activities, container, false); + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); initializeXmlId(view); dbServiceSubscriber = new DbServiceSubscriber(); realm = AppController.getRealmobj(context); @@ -266,6 +270,12 @@ private void bindEvents() { @Override public void onClick(View view) { if (AppConfig.AppType.equalsIgnoreCase(getString(R.string.app_gateway))) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_activities_home)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent intent = new Intent(context, StudyActivity.class); ComponentName cn = intent.getComponent(); Intent mainIntent = Intent.makeRestartActivityTask(cn); @@ -286,8 +296,20 @@ public void onClick(View view) { mScheduledTime.add(context.getResources().getString(R.string.tasks1)); CustomActivitiesDailyDialogClass c = new CustomActivitiesDailyDialogClass( - context, mScheduledTime, filterPos, true, SurveyActivitiesFragment.this, status.get(filterPos), currentRunStatusForActivities.get(filterPos)); + context, + mScheduledTime, + filterPos, + true, + SurveyActivitiesFragment.this, + status.get(filterPos), + currentRunStatusForActivities.get(filterPos)); c.show(); + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_activities_filter)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); } }); swipeRefreshLayout.setOnRefreshListener( @@ -728,7 +750,6 @@ public void asyncResponse(T response, int responseCode) { } else { Toast.makeText(context, R.string.unable_to_parse, Toast.LENGTH_SHORT).show(); } - } else if (responseCode == UPDATE_STUDY_PREFERENCE) { // check for notification AppController.getHelperProgressDialog().dismissDialog(); @@ -1461,7 +1482,7 @@ private void callGetStudyInfoWebservice() { "get", url, STUDY_INFO, - getActivity(), + context, StudyHome.class, null, header, @@ -1628,6 +1649,12 @@ private class CalculateRuns @Override protected ArrayList doInBackground(ArrayList... params) { + SharedPreferenceHelper.writePreference(context, "runsCalculating", "true"); + calculateRunHoldServiceeintent = new Intent(context, CalculateRunHoldService.class); + if (!AppController.isMyServiceRunning(context, CalculateRunHoldService.class)) { + context.startService(calculateRunHoldServiceeintent); + } + realm = AppController.getRealmobj(context); try { @@ -2309,7 +2336,13 @@ protected ArrayList doInBackground(ArrayList... para @Override protected void onPostExecute(ArrayList result) { + AppController.getHelperProgressDialog() + .updateMsg(context.getString(R.string.activity_loading_msg)); + SharedPreferenceHelper.writePreference(context, "runsCalculating", "false"); + if (AppController.isMyServiceRunning(context, CalculateRunHoldService.class)) { + context.stopService(calculateRunHoldServiceeintent); + } realm = AppController.getRealmobj(context); surveyActivitiesRecyclerView.setLayoutManager(new LinearLayoutManager(context)); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/SurveyActivitiesListAdapter.java b/Android/app/src/main/java/com/harvard/studyappmodule/SurveyActivitiesListAdapter.java index 62dc3f9eb5..99e96385df 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/SurveyActivitiesListAdapter.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/SurveyActivitiesListAdapter.java @@ -19,10 +19,11 @@ import android.content.Context; import android.graphics.Color; import android.graphics.drawable.GradientDrawable; +import android.os.Bundle; import android.os.Handler; -import android.support.v7.widget.AppCompatImageView; -import android.support.v7.widget.AppCompatTextView; -import android.support.v7.widget.RecyclerView; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.recyclerview.widget.RecyclerView; import android.text.Html; import android.view.LayoutInflater; import android.view.View; @@ -36,6 +37,7 @@ import com.harvard.studyappmodule.surveyscheduler.SurveyScheduler; import com.harvard.studyappmodule.surveyscheduler.model.ActivityStatus; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -57,6 +59,7 @@ public class SurveyActivitiesListAdapter private boolean paused; private Date joiningDate; private ArrayList timePos = new ArrayList<>(); + private CustomFirebaseAnalytics analyticsInstance; SurveyActivitiesListAdapter( Context context, @@ -80,6 +83,7 @@ public Holder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.survey_activities_list_item, parent, false); + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); return new Holder(v); } @@ -749,6 +753,12 @@ public void onBindViewHolder(final Holder holder, int position) { holder.container.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.survey_activities_list)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); int currentRunVal = currentRunStatusForActivities.get(holder.getAdapterPosition()).getCurrentRunId(); int totalRunVal = currentRunStatusForActivities.get(holder.getAdapterPosition()).getTotalRun(); if (click) { @@ -818,6 +828,12 @@ public void run() { holder.more.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.survey_activities_list_more)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); int p = 0; try { p = timePos.get(holder.getAdapterPosition()); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/SurveyActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/SurveyActivity.java index f56de2a317..04ca12497f 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/SurveyActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/SurveyActivity.java @@ -30,23 +30,22 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v4.app.ActivityCompat; -import android.support.v4.app.NotificationManagerCompat; -import android.support.v4.view.GravityCompat; -import android.support.v4.widget.DrawerLayout; -import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatImageView; -import android.support.v7.widget.AppCompatTextView; -import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; - +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.appcompat.widget.Toolbar; +import androidx.core.app.ActivityCompat; +import androidx.core.app.NotificationManagerCompat; +import androidx.core.view.GravityCompat; +import androidx.drawerlayout.widget.DrawerLayout; import com.harvard.AppConfig; import com.harvard.BuildConfig; import com.harvard.FdaApplication; @@ -59,6 +58,7 @@ import com.harvard.usermodule.event.LogoutEvent; import com.harvard.usermodule.webservicemodel.LoginData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; @@ -66,10 +66,8 @@ import com.harvard.utils.version.VersionChecker; import com.harvard.webservicemodule.apihelper.ApiCall; import com.harvard.webservicemodule.events.AuthServerConfigEvent; - import io.realm.Realm; import io.realm.RealmResults; - import java.util.HashMap; public class SurveyActivity extends AppCompatActivity @@ -122,11 +120,13 @@ public class SurveyActivity extends AppCompatActivity private String latestVersion; private boolean force = false; AlertDialog.Builder alertDialogBuilder; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_survey); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); bindEvents(); // default settings @@ -204,6 +204,12 @@ public void onDrawerSlide(View drawerView, float slideOffset) { @Override public void onDrawerOpened(View drawerView) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_side_menu)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); checkSignOrSignOutScenario(); } @@ -283,6 +289,12 @@ private void initializeXmlId() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_side_menu)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); openDrawer(); } }); @@ -294,6 +306,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_side_home)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); menulayout.setVisibility(View.VISIBLE); toolbar.setVisibility(View.GONE); closeDrawer(); @@ -308,6 +326,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_side_resources)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); menulayout.setVisibility(View.GONE); toolbar.setVisibility(View.VISIBLE); menutitle.setText(R.string.resources); @@ -331,6 +355,12 @@ public void onClick(View view) { closeDrawer(); if (previousValue != R.id.mSignInProfileLayout) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_side_my_account)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); previousValue = R.id.mSignInProfileLayout; getSupportFragmentManager() .beginTransaction() @@ -345,6 +375,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_side_reachout)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); menulayout.setVisibility(View.GONE); toolbar.setVisibility(View.VISIBLE); closeDrawer(); @@ -372,6 +408,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_side_sign_out)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); closeDrawer(); previousValue = R.id.mSignOutLayout; logout(); @@ -401,7 +443,12 @@ private void logout() { getResources().getString(R.string.sign_out), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_side_sign_out_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); AppController.getHelperProgressDialog() .showProgress(SurveyActivity.this, "", "", false); @@ -444,6 +491,12 @@ SurveyActivity.this, getString(R.string.userid), "") getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_side_sign_out_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); } }); @@ -469,14 +522,7 @@ private void closeDrawer() { } public void setVersion(TextView version) { - try { - PackageInfo info = - getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA); - version.append("" + info.versionName); - } catch (PackageManager.NameNotFoundException e) { - Logger.log(e); - version.setText(""); - } + version.append(BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")"); } private void bindEvents() { @@ -516,44 +562,69 @@ private void openResources() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); switch (view.getId()) { case R.id.myDashboardButtonLayout: - dashboardButton.setBackgroundResource(R.drawable.dashboard_blue_active); - activitiesButton.setBackgroundResource(R.drawable.activities_grey); - resourcesButton.setBackgroundResource(R.drawable.resources_grey); - dashboardButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimary)); - activitiesButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimaryBlack)); - resourcesButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimaryBlack)); - getSupportFragmentManager() - .beginTransaction() - .replace(R.id.frameLayoutContainer, surveyDashboardFragment, "fragment") - .commit(); + if (previousValue != R.id.myDashboardButtonLayout) { + previousValue = R.id.myDashboardButtonLayout; + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.dashboard_label)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + dashboardButton.setBackgroundResource(R.drawable.dashboard_blue_active); + activitiesButton.setBackgroundResource(R.drawable.activities_grey); + resourcesButton.setBackgroundResource(R.drawable.resources_grey); + dashboardButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimary)); + activitiesButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimaryBlack)); + resourcesButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimaryBlack)); + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.frameLayoutContainer, surveyDashboardFragment, "fragment") + .commit(); + } break; case R.id.mActivitiesButtonLayout: - dashboardButton.setBackgroundResource(R.drawable.dashboard_grey); - activitiesButton.setBackgroundResource(R.drawable.activities_blue_active); - resourcesButton.setBackgroundResource(R.drawable.resources_grey); - dashboardButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimaryBlack)); - activitiesButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimary)); - resourcesButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimaryBlack)); - getSupportFragmentManager() - .beginTransaction() - .replace(R.id.frameLayoutContainer, surveyActivitiesFragment, "fragment") - .commit(); + if (previousValue != R.id.mActivitiesButtonLayout) { + previousValue = R.id.mActivitiesButtonLayout; + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.activities_label)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + dashboardButton.setBackgroundResource(R.drawable.dashboard_grey); + activitiesButton.setBackgroundResource(R.drawable.activities_blue_active); + resourcesButton.setBackgroundResource(R.drawable.resources_grey); + dashboardButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimaryBlack)); + activitiesButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimary)); + resourcesButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimaryBlack)); + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.frameLayoutContainer, surveyActivitiesFragment, "fragment") + .commit(); + } break; case R.id.mResourcesButtonLayout: - dashboardButton.setBackgroundResource(R.drawable.dashboard_grey); - activitiesButton.setBackgroundResource(R.drawable.activities_grey); - resourcesButton.setBackgroundResource(R.drawable.resources_blue_active); - dashboardButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimaryBlack)); - activitiesButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimaryBlack)); - resourcesButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimary)); - getSupportFragmentManager() - .beginTransaction() - .replace(R.id.frameLayoutContainer, surveyResourcesFragment, "fragment") - .commit(); + if (previousValue != R.id.mResourcesButtonLayout) { + previousValue = R.id.mResourcesButtonLayout; + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.resources_label)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + dashboardButton.setBackgroundResource(R.drawable.dashboard_grey); + activitiesButton.setBackgroundResource(R.drawable.activities_grey); + resourcesButton.setBackgroundResource(R.drawable.resources_blue_active); + dashboardButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimaryBlack)); + activitiesButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimaryBlack)); + resourcesButtonLabel.setTextColor(getResources().getColor(R.color.colorPrimary)); + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.frameLayoutContainer, surveyResourcesFragment, "fragment") + .commit(); + } break; } } @@ -638,8 +709,7 @@ public void asyncResponse(T response, int responseCode) { if (responseCode == LOGOUT_REPSONSECODE) { Toast.makeText(this, getResources().getString(R.string.signed_out), Toast.LENGTH_SHORT) .show(); - SharedPreferences settings = SharedPreferenceHelper.getPreferences(SurveyActivity.this); - settings.edit().clear().apply(); + SharedPreferenceHelper.deletePreferences(this); // delete passcode from keystore String pass = AppController.refreshKeys("passcode"); if (pass != null) { @@ -786,6 +856,12 @@ public void isUpgrade(boolean b, String latestVersion, final boolean force) { positiveButton, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_upgrade_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); startActivityForResult( new Intent(Intent.ACTION_VIEW, Uri.parse(VersionChecker.PLAY_STORE_URL)), RESULT_CODE_UPGRADE); @@ -796,6 +872,12 @@ public void onClick(DialogInterface dialog, int id) { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_upgrade_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); if (force) { Toast.makeText( @@ -851,10 +933,16 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten "ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.app_update_next_time_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); } - }).show(); - + }) + .show(); } } } diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/SurveyCompleteActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/SurveyCompleteActivity.java index c186302c55..2345a10a4f 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/SurveyCompleteActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/SurveyCompleteActivity.java @@ -17,7 +17,7 @@ import android.content.Intent; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.view.View; import android.widget.TextView; import android.widget.Toast; @@ -42,6 +42,7 @@ import com.harvard.usermodule.webservicemodel.Studies; import com.harvard.usermodule.webservicemodel.StudyData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; @@ -50,6 +51,10 @@ import com.harvard.webservicemodule.events.ResponseDatastoreConfigEvent; import io.realm.Realm; import io.realm.RealmResults; + +import java.text.DateFormat; +import java.util.Calendar; +import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -72,12 +77,14 @@ public class SurveyCompleteActivity extends AppCompatActivity private DbServiceSubscriber dbServiceSubscriber; private double completion = 0; private double adherence = 0; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_survey_complete); dbServiceSubscriber = new DbServiceSubscriber(); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); realm = AppController.getRealmobj(this); initializeXmlId(); setFont(); @@ -85,6 +92,12 @@ protected void onCreate(Bundle savedInstanceState) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_complete_done)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); next.setClickable(false); next.setEnabled(false); updateProcessResponse(); @@ -165,7 +178,9 @@ this, getResources().getString(R.string.unable_to_submit_result), Toast.LENGTH_S private JSONObject getResponseDataJson( ActivityObj activityObj, Activities activities, Studies studies) { + JSONObject responseJson = new JSONObject(); JSONObject processResponsejson = new JSONObject(); + JSONObject activityState = new JSONObject(); try { processResponsejson.put("type", activityObj.getType()); processResponsejson.put("participantId", studies.getParticipantId()); @@ -184,6 +199,18 @@ private JSONObject getResponseDataJson( processResponsejson.put("metadata", infoJson); processResponsejson.put( "data", generateresult(activityObj, getIntent().getStringExtra(EXTRA_STUDYID))); + + responseJson.put("activityResponse", processResponsejson); + + int completedRun = getIntent().getIntExtra(CustomSurveyViewTaskActivity.COMPLETED_RUN, 0); + completedRun = completedRun + 1; + int currentRun = getIntent().getIntExtra(CustomSurveyViewTaskActivity.RUNID, 0); + int missedRun = currentRun - completedRun; + JSONObject activityRun = new JSONObject(); + activityRun.put("total", getIntent().getIntExtra(CustomSurveyViewTaskActivity.TOTAL_RUN, 0)); + activityRun.put("completed", completedRun); + activityRun.put("missed", missedRun); + processResponsejson.put("activityRun", activityRun); } catch (JSONException e) { Logger.log(e); } @@ -198,6 +225,7 @@ private JSONObject generateresult(ActivityObj activityObj, String stringExtra) { dataobj.put("startTime", activityObj.getMetadata().getStartDate()); dataobj.put("endTime", activityObj.getMetadata().getEndDate()); dataobj.put("resultType", activityObj.getType()); + dataobj.put("submittedTime", AppController.getDateFormatForApi().format(Calendar.getInstance().getTime())); JSONArray resultarray = new JSONArray(); JsonParser jsonParser = new JsonParser(); @@ -560,43 +588,6 @@ private void setFont() { } } - public void updateUserPreference() { - HashMap header = new HashMap(); - Realm realm = AppController.getRealmobj(SurveyCompleteActivity.this); - Studies studies = - dbServiceSubscriber.getStudies( - getIntent().getStringExtra(CustomSurveyViewTaskActivity.STUDYID), realm); - header.put( - "Authorization", - "Bearer " - + AppController.getHelperSharedPreference() - .readPreference(this, getResources().getString(R.string.auth), "")); - header.put( - "userId", - AppController.getHelperSharedPreference() - .readPreference(this, getResources().getString(R.string.userid), "")); - header.put("participantId", studies.getParticipantId()); - - ResponseDatastoreConfigEvent responseDatastoreConfigEvent = - new ResponseDatastoreConfigEvent( - "post_object", - Urls.UPDATE_ACTIVITY_PREFERENCE, - UPDATE_USERPREFERENCE_RESPONSECODE, - this, - LoginData.class, - null, - header, - getActivityPreferenceJson(), - false, - this); - - dbServiceSubscriber.closeRealmObj(realm); - ActivityStateEvent activityStateEvent = new ActivityStateEvent(); - activityStateEvent.setResponseDatastoreConfigEvent(responseDatastoreConfigEvent); - UserModulePresenter userModulePresenter = new UserModulePresenter(); - userModulePresenter.performActivityState(activityStateEvent); - } - private JSONObject getActivityPreferenceJson() { String surveyId = getIntent().getStringExtra(CustomSurveyViewTaskActivity.EXTRA_STUDYID); surveyId = surveyId.substring(0, surveyId.lastIndexOf("_")); @@ -657,46 +648,7 @@ public void onBackPressed() { @Override public void asyncResponse(T response, int responseCode) { - if (responseCode == UPDATE_USERPREFERENCE_RESPONSECODE) { - LoginData loginData = (LoginData) response; - if (loginData != null) { - - // calculate completion and adherence - int completed = - Integer.parseInt( - AppController.getHelperSharedPreference() - .readPreference( - SurveyCompleteActivity.this, - getResources().getString(R.string.completedRuns), - "")); - int missed = - Integer.parseInt( - AppController.getHelperSharedPreference() - .readPreference( - SurveyCompleteActivity.this, - getResources().getString(R.string.missedRuns), - "")); - int total = - Integer.parseInt( - AppController.getHelperSharedPreference() - .readPreference( - SurveyCompleteActivity.this, - getResources().getString(R.string.totalRuns), - "")); - - if ((double) total > 0) { - completion = (((double) completed + (double) missed + 1d) / (double) total) * 100d; - } - if (((double) completed + (double) missed + 1d) > 0) { - adherence = - (((double) completed + 1d) / ((double) completed + (double) missed + 1d)) * 100d; - } - updateStudyState("" + (int) completion, "" + (int) adherence); - } else { - AppController.getHelperProgressDialog().dismissDialog(); - Toast.makeText(this, R.string.unable_to_parse, Toast.LENGTH_SHORT).show(); - } - } else if (responseCode == UPDATE_STUDY_PREFERENCE) { + if (responseCode == UPDATE_STUDY_PREFERENCE) { AppController.getHelperProgressDialog().dismissDialog(); String surveyId = getIntent().getStringExtra(CustomSurveyViewTaskActivity.EXTRA_STUDYID); surveyId = surveyId.substring(0, surveyId.lastIndexOf("_")); @@ -742,7 +694,37 @@ public void asyncResponse(T response, int responseCode) { } else if (responseCode == PROCESS_RESPONSE_RESPONSECODE) { LoginData loginData = (LoginData) response; if (loginData != null) { - updateUserPreference(); + // calculate completion and adherence + int completed = + Integer.parseInt( + AppController.getHelperSharedPreference() + .readPreference( + SurveyCompleteActivity.this, + getResources().getString(R.string.completedRuns), + "")); + int missed = + Integer.parseInt( + AppController.getHelperSharedPreference() + .readPreference( + SurveyCompleteActivity.this, + getResources().getString(R.string.missedRuns), + "")); + int total = + Integer.parseInt( + AppController.getHelperSharedPreference() + .readPreference( + SurveyCompleteActivity.this, + getResources().getString(R.string.totalRuns), + "")); + + if ((double) total > 0) { + completion = (((double) completed + (double) missed + 1d) / (double) total) * 100d; + } + if (((double) completed + (double) missed + 1d) > 0) { + adherence = + (((double) completed + 1d) / ((double) completed + (double) missed + 1d)) * 100d; + } + updateStudyState("" + (int) completion, "" + (int) adherence); } else { AppController.getHelperProgressDialog().dismissDialog(); } @@ -807,30 +789,6 @@ public void asyncResponseFailure(int responseCode, String errormsg, String statu // offline data storing for response server finish - // offline data storing activity preference - try { - int number = dbServiceSubscriber.getUniqueID(realm); - if (number == 0) { - number = 1; - } else { - number += 1; - } - AppController.pendingService( - this, - number, - "post_object", - Urls.UPDATE_ACTIVITY_PREFERENCE, - "", - getActivityPreferenceJson().toString(), - "ResponseDatastore", - "", - "", - ""); - } catch (Exception e) { - Logger.log(e); - } - // offline data storing activity preference finish - // offline data storing study preference try { int number = dbServiceSubscriber.getUniqueID(realm); @@ -913,33 +871,6 @@ public void asyncResponseFailure(int responseCode, String errormsg, String statu setResult(RESULT_OK, intent); finish(); } else { - - // offline data storing activity preference - try { - if (responseCode == UPDATE_USERPREFERENCE_RESPONSECODE) { - int number = dbServiceSubscriber.getUniqueID(realm); - if (number == 0) { - number = 1; - } else { - number += 1; - } - AppController.pendingService( - this, - number, - "post_object", - Urls.UPDATE_ACTIVITY_PREFERENCE, - "", - getActivityPreferenceJson().toString(), - "ResponseDatastore", - "", - "", - ""); - } - } catch (Exception e) { - Logger.log(e); - } - // offline data storing activity preference finish - // offline data storing study preference try { int number = dbServiceSubscriber.getUniqueID(realm); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/SurveyDashboardFragment.java b/Android/app/src/main/java/com/harvard/studyappmodule/SurveyDashboardFragment.java index a5b52a84b6..19ede6decb 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/SurveyDashboardFragment.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/SurveyDashboardFragment.java @@ -33,12 +33,6 @@ import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.Environment; -import android.support.annotation.NonNull; -import android.support.v4.app.ActivityCompat; -import android.support.v4.app.Fragment; -import android.support.v4.content.FileProvider; -import android.support.v7.widget.AppCompatImageView; -import android.support.v7.widget.AppCompatTextView; import android.text.Spannable; import android.text.SpannableString; import android.text.style.ForegroundColorSpan; @@ -51,6 +45,12 @@ import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.core.app.ActivityCompat; +import androidx.core.content.FileProvider; +import androidx.fragment.app.Fragment; import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; @@ -69,6 +69,7 @@ import com.harvard.studyappmodule.surveyscheduler.model.CompletionAdherence; import com.harvard.usermodule.webservicemodel.Studies; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; @@ -154,6 +155,7 @@ public class SurveyDashboardFragment extends Fragment implements ApiCall.OnAsync private Studies studies; private ArrayList arrayList; private ArrayList arrayListDup; + private CustomFirebaseAnalytics analyticsInstance; // NOTE: Regarding Day, Week and Month functionality // currently day functionality next, previous are working @@ -178,6 +180,7 @@ public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment view = inflater.inflate(R.layout.fragment_survey_dashboard, container, false); + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); dbServiceSubscriber = new DbServiceSubscriber(); realm = AppController.getRealmobj(context); initializeXmlId(view); @@ -401,6 +404,12 @@ private void bindEvents() { @Override public void onClick(View v) { if (AppConfig.AppType.equalsIgnoreCase(getString(R.string.app_gateway))) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_dashbord_home)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent intent = new Intent(context, StudyActivity.class); ComponentName cn = intent.getComponent(); Intent mainIntent = Intent.makeRestartActivityTask(cn); @@ -416,6 +425,12 @@ public void onClick(View v) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_dashbord_share)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); screenshotWritingPermission(view); } }); @@ -424,6 +439,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_dashbord_day)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (!dateType.equalsIgnoreCase(DAY)) { nextDateLayout.setVisibility(View.INVISIBLE); setDay(); @@ -436,6 +457,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_dashbord_week)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (!dateType.equalsIgnoreCase(WEEK)) { nextDateLayout.setVisibility(View.INVISIBLE); setWeek(); @@ -447,6 +474,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_dashbord_month)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); try { if (!dateType.equalsIgnoreCase(MONTH)) { nextDateLayout.setVisibility(View.INVISIBLE); @@ -462,6 +495,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_dashbord_change_date_left)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); nextDateLayout.setVisibility(View.VISIBLE); if (dateType.equalsIgnoreCase(DAY)) { try { @@ -534,7 +573,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { - + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_dashbord_change_date_right)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (dateType.equalsIgnoreCase(DAY)) { try { SimpleDateFormat simpleDateFormat = @@ -637,6 +681,11 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, getString(R.string.trends)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (dashboardData != null && dashboardData.getDashboard().getCharts().size() > 0) { Intent intent = new Intent(context, ChartActivity.class); intent.putExtra("studyId", ((SurveyActivity) context).getStudyId()); @@ -1095,12 +1144,14 @@ protected void onPostExecute(String result) { new ResponseInfoActiveTaskModel(); if (!arrayListDup.contains( dashboardData - .getDashboard() - .getStatistics() - .get(i) - .getDataSource() - .getActivity() - .getActivityId())) { + .getDashboard() + .getStatistics() + .get(i) + .getDataSource() + .getActivity() + .getActivityId() + + "," + + dashboardData.getDashboard().getStatistics().get(i).getDataSource().getKey())) { responseInfoActiveTaskModel.setActivityId( dashboardData .getDashboard() @@ -1122,12 +1173,14 @@ protected void onPostExecute(String result) { arrayList.add(responseInfoActiveTaskModel); arrayListDup.add( dashboardData - .getDashboard() - .getStatistics() - .get(i) - .getDataSource() - .getActivity() - .getActivityId()); + .getDashboard() + .getStatistics() + .get(i) + .getDataSource() + .getActivity() + .getActivityId() + + "," + + dashboardData.getDashboard().getStatistics().get(i).getDataSource().getKey()); } } for (int i = 0; i < dashboardData.getDashboard().getCharts().size(); i++) { @@ -1135,12 +1188,14 @@ protected void onPostExecute(String result) { new ResponseInfoActiveTaskModel(); if (!arrayListDup.contains( dashboardData - .getDashboard() - .getCharts() - .get(i) - .getDataSource() - .getActivity() - .getActivityId())) { + .getDashboard() + .getCharts() + .get(i) + .getDataSource() + .getActivity() + .getActivityId() + + "," + + dashboardData.getDashboard().getCharts().get(i).getDataSource().getKey())) { responseInfoActiveTaskModel.setActivityId( dashboardData .getDashboard() @@ -1162,12 +1217,14 @@ protected void onPostExecute(String result) { arrayList.add(responseInfoActiveTaskModel); arrayListDup.add( dashboardData - .getDashboard() - .getCharts() - .get(i) - .getDataSource() - .getActivity() - .getActivityId()); + .getDashboard() + .getCharts() + .get(i) + .getDataSource() + .getActivity() + .getActivityId() + + "," + + dashboardData.getDashboard().getCharts().get(i).getDataSource().getKey()); } } } @@ -1181,6 +1238,7 @@ protected void onPostExecute(String result) { 0) .execute(); } else { + AppController.getHelperProgressDialog().dismissDialog(); addViewStatisticsValues(); } } @@ -1447,22 +1505,24 @@ protected void onPostExecute(String response) { JSONObject jsonObject1 = new JSONObject(String.valueOf(jsonArray.get(i))); JSONArray jsonArray1 = (JSONArray) jsonObject1.get("data"); int duration = 0; + Date completedDate = null; for (int j = 0; j < jsonArray1.length(); j++) { JSONObject jsonObjectData = (JSONObject) jsonArray1.get(j); Type type = new TypeToken>() {}.getType(); Map map = gson.fromJson(String.valueOf(jsonObjectData), type); StepRecordCustom stepRecordCustom = new StepRecordCustom(); - Date completedDate = new Date(); - try { - Object completedDateValMap = gson.toJson(map.get("Created")); - Map completedDateVal = - gson.fromJson(String.valueOf(completedDateValMap), type); - if (completedDateVal != null) { - completedDate = - simpleDateFormat.parse(String.valueOf(completedDateVal.get("value"))); + if (completedDate == null) { + try { + Object completedDateValMap = gson.toJson(map.get("Created")); + Map completedDateVal = + gson.fromJson(String.valueOf(completedDateValMap), type); + if (completedDateVal != null) { + completedDate = + simpleDateFormat.parse(String.valueOf(completedDateVal.get("value"))); + } + } catch (JsonSyntaxException | ParseException e) { + Logger.log(e); } - } catch (JsonSyntaxException | ParseException e) { - Logger.log(e); } try { @@ -1475,6 +1535,7 @@ protected void onPostExecute(String response) { } catch (Exception e) { Logger.log(e); } + for (Map.Entry entry : map.entrySet()) { String key = entry.getKey(); String valueobj = gson.toJson(entry.getValue()); @@ -1507,59 +1568,98 @@ protected void onPostExecute(String response) { + runId + "_" + stepKey); - } else { - stepRecordCustom.setStepId(key); - stepRecordCustom.setTaskStepID( + stepRecordCustom.setStudyId(studyId); + stepRecordCustom.setActivityID( + studyId + "_STUDYID_" + responseInfoActiveTaskModel.getActivityId()); + stepRecordCustom.setTaskId( studyId + "_STUDYID_" + responseInfoActiveTaskModel.getActivityId() + "_" - + runId - + "_" - + key); - } - stepRecordCustom.setStudyId(studyId); - stepRecordCustom.setActivityID( - studyId + "_STUDYID_" + responseInfoActiveTaskModel.getActivityId()); - stepRecordCustom.setTaskId( - studyId - + "_STUDYID_" - + responseInfoActiveTaskModel.getActivityId() - + "_" - + runId); - - stepRecordCustom.setCompleted(completedDate); - stepRecordCustom.setStarted(completedDate); - - try { - Date anchordate = AppController.getLabkeyDateFormat().parse("" + value); - value = AppController.getDateFormatForApi().format(anchordate); - } catch (ParseException e) { - Logger.log(e); + + runId); + + stepRecordCustom.setCompleted(completedDate); + stepRecordCustom.setStarted(completedDate); + + JSONObject jsonObject2 = new JSONObject(); + ActivitiesWS activityObj = + dbServiceSubscriber.getActivityObj( + responseInfoActiveTaskModel.getActivityId(), studyId, realm); + if (activityObj.getType().equalsIgnoreCase("task")) { + JSONObject jsonObject3 = new JSONObject(); + jsonObject3.put("value", value); + jsonObject3.put("duration", duration); + + jsonObject2.put("answer", jsonObject3); + } else { + jsonObject2.put("answer", value); + } + + stepRecordCustom.setResult(String.valueOf(jsonObject2)); + Number currentIdNum = dbServiceSubscriber.getStepRecordCustomId(realm); + if (currentIdNum == null) { + stepRecordCustom.setId(1); + } else { + stepRecordCustom.setId(currentIdNum.intValue() + 1); + } + dbServiceSubscriber.updateStepRecord(context, stepRecordCustom); + } else { + if (key.equalsIgnoreCase(stepKey)) { + stepRecordCustom.setStepId(key); + stepRecordCustom.setTaskStepID( + studyId + + "_STUDYID_" + + responseInfoActiveTaskModel.getActivityId() + + "_" + + runId + + "_" + + key); + + stepRecordCustom.setStudyId(studyId); + stepRecordCustom.setActivityID( + studyId + "_STUDYID_" + responseInfoActiveTaskModel.getActivityId()); + stepRecordCustom.setTaskId( + studyId + + "_STUDYID_" + + responseInfoActiveTaskModel.getActivityId() + + "_" + + runId); + + stepRecordCustom.setCompleted(completedDate); + stepRecordCustom.setStarted(completedDate); + + try { + Date anchordate = AppController.getLabkeyDateFormat().parse("" + value); + value = AppController.getDateFormatForApi().format(anchordate); + } catch (ParseException e) { + Logger.log(e); + } + + JSONObject jsonObject2 = new JSONObject(); + ActivitiesWS activityObj = + dbServiceSubscriber.getActivityObj( + responseInfoActiveTaskModel.getActivityId(), studyId, realm); + if (activityObj.getType().equalsIgnoreCase("task")) { + JSONObject jsonObject3 = new JSONObject(); + jsonObject3.put("value", value); + jsonObject3.put("duration", duration); + + jsonObject2.put("answer", jsonObject3); + } else { + jsonObject2.put("answer", value); + } + + stepRecordCustom.setResult(String.valueOf(jsonObject2)); + Number currentIdNum = dbServiceSubscriber.getStepRecordCustomId(realm); + if (currentIdNum == null) { + stepRecordCustom.setId(1); + } else { + stepRecordCustom.setId(currentIdNum.intValue() + 1); + } + dbServiceSubscriber.updateStepRecord(context, stepRecordCustom); + } } } - JSONObject jsonObject2 = new JSONObject(); - ActivitiesWS activityObj = - dbServiceSubscriber.getActivityObj( - responseInfoActiveTaskModel.getActivityId(), studyId, realm); - if (activityObj.getType().equalsIgnoreCase("task")) { - JSONObject jsonObject3 = new JSONObject(); - jsonObject3.put("value", value); - jsonObject3.put("duration", duration); - - jsonObject2.put("answer", jsonObject3); - } else { - jsonObject2.put("answer", value); - } - - stepRecordCustom.setResult(String.valueOf(jsonObject2)); - Number currentIdNum = dbServiceSubscriber.getStepRecordCustomId(realm); - if (currentIdNum == null) { - stepRecordCustom.setId(1); - } else { - stepRecordCustom.setId(currentIdNum.intValue() + 1); - } - dbServiceSubscriber.updateStepRecord(context, stepRecordCustom); } } } diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/SurveyResourcesFragment.java b/Android/app/src/main/java/com/harvard/studyappmodule/SurveyResourcesFragment.java index b86b7bf346..fecde97eb1 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/SurveyResourcesFragment.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/SurveyResourcesFragment.java @@ -21,15 +21,15 @@ import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v7.widget.AppCompatImageView; -import android.support.v7.widget.AppCompatTextView; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import android.widget.Toast; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; @@ -53,6 +53,7 @@ import com.harvard.usermodule.webservicemodel.LoginData; import com.harvard.usermodule.webservicemodel.Studies; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; @@ -96,6 +97,7 @@ public class SurveyResourcesFragment extends Fragment implements ApiCall.OnAs private static String RESOURCES = "resources"; private Realm realm; private ArrayList arrayList; + private CustomFirebaseAnalytics analyticsInstance; @Override public void onAttach(Context context) { @@ -108,6 +110,7 @@ public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_survey_resources, container, false); + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); dbServiceSubscriber = new DbServiceSubscriber(); realm = AppController.getRealmobj(context); initializeXmlId(view); @@ -175,6 +178,12 @@ private void initializeXmlId(View view) { @Override public void onClick(View view) { if (AppConfig.AppType.equalsIgnoreCase(getString(R.string.app_gateway))) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.survey_resource_home)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent intent = new Intent(context, StudyActivity.class); ComponentName cn = intent.getComponent(); Intent mainIntent = Intent.makeRestartActivityTask(cn); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/activitybuilder/CustomSurveyViewTaskActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/activitybuilder/CustomSurveyViewTaskActivity.java index af3f386059..e831811986 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/activitybuilder/CustomSurveyViewTaskActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/activitybuilder/CustomSurveyViewTaskActivity.java @@ -24,11 +24,11 @@ import android.content.Intent; import android.graphics.Color; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import android.text.SpannableString; import android.text.style.ForegroundColorSpan; import android.view.Menu; @@ -54,6 +54,7 @@ import com.harvard.studyappmodule.studymodel.StudyHome; import com.harvard.utils.ActiveTaskService; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import io.realm.Realm; import io.realm.RealmList; @@ -90,6 +91,7 @@ public class CustomSurveyViewTaskActivity extends AppCompatActivity implement private static final String RUN_START_DATE = "ViewTaskActivity.RunStartDate"; private static final String RUN_END_DATE = "ViewTaskActivity.RunEndDate"; private static final String BRANCHING = "ViewTaskActivity.branching"; + private CustomFirebaseAnalytics analyticsInstance; private StepSwitcherCustom root; @@ -144,6 +146,7 @@ public static Intent newIntent( @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); super.setResult(RESULT_CANCELED); super.setContentView(R.layout.stepswitchercustom); Toolbar toolbar = (Toolbar) findViewById(org.researchstack.backbone.R.id.toolbar); @@ -224,6 +227,11 @@ protected Step getCurrentStep() { } protected void showNextStep() { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_survey_task_next)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); savestepresult(currentStep, true); Step nextStep = task.getStepAfterStep(currentStep, taskResult); if (nextStep == null) { @@ -428,6 +436,11 @@ private void setRemainder( } protected void showPreviousStep() { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_survey_task_back)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Step previousStep = task.getStepBeforeStep(currentStep, taskResult); if (previousStep == null) { finish(); @@ -520,6 +533,11 @@ public boolean onOptionsItemSelected(MenuItem item) { return true; } else if (item.getItemId() == R.id.action_settings) { showConfirmExitDialog(); + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_survey_task_exit)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); return true; } @@ -633,10 +651,28 @@ private void showConfirmExitDialog() { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_survey_task_end_task)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }) - .setNegativeButton(R.string.cancel, null) + .setNegativeButton( + R.string.cancel, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_survey_task_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + } + }) .create(); alertDialog.show(); } diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/consent/ConsentDocumentStepLayoutCustom.java b/Android/app/src/main/java/com/harvard/studyappmodule/consent/ConsentDocumentStepLayoutCustom.java index 04e591c294..0fec1e1331 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/consent/ConsentDocumentStepLayoutCustom.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/consent/ConsentDocumentStepLayoutCustom.java @@ -11,6 +11,7 @@ import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; +import android.os.Bundle; import android.util.AttributeSet; import android.util.Base64; import android.view.LayoutInflater; @@ -18,6 +19,7 @@ import android.webkit.WebView; import android.widget.LinearLayout; import com.harvard.R; +import com.harvard.utils.CustomFirebaseAnalytics; import org.researchstack.backbone.result.StepResult; import org.researchstack.backbone.step.ConsentDocumentStep; import org.researchstack.backbone.step.Step; @@ -34,6 +36,7 @@ public class ConsentDocumentStepLayoutCustom extends LinearLayout implements Ste private ConsentDocumentStep step; private StepResult stepResult; + private CustomFirebaseAnalytics analyticsInstance; public ConsentDocumentStepLayoutCustom(Context context) { super(context); @@ -51,6 +54,7 @@ public ConsentDocumentStepLayoutCustom(Context context, AttributeSet attrs, int public void initialize(Step step, StepResult result) { this.step = (ConsentDocumentStep) step; this.confirmationDialogBody = ((ConsentDocumentStep) step).getConfirmMessage(); + this.analyticsInstance = CustomFirebaseAnalytics.getInstance(getContext()); this.htmlContent = ((ConsentDocumentStep) step).getConsentHTML(); this.stepResult = result; @@ -86,41 +90,70 @@ private void initializeStep() { String htmlBase64 = Base64.encodeToString(htmlContent.getBytes(), Base64.NO_WRAP); pdfView.loadData(htmlBase64, "text/html", "base64"); - SubmitBar submitBar = (SubmitBar) findViewById(R.id.submit_bar); - submitBar.setPositiveAction(new Action1() { - @Override - public void call(Object v) { - ConsentDocumentStepLayoutCustom.this.showDialog(); - } - }); - submitBar.setNegativeAction(new Action1() { - @Override - public void call(Object v) { - callbacks.onCancelStep(); - } - }); + final SubmitBar submitBar = (SubmitBar) findViewById(R.id.submit_bar); + submitBar.setPositiveAction( + new Action1() { + @Override + public void call(Object v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getContext().getString(R.string.consent_review_agree_text)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + submitBar.getPositiveActionView().setEnabled(false); + ConsentDocumentStepLayoutCustom.this.showDialog(submitBar); + } + }); + submitBar.setNegativeAction( + new Action1() { + @Override + public void call(Object v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getContext().getString(R.string.consent_review_disagree_text)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + callbacks.onCancelStep(); + } + }); } - private void showDialog() { + private void showDialog(final SubmitBar submitBar) { new AlertDialog.Builder(getContext()) - .setTitle(R.string.rsb_consent_review_alert_title) - .setMessage(confirmationDialogBody) - .setCancelable(false) - .setPositiveButton( - R.string.rsb_agree, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - stepResult.setResult(true); - callbacks.onSaveStep(StepCallbacks.ACTION_NEXT, step, stepResult); - } - }) - .setNegativeButton( - R.string.rsb_consent_review_cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - // Gives them a chance to read it again - } - }) - .show(); + .setTitle(R.string.rsb_consent_review_alert_title) + .setMessage(confirmationDialogBody) + .setCancelable(false) + .setPositiveButton( + R.string.rsb_agree, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getContext().getString(R.string.consent_agree_agree)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + stepResult.setResult(true); + callbacks.onSaveStep(StepCallbacks.ACTION_NEXT, step, stepResult); + } + }) + .setNegativeButton( + R.string.rsb_consent_review_cancel, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Gives them a chance to read it again + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getContext().getString(R.string.consent_agree_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + } + }) + .show(); } } \ No newline at end of file diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/consent/CustomConsentViewTaskActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/consent/CustomConsentViewTaskActivity.java index b32830fde6..49edcb7676 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/consent/CustomConsentViewTaskActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/consent/CustomConsentViewTaskActivity.java @@ -18,24 +18,12 @@ import android.annotation.SuppressLint; import android.app.Activity; -import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.graphics.Color; -import android.os.AsyncTask; import android.os.Bundle; -import android.os.Environment; import android.os.Handler; -import android.print.PdfConverter; -import android.support.annotation.MainThread; -import android.support.annotation.NonNull; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; import android.text.Html; import android.text.SpannableString; import android.text.style.ForegroundColorSpan; @@ -44,6 +32,11 @@ import android.view.MenuItem; import android.view.inputmethod.InputMethodManager; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import com.google.gson.Gson; import com.harvard.R; import com.harvard.eligibilitymodule.ComprehensionFailureActivity; @@ -69,6 +62,7 @@ import com.harvard.usermodule.webservicemodel.Studies; import com.harvard.usermodule.webservicemodel.StudyData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; @@ -76,25 +70,13 @@ import com.harvard.webservicemodule.events.ParticipantConsentDatastoreConfigEvent; import com.harvard.webservicemodule.events.ParticipantEnrollmentDatastoreConfigEvent; import com.harvard.webservicemodule.events.StudyDatastoreConfigEvent; -import com.tom_roush.pdfbox.pdmodel.PDDocument; -import com.tom_roush.pdfbox.pdmodel.PDPage; -import com.tom_roush.pdfbox.pdmodel.PDPageContentStream; -import com.tom_roush.pdfbox.pdmodel.graphics.image.LosslessFactory; -import com.tom_roush.pdfbox.pdmodel.graphics.image.PDImageXObject; import io.github.lucasfsc.html2pdf.Html2Pdf; import io.realm.Realm; import io.realm.RealmList; -import java.io.BufferedInputStream; import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; import java.lang.reflect.Constructor; -import java.net.HttpURLConnection; -import java.net.URL; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -123,6 +105,7 @@ public class CustomConsentViewTaskActivity extends AppCompatActivity private static final String PDFTITLE = "ViewTaskActivity.pdfTitle"; private static final String ELIGIBILITY = "ViewTaskActivity.eligibility"; public static final String TYPE = "ViewTaskActivity.type"; + private CustomFirebaseAnalytics analyticsInstance; private StepSwitcherCustom root; private static final String FILE_FOLDER = "FDA_PDF"; @@ -184,6 +167,7 @@ protected void onCreate(Bundle savedInstanceState) { super.setResult(RESULT_CANCELED); super.setContentView(R.layout.stepswitchercustom); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); Toolbar toolbar = (Toolbar) findViewById(org.researchstack.backbone.R.id.toolbar); setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); @@ -264,6 +248,11 @@ protected void showNextStep() { if (nextStep == null) { saveAndFinish(); } else { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_consent_view_next)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); String checkIdentifier; if (consent.getSharing().getTitle().equalsIgnoreCase("") && consent.getSharing().getText().equalsIgnoreCase("") @@ -389,6 +378,11 @@ public boolean onCreateOptionsMenu(Menu menu) { } protected void showPreviousStep() { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_consent_view_back)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); previousStep = task.getStepBeforeStep(currentStep, taskResult); if (previousStep == null) { finish(); @@ -998,6 +992,11 @@ public boolean onOptionsItemSelected(MenuItem item) { notifyStepOfBackPress(); return true; } else if (item.getItemId() == R.id.action_settings) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_consent_view_exit)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); return true; } @@ -1074,10 +1073,28 @@ private void showConfirmExitDialog() { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_consent_view_end_task)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); CustomConsentViewTaskActivity.this.finish(); } }) - .setNegativeButton(getResources().getString(R.string.cancel), null) + .setNegativeButton( + getResources().getString(R.string.cancel), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_consent_view_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + } + }) .create(); alertDialog.show(); } @@ -1093,6 +1110,12 @@ public void onCancelStep() { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_consent_view_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); setResult(12345); finish(); } @@ -1102,6 +1125,12 @@ public void onClick(DialogInterface dialog, int which) { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.custom_consent_view_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); } }) diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/consent/consentsharingstepcustom/LoadMoreActivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/consent/consentsharingstepcustom/LoadMoreActivity.java index 3f3f4078b2..04bf50b7f3 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/consent/consentsharingstepcustom/LoadMoreActivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/consent/consentsharingstepcustom/LoadMoreActivity.java @@ -18,18 +18,22 @@ import android.os.Build; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.text.Html; import android.view.View; import android.webkit.WebView; import android.widget.ImageView; import com.harvard.R; +import com.harvard.utils.CustomFirebaseAnalytics; public class LoadMoreActivity extends AppCompatActivity { + private CustomFirebaseAnalytics analyticsInstance; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); setContentView(R.layout.activity_load_more); WebView textView = (WebView) findViewById(R.id.content); @@ -45,6 +49,12 @@ protected void onCreate(Bundle savedInstanceState) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.load_more_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/consent/consentsharingstepcustom/SingleChoiceSharingStepBody.java b/Android/app/src/main/java/com/harvard/studyappmodule/consent/consentsharingstepcustom/SingleChoiceSharingStepBody.java index b64a77780c..aa471002fa 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/consent/consentsharingstepcustom/SingleChoiceSharingStepBody.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/consent/consentsharingstepcustom/SingleChoiceSharingStepBody.java @@ -17,8 +17,9 @@ import android.content.Intent; import android.content.res.Resources; -import android.support.annotation.IdRes; -import android.support.v4.content.ContextCompat; +import android.os.Bundle; +import androidx.annotation.IdRes; +import androidx.core.content.ContextCompat; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -28,6 +29,7 @@ import android.widget.RadioGroup; import android.widget.TextView; import com.harvard.R; +import com.harvard.utils.CustomFirebaseAnalytics; import org.researchstack.backbone.answerformat.ChoiceAnswerFormat; import org.researchstack.backbone.model.Choice; import org.researchstack.backbone.result.StepResult; @@ -41,6 +43,7 @@ public class SingleChoiceSharingStepBody implements StepBody { private ChoiceAnswerFormat format; private Choice[] choices; private T currentSelected; + private CustomFirebaseAnalytics analyticsInstance; public SingleChoiceSharingStepBody(Step step, StepResult result) { this.step = (ConsentSharingStepCustom) step; @@ -69,6 +72,7 @@ public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent) ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); layoutParams.leftMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_left); layoutParams.rightMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_right); + analyticsInstance = CustomFirebaseAnalytics.getInstance(inflater.getContext()); view.setLayoutParams(layoutParams); return view; @@ -104,6 +108,12 @@ private View initViewDefault(final LayoutInflater inflater, ViewGroup parent) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + inflater.getContext().getString(R.string.single_choice_load_more)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); Intent intent = new Intent(inflater.getContext(), LoadMoreActivity.class); intent.putExtra("htmlcontent", "" + step.getLoadmoretxt()); inflater.getContext().startActivity(intent); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/custom/SurveyStepLayoutCustom.java b/Android/app/src/main/java/com/harvard/studyappmodule/custom/SurveyStepLayoutCustom.java index 0f43e45d14..8e9556fef7 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/custom/SurveyStepLayoutCustom.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/custom/SurveyStepLayoutCustom.java @@ -10,9 +10,10 @@ import android.content.Context; import android.content.Intent; +import android.os.Bundle; import android.os.Parcelable; -import android.support.annotation.NonNull; -import android.support.annotation.StringRes; +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; import android.text.Html; import android.util.AttributeSet; import android.view.LayoutInflater; @@ -20,6 +21,10 @@ import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; + +import com.harvard.R; +import com.harvard.utils.CustomFirebaseAnalytics; + import java.lang.reflect.Constructor; import org.researchstack.backbone.ResourcePathManager; import org.researchstack.backbone.result.StepResult; @@ -41,6 +46,7 @@ public class SurveyStepLayoutCustom extends FixedSubmitBarLayoutCustom implement private StepCallbacks callbacks; private LinearLayout container; private StepBody stepBody; + private CustomFirebaseAnalytics analyticsInstance; public SurveyStepLayoutCustom(Context context) { super(context); @@ -72,6 +78,7 @@ public void initialize(Step step, StepResult result) { this.questionStep = (QuestionStep) step; this.stepResult = result; + analyticsInstance = CustomFirebaseAnalytics.getInstance(getContext()); initializeStep(); } @@ -203,6 +210,11 @@ protected void onNextClicked() { } public void onSkipClicked() { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getContext().getString(R.string.rsb_step_skip)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (callbacks != null) { callbacks.onSaveStep(StepCallbacks.ACTION_NEXT, getStep(), stepBody.getStepResult(true)); } diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/custom/activetask/Tappingactivity.java b/Android/app/src/main/java/com/harvard/studyappmodule/custom/activetask/Tappingactivity.java index aa5b638028..1c478c7812 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/custom/activetask/Tappingactivity.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/custom/activetask/Tappingactivity.java @@ -21,7 +21,8 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; -import android.support.v7.app.AlertDialog; +import android.os.Bundle; +import androidx.appcompat.app.AlertDialog; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; @@ -37,6 +38,7 @@ import com.harvard.studyappmodule.activitybuilder.CustomSurveyViewTaskActivity; import com.harvard.studyappmodule.custom.QuestionStepCustom; import com.harvard.utils.ActiveTaskService; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.ikovac.timepickerwithseconds.MyTimePickerDialog; import com.ikovac.timepickerwithseconds.TimePicker; @@ -61,6 +63,7 @@ public class Tappingactivity implements StepBody { private int maxTime; private RelativeLayout timereditlayout; private int finalSecond; + private CustomFirebaseAnalytics analyticsInstance; public Tappingactivity(Step step, StepResult result) { this.step = (QuestionStepCustom) step; @@ -73,6 +76,7 @@ public View getBodyView(int viewType, final LayoutInflater inflater, ViewGroup p View view = inflater.inflate(R.layout.content_fetal_kick_counter, null); context = inflater.getContext(); tapButton = (ImageView) view.findViewById(R.id.tapbutton); + analyticsInstance = CustomFirebaseAnalytics.getInstance(inflater.getContext()); editButton = (ImageView) view.findViewById(R.id.editButton); final ImageView startTimer = (ImageView) view.findViewById(R.id.startTimer); timer = (TextView) view.findViewById(R.id.mTimer); @@ -114,7 +118,12 @@ public void afterTextChanged(Editable s) { new View.OnClickListener() { @Override public void onClick(View v) { - + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.start_timer)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); activateservice(maxTime); IntentFilter filter = new IntentFilter(); filter.addAction("com.harvard.ActiveTask"); @@ -136,6 +145,12 @@ public void onClick(View v) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.tap_time)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); final String[] duration = timer.getText().toString().split(":"); if (timeup) { new MyTimePickerDialog( @@ -189,6 +204,12 @@ public void onTimeSet(TimePicker view, int hourOfDay, int minute, int seconds) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.tap_btn)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); kickcounter.setFocusable(false); kickcounter.setFocusableInTouchMode(false); kickcounter.setFocusable(true); @@ -396,6 +417,12 @@ private void endAlert(String message) { context.getString(R.string.proceed), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.tap_proceed)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); ((CustomSurveyViewTaskActivity) context) .onSaveStep(StepCallbacks.ACTION_NEXT, step, getStepResult(false)); } @@ -404,6 +431,12 @@ public void onClick(DialogInterface dialog, int which) { context.getString(R.string.edit), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.tap_edit)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); } }); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ContinuousScaleQuestion.java b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ContinuousScaleQuestion.java index 806b2a5cfb..ac8a6b8976 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ContinuousScaleQuestion.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ContinuousScaleQuestion.java @@ -17,6 +17,7 @@ import android.content.res.Resources; import android.util.Base64; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -29,6 +30,10 @@ import com.harvard.studyappmodule.custom.QuestionStepCustom; import com.harvard.utils.Logger; import com.harvard.utils.VerticalSeekBar; +import com.jaygoo.widget.OnRangeChangedListener; +import com.jaygoo.widget.RangeSeekBar; +import com.jaygoo.widget.VerticalRangeSeekBar; + import java.text.NumberFormat; import org.researchstack.backbone.result.StepResult; import org.researchstack.backbone.step.Step; @@ -41,7 +46,7 @@ public class ContinuousScaleQuestion implements StepBody { private ContinousScaleAnswerFormat format; private TextView currentvalue; private Double currentSelected; - private SeekBar seekBar; + private RangeSeekBar seekBar; private int stepSection; private int min; private double value; @@ -99,15 +104,15 @@ private View initViewDefault(LayoutInflater inflater, ViewGroup parent) { if (!format.isVertical()) { seekbarlayout = inflater.inflate(R.layout.seekbar_horizontal_layout, parent, false); - seekBar = (SeekBar) seekbarlayout.findViewById(R.id.seekbar); + seekBar = (RangeSeekBar) seekbarlayout.findViewById(R.id.seekbar); } else { seekbarlayout = inflater.inflate(R.layout.seekbar_vertical_layout, parent, false); - seekBar = (VerticalSeekBar) seekbarlayout.findViewById(R.id.seekbar); + seekBar = (VerticalRangeSeekBar) seekbarlayout.findViewById(R.id.seekbar); } if (stepSection != 0) { - seekBar.setMax((max - min) * (stepSection * 10)); + seekBar.setRange(0, (max - min) * (stepSection * 10)); } else { - seekBar.setMax((max - min)); + seekBar.setRange(0, (max - min)); } TextView mindesc = (TextView) seekbarlayout.findViewById(R.id.mindesc); @@ -129,29 +134,33 @@ private View initViewDefault(LayoutInflater inflater, ViewGroup parent) { byte[] imageByteArray = Base64.decode(format.getMinImage().split(",")[1], Base64.DEFAULT); Glide.with(inflater.getContext()).load(imageByteArray).into(minimage); } else { - minimage.setVisibility(View.INVISIBLE); + minimage.setVisibility(View.GONE); } if (!format.getMaxImage().equalsIgnoreCase("")) { byte[] imageByteArray = Base64.decode(format.getMaxImage().split(",")[1], Base64.DEFAULT); Glide.with(inflater.getContext()).load(imageByteArray).into(maximage); } else { - maximage.setVisibility(View.INVISIBLE); + maximage.setVisibility(View.GONE); } currentvalue.setText(String.valueOf(min)); - seekBar.setOnSeekBarChangeListener( - new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int i, boolean b) { - setvaluetotext(); - } - @Override - public void onStartTrackingTouch(SeekBar seekBar) {} + seekBar.setOnRangeChangedListener(new OnRangeChangedListener() { + @Override + public void onRangeChanged(RangeSeekBar rangeSeekBar, float v, float v1, boolean b) { + setvaluetotext(); + } + + @Override + public void onStartTrackingTouch(RangeSeekBar rangeSeekBar, boolean b) { - @Override - public void onStopTrackingTouch(SeekBar seekBar) {} - }); + } + + @Override + public void onStopTrackingTouch(RangeSeekBar rangeSeekBar, boolean b) { + + } + }); if (currentSelected != null) { double selected; @@ -196,10 +205,10 @@ private void setvaluetotext() { if (stepSection != 0) { value = Double.parseDouble("" + min) - + Double.parseDouble("" + seekBar.getProgress()) - / Double.parseDouble("" + (stepSection * 10)); + + Double.parseDouble("" + (int) seekBar.getLeftSeekBar().getProgress()) + / Double.parseDouble("" + (stepSection * 10)); } else { - value = Double.parseDouble("" + min) + Double.parseDouble("" + seekBar.getProgress()); + value = Double.parseDouble("" + min) + Double.parseDouble("" + (int) seekBar.getLeftSeekBar().getProgress()); } NumberFormat nf = NumberFormat.getInstance(); nf.setMaximumFractionDigits(stepSection); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/CustomDateQuestionBody.java b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/CustomDateQuestionBody.java index 14e3a9dd8d..c0f63ff6dd 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/CustomDateQuestionBody.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/CustomDateQuestionBody.java @@ -18,9 +18,11 @@ import android.app.DatePickerDialog; import android.app.TimePickerDialog; +import android.content.Context; import android.content.DialogInterface; import android.content.res.Resources; -import android.support.v7.view.ContextThemeWrapper; +import android.os.Bundle; +import androidx.appcompat.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -33,6 +35,7 @@ import com.harvard.studyappmodule.custom.AnswerFormatCustom; import com.harvard.studyappmodule.custom.QuestionStepCustom; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import java.text.DateFormat; import java.text.ParseException; @@ -49,6 +52,8 @@ public class CustomDateQuestionBody implements StepBody { private DateAnswerformatCustom format; private Calendar calendar; private DateFormat dateformatter; + private CustomFirebaseAnalytics analyticsInstance; + Context context; private boolean hasChosenDate; @@ -91,6 +96,8 @@ public View getBodyView(int viewType, final LayoutInflater inflater, ViewGroup p View view = inflater.inflate(R.layout.rsb_item_date_view, parent, false); TextView title = (TextView) view.findViewById(R.id.label); + analyticsInstance = CustomFirebaseAnalytics.getInstance(inflater.getContext()); + this.context = inflater.getContext(); if (viewType == VIEW_TYPE_COMPACT) { title.setText(step.getTitle()); } else { @@ -124,14 +131,21 @@ public void onFocusChange(View v, boolean hasFocus) { } }); - textView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (v.isFocused()) { - CustomDateQuestionBody.this.showDialog(textView, inflater); - } - } - }); + textView.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.text_view)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + if (v.isFocused()) { + CustomDateQuestionBody.this.showDialog(textView, inflater); + } + } + }); Resources res = parent.getResources(); LinearLayout.MarginLayoutParams layoutParams = @@ -169,7 +183,13 @@ public StepResult getStepResult(boolean skipped) { @Override public BodyAnswer getBodyAnswerState() { if (!hasChosenDate) { - return new BodyAnswer(false, R.string.rsb_invalid_answer_date_none); + if (format.getStyle() == AnswerFormatCustom.DateAnswerStyle.Date) { + return new BodyAnswer(false, R.string.rsb_invalid_answer_date_none); + } else if (format.getStyle() == AnswerFormatCustom.DateAnswerStyle.TimeOfDay) { + return new BodyAnswer(false, R.string.rsb_invalid_answer_time_none); + } else { + return new BodyAnswer(false, R.string.rsb_invalid_answer_date_time_none); + } } return format.validateAnswer(calendar.getTime()); @@ -188,20 +208,38 @@ public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH)); - datePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE, inflater.getContext().getString(R.string.cancel), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_NEGATIVE) { - dialog.dismiss(); - } - } - }); - datePickerDialog.setButton(DialogInterface.BUTTON_POSITIVE, inflater.getContext().getString(R.string.ok_2), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_POSITIVE) { - dialog.dismiss(); - Calendar calendar1 = Calendar.getInstance(); - calendar1.setTime(calendar.getTime()); - calendar1.set( + datePickerDialog.setButton( + DialogInterface.BUTTON_NEGATIVE, + inflater.getContext().getString(R.string.cancel), + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_data_question_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + if (which == DialogInterface.BUTTON_NEGATIVE) { + dialog.dismiss(); + } + } + }); + datePickerDialog.setButton( + DialogInterface.BUTTON_POSITIVE, + inflater.getContext().getString(R.string.ok_2), + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_data_question_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + if (which == DialogInterface.BUTTON_POSITIVE) { + dialog.dismiss(); + Calendar calendar1 = Calendar.getInstance(); + calendar1.setTime(calendar.getTime()); + calendar1.set( datePickerDialog.getDatePicker().getYear(), datePickerDialog.getDatePicker().getMonth(), datePickerDialog.getDatePicker().getDayOfMonth()); @@ -268,22 +306,40 @@ public void onTimeSet(TimePicker view, int hourOfDay, int minute) { calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), true); - timePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE, inflater.getContext().getString(R.string.cancel), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_NEGATIVE) { - dialog.dismiss(); - } - } - }); - timePickerDialog.setButton(DialogInterface.BUTTON_NEUTRAL, inflater.getContext().getString(R.string.clear), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_NEUTRAL) { - dialog.dismiss(); - tv.setText(""); - hasChosenDate = false; - } - } - }); + timePickerDialog.setButton( + DialogInterface.BUTTON_NEGATIVE, + inflater.getContext().getString(R.string.cancel), + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_data_question_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + if (which == DialogInterface.BUTTON_NEGATIVE) { + dialog.dismiss(); + } + } + }); + timePickerDialog.setButton( + DialogInterface.BUTTON_NEUTRAL, + inflater.getContext().getString(R.string.clear), + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_data_question_clear)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + if (which == DialogInterface.BUTTON_NEUTRAL) { + dialog.dismiss(); + tv.setText(""); + hasChosenDate = false; + } + } + }); timePickerDialog.show(); @@ -297,83 +353,130 @@ public void onDateSet( calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH)); - datePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE, inflater.getContext().getString(R.string.cancel), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_NEGATIVE) { - dialog.dismiss(); - } - } - }); - datePickerDialog.setButton(DialogInterface.BUTTON_NEUTRAL, inflater.getContext().getString(R.string.clear), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_NEUTRAL) { - dialog.dismiss(); - tv.setText(""); - hasChosenDate = false; - } - } - }); - datePickerDialog.setButton(DialogInterface.BUTTON_POSITIVE, inflater.getContext().getString(R.string.ok_2), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_POSITIVE) { - dialog.dismiss(); - calendar.set( + datePickerDialog.setButton( + DialogInterface.BUTTON_NEGATIVE, + inflater.getContext().getString(R.string.cancel), + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_data_question_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + if (which == DialogInterface.BUTTON_NEGATIVE) { + dialog.dismiss(); + } + } + }); + datePickerDialog.setButton( + DialogInterface.BUTTON_NEUTRAL, + inflater.getContext().getString(R.string.clear), + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_data_question_clear)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + if (which == DialogInterface.BUTTON_NEUTRAL) { + dialog.dismiss(); + tv.setText(""); + hasChosenDate = false; + } + } + }); + datePickerDialog.setButton( + DialogInterface.BUTTON_POSITIVE, + inflater.getContext().getString(R.string.ok_2), + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_data_question_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + if (which == DialogInterface.BUTTON_POSITIVE) { + dialog.dismiss(); + calendar.set( datePickerDialog.getDatePicker().getYear(), datePickerDialog.getDatePicker().getMonth(), datePickerDialog.getDatePicker().getDayOfMonth()); - TimePickerDialog timePickerDialog = - new TimePickerDialog(contextWrapper, new TimePickerDialog.OnTimeSetListener() { - @Override - public void onTimeSet(TimePicker tview, int hourOfDay, int minute) { + TimePickerDialog timePickerDialog = + new TimePickerDialog( + contextWrapper, + new TimePickerDialog.OnTimeSetListener() { + @Override + public void onTimeSet(TimePicker tview, int hourOfDay, int minute) { - Calendar calendar1 = Calendar.getInstance(); - calendar1.setTime(calendar.getTime()); - calendar1.set(Calendar.HOUR_OF_DAY, hourOfDay); - calendar1.set(Calendar.MINUTE, minute); - if (format.validateAnswer(calendar1.getTime()).isValid()) { - calendar.set(Calendar.HOUR_OF_DAY, hourOfDay); - calendar.set(Calendar.MINUTE, minute); + Calendar calendar1 = Calendar.getInstance(); + calendar1.setTime(calendar.getTime()); + calendar1.set(Calendar.HOUR_OF_DAY, hourOfDay); + calendar1.set(Calendar.MINUTE, minute); + if (format.validateAnswer(calendar1.getTime()).isValid()) { + calendar.set(Calendar.HOUR_OF_DAY, hourOfDay); + calendar.set(Calendar.MINUTE, minute); - hasChosenDate = true; - // Set result to our edit text - String formattedResult = + hasChosenDate = true; + // Set result to our edit text + String formattedResult = CustomDateQuestionBody.this.createFormattedResult(); - tv.setText(formattedResult); - } else { - Toast.makeText( - inflater.getContext(), - format + tv.setText(formattedResult); + } else { + Toast.makeText( + inflater.getContext(), + format .validateAnswer(calendar1.getTime()) .getString(inflater.getContext()), - Toast.LENGTH_LONG) + Toast.LENGTH_LONG) .show(); + } + } + }, + calendar.get(Calendar.HOUR_OF_DAY), + calendar.get(Calendar.MINUTE), + true); + timePickerDialog.setButton( + DialogInterface.BUTTON_NEGATIVE, + inflater.getContext().getString(R.string.cancel), + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_data_question_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + if (which == DialogInterface.BUTTON_NEGATIVE) { + dialog.dismiss(); } } - }, - calendar.get(Calendar.HOUR_OF_DAY), - calendar.get(Calendar.MINUTE), - true); - timePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE, inflater.getContext().getString(R.string.cancel), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_NEGATIVE) { - dialog.dismiss(); - } - } - }); - timePickerDialog.setButton(DialogInterface.BUTTON_NEUTRAL, inflater.getContext().getString(R.string.clear), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_NEUTRAL) { - dialog.dismiss(); - tv.setText(""); - hasChosenDate = false; - } + }); + timePickerDialog.setButton( + DialogInterface.BUTTON_NEUTRAL, + inflater.getContext().getString(R.string.clear), + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_data_question_clear)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + if (which == DialogInterface.BUTTON_NEUTRAL) { + dialog.dismiss(); + tv.setText(""); + hasChosenDate = false; + } + } + }); + timePickerDialog.show(); } - }); - timePickerDialog.show(); - } - } - }); + } + }); datePickerDialog.show(); } else { throw new RuntimeException("DateAnswerStyle " + format.getStyle() + " is not recognised"); diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/FormBodyCustom.java b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/FormBodyCustom.java index c169416db1..4d4f669c08 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/FormBodyCustom.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/FormBodyCustom.java @@ -15,10 +15,12 @@ package com.harvard.studyappmodule.custom.question; +import android.content.Context; import android.content.res.Resources; import android.graphics.Paint; +import android.os.Bundle; import android.os.Handler; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.Gravity; @@ -32,6 +34,7 @@ import com.harvard.studyappmodule.custom.ChoiceAnswerFormatCustom; import com.harvard.studyappmodule.custom.QuestionStepCustom; import com.harvard.studyappmodule.custom.StepResultCustom; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import java.lang.reflect.Constructor; import java.util.ArrayList; @@ -55,6 +58,8 @@ public class FormBodyCustom implements StepBody { private int formIncrement = 0; private int actionBarHeight = 0; private int navigationBarHeight = 0; + private CustomFirebaseAnalytics analyticsInstance; + private Context context; public FormBodyCustom(Step step, StepResult result) { this.step = (QuestionStep) step; @@ -133,6 +138,8 @@ public View getBodyView(int viewType, final LayoutInflater inflater, final ViewG DisplayMetrics displayMetrics = inflater.getContext().getResources().getDisplayMetrics(); final int height = displayMetrics.heightPixels; final LinearLayout body = (LinearLayout) inflater.inflate(R.layout.formbody, parent, false); + this.context = inflater.getContext(); + this.analyticsInstance = CustomFirebaseAnalytics.getInstance(context.getApplicationContext()); final ObservableScrollView observableScrollView = (ObservableScrollView) parent.findViewById(R.id.rsb_content_container_scrollview); @@ -185,6 +192,12 @@ public View getBodyView(int viewType, final LayoutInflater inflater, final ViewG new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.add_more)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); View firstview = null; body.removeView(addmore); StepBody stepBody; diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/InstructionStepLayoutCustom.java b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/InstructionStepLayoutCustom.java index 38b8ff8f9d..ea19c5e6c1 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/InstructionStepLayoutCustom.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/InstructionStepLayoutCustom.java @@ -12,7 +12,7 @@ import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Build; -import android.support.customtabs.CustomTabsIntent; +import androidx.browser.customtabs.CustomTabsIntent; import android.text.Html; import android.util.AttributeSet; import android.view.View; diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/LocationQuestion.java b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/LocationQuestion.java index 770e5429c0..c50d4ef812 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/LocationQuestion.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/LocationQuestion.java @@ -26,10 +26,6 @@ import android.location.LocationManager; import android.os.Bundle; import android.os.Handler; -import android.support.v4.app.ActivityCompat; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentTransaction; -import android.support.v7.app.AppCompatActivity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; @@ -40,6 +36,10 @@ import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.location.LocationListener; @@ -191,10 +191,6 @@ public void onMapReady(final GoogleMap googleMap) { .addOnConnectionFailedListener(LocationQuestion.this) .build(); - LocationManager service = - (LocationManager) - context.getSystemService(Context.LOCATION_SERVICE); - service.addGpsStatusListener(LocationQuestion.this); try { googleApiClient.connect(); } catch (Exception e) { diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/MultiChoiceImageQuestionBody.java b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/MultiChoiceImageQuestionBody.java index 7eaaee9011..fc52136b51 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/MultiChoiceImageQuestionBody.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/MultiChoiceImageQuestionBody.java @@ -15,7 +15,9 @@ package com.harvard.studyappmodule.custom.question; +import android.content.Context; import android.content.res.Resources; +import android.os.Bundle; import android.util.Base64; import android.view.LayoutInflater; import android.view.View; @@ -26,6 +28,7 @@ import com.bumptech.glide.Glide; import com.harvard.R; import com.harvard.studyappmodule.custom.QuestionStepCustom; +import com.harvard.utils.CustomFirebaseAnalytics; import org.researchstack.backbone.result.StepResult; import org.researchstack.backbone.step.Step; import org.researchstack.backbone.ui.step.body.BodyAnswer; @@ -36,6 +39,8 @@ public class MultiChoiceImageQuestionBody implements StepBody { private StepResult result; private ChoiceCustomImage[] choices; private T currentSelected; + private CustomFirebaseAnalytics analyticsInstance; + private Context context; public MultiChoiceImageQuestionBody(Step step, StepResult result) { this.step = (QuestionStepCustom) step; @@ -59,6 +64,7 @@ public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent) View view = getViewForType(viewType, inflater, parent); Resources res = parent.getResources(); + this.context = inflater.getContext(); LinearLayout.MarginLayoutParams layoutParams = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); @@ -67,7 +73,7 @@ public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent) layoutParams.rightMargin = res.getDimensionPixelSize(org.researchstack.backbone.R.dimen.rsb_margin_right); view.setLayoutParams(layoutParams); - + this.analyticsInstance = CustomFirebaseAnalytics.getInstance(context.getApplicationContext()); return view; } @@ -116,13 +122,22 @@ private View initViewDefault(final LayoutInflater inflater, ViewGroup parent) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.image_view)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (pervioustxtview[0] != null) { byte[] imageByteArray = - Base64.decode(choices[pervioustxtview[0].getId()].getImage().split(",")[1], Base64.DEFAULT); + Base64.decode( + choices[pervioustxtview[0].getId()].getImage().split(",")[1], + Base64.DEFAULT); Glide.with(inflater.getContext()).load(imageByteArray).into(pervioustxtview[0]); } byte[] imageByteArray = - Base64.decode(choices[imageView.getId()].getSelectedImage().split(",")[1], Base64.DEFAULT); + Base64.decode( + choices[imageView.getId()].getSelectedImage().split(",")[1], Base64.DEFAULT); Glide.with(inflater.getContext()).load(imageByteArray).into(imageView); imageView.setLayoutParams(layoutParams); pervioustxtview[0] = imageView; diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/MultiChoiceTextQuestionBody.java b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/MultiChoiceTextQuestionBody.java index c8e8bbf4aa..01bb03b28c 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/MultiChoiceTextQuestionBody.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/MultiChoiceTextQuestionBody.java @@ -17,9 +17,6 @@ import android.app.Activity; import android.content.res.Resources; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.AppCompatCheckBox; -import android.support.v7.widget.SearchView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -29,6 +26,9 @@ import android.widget.LinearLayout; import android.widget.RadioGroup; import android.widget.TextView; +import androidx.appcompat.widget.AppCompatCheckBox; +import androidx.appcompat.widget.SearchView; +import androidx.core.content.ContextCompat; import com.google.gson.Gson; import com.harvard.R; import com.harvard.studyappmodule.custom.QuestionStepCustom; diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ScaleQuestion.java b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ScaleQuestion.java index b29ade6db7..20a02d4494 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ScaleQuestion.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ScaleQuestion.java @@ -17,6 +17,7 @@ import android.content.res.Resources; import android.util.Base64; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -28,6 +29,10 @@ import com.harvard.R; import com.harvard.studyappmodule.custom.QuestionStepCustom; import com.harvard.utils.Logger; +import com.jaygoo.widget.OnRangeChangedListener; +import com.jaygoo.widget.RangeSeekBar; +import com.jaygoo.widget.VerticalRangeSeekBar; + import org.researchstack.backbone.result.StepResult; import org.researchstack.backbone.step.Step; import org.researchstack.backbone.ui.step.body.BodyAnswer; @@ -39,7 +44,7 @@ public class ScaleQuestion implements StepBody { private ScaleAnswerFormat format; private TextView mcurrentvalue; private Double currentSelected; - private SeekBar seekBar; + private RangeSeekBar seekBar; private int min; private int stepSection; private double value; @@ -96,14 +101,13 @@ private View initViewDefault(LayoutInflater inflater, ViewGroup parent) { View seekbarlayout; if (!format.isVertical()) { seekbarlayout = inflater.inflate(R.layout.seekbar_horizontal_layout, parent, false); - seekBar = (SeekBar) seekbarlayout.findViewById(R.id.seekbar); - seekBar.setMax((max - min) / stepSection); + seekBar = (RangeSeekBar) seekbarlayout.findViewById(R.id.seekbar); } else { seekbarlayout = inflater.inflate(R.layout.seekbar_vertical_layout, parent, false); - seekBar = (SeekBar) seekbarlayout.findViewById(R.id.seekbar); - seekBar.setMax((max - min) / stepSection); + seekBar = (VerticalRangeSeekBar) seekbarlayout.findViewById(R.id.seekbar); } - + seekBar.setSteps(max / stepSection); + seekBar.setRange(0, ((max - min) / stepSection)); TextView mindesc = (TextView) seekbarlayout.findViewById(R.id.mindesc); ImageView minimage = (ImageView) seekbarlayout.findViewById(R.id.minimage); @@ -121,13 +125,13 @@ private View initViewDefault(LayoutInflater inflater, ViewGroup parent) { byte[] imageByteArray = Base64.decode(format.getMinImage().split(",")[1], Base64.DEFAULT); Glide.with(inflater.getContext()).load(imageByteArray).into(minimage); } else { - minimage.setVisibility(View.INVISIBLE); + minimage.setVisibility(View.GONE); } if (!format.getMaxImage().equalsIgnoreCase("")) { byte[] imageByteArray = Base64.decode(format.getMaxImage().split(",")[1], Base64.DEFAULT); Glide.with(inflater.getContext()).load(imageByteArray).into(maximage); } else { - maximage.setVisibility(View.INVISIBLE); + maximage.setVisibility(View.GONE); } TextView mintitle = (TextView) seekbarlayout.findViewById(R.id.mintitle); TextView maxtitle = (TextView) seekbarlayout.findViewById(R.id.maxtitle); @@ -136,19 +140,22 @@ private View initViewDefault(LayoutInflater inflater, ViewGroup parent) { mcurrentvalue.setText(String.valueOf(min)); - seekBar.setOnSeekBarChangeListener( - new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int i, boolean b) { - setvaluetotxt(); - } + seekBar.setOnRangeChangedListener(new OnRangeChangedListener() { + @Override + public void onRangeChanged(RangeSeekBar rangeSeekBar, float v, float v1, boolean b) { + setvaluetotxt(); + } - @Override - public void onStartTrackingTouch(SeekBar seekBar) {} + @Override + public void onStartTrackingTouch(RangeSeekBar rangeSeekBar, boolean b) { - @Override - public void onStopTrackingTouch(SeekBar seekBar) {} - }); + } + + @Override + public void onStopTrackingTouch(RangeSeekBar rangeSeekBar, boolean b) { + + } + }); if (currentSelected != null) { int selected = ((currentSelected.intValue() - min) / stepSection); @@ -178,8 +185,8 @@ public void onStopTrackingTouch(SeekBar seekBar) {} } private void setvaluetotxt() { - value = min + (seekBar.getProgress() * stepSection); - mcurrentvalue.setText(String.valueOf(value)); + value = min + (((int) seekBar.getLeftSeekBar().getProgress()) * stepSection); + mcurrentvalue.setText(String.valueOf((int) value)); } private View initViewCompact(LayoutInflater inflater, ViewGroup parent) { diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ScaleTextQuestion.java b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ScaleTextQuestion.java index f495c6c22a..fb5a7d7767 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ScaleTextQuestion.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ScaleTextQuestion.java @@ -16,16 +16,20 @@ package com.harvard.studyappmodule.custom.question; import android.content.res.Resources; -import android.view.Gravity; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; -import android.widget.SeekBar; import android.widget.TextView; import com.harvard.R; import com.harvard.studyappmodule.custom.QuestionStepCustom; import com.harvard.utils.Logger; +import com.jaygoo.widget.OnRangeChangedListener; +import com.jaygoo.widget.RangeSeekBar; +import com.jaygoo.widget.SeekBar; +import com.jaygoo.widget.VerticalRangeSeekBar; + import java.util.ArrayList; import org.researchstack.backbone.result.StepResult; import org.researchstack.backbone.step.Step; @@ -38,10 +42,11 @@ public class ScaleTextQuestion implements StepBody { private ScaleTextAnswerFormat format; private TextView mcurrentvalue; private String currentSelected; - private SeekBar seekBar; + private RangeSeekBar seekBar; private int value; private ChoiceTextExclusive[] choiceTextExclusives; private ArrayList valuelist; + private ArrayList textlist; public ScaleTextQuestion(Step step, StepResult result) { this.step = (QuestionStepCustom) step; @@ -49,8 +54,10 @@ public ScaleTextQuestion(Step step, StepResult result) { this.format = (ScaleTextAnswerFormat) this.step.getAnswerFormat1(); choiceTextExclusives = format.getChoiceTextExclusive(); valuelist = new ArrayList<>(); + textlist = new ArrayList<>(); for (ChoiceTextExclusive choiceTextExclusive : choiceTextExclusives) { valuelist.add("" + choiceTextExclusive.getValue()); + textlist.add(choiceTextExclusive.getText()); } String resultValue = this.result.getResult(); if (resultValue != null) { @@ -95,49 +102,19 @@ private View initViewDefault(LayoutInflater inflater, ViewGroup parent) { final int max = choiceTextExclusives.length; int min = 1; + CharSequence[] tickValues = textlist.toArray(new CharSequence[textlist.size()]); + View seekbarlayout; if (!format.isVertical()) { seekbarlayout = inflater.inflate(R.layout.seekbar_horizontal_layout, parent, false); - seekBar = (SeekBar) seekbarlayout.findViewById(R.id.seekbar); - seekBar.setMax((max - min)); + seekBar = (RangeSeekBar) seekbarlayout.findViewById(R.id.seekbar); } else { seekbarlayout = inflater.inflate(R.layout.seekbar_text_vertical_layout, parent, false); - seekBar = (SeekBar) seekbarlayout.findViewById(R.id.seekbar); - LinearLayout scalevsaluelayout = (LinearLayout) seekbarlayout.findViewById(R.id.scaleValue); - scalevsaluelayout.setWeightSum(choiceTextExclusives.length); - - for (int i = choiceTextExclusives.length - 1; i >= 0; i--) { - LinearLayout linearLayout1 = new LinearLayout(inflater.getContext()); - LinearLayout.LayoutParams params = - new LinearLayout.LayoutParams( - LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1); - params.gravity = Gravity.CENTER; - - TextView textView = new TextView(inflater.getContext()); - LinearLayout.LayoutParams txtparams = - new LinearLayout.LayoutParams( - LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); - if (i == choiceTextExclusives.length - 1) { - txtparams.gravity = Gravity.TOP; - textView.setGravity(Gravity.TOP); - } else if (i == 0) { - txtparams.gravity = Gravity.BOTTOM; - textView.setGravity(Gravity.BOTTOM); - } else { - txtparams.gravity = Gravity.CENTER; - textView.setGravity(Gravity.CENTER); - params.setMargins(0, 30, 0, 30); - } - textView.setLayoutParams(txtparams); - textView.setText(choiceTextExclusives[i].getText()); - linearLayout1.setLayoutParams(params); - linearLayout1.addView(textView); - - scalevsaluelayout.addView(linearLayout1); - } - - seekBar.setMax((max - min)); + seekBar = (VerticalRangeSeekBar) seekbarlayout.findViewById(R.id.seekbar); + seekBar.setTickMarkTextArray(tickValues); } + seekBar.setRange(0, choiceTextExclusives.length - 1); + seekBar.setSteps(choiceTextExclusives.length - 1); mcurrentvalue = (TextView) seekbarlayout.findViewById(R.id.currentvalue); TextView mintitle = (TextView) seekbarlayout.findViewById(R.id.mintitle); @@ -152,25 +129,28 @@ private View initViewDefault(LayoutInflater inflater, ViewGroup parent) { mcurrentvalue.setText(String.valueOf(choiceTextExclusives[0].getText())); - seekBar.setOnSeekBarChangeListener( - new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int i, boolean b) { - setvaluetotxt(); - } + seekBar.setOnRangeChangedListener(new OnRangeChangedListener() { + @Override + public void onRangeChanged(RangeSeekBar rangeSeekBar, float v, float v1, boolean b) { + setvaluetotxt(v); + } + + @Override + public void onStartTrackingTouch(RangeSeekBar rangeSeekBar, boolean b) { + + } - @Override - public void onStartTrackingTouch(SeekBar seekBar) {} + @Override + public void onStopTrackingTouch(RangeSeekBar rangeSeekBar, boolean b) { - @Override - public void onStopTrackingTouch(SeekBar seekBar) {} - }); + } + }); + int defaultval; if (currentSelected != null) { - int selected = valuelist.indexOf("" + currentSelected); - seekBar.setProgress(selected); + defaultval = valuelist.indexOf("" + currentSelected); + seekBar.setProgress(defaultval); } else { - int defaultval; if (format.getDefaultval() != null && !format.getDefaultval().equalsIgnoreCase("")) { try { defaultval = Integer.parseInt(format.getDefaultval()); @@ -184,17 +164,14 @@ public void onStopTrackingTouch(SeekBar seekBar) {} seekBar.setProgress(((defaultval - min))); } - if (format.isVertical()) { - setvaluetotxt(); - } linearLayout.removeAllViewsInLayout(); linearLayout.addView(seekbarlayout); return linearLayout; } - private void setvaluetotxt() { - value = (seekBar.getProgress()); + private void setvaluetotxt(float rangeSeekBar) { + value = (int) (rangeSeekBar); mcurrentvalue.setText(String.valueOf(choiceTextExclusives[value].getText())); } diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/SingleChoiceTextQuestionBody.java b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/SingleChoiceTextQuestionBody.java index 596b913b5d..cedd5df64e 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/SingleChoiceTextQuestionBody.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/SingleChoiceTextQuestionBody.java @@ -17,9 +17,6 @@ import android.app.Activity; import android.content.res.Resources; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.AppCompatCheckBox; -import android.support.v7.widget.SearchView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -29,6 +26,9 @@ import android.widget.LinearLayout; import android.widget.RadioGroup; import android.widget.TextView; +import androidx.appcompat.widget.AppCompatCheckBox; +import androidx.appcompat.widget.SearchView; +import androidx.core.content.ContextCompat; import com.google.gson.Gson; import com.harvard.R; import com.harvard.studyappmodule.custom.QuestionStepCustom; diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/TimeIntervalAnswerFormat.java b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/TimeIntervalAnswerFormat.java index 9e18359971..c2bfd4c6f1 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/TimeIntervalAnswerFormat.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/TimeIntervalAnswerFormat.java @@ -22,6 +22,7 @@ public class TimeIntervalAnswerFormat extends ChoiceAnswerFormatCustom { private final int step; private final String defaultvalue; + public TimeIntervalAnswerFormat( CustomAnswerStyle style, int step, String defaultvalue) { this.style = style; diff --git a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ValuePickerQuestion.java b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ValuePickerQuestion.java index b88e10340c..bd1ba6c76b 100644 --- a/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ValuePickerQuestion.java +++ b/Android/app/src/main/java/com/harvard/studyappmodule/custom/question/ValuePickerQuestion.java @@ -18,6 +18,7 @@ import android.app.Dialog; import android.content.Context; import android.content.res.Resources; +import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -29,6 +30,7 @@ import com.harvard.R; import com.harvard.studyappmodule.custom.ChoiceAnswerFormatCustom; import com.harvard.studyappmodule.custom.QuestionStepCustom; +import com.harvard.utils.CustomFirebaseAnalytics; import org.researchstack.backbone.answerformat.ChoiceAnswerFormat; import org.researchstack.backbone.model.Choice; import org.researchstack.backbone.result.StepResult; @@ -43,6 +45,7 @@ public class ValuePickerQuestion implements StepBody { private String currentSelected; private TextView textView; private String resultValue; + private CustomFirebaseAnalytics analyticsInstance; public ValuePickerQuestion(Step step, StepResult result) { if (step instanceof QuestionStepCustom) { @@ -65,7 +68,6 @@ public ValuePickerQuestion(Step step, StepResult result) { @Override public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent) { View view = getViewForType(viewType, inflater, parent); - Resources res = parent.getResources(); LinearLayout.MarginLayoutParams layoutParams = new LinearLayout.LayoutParams( @@ -75,7 +77,7 @@ public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent) layoutParams.rightMargin = res.getDimensionPixelSize(org.researchstack.backbone.R.dimen.rsb_margin_right); view.setLayoutParams(layoutParams); - + analyticsInstance = CustomFirebaseAnalytics.getInstance(inflater.getContext().getApplicationContext()); return view; } @@ -104,6 +106,12 @@ private View initViewDefault(final LayoutInflater inflater, ViewGroup parent) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + inflater.getContext().getString(R.string.text_view)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); showDialog(inflater.getContext()); } }); @@ -111,7 +119,7 @@ public void onClick(View v) { return body; } - private void showDialog(Context context) { + private void showDialog(final Context context) { final Dialog dialog = new Dialog(context); dialog.setCancelable(false); @@ -122,7 +130,12 @@ private void showDialog(Context context) { new View.OnClickListener() { @Override public void onClick(View v) { - + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.valuer_picker_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); } }); @@ -141,6 +154,12 @@ public void onClick(View v) { new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView> parent, View view, int position, long id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.valuer_picker_list)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); textView.setText(numberpickervalue[position]); resultValue = choices[position].getValue().toString(); diff --git a/Android/app/src/main/java/com/harvard/usermodule/AuthServerErrorHandler.java b/Android/app/src/main/java/com/harvard/usermodule/AuthServerErrorHandler.java index d07710015e..edbf49aa4c 100644 --- a/Android/app/src/main/java/com/harvard/usermodule/AuthServerErrorHandler.java +++ b/Android/app/src/main/java/com/harvard/usermodule/AuthServerErrorHandler.java @@ -11,8 +11,8 @@ import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v7.app.AppCompatActivity; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; import android.widget.Toast; import com.harvard.AppConfig; import com.harvard.R; diff --git a/Android/app/src/main/java/com/harvard/usermodule/ConfirmPasscodeSetup.java b/Android/app/src/main/java/com/harvard/usermodule/ConfirmPasscodeSetup.java index 0e582d8184..ec0d4dce80 100644 --- a/Android/app/src/main/java/com/harvard/usermodule/ConfirmPasscodeSetup.java +++ b/Android/app/src/main/java/com/harvard/usermodule/ConfirmPasscodeSetup.java @@ -18,8 +18,8 @@ import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatTextView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; import android.view.View; import android.widget.RelativeLayout; import android.widget.TextView; @@ -27,6 +27,7 @@ import com.harvard.R; import com.harvard.passcodemodule.PasscodeView; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; public class ConfirmPasscodeSetup extends AppCompatActivity { @@ -37,11 +38,13 @@ public class ConfirmPasscodeSetup extends AppCompatActivity { private PasscodeView passcodeView; private static final int JOIN_STUDY_RESPONSE = 100; private TextView passcodetitle; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_passcode_setup); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); setTextForView(); @@ -90,6 +93,12 @@ public void run() { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.confirm_passcode_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }); diff --git a/Android/app/src/main/java/com/harvard/usermodule/ForgotPasswordActivity.java b/Android/app/src/main/java/com/harvard/usermodule/ForgotPasswordActivity.java index 1530cbc0e8..da83a64a7d 100644 --- a/Android/app/src/main/java/com/harvard/usermodule/ForgotPasswordActivity.java +++ b/Android/app/src/main/java/com/harvard/usermodule/ForgotPasswordActivity.java @@ -17,9 +17,9 @@ import android.content.Intent; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatEditText; -import android.support.v7.widget.AppCompatTextView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatEditText; +import androidx.appcompat.widget.AppCompatTextView; import android.view.View; import android.widget.RelativeLayout; import android.widget.Toast; @@ -31,6 +31,7 @@ import com.harvard.usermodule.model.Apps; import com.harvard.usermodule.webservicemodel.ForgotPasswordData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.Urls; import com.harvard.webservicemodule.apihelper.ApiCall; @@ -51,11 +52,13 @@ public class ForgotPasswordActivity extends AppCompatActivity private static final int RESEND_CONFIRMATION = 101; public static String FROM = "ForgotPasswordActivity"; private static final int GO_TO_SIGNIN = 111; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_forgot_password); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); setTextForView(); setFont(); @@ -92,6 +95,12 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.forgot_password_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); try { AppController.getHelperHideKeyboard(ForgotPasswordActivity.this); } catch (Exception e) { @@ -105,6 +114,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.forgot_password_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); try { AppController.getHelperHideKeyboard(ForgotPasswordActivity.this); } catch (Exception e) { @@ -118,6 +133,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.forgot_password_submit)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (email.getText().toString().equalsIgnoreCase("")) { Toast.makeText( ForgotPasswordActivity.this, diff --git a/Android/app/src/main/java/com/harvard/usermodule/LoginCallbackActivity.java b/Android/app/src/main/java/com/harvard/usermodule/LoginCallbackActivity.java index 9239883e2a..da3867bfec 100644 --- a/Android/app/src/main/java/com/harvard/usermodule/LoginCallbackActivity.java +++ b/Android/app/src/main/java/com/harvard/usermodule/LoginCallbackActivity.java @@ -13,8 +13,8 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v7.app.AppCompatActivity; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; import android.widget.Toast; import com.google.firebase.iid.FirebaseInstanceId; import com.harvard.AppConfig; diff --git a/Android/app/src/main/java/com/harvard/usermodule/NewPasscodeSetupActivity.java b/Android/app/src/main/java/com/harvard/usermodule/NewPasscodeSetupActivity.java index c26ea27d47..0aa1afcf84 100644 --- a/Android/app/src/main/java/com/harvard/usermodule/NewPasscodeSetupActivity.java +++ b/Android/app/src/main/java/com/harvard/usermodule/NewPasscodeSetupActivity.java @@ -17,8 +17,8 @@ import android.content.Intent; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatTextView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; import android.view.View; import android.widget.RelativeLayout; import android.widget.TextView; diff --git a/Android/app/src/main/java/com/harvard/usermodule/SignupActivity.java b/Android/app/src/main/java/com/harvard/usermodule/SignupActivity.java index e6c0ecbfd8..8e062b8f92 100644 --- a/Android/app/src/main/java/com/harvard/usermodule/SignupActivity.java +++ b/Android/app/src/main/java/com/harvard/usermodule/SignupActivity.java @@ -21,11 +21,6 @@ import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; -import android.support.v4.content.ContextCompat; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatCheckBox; -import android.support.v7.widget.AppCompatEditText; -import android.support.v7.widget.AppCompatTextView; import android.text.SpannableStringBuilder; import android.text.TextPaint; import android.text.method.LinkMovementMethod; @@ -36,6 +31,11 @@ import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatCheckBox; +import androidx.appcompat.widget.AppCompatEditText; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.core.content.ContextCompat; import com.google.firebase.iid.FirebaseInstanceId; import com.harvard.AppConfig; import com.harvard.BuildConfig; @@ -49,6 +49,7 @@ import com.harvard.usermodule.webservicemodel.RegistrationData; import com.harvard.usermodule.webservicemodel.UpdateUserProfileData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SetDialogHelper; import com.harvard.utils.Urls; @@ -88,6 +89,7 @@ public class SignupActivity extends AppCompatActivity implements ApiCall.OnAsync private RegistrationData registrationData; private String userAuth; private String userID; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { @@ -105,6 +107,7 @@ protected void onCreate(Bundle savedInstanceState) { termsAndConditionData.setPrivacy(dbServiceSubscriber.getApps(realm).getPrivacyPolicyUrl()); termsAndConditionData.setTerms(dbServiceSubscriber.getApps(realm).getTermsUrl()); dbServiceSubscriber.closeRealmObj(realm); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); } private void initializeXmlId() { @@ -156,6 +159,12 @@ public void updateDrawState(TextPaint ds) { @Override public void onClick(View widget) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.signup_terms)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (termsAndConditionData != null && !termsAndConditionData.getTerms().isEmpty()) { Intent termsIntent = new Intent(SignupActivity.this, TermsPrivacyPolicyActivity.class); @@ -190,6 +199,12 @@ public void updateDrawState(TextPaint ds) { @Override public void onClick(View widget) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.signup_privacy_policy)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (termsAndConditionData != null && !termsAndConditionData.getPrivacy().isEmpty()) { Intent termsIntent = new Intent(SignupActivity.this, TermsPrivacyPolicyActivity.class); @@ -236,6 +251,11 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, getString(R.string.signup_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); try { AppController.getHelperHideKeyboard(SignupActivity.this); } catch (Exception e) { @@ -249,6 +269,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.signup_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }); @@ -257,6 +283,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.signup_submit)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (clicked == false) { clicked = true; password.clearFocus(); @@ -278,6 +310,11 @@ public void run() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, getString(R.string.signup_info)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); SetDialogHelper.setNeutralDialog( SignupActivity.this, getResources().getString(R.string.registration_message), diff --git a/Android/app/src/main/java/com/harvard/usermodule/SignupProcessCompleteActivity.java b/Android/app/src/main/java/com/harvard/usermodule/SignupProcessCompleteActivity.java index b158d30ef1..086c04aa4c 100644 --- a/Android/app/src/main/java/com/harvard/usermodule/SignupProcessCompleteActivity.java +++ b/Android/app/src/main/java/com/harvard/usermodule/SignupProcessCompleteActivity.java @@ -18,25 +18,28 @@ import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatTextView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; import android.view.View; import com.harvard.AppConfig; import com.harvard.R; import com.harvard.studyappmodule.StandaloneActivity; import com.harvard.studyappmodule.StudyActivity; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; public class SignupProcessCompleteActivity extends AppCompatActivity { private AppCompatTextView congratsLabel; private AppCompatTextView nextButton; private AppCompatTextView signupCompleteLabel; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_signup_process_complete); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); setFont(); @@ -68,6 +71,12 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.signup_process_complete_done)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (getIntent().getStringExtra("from") != null && getIntent().getStringExtra("from").equalsIgnoreCase("StudyInfo")) { Intent intent = new Intent(); diff --git a/Android/app/src/main/java/com/harvard/usermodule/TermsPrivacyPolicyActivity.java b/Android/app/src/main/java/com/harvard/usermodule/TermsPrivacyPolicyActivity.java index c697072c3f..22ac3ee80b 100644 --- a/Android/app/src/main/java/com/harvard/usermodule/TermsPrivacyPolicyActivity.java +++ b/Android/app/src/main/java/com/harvard/usermodule/TermsPrivacyPolicyActivity.java @@ -16,9 +16,9 @@ package com.harvard.usermodule; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatTextView; -import android.util.Log; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; + import android.view.View; import android.webkit.WebView; import android.webkit.WebViewClient; @@ -26,6 +26,7 @@ import com.harvard.R; import com.harvard.storagemodule.DbServiceSubscriber; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import io.realm.Realm; @@ -33,11 +34,14 @@ public class TermsPrivacyPolicyActivity extends AppCompatActivity { private RelativeLayout backBtn; private AppCompatTextView title; private WebView webView; + private CustomFirebaseAnalytics analyticsInstance; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_terms_privacy_policy); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); initializeXmlId(); setTextForView(); setFont(); @@ -106,6 +110,12 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.terms_privacy_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); finish(); } }); diff --git a/Android/app/src/main/java/com/harvard/usermodule/VerificationStepActivity.java b/Android/app/src/main/java/com/harvard/usermodule/VerificationStepActivity.java index 930198e576..29e4b6bfbc 100644 --- a/Android/app/src/main/java/com/harvard/usermodule/VerificationStepActivity.java +++ b/Android/app/src/main/java/com/harvard/usermodule/VerificationStepActivity.java @@ -21,13 +21,13 @@ import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; -import android.support.customtabs.CustomTabsIntent; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.AppCompatEditText; -import android.support.v7.widget.AppCompatTextView; import android.view.View; import android.widget.RelativeLayout; import android.widget.Toast; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatEditText; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.browser.customtabs.CustomTabsIntent; import com.harvard.R; import com.harvard.gatewaymodule.GatewayActivity; import com.harvard.storagemodule.DbServiceSubscriber; @@ -36,6 +36,7 @@ import com.harvard.usermodule.model.Apps; import com.harvard.usermodule.webservicemodel.LoginData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; @@ -67,11 +68,13 @@ public class VerificationStepActivity extends AppCompatActivity private String emailId; private String type; private LoginData loginData; + private CustomFirebaseAnalytics analyticsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_verification_step); + analyticsInstance = CustomFirebaseAnalytics.getInstance(this); userId = getIntent().getStringExtra("userid"); auth = getIntent().getStringExtra("auth"); emailId = getIntent().getStringExtra("email"); @@ -145,9 +148,13 @@ private void bindEvents() { new View.OnClickListener() { @Override public void onClick(View view) { - SharedPreferences settings = - SharedPreferenceHelper.getPreferences(VerificationStepActivity.this); - settings.edit().clear().apply(); + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.verification_step_back)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + SharedPreferenceHelper.deletePreferences(VerificationStepActivity.this); // delete passcode from keystore String pass = AppController.refreshKeys("passcode"); if (pass != null) { @@ -161,9 +168,13 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { - SharedPreferences settings = - SharedPreferenceHelper.getPreferences(VerificationStepActivity.this); - settings.edit().clear().apply(); + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.verification_step_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + SharedPreferenceHelper.deletePreferences(VerificationStepActivity.this); // delete passcode from keystore String pass = AppController.refreshKeys("passcode"); if (pass != null) { @@ -177,7 +188,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { - + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.verification_step_submit)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); VerifyUserEvent verifyUserEvent = new VerifyUserEvent(); HashMap params = new HashMap<>(); HashMap header = new HashMap(); @@ -216,6 +232,12 @@ public void onClick(View view) { new View.OnClickListener() { @Override public void onClick(View view) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + getString(R.string.verification_step_resend)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); AppController.getHelperProgressDialog() .showProgress(VerificationStepActivity.this, "", "", false); ResendEmailEvent resendEmailEvent = new ResendEmailEvent(); @@ -305,9 +327,7 @@ public void asyncResponseFailure(int responseCode, String errormsg, String statu if (statusCode.equalsIgnoreCase("401")) { Toast.makeText(this, errormsg, Toast.LENGTH_SHORT).show(); if (from != null && from.equalsIgnoreCase("Activity")) { - SharedPreferences settings = - SharedPreferenceHelper.getPreferences(VerificationStepActivity.this); - settings.edit().clear().apply(); + SharedPreferenceHelper.deletePreferences(this); // delete passcode from keystore String pass = AppController.refreshKeys("passcode"); if (pass != null) { @@ -330,9 +350,7 @@ public void asyncResponseFailure(int responseCode, String errormsg, String statu @Override public void onBackPressed() { super.onBackPressed(); - SharedPreferences settings = - SharedPreferenceHelper.getPreferences(VerificationStepActivity.this); - settings.edit().clear().apply(); + SharedPreferenceHelper.deletePreferences(this); // delete passcode from keystore String pass = AppController.refreshKeys("passcode"); if (pass != null) { diff --git a/Android/app/src/main/java/com/harvard/utils/ActiveTaskService.java b/Android/app/src/main/java/com/harvard/utils/ActiveTaskService.java index 80226106b3..225ffb45a3 100644 --- a/Android/app/src/main/java/com/harvard/utils/ActiveTaskService.java +++ b/Android/app/src/main/java/com/harvard/utils/ActiveTaskService.java @@ -22,13 +22,14 @@ import android.app.Service; import android.content.Context; import android.content.Intent; +import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Build; import android.os.IBinder; import android.os.PowerManager; -import android.support.annotation.Nullable; -import android.support.v4.app.NotificationCompat; +import androidx.annotation.Nullable; +import androidx.core.app.NotificationCompat; import com.harvard.FdaApplication; import com.harvard.R; import com.harvard.offlinemodule.model.OfflineData; @@ -70,21 +71,25 @@ public int onStartCommand(final Intent intent, int flags, int startId) { && intent.getStringExtra("broadcast").equalsIgnoreCase("yes")) { startAlarm(); } else if (intent.getStringExtra("SyncAdapter") != null) { - realm = AppController.getRealmobj(this); - Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); - Notification notification = - new NotificationCompat.Builder(this) - .setContentTitle(getResources().getString(R.string.app_name)) - .setTicker("Sync adapter") - .setContentText("Syncing offline data") - .setChannelId(FdaApplication.NOTIFICATION_CHANNEL_ID_SERVICE) - .setSmallIcon(R.mipmap.ic_launcher) - .setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false)) - .setOngoing(true) - .build(); + try { + realm = AppController.getRealmobj(this); + Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); + Notification notification = + new NotificationCompat.Builder(this) + .setContentTitle(getResources().getString(R.string.app_name)) + .setTicker("Sync adapter") + .setContentText("Syncing offline data") + .setChannelId(FdaApplication.NOTIFICATION_CHANNEL_ID_SERVICE) + .setSmallIcon(R.mipmap.ic_launcher) + .setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false)) + .setOngoing(true) + .build(); - startForeground(102, notification); - getPendingData(); + startForeground(102, notification); + getPendingData(); + } catch (Exception e) { + Logger.log(e); + } } else { try { sec = 0; @@ -174,7 +179,13 @@ private void startAlarm() { try { Calendar localCalendar = Calendar.getInstance(); Intent intent1 = new Intent(this, AlarmService.class); - PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, intent1, 0); + PendingIntent alarmIntent; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + alarmIntent = + PendingIntent.getBroadcast(this, 0, intent1, 0 | PendingIntent.FLAG_IMMUTABLE); + } else { + alarmIntent = PendingIntent.getBroadcast(this, 0, intent1, 0); + } AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); // 21600000 alarmManager.setAlarmClock( new AlarmManager.AlarmClockInfo(localCalendar.getTimeInMillis() + 180000, alarmIntent), diff --git a/Android/app/src/main/java/com/harvard/utils/AppController.java b/Android/app/src/main/java/com/harvard/utils/AppController.java index f646551bcb..58aefbdc34 100644 --- a/Android/app/src/main/java/com/harvard/utils/AppController.java +++ b/Android/app/src/main/java/com/harvard/utils/AppController.java @@ -26,16 +26,21 @@ import android.graphics.Typeface; import android.net.Uri; import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.security.KeyPairGeneratorSpec; -import android.support.v4.app.NotificationManagerCompat; -import android.support.v4.content.ContextCompat; -import android.support.v7.app.AlertDialog; import android.util.Base64; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.TextView; +import android.widget.Toast; +import androidx.appcompat.app.AlertDialog; +import androidx.core.app.NotificationManagerCompat; +import androidx.core.content.ContextCompat; import com.harvard.AppConfig; import com.harvard.BuildConfig; import com.harvard.R; @@ -45,7 +50,6 @@ import com.harvard.offlinemodule.model.OfflineData; import com.harvard.storagemodule.DbServiceSubscriber; import com.harvard.studyappmodule.StandaloneActivity; -import com.harvard.studyappmodule.StudyActivity; import com.harvard.studyappmodule.studymodel.Resource; import com.harvard.utils.realm.RealmEncryptionHelper; import com.harvard.utils.realm.RealmMigrationHelper; @@ -59,7 +63,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; -import java.net.URLDecoder; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyPairGenerator; @@ -80,7 +83,6 @@ import java.util.Map; import java.util.Random; import java.util.regex.Pattern; - import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; @@ -102,6 +104,8 @@ public class AppController { private static final String TAG = "FDAKeystore"; private static String keystoreValue = null; public static String loginCallback = "login_callback"; + public static int SchemaVersion = 2; + private static CustomFirebaseAnalytics analyticsInstance; public static final String STARTING_TAGS = "<\\w+((\\s+\\w+(\\s*=\\s*(?:\".*?\"|'.*?'|[^'\">\\s]+))?)+\\s*|\\s*)>"; public static final String ENDDING_TAGS = "\\w+>"; @@ -149,8 +153,7 @@ public static boolean getHelperIsValidEmail(String target) { } public static void getHelperSessionExpired(Context context, String msg) { - SharedPreferences settings = SharedPreferenceHelper.getPreferences(context); - settings.edit().clear().apply(); + SharedPreferenceHelper.deletePreferences(context); // delete passcode from keystore String pass = AppController.refreshKeys("passcode"); if (pass != null) { @@ -254,19 +257,62 @@ public static Typeface getHelveticaTypeface(Context context) { return retTypeface; } - public static Realm getRealmobj(Context context) { - if (config == null) { - RealmEncryptionHelper realmEncryptionHelper = - RealmEncryptionHelper.initHelper(context, context.getString(R.string.app_name)); - byte[] key = realmEncryptionHelper.getEncryptKey(); - config = + public static Realm getRealmobj(final Context context) { + Realm realm; + try { + realm = Realm.getDefaultInstance(); + } catch (Exception e) { + byte[] key = AppController.getkey(context, context.getString(R.string.app_name)); + RealmConfiguration config = + new RealmConfiguration.Builder() + .encryptionKey(key) + .schemaVersion(SchemaVersion) + .migration(new RealmMigrationHelper()) + .build(); + Realm.removeDefaultConfiguration(); + Realm.setDefaultConfiguration(config); + realm = Realm.getDefaultInstance(); + Logger.log(e); + } + return realm; + } + + private static byte[] getkey(Context context, String keyName) { + RealmEncryptionHelper realmEncryptionHelper = RealmEncryptionHelper.initHelper(context, keyName); + byte[] key = realmEncryptionHelper.getEncryptKey(); + String s = bytesToHex(key); + Log.wtf("realm key for " + keyName, "" + s); + return key; + } + + public static void checkIfAppNameChangeAndMigrate(Context context) { + if (!context.getString(R.string.app_name).equalsIgnoreCase(SharedPreferenceHelper.readPreference(context, "appname", context.getString(R.string.app_name)))) { + byte[] key = getkey(context, SharedPreferenceHelper.readPreference(context, "appname", context.getString(R.string.app_name))); + RealmConfiguration config = new RealmConfiguration.Builder() .encryptionKey(key) - .schemaVersion(2) + .schemaVersion(SchemaVersion) .migration(new RealmMigrationHelper()) .build(); + Realm realm = Realm.getInstance(config); + RealmEncryptionHelper.getInstance().deleteEntry(SharedPreferenceHelper.readPreference(context, "appname", context.getString(R.string.app_name))); + byte[] NewKey = getkey(context, context.getString(R.string.app_name)); + realm.writeEncryptedCopyTo(new File(context.getFilesDir(), "temp.realm"), NewKey); + realm.close(); + File file = new File(context.getFilesDir(), "default.realm"); + file.delete(); + renameFile(context, "temp.realm", "default.realm"); } - return Realm.getInstance(config); + byte[] key = AppController.getkey(context, context.getString(R.string.app_name)); + RealmConfiguration config = + new RealmConfiguration.Builder() + .encryptionKey(key) + .schemaVersion(SchemaVersion) + .migration(new RealmMigrationHelper()) + .build(); + Realm.removeDefaultConfiguration(); + Realm.setDefaultConfiguration(config); + SharedPreferenceHelper.writePreference(context, "appname", context.getString(R.string.app_name)); } public static void clearDBfile() { @@ -427,12 +473,26 @@ public static AlertDialog setNeutralDialog( .setPositiveButton( positiveButton, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) {} + public void onClick(DialogInterface dialog, int id) { + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_data_question_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); + } }) .setNegativeButton( context.getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_data_question_cancel)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); if (finish) { ((Activity) context).finish(); @@ -448,6 +508,12 @@ public void onClick(DialogInterface dialog, int id) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_data_question_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); // Do stuff, possibly set wantToCloseDialog to true then... final String appPackageName = context.getPackageName(); try { @@ -483,6 +549,11 @@ public void onClick(View v) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString(CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_data_question_cancel)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, + eventProperties); alertDialog.dismiss(); ((SplashActivity) context).loadsplash(); } @@ -502,6 +573,11 @@ public void onClick(View v) { new View.OnClickListener() { @Override public void onClick(View v) { + Bundle eventProperties = new Bundle(); + eventProperties.putString(CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.upgrade)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, + eventProperties); final String appPackageName = context.getPackageName(); try { ((Activity) context) @@ -881,8 +957,7 @@ public static void pendingService( } public static void forceSignout(Context context) { - SharedPreferences settings = SharedPreferenceHelper.getPreferences(context); - settings.edit().clear().apply(); + SharedPreferenceHelper.deletePreferences(context); // delete passcode from keystore String pass = AppController.refreshKeys("passcode"); if (pass != null) { @@ -926,8 +1001,7 @@ public static void forceSignout(Context context) { } public static void signout(Context context) { - SharedPreferences settings = SharedPreferenceHelper.getPreferences(context); - settings.edit().clear().apply(); + SharedPreferenceHelper.deletePreferences(context); // delete passcode from keystore String pass = AppController.refreshKeys("passcode"); if (pass != null) { @@ -968,6 +1042,34 @@ public static void signout(Context context) { } } + public static void clearAllAppData(Context context) { + SharedPreferenceHelper.deletePreferences(context); + // delete passcode from keystore + String pass = AppController.refreshKeys("passcode"); + if (pass != null) { + AppController.deleteKey("passcode_" + pass); + } + DbServiceSubscriber dbServiceSubscriber = new DbServiceSubscriber(); + Realm realm = getRealmobj(context); + dbServiceSubscriber.deleteDb(context); + try { + NotificationModuleSubscriber notificationModuleSubscriber = + new NotificationModuleSubscriber(dbServiceSubscriber, realm); + notificationModuleSubscriber.cancleActivityLocalNotification(context); + notificationModuleSubscriber.cancleResourcesLocalNotification(context); + } catch (Exception e) { + Logger.log(e); + } + NotificationModuleSubscriber notificationModuleSubscriber = + new NotificationModuleSubscriber(dbServiceSubscriber, realm); + notificationModuleSubscriber.cancelNotificationTurnOffNotification(context); + dbServiceSubscriber.closeRealmObj(realm); + + // clear notifications from notification tray + NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); + notificationManager.cancelAll(); + } + public static String getHashedValue(String valueToHash) { String generatedHash = null; try { @@ -1047,4 +1149,34 @@ public static boolean isMyServiceRunning(Context context, Class> serviceClass) } return false; } + + private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); + + public static String bytesToHex(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = HEX_ARRAY[v >>> 4]; + hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; + } + return new String(hexChars); + } + + + public static void renameFile(Context context, String oldName, String newName) { + File dir = context.getFilesDir(); + if (dir.exists()) { + File from = new File(dir, oldName); + File to = new File(dir, newName); + if (from.exists()) { + from.renameTo(to); + } + } + } + + public static ArrayList getExcludePreferenceList() { + ArrayList excludedList = new ArrayList<>(); + excludedList.add("appname"); + return excludedList; + } } diff --git a/Android/app/src/main/java/com/harvard/utils/CustomFirebaseAnalytics.java b/Android/app/src/main/java/com/harvard/utils/CustomFirebaseAnalytics.java new file mode 100644 index 0000000000..92a7e19f2c --- /dev/null +++ b/Android/app/src/main/java/com/harvard/utils/CustomFirebaseAnalytics.java @@ -0,0 +1,51 @@ +/* + * Copyright 2020 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + */ + +package com.harvard.utils; + +import android.content.Context; +import android.os.Bundle; +import com.google.firebase.analytics.FirebaseAnalytics; + +public class CustomFirebaseAnalytics { + + private static volatile CustomFirebaseAnalytics instance; + private static FirebaseAnalytics firebaseAnalytics; + + public static CustomFirebaseAnalytics getInstance(Context context) { + if (instance == null) { + synchronized (CustomFirebaseAnalytics.class) { + if (instance == null) { + instance = new CustomFirebaseAnalytics(); + } + } + } + firebaseAnalytics = FirebaseAnalytics.getInstance(context); + return instance; + } + + public static class Param { + + public static final String BUTTON_CLICK_REASON = "button_click_reason"; + + protected Param() { + } + } + + public static class Event { + + public static final String ADD_BUTTON_CLICK = "add_button_click"; + + protected Event() { + } + } + + public void logEvent(String eventName, Bundle eventProperties) { + firebaseAnalytics.logEvent(eventName, eventProperties); + } +} diff --git a/Android/app/src/main/java/com/harvard/utils/PdfViewerView.java b/Android/app/src/main/java/com/harvard/utils/PdfViewerView.java new file mode 100644 index 0000000000..e34b72b20f --- /dev/null +++ b/Android/app/src/main/java/com/harvard/utils/PdfViewerView.java @@ -0,0 +1,237 @@ +/* + * Copyright 2020 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + */ + +package com.harvard.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.pdf.PdfRenderer; +import android.os.Build; +import android.os.ParcelFileDescriptor; +import android.util.AttributeSet; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; +import androidx.viewpager.widget.PagerAdapter; +import androidx.viewpager.widget.ViewPager; +import com.github.chrisbanes.photoview.PhotoView; +import com.google.android.material.tabs.TabLayout; +import com.harvard.R; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) +public class PdfViewerView extends ViewPager { + + private PdfRenderer pdfRender; + Context context; + + public PdfViewerView(Context context) { + super(context); + this.context = context; + } + + public PdfViewerView(Context context, AttributeSet attrs) { + super(context, attrs); + this.context = context; + } + + + /** + * Uses the {@link ParcelFileDescriptor} directly, see {@link PdfRenderer(ParcelFileDescriptor)} + * + * @param input {@link ParcelFileDescriptor} + */ + public void setPdf(@NonNull ParcelFileDescriptor input) { + if (pdfRender != null) { + pdfRender.close(); + } + try { + pdfRender = new PdfRenderer(input); + } catch (IOException e) { + throw new RuntimeException(e); + } + PdfAdapter pdfAdapter = new PdfAdapter(context, pdfRender); + TabLayout tabLayout = (TabLayout) this.findViewById(R.id.tab_layout); + tabLayout.setupWithViewPager(this, true); + setAdapter(pdfAdapter); + } + + /** + * Sets the pdf with the file uses {@link #setPdf(ParcelFileDescriptor)} internally + * + * @param file of the pdf to load + */ + public void setPdf(@NonNull File file) { + try { + setPdf(ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * Sets a pdf to view from the assets directory + * + * @param assetFile the path and name of the asset to load + */ + public void setPdfFromAsset(@NonNull String assetFile) { + try { + File file = new File(context.getFilesDir(), assetFile); + if (!file.exists()) { + // copy to the assets dir + InputStream asset = context.getAssets().open(assetFile); + FileOutputStream output = new FileOutputStream(file); + final byte[] buffer = new byte[1024]; + int size; + while ((size = asset.read(buffer)) != -1) { + output.write(buffer, 0, size); + } + asset.close(); + output.close(); + } + setPdf(file); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * Sets a pdf to view from a byte array + * + * @param bytes for the file + * @param name the name of the file to save in the app's cache dir + */ + public void setPdfFromBytes(@NonNull byte[] bytes, @NonNull String name) { + File file = new File("/data/data/" + context.getPackageName() + "/files/", name); + try { + if (name.equalsIgnoreCase("temp.pdf") && file.exists()) { + file.delete(); + } + if (!file.exists()) { + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)); + bos.write(bytes); + bos.flush(); + bos.close(); + } + setPdf(file); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * @return The current page count + */ + public int getPageCount() { + return pdfRender == null ? 0 : pdfRender.getPageCount(); + } + + /** + * @return The current page via {@link #getCurrentItem()} + */ + public int getCurrentPage() { + return getCurrentItem(); + } + + private static class PdfAdapter extends PagerAdapter { + + @NonNull + private final PdfRenderer renderer; + private final int count; + private PdfRenderer.Page currentPage; + @NonNull + private final Context context; + + private PdfAdapter(@NonNull Context context, @NonNull PdfRenderer renderer) { + this.context = context; + this.count = renderer.getPageCount(); + this.renderer = renderer; + } + + @Override + public int getCount() { + return count; + } + + @Override + public Object instantiateItem(ViewGroup container, int position) { + if (currentPage != null) { + try { + currentPage.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + currentPage = renderer.openPage(position); + + final Bitmap bitmap = Bitmap.createBitmap(currentPage.getWidth(), currentPage.getHeight(), + Bitmap.Config.ARGB_8888); + Runnable runnable = new Runnable() { + public void run() { + currentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY); + } + }; + runnable.run(); + + PhotoView photoView = new PhotoView(context); + + photoView.setImageBitmap(bitmap); + + container.addView(photoView); + + return photoView; + } + + @Override + public void destroyItem(ViewGroup container, int position, Object object) { + try { + if (currentPage != null) { + try { + currentPage.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } catch (Exception e) { + // no op, need to make sure it is closed + } + + container.removeView((View) object); + } + + @Override + public boolean isViewFromObject(View view, Object object) { + return view == object; + } + } + @Override + public boolean onTouchEvent(MotionEvent ev) { + try { + return super.onTouchEvent(ev); + } catch (IllegalArgumentException ex) { + ex.printStackTrace(); + } + return false; + } + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + try { + return super.onInterceptTouchEvent(ev); + } catch (IllegalArgumentException ex) { + ex.printStackTrace(); + } + return false; + } +} diff --git a/Android/app/src/main/java/com/harvard/utils/ProgressDialogHelper.java b/Android/app/src/main/java/com/harvard/utils/ProgressDialogHelper.java index 9e3946ed41..a90d16cfe0 100644 --- a/Android/app/src/main/java/com/harvard/utils/ProgressDialogHelper.java +++ b/Android/app/src/main/java/com/harvard/utils/ProgressDialogHelper.java @@ -146,6 +146,12 @@ public void dismissDialog() { } } + public void updateMsg(String msg){ + if (ringProgressDialog != null && ringProgressDialog.isShowing()) { + ringProgressDialog.setMessage(msg); + } + } + private static Drawable getdrawable(Context context, int id) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { return context.getResources().getDrawable(id, context.getTheme()); diff --git a/Android/app/src/main/java/com/harvard/utils/SetDialogHelper.java b/Android/app/src/main/java/com/harvard/utils/SetDialogHelper.java index 6b81740874..06efe52c53 100644 --- a/Android/app/src/main/java/com/harvard/utils/SetDialogHelper.java +++ b/Android/app/src/main/java/com/harvard/utils/SetDialogHelper.java @@ -18,7 +18,8 @@ import android.app.Activity; import android.content.Context; import android.content.DialogInterface; -import android.support.v7.app.AlertDialog; +import android.os.Bundle; +import androidx.appcompat.app.AlertDialog; import com.harvard.R; public class SetDialogHelper { @@ -31,6 +32,8 @@ public class SetDialogHelper { * @param finish whether to finish the activity * @param positiveButton Name of pos button */ + private static CustomFirebaseAnalytics analyticsInstance; + public static void setNeutralDialog( final Context context, String message, @@ -39,6 +42,7 @@ public static void setNeutralDialog( String title) { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context, R.style.MyAlertDialogStyle); + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); alertDialogBuilder.setTitle(title); alertDialogBuilder .setMessage(message) @@ -47,6 +51,12 @@ public static void setNeutralDialog( positiveButton, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_message_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); if (finish) { ((Activity) context).finish(); } @@ -65,6 +75,7 @@ public void onClick(DialogInterface dialog, int id) { */ public static void setDialogResultOK( final Context context, String message, String positiveButton) { + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context, R.style.MyAlertDialogStyle); alertDialogBuilder.setTitle( @@ -76,6 +87,11 @@ public static void setDialogResultOK( positiveButton, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString(CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_message_ok)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, + eventProperties); ((Activity) context).setResult(Activity.RESULT_OK); ((Activity) context).finish(); } @@ -94,6 +110,7 @@ public void onClick(DialogInterface dialog, int which) { */ public static void setDialogResultOkWithCancel( final Context context, String message, String positiveButton, String negativeButton) { + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context, R.style.MyAlertDialogStyle); alertDialogBuilder.setTitle( @@ -105,6 +122,11 @@ public static void setDialogResultOkWithCancel( positiveButton, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString(CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.custom_message_ok)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, + eventProperties); ((Activity) context).setResult(Activity.RESULT_OK); ((Activity) context).finish(); } @@ -113,6 +135,11 @@ public void onClick(DialogInterface dialog, int which) { negativeButton, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { + Bundle eventProperties = new Bundle(); + eventProperties.putString(CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.negative)); + analyticsInstance.logEvent(CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, + eventProperties); ((Activity) context).finish(); } }); diff --git a/Android/app/src/main/java/com/harvard/utils/SharedPreferenceHelper.java b/Android/app/src/main/java/com/harvard/utils/SharedPreferenceHelper.java index 2603e328b5..e573802ff8 100644 --- a/Android/app/src/main/java/com/harvard/utils/SharedPreferenceHelper.java +++ b/Android/app/src/main/java/com/harvard/utils/SharedPreferenceHelper.java @@ -17,6 +17,8 @@ import android.content.Context; import android.content.SharedPreferences; +import java.util.ArrayList; +import java.util.Map; public class SharedPreferenceHelper { @@ -65,4 +67,21 @@ public static SharedPreferences getPreferences(Context context) { private static SharedPreferences.Editor getEditor(Context context) { return getPreferences(context).edit(); } + + public static void deletePreferences(Context context) { + ArrayList excludeKey = AppController.getExcludePreferenceList(); + SharedPreferences sharedPreferences = getPreferences(context); + Map mapPref = sharedPreferences.getAll(); + if (!excludeKey.isEmpty()) { + for (int i = 0; i < excludeKey.size(); i++) { + if (mapPref.containsKey(excludeKey.get(i))) { + mapPref.remove(excludeKey.get(i)); + } + } + } + + for (Map.Entry prefToRemove : mapPref.entrySet()) { + sharedPreferences.edit().remove(prefToRemove.getKey()).apply(); + } + } } diff --git a/Android/app/src/main/java/com/harvard/utils/VerticalSeekBar.java b/Android/app/src/main/java/com/harvard/utils/VerticalSeekBar.java index c9a1867471..7062ecca87 100644 --- a/Android/app/src/main/java/com/harvard/utils/VerticalSeekBar.java +++ b/Android/app/src/main/java/com/harvard/utils/VerticalSeekBar.java @@ -21,7 +21,7 @@ import android.view.MotionEvent; @SuppressWarnings("DefaultFileTemplate") -public class VerticalSeekBar extends android.support.v7.widget.AppCompatSeekBar { +public class VerticalSeekBar extends androidx.appcompat.widget.AppCompatSeekBar { private OnSeekBarChangeListener seekBarListener; public VerticalSeekBar(Context context) { diff --git a/Android/app/src/main/java/com/harvard/utils/realm/Logger.java b/Android/app/src/main/java/com/harvard/utils/realm/Logger.java index 08eecf2b52..dbeeec8408 100644 --- a/Android/app/src/main/java/com/harvard/utils/realm/Logger.java +++ b/Android/app/src/main/java/com/harvard/utils/realm/Logger.java @@ -15,7 +15,7 @@ package com.harvard.utils.realm; -import android.support.annotation.Nullable; +import androidx.annotation.Nullable; import android.util.Log; import com.harvard.BuildConfig; import com.harvard.FdaApplication; diff --git a/Android/app/src/main/java/com/harvard/utils/realm/RealmEncryptionHelper.java b/Android/app/src/main/java/com/harvard/utils/realm/RealmEncryptionHelper.java index 3f3a3bf5b5..13139458b5 100644 --- a/Android/app/src/main/java/com/harvard/utils/realm/RealmEncryptionHelper.java +++ b/Android/app/src/main/java/com/harvard/utils/realm/RealmEncryptionHelper.java @@ -23,6 +23,8 @@ import android.security.keystore.KeyGenParameterSpec; import android.security.keystore.KeyProperties; import android.util.Base64; +import android.util.Log; + import com.harvard.R; import com.harvard.utils.Logger; import java.io.ByteArrayInputStream; @@ -30,9 +32,16 @@ import java.math.BigInteger; import java.security.KeyPairGenerator; import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.PrivateKey; +import java.security.PublicKey; import java.security.SecureRandom; +import java.security.cert.Certificate; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; +import java.util.Enumeration; + import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; @@ -47,17 +56,12 @@ public class RealmEncryptionHelper { private static final String ANDROID_KEY_STORE = "AndroidKeyStore"; private static final String RSA_MODE = "RSA/ECB/PKCS1Padding"; private static final String ENCRYPTED_KEY = "ENCRYPTED_KEY"; - private String keyName; - private KeyStore keyStore; - private SharedPreferences prefsHelper; public static RealmEncryptionHelper initHelper(Context context, String keyName) { - if (instance == null) { - instance = new RealmEncryptionHelper(context, keyName); - } + instance = new RealmEncryptionHelper(context, keyName); return instance; } @@ -74,14 +78,23 @@ private RealmEncryptionHelper(Context context, String keyName) { prefsHelper = PreferenceManager.getDefaultSharedPreferences(context); } + public void deleteEntry(String alias) { + try { + keyStore = KeyStore.getInstance(ANDROID_KEY_STORE); + keyStore.load(null); + keyStore.deleteEntry(alias); + } catch (Exception e) { + Logger.log(e); + } + } + @SuppressWarnings("NewApi") public byte[] getEncryptKey() { byte[] encryptedKey = new byte[64]; try { keyStore = KeyStore.getInstance(ANDROID_KEY_STORE); keyStore.load(null); - - if (!keyStore.containsAlias(context.getString(R.string.app_name))) { + if (!keyStore.containsAlias(keyName)) { // Create new key and save to KeyStore KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, ANDROID_KEY_STORE); @@ -128,27 +141,28 @@ private byte[] getSecretKey() { String encryptedKeyB64 = prefsHelper.getString(ENCRYPTED_KEY, null); byte[] key = new byte[64]; try { - byte[] encryptedKey = Base64.decode(encryptedKeyB64, Base64.DEFAULT); - key = rsaDecrypt(encryptedKey); - + if (encryptedKeyB64 == null || encryptedKeyB64.equalsIgnoreCase("")) { + deleteEntry(keyName); + key = getEncryptKey(); + } else { + byte[] encryptedKey = Base64.decode(encryptedKeyB64, Base64.DEFAULT); + key = rsaDecrypt(encryptedKey); + } } catch (Exception e) { Logger.log(e); } - return key; } private byte[] generate64BitSecretKey() { byte[] key = new byte[64]; + String encryptedKeyB64; try { - String encryptedKeyB64 = prefsHelper.getString(ENCRYPTED_KEY, null); - if (encryptedKeyB64 == null) { - SecureRandom secureRandom = new SecureRandom(); - secureRandom.nextBytes(key); - byte[] encryptedKey = rsaEncrypt(key); - encryptedKeyB64 = Base64.encodeToString(encryptedKey, Base64.DEFAULT); - prefsHelper.edit().putString(ENCRYPTED_KEY, encryptedKeyB64).apply(); - } + SecureRandom secureRandom = new SecureRandom(); + secureRandom.nextBytes(key); + byte[] encryptedKey = rsaEncrypt(key); + encryptedKeyB64 = Base64.encodeToString(encryptedKey, Base64.DEFAULT); + prefsHelper.edit().putString(ENCRYPTED_KEY, encryptedKeyB64).apply(); } catch (Exception e) { Logger.log(e); } @@ -157,7 +171,9 @@ private byte[] generate64BitSecretKey() { private byte[] rsaEncrypt(byte[] secret) throws Exception { Cipher inputCipher = Cipher.getInstance(RSA_MODE); - inputCipher.init(Cipher.ENCRYPT_MODE, keyStore.getCertificate(keyName).getPublicKey()); + Certificate cert = keyStore.getCertificate(keyName); + PublicKey publicKey = cert.getPublicKey(); + inputCipher.init(Cipher.ENCRYPT_MODE, publicKey); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, inputCipher); diff --git a/Android/app/src/main/java/com/harvard/utils/realm/RealmMigrationHelper.java b/Android/app/src/main/java/com/harvard/utils/realm/RealmMigrationHelper.java index c26af49a70..2ab73ff443 100644 --- a/Android/app/src/main/java/com/harvard/utils/realm/RealmMigrationHelper.java +++ b/Android/app/src/main/java/com/harvard/utils/realm/RealmMigrationHelper.java @@ -35,78 +35,116 @@ public void migrate(final DynamicRealm realm, long oldVersion, long newVersion) if (oldVersion == 0) { // time separated into start and end time RealmObjectSchema anchorRuns = schema.get("AnchorRuns"); - anchorRuns - .addField("startTime", String.class) - .addField("endTime", String.class) - .transform( - new RealmObjectSchema.Function() { - @Override - public void apply(DynamicRealmObject obj) { - obj.set("startTime", obj.getString("time")); - obj.set("endTime", obj.getString("time")); - } - }) - .removeField("time"); + if (anchorRuns != null && !anchorRuns.hasField("startTime")) { + anchorRuns + .addField("startTime", String.class) + .transform( + new RealmObjectSchema.Function() { + @Override + public void apply(DynamicRealmObject obj) { + obj.set("startTime", obj.getString("time")); + } + }); + } + if (anchorRuns != null && !anchorRuns.hasField("endTime")) { + anchorRuns + .addField("endTime", String.class) + .transform( + new RealmObjectSchema.Function() { + @Override + public void apply(DynamicRealmObject obj) { + obj.set("endTime", obj.getString("time")); + } + }); + } + if (anchorRuns != null && anchorRuns.hasField("time")) { + anchorRuns.removeField("time"); + } // Added enroll field RealmObjectSchema consentDocumentData = schema.get("ConsentDocumentData"); - consentDocumentData - .addField("enrollAgain", boolean.class) - .transform( - new RealmObjectSchema.Function() { - @Override - public void apply(DynamicRealmObject obj) { - obj.set("enrollAgain", false); - } - }); + if (consentDocumentData != null && !consentDocumentData.hasField("enrollAgain")) { + consentDocumentData + .addField("enrollAgain", boolean.class) + .transform( + new RealmObjectSchema.Function() { + @Override + public void apply(DynamicRealmObject obj) { + obj.set("enrollAgain", false); + } + }); + } RealmObjectSchema studyUpdate = schema.get("StudyUpdate"); - studyUpdate - .addField("enrollAgain", boolean.class) - .transform( - new RealmObjectSchema.Function() { - @Override - public void apply(DynamicRealmObject obj) { - obj.set("enrollAgain", false); - } - }); + if (studyUpdate != null && !studyUpdate.hasField("enrollAgain")) { + studyUpdate + .addField("enrollAgain", boolean.class) + .transform( + new RealmObjectSchema.Function() { + @Override + public void apply(DynamicRealmObject obj) { + obj.set("enrollAgain", false); + } + }); + } oldVersion++; } else if (oldVersion == 1) { // Added verificationTime field RealmObjectSchema profile = schema.get("Profile"); - profile - .addField("verificationTime", String.class) - .transform( - new RealmObjectSchema.Function() { - @Override - public void apply(DynamicRealmObject obj) { - obj.set("verificationTime", ""); - } - }); + if (profile != null && !profile.hasField("verificationTime")) { + profile + .addField("verificationTime", String.class) + .transform( + new RealmObjectSchema.Function() { + @Override + public void apply(DynamicRealmObject obj) { + obj.set("verificationTime", ""); + } + }); + } // Added Apps - schema.create("Android") - .addField("latestVersion", String.class) - .addField("forceUpdate", String.class); - - schema.create("VersionModel") - .addField("android", Android.class); - - schema.create("Apps") - .addField("message", String.class) - .addField("appName", String.class) - .addField("appId", String.class) - .addField("fromEmail", String.class) - .addField("contactUsEmail", String.class) - .addField("supportEmail", String.class) - .addField("status", int.class) - .addField("code", String.class) - .addField("termsUrl", String.class) - .addField("appWebsite", String.class) - .addField("version", VersionModel.class); + if (!schema.contains("Android")) { + schema + .create("Android") + .addField("latestVersion", String.class) + .addField("forceUpdate", String.class); + } + + if (!schema.contains("VersionModel")) { + schema.create("VersionModel").addField("android", Android.class); + } + + if (!schema.contains("Apps")) { + schema + .create("Apps") + .addField("message", String.class) + .addField("appName", String.class) + .addField("appId", String.class) + .addField("fromEmail", String.class) + .addField("contactUsEmail", String.class) + .addField("supportEmail", String.class) + .addField("status", int.class) + .addField("code", String.class) + .addField("termsUrl", String.class) + .addField("appWebsite", String.class) + .addField("version", VersionModel.class); + } oldVersion++; } } + + public int hashCode() { + return RealmMigrationHelper.class.hashCode(); + } + + public boolean equals(Object object) { + if (object == null) { + return false; + } + return object instanceof RealmMigrationHelper; + } + } diff --git a/Android/app/src/main/java/com/harvard/webservicemodule/apihelper/ApiCall.java b/Android/app/src/main/java/com/harvard/webservicemodule/apihelper/ApiCall.java index a465e659e7..1fd2b8cdb1 100644 --- a/Android/app/src/main/java/com/harvard/webservicemodule/apihelper/ApiCall.java +++ b/Android/app/src/main/java/com/harvard/webservicemodule/apihelper/ApiCall.java @@ -18,7 +18,8 @@ import android.content.Context; import android.content.DialogInterface; import android.os.AsyncTask; -import android.support.v7.app.AlertDialog; +import android.os.Bundle; +import androidx.appcompat.app.AlertDialog; import com.google.gson.Gson; import com.google.gson.stream.JsonReader; import com.harvard.BuildConfig; @@ -27,6 +28,7 @@ import com.harvard.studyappmodule.activitybuilder.model.servicemodel.ActivityInfoData; import com.harvard.usermodule.webservicemodel.TokenData; import com.harvard.utils.AppController; +import com.harvard.utils.CustomFirebaseAnalytics; import com.harvard.utils.Logger; import com.harvard.utils.SharedPreferenceHelper; import com.harvard.utils.Urls; @@ -52,9 +54,11 @@ public class ApiCall extends AsyncTask { private Responsemodel responseModel; private boolean showAlert; private String serverType; + private CustomFirebaseAnalytics analyticsInstance; public ApiCall(Context context) { this.context = context; + analyticsInstance = CustomFirebaseAnalytics.getInstance(context); } /** @@ -554,6 +558,12 @@ private void setShowalert(String msg) { context.getResources().getString(R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { + Bundle eventProperties = new Bundle(); + eventProperties.putString( + CustomFirebaseAnalytics.Param.BUTTON_CLICK_REASON, + context.getString(R.string.error_message_ok)); + analyticsInstance.logEvent( + CustomFirebaseAnalytics.Event.ADD_BUTTON_CLICK, eventProperties); dialog.dismiss(); } }); diff --git a/Android/app/src/main/res/drawable/default_dot.xml b/Android/app/src/main/res/drawable/default_dot.xml new file mode 100644 index 0000000000..318c2bc339 --- /dev/null +++ b/Android/app/src/main/res/drawable/default_dot.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/Android/app/src/main/res/drawable/selected_dot.xml b/Android/app/src/main/res/drawable/selected_dot.xml new file mode 100644 index 0000000000..6cc9dd8c69 --- /dev/null +++ b/Android/app/src/main/res/drawable/selected_dot.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/Android/app/src/main/res/drawable/tab_selector.xml b/Android/app/src/main/res/drawable/tab_selector.xml new file mode 100644 index 0000000000..b7307674be --- /dev/null +++ b/Android/app/src/main/res/drawable/tab_selector.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/Android/app/src/main/res/layout/activity_change_password.xml b/Android/app/src/main/res/layout/activity_change_password.xml index 317deb17a4..5ff03c5800 100644 --- a/Android/app/src/main/res/layout/activity_change_password.xml +++ b/Android/app/src/main/res/layout/activity_change_password.xml @@ -8,7 +8,7 @@ android:background="@android:color/white" android:orientation="vertical"> - - - - + - - - - - - - - - - - - - - - - + - - - - - + - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - + - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -44,7 +44,7 @@ android:layout_height="match_parent" android:layout_weight="2.4"> - - - - - - - + - - - - + - - - - - - - + - - + android:layout_below="@id/hrLine1" + android:visibility="gone"> + + + diff --git a/Android/app/src/main/res/layout/activity_pdfgeneration.xml b/Android/app/src/main/res/layout/activity_pdfgeneration.xml index 959894787f..f3d12f807b 100644 --- a/Android/app/src/main/res/layout/activity_pdfgeneration.xml +++ b/Android/app/src/main/res/layout/activity_pdfgeneration.xml @@ -1,9 +1,22 @@ - + + + android:layout_height="match_parent" + android:visibility="gone"> + + + diff --git a/Android/app/src/main/res/layout/activity_resources_web_view.xml b/Android/app/src/main/res/layout/activity_resources_web_view.xml index a84a66fdb5..c1f4e11a3c 100644 --- a/Android/app/src/main/res/layout/activity_resources_web_view.xml +++ b/Android/app/src/main/res/layout/activity_resources_web_view.xml @@ -5,7 +5,7 @@ android:layout_height="match_parent" android:orientation="vertical"> - - - - - + - - + android:visibility="gone"> + + + + + diff --git a/Android/app/src/main/res/layout/activity_sign_in_study.xml b/Android/app/src/main/res/layout/activity_sign_in_study.xml index 9eebeb2e27..0e842004f7 100644 --- a/Android/app/src/main/res/layout/activity_sign_in_study.xml +++ b/Android/app/src/main/res/layout/activity_sign_in_study.xml @@ -7,7 +7,7 @@ android:background="@android:color/white" tool:context="com.harvard.studyappmodule.StudySignInActivity"> - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/Android/app/src/main/res/layout/activity_standalone_study_info.xml b/Android/app/src/main/res/layout/activity_standalone_study_info.xml index db8197a201..6e21b1cb60 100644 --- a/Android/app/src/main/res/layout/activity_standalone_study_info.xml +++ b/Android/app/src/main/res/layout/activity_standalone_study_info.xml @@ -12,7 +12,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - @@ -26,7 +26,7 @@ - - - + - - - - - - - - - - - - - - - - - - - + diff --git a/Android/app/src/main/res/layout/activity_study_info.xml b/Android/app/src/main/res/layout/activity_study_info.xml index 7e2ccc770f..c0bcb9984b 100644 --- a/Android/app/src/main/res/layout/activity_study_info.xml +++ b/Android/app/src/main/res/layout/activity_study_info.xml @@ -12,7 +12,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - @@ -26,7 +26,7 @@ - - - + - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/Android/app/src/main/res/layout/activity_survey_complete.xml b/Android/app/src/main/res/layout/activity_survey_complete.xml index b3477c9af1..1391ab3bac 100644 --- a/Android/app/src/main/res/layout/activity_survey_complete.xml +++ b/Android/app/src/main/res/layout/activity_survey_complete.xml @@ -18,7 +18,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - - - - - - - - - + - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - @@ -114,7 +114,7 @@ android:maxLines="1" android:textCursorDrawable="@drawable/custom_cursor_drawable" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - + - - - - + diff --git a/Android/app/src/main/res/layout/fragment_survey_dashboard.xml b/Android/app/src/main/res/layout/fragment_survey_dashboard.xml index e11dbf4261..8f17bbb32a 100644 --- a/Android/app/src/main/res/layout/fragment_survey_dashboard.xml +++ b/Android/app/src/main/res/layout/fragment_survey_dashboard.xml @@ -6,7 +6,7 @@ android:background="@color/white" tool:context="com.harvard.studyappmodule.SurveyDashboardFragment"> - - - - - - - + - - - - @@ -161,14 +161,14 @@ android:layout_height="wrap_content" android:layout_weight="1.45"> - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:orientation="vertical"> - + android:layout_above="@+id/sharelayout" + android:visibility="gone"> + + + - - - - - + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto"> - + android:paddingBottom="2dp" + app:rsb_gravity="bottom" + app:rsb_indicator_show_mode="alwaysHide" + app:rsb_mode="single" + app:rsb_progress_color="@color/colorAccent" + app:rsb_step_color="@color/colorAccent" + app:rsb_step_height="10dp" + app:rsb_step_width="2dp" + app:rsb_thumb_drawable="@drawable/thumb_image" + app:rsb_thumb_height="40dp" + app:rsb_thumb_width="40dp" + app:rsb_tick_mark_gravity="center" + app:rsb_tick_mark_layout_gravity="bottom" + app:rsb_tick_mark_mode="other" + app:rsb_tick_mark_text_color="@color/black_shade" /> + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:nestedScrollingEnabled="true"> - - + - + - - + + + + - - + + \ No newline at end of file diff --git a/Android/app/src/main/res/layout/seekbar_vertical_layout.xml b/Android/app/src/main/res/layout/seekbar_vertical_layout.xml index f0db10cd06..87ce5ab734 100644 --- a/Android/app/src/main/res/layout/seekbar_vertical_layout.xml +++ b/Android/app/src/main/res/layout/seekbar_vertical_layout.xml @@ -1,8 +1,9 @@ + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:nestedScrollingEnabled="true"> - + app:rsb_gravity="center" + app:rsb_tick_mark_orientation="vertical" + app:rsb_indicator_show_mode="alwaysHide" + app:rsb_mode="single" + app:rsb_progress_color="@color/colorAccent" + app:rsb_step_color="@color/colorAccent" + app:rsb_step_height="10dp" + app:rsb_step_width="2dp" + app:rsb_thumb_drawable="@drawable/thumb_image" + app:rsb_thumb_height="40dp" + app:rsb_thumb_width="40dp" + app:rsb_tick_mark_layout_gravity="bottom" + app:rsb_tick_mark_mode="number" + app:rsb_tick_mark_text_size="12sp" + app:rsb_tick_mark_text_color="@color/black_shade" + app:rsb_tick_mark_text_margin="-20dp" + /> - - - @@ -41,7 +41,7 @@ android:layout_height="match_parent" android:layout_above="@+id/adjustContentCentral"> - - - - - - --> - - - - - - - - + - - - - - - - @@ -194,13 +194,13 @@ android:layout_height="wrap_content" android:visibility="invisible"> - - --> - diff --git a/Android/app/src/main/res/layout/study_sign_in_list_item.xml b/Android/app/src/main/res/layout/study_sign_in_list_item.xml index 1a246a8df1..cc6de653de 100644 --- a/Android/app/src/main/res/layout/study_sign_in_list_item.xml +++ b/Android/app/src/main/res/layout/study_sign_in_list_item.xml @@ -12,7 +12,7 @@ android:paddingLeft="18dp" android:paddingTop="24dp"> - - - - - - - - - - - - - - - - diff --git a/Android/app/src/main/res/layout/top_bar_layout.xml b/Android/app/src/main/res/layout/top_bar_layout.xml index f13a59b6d9..b2a8edd674 100644 --- a/Android/app/src/main/res/layout/top_bar_layout.xml +++ b/Android/app/src/main/res/layout/top_bar_layout.xml @@ -6,7 +6,7 @@ android:layout_height="wrap_content" android:background="@android:color/white"> - - - - - - + - You have been signed out of the app. Sorry, an error occurred and your e-consent could not be completed. Please try again. This will also delete your app account. - Please wait as we set up the study for you, this may take a few seconds + Fetching study content.... + We are setting up the study for you. This may take a few minutes. Please check back shortly. &learn_more_txt; &learn_more_txt; &learn_more_txt; @@ -539,4 +540,179 @@ Terms Privacy policy + Please choose a time. + Please choose a date and time. + + + Eligible + Not eligible + Eligibility confirmation + Custom view task end task + Custom view task cancel + Custom view task back + Custom view task exit + Custom view task next + Custom survey task next + Custom survey end task + Custom survey task cancel + Custom survey task exit + Custom survey task back + Load more + Verification back button + Verification submit button + Verification cancel button + Verification resend button + Custom consent view next + Custom consent disagree ok + Custom ok button + Custom cancel button + Custom clear button + Time + Tap edit button + Tap proceed button + Custom consent view exit + Custom consent disagree cancel + Custom consent view back + Custom consent end task + Password change submit + Forgot passcode + Chart screen share button + Chart screen back button + Chart screen left arrow + Chart screen right arrow + Consent complete View-pdf + Consent complete done button + Consent complete share button + Contact us back button + Contact us submit button + Custom activities dialog close + Custom dialog done button + Delete account back button + Delete account agree button + Delete account disagree button + Eligibility enroll back button + Eligibility enroll submit button + Enrollment validate continue + Gateway resources list item selected + Gateway resources back button + Gateway resources share button + Back button for load-more actvity + Password change back button + Notification back button + Notification list item selected + Pdf display back button + Pdf display share button + Feedback back button + Feedback submit button + Filter cancel button + Filter apply button + Profile fragment time reminder button + Profile fragment password change + Profile fragment passcode change + Profile fragment passcode change button + Profile fragment notification reciver button + Profile fragment study reminder button + Profile fragment signout button + Profile fragment delete button + Reachout list item selected + Feedback selected + Contact-us selected + Resources list item selected + Leave study accept + Leave study reject + Resources back button + Resources share button + Signup fragment terms + Signup fragment privacy_policy + Signup fragment submit button + Update next time ok + App upgrade accepted + App upgrade reject + Study info back button + Study list item selected + Sign up list item selected + Activities Home + Activities list item selected + Activities list more + Activities filter + Survey side menu + Survey side menu home + Survey side menu reachout + Survey side menu resources + Survey side menu sign-in + Survey side menu sign-out + Survey side menu my-account + Survey sign-out accept + Survey sign-out reject + Survey complete done button + Dashboard home + Dashboard share button + Dashboard day selected + Dashboard week selected + Dashboard month selected + Dashboard left arrow change date + Dashboard right arrow change date + Confirm passcode back button + Frogot password back button + Frogot password cancel button + Frogot password submit button + Resource home + Signup terms + Signup privacy_policy + Signup submit button + Signup back button + Signup cancel button + Signup info button + Signup complete done button + Terms privacy back button + Error message ok button + Splash retry accept + Splash retry reject + Web-view back button + Passcode setup retry + Passcode setup signout ok + Passcode setup signout cancel + Study info button + Study side menu + Study side menu home + Study side menu reachout + Study side menu resources + Study edit + Study side menu sign-in + Study side menu sign-up + Study search icon clicked + Study search clear button + Study search cancel + Study notfication + Study side menu sign-out + Study side menu my-account + Study sign-out accept + app website view + Consent review agree button + Consent review disagree button + Consent agree + Consent cancel + Consent dis-agree ok + Consent dis-agree cancel + Study sign-out reject + Custom dialog message ok + Back btn clicked + Info btn clicked + + Alart dialog negative + Tap button click + Text View value picker + Value picker cancel button + Value picker list item select + Add more questions + Image View + Share button + Left arrow + Right arrow + Text dynamic + Container + Menu + Preview + My account + diff --git a/Android/gradle.properties b/Android/gradle.properties index 82618cecb4..d546deaf0e 100644 --- a/Android/gradle.properties +++ b/Android/gradle.properties @@ -6,6 +6,8 @@ # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. +android.enableJetifier=true +android.useAndroidX=true org.gradle.jvmargs=-Xmx1536m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit diff --git a/auth-server/oauth-scim-service/src/main/resources/static/css/login.scss b/auth-server/oauth-scim-service/src/main/resources/static/css/login.scss index 5a43091280..de8660a710 100644 --- a/auth-server/oauth-scim-service/src/main/resources/static/css/login.scss +++ b/auth-server/oauth-scim-service/src/main/resources/static/css/login.scss @@ -66,7 +66,7 @@ body.my-login-page { } } -@media screen and (max-width: 320px) { +@media screen and (max-width: 300px) { .my-login-page .card.fat { padding: 0; } diff --git a/auth-server/oauth-scim-service/src/main/resources/static/css/style.css b/auth-server/oauth-scim-service/src/main/resources/static/css/style.css index 7a7211188a..19ba217efe 100644 --- a/auth-server/oauth-scim-service/src/main/resources/static/css/style.css +++ b/auth-server/oauth-scim-service/src/main/resources/static/css/style.css @@ -262,7 +262,7 @@ footer ul li:last-child a { } /* media queries scss */ -@media ( min-width : 320px) { +@media ( min-width : 300px) { .centered__div { width: 92%; bottom: 2%; @@ -349,7 +349,7 @@ body#body-container { font-weight: 600; } -@media ( min-width : 320px) { +@media ( min-width : 300px) { .centered__div__mobile { width: 270px; } @@ -448,7 +448,7 @@ body#body-container { padding: 40% 0% !important; } -@media only screen and (max-width: 500px) and (min-width: 320px) { +@media only screen and (max-width: 500px) and (min-width: 300px) { .input__field input { text-indent: 18px; } @@ -551,7 +551,7 @@ body#body-container { 100% { transform: rotate(360deg); transform: rotate(360deg); } } -@media only screen and (max-width: 900px) and (min-width: 320px) { +@media only screen and (max-width: 900px) and (min-width: 300px) { .loading_text { margin-top: 90%; } @@ -565,7 +565,7 @@ body#body-container { margin-top: 60%; } -@media only screen and (max-width: 500px) and (min-width: 320px) { +@media only screen and (max-width: 500px) and (min-width: 300px) { .mob_mt { margin-top:10px; } } diff --git a/auth-server/oauth-scim-service/src/main/resources/templates/login.html b/auth-server/oauth-scim-service/src/main/resources/templates/login.html index 81cea50cbe..c5e45a25ed 100644 --- a/auth-server/oauth-scim-service/src/main/resources/templates/login.html +++ b/auth-server/oauth-scim-service/src/main/resources/templates/login.html @@ -52,6 +52,12 @@ input { filter: none !important; } + +.visibility__hidden { + visibility: hidden !important; +} + + @@ -100,34 +106,30 @@ - - - Forgot - password? - + class="input__feild mob_mt display-flex-center login__btn__container"> Sign in + - - Forgot - password? + + Forgot_password? + + + + New user? Sign up - - @@ -145,8 +147,8 @@