diff --git a/crash/app/src/main/AndroidManifest.xml b/crash/app/src/main/AndroidManifest.xml
index 5722a783c..843063b8e 100644
--- a/crash/app/src/main/AndroidManifest.xml
+++ b/crash/app/src/main/AndroidManifest.xml
@@ -1,26 +1,21 @@
-
-
+
-
+
@@ -30,7 +25,6 @@ specific language governing permissions and limitations under the License.
-
-
+
\ No newline at end of file
diff --git a/crash/app/src/main/java/com/google/samples/quickstart/crash/EntryChoiceActivity.kt b/crash/app/src/main/java/com/google/samples/quickstart/crash/EntryChoiceActivity.kt
index 7c85ba60e..ea5831939 100644
--- a/crash/app/src/main/java/com/google/samples/quickstart/crash/EntryChoiceActivity.kt
+++ b/crash/app/src/main/java/com/google/samples/quickstart/crash/EntryChoiceActivity.kt
@@ -16,7 +16,14 @@ class EntryChoiceActivity : BaseEntryChoiceActivity() {
Choice(
"Kotlin",
"Run the Firebase Crash quickstart written in Kotlin.",
- Intent(this, com.google.samples.quickstart.crash.kotlin.MainActivity::class.java))
+ Intent(this, com.google.samples.quickstart.crash.kotlin.MainActivity::class.java)),
+ Choice(
+ "Compose",
+ "Run the Firebase Remote Crash quickstart written in Compose.",
+ Intent(
+ this,
+ com.google.samples.quickstart.crash.kotlin.MainComposeActivity::class.java)
+ )
)
}
}
diff --git a/crash/app/src/main/java/com/google/samples/quickstart/crash/kotlin/MainComposeActivity.kt b/crash/app/src/main/java/com/google/samples/quickstart/crash/kotlin/MainComposeActivity.kt
new file mode 100644
index 000000000..6e8b84db7
--- /dev/null
+++ b/crash/app/src/main/java/com/google/samples/quickstart/crash/kotlin/MainComposeActivity.kt
@@ -0,0 +1,162 @@
+package com.google.samples.quickstart.crash.kotlin
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+
+import androidx.compose.material.Button
+import androidx.compose.material.ButtonDefaults
+import androidx.compose.material.Checkbox
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Scaffold
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.material.TopAppBar
+import androidx.compose.material.rememberScaffoldState
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+
+import com.google.firebase.crashlytics.FirebaseCrashlytics
+import com.google.firebase.crashlytics.ktx.crashlytics
+import com.google.firebase.crashlytics.ktx.setCustomKeys
+import com.google.firebase.ktx.Firebase
+import com.google.samples.quickstart.crash.R
+import com.google.samples.quickstart.crash.kotlin.ui.theme.CrashTheme
+import kotlinx.coroutines.launch
+
+class MainComposeActivity : ComponentActivity() {
+
+ private lateinit var crashlytics: FirebaseCrashlytics
+ private lateinit var customKeySamples: CustomKeySamples
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ // Taken from original MainActivity.kt
+ customKeySamples = CustomKeySamples(applicationContext)
+ customKeySamples.setSampleCustomKeys()
+ customKeySamples.updateAndTrackNetworkState()
+
+ crashlytics = Firebase.crashlytics
+
+ // Log the onCreate event, this will also be printed in logcat
+ crashlytics.log("onCreate with jetpack compose")
+
+ // Add some custom values and identifiers to be included in crash reports
+ crashlytics.setCustomKeys {
+ key("MeaningOfLife", 42)
+ key("LastUIAction", "Test value")
+ }
+ crashlytics.setUserId("123456789")
+
+ // Report a non-fatal exception, for demonstration purposes
+ crashlytics.recordException(Exception("Non-fatal exception: something went wrong!"))
+
+ setContent {
+ CrashTheme {
+ // A surface container using the 'background' color from the theme
+ Surface(
+ modifier = Modifier.fillMaxSize(),
+ color = MaterialTheme.colors.background
+ ) {
+ MainAppView(crashlytics)
+ }
+ }
+ }
+ }
+}
+
+@Composable
+fun MainAppView(crashlytics: FirebaseCrashlytics) {
+
+ val scaffoldState = rememberScaffoldState() // this contains the `SnackbarHostState`
+ val checkedState = remember { mutableStateOf(true) }
+
+ // Log that the Activity was created.
+ // [START crashlytics_log_event]
+ crashlytics.log("Activity created")
+ // [END crashlytics_log_event]
+
+ Scaffold(
+ scaffoldState = scaffoldState,
+ topBar = {
+ TopAppBar(
+ backgroundColor = colorResource(R.color.colorPrimary)
+ ) {
+ Text(
+ text = stringResource(R.string.app_name),
+ style = MaterialTheme.typography.h6,
+ textAlign = TextAlign.Center,
+ modifier = Modifier.padding(8.dp),
+ color = Color.White
+ )
+ }
+ }, content = {
+ Column(modifier = Modifier.padding(it).fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
+ Spacer(modifier = Modifier.height(24.dp))
+
+ Image(painter = painterResource(R.drawable.firebase_lockup_400), contentDescription = "")
+
+ Spacer(modifier = Modifier.height(50.dp))
+
+ // Button to fetch remote welcome
+ Button(
+ colors = ButtonDefaults.buttonColors(backgroundColor = colorResource(R.color.colorAccent)),
+ onClick = {
+
+ // crashlytics Functionality
+ crashlytics.log("Crash button clicked using jetpack compose.")
+ println("CRASHHHH")
+
+ if (checkedState.value) {
+ try {
+ throw NullPointerException()
+ } catch (ex: NullPointerException) {
+ // [START crashlytics_log_and_report]
+ crashlytics.log("NPE caught!")
+ crashlytics.recordException(ex)
+ // [END crashlytics_log_and_report]
+ }
+ } else {
+ throw NullPointerException()
+ }
+
+
+ }
+ ) {
+ Text(
+ text = "CAUSE CRASH",
+ fontSize = 20.sp,
+ color = Color.White
+ )
+ }
+ Row(modifier = Modifier.padding(8.dp)) {
+ Checkbox(
+ checked = checkedState.value,
+ onCheckedChange = { checkedState.value = it }
+ )
+ Text(text = "Catch Crash", fontSize = 20.sp ,modifier = Modifier.padding(8.dp))
+ }
+
+ }
+ })
+}
diff --git a/crash/app/src/main/java/com/google/samples/quickstart/crash/kotlin/ui/theme/Color.kt b/crash/app/src/main/java/com/google/samples/quickstart/crash/kotlin/ui/theme/Color.kt
new file mode 100644
index 000000000..7f38fd249
--- /dev/null
+++ b/crash/app/src/main/java/com/google/samples/quickstart/crash/kotlin/ui/theme/Color.kt
@@ -0,0 +1,8 @@
+package com.google.samples.quickstart.crash.kotlin.ui.theme
+
+import androidx.compose.ui.graphics.Color
+
+val Purple200 = Color(0xFFBB86FC)
+val Purple500 = Color(0xFF6200EE)
+val Purple700 = Color(0xFF3700B3)
+val Teal200 = Color(0xFF03DAC5)
\ No newline at end of file
diff --git a/crash/app/src/main/java/com/google/samples/quickstart/crash/kotlin/ui/theme/Shape.kt b/crash/app/src/main/java/com/google/samples/quickstart/crash/kotlin/ui/theme/Shape.kt
new file mode 100644
index 000000000..e6f77e02e
--- /dev/null
+++ b/crash/app/src/main/java/com/google/samples/quickstart/crash/kotlin/ui/theme/Shape.kt
@@ -0,0 +1,11 @@
+package com.google.samples.quickstart.crash.kotlin.ui.theme
+
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Shapes
+import androidx.compose.ui.unit.dp
+
+val Shapes = Shapes(
+ small = RoundedCornerShape(4.dp),
+ medium = RoundedCornerShape(4.dp),
+ large = RoundedCornerShape(0.dp)
+)
\ No newline at end of file
diff --git a/crash/app/src/main/java/com/google/samples/quickstart/crash/kotlin/ui/theme/Theme.kt b/crash/app/src/main/java/com/google/samples/quickstart/crash/kotlin/ui/theme/Theme.kt
new file mode 100644
index 000000000..b1a0a6a6f
--- /dev/null
+++ b/crash/app/src/main/java/com/google/samples/quickstart/crash/kotlin/ui/theme/Theme.kt
@@ -0,0 +1,44 @@
+package com.google.samples.quickstart.crash.kotlin.ui.theme
+
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.darkColors
+import androidx.compose.material.lightColors
+import androidx.compose.runtime.Composable
+
+private val DarkColorPalette = darkColors(
+ primary = Purple200,
+ primaryVariant = Purple700,
+ secondary = Teal200
+)
+
+private val LightColorPalette = lightColors(
+ primary = Purple500,
+ primaryVariant = Purple700,
+ secondary = Teal200
+
+ /* Other default colors to override
+ background = Color.White,
+ surface = Color.White,
+ onPrimary = Color.White,
+ onSecondary = Color.Black,
+ onBackground = Color.Black,
+ onSurface = Color.Black,
+ */
+)
+
+@Composable
+fun CrashTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
+ val colors = if (darkTheme) {
+ DarkColorPalette
+ } else {
+ LightColorPalette
+ }
+
+ MaterialTheme(
+ colors = colors,
+ typography = Typography,
+ shapes = Shapes,
+ content = content
+ )
+}
\ No newline at end of file
diff --git a/crash/app/src/main/java/com/google/samples/quickstart/crash/kotlin/ui/theme/Type.kt b/crash/app/src/main/java/com/google/samples/quickstart/crash/kotlin/ui/theme/Type.kt
new file mode 100644
index 000000000..e5fdca94b
--- /dev/null
+++ b/crash/app/src/main/java/com/google/samples/quickstart/crash/kotlin/ui/theme/Type.kt
@@ -0,0 +1,28 @@
+package com.google.samples.quickstart.crash.kotlin.ui.theme
+
+import androidx.compose.material.Typography
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.sp
+
+// Set of Material typography styles to start with
+val Typography = Typography(
+ body1 = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 16.sp
+ )
+ /* Other default text styles to override
+ button = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.W500,
+ fontSize = 14.sp
+ ),
+ caption = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 12.sp
+ )
+ */
+)
\ No newline at end of file
diff --git a/crash/app/src/main/res/values/strings.xml b/crash/app/src/main/res/values/strings.xml
index 0e8e90d3b..8f8eafecb 100644
--- a/crash/app/src/main/res/values/strings.xml
+++ b/crash/app/src/main/res/values/strings.xml
@@ -2,4 +2,5 @@
Firebase Crashlytics
Cause Crash
Catch Crash
+ MainComposeActivity.kt
diff --git a/crash/build.gradle b/crash/build.gradle
index 253a0e83f..6fb9f9f39 100644
--- a/crash/build.gradle
+++ b/crash/build.gradle
@@ -1,6 +1,9 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
+ ext {
+ compose_version = '1.3.0'
+ }
repositories {
mavenLocal()
google()
diff --git a/crash/gradle.properties b/crash/gradle.properties
index aac7c9b46..29b531a1d 100644
--- a/crash/gradle.properties
+++ b/crash/gradle.properties
@@ -10,7 +10,7 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
-
+android.useAndroidX=true
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects