package com.example.sergey.notiremove import android.app.Activity import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent import android.content.ContentValues import android.content.Context import android.content.Intent import android.database.Cursor import android.database.sqlite.SQLiteDatabase import android.graphics.Color import android.os.Bundle import android.support.v4.app.NotificationCompat import android.support.v4.app.TaskStackBuilder import android.util.Log import android.view.View import android.view.View.OnClickListener import android.widget.Button class MainActivity : Activity(), OnClickListener { var channelId = "my_channel_01" // accommodate API >= 26 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // ---I deliberately left out onClick attributes in XML, to connect up the buttons // at runtime. This is excessive. Instead, just add android:onClick="onClick" // to the activity_main layout and remove the redundant OnClickListener from Activity. val b1 : Button = findViewById(R.id.button1) b1.setOnClickListener( { v: View -> this.onClick(v) } ) // spurious lambda, type checks; // can be converted to a reference, this::onClick // also not necessary if XML of Button 2 has onClick set as above val b2 : Button = findViewById(R.id.button2) b2.setOnClickListener(this) // ---end excessive code createChannel(channelId) } // This handler function is called for both buttons, but can distinguish // which one was pressed, by checking the ID of the View passed in as argument // (which will be either Button 1 or Button 2). override fun onClick(v: View) { Log.d("Notify", "onClick() called" + v.id.toString()) when (v.id) { R.id.button1 -> createAndGenerateNotifcation() R.id.button2 -> RemoveAllNotifications() } } fun createAndGenerateNotifcation() { Log.d("Notify", "createAndGenerateNotifcation() called") // This works for APIs >= 15, due to using NotificationCompat rather than Notification val mBuilder : NotificationCompat.Builder = NotificationCompat.Builder( this, channelId).setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Notification Title").setContentText("Body") mBuilder.setAutoCancel(true) // notification goes away if clicked val resultIntent = Intent() // See https://developer.android.com/training/notify-user/navigation.html val stackBuilder : TaskStackBuilder = TaskStackBuilder.create(this) stackBuilder.addNextIntent(resultIntent) val notiId : Long = System.currentTimeMillis() // use system time for IDs of notifications insertNotificationIntoDb(notiId) var resultPendingIntent : PendingIntent = stackBuilder.getPendingIntent(0, // 0 causes bugs on some systems! PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(resultPendingIntent) var mNotificationManager : NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager mNotificationManager.notify(notiId.toInt(), mBuilder.build()) } // This code uses a SQLite database to keep track of notification IDs persistently, // to cancel each one of them individually. // This is overkill, because notifications can be all cancelled at once with // cancelAll(). fun insertNotificationIntoDb(id: Long) { Log.d("Notify", "insetNotificationIntoDb() called") var mBase : DataBase = DataBase(this) var cValues : ContentValues = ContentValues() // what a SQL database query expects for a row cValues.put("noti_id", id); // values for this table's new row var db : SQLiteDatabase = mBase.getWritableDatabase() var i = db.insert("noti", null, cValues); Log.i("Insert", i.toString()) try { db.close(); } catch ( e : Exception) { Log.d("Exception", "caught exception in insertNotifi") } } fun RemoveAllNotifications() { var mBase : DataBase = DataBase(this); var cur : Cursor = mBase.getWritableDatabase().query("noti", null, null, null, null, null, null, null) cur.moveToFirst(); var mNotificationManager : NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager do { var id : Int = cur.getInt(0); mNotificationManager.cancel(id); } while (cur.moveToNext()); try { cur.close(); } catch ( e : Exception) { Log.d("Exception", "caught exception in RemoveAllNotification") } } private fun createChannel(id: String) { if (android.os.Build.VERSION.SDK_INT >= 26) { val mNotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // The user-visible name of the channel. val importance = NotificationManager.IMPORTANCE_LOW val mChannel = NotificationChannel(id, "Notify Channel", importance) // Configure the notification channel. mChannel.description = "My Notification Channel" mChannel.enableLights(true) // Sets the notification light color for notifications posted to this // channel, if the device supports this feature. mChannel.lightColor = Color.RED mChannel.enableVibration(true) mChannel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400) mNotificationManager.createNotificationChannel(mChannel) } } }