Imge: An app for physiologists – Part II

Imge: An app for physiologists – Part II

Kotlin

It’s a (almost!) 100% Kotlin app. This is my third app with Kotlin, after Owly and another one developed for a client. Needless to say, Kotlin is just great – deserves a dedicated article about why to choose it over Java.

Apart from 3 Java files, it’s all Kotlin!

Architecture - MVP

For several years, like many other Android developers, I prefered MVC as my primary architecture choice. However in last couple of years, again like many others, I moved to MVP which is proved to be very solid approach for Android app development.

My implementation for Imge app was very standard and straight-forward: Activities and Fragments as Views, Presenters for each, Model layer for entities and repositories to access Firebase API and other resources:

Model: Room as ORM

Room is a part of Android Architecture Components.It’s the object-relations-mapping library that makes it easy (and even fun) to work with Sqlite. I like Room as it makes my job much easier and the app more stable.

In the model layer I also have my entities, data-access-objects and repository classes for Database operations.

Views and Presenters

Well there is nothing interesting here. It’s the classic Views of MVP (activities and fragments in our case) and  presenter for each with the callback interfaces.

In App Billing

Users in the app uses credits to submit tests for a review. Credits are purchasable from the Google Play within the app. Imge uses Google’s In-App-Billing framework to  offer these credits as products.

Firebase as Backend service

App uses several Firebase features as a backend service. As I mentioned it many times before, I love Firebase! Without a so complete mobile backend system like Firebase, all projects would take at least 3x more since we would need to develop our own backend API.

Imge uses Firebase Database, Crashlytics, Analytics, Cloud messaging, Remote config, Firebase Storage and Authentication. Anything left? Ah Machine Learning service! We don’t use it (yet)!

DI - Dagger

Actually I’m not a big fan of Dagger but in this project I used Dagger heavily! It really helped me to save time and keep my files clean. There are so many objects that I reuse through the app so Dagger made sense for me. I used both field  and constructor injection.

RxJava for Android

I cannot image a data centric app without RxJava now. It makes developer’s life so easy that I admire RxAndroid every single time! 

I won’t go into the details of RxAndroid as there thousands of articles online. All I’ll say it RxAndroid did good job in my Repository classes. All data is loaded async and send back to the subscribers. That greatly helps to have a smooth user experience as at no time user is blocked with a heavy work on main thread.

Facebook and Google Sign-In

Lifesaver, simple. I cannot imagine any app user at the moment filling up a long (or even short) registration form with email address and password. I don’t, at least. 

The procedure is very standard for Facebook and Google Sign In so we you need to authenticate your users, you should definitely use these.

Stetho for inspecting the app (by Facebook)

I need to admit that I’m not a big fan of Facebook. No, it isn’t about failing an interview with them 🙂

However, stetho by Facebook is a true hero. It always saves me tons of time when it comes to debugging SQLite, SharedPreferences and UI problems.

If you haven’t tried it before, make sure you give it a go.

Stetho – massive help when it comes to hunting bugs around SQLite and SharedPref.

Other 3rd parties

It worth mentioning that I used several other libraries, most of which are quite standard for many developers:

  • Gson
  • Glide
  • Recycler view & Card view
  • Joda (yes, still!)
  • Stetho by Facebook

Let me know what you think!

Well these are the techs I used in Imge. I know I haven’t provided much insight about the details of usage of these libraries and services but still I would like to get some feedback!

What do you think? Are there better alternatives? What do you guys use in your projects? What are your must-have libs?

Thanks for reading!

Imge: An app for physiologists to analyse kid’s drawings – Part I

Imge: An app for physiologists to analyse kid’s drawings – Part I

This month I’m outsourced a project called Imge, an Android application for physiologists and parents.

Parents simply take a photo of their kid’s drawings and send it to a group of physiologists to analyse. Professionals analyse it, put their comments into the system and parents are notified about the results. Simple – and fun!

I didn’t know in the beginning but apparently there are some physiological tests like Goodenough–Harris Draw that is used to evaluate the children ‘for a variety of purposes’. The definition on Wiki for this particular test is:

The Draw-a-Person test (DAP, DAP test, or Goodenough–Harris Draw-a-Person test) is a psychological projective personality or cognitive test used to evaluate children and adolescents for a variety of purposes.
Wiki

So how does it work?

Sign-in with Google or Facebook
When app is launched, user is displayed the sign-in screen with a description of the app and a 30-second cartoon animation showing what the app is about. It’s in Turkish but if you’re interested, you can see it here:

User can sign-in either with Facebook or Google accounts. App makes the API call to get the user email, name and the public profile. That’s all we need.

Taking tests
Once signed-in, available tests are displayed along with the age group and detailed info. User needs credits to take the tests. App uses Google in-app-billing to offer several different products (bunch of credits). These can be purchased and consumed to take tests.

Submitting a test
After user decides which test she would like to take, she either takes a photo of the kid’s drawing or simply chooses one from the gallery. Then she fills a very short form and submits the drawing.

Physiologists notified
A physiologist is notified about the submission and after she carefully analyses it, another notification is sent to user to notify her that the analysis is completed. She launches the app, reads what the physiologist has to say.

Rating the physiologist & further therapy
After this point user can rate the physiologist and if happy with the service, they can take it further with a face-to-face therapy.

What’s coming?
We are adding dynamic content to the app so users can watch videos or read articles while waiting for the analysis of their kid’s drawings. These content will be highly related to the context of the app.

Screenshots

Here are some screenshots of the application.

In the second part I’ll talk about the technologies I used and the architecture of the app. Any questions, please just contact me! Thanks!

Lessons learnt: In Firebase Spark plan, simultaneous connections limit is 100!

Lessons learnt: In Firebase Spark plan, simultaneous connections limit is 100!

My latest Android app with Kotlin, Owly, displays one fact a day on your screen. Simple. The way I designed it is, a job is scheduled to work at 13:00 local time every day and when the job is triggered, it’s making a call to Firebase database to retrieve a Fact object to the device.

It all worked very well in the first week. Zero crash rate. Zero complaints. In the second week, I started getting emails saying that

App doesn’t show a new fact. All I see is the old ones!

I’m using Crashlytics for automatic bug reporting but wasn’t getting any reports. Then I checked logs and realized despite of making the call to Firebase database, application was not receiving any data!

After narrowing the issue down that much, I finally figured out what was wrong: I had 700+ active users and they were all trying to get the data from server at the same time (13:00)! When I was scheduling the job, I just didn’t think about the simultaneous connection limit of Firebase – which was only 100 in the Spark(free) plan. Therefore all connection requests after the 100th one was being refused.

Solution

Well the easiest solution could be upgrading to Blaze plan which was allowing 100.000 concurrent connections (when you pay $25 per month). What I did though was to change the fact retrieving time for users, setting a random time between 11am and 3pm:

That worked pretty well and we don’t have any issues at the moment. As expected, database connection went back to the desired levels, around 20 at a time:

Hope you remember to check your backend limits when you’re up to something. Price you pay for not doing so maybe a lot more than couple of uninstalls I had!

Icons made by Freepik from www.flaticon.com is licensed by CC 3.0 BY
Owly – A pet project in Kotlin (Part I)

Owly – A pet project in Kotlin (Part I)

What is it and Why?

Owly is a small Android application I developed in Kotlin, as a pet project. On a lazy Sunday afternoon my brother came up with the idea of an app that delivers a fact as a notification every day. OK, maybe not the most interesting or challenging idea out there but still a good start to actually do something with a brother.

Me & my brother: Who is the developer (guess who)?

He took the role of Product Owner (also responsible with marketing  & distribution) and I became the Kotlin developer (surprise surprise). My motivation behind it was obviously to learn Kotlin! I’ve been reading and reading about it for quite some time and was very interested & excited, just didn’t have any chance at work to try. Owly seemed like a good chance to get my hands dirty.

We started toying with the idea and drawing screens on papers. Even after all these years in professional app development, I’m still amazed with the fact that there are A LOT to discuss and decide even for such a (relatively) small app.

   

A fact delivered. Users can swipe left to see the images of the fact or scroll up and down to access the previously delivered facts. To vote a fact, users have like and dislike buttons (red and green smileys at the bottom).

5 Weeks of development: Evenings & some of the weekends only

Anyway we agreed on basics and I started my first Kotlin project. Within first week, we had a working concept that delivers the facts. The remaining 4 weeks were all about adding all that nice to haves, improvements (so to speak), a lot of “shall we use a lighter red colour here” s – well you probably know how it is. I’m a little bit crushed with the excitement and amateur soul of my brother – who is a physiologist by profession by the way (he runs a care home during the day).

After like 5 weeks, we were ready to publish the app. We published for Turkey only (where my brother resides) and started working on marketing right after. These days he’s quite busy with that but marketing is probably a topic for another post.

Well from my view of point project was very succesfull:

  • 87% of the code is in Kotlin which means I succeeded at what I aimed – learning Kotlin
  • Idea to market only in 5 weeks, working in the evenings and at some weekends only
  • Used tones of new stuff and improved my existing skills during the development
  • Maybe the most important part – I enjoyed working on it A LOT! So much fun

Technologies used

  • Developed with Kotlin (around 87% of the code)

  • Firebase as the backend: We used Realtime NoSQL database, Firebase authentication, Crashlytics and Firebase Analytics. Awesome stuff, very happy with it.
  • Async programming with Firebase API: Nice and smooth user experience through the application.
  • WorkManager, OneTimeWorkRequest and PeriodicWorkRequest to schedule the fact delivery in the most optimal way (awesome stuff, seriously!). No load on device processor.
  • Recyclerview and CardView for the facts. High performance scrolling, swiping fact cards to vote and remove from the deck.
  • Constraint layout for UI
  • User preferences: PreferenceFragment loading preferences xml from resources – nice, clean and ‘familiar’ preferences screen.
  • Multiple language support

Design patterns

Used MVVM, Observer Design Pattern, Singleton, Async development, Adapter pattern with the app.

Some screenshots

 

Part 2

In part 2, I’ll talk more about how Owly works, from a technical view of point.

 

Get it on Google Play

Fading overlay when swiping a RecyclerView item

Fading overlay when swiping a RecyclerView item

If you don’t know already, RecyclerView is a state-of-art library in Android SDK. You can do pretty much everything with RecyclerView.

In this article I’ll quickly show you how to overlay a fading View on top of a RecyclerView item, as seen below:

ItemTouchHelper.Callback

ItemTouchHelper is a useful callback that we attach to RecyclerView to learn about the item’s (row’s) movement. First thing we need to do is to create a callback variable:

private val itemTouchCallback = object : ItemTouchHelper.Callback() {
   // override the methods
}

This callback has the methods that I haven’t put here but below we’ll be implementing one of them. Now we need to attach our recycler view to an ItemTouchHelper that takes our itemTouchCallback as its callback:

val itemTouchHelper = ItemTouchHelper(simpleItemTouchCallback) 
itemTouchHelper.attachToRecyclerView(recyclerView)

Now our callback will notify us about any movements of the recyclerView items, including swiping right and left. Now let’s see the implementation of the callback:

private val itemTouchCallback = object : ItemTouchHelper.Callback() {
    override fun getMovementFlags(recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder?): Int {
        return makeMovementFlags(0, ItemTouchHelper.START or ItemTouchHelper.END)
    }

    override fun onMove(recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder?, target: RecyclerView.ViewHolder?): Boolean {
        return false
    }

    override fun onSwiped(viewHolder: RecyclerView.ViewHolder?, direction: Int) {

        if (direction == ItemTouchHelper.START)
            doSomething()
        else if (direction == ItemTouchHelper.END)
            doAnotherThing()
    }

    override fun onChildDraw(c: Canvas?, recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder?, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {
        val holder: FactViewHolder = viewHolder as FactViewHolder
        holder.likeImage.alpha = Math.max(if (dX > 0) dX / OPACITY_COEFFICIENT else OPACITY_MIN, OPACITY_MIN)
        holder.dislikeImage.alpha = Math.max(if (dX < 0) Math.abs(dX) / OPACITY_COEFFICIENT else OPACITY_MIN, OPACITY_MIN)
        holder.likeImage.invalidate()
        holder.dislikeImage.invalidate()

        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
    }
}

getMovementFlags

Override this method just to indicate what moves we’re interested in. In the code above we are returning START and END flags meaning we’re interested in user moving the items left and right.

onSwiped

Here do whatever you need to do depending on the swipe direction.

onChildDraw

Now this is the method we need! It’s fired each time children of the item are drawn. Here depending on the change in x direction (dX), we’re setting the alpha value of the like / dislike images. Then we invalidate them (not sure we need that invalidation, I’ll re-check!)

And the result is as seen in the image above. Pretty easy isn’t it?