diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0cf6eeb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,59 @@
+lt application files
+*.apk
+*.ap_
+
+# Files for the ART/Dalvik VM
+*.dex
+
+# Java class files
+*.class
+
+# Generated files
+bin/
+gen/
+out/
+
+# Gradle files
+.gradle/
+build/
+/*/build/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Proguard folder generated by Eclipse
+proguard/
+
+# Log Files
+*.log
+
+# Android Studio Navigation editor temp files
+.navigation/
+
+# Android Studio captures folder
+captures/
+
+# Intellij
+*.iml
+.idea/
+
+# Keystore files
+*.jks
+
+# Mac files
+.DS_Store
+
+# Google credentials files
+google-services.json*.iml
+
+fastlane/.env
+
+app/release/
+
+fastlane/README.md
+
+fastlane/report.xml
+
+.project
+
+.settings/
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..b32fe16
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+source "https://rubygems.org"
+
+git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
+
+# gem "rails"
+
+gem "fastlane", "~> 2.137"
+
+plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
+eval_gemfile(plugins_path) if File.exist?(plugins_path)
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000..eeb2c6a
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,161 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ CFPropertyList (3.0.2)
+ addressable (2.7.0)
+ public_suffix (>= 2.0.2, < 5.0)
+ atomos (0.1.3)
+ babosa (1.0.3)
+ claide (1.0.3)
+ colored (1.2)
+ colored2 (3.1.2)
+ commander-fastlane (4.4.6)
+ highline (~> 1.7.2)
+ declarative (0.0.10)
+ declarative-option (0.1.0)
+ digest-crc (0.4.1)
+ domain_name (0.5.20190701)
+ unf (>= 0.0.5, < 1.0.0)
+ dotenv (2.7.5)
+ emoji_regex (1.0.1)
+ excon (0.71.0)
+ faraday (0.17.1)
+ multipart-post (>= 1.2, < 3)
+ faraday-cookie_jar (0.0.6)
+ faraday (>= 0.7.4)
+ http-cookie (~> 1.0.0)
+ faraday_middleware (0.13.1)
+ faraday (>= 0.7.4, < 1.0)
+ fastimage (2.1.7)
+ fastlane (2.137.0)
+ CFPropertyList (>= 2.3, < 4.0.0)
+ addressable (>= 2.3, < 3.0.0)
+ babosa (>= 1.0.2, < 2.0.0)
+ bundler (>= 1.12.0, < 3.0.0)
+ colored
+ commander-fastlane (>= 4.4.6, < 5.0.0)
+ dotenv (>= 2.1.1, < 3.0.0)
+ emoji_regex (>= 0.1, < 2.0)
+ excon (>= 0.45.0, < 1.0.0)
+ faraday (~> 0.17)
+ faraday-cookie_jar (~> 0.0.6)
+ faraday_middleware (~> 0.13.1)
+ fastimage (>= 2.1.0, < 3.0.0)
+ gh_inspector (>= 1.1.2, < 2.0.0)
+ google-api-client (>= 0.21.2, < 0.24.0)
+ google-cloud-storage (>= 1.15.0, < 2.0.0)
+ highline (>= 1.7.2, < 2.0.0)
+ json (< 3.0.0)
+ jwt (~> 2.1.0)
+ mini_magick (>= 4.9.4, < 5.0.0)
+ multi_xml (~> 0.5)
+ multipart-post (~> 2.0.0)
+ plist (>= 3.1.0, < 4.0.0)
+ public_suffix (~> 2.0.0)
+ rubyzip (>= 1.3.0, < 2.0.0)
+ security (= 0.1.3)
+ simctl (~> 1.6.3)
+ slack-notifier (>= 2.0.0, < 3.0.0)
+ terminal-notifier (>= 2.0.0, < 3.0.0)
+ terminal-table (>= 1.4.5, < 2.0.0)
+ tty-screen (>= 0.6.3, < 1.0.0)
+ tty-spinner (>= 0.8.0, < 1.0.0)
+ word_wrap (~> 1.0.0)
+ xcodeproj (>= 1.8.1, < 2.0.0)
+ xcpretty (~> 0.3.0)
+ xcpretty-travis-formatter (>= 0.0.3)
+ fastlane-plugin-appcenter (1.7.1)
+ gh_inspector (1.1.3)
+ google-api-client (0.23.9)
+ addressable (~> 2.5, >= 2.5.1)
+ googleauth (>= 0.5, < 0.7.0)
+ httpclient (>= 2.8.1, < 3.0)
+ mime-types (~> 3.0)
+ representable (~> 3.0)
+ retriable (>= 2.0, < 4.0)
+ signet (~> 0.9)
+ google-cloud-core (1.4.1)
+ google-cloud-env (~> 1.0)
+ google-cloud-env (1.3.0)
+ faraday (~> 0.11)
+ google-cloud-storage (1.16.0)
+ digest-crc (~> 0.4)
+ google-api-client (~> 0.23)
+ google-cloud-core (~> 1.2)
+ googleauth (>= 0.6.2, < 0.10.0)
+ googleauth (0.6.7)
+ faraday (~> 0.12)
+ jwt (>= 1.4, < 3.0)
+ memoist (~> 0.16)
+ multi_json (~> 1.11)
+ os (>= 0.9, < 2.0)
+ signet (~> 0.7)
+ highline (1.7.10)
+ http-cookie (1.0.3)
+ domain_name (~> 0.5)
+ httpclient (2.8.3)
+ json (2.3.0)
+ jwt (2.1.0)
+ memoist (0.16.2)
+ mime-types (3.3)
+ mime-types-data (~> 3.2015)
+ mime-types-data (3.2019.1009)
+ mini_magick (4.9.5)
+ multi_json (1.14.1)
+ multi_xml (0.6.0)
+ multipart-post (2.0.0)
+ nanaimo (0.2.6)
+ naturally (2.2.0)
+ os (1.0.1)
+ plist (3.5.0)
+ public_suffix (2.0.5)
+ representable (3.0.4)
+ declarative (< 0.1.0)
+ declarative-option (< 0.2.0)
+ uber (< 0.2.0)
+ retriable (3.1.2)
+ rouge (2.0.7)
+ rubyzip (1.3.0)
+ security (0.1.3)
+ signet (0.12.0)
+ addressable (~> 2.3)
+ faraday (~> 0.9)
+ jwt (>= 1.5, < 3.0)
+ multi_json (~> 1.10)
+ simctl (1.6.6)
+ CFPropertyList
+ naturally
+ slack-notifier (2.3.2)
+ terminal-notifier (2.0.0)
+ terminal-table (1.8.0)
+ unicode-display_width (~> 1.1, >= 1.1.1)
+ tty-cursor (0.7.0)
+ tty-screen (0.7.0)
+ tty-spinner (0.9.2)
+ tty-cursor (~> 0.7)
+ uber (0.1.0)
+ unf (0.1.4)
+ unf_ext
+ unf_ext (0.0.7.6)
+ unicode-display_width (1.6.0)
+ word_wrap (1.0.0)
+ xcodeproj (1.13.0)
+ CFPropertyList (>= 2.3.3, < 4.0)
+ atomos (~> 0.1.3)
+ claide (>= 1.0.2, < 2.0)
+ colored2 (~> 3.1)
+ nanaimo (~> 0.2.6)
+ xcpretty (0.3.0)
+ rouge (~> 2.0.7)
+ xcpretty-travis-formatter (1.0.0)
+ xcpretty (~> 0.2, >= 0.0.7)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ fastlane (~> 2.137)
+ fastlane-plugin-appcenter
+
+BUNDLED WITH
+ 2.0.2
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..06779c6
--- /dev/null
+++ b/README.md
@@ -0,0 +1,38 @@
+# Visual Studio App Center Sample App for Android
+
+The Android application in this repository and its corresponding tutorials will help you quickly and easily onboard to Visual Studio App Center.
+
+## About this repository
+
+The App Center SDK modules are already integrated within the application. Simply follow the tutorials to learn how to use each service.
+
+### Build status (master branch)
+
+| Build Service | Status |
+| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| App Center | [](https://appcenter.ms) |
+| Azure Pipelines | [](https://dev.azure.com/msmobilecenter/Mobile-Center/_build/latest?definitionId=3725&branchName=master) |
+
+## Tutorials
+
+First navigate to the **Getting Started** tutorial linked below. After following that tutorial, you can choose which App Center service to explore.
+
+## Contents
+
+| Tutorial | Description |
+| ------------------------------------------------------------------------------------------------- | ------------------------------------------ |
+| [Getting Started](https://docs.microsoft.com/en-us/appcenter/quickstarts/android/getting-started) | Set up the app |
+| [Build](https://docs.microsoft.com/en-us/appcenter/quickstarts/android/build) | Build the app |
+| [Test](https://docs.microsoft.com/en-us/appcenter/quickstarts/android/test) | Run automated UI tests on real devices |
+| [Distribute](https://docs.microsoft.com/en-us/appcenter/quickstarts/android/distribute) | Distribute application to a group of users |
+| [Crashes](https://docs.microsoft.com/en-us/appcenter/quickstarts/android/crashes) | Monitor application crashes |
+| [Analytics](https://docs.microsoft.com/en-us/appcenter/quickstarts/android/analytics) | View user analytics |
+| [Push](https://docs.microsoft.com/en-us/appcenter/quickstarts/android/push) | Send push notifications to your app users |
+
+### Added functionality
+
+Using Gradle you can pass environment variables into your Build Configuration and use them as variables within your application.
+
+For more information on how to do so, visit our docs here: [Build time environment variables using Gradle](https://docs.microsoft.com/en-us/appcenter/build/custom/variables/#buildgradle-for-android)
+
+And if you want to try it out, you can fork this repository and add your App Secret by adding the APPCENTER_APP_SECRET environment variable in hte App Center Build configuration.
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/appcenter-post-build.sh b/app/appcenter-post-build.sh
new file mode 100644
index 0000000..5112da1
--- /dev/null
+++ b/app/appcenter-post-build.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+echo "This is an App Center Post-Build script. For more information on how to use App Center build scripts vist: https://docs.microsoft.com/en-us/appcenter/build/custom/scripts"
diff --git a/app/appcenter-post-clone.sh b/app/appcenter-post-clone.sh
new file mode 100644
index 0000000..a547ed0
--- /dev/null
+++ b/app/appcenter-post-clone.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+echo "This is an App Center Post-Clone script. For more information on how to use App Center build scripts vist: https://docs.microsoft.com/en-us/appcenter/build/custom/scripts"
diff --git a/app/appcenter-pre-build.sh b/app/appcenter-pre-build.sh
new file mode 100644
index 0000000..2f4cfcb
--- /dev/null
+++ b/app/appcenter-pre-build.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+echo "This is an App Center Pre-Build script. For more information on how to use App Center build scripts vist: https://docs.microsoft.com/en-us/appcenter/build/custom/scripts"
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..377b723
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,57 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+
+android {
+ compileSdkVersion 30
+ buildToolsVersion "29.0.2"
+ defaultConfig {
+ applicationId "ms.appcenter.sampleapp.android"
+ minSdkVersion 21
+ targetSdkVersion 30
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ // Obtain the value of APPCENTER_APP_SECRET environment variable from Build time.
+ buildConfigField("String", "APPCENTER_APP_SECRET", "\"\"")
+ if (System.getenv("APPCENTER_APP_SECRET") != null) {
+ buildConfigField("String", "APPCENTER_APP_SECRET", "\"${System.getenv("APPCENTER_APP_SECRET")}\"")
+ }
+ }
+ buildTypes {
+ release {
+ minifyEnabled true
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility = 1.8
+ targetCompatibility = 1.8
+ }
+}
+
+dependencies {
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation 'androidx.appcompat:appcompat:1.2.0'
+ implementation 'com.google.android.material:material:1.2.1'
+
+ def appCenterSdkVersion = '4.0.0'
+ implementation "com.microsoft.appcenter:appcenter-analytics:${appCenterSdkVersion}"
+ implementation "com.microsoft.appcenter:appcenter-crashes:${appCenterSdkVersion}"
+ implementation "com.microsoft.appcenter:appcenter-distribute:${appCenterSdkVersion}"
+
+ // Unit Testing
+ testImplementation 'androidx.test.ext:junit:1.1.2'
+
+ // Espresso UI Testing
+ androidTestImplementation 'androidx.test.ext:junit:1.1.2'
+ androidTestImplementation('androidx.test.espresso:espresso-core:3.3.0', {
+ exclude group: 'com.android.support', module: 'support-annotations'
+ })
+
+ androidTestImplementation('com.microsoft.appcenter:espresso-test-extension:1.4')
+ implementation "androidx.core:core-ktx:1.3.2"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
+repositories {
+ mavenCentral()
+}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..6f9f74b
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/tina/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/app/src/androidTest/java/ms/appcenter/sampleapp/android/ExampleInstrumentedTest.java b/app/src/androidTest/java/ms/appcenter/sampleapp/android/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..8e879f4
--- /dev/null
+++ b/app/src/androidTest/java/ms/appcenter/sampleapp/android/ExampleInstrumentedTest.java
@@ -0,0 +1,40 @@
+package ms.appcenter.sampleapp.android;
+
+import android.content.Context;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.Rule;
+import org.junit.After;
+import com.microsoft.appcenter.espresso.Factory;
+import com.microsoft.appcenter.espresso.ReportHelper;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Instrumentation test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Rule
+ public ReportHelper reportHelper = Factory.getReportHelper();
+
+ @After
+ public void TearDown() {
+ reportHelper.label("Stopping App");
+ }
+
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+ assertEquals("ms.appcenter.sampleapp.android", appContext.getPackageName());
+ }
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..ba1d86c
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png
new file mode 100644
index 0000000..f687dc8
Binary files /dev/null and b/app/src/main/ic_launcher-web.png differ
diff --git a/app/src/main/java/ms/appcenter/sampleapp/android/AnalyticsActivity.kt b/app/src/main/java/ms/appcenter/sampleapp/android/AnalyticsActivity.kt
new file mode 100644
index 0000000..2b8d27b
--- /dev/null
+++ b/app/src/main/java/ms/appcenter/sampleapp/android/AnalyticsActivity.kt
@@ -0,0 +1,59 @@
+package ms.appcenter.sampleapp.android
+
+import android.app.Dialog
+import android.content.DialogInterface
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
+import androidx.appcompat.app.AlertDialog
+import androidx.fragment.app.DialogFragment
+import androidx.fragment.app.Fragment
+import com.microsoft.appcenter.analytics.Analytics
+import java.util.*
+
+class AnalyticsActivity : Fragment() {
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View {
+ val rootView = inflater.inflate(
+ R.layout.analytics_root, container, false) as ViewGroup
+ val eventButton = rootView.findViewById