PacktPub is one of the great ebook and videos site for tech users and they offer one free ebook everyday. Most of the time, i forget to visit the site so i missed lot of free good ebooks and regret it later. So, i decided to create a weekend side project to explore kotlin language and also to refresh my android skills by understanding latest andriod O background processing limitations.
It took some time to understand the basic kotlin language concepts (like companion objects, null safety) but its a good oppertunity for .Net developers to explore this language rather than coding in java for android apps. Kotlin also provides some real good extensions plugins to eliminate lot of boilerplate android code like findviewbyid.
Application Overview
This app launches the main activity with asynctask in background to parse the content to get the free ebook title, image url and render it on the main activity. It also check the site periodically (based on settings) and notify the user.
I have created AlarmManagerHelper class to set the repeating alarm based on the sync frequency settings. The Sync Frequency Settings are stored in SharedPreferences.
internalclassAlarmManagerHelper(ctx: Context) : ContextWrapper(ctx) { funsetBroadCastAlert(argRefreshAlarm: Boolean) { var refreshAlarm = argRefreshAlarm val alarmManager = this.getSystemService(Activity.ALARM_SERVICE) as AlarmManager val notificationIntent = Intent(Constants.ALARM_RECEIVER_INTENT_TRIGGER) notificationIntent.setClass(this, NotificationReceiver::class.java) var pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_NO_CREATE) if (pendingIntent == null) { pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT) refreshAlarm = true } if (refreshAlarm) { val syncFrequency: String by DelegatesExt.preference(this, Constants.SYNC_FREQUENCY_NAME, Constants.SYNC_FREQUENCY_DEFAULT_VALUE) val syncFrequencyLong = syncFrequency.toLong() var finalCalInMillis: Long = System.currentTimeMillis() + (syncFrequencyLong * AlarmManager.INTERVAL_HOUR) alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, finalCalInMillis, (syncFrequencyLong * AlarmManager.INTERVAL_HOUR) , pendingIntent) } } }
From Android O, there are lot of limitations on background execution limits and you can read all those details in android developer guide. For this project, i need a background job that should run periodically based on frequency settings defined in the app and send the notification to user with the book title. I used JobIntentService to do the background work and send the notification to user
I used Jsoup Library to parse the HTML content. Jsoup is a Java library for working with real-world HTML. It provides a very convenient API for extracting and manipulating data, using the best of DOM, CSS, and jquery-like methods.
internalclassParserHelper(ctx: Context) : ContextWrapper(ctx) { privateval tag: String = "ParserHelper" dataclassParserEntity(val title: String, val imageURL: String?) funparsePacktPubFreeBook(): ParserEntity { var title = "Internet access not available" var imageURL: String? = null if (isInternetConnected()) { try { val htmlContent = Jsoup.connect(getString(R.string.FREE_BOOK_URL)).get() title = htmlContent.select("div[class=dotd-title]").text() imageURL = "http:" + htmlContent.select("img[class=bookimage imagecache imagecache-dotd_main_image]").attr("src") } catch (e: Exception) { Log.e(tag, "Error in fetching the content " + e.printStackTrace()) } } return ParserEntity(title, imageURL) } privatefunisInternetConnected(): Boolean { val cm = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val activeNetwork = cm.activeNetworkInfo return activeNetwork != null && activeNetwork.isConnectedOrConnecting } }
So, overall this project will give you the idea of how to develop an android app in kotlin including running the background job and send the notitfication to users. I have uploaded the entire source code in github.