Montag, 6. Juli 2015

How to show data from cache and simultaneously refresh it from network with RxJava

This blog post is inspired by the blog post of Dan Lew, who is explaining how you can load data from multiple sources with RxJava in a single stream. It would probably make sense to read his post first, because I'm referring to it quite well (no worries, it's short).

I like the idea of having a single data stream responsible for fetching data, either from the cache or from the network, so I don't have to care where it comes from while I would like to fetch and display it.
I also like the approach to get fresh data from the network once your current data is stale...but unfortunately there is one drawback in the approach of Dan. The client has to know when it's data is stale, and that's not always the case, at least for me. In my application the client always asks the server for fresh data and if the server doesn't has any, it responses with a 304 (nothing changed).

So the use case for the client I would like to achieve is the following:
- fetch data from cache/database and display it
- request data from server in background simultaneously
- if the server has fresh data, persist it in the database and update the UI with the fresh data
- if the server doesn't have fresh data, just do nothing since the data from cache is already displayed
- do this by using a single stream

Since we know already by Dan Lew how to load the data from multiple sources in a single stream, the first thing to achieve what I would like to have from above is to remove the first() call to be able to run all source observables after each other:

// Our sources 
Observable<Data> cache = getCacheObservable();  
Observable<Data> network = getNetworkObservable();

// Retrieve the first source with data
Observable<Data> source = Observable  
  .concat(cache, network)
  .first();

Now the cache and network observables are running both, but as said before after each other and not simultaneously because that's what concat() does. Fortunately there is a method of RxJava which also solves this problem and it's called merge(). It does basically the same as concat() but in parallel.

Observable<Data> source = Observable  
  .merge(cache, network);

Since we want to have all this stuff happening in the background but display it int he UI we need to take care of it by using the right schedulers:

Observable.merge(cache.subscribeOn(Schedulers.newThread(), 
                 network.subscribeOn(Schedulers.newThread())
          .observeOn(AndroidSchedulers.mainThread())
          .subscribe((data) -> handleShowData(data));

Here it's important to subscribe each of the single observables on a new thread to ensure it will run in parallel. Otherwise if you would subscribe only the resulting observable on a new thread it would run in background but still after each other (like if we would use concat()).

Conclusion

I think this is a nice and clean way to get data synced on the client side and I hope you think the same. I didn't cover the part of how to store the data in the database, because it's already covered by the post of Dan Lew. 
But I have created a small and simple application on github which fulfills all the points from my use case above, so check it out :)

Donnerstag, 27. November 2014

Let your washing machine tell you when it's finished

I had a nice idea for lazy people like me:
Wouldn't it be cool if your washing machine told you when it is done cleaning your dirty undies?

Some of you may think now: "wtf?" or "why would I need this?"

I always have the same problem: I turn on my washing machine at 8 o'clock in the evening, then I start working on my laptop till around midnight and by that time I have totally forgotten about the laundry. After having worked I am normally tired and I just want to go to bed, but when I come into the bathroom (where my washing machine is waiting for me) I see the red LED's blinking, basically yelling at me "Heeey! Did you forget about me? YOU HAVE TO HANG THE FUCKING LAUNDRY! AND IT IS NOT JUST SOME T-SHIRTS! I HAVE MANY SOCKS AND UNDIES!!!!". 
So I have to hang the laundry absolutely tired and annoyed. 

To put an end to this and not be annoyed every fucking time I come into the bathroom at midnight I thought: How can the washing machine just tell me when it is finished?
There are some washing machines that make beeping noises when they are finished - but I don't own any of those and I don't want to spend the money for a new one.

At AVM GmbH I found a  nice device called Dect!200 which is a switchable socket connected to the Fritz!Box via DECT. This socket can measure the voltage flow and you can check the data and work with it in the web interface of the Fritz!Box.

Let's get the washing machine a bit smarter

Things you need:

  • Fritz!Box from AVM GmbH (I had the 7490, costs: ca. 199€, you can use any Fritz!Box which supports DECT)
  • AVM FRITZ!DECT 200 (switchable smart socket, costs ca. 45€)
  • Time to spend: max. 30 minutes


Easy idea: measure the voltage when the washing machine is done and in standby mode. Now I can trigger the socket to turn off when the standby voltage is flowing for some time, e.g. 10 minutes. 


Step 1: Go to the web interface and navigate to home network (Heimnetz) -> Smart Home


There you choose the settings menu of the Dect!200. I called it "Waschmaschine" (washing machine).


Step 2: Go to the tab "Automatisch Schalten" (not sure how it's called in English, maybe something like automatic)



Step 3: Scroll down to "Abschalten bei Standby" (turn off on standby) and enter the Watt value which your machine has in standby mode. To know the value just turn on the machine and wait a bit - go to the Smart Home section and read the actual consumption. In my case it was 1,14 Watt so I put in 1,15 just to be sure and 10 minutes, also just to be sure. You can also set it to 5 minutes but that will not make the cake big.




Done - but this will not tell me when the washing machine is done - it will just shut off the yelling LED's which would make it even more likely for me to forget about the laundry and leave it in the machine until I try to wash some clothes the next time.

Push Notification
Thanks to the Fritz!Box there is a push notification feature which sends you an e-mail every time there is a toggle, i.e. the socket has been switched on or off. I just configured this and BAM! I get an email every time the washing machine turns on and off (because you have to toggle the socket).

When I receive an e-mail I get a push notification on my smart phone:

(the text says: "your washing machine was turned off")





Nice side effect: now I am getting informed when my girlfriend is using my washing machine and I can immediately react by sending her some smilies and kisses from where ever I am to say "THANKS for washing my shit!" 



Now that I know I can trigger stuff - I am planning some new cool things.
The next project will be: How can I turn off the lights in the living room after having forgotten to turn them  after having hung my laundry while being extremely tired and annoyed from the yelling LED's?


Answer: By creating a power cable with luster terminals on each side and connect it with my overhead lights and the Dect!200 switchable socket!  I will explain how to do this next time.

Mittwoch, 13. August 2014

SnappingSeekBar

I have developed my own implementation of a snapping seek bar. It automatically creates indicators depending on how it is configured. The seek bar is able to display short texts for each indicator. If an indicator gets tapped, the thumb animates smoothly to the tapped indicator. The thumb can also be slided and after releasing it snaps to the most nearest indicator. The seek bar is very customizable: you can change several colors, drawables or strings for the items you are using.

The usage is very simple. You can put it in your xml or add it programmatically:

From xml:

<com.tobishiba.SnappingSeekBarSample.views.SnappingSeekBar
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:progressDrawable="@drawable/seekbar_progress"
    app:thumb="@drawable/seekbar_thumb"
    app:progressColor="@color/blue"
    app:thumbnailColor="@color/blue_light"
    app:indicatorColor="@color/white"
    app:textIndicatorColor="@color/white"
    app:textSize="12dp"
    app:indicatorSize="12dp"
    app:itemsArrayId="@array/big_indicators_items"/>


From code:

private SnappingSeekBar createSnappingSeekBarProgrammatically() {
    final SnappingSeekBar snappingSeekBar = new SnappingSeekBar(this);
    snappingSeekBar.setProgressDrawable(R.drawable.seekbar_progress;
    snappingSeekBar.setThumbDrawable(R.drawable.seekbar_thumb);
    snappingSeekBar.setItems(new String[]{"Wow", "such", "amazing"});
    snappingSeekBar.setProgressColor(resources.getColor(R.color.green_darker));
    snappingSeekBar.setThumbnailColor(resources.getColor(R.color.yellow_light));
    snappingSeekBar.setTextIndicatorColor(resources.getColor(R.color.red_darker));
    snappingSeekBar.setIndicatorColor(resources.getColor(R.color.green_light));
    snappingSeekBar.setTextSize(14);
    snappingSeekBar.setIndicatorSize(14);
    snappingSeekBar.setOnItemSelectionListener(this);
    return snappingSeekBar;
}


Just check it out on github or at Google Play!

Dienstag, 12. August 2014

How to create an ProgressCircle instead of a ProgressBar

In the picture you see the result of this little tutorial. A ProgressCircle where the progress is visualized as a circle from 0% to 100%.


First of all you will need a new progress drawable.

<?xml version="1.0" encoding="UTF-8" ?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <shape
            android:innerRadiusRatio="2.2"
            android:shape="ring"
            android:useLevel="false"
            android:thicknessRatio="90.0">
            <solid android:color="@color/white"/>
        </shape>
    </item>
    <item android:id="@android:id/progress">
        <shape
            android:innerRadiusRatio="2.2"
            android:shape="ring"
            android:thicknessRatio="25.0">
            <solid android:color="@color/attribute_green"/>
        </shape>
    </item>
</layer-list>

Inside of the drawable xml you have the background and the progress of the ProgressBar.
After creating the ProgressDrawable you have to put it as progressDrawable to the ProgressBar Widget as shown below:

<ProgressBar
    android:id="@+id/manufacture_count_progress"
    style="?android:attr/progressBarStyleHorizontal" 
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:rotation="90"
    android:indeterminate="false"
    android:layout_centerInParent="true"
    android:max="100"
    android:progress="10"
    android:progressDrawable="@drawable/progressbar" />

Done! Now you will see a CircleProgressBar. You can use it the exact same way like with the normal drawable. Have Fun.

Samstag, 2. August 2014

ähm...hello world :)

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Toast.makeText(this, "Hello world!", Toast.LENGTH_LONG).show();
}