Implementing the discrete Seekbar for Wave Generator

The Wave Generator instrument in PSLab Android app allows us to produce waveforms having different values of properties like frequency, duty, phase etc.

The range of these properties allowed by PSLab Device are :

Table showing the range of properties that can be set for waves by PSLab device
Wave Property Range
Min Max Step Size
Frequency 10 Hz 5000 Hz 1 Hz
Phase 360°
Duty 10% 100% 10%

We can set these values using the up/down arrow buttons provided by the wave generator but the problem is that the range of values is very high and least counts are small so it is convenient to set the values using only the up and down arrow buttons.

Therefore we need something that could allow us to directly set any value of our choice while keeping the UI interactive.

The solution to this problem – “Discrete Seekbar”. It contains a slider having points at equal intervals and whose length represents the range of the values and a head that slides over the slider and is used to select a specific value from a range of values.

I have included the discrete Seekbar in Wave Generator by using a third-party library if you want to add Seekbar directly you can do that by directly using the default Seekbar widget provided by Android SDK and setting the following attribute in as shown below.

android:theme = “@style/Widget.AppCompat.SeekBar.Discrete”

Refer to this post[2] for implementing Seekbar directly without an external library.

The reason I chose this library is that:-

  • It offers various implementation of different types of Seekbar like discrete and continuous.
  • Implementation of Seekbar is simpler and it offers various customizations like thumb color, track color, tick text etc.  

In following steps I will implement the discrete Seekbar:

Step 1 Adding the dependency

For this project, I will be using an external library “IndicatorSeekbarLibrary” by Warkiz[1], for adding the dependency we need to include the following code in our build.gradle file.

implementation 'com.github.warkiz.widget:indicatorseekbar:2.0.9'

Step 2 Including the Seekbar in layout

For this step, we need to add the Seekbar widget using <com.warkiz.widget.IndicatorSeekBar> XML tag in our wave generator layout file to include the Seekbar in our layout as shown in the code below:

    app:isb_track_progress_size="4dp" />

Some important attributes used above:

app:isb_max : defines the max value that can be achieved by the Seekbar.

app:isb_min :  defines the min value that can be achieved by the Seekbar

app:isb_ticks_count: no. of ticks(interval) that has to be shown on the slider

We can see different components of Seekbar like track, indicator, thumb, tick of SeekBar in the following diagram[2].

Figure 1 depicts the different attributes of the slider
(Source –

Step 3 Attaching the listener to the Seekbar in Java file

In this step we need to attach the listener to the Seekbar to record changes in the Seekbar made by the user, for this we will create a new listener with the help of onSeekBarChangeListener interface and attach it with the Seekbar as shown in following code

IndicatorSeekBar seekbar = (IndicatorSeekBar) findViewbyId(;

seekBar.setOnSeekChangeListener(new OnSeekChangeListener() {
            public void onSeeking(SeekParams seekParams) {
                /* called when the user is sliding the thumb */

            public void onStartTrackingTouch(IndicatorSeekBar seekBar) {
                /* called when the sliding of thumb is started */

            public void onStopTrackingTouch(IndicatorSeekBar seekBar) {
                /* called when the sliding of thumb stops */

After following all the above steps, I  implemented the Seekbar shown in Figure 2 below in my wave generator and now it becomes really easy to set different values of properties for without having to continually press the up/down button.

Figure 2 shows the Seekbar included in wave generator beside up/down arrow button


  1. warkiz/IndicatorSeekBar library  – Github Repo of the Indicator SeekBar library
  2. – Blog by Nilesh Shenta on how to implement discrete without third party library


Integrating Forgot Password feature within Login Screen in SUSI Android App

For a user’s point of view the interface and the flow of the app is of great importance, the UI of the app should be simple and sufficient so that it does not confuse the user and provides all the necessary information to the user with the first look. In all the  apps it is the user interface that engages the user and makes the user want to use the app. So, in SUSI Android app UI flow was improved by removing the Forgot Password activity altogether.

What SUSI.AI android app previously had ?

Previously the SUSI.AI android app used to have three different screens for the user’s account related support :

  1. Login Screen
  2. Forgot Password Screen
  3. SignUp Screen    

The login screen had a Forgot Password? Option that takes the user to a new screen where the details entered in the login activity had to be entered again and only then can the user request a new password.

What are the drawbacks of this ?

Separately, providing a new activity for the specific purpose of resetting the password does not contribute towards an efficient use of UI items of the screen. A scenario where this will be annoying to the user is for eg :  when a user tries to login to the app and is unable to do so because of the incorrect credentials, user simply clicks on the Forgot Password option and on opening the Forgot Password activity to the user’s surprise all the fields entered in the login screen are to be entered again and this is really fuzzy and sometimes frustrating to the user.

A simple solution implemented for this purpose was to automatically reflect the credentials entered by the user in the login screen on the forgot password screen so  that user did not had to enter all the details again.

What better could be done and the solution?

The simplest UI for the purpose of resetting a password is to just click the Forgot Password? and user receives an email to reset the password.

Using this approach several changes were made to the app’s code.

The first change to be made was to implement the ForgotPasswordPresenter.kt functions in the LoginPresenter.kt and similarly implement the IForgotPasswordView.kt functions in the LoginActivity.kt.

The two major functions in the  IForgotPasswordPresenter.kt were :

fun requestPassword(email: String, url: String, isPersonalServerChecked: Boolean)

fun cancelSignup()

Along with these functions in the LoginPresenter.kt the view functions to reflect the view actions of the ForgotPasswordActivity.kt had to be implemented in the LoginActivity.kt file, so the functions added to the ILoginView.kt file were :

fun showForgotPasswordProgress(boolean: Boolean)

fun resetPasswordSuccess()

fun resetPasswordFailure(title: String?, message: String?, button: String?, color: Int)

Now, the two functions above which were earlier present in the ForgotPasswordPresenter.kt file were implemented in the LoginPresenter.kt file and along with the requestPassword() method the listener IForgotPasswordModel.OnFinishListener had to be implemented in the Login Presenter too. So, on implementing this listener we implement a method :

override fun onForgotPasswordModelSuccess(response: Response<ForgotPasswordResponse>) {
  if (response.isSuccessful && response.body() != null) {
  } else if (response.code() == 422) {
      loginView?.resetPasswordFailure(utilModel.getString(R.string.email_invalid_title), utilModel.getString(R.string.email_invalid), utilModel.getString(R.string.retry), Color.RED)
  } else {
      loginView?.resetPasswordFailure(“${response.code()} “ + utilModel.getString(R.string.error), response.message(), utilModel.getString(R.string.ok), Color.BLUE)


Now after implementing these methods in Presenter file we have to implement the methods. The function resetPasswordSuccess() works as :

override fun resetPasswordSuccess() {

On successful request for the password from the server the above method in the activity is called and so it takes us to the new activity. The new activity  only contains a simple screen with a default message :

The above screen is the final output once we click on Forgot Password? on the login screen.

References :

Trying to Build Android MVP App in Kotlin – Eminarti Sianturi

Build a Responsive UI with constraint layout


How the presenter and view interact in the MVP pattern


Creating Control Panel For Wave Generator using Constraint Layout


In the blog Creating the onScreen Monitor Using CardView I had created the monitors to view the wave properties in this blog we will create the UI of controlling panel that will be used for that monitors with multiple buttons for both analog and digital waveforms.

Which layout to choose?

In today’s world, there are millions of Android devices present with different screen sizes and densities and the major concern of an Android developer is to make the layout that fits all the devices and this task is really difficult to handle with a linear or relative layout with fixed dimensions.

To create a complex layout with lots of views inside the parent using linear layout we have to make use of the attribute layout_weight for their proper stretching and positioning, but such a complex layout require a lot of nesting of weights and  android tries to avoid it by giving a warning :

Nested Weights are bad for performance

This is because layout_weight attribute requires a widget to be measured twice[1]. When a LinearLayout with non-zero weights is nested inside another LinearLayout with non-zero weights, then the number of measurements increases exponentially.

So, to overcome this issue we will make use of special type of layout “Constraint Layout” which was introduced in Google I/O 2016.

Features of Constraint Layout:-

  • It is similar to Relative Layout as all views are laid out according to their relationship with the sibling, but it is more flexible than Relative Layout.
  • It helps to flatten the view hierarchy for complex layouts.
  • This layout is created with the help of powerful tool provided by Android which has a palette on the left-hand side from where we can drag and drop the different widgets like TextView, ImageView, Buttons etc. and on the right-hand side it provides options for positioning, setting margins and other styling option like setting color, change text style etc.
  • It automatically adjusts the layout according to the screen size and hence doesn’t require the use of layout_weight attribute.

In following steps, I will create the controlling panel for Wave generator which is a complex layout with lots of buttons with the help of constraint layout.

Step 1: Add the dependency of the Constraint Layout in the Project

To use Constraint layout add the following to your build.gradle file and sync the project

dependencies {
    implementation ""

Step 2: Applying Guidelines to the layout

Guidelines[3] are anchors that won’t be displayed in your app, they are like one line of a grid above your layout and can be used to attach or constraint your widgets to it. They are only visible on your blueprint or preview editor. These will help to position and constraint the UI components on the screen easily.

For adding guidelines :

As shown in Figure 1 Right-click anywhere on the layout -> Select helpers -> Select horizontal or vertical guideline according to your need.

Figure 1 shows the horizontal guideline being added to the layout.

And for positioning the guideline we have to set the value of attribute layout_constraintGuide_percent  

Let’s say we want the guideline to be at the middle of the screen so we’ll set :


For my layout I have added three guideline :

  • One horizontal guideline at 50%
  • Two vertical guidelines at 30% and 65%

Doing this will bifurcate the screen into six square blocks as shown in below figure :

Figure 2 shows the blueprint of constraint layout containing two vertical and one horizontal guidelines with their percentage offset from respective bases

Step 3: Adding the buttons in the blocks

Until now we have created six squares blocks, now we have to put a button view in each of the boxes.

  • First drag and drop button view from the Palette (shown in Figure 3) on the left side inside the box.

    Figure 3 shows the layout editor palette


  • Then we have to set constraints of this button by clicking on the small circle present on the middle of edges and dragging it onto the side of the block facing it.

    Figure 4 shows the button widget getting constrained to sides


  • Set the layout_width and layout_height attribute of the button to be “0dp”, doing this the button will expand in all the direction occupying all the space with respect to the border it has been constrained with.

    Figure 6 shows the button widget expanding to all the available space in the box

Similarly, adding buttons in all the square blocks and providing proper theme color we will have a blueprint and layout as shown in Figure 6.

Figure 6 shows the waveform panel blueprint and actual layout for analog waves with six buttons

Following the same steps until now, I have created the other controlling panel layout having buttons for digital waves as shown in Figure 7

Figure 7 shows other constraint layout for digital waves having seven buttons

Detailing and combining the panels to form Complete UI

After adding both the panels we have created in this layout inside the Wave Generator we have the layout as shown in Figure 8

Figure 8 shows the UI of Wave Generator as shown by a actual Android device in the PSLab app.

As we can see on adding the panels the button created inside the layout shrink so as to adapt to the screen and giving out a beautiful button-like appearance.


  1. Blog on Nested Weights are bad for performance
  2. Developer Article – Build a Responsive UI with ConstraintLayout
  3. Information about Guidelines

Post feedback for SUSI Skills in SUSI iOS

SUSI iOS, web and Android clients allow the user to rate the SUSI Skills in a 5-star rating system. Users can write about how much particular skill is helpful for them or if improvements are needed. Users can rate skills from one to five star as well. Here we will see how to submit feedback for SUSI skills and how it is implemented on SUSI iOS.

How to submit feedback –

  1. Go to Skill Listing Screen < Skill Detail Screen
  2. Scroll to the feedback section
  3. Write feedback about SUSI skill
  4. Click on POST button to post the skill feedback

An anonymous user can not submit skill feedback. You must have to logged-in in order to post skill feedback. If you are not logged-in and click POST button to post skill feedback, an alert is presented with Login option, by clicking Login, the user is directed to Login screen where the user can log in and later can post skill feedback.

Implementation of posting skill feedback –

Google’s Material textfield is used for skill feedback text field. We have assigned TextField class from Material target to skill feedback text field to make it very interactive and give better user experience.

Skill feedback text field in the normal state –

Skill feedback text field in the active state –

When the user clicks POST after writing skill feedback, we check if the user is logged-in or not.

if let delegate = UIApplication.shared.delegate as? AppDelegate, let user = delegate.currentUser {

We have saved the logged-in user globally using AppDelegate shared method during login and using it here. The AppDelegate is sort of like the entry point for the application. It implements UIApplicationDelegate and contains methods that are called when application launches, when is going to the background (i.e. when the user hit the home key), when it’s opened back up, and more. The AppDelegate object is stored as a property on the UIApplication class and is accessible from anywhere in swift classes.

Case 1: If the user is not logged-in, we show a popup to the user with the login option

By clicking Login, the user is directed to Login screen where the user can log in and later can post skill feedback.

Case 2: If the user is already logged-in, we use the endpoint below for posting skill feedback –

ModelWith following parameters –

  • Group
  • Skill
  • Feedback
  • Access token
Client.sharedInstance.postSkillFeedback(postFeedbackParam) { (feedback, success, responseMessage) in
DispatchQueue.main.async {
if success {
self.skillFeedbackTextField.text = ""
} else {

In return response, we get feedback posted by the user –

feedback: "Helpful",
accepted: true,
message: "Skill feedback updated"


Resources –

  1. Material Design Guidelines for iOS
  2. Apple’s documentation on UIApplicationDelegate API
  3. Apple’s documentation on UIApplication API
  4. ChrisRisner’s article on Singletons and AppDelegate

Creating Device Screen to show connection status of PSLab Device

For using the PSLab Device the user needs to connect the PSLab device to an Android Phone having a PSLab android app. So there should be a screen that should be able to show the proper status of the PSLab device connection to the android app dynamically and it should also contain instructions on “How to connect the device to the app”.

So, in this blog we will create a device screen which shows the proper status of the connection of the PSLab device with the phone.

First step will be designing the layout for the device screen, for this we will create a fragment named HomeFragment and for its layout we will make use of the Relative Layout as view group and then create a Linearlayout inside it and position it at the center so that it always appears at the center in different screen sizes.

Then inside the LinearLayout, we will create(as shown in respective order) :

  1. ImageView and TextView for showing the status of device connection.
  2. Linear Layout with multiple TextView showing instructions on “How to connect the device to the screen”.
  3. A TextView that will direct the user to a webview showing PSLab website.

After creating all the above views we have created the layout will look like this: –

Now for showing the PSLab connection status dynamically, we have to implement following logic:

  1. When the device is connected it should show the connected icon and text and hide the instructions.
  2. When the device is disconnected it should show the disconnected icon and text and also the instructions.

For this, we will create a method inside the HomeFragment Java file which make use of Arguments deviceConnected and deviceFound to store device connected status.

public static HomeFragment newInstance(boolean deviceConnected, boolean deviceFound) {
HomeFragment homeFragment = new HomeFragment();
homeFragment.deviceConnected = deviceConnected;
homeFragment.deviceFound = deviceFound;
return homeFragment;

When both arguments are true we will show the connected text and icon and hide the instructions.

And when both arguments are false we will show the disconnected text and icon and display the instructions.

if (deviceFound && deviceConnected) {
} else {

How do we know that the device is connected?

For this, we have to handle the USB Attach event [1] that is whenever the USB is connected the Android will give a broadcast of USB connected and on receiving that broadcast in the app we will replace the HomeFragment giving setting both arguments to true. 

We will create a Broadcast Receiver[2] in the main activity which executes it’s onReceive() method on receiving USB attach event.

private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
   public void onReceive(Context context, Intent intent) {
     String action = intent.getAction();
     if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
       UsbDevice device =  intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
           HomeFragment.newInstance(true, true)).commitAllowingStateLoss();

Here In the OnReceive Method, we will replace our device screen fragment by passing parameters deviceConnected = true and deviceFound = true to HomeFragment newInstance() method.

Every time we create a Receiver we have to bind corresponding intent filters with broadcast receivers when the application is created.

IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED);
registerReceiver(mUsbReceiver, filter);

Similarly, we also have to handle the USB Detach event [2], here we will create a Broadcast Receiver[2] which executes in onReceive() method whenever the device is detached and here inside onReceive() method we will replace our device screen by passing parameters deviceConnected = false and deviceFound = false to newInstance() method in HomeFragment.

private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
   public void onReceive(Context context, Intent intent) {
     String action = intent.getAction();
     if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {                                           
           HomeFragment.newInstance(false, false)).commitAllowingStateLoss();

Thus, as shown in fig. 2 we have shown the PSLab device connection status dynamically on the screen by handling the USB attach/detach events.

Figure 2 shows the UI of ‘Device Screen’ for the two possible status: ‘not connected’ and ‘connected’


  1. Codepool Blog – “How to monitor USB events on Android?” by Xiao Ling
  2. Vogella article “What is Broadcast Receiver and how to insert it your app?”

Creating Custom Borders for Widgets and Layouts in PSLab Android

User Interface (UI) is one of the most important part of any software development. In PSLab Android App while developing the UI, custom borders are used for various widgets and layouts. This makes the UI look more appealing and widgets and layouts look more highlighted.

In Android, we can do a range of border customization. We can make border rounded, define its thickness and even change its color. Let’s see how to achieve this.

First, go to drawable folder in the tree view on the left size of the Android studio. Then go to new and click on Drawable resource file.

Then a New Resource File dialog box will appear. Type the filename and then click OK.

After this, a new XML file is created. Now we can write the code for creating custom borders. For this, we have to define few elements.

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="">

Shape Drawables allows defining background, borders, and gradients for the Views.

<solid android:color="#FFFFFF"/>

Here we are setting the background color of the widget/layout to which the border is applied to.

<stroke android:width="3dip" android:color="#B1BCBE" />

Now we are applying the 3dip width to the border and set its color. This shape requires the <stroke> element to define the width and color of the line.

<corners android:radius="10dip"/>

In order to make the corners of the border round, <corner> element is used to define the radius of the corners. We are taking it to be 10dip.

<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />

The padding is expressed in pixels for the left, top, right and bottom parts of the view. Padding is used to offset the content of the view by a specific number of pixels.

After applying this border on a layout we get the following results.

Similarly making following changes in the element values help us to make border for the Text View

<solid android:color="@android:color/white" />
<stroke android:width="1dip" android:color="#ffcdd2" />
<corners android:radius="2dp"/>

Other examples

Control Activity

Logical Analyzer Activity


  1. Stack Overflow Solution to How to make a layout with rounded corners?
  2. Youtube Video on How to create a layout with rounded corner borders in Android? by Sylvain Saurel

Adding Tweet Streaming Feature in World Mood Tracker loklak App

The World Mood Tracker was added to loklak apps with the feature to display aggregated data from the emotion classifier of loklak server. The next step in the app was adding the feature to display the stream of Tweets from a country as they are discovered by loklak. With the addition of stream servlet in loklak, it was possible to utilise it in this app.

In this blog post, I will be discussing the steps taken while adding to introduce this feature in World Mood Tracker app.

Props for WorldMap component

The WorldMap component holds the view for the map displayed in the app. This is where API calls to classifier endpoint are made and results are displayed on the map. In order to display tweets on clicking a country, we need to define react props so that methods from higher level components can be called.

In order to enable props, we need to change the constructor for the component –

export default class WorldMap extends React.Component {
    constructor(props) {


We can now pass the method from parent component to enable streaming and other components can close the stream by using props in them –

export default class WorldMoodTracker extends React.Component {
    showStream(countryName, countryCode) {
        /* Do something to enable streaming component */
    render() {
        return (
                <WorldMap showStream={this.showStream}/>


Defining Actions on Clicking Country Map

As mentioned in an earlier blog post, World Mood Tracker uses Datamaps to visualize data on a map. In order to trigger a piece of code on clicking a country, we can use the “done” method of the Datamaps instance. This is where we use the props passed earlier –

done: function(datamap) {
    datamap.svg.selectAll('.datamaps-subunit').on('click', function (geography) {
        props.showStream(, reverseCountryCode(;


The name and ID for the country will be used to display name and make API call to stream endpoint respectively.

The StreamOverlay Component

The StreamOverlay components hold all the utilities to display the stream of Tweets from loklak. This component is used from its parent components whose state holds info about displaying this component –

export default class WorldMoodTracker extends React.Component {
    getStreamOverlay() {
        if (this.state.enabled) {
            return (<StreamOverlay
                show={true} channel={}
                country={} onClose={this.onOverlayClose}/>);

    render() {
        return (


The corresponding props passed are used to render the component and connect to the stream from loklak server.

Creating Overlay Modal

On clicking the map, an overlay is shown. To display this overlay, react-overlays is used. The Modal component offered by the packages provides a very simple interface to define the design and interface of the component, including style, onclose hook, etc.

import {Modal} from 'react-overlays';

<Modal aria-labelledby='modal-label'
    <div style={dialogStyle()}>


It must be noted that modalStyle and backdropStyle are React style objects.

Dialog Style

The dialog style is defined to provide some space at the top, clicking where, the overlay is closed. To do this, vertical height units are used –

const dialogStyle = function () {
    return {
        position: 'absolute',
        width: '100%',
        top: '5vh',
        height: '95vh',
        padding: 20


Connecting to loklak Tweet Stream

loklak sends Server Sent Events to clients connected to it. To utilise this stream, we can use the natively supported EventSource object. Event stream is started with the render method of the StreamOverlay component –

render () {


This channel is used to connect to twitter/country/<country-ID> channel on the stream and then this can be passed to EventStream constructor. On receiving a message, a list of Tweets is appended and later rendered in the view –

startEventSource(country) {
    let channel = 'twitter%2Fcountry%2F' + country;
    if (this.eventSource) {
    this.eventSource = new EventSource(host + '/api/stream.json?channel=' + channel);
    this.eventSource.onmessage = (event) => {
        let json = JSON.parse(;
        if (this.state.tweets.length > 250) {


The size of the list is restricted to 250 here, so when a newer Tweet comes in, the oldest one is chopped off. And thanks to fast DOM actions in React, the rendering doesn’t take much time.

Rendering Tweets

The Tweets are displayed as simple cards on which user can click to open it on Twitter in a new tab. It contains basic information about the Tweet – screen name and Tweet text. Images are not rendered as it would make no sense to load them when Tweets are coming at a high rate.

function getTweetHtml(json) {
    return (
        <div style={{padding: '5px', borderRadius: '3px', border: '1px solid black', margin: '10px'}}>
            <a href={} target="_blank">
            <div style={{marginBottom: '5px'}}>
            <div style={{overflowX: 'hidden'}}>{json['text']}</div>


They are rendered using a simple map in the render method of StreamOverlay component –

<div className={styles.container} style={{'height': '100%', 'overflowY': 'auto',
    'overflowX': 'hidden', maxWidth: '100%'}}>


Closing Overlay

With the previous setup in place, we can now see Tweets from the loklak backend as they arrive. But the problem is that we will still be connected to the stream when we click-close the modal. Also, we would need to close the overlay from the parent component in order to stop rendering it.

We can use the onclose method for the Modal here –

close() {
    if (this.eventSource) {
        this.eventSource = null;


Here, props.onClose() disables rendering of StreamOverlay in the parent component.


In this blog post, I explained how the flow of props are used in the World Mood Tracker app to turn on and off the streaming in the overlay defined using react-overlays. This feature shows a basic setup for using the newly introduced stream API in loklak.

The motivation of such application was taken from emojitracker by mroth as mentioned in fossasia/ The changes were proposed in fossasia/ by @singhpratyush (me).

The app can be accessed live at


Using Firebase Test Lab for Testing test cases of Phimpme Android

As now we started writing some test cases for Phimpme Android. While running my instrumentation test case, I saw a tab of Cloud Testing in Android Studio. This is for Firebase Test Lab. Firebase Test Lab provides cloud-based infrastructure for testing Android apps. Everyone doesn’t have every devices of all the android versions. But testing on all of them is equally important.

How I used test lab in Phimpme

  • Run your first test on Firebase

Select Test Lab in your project on the left nav on the Firebase console, and then click Run a Robo test. The Robo test automatically explores your app on wide array of devices to find defects and report any crashes that occur. It doesn’t require you to write test cases. All you need is the app’s APK. Nothing else is needed to use Robo test.

Upload your Application’s APK (app-debug-unaligned.apk) in the next screen and click Continue

Configure the device selection, a wide range of devices and all API levels are present there. You can save the template for future use.

Click on start test to start testing. It will start the tests and show the real time progress as well.

  • Using Firebase Test Lab from Android Studio

It required Android Studio 2.0+. You needs to edit the configuration of Android Instrumentation test.

Select the Firebase Test Lab Device Matrix under the Target. You can configure Matrix, matrix is actually on what virtual and physical devices do you want to run your test. See the below screenshot for details.

Note: You need to enable the firebase in your project

So using test lab on firebase we can easily test the test cases on multiple devices and make our app more scalable.


Receiving Data From the Network Asynchronously

We often need to receive information from networks in Android apps. Although it is a simple process but the problem arises when it is done through the main user interaction thread. To understand this problem better consider using an app which shows some text downloaded from the online database. As the user clicks a button to display a text it may take some time to get the HTTP response. So what does an activity do in that time? It creates a lag in the user interface and makes the app to stop responding. Recently I implemented this in Connfa App to download data in Open Event Format.

To solve that problem we use concurrent thread to download the data and send the result back to be processed separating it from main user interaction thread. AsyncTask allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most). If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask.

An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.

In this blog, I describe how to download data in an android app with AsyncTask using OkHttp library.

First, you need to add dependency for OkHttp Library,

compile 'com.squareup.okhttp:okhttp:2.4.0' 

Extend AsyncTask class and implement all the functions in the class by overriding them to modify them accordingly. Here I declare a class named AsyncDownloader extending AsyncTask. We took the string parameter, integer type progress and string type result to return instead which will be our JSON data and param is our URL. Instead of using get the function of AsyncTask we implement an interface to receive data so the main user interaction thread does not have to wait for the return of the result.

public class AsyncDownloader extends AsyncTask<String, Integer, String> {
    private String jsonData = null;

    public interface JsonDataSetter {
        void setJsonData(String str);

    JsonDataSetter jsonDataSetterListener;

    public AsyncDownloader(JsonDataSetter context) {

        this.jsonDataSetterListener = context;

    protected void onPreExecute() {

    protected String doInBackground(String... params) {

        String url = params[0];

        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
        Call call = client.newCall(request);

        Response response = null;

        try {
            response = call.execute();

            if (response.isSuccessful()) {
                jsonData = response.body().string();

            } else {
                jsonData = null;

        } catch (IOException e) {

        return jsonData;

    protected void onPostExecute(String jsonData) {

We download the data in doInBackground making a request using OkHttp library and send the result back in onPostExecute method using our interface method. See above to check out the complete class implementation.

You can make an instance to AsyncDownloader in an activity. Implement interface to receive that data.

Tip: Always close AsyncTask after using to avoid many concurrent tasks at one time.

Find the complete code here.


Using The Dark and Light Theme in SUSI iOS

SUSI being an AI for interactive chat bots, provides answers to the users in the intelligent way. So, to make the SUSI iOS app more user friendly, the option of switching between themes was introduced. This also enables the user switch between themes based on the environment around. Any user can switch between the light and dark themes easily from the settings.

We start by declaring an enum called `theme` which contains two strings namely, dark and light.

enum theme: String {
    case light
    case dark

We can update the color scheme based on the theme selected very easily by checking the currently active theme and based on that check, we update the color scheme. To check the currently active theme, we define a variable in the `AppDelegate` which holds the value.

var activeTheme: String?

Below is the way the color scheme of the LoginViewController is set.

var activeTheme: String?func setupTheme() {
  let image = UIImage(named: ControllerConstants.susi)?.withRenderingMode(.alwaysTemplate)
  susiLogo.image = image
  susiLogo.tintColor = .white
  UIApplication.shared.statusBarStyle = .lightContent
  let activeTheme = AppDelegate().activeTheme
  if activeTheme == theme.light.rawValue {
    view.backgroundColor = UIColor.lightThemeBackground()
  } else if activeTheme == theme.dark.rawValue {
    view.backgroundColor = UIColor.darkThemeBackground()

Here, we first get the image and set the rendering mode to `alwaysTemplate` so that we can change the tint color of the image. Next, we assign the image to the `IBOutlet` and change the tint color to `white`. We also change the status bar style to `lightContent`. Next, we check the active theme and change the view’s background color accordingly. For this method to execute, we call it inside, `viewDidLoad` so that the theme loads up as the view loads.

Next, lets add this option of switching between themes inside the `SettingsViewController`. We add a cell with `titleLabel` as `Change Theme` and use the collectionView’s delegate method of `didSelect` to show an alert. This alert contains three options, Dark theme, Light Theme and Cancel. Let’s code that method which presents the alert.

func themeToggleAlert() {
  let imageDialog = UIAlertController(title: ControllerConstants.toggleTheme, message: nil, preferredStyle: UIAlertControllerStyle.alert)
  imageDialog.addAction(UIAlertAction(title: theme.dark.rawValue.capitalized, style: .default, handler: { (_: UIAlertAction!) in
    imageDialog.dismiss(animated: true, completion: nil)
    AppDelegate().activeTheme = theme.dark.rawValue
    self.settingChanged(sender: self.imagePicker)
  imageDialog.addAction(UIAlertAction(title: theme.light.rawValue.capitalized, style: .default, handler: { (_: UIAlertAction!) in
    imageDialog.dismiss(animated: true, completion: nil)
    AppDelegate().activeTheme = theme.light.rawValue
    self.settingChanged(sender: self.imagePicker)
  imageDialog.addAction(UIAlertAction(title: ControllerConstants.dialogCancelAction, style: .cancel, handler: { (_: UIAlertAction!) in
    imageDialog.dismiss(animated: true, completion: nil)
  self.present(imageDialog, animated: true, completion: nil)

Here, we assign the alert view’s title and add 3 actions and their respective completion handlers. If we see inside these completion handlers, we can notice that we first dismiss the alert followed by updating the activeTheme variable in AppDelegate and call the `settingChanged` function which updates the user’s settings on the server. Finally, we update the color scheme.

Now, if we build and run the app and change the theme from the settings, we will notice that on returning to the chat view, the color scheme is not updated. The reason here is that we are setting up the theme on viewDidLoad which loads only once and is not executed until the controller is presented again. Here, we make use of the `viewDidAppear` method which executes every time the view appears.

override func viewDidAppear(_ animated: Bool) {

To persist the selected theme, we used the UserDefaults to save the theme which got assigned everytime to the `activeTheme` variable when the app loads up.

UserDefaults.standard.set(AppDelegate().activeTheme, forKey: ControllerConstants.UserDefaultsKeys.theme)

On app launch, we assigned this User Default the value of the light theme as a default.

Below is the final output: