Android

Handling different Android versions with strategy pattern

2017-03-26 Android, DSP2017, Software Design Patterns No comments

When we’re developing Android apps, we have to remember that different users have different versions of the Android OS. Unfortunately, not all of them has the newest version of the system and some of them have older devices with older systems. Some of these devices may be even unsupported because e.g. Google supports their devices like Nexus and Pixel for only 2 years. When we want to reach as many users as possible and make the app available for almost everyone, we have to handle different Android versions. One of the solutions for that problem is strategy design pattern (it’s also called Policy in Domain-Driven Design).

I’m developing an Android open-source library called ReactiveNetwork, which is used for monitoring connectivity with the network in the system. Network monitoring strategies vary between different versions of Android and I wanted to choose an appropriate strategy for appropriate Android version. To do so, I’ve created NetworkObservingStrategy interface:

public interface NetworkObservingStrategy {
  Observable observeNetworkConnectivity(final Context context);
  void onError(final String message, final Exception exception);
}

This interface can have many implementations like LollipopNetworkObservingStrategy, PreLollipopNetworkObservingStrategy and MarshmallowNetworkObservingStrategy. Morever, more implementations can be added in the future.

After that, we can choose a valid strategy for the concrete version of the system:

public static Observable<Connectivity> observeNetworkConnectivity(final Context context) {
  final NetworkObservingStrategy strategy;

  if (Preconditions.isAtLeastAndroidMarshmallow()) {
    strategy = new MarshmallowNetworkObservingStrategy();
  } else if (Preconditions.isAtLeastAndroidLollipop()) {
    strategy = new LollipopNetworkObservingStrategy();
  } else {
    strategy = new PreLollipopNetworkObservingStrategy();
  }

  return strategy.observeNetworkConnectivity(context);
}

That’s it. Now, we have the separate code working for Android M, L and all devices with system version lower than L.
This approach can also be applied to other areas.

Android design inspirations

2017-03-19 Android, Design, DSP2017 No comments

When we are planning to create our next Android app, besides the codebase, it’s also good to plan its design, UI, and UX. Before doing that, we can take a look at some inspirations and work of other people to gather a few UI design patterns, inspirations, and ideas.
Good resource of such inspirations is Android Niceties website. As the authors write, this website is
a collection of screenshots encompassing some of the most beautiful looking Android apps.

You can also take a look at https://pl.pinterest.com/explore/android-ui/.

Do you know any other similar resources? Share them in comments :-).

Unit test coverage report with Travis CI for Robolectric on Android

2017-03-19 Android, Continuous Integration, DSP2017, Gradle, Unit Tests No comments

Introduction

Some time ago, I’ve written an article about Test coverage report for Android application. It got some interest (many comments below article and many visits according to Google Analytics), so I decided to refresh this topic. Previously, I’ve written instrumentation unit tests, which needed to be executed on a real device or an emulator. It’s a good approach when you want to test functionalities strongly connected with the device. E.g. when you want to test operations on a real SQLite database or something like that. Nevertheless, this approach has huge disadvantages. It’s hard to run tests on the Continous Integration server because we need to have the emulator or device up & connected all the time and also tests need to interact properly with the device to get passed what is not so easy. In most cases, mocking part of the application’s behavior is enough. In that case, we can easily run tests on a CI server and have deterministic test results. In order to do that, we can use Robolectric.

Gradle configuration

First, we have to add appropriate dependency to jacoco-android plugin in our top-level build.gradle file:

buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath 'com.android.tools.build:gradle:2.3.0'
    classpath 'com.dicedmelon.gradle:jacoco-android:0.1.1'
  }
}

Next, we need to add appropriate test dependencies in another build.gradle file for our app or library.

dependencies {
  testCompile 'junit:junit:4.12'
  testCompile 'com.google.truth:truth:0.32'
  testCompile 'org.robolectric:robolectric:3.1.2'
  testCompile 'org.mockito:mockito-core:2.7.17'
}

I’ve added also dependencies to JUnit, Truth and Mockito library, which are used in my tests.

We also need to add appropriate plugins:

apply plugin: 'jacoco'
apply plugin: 'jacoco-android'

To avoid ignoring our tests by the coverage report, we need to configure the following settings:

android {
  testOptions {
    unitTests.all {
      jacoco {
        includeNoLocationClasses = true
      }
    }
  }
}

Next, we need to configure report output:

jacocoAndroidUnitTestReport {
  csv.enabled false
  html.enabled true
  xml.enabled true
}

Travis CI configuration

We are done with Gradle configuration. I’m assuming we have Travis CI build configured. If you don’t know, how to do this, visit travis-ci.org and enable builds for your project. It’ pretty easy. Now, we should visit codecov.io website, register there (e.g. with GitHub account) and add our project. After that, we need to add the following items to our .travis.yml file:

after_success:
  - bash <(curl -s https://codecov.io/bash)

script:
  - ./gradlew clean build test jacocoTestReport check

Here we are performing clean, build an application, running unit tests, generating test coverage report with Jacoco and performing check (Lint, FindBugs, PMD & CheckStyle).

Writing unit tests with Robolectric

Next we can place our tests in src/test/ directory.
Sample unit test can look as follows:

In my case, I also needed to create src/test/resources/robolectric.properties file with the following content:

sdk=23

because Robolectric didn’t work with the Android SDK newer than 23. Moreover, I also needed to use Robolectric v. 3.1.2, because I had problems with running tests and generating coverage report with the latest version of the Robolectric.

Summary

When we have everything configured, we can push our tests to the GitHub repository, Travis CI build will be triggered and we can beautiful test coverage report, which can help to improve our tests.

We can also click on the main package and see detailed coverage information for the several packages.

Moreover, we can analyze coverage change in time.

I’ve applied approach described in this article in ReactiveNetwork open-source library. If want to see the complete solution, take a look at the source code of this project or see its coverage report on-line.

ReactiveNetwork – release v. 0.5.0

2016-07-24 Android, Java, Open source No comments

I have never thought that seemingly tiny thing like monitoring network connectivity on a mobile device can be subject to development for at least about one year!

I’ve recently released a new version of my project – ReactiveNetwork library – v. 0.5.0.

Highlights of this release are as follows:

  • added support for the new network monitoring strategy with NetworkCallback available since Android Lollipop (API 21)
  • kept backward compatibility of network monitoring with pre-Lollipop devices
  • added possibility to implement custom network monitoring strategy
  • made methods responsible for creating Observables static like in original RxJava project
  • added Preconditions class verifying correctness of the input parameters
  • changed API of Observable responsible for monitoring network from Observable<ConnectivityStatus> observeNetworkConnectivity(context) to Observable<Connectivity> observeNetworkConnectivity(context)
  • replaced ConnectivityStatus enum with Connectivity class containing info about network state, type and name
  • added more unit tests

You can read detailed release notes on GitHub.

I hope, this project will make your apps more robust and you won’t be surprised by incorrect network monitoring when your users will upgrade their devices to Android N. The newest Android version is not officially released to all Android devices yet, but it’s already supported by ReactiveNetwork library.

Setting up Android Studio on OS X

2016-07-05 Android, Apple, macOS, OS X No comments

Setting up Android Studio on OS X can be tricky. I had a strange problem with tools.jar file and I am not the only one.

After installation of Android Studio, when I started it up, I got an error, which looked like that:

'tools.jar' seems to be not in Android Studio classpath.  
Please ensure JAVA_HOME points to JDK rather than JRE.

jdk_required_screenshot

Luckilly, I fixed this problem and set up Android studio in the following way in my .zshrc file.

If you are not using ZSH, you should set it up in your .bashrc or .bash_profile file.

  # android
  export STUDIO_JDK=/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk
  export ANDROID_HOME=$HOME/Library/Android/sdk
  export PATH=$ANDROID_HOME:$PATH
  export PATH=$ANDROID_HOME/tools:$PATH
  export PATH=$ANDROID_HOME/platform-tools:$PATH
  alias runAndroidStudio="/Applications/Android\ Studio.app/Contents/MacOS/studio"

Please, remember to set your version of JDK. If you have a different version than me, you need to change STUDIO_JDK variable respectively.

Complete source of my .zshrc file can be found here: https://github.com/pwittchen/dotfiles/blob/master/.zshrc

Then, I need to start Android Studio with the following command from terminal:

$ runAndroidStudio

Unfortunately, opening it via Spotlight or from Applications menu doesn’t work properly in my case. If you know, how to fix it, leave a comment below this article!

That’s it! With that setup, I can finally use Android Studio on Mac OS X.

ReactiveNetwork – new releases & roadmap

2016-06-10 Android, Java, Open source, RxJava No comments

Recent updates

I’ve recently released version 0.3.0 of ReactiveNetwork library for Android. As you can see in the release notes, it contains a lot of updates.
Highlights:

  • Deprecated methods related to monitoring WiFi Access Points and WiFi Singal level in favor of ReactiveWiFi project, which has this functionality extracted from ReactiveNetwork
  • Deprecated methods and enums related to monitoring connectivity with The Internet
  • Added Observables, which allows monitoring Internet connectivity basing on socket connection with a remote host (we can also monitor specific host with given parameters)

Roadmap for the future versions

Updates planned for 0.4.0:

  • Removing deprecated methods
  • Removing unused permissions from AndroidManifest.xml

Track progress of releasing 0.4.0 on GitHub

Updates planned for 0.5.0:

  • Updating library code with respect to the updates in Android 5 and 6 (especially ConnectivityManager) related to monitoring network connectivity mentioned in issue #62 on GitHub
  • Creating strategy interface to keep backward compatibility with Pre-Lollipop devices, so we’ll be able to monitor network in a different way depending on the given Android version

Track progress of releasing 0.5.0 on GitHub

Another future updates (not related to any version):
These updates are also important, but they’re not related to library API

  • Adding example of library usage with Retrofit (without breaking reactive stream chain)

Track progress of resolving this issue on GitHub

Final thoughts

Currently, it’s my most popular open-source project and people rely on it in production apps, so I’m trying to keep it as simple and as good as I can with respect to the recent updates of Android SDK. I’m getting really good feedback from people on GitHub and seriously considering it during the development process. If something bothers you in that project, don’t hesitate to create an Issue or new Pull Request on GitHub.

Handle swipe events in reactive style

2016-03-11 Android, Java, Open source, RxJava No comments

Introduction

Initial Swipe Detector project was created on 24th of December 2014 on GitHub, so more than one year ago. I also wrote an article about that on my blog. I needed that to detect moment when user is swiping horizontally, to block vertical scroll on the ListView while deleting item with “swipe to delete” functionality. This gives better UX and apps from Google works in the same way. Mentioned project was just a simple proof of concept showing how can we detect whether user is swiping on the screen of mobile device and in which direction. Recently, I thought that it would be cool if we had a separate generic library to do the same thing. It would be even cooler if this library will provide RxJava Observable to handle such events in a reactive way. That’s why I’ve decided to take this project, extract generic code to library and write an Observable wrapping listener, which handles swipe events. Please, take a look at the outcome of that work.

swipe

Preparation

New library is called swipe. If we want to use it, we need to add proper dependencies to our build.gradle file:

dependencies {
  compile 'com.github.pwittchen:swipe:0.0.1'
}

Next, we need to create Swipe attribute in our Activity:

private Swipe swipe;

We also need to remember to call dispatchTouchEvent(MotionEvent) method:

We need to perform things described above both for listener and RxJava Observable.

Imperative way

If we are not familiar with RxJava, we can handle swipe events in an imperative way with listener:

Reactive way

If we want to use the power of RxJava and code our app in a reactive style, we need to add Subscription attribute.

private Subscription subscription;

Now, we can subscribe an Observable:

Please note, there’s much less code than in the case of listener.

We need to remember to unsubscribe our Observable, when it’s no longer needed:

That’s it! I hope it will help you to detect and handle swipe events in your apps.

Source code of the library is available on GitHub: https://github.com/pwittchen/swipe.

Infinite scroll for RecyclerView in Android

2016-02-28 Android, Java, Open source, UI 5 comments

Introduction

Three years ago I wrote short article about Endless ListView in Android. This solution was dedicated to ListView, wasn’t perfect and generic. Moreover, lot of people asked questions about this solution and they weren’t sure how to use it properly. I also had some problems with implementing endless scroll AKA infinite scroll in Android apps. In addition, in the newest Android SDK it’s recommended to use RecyclerView instead of ListView. For a long time I couldn’t find the right implementation of the infinite scroll AKA endless scroll for Android. A few solutions I’ve found weren’t production ready, weren’t working correctly or had too many features. I wanted to have small, easy and flexible solution to implement infinite scroll for Android, which works with RecyclerView from the newest Android API. That’s why I created new project called InfiniteScroll, which helps to implement infinite scroll on Android. Library is tested and its behavior is documented by appropriate unit tests. If you would like to see it in action, check out gif animation presenting how sample app works. Library is very tiny, but does its job.

How to use it?

First of all, we need to add library dependency to our build.gradle file:

dependencies {
  compile 'com.github.pwittchen:infinitescroll:0.0.1'
}

We also need to create necessary fields in our Activity:

public RecyclerView recyclerView;
private LinearLayoutManager layoutManager;

Next, we need to create new InfiniteScrollListener:

Then, we need to initialize RecyclerView and LinearLayoutManager in our Activity and add previously created listener to RecyclerView:

If we want to display loading progress, we should add additional view for it, show it while loading starts and hide it when loading is finished.

That’s it!

Please note: We can also implement “Load more” button with that library. Instead of loading items immediately, we can display such button when user scrolled to the end of the list.

Exemplary apps

You can see how, library can be implemented in the following places:

  • Sample app from main repository, which loads Strings into RecyclerView
  • Search Twitter app, which allows to search tweets and scroll them infinitely

Summary

I think, this time infinite scroll is implemented in the right and re-usable way. I hope, it will make your life easier while developing your apps.

Source code of the library can be found at: https://github.com/pwittchen/InfiniteScroll.

ReactiveNetwork – release of v. 0.2.0

2016-02-11 Android, Java, Open source, RxJava No comments

I’ve recently released new version of ReactiveNetwork library for Android.

Here are the fresh release notes for version 0.2.0:

  • added possibility to observe WiFi signal level with observeWifiSignalLevel(context, numLevels) and observeWifiSignalLevel(context) method
  • created WifiSignalLevel enum
  • added internet check to parameters of getConnectivityStatus(context, checkInternet) method
  • made getConnectivityStatus(context, checkInternet) method public
  • changed String variable status in ConnectivityStatus enum to description and made it public
  • changed output of the toString() method in ConnectivityStatus to keep consistency with another enum
  • made ReactiveNetwork class non-final
  • bumped Kotlin version in sample app to 1.0.0-rc-1036
  • increased immutability of code of the library
  • updated sample apps and documentation

Thanks to @llp and his Pull Request, we are able to observe WiFi signal level AKA RSSI now! It’s one of the most interesting features in the newest release.

We can do it as follows:

or we can observe an enum value instead of integer:

WifiSignalLevel enum can have the following values:

public enum WifiSignalLevel {
  NO_SIGNAL(0, "no signal"),
  POOR(1, "poor"),
  FAIR(2, "fair"),
  GOOD(3, "good"),
  EXCELLENT(4, "excellent");
  ...
}

Any feedback will be appreciated!

Happy coding!

Reactive Live Coding during GDG DevFest 2015 in Poland

2015-11-29 Android, Conferences, Google, Java, RxJava 2 comments

I was asked to be a speaker during GDG DevFest 2015 conference in Warsaw, Poland. Of course, I accepted this invitation and prepared presentation titled “Reactive Live Coding”. Presentation covered basics of Reactive Programming, RxJava and RxAndroid. Besides my talk I’ve done live coding to show how to use mentioned libraries and basics principles of Reactive Programming in real life. I had only 20 minutes for all of that, so my time-box was very limited. Being a speaker at conference was really interesting and challenging experience, which I haven’t had before. Moreover, I could meet a lot of interesting people and hear very inspiring talks covering different topics. You can check activity from conference by browsing #devfest15pl hashtag on Twitter and Facebook event. You can also check official website of the conference at devfest.pl.

Slides from my presentation are available below.

Source code of the exemplary Android app shown and partially coded during the presentation is available at github.com/pwittchen/guitar-browser.

Picture documenting part of my short talk made by @depodefi can be found below.

CU59bM6W4AABP68

GDG DevFest organizers have done really good job and I can definitely recommend this conference to anyone interested in new IT technologies.