Make a Timer App: Notifications (Ep 4) – Android Kotlin Tutorial (Code)

Learn how to create a beautiful material design timer app for Android.

In this course you will learn how to make a user interface. Later we’re going to code a timer which can run in the foreground. Then we are going to upgrade it to be able to run also in the background – and we will control it from notifications! Finally we will create a settings activity where a user will be able to set the length of the timer.

In the fourth part we’re creating notifications for when the timer is running, paused, or when it finishes. We also include the code which can control the timer right from the notifications!

 

This post contains all the code that’s been written in this YouTube video.

 

You can also check out this GitHub repository: https://github.com/ResoCoder/TimerAppAndroidTutorial

 

NotificationUtil.kt

 

TimerNotificationActionReceiver.kt

 

AppConstants.kt

 

AndroidManifest.xml

 

TimerExpiredReceiver.kt

 

TimerActivity.kt

 

Leave a comment


This site uses Akismet to reduce spam. Learn how your comment data is processed.


Martin

8 months ago

i use this in my app and it works perfect, but when i finish the 4th video it starts crashing when i put it in background.
it throws:

FATAL EXCEPTION: main
Process: com.martin.brewer, PID: 28546
java.lang.NoClassDefFoundError: Failed resolution of: Landroid/app/NotificationChannel;
at com.martin.brewer.util.NotificationUtil$Companion.createNotificationChannel(NotificationUtil.kt:123)
at com.martin.brewer.util.NotificationUtil$Companion.showTimerRunning(NotificationUtil.kt:65)
at com.martin.brewer.View.MainActivity.onPause(MainActivity.kt:92)
at android.app.Activity.performPause(Activity.java:6348)
at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1311)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3367)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3340)
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3315)
at android.app.ActivityThread.-wrap13(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1355)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.ClassNotFoundException: Didn’t find class “android.app.NotificationChannel” on path: DexPathList[[zip file “/data/app/com.martin.brewer-2/base.apk”],nativeLibraryDirectories=[/data/app/com.martin.brewer-2/lib/x86, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at com.martin.brewer.util.NotificationUtil$Companion.createNotificationChannel(NotificationUtil.kt:123) 
at com.martin.brewer.util.NotificationUtil$Companion.showTimerRunning(NotificationUtil.kt:65) 
at com.martin.brewer.View.MainActivity.onPause(MainActivity.kt:92) 
at android.app.Activity.performPause(Activity.java:6348) 
at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1311) 
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3367) 
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3340) 
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3315) 
at android.app.ActivityThread.-wrap13(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1355) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
Suppressed: java.lang.ClassNotFoundException: android.app.NotificationChannel
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
… 17 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available

Do you know how can i fix it?

Thanks
Martin

Martin

8 months ago

y comment this 3 lines [ nManager.createNotificationChannel(CHANNEL_ID_TIMER, CHANNEL_NAME_TIMER, true) ] and its works, do yo know why is crashing with them and how can i fix it?

here is the function:

@TargetApi(26)
private fun NotificationManager.createNotificationChannel(channelID: String, channelName: String, playSound: Boolean){
val channelImportance = if(playSound) {
NotificationManager.IMPORTANCE_DEFAULT
} else {
NotificationManager.IMPORTANCE_LOW
}
val nChannel = NotificationChannel(channelID, channelName, channelImportance)
nChannel.enableLights(true)
nChannel.lightColor = Color.BLUE
this.createNotificationChannel(nChannel)
}

Thanks!

Matej Rešetár

8 months ago

Hey! It seems that you’ve forgotten to check the version of the device / emulator.

Wrap the content of the provided function in this if statement: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) and it should work.

Are you using a pre-Oreo device to test your app?

Martin

8 months ago

It works!! thanks! I was using marshmallow, I do what you say and it works on it and in oreo too. Thank you very much for the tutorial and for helping me!

Development made simple

Your success is our success. If you have any questions, let us know.

Copyright 2017 - 2018 Reso Coder © All Rights Reserved