diff --git a/labs/Lab8_Alarms/.gitignore b/labs/Lab8_Alarms/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..ceff37eff0e621e8f96607f26a6bced4727fb5a5
--- /dev/null
+++ b/labs/Lab8_Alarms/.gitignore
@@ -0,0 +1,39 @@
+# built application files
+*.apk
+*.ap_
+
+# files for the dex VM
+*.dex
+
+# Java class files
+*.class
+
+# generated files
+bin/
+gen/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Eclipse project files
+.classpath
+.settings
+
+# Proguard folder generated by Eclipse
+proguard/
+
+# Intellij project files
+*.iml
+*.ipr
+*.iws
+.idea
+.idea/workspace.xml
+.gradle
+build/
+captures/
+
+# Mac files
+.DS_Store
+
+# Windows thumbnail db
+Thumbs.db
diff --git a/labs/Lab8_Alarms/Lab8_Alarms.pdf b/labs/Lab8_Alarms/Lab8_Alarms.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..dd94d7eeac71784455b37c99ce256fbb86921ff7
Binary files /dev/null and b/labs/Lab8_Alarms/Lab8_Alarms.pdf differ
diff --git a/labs/Lab8_Alarms/Lab8_AlarmsScreencast.mp4 b/labs/Lab8_Alarms/Lab8_AlarmsScreencast.mp4
new file mode 100644
index 0000000000000000000000000000000000000000..8a939982207f61d2a1aba090d9b38a6a416b439a
Binary files /dev/null and b/labs/Lab8_Alarms/Lab8_AlarmsScreencast.mp4 differ
diff --git a/labs/Lab8_Alarms/app/build.gradle b/labs/Lab8_Alarms/app/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..2040d1f966c325a9b21080d1abedb8d0cf1018a4
--- /dev/null
+++ b/labs/Lab8_Alarms/app/build.gradle
@@ -0,0 +1,30 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+
+android {
+    compileSdkVersion 26
+    buildToolsVersion '29'
+
+    defaultConfig {
+        applicationId "course.labs.alarmslab"
+        minSdkVersion 21
+        targetSdkVersion 26
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+        }
+    }
+}
+
+dependencies {
+    implementation 'com.android.support:support-v4:26.0.1'
+    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
+repositories {
+    mavenCentral()
+}
diff --git a/labs/Lab8_Alarms/app/src/main/AndroidManifest.xml b/labs/Lab8_Alarms/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..106ebc8e976afb89abf1106c2650721db2140d90
--- /dev/null
+++ b/labs/Lab8_Alarms/app/src/main/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="course.labs.alarmslab">
+
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@android:style/Theme.Holo.Light">
+        <activity
+            android:name="course.labs.alarmslab.AlarmCreateActivity"
+            android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <service android:name=".AlarmTweetService"></service>
+
+    </application>
+
+</manifest>
diff --git a/labs/Lab8_Alarms/app/src/main/java/course/labs/alarmslab/AlarmCreateActivity.kt b/labs/Lab8_Alarms/app/src/main/java/course/labs/alarmslab/AlarmCreateActivity.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c686b159c9e0e2d7f847ad326e8f16394f9b7447
--- /dev/null
+++ b/labs/Lab8_Alarms/app/src/main/java/course/labs/alarmslab/AlarmCreateActivity.kt
@@ -0,0 +1,52 @@
+package course.labs.alarmslab
+
+import android.app.Activity
+import android.app.AlarmManager
+import android.os.Bundle
+import android.view.View
+import android.widget.EditText
+
+class AlarmCreateActivity : Activity() {
+    private val mAlarmManager: AlarmManager? = null
+    private val mTweetTextView: EditText? = null
+    private val mDelayTextView: EditText? = null
+    private val mID: Int = 0
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState?: Bundle())
+        // TODO create reference to the AlarmManager using ALARM_SERVICE as well as locate necessary text views
+
+    }
+
+    fun set(v: View) {
+
+        val tweetText = mTweetTextView!!.text.toString()
+        val delay = Integer.parseInt(mDelayTextView!!.text.toString()) * 1000L
+
+        // TODO Create Intents for the alarm service. Also add the tweet as an extra to the Intent
+        // Additionally you will need to create a pending intent that will use the original intent
+        // you create to start the AlarmTweetService. Use the PendingIntent.getService() method. Be
+        // aware you will need to pass a unique value for the request code (why?) as well as the
+        // flag PendingIntent.FLAG_ONE_SHOT.
+
+
+        // TODO make log statement that tweet was sent to AlarmTweetService
+
+
+        // TODO use AlarmManager set method to set Alarm
+
+    }
+
+    fun clear(v: View) {
+        // TODO clear views
+
+    }
+
+    companion object {
+
+
+        val TWEET_STRING = "TWEET"
+
+        private val TAG = "AlarmCreateActivity"
+    }
+}
diff --git a/labs/Lab8_Alarms/app/src/main/java/course/labs/alarmslab/AlarmTweetService.kt b/labs/Lab8_Alarms/app/src/main/java/course/labs/alarmslab/AlarmTweetService.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6ad9e57cd9918f2149e6a9237ba7282752c888ec
--- /dev/null
+++ b/labs/Lab8_Alarms/app/src/main/java/course/labs/alarmslab/AlarmTweetService.kt
@@ -0,0 +1,294 @@
+package course.labs.alarmslab
+
+import android.app.Service
+import android.content.Intent
+import android.os.AsyncTask
+import android.os.IBinder
+import android.util.Base64
+import android.util.Log
+import android.widget.Toast
+
+import org.json.JSONException
+import org.json.JSONObject
+
+import java.io.BufferedReader
+import java.io.IOException
+import java.io.InputStreamReader
+import java.io.OutputStreamWriter
+import java.io.UnsupportedEncodingException
+import java.lang.StringBuilder
+import java.net.MalformedURLException
+import java.net.URL
+import java.net.URLEncoder
+import java.security.InvalidKeyException
+import java.security.Key
+import java.security.NoSuchAlgorithmException
+import java.security.SecureRandom
+
+import javax.crypto.Mac
+import javax.crypto.spec.SecretKeySpec
+import javax.net.ssl.HttpsURLConnection
+
+class AlarmTweetService : Service() {
+
+    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
+
+        if (intent.extras != null) {
+
+            mRandom = SecureRandom()
+
+            NetworkingTask().execute(intent.extras.getString(AlarmCreateActivity.TWEET_STRING))
+
+        }
+
+        return Service.START_STICKY
+    }
+
+    inner class NetworkingTask : AsyncTask<String, Void, Boolean>() {
+
+        override fun doInBackground(vararg args: String): Boolean? {
+            try {
+                return postTweet(args[0])
+            } catch (e: IOException) {
+                e.printStackTrace()
+                Log.d(TAG, "COULDN'T GET IT")
+            }
+
+            return false
+        }
+
+        override fun onPostExecute(result: Boolean?) {
+            Toast.makeText(applicationContext,
+                    "The Tweet was submitted with result:" + result!!,
+                    Toast.LENGTH_LONG).show()
+        }
+
+    }
+
+    override fun onBind(intent: Intent): IBinder? {
+        return null
+    }
+
+    companion object {
+        // The tweets would be visible at the twitter handle @UMDAndroid
+        // Notification ID to allow for future updates
+        private val TAG = "AlarmTweetService"
+
+
+        // Consumer Key
+        private val CONSUMER_KEY = "AwK1CjvJ9DMJlQf5bGLEW5uj0"
+
+        // Consumer Secret
+        private val CONSUMER_SECRET = "Vbynk2ka6wghFvVaWCLLl1vTpabNlehoPbdueXkPMPO7vr4Ojp"
+
+        // Access Token
+        private val ACCESS_TOKEN = "1187089419305672705-D5aYNVyKJHJmhOWrd19HHPjl14FVDh"
+
+        // Access Token Secret
+        private val ACCESS_TOKEN_SECRET = "0zEQJ9ekgJZ8tNDuTVKXFRs5p1BwTj1aSSoLKjCmZSzVn"
+
+        // networking variables
+        private var mRandom: SecureRandom? = null
+
+        @Throws(IOException::class)
+        private fun postTweet(status: String): Boolean {
+            var connection: HttpsURLConnection? = null
+            val nonce = newNonce()
+            val timestamp = timestamp()
+
+            try {
+
+                // URL for updating the Twitter status
+                val url = URL(
+                        "https://api.twitter.com/1.1/statuses/update.json")
+                
+                connection = url.openConnection() as HttpsURLConnection
+
+                connection.doOutput = true
+                connection.doInput = true
+
+                connection.requestMethod = "POST"
+
+                connection.setRequestProperty("Host", "api.twitter.com")
+                connection.setRequestProperty("User-Agent", "TwitterNetworkingLab")
+                connection.setRequestProperty("Authorization", "OAuth "
+                        + "oauth_consumer_key=\"" + CONSUMER_KEY + "\", "
+                        + "oauth_nonce=\"" + nonce + "\", " + "oauth_signature=\""
+                        + signature(status, nonce, timestamp) + "\", "
+                        + "oauth_signature_method=\"HMAC-SHA1\", "
+                        + "oauth_timestamp=\"" + timestamp + "\", "
+                        + "oauth_token=\"" + ACCESS_TOKEN + "\", "
+                        + "oauth_version=\"1.0\"")
+                connection.setRequestProperty("Content-Type",
+                        "application/x-www-form-urlencoded")
+
+                Log.d(TAG, connection.requestProperties.toString())
+
+                // This POST request needs a body
+                // This is how you write to the body
+
+                val out = OutputStreamWriter(
+                        connection.outputStream)
+
+                // Twitter status is added here.
+
+                out.write("status=" + URLEncoder.encode(status, "UTF-8"))
+
+                out.flush()
+                out.close()
+
+                val test = "status=" + URLEncoder.encode(status, "UTF-8")
+                Log.i(TAG, test)
+                val response = JSONObject(read(connection))
+
+                if (response != null) {
+                    Log.d(TAG, "The tweet seems to have been posted successfully!")
+                }
+
+                return response != null
+
+            } catch (e: MalformedURLException) {
+                throw IOException("Invalid URL.", e)
+            } catch (e: JSONException) {
+                throw IOException("Invalid response from Twitter", e)
+            } finally {
+                connection?.disconnect()
+            }
+        }
+
+        private fun read(connection: HttpsURLConnection): String {
+            val stringBuffer = StringBuffer()
+            try {
+                val reader = BufferedReader(InputStreamReader(
+                        connection.inputStream))
+                reader.forEachLine { stringBuffer.append(it+"\n") }
+
+            } catch (e: IOException) {
+                try {
+                    Log.i(TAG,
+                            "Error reponse from twitter: " + connection.responseMessage)
+                } catch (e1: IOException) {
+                    e1.printStackTrace()
+                }
+
+                stringBuffer.append("Failed")
+            }
+
+            return stringBuffer.toString()
+        }
+
+        private fun newNonce(): String {
+            val random = ByteArray(32)
+            mRandom!!.nextBytes(random)
+
+            var nonce = Base64.encodeToString(random, Base64.NO_WRAP)
+            nonce = nonce.replace("[^a-zA-Z0-9\\s]".toRegex(), "")
+            return nonce
+
+        }
+
+        private fun timestamp(): String {
+            val time = System.currentTimeMillis() / 1000L
+            return time.toString()
+        }
+
+        private fun signature(status: String, nonce: String,
+                              timestamp: String): String {
+            var status = status
+            var nonce = nonce
+            var timestamp = timestamp
+            var output = ""
+            // Obviously you can use a TreeMap with concurrency to implement this,
+            // but this way you can see what is going on
+            try {
+                // Gather all parameters used for the status post
+                var signatureBaseString = ""
+                var parameterString = ""
+                var signingKey = ""
+                var signature = ""
+
+                val httpMethod = "POST"
+                var baseURL = "https://api.twitter.com/1.1/statuses/update.json"
+
+                var consumerKey = CONSUMER_KEY
+                var encMethod = "HMAC-SHA1"
+                var token = ACCESS_TOKEN
+                var version = "1.0"
+
+                var kStatus = "status"
+                var kKey = "oauth_consumer_key"
+                var kNonce = "oauth_nonce"
+                var kSigMeth = "oauth_signature_method"
+                var kTimestamp = "oauth_timestamp"
+                var kToken = "oauth_token"
+                var kVersion = "oauth_version"
+
+                // encode the parameters put into the http request header separately
+                consumerKey = URLEncoder.encode(consumerKey, "UTF-8")
+                nonce = URLEncoder.encode(nonce, "UTF-8")
+                encMethod = URLEncoder.encode(encMethod, "UTF-8")
+                timestamp = URLEncoder.encode(timestamp, "UTF-8")
+                token = URLEncoder.encode(token, "UTF-8")
+                version = URLEncoder.encode(version, "UTF-8")
+                status = URLEncoder.encode(status, "UTF-8")
+                status = status.replace("+", "%20") // URLEncoder encodes " " to
+                // "+", which is incorrect
+                // for twitter encoding
+
+                kKey = URLEncoder.encode(kKey, "UTF-8")
+                kNonce = URLEncoder.encode(kNonce, "UTF-8")
+                kSigMeth = URLEncoder.encode(kSigMeth, "UTF-8")
+                kTimestamp = URLEncoder.encode(kTimestamp, "UTF-8")
+                kToken = URLEncoder.encode(kToken, "UTF-8")
+                kVersion = URLEncoder.encode(kVersion, "UTF-8")
+                kStatus = URLEncoder.encode(kStatus, "UTF-8")
+
+                // append the parameters together with = and &
+                parameterString = (kKey + "=" + consumerKey + "&" + kNonce + "="
+                        + nonce + "&" + kSigMeth + "=" + encMethod + "&"
+                        + kTimestamp + "=" + timestamp + "&" + kToken + "=" + token
+                        + "&" + kVersion + "=" + version + "&" + kStatus + "="
+                        + status)
+
+                // build the signature base string
+                signatureBaseString += httpMethod
+                signatureBaseString += "&"
+                baseURL = URLEncoder.encode(baseURL, "UTF-8")
+                signatureBaseString += baseURL
+                signatureBaseString += "&"
+                parameterString = URLEncoder.encode(parameterString, "UTF-8")
+                signatureBaseString += parameterString
+                Log.d(TAG, signatureBaseString)
+
+                // generate the HMAC-SHA1 signing key with the application and
+                // account secrets
+                signingKey = (URLEncoder.encode(CONSUMER_SECRET, "UTF-8") + "&"
+                        + URLEncoder.encode(ACCESS_TOKEN_SECRET, "UTF-8"))
+
+                // this should be self explanatory
+                val bytes = signingKey.toByteArray()
+                val key = SecretKeySpec(bytes, 0, bytes.size, "HmacSHA1")
+                val mac = Mac.getInstance("HmacSHA1")
+                mac.init(key)
+                val signatureBytes = mac.doFinal(signatureBaseString.toByteArray())
+                signature = Base64.encodeToString(signatureBytes, Base64.NO_WRAP)
+                signature = URLEncoder.encode(signature, "UTF-8")
+
+                output = signature
+
+            } catch (e: UnsupportedEncodingException) {
+                Log.d(TAG, "Error encoding parameters")
+                e.printStackTrace()
+            } catch (e: InvalidKeyException) {
+                Log.d(TAG, "Error encrypting signature")
+                e.printStackTrace()
+            } catch (e: NoSuchAlgorithmException) {
+                Log.d(TAG, "Invalid algorithm for signature")
+                e.printStackTrace()
+            }
+
+            return output
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/labs/Lab8_Alarms/app/src/main/res/layout/main.xml b/labs/Lab8_Alarms/app/src/main/res/layout/main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f6b96bb342d99366d23262f0dbe0320aea660e2e
--- /dev/null
+++ b/labs/Lab8_Alarms/app/src/main/res/layout/main.xml
@@ -0,0 +1,79 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_vertical_margin"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    tools:context=".AlarmCreateActivity" >
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/title"
+        android:paddingBottom="5dp"
+        android:textSize="20sp" />
+
+    <EditText
+        android:id="@+id/text"
+        android:layout_width="match_parent"
+        android:layout_height="50dp"
+        android:hint="@string/placeholder"
+        android:inputType="textMultiLine" >
+
+        <requestFocus />
+    </EditText>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" 
+        android:paddingTop="25dp">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/prompt" />
+
+        <EditText
+            android:id="@+id/time"
+            android:layout_width="15dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:ems="10"
+            android:inputType="number"
+            android:minLines="1"
+            android:text="@string/placeholder2" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/prompt2" />
+    </LinearLayout>
+    
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal"
+        android:orientation="horizontal"
+        android:paddingTop="25dp" >
+	    
+	    <Button
+	        android:id="@+id/set"
+	        android:layout_width="wrap_content"
+	        android:layout_height="wrap_content"
+	        android:text="@string/button"
+	        android:onClick="set" />
+	    
+	    <Button
+	        android:id="@+id/clear"
+	        android:layout_width="wrap_content"
+	        android:layout_height="wrap_content"
+	        android:text="@string/clear"
+	        android:onClick="clear" />
+	
+	</LinearLayout>
+
+</LinearLayout>
diff --git a/labs/Lab8_Alarms/app/src/main/res/menu/alarm_create.xml b/labs/Lab8_Alarms/app/src/main/res/menu/alarm_create.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c00202823049e8d5b1590e1223f20fef8a966353
--- /dev/null
+++ b/labs/Lab8_Alarms/app/src/main/res/menu/alarm_create.xml
@@ -0,0 +1,9 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:id="@+id/action_settings"
+        android:orderInCategory="100"
+        android:showAsAction="never"
+        android:title="@string/action_settings"/>
+
+</menu>
diff --git a/labs/Lab8_Alarms/app/src/main/res/mipmap-hdpi/ic_launcher.png b/labs/Lab8_Alarms/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..288b66551d1efd1f13dd06f20a67534d2df57946
Binary files /dev/null and b/labs/Lab8_Alarms/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/labs/Lab8_Alarms/app/src/main/res/mipmap-mdpi/ic_launcher.png b/labs/Lab8_Alarms/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..6ae570b4db4da165fada0650079061cb56aa8793
Binary files /dev/null and b/labs/Lab8_Alarms/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/labs/Lab8_Alarms/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/labs/Lab8_Alarms/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..d4fb7cd9d868f1d7d9964f1686dcbc018ef9495a
Binary files /dev/null and b/labs/Lab8_Alarms/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/labs/Lab8_Alarms/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/labs/Lab8_Alarms/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..85a6081587e2c2b9793d796ee7b07e12fdf860db
Binary files /dev/null and b/labs/Lab8_Alarms/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/labs/Lab8_Alarms/app/src/main/res/raw/alarm_rooster.mp3 b/labs/Lab8_Alarms/app/src/main/res/raw/alarm_rooster.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..62b05ca9b3cae17e9b08e205a680ab70b7615728
Binary files /dev/null and b/labs/Lab8_Alarms/app/src/main/res/raw/alarm_rooster.mp3 differ
diff --git a/labs/Lab8_Alarms/app/src/main/res/values/dimens.xml b/labs/Lab8_Alarms/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000000000000000000000000000000000000..55c1e5908c7e0f157fe815acd6d5cd7358463390
--- /dev/null
+++ b/labs/Lab8_Alarms/app/src/main/res/values/dimens.xml
@@ -0,0 +1,7 @@
+<resources>
+
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+
+</resources>
diff --git a/labs/Lab8_Alarms/app/src/main/res/values/strings.xml b/labs/Lab8_Alarms/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d01d372858fb0a38bd0f1029ba1440ac7813fb92
--- /dev/null
+++ b/labs/Lab8_Alarms/app/src/main/res/values/strings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">AlarmsLab</string>
+    <string name="action_settings">Settings</string>
+    <string name="title">Change your Twitter Status</string>
+    <string name="placeholder">tweet goes here.</string>
+    <string name="prompt">To post in</string>
+    <string name="prompt2">seconds</string>
+    <string name="placeholder2">5</string>
+    <string name="button">Submit</string>
+    <string name="clear">Clear</string>
+
+</resources>
diff --git a/labs/Lab8_Alarms/app/src/main/res/values/styles.xml b/labs/Lab8_Alarms/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6ce89c7ba4394d8cab27953d41456ce234ca37c3
--- /dev/null
+++ b/labs/Lab8_Alarms/app/src/main/res/values/styles.xml
@@ -0,0 +1,20 @@
+<resources>
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Light">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="AppBaseTheme">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+
+</resources>
diff --git a/labs/Lab8_Alarms/build.gradle b/labs/Lab8_Alarms/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..4b8b998d603537228a78784e61d0c147c0d113b4
--- /dev/null
+++ b/labs/Lab8_Alarms/build.gradle
@@ -0,0 +1,22 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+    ext.kotlin_version = '1.3.50'
+    repositories {
+        jcenter()
+        google()
+        maven {
+            url "https://maven.google.com"
+        }
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:3.1.4'
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+    }
+}
+
+allprojects {
+    repositories {
+        jcenter()
+        google()
+    }
+}
diff --git a/labs/Lab8_Alarms/gradle/wrapper/gradle-wrapper.jar b/labs/Lab8_Alarms/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..13372aef5e24af05341d49695ee84e5f9b594659
Binary files /dev/null and b/labs/Lab8_Alarms/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/labs/Lab8_Alarms/gradle/wrapper/gradle-wrapper.properties b/labs/Lab8_Alarms/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..e048a29550871928bc478c253d1d3fd963b14cf1
--- /dev/null
+++ b/labs/Lab8_Alarms/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Tue Oct 09 14:30:26 EDT 2018
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
diff --git a/labs/Lab8_Alarms/gradlew b/labs/Lab8_Alarms/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..9d82f78915133e1c35a6ea51252590fb38efac2f
--- /dev/null
+++ b/labs/Lab8_Alarms/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/labs/Lab8_Alarms/gradlew.bat b/labs/Lab8_Alarms/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..8a0b282aa6885fb573c106b3551f7275c5f17e8e
--- /dev/null
+++ b/labs/Lab8_Alarms/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/labs/Lab8_Alarms/settings.gradle b/labs/Lab8_Alarms/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..e7b4def49cb53d9aa04228dd3edb14c9e635e003
--- /dev/null
+++ b/labs/Lab8_Alarms/settings.gradle
@@ -0,0 +1 @@
+include ':app'