diff --git a/GNSSLogger/.idea/jarRepositories.xml b/GNSSLogger/.idea/jarRepositories.xml
new file mode 100644
index 0000000..0a1b94d
--- /dev/null
+++ b/GNSSLogger/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/GNSSLogger/app/build.gradle b/GNSSLogger/app/build.gradle
index e2b770b..936cb46 100644
--- a/GNSSLogger/app/build.gradle
+++ b/GNSSLogger/app/build.gradle
@@ -2,6 +2,7 @@ plugins {
id 'com.android.application'
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
}
+apply plugin: 'kotlin-android'
android {
compileSdk 32
@@ -26,6 +27,12 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
+
+ testOptions {
+ unitTests {
+ includeAndroidResources = true
+ }
+ }
}
dependencies {
@@ -38,8 +45,16 @@ dependencies {
implementation files('libs/achartengine-1.2.0.jar')
implementation("com.google.guava:guava:31.1-android")
implementation 'com.google.android.material:material:1.6.1'
+ implementation "androidx.core:core:1.8.0"
+ testImplementation 'androidx.test:core:1.4.0'
+ testImplementation 'junit:junit:4.13.2'
+ testImplementation 'org.robolectric:robolectric:4.8.1'
+ testImplementation "com.google.truth:truth:1.1.3"
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
- testImplementation 'junit:junit:4.13.2'
- implementation "androidx.core:core:1.8.0"
+ implementation "androidx.core:core-ktx:+"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
+repositories {
+ mavenCentral()
}
\ No newline at end of file
diff --git a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java
index f385309..5e7131a 100755
--- a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java
+++ b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java
@@ -16,7 +16,6 @@
package com.google.android.apps.location.gps.gnsslogger;
-
import android.Manifest;
import android.app.Activity;
import android.app.PendingIntent;
@@ -42,6 +41,7 @@
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.viewpager.widget.ViewPager;
+import com.google.android.apps.location.gps.gnsslogger.util.PendingIntentCompat;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
@@ -141,12 +141,12 @@ protected void onCreate(Bundle savedInstanceState) {
protected PendingIntent createActivityDetectionPendingIntent() {
Intent intent = new Intent(this, DetectedActivitiesIntentReceiver.class);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
- return PendingIntent.getBroadcast(this, 0, intent,
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
- } else {
- return PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
- }
+ return PendingIntentCompat.getBroadcast(
+ /* context= */ this,
+ /* requestCode= */ 0,
+ intent,
+ PendingIntent.FLAG_UPDATE_CURRENT,
+ /* isMutable= */ true);
}
private synchronized void buildGoogleApiClient() {
diff --git a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/util/PendingIntentCompat.kt b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/util/PendingIntentCompat.kt
new file mode 100644
index 0000000..b8da594
--- /dev/null
+++ b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/util/PendingIntentCompat.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.android.apps.location.gps.gnsslogger.util
+
+import android.content.Intent
+import android.app.PendingIntent
+import android.content.Context
+import com.google.android.apps.location.gps.gnsslogger.util.PendingIntentCompat
+import android.os.Build
+
+/** Helper for accessing features in [PendingIntent]. */
+object PendingIntentCompat {
+ /**
+ * Retrieves a [PendingIntent] with mandatory mutability flag set on supported platform
+ * versions. The caller provides the flag as combination of all the other values except mutability
+ * flag. This method combines mutability flag when necessary. See [ ][PendingIntent.getBroadcast].
+ */
+ @JvmStatic
+ fun getBroadcast(
+ context: Context,
+ requestCode: Int,
+ intent: Intent,
+ flags: Int,
+ isMutable: Boolean): PendingIntent {
+ return PendingIntent.getBroadcast(
+ context, requestCode, intent, addMutabilityFlags(isMutable, flags))
+ }
+
+ private fun addMutabilityFlags(isMutable: Boolean, flags: Int): Int {
+ var flags = flags
+ if (isMutable) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ flags = flags or PendingIntent.FLAG_MUTABLE
+ }
+ } else {
+ // Minimum support SDK is 24.
+ flags = flags or PendingIntent.FLAG_IMMUTABLE
+ }
+ return flags
+ }
+}
\ No newline at end of file
diff --git a/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/ExampleUnitTest.java b/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/ExampleUnitTest.java
deleted file mode 100644
index 00efbce..0000000
--- a/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.google.android.apps.location.gps.gnsslogger;
-
-import static org.junit.Assert.*;
-
-import org.junit.Test;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() {
- assertEquals(4, 2 + 2);
- }
-}
diff --git a/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/util/PendingIntentCompatTest.java b/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/util/PendingIntentCompatTest.java
new file mode 100644
index 0000000..f44d1d2
--- /dev/null
+++ b/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/util/PendingIntentCompatTest.java
@@ -0,0 +1,121 @@
+package com.google.android.apps.location.gps.gnsslogger.util;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import androidx.test.core.app.ApplicationProvider;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowPendingIntent;
+
+/** Unit test for {@link PendingIntentCompat}. */
+@RunWith(RobolectricTestRunner.class)
+public class PendingIntentCompatTest {
+ private final Context context = ApplicationProvider.getApplicationContext();
+
+ /** Immutable is introduced in M, but the project's minimum support version is 24 */
+ @Config(sdk = Build.VERSION_CODES.N)
+ @Test
+ public void addMutabilityFlags_immutableOnMPlus() {
+ int requestCode = 7465;
+ Intent intent = new Intent();
+ ShadowPendingIntent shadow =
+ shadowOf(
+ PendingIntentCompat.getBroadcast(
+ context,
+ requestCode,
+ intent,
+ PendingIntent.FLAG_UPDATE_CURRENT,
+ /* isMutable= */ false));
+ assertThat(shadow.getFlags())
+ .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+ }
+
+ @Config(maxSdk = Build.VERSION_CODES.R)
+ @Test
+ public void addMutabilityFlags_mutableOnPreS() {
+ int requestCode = 7465;
+ Intent intent = new Intent();
+ ShadowPendingIntent shadow =
+ shadowOf(
+ PendingIntentCompat.getBroadcast(
+ context,
+ requestCode,
+ intent,
+ PendingIntent.FLAG_UPDATE_CURRENT,
+ /* isMutable= */ true));
+ assertThat(shadow.getFlags()).isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT);
+ }
+
+ @Config(maxSdk = Build.VERSION_CODES.R)
+ @Test
+ public void addMutabilityFlags_immutableOnPreS() {
+ int requestCode = 7465;
+ Intent intent = new Intent();
+ ShadowPendingIntent shadow =
+ shadowOf(
+ PendingIntentCompat.getBroadcast(
+ context,
+ requestCode,
+ intent,
+ PendingIntent.FLAG_UPDATE_CURRENT,
+ /* isMutable= */ false));
+ assertThat(shadow.getFlags())
+ .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+ }
+
+ @Config(minSdk = Build.VERSION_CODES.S)
+ @Test
+ public void addMutabilityFlags_mutableOnSPlus() {
+ int requestCode = 7465;
+ Intent intent = new Intent();
+ ShadowPendingIntent shadow =
+ shadowOf(
+ PendingIntentCompat.getBroadcast(
+ context,
+ requestCode,
+ intent,
+ PendingIntent.FLAG_UPDATE_CURRENT,
+ /* isMutable= */ true));
+ assertThat(shadow.getFlags())
+ .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
+ }
+
+ @Config(minSdk = Build.VERSION_CODES.S)
+ @Test
+ public void addMutabilityFlags_immutableOnSPlus() {
+ int requestCode = 7465;
+ Intent intent = new Intent();
+ ShadowPendingIntent shadow =
+ shadowOf(
+ PendingIntentCompat.getBroadcast(
+ context,
+ requestCode,
+ intent,
+ PendingIntent.FLAG_UPDATE_CURRENT,
+ /* isMutable= */ false));
+ assertThat(shadow.getFlags())
+ .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+ }
+
+ @Test
+ public void getBroadcast() {
+ int requestCode = 7465;
+ Intent intent = new Intent();
+ ShadowPendingIntent shadow =
+ shadowOf(
+ PendingIntentCompat.getBroadcast(
+ context,
+ requestCode,
+ intent,
+ PendingIntent.FLAG_UPDATE_CURRENT,
+ /* isMutable= */ false));
+ assertThat(shadow.isBroadcast()).isTrue();
+ }
+}
diff --git a/GNSSLogger/build.gradle b/GNSSLogger/build.gradle
index 41052eb..bb78f47 100644
--- a/GNSSLogger/build.gradle
+++ b/GNSSLogger/build.gradle
@@ -1,4 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ ext.kotlin_version = '1.7.20-Beta'
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
plugins {
id 'com.android.application' version '7.2.1' apply false
id 'com.android.library' version '7.2.1' apply false
diff --git a/GNSSLogger/settings.gradle b/GNSSLogger/settings.gradle
index 0e73733..58d7621 100644
--- a/GNSSLogger/settings.gradle
+++ b/GNSSLogger/settings.gradle
@@ -6,7 +6,7 @@ pluginManagement {
}
}
dependencyResolutionManagement {
- repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
google()
mavenCentral()