Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

15 June 2019

Mockito 2.0 and a thousand failing unit tests

Wow this killed me for a few days. I upgraded my long since out of date Mockito to the latest version 2.28.2 from version 1.something. Instantly 90% of my unit tests failed. Queue a long drawn out investigation to try and figure out what was happening. Numerous culprits were held under the spotlight and shaken down.

Ultimately, (as is usually the case) the answer was somewhat simple. My mock methods had all been declared irrelevant by this change to Mockito:

anyString() no longer accepts nulls.

So a mock method like this:

when(mockClass.mockMethod(anyString())).thenReturn("All your base are belong to me")

Simply stopped returning anything.

https://github.com/mockito/mockito/issues/185

The workaround is either to use any() or a deliberate null.

when(mockClass.mockMethod(any())).thenReturn("All your base are belong to me")


when(mockClass.mockMethod(isNull())).thenReturn("All your base are belong to me")


I hope this helps someone avoid my mistakes. Happy coding.

31 October 2017

RxJava Publish Subject is pretty awesome


Hopefully you're all now using RxJava because it's pretty awesome. Now I'm not about to force on you another tutorial, there are plenty out there. I've been using RxJava for ages now and only just discovered a new thing. I love discovering new things, especially about something I've used for ages. So I discovered PublishSubject, this is basically an amazing alternative to creating callbacks all over the place.

Normally if I were to implement a callback from a fragment to an activity I'd do something like this:

public interface IFragmentListener{
    void onFragmentSuccess();
}

private IFragmentListener mFragmentListener;

Then of course my activity would implement that interface and receive callbacks when mFragmentListener is called.

However there's a better way to do things, and that's with publishSubject.

private PublishSubject<String> mSelectionObservable = PublishSubject.create();

mSelectionObservable.onNext("Hello");

public Observable<String> getSelectionObservable() {
    return mSelectionObservable;
}

PublishSubject allows you to declare an observable which you can subscribe to and send callbacks whenever you want. As you can see when I call mSelectionObservable.onNext().

Your activity can subscribe to the publishSubject like this

frag.getSelectionObservable()
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .doOnNext(new Action1<String>() {
    @Override
    public void call(String s) {
        Log.d(TAG, "call: ");
        Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
    }
}).subscribe();

Hope that helps make your code more awesome!

30 December 2016

Improving on SimpleDateFormat


I'm a big fan of SimpleDateFormat, but it suffers from one critical problem. Your date format is forced on the user. I've learnt the hard way (as have most developers) that American's have their own date format (mm/dd/yyyy), us Brits have our own format (dd/mm/yy) and of course there are many other countries that also have different ideas.

Using SimpleDateFormat means you pick a format and the user has to like it. In some cases this could even be very frustrating for the user. You could of course allow them to pick their own format, but that's a lot of work.

My point here is Android has a little used method of doing this hard work for you and it utilizes the user's locale as set in the phone settings, to calculate this format. That is java.text.DateFormat.
So if the user has English American locale, then DateFormat will use that, if it has en-UK then that's the format it'll use. Magic!


import java.text.DateFormat;
DateFormat dateTimeFormat;


dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, Locale.getDefault());


Date date = new Date();
dateTimeFormat.format(date);


Next time you're displaying a date or a time, why not try using DateFormat instead of forcing your format on the user?

22 December 2016

Inject Javascript into Android WebView

Here's an interesting one I stumbled across the other day. The ability to "inject" some javascript into a webview and override the existing javascript for a webpage.

Let's say you want to override an existing javascript function, maybe one that's broken or you just want to change functionality. This is possible using onPageFinished.

Now I'm not going to say you *should* do this, nor will I say it is recommended or a good idea. I'm just pointing out that it's possible and saying it's mildly interesting.
Obviously there are warnings that go with enabling javscript on your webview and you should take heed of them over my example here.

Here's my HTML that I will load in a webview. For this example I've loaded it locally from my assets folder. I see no reason why this wouldn't work on a remote page.


<html>
    <head>
        <title>hello</title>
        <script>
            function myFunction() {
                document.getElementById("demo").innerHTML = "Gonzo was here";
            }
        </script>
    </head>
    <body>
        <p>
            <button name="Sumit" label="Submit" value="Submit" id="Submit" onclick="myFunction()">Submit</button>

            <br /><br />
            <div id="demo">Hello</div>
        </p>
    </body>
</html>


Let's try and change that javascript function to do something else:


final WebView webView = (WebView) findViewById(R.id.webView);

webView.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        webView.loadUrl("javascript:function myFunction(){document.getElementById(\"demo\").innerHTML = \"Paragraph changed.\";}");
    }
});

WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.loadUrl("file:///android_asset/test.htm");


As you can see we've injected a custom function that overrides the results with a different output. Interesting huh?

30 May 2016

Android Lambda

I've heard a lot about lambda recently and how amazing Java 8 is. I'm not really sure this will have a huge impact on Android as I fail to see the relevance, none the less I was interested and keen to experiment.

I thought I'd create a super simple example by changing the OnClickListener of a button and trying to replace it with a lambda. Nothing shocking here, just wanted to know if I could. So I created a brand new project and here's how I got it working.

Before we go any further you'll need to:

  • Donwload the Android N SDK, 
  • Download JDK 1.8 (and target it with Android Studio) 
  • You'll need an emulator or device capable of running Android N.

Android N

To use lambdas we have to target Android N so I've updated the compile version, build tools, min Sdk and target Sdk.

android {
    compileSdkVersion 'android-N'
    buildToolsVersion '24.0.0-rc3'

    defaultConfig {
        applicationId "eightest.test.com.eighttest"
        minSdkVersion 'N'
        targetSdkVersion 'N'
        versionCode 1
        versionName "1.0"
    }

The code

This is what we would normally do for a onClick
findViewById(R.id.activity_main_text).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        showToast()
    }
});

This is how a lambda makes it look a little cleaner
findViewById(R.id.activity_main_text).setOnClickListener((View v) -> {showToast();});

Target Java 8

We need to specifically target java 8 (do this inside the Android brackets, after buildTypes)
    compileOptions {
        targetCompatibility 1.8
        sourceCompatibility 1.8
    }

Utilise Jack compiler

Now we need to tell Android to use the Jack compiler which will allow us to utilise Java 8.
    defaultConfig {
        applicationId "eightest.test.com.eighttest"
        minSdkVersion 'N'
        targetSdkVersion 'N'
        versionCode 1
        versionName "1.0"
        jackOptions {
            enabled true
        }
    }

This content is copyright and owned by https://webdeveloperpadawan.blogspot.com/

03 May 2016

Android n00b lessons

I've been training a couple of relatively junior Android developers recently and I've seen a few mistakes repeated. I thoughts I'd mention them here in the hope it will help someone else. This isn't supposed to be a laugh at anyone's expense, just a discussion about how to improve your code and become a better developer.
  1. Don't close a cursor properly
    I see this in on-line examples, in old code and in new code written by juniors. The fact is there are a lot of things that can go wrong when using a cursor, so you need to be a bit careful and make sure you don't throw an error or waste memory. 
    1. First and foremost close the cursor.
    2. Your cursor might be null
    3. Use finally to close your cursor, it works really well!

    Cursor data = context.getContentResolver().query(MyProvider.DETAILS, null, null, null, null);
    
    try {
        if (data != null && data.moveToFirst()) {
            retVal = data.getString(data.getColumnIndex(columnName));
        }
    } finally {
        if(data != null) {
            data.close();
        }
    }

  2. Catching an error badly
    Arrrg! I see this far too often. An empty catch block. Even if it's just a Log.e, that's better than nothing. OK I'll admit there are some situations where you just don't care if an error is thrown (like above), but all too often people just throw the try in to avoid compile errors and leave the catch empty. Don't do it!

            try {
                int a = 1;
            }catch(Exception e){
                    
            }
    

  3. Excessive use of RecyclerView
    RecyclerView is new, it's cool and it's heavily publicized. That doesn't mean you should use it ALL the time. If you've got a small simple app with one ListView that will show about three elements, please don't bring an entire new library into the project. A ListView is OK. If your ListView is small and your needs simple, don't panic, you can use a ListView. The world will not end, I promise. Yes the RecyclerView is efficient, especially when you want to use animations or change elements but sometimes it's like cutting the grass with a machine gun. I don't want to say RecyclerView is bad, it's a fantastic tool, but use your perspective and let's keep it simple people!

  4. Variables in a loop
    This one was really interesting. Conventional wisdom often states you should never create a variable in a loop, and to be honest I always held with this. However I did some research recently and it seems that it's actually most efficient to declare the variable in the smallest scope possible. If that means declaring it in the loop, then fine, as long as that's NOT then used outside the loop.

    for (Person person : people) {
        String desc = person.getDescription();
        ...
    }
    

If you've any more suggestions then I'd love to hear them.

11 November 2015

Android layout with view fixed to bottom


I recently submitted a stack overflow question about a problem I was having. I didn't get the answer I was looking for so eventually I answered it myself.

The concept I wanted to achieve was to have a view stick to the bottom of the screen. Pretty easy in a relative layout with alignParentBottom="true". However the screen was a registration screen, so it had edit text boxes. When you click on an edit text box, the soft keyboard appears. The problem I then had of course was that my bottom view then popped up to the top of the keyboard and obscured most of the screen.



The above diagram goes a little way to representing what I was seeing, with three being the keyboard and two being the view I wanted stuck to the bottom. The overall container being a RelativeLayout with the blue being a ScrollView and the red alignParentBottom="true".

After much head scratching I finally stumbled across a solution, although it was a bit different to what I was expecting.

First I moved the red bottom view into the scrollview and added a stretcher view with a height of zero.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ScrollView
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true"
        android:isScrollContainer="false">

        <LinearLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <EditText />
            <EditText />

            <View
                android:id="@+id/stretcher"
                android:layout_width="match_parent"
                android:layout_height="0dp" />

            <TextView
                android:id="@+id/2"
                android:layout_gravity="bottom"
                text="2" />
        </LinearLayout>
    </ScrollView>
</RelativeLayout>


The next step was to add a view tree observer.

    final View mainLayout = getView();
    final View mainContent = getView().findViewById(R.id.content);
    final View stretcherView = getView().findViewById(R.id.stretcher);

    //Main layout uses weight some, so we can't hard code the size of the circles.
    //We must dynamically re-size
    mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (android.os.Build.VERSION.SDK_INT >= 16) {
                mainLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } else {
                mainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }

            //Calculate the desired height of the stretcher view to be the remainder between full screen and content.
            int stretchHeight = mainLayout.getHeight() - mainContent.getHeight();

            //Apply calculated height remainder to stretched view.
            //This enables our bottom box to be pushed to the bottom without obstructing the content when the keyboard appears.
            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) stretcherView.getLayoutParams();
            params.height = stretchHeight;
            stretcherView.setLayoutParams(params);
        }
    });


This listener watches the entire screen and then measures the difference between the full screen and the scrollview. It then inflates the stretcher view by this difference. What we're effectively doing is nudging the bottom view to the bottom of the screen. Now when we load the page the bottom view sits nicely on the bottom of the screen, but when the keyboard moves the bottom view stays underneath and appears in the scroll.

Hope this helps somebody else!

31 May 2015

Android Design Support Library Collapsing Toolbar


Following Google IO I'm always that much more inspired to try a few new things with Android.
Shortly after IO I noticed this new post on the devlopers blog:
http://android-developers.blogspot.co.uk/2015/05/android-design-support-library.html

I immediately loved the CollapsingToolbarLayout as I've had to make something similar myself and never quite got it perfect. The fact that Google are releasing quick and easy ways to implement these design elements is absolutely fantastic. Long may it continue!

When I saw Ian Lake's post on this collapsing toolbar I was super keen to give them a go:
https://plus.google.com/+IanLake/posts/QGR5XNcPPeG

I didn't get especially far until this example from Chris Banes:
https://github.com/chrisbanes/cheesesquare

I decided (as usual) to make mine as simple as possible, stripping out as much of the superfluous stuff as I could.

First we need the support and design libraries:
    compile 'com.android.support:appcompat-v7:22.2.0'
    compile 'com.android.support:design:22.2.0'
    compile 'com.android.support:recyclerview-v7:22.2.0'

First thing we'll do is the xml for our main activity
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|enterAlways" />

        <TextView
            android:text="@string/hello_world"
            android:padding="20dp"
            android:layout_width="match_parent"
            android:textColor="#00FF00"
            android:layout_height="wrap_content"/>
    </android.support.design.widget.AppBarLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/activity_main_listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>

The important bit here is the AppBarLayout which contains the Toolbar and a TextView which I want to hover over the top of the listview.

Second you'll notice we're using a RecyclerView which is new to me but looks to be more powerful than Listview.

Our ActivityMain just passes an ArrayList of Strings too the Recycler View
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.activity_main_listview);
recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
recyclerView.setAdapter(new MyRecyclerView(this, players));

Oh and of course don't forget to make sure your Activity uses AppCompatActivity and your manifest has a theme which overrides or implements Theme.AppCompat.Light.NoActionBar
You'll need the MyRecylcerView class but that's fairly boring and I borrowed most of it from Chris Banes, so I'll let you look at that in the git repo (bottom).

Now we need to look at the detail page where we use CollapsingToolbarLayout. First the xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:theme="@style/ActionBarPopupThemeOverlay"
        android:fitsSystemWindows="true">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            android:fitsSystemWindows="true"
            app:contentScrim="@color/colorPrimary"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleMarginEnd="64dp">

            <ImageView
                android:id="@+id/backdrop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:theme="@style/ActionBarPopupThemeOverlay"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_collapseMode="pin" />
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:paddingTop="24dp">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:textColor="@color/colorAccent"
                android:text="All your base are belong to me." />
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

Here we use a NestedScrollView instead of a RecyclerView, hence the big list of TextViews

The Activity is even simpler here, we read in the extra and setup the toolbar title and background image, then setup the action bar so it's an up navaigation and set the title:
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle(muppetName);

That's basically it, a few new concepts and tools here but its super easy.

Here's the GitHub repo of all of this:
https://github.com/jimbo1299/androiddesigntest


01 March 2015

Security isn't a dirty word Blackadder

Hopefully we all understand the concepts behind asymmetric (Public / Private key) encryption. It’s something we use all the time (https, SSL etc) but I've never actually put code to screen and tried to implement it. I've always relied on standard symmetric-key algorithm. So I thought I’d give it a go in Java / Android and along the way I learned a lot. In this blog article I thought I’d outline a few things I've learned. I’ll put some code up as I go, but I’d like to try and focus a bit more on the lessons.
All security is equal, except some more equal than others
We all know in symmetric encryption DES is bad, right?
DES is now considered to be insecure for many applications
http://en.wikipedia.org/wiki/Data_Encryption_Standard#Brute_force_attack


Well in theory public / private key encryption is infinitely better as long as you never give out your private key. Easy peasy, so we choose one of these and away we go:
  • RSA
  • EIGamal
  • Diffie-Helman
So I want to take a basic string “All your base are belong to me” and I want to encrypt it using a public key and decrypt it using a private key.
Rush to code

Impatient as I am I rush to get some code in and find this code to try out:
byte[] data = readBytesFromfile(“mypublickey”);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(data); 
KeyFactory kf = KeyFactory.getInstance("RSA");
pubKey = kf.generatePublic(keySpec);

Great, now I need a public and private key to test my amazing new code.

I learn a few bits about encryption

I’d heard of PGP and apparently this has no known weaknesses, perfect, I want this! So away I go and find a tool to generate my PGP public and private key. I throw these into my java code and straight away get an error. Hmmm. Something doesn't feel right here. Plus I'm not too sure about PGP and OpenPGP. OK back to wikipedia. Apparently PGP is a protocol, not an algorithm and for its asymmetric files it uses RSA anyway! Doh! So I resort to RSA and now I need to generate an RSA key.


So I've already got puttyGen installed and it I don’t know why it says SSH but it definitely says RSA right there with a big button saying “Generate”. Boom, surely this will work, nothing can stop me now!
Now I get a java error InvalidKeySpecException
Hmm, after some serious time googling I ask stack overflow
http://stackoverflow.com/questions/28218636/invalidkeyspecexception-using-public-key
Although it doesn't solve my problem, Maarten alerts me to the fact that in java I need to use the X509 format.
Hang on SSH is a protocol isn't it? (Back to wikipedia). Right ok so PGP and SSH are protocols that implement asymmetric encryption using the RSA algorithm. I don’t want a protocol, I want to just generate an encrypted string.


To do that I need a public key which java can read. So all I need is to generate a key in the right format….That makes sense.

Using KeyTool and OpenSSL to generate a 509 certificate


This doesn't take me long using java keytool and openssl to generate an x509 certificate.
keytool -genkey -keyalg RSA -keysize 1024 -keystore C:\temp\hello.keystore

keytool -importkeystore -srckeystore C:/temp/hello.keystore -destkeystore C:/temp/hello.p12 -deststoretype PKCS12

openssl pkcs12 -in C:/temp/hello.p12 -out C:/temp/hellonew.pem -nodes

openssl x509 -in C:/temp/hellonew.pem -inform PEM -out C:/temp/hellodernew.der -outform DER

Reading an X509 certificate
Now we need to adapt our code to read the key in the new format.
public static PublicKey getPublicKey(byte[] keyBytes){
    PublicKey publicKey = null;

    if(keyBytes != null) {

        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory kf = null;
        try {
            kf = KeyFactory.getInstance("RSA");
            publicKey = kf.generatePublic(spec);
        } catch (NoSuchAlgorithmException e) {
            Log.e(TAG, "NoSuchAlgorithmException");
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            Log.e(TAG, "InvalidKeySpecException " + e.getMessage());
            e.printStackTrace();
        }
    }

    return publicKey;
}

This means we can now use our PublicKey to encrypt our message! Wohoo


Decryption

To decrypt we use a similar function

    public static PrivateKey getPrivateKey(byte[] keyBytes){
        PrivateKey privatekey = null;

         if(keyBytes != null) {
            PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory kf = null;
            try {
                kf = KeyFactory.getInstance("RSA");
                privatekey = kf.generatePrivate(spec);
            } catch (NoSuchAlgorithmException e) {
                Log.e(TAG, "NoSuchAlgorithmException");
                e.printStackTrace();
            } catch (InvalidKeySpecException e) {
                Log.e(TAG, "InvalidKeySpecException");
                e.printStackTrace();
            }
        }

         return privatekey;
    }


Encrypting a large file

For various reasons I've also learned you can’t just encrypt a file with your public key. This guy gives an excellent description of what you should be doing:


The basic idea is as such:
  1. Create a session key using symmetric encryption, AES for example.
  2. Then encrypt the file using this session key
  3. Using your public key encrypt the session key
  4. Send the AES encrypted file and the public key encrypted session key together
  5. Your server / recipient uses the private key they have and decrypts the session key then using that decrypts the file.


This method allows for fast encryption and secure transmission. If anyone brute forces the session key, they've only ever got one file. They need to start again for every single new file!

Anyway, that’s about what I've learned on this particular journey. I hope its of some help.

25 February 2015

Unit Tests, wonderful Unit tests


As I've mentioned before, I quite like unit tests. At the hands of Adam I've learnt to love and respect them. So when I had to write a simple function to ensure a password:

  • Is at least eight characters
  • Contains an upper-case character
  • Contains a lower-case character
  • Contains a digit
  • Contains a special character
I thought this would be a great reason to add some new unit tests in. Plus I'll be damned if I'm going to do all the typing on a phone to test and register all the various cases I can think of. As it happens this turned out to be a great idea because there was at least one case I'd missed.

Kids, unit tests work!

I thought I'd turn this into a challenge, how would you write the desired function? I'll provide the unit tests and you can impress me with your regex or your clever functions! Feel free to use any language you so desire. Winner gets the glory!

    @SmallTest
    public void testBlank(){
        String password = "";
        assertFalse(Utils.isPasswordValid(password));
    }

    @SmallTest
    public void testLower(){
        String password = "a";
        assertFalse(Utils.isPasswordValid(password));
    }

    @SmallTest
    public void testUpper(){
        String password = "A";
        assertFalse(Utils.isPasswordValid(password));
    }

    @SmallTest
    public void testNumber(){
        String password = "123";
        assertFalse(Utils.isPasswordValid(password));
    }

    @SmallTest
    public void testPadded(){
        String password = "     ";
        assertFalse(Utils.isPasswordValid(password));
    }

    @SmallTest
    public void testWhite(){
        String password = "\t\t";
        assertFalse(Utils.isPasswordValid(password));
    }

    @SmallTest
    public void testGood(){
        String password = "ab12CD*!";
        assertTrue(Utils.isPasswordValid(password));
    }

    @SmallTest
    public void testNoUpper(){
        String password = "ab12cd*!";
        assertFalse(Utils.isPasswordValid(password));
    }

    @SmallTest
    public void testNoLower(){
        String password = "AB12CD*!";
        assertFalse(Utils.isPasswordValid(password));
    }

    @SmallTest
    public void testNoNumber(){
        String password = "abcdCD*!";
        assertFalse(Utils.isPasswordValid(password));
    }

    @SmallTest
    public void testNoSymbol(){
        String password = "abcdCD12";
        assertFalse(Utils.isPasswordValid(password));
    }

    @SmallTest
    public void testGoodLong(){
        String password = "abcdCD12*&asdbbs167672HGSAHGAS!&^";
        assertTrue(Utils.isPasswordValid(password));
    }

    @SmallTest
    public void testGoodOne(){
        String password = "aaaaaA1\"";
        assertTrue(Utils.isPasswordValid(password));
    }

19 February 2015

Android Studio Build Types

Android Studio, somewhat predictably, allows two deployment modes debug and release. Configuring this in gradle allows you to configure certain options like if we should use proguard or not and what signing config to use. However this can be taken further to allow customization of certain java files based on release or debug build.


I’m not talking here about flavours, which is something slightly different. What I want to do is use one java class for debug and a different one for a release build. This allows me to suppress some debugging functions on a release build.

1. Create a Simple Project

First I create a new project and quickly setup a simple MainActivity with a button to launch a SecondActivity. I’m going to keep these activities very simple just to prove the concept. Don’t create the SecondActivity yet, we’ll do it in the next step.

2. Create Build Types

First update your app/build.gradle file to reflect the following, note the buildTypes:


apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.example.android.myapplication"
        minSdkVersion 10
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }

    signingConfigs {
        debug {
            storeFile file("--path-to-debug-keystore--")
        }
        release {
            storeFile file("--path-to-release-keystore--")
            storePassword "--password--"
            keyAlias "--alias--"
            keyPassword "--password--"
        }
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            signingConfig signingConfigs.release
        }
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            signingConfig signingConfigs.debug
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
}

Note I’ve included a release keystore here with password and alias password. This is obviously not recommended for a real app. You would ideally release using the “Generate Signed APK…” However I’ve done it in this example as it allows me to quickly release using the build button.

3. Create folder structure

Create release and debug folders inside src. Inside both create a java folder, one (normally debug) will go blue and allow you to create a package. Create a new package matching your default package. In the other (normally release) you’ll have to just create folders instead of a package. Now create a SecondActivity.java in both. As the image below shows, you'll never get both release and debug to be correctly marked as a package. However when you switch using the build variants tab, you'll see the currently selected one change.



4. Test

Now you’re setup to configure your second activity as you wish, in my example I had each update a textview to say debug or release. Open the Build Variants tab in Android Studio and switch between build variants. This allows you to toggle the modes and release as such.

26 January 2015

REST Web Services Part 2 - Java

Sometime last year, I started what I hoped would be a blog post series on REST in various languages.




Part one was using CFML and Taffy. Due to the usual complaints of time and patience it’s taking me forever to continue it, but hey ho. Here’s the second part. In this one I wanted to look at a java implementation of REST services. To make it more interesting I wanted to use Google App Engine (GAE) for hosting. Google App Engine is a great resource for testing as its pretty solid and a generous with its free quota. Plus it frees me from the worries of settings up a proper environment.


Obviously using Java for REST and then forcing all of this into the specifications of GAE may prove a little tricky. However I'm sure there are some technologies out there which do all the hard work leaving me to just define my rest services with minimal fuss.


So I started out with some Googling of GAE and REST. Support seemed overwhelmingly in favour of something called Restlet. Which with a bit of reading seemed to be a framework for creating REST services with Java. Plus it had a specific release for Google App Engine. Perfect!


Retlet didn’t have a “built for stupid” tutorial, so I've made my own. It’s loosely based on this intro



Start by downloading Restlet gae zip file and unzip




So lets use the backend project we created in my last tutorial




Create a libs directory under the root of backend.


Opening your unzipped Restlet folder to this directory restlet-gae-2.3.0\lib find the following two files:


  • org.restlet.ext.servlet.jar
  • org.restlet.jar


and copy them into your new libs directory and add this line to your gradle dependencies


compile fileTree(dir: 'libs', include: ['*.jar'])


Now add the following .java files to you backend package:
  • MyApplication
  • MyServerResource
  • NewServerResource


MyApplication.java
package com.example.myapplication.backend;

import org.restlet.Application;
import org.restlet.Restlet;
import org.restlet.routing.Router;

public class MyApplication extends Application {

    /**
     * Creates a root Restlet that will receive all incoming calls.
     */
    @Override
    public Restlet createInboundRoot() {
        // Create a router Restlet that routes each call to a
        // new instance of HelloWorldResource.
        Router router = new Router(getContext());

        // Defines only one route
        router.attachDefault(MyServerResource.class);
        //router.attach("/base/{username}", NewServerResource.class);
        //router.attach("/base", NewServerResource.class);

        return router;
    }
}
MyServerResource.java
package com.example.myapplication.backend;

import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;

public class MyServerResource extends ServerResource{

    @Get
    public String represent(){
        return "Hello world";
    }
}
Now edit your web.xml file


webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
    <display-name>first steps servlet</display-name>

    <servlet>
        <servlet-name>SystemServiceServlet</servlet-name>
        <servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
        <init-param>
            <param-name>services</param-name>
            <param-value>com.example.myapplication.backend.MyEndpoint</param-value>
        </init-param>
    </servlet>

    <servlet>
        <servlet-name>RestletServlet</servlet-name>
        <servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
        <init-param>
            <param-name>org.restlet.application</param-name>
            <param-value>com.example.myapplication.backend.MyApplication</param-value>
        </init-param>
    </servlet>

    <!-- Catch all requests -->
    <servlet-mapping>
        <servlet-name>SystemServiceServlet</servlet-name>
        <url-pattern>/_ah/spi/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>RestletServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

Note despite the Restlet tutorial I've left SystemServiceServlet in there. Ideally I’d want to remove this but GAE whines incessantly if you don’t have a servlet named SystemServiceServlet. Perhaps there’s a way to rename the RestletServlet but maybe one for another day.


That’s it. Now I shall try and explain a bit what’s going on. MyApplication is where the magic really happens, this is where we configure our REST urls. This line sets the default behaviour


router.attachDefault(MyServerResource.class);


Which if you open MyServerResource.java you’ll see it’s super simple it just says “hello world”. If you were to only include the attachDefault method (as above) you could happily run your app and http://localhost:8080/hippopotamus would return Hello world. This is a super simple GET request.


Fantastic! One job done.


Now Let’s make it a big more complicated. Let’s add a GET method with a param and a POST method. (un-comment the two router.attach lines in myApplication).


NewServerResource.java
package com.example.myapplication.backend;

import org.restlet.data.Form;
import org.restlet.representation.Representation;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.ServerResource;


public class NewServerResource extends ServerResource{

    @Get
    public String restGetMethod(){

        String username  = "";
        try{
            //get param from request
            username = getRequest().getAttributes().get("username").toString();

        }catch(Exception e){
            username = "default";
        }

        return "Dear " + username + ". All your base are belong to me!";
    }

    @Post
    public String restPostMethod(Representation r){

        String username = "";

        //Get form details
        final Form form = new Form(r);

        //get username field out of form
        username = form.getFirstValue("username");

        return "Morning " + username + ". I've had it with all these snakes on the plane.";
    }
}

So a bit more complicated. The first is a @Get method which looks for a username param and returns “Dear username. All your base are belong to me!”


The second is based on a POST method. Here we’re grabbing the Form object and requests a value for the field username. It returns “Morning username. I've had it with all these snakes on the plane.”


So lets take a look how we pass these params to these methods back in MyApplication.


router.attachDefault(MyServerResource.class);
router.attach("/base/{username}", NewServerResource.class);
router.attach("/base", NewServerResource.class);


When you use router.attach you need to give it a url. So you can see here if we pass localhost:8080/base/gonzo then we’ll hit NewServerResource with the param username=gonzo. This is out GET request.


If we pass /base we’ll hit NewServerResource without any params. This will be our POST request.


So to summarize here are the responses we can expect to see from various REST urls:










Lastly to test the POST I’ve constructed a little form
<html>
    <head>
        <title>Post test</title>
    </head>
    <body>
        <p>Hello this is a post test for localhost</p>
        <br />
        <form action="http://localhost:8080/base" method="POST">
            <input name="username" type="text" />
            <button name="submit" type="submit" value="submit">Submit</button>
        </form>
    </body>
</html>

Note the input box. If we fill that in and submit we get this:


Morning Kermit. I've had it with all these snakes on the plane.


Fantastic, exactly what we wanted.


This is great, I’m delighted, a very easy way to get REST running on the cloud. Good work to all the chaps at Restlet, great little product and I feel like I’m only scratching the surface.

22 January 2015

Google App Engine and Android playing nice.

I'm a big fan of cloud services, especially when they give you a free or basic quota such as Google App Engine which you can use for development or testing. I’ve done quite a bit of work with Google App Engine before but not in a while. It became a real heavy beast involving importing add ons to Eclipse and configuring a multitude of environment settings.

However recently I've moved to Android Studio and apparently Google Cloud support is built in. Learning this I was then inspired by a recent post on the Android Developers Blog:
http://android-developers.blogspot.co.uk/2014/12/build-mobile-app-services-with-google.html

I felt this wasn't a great tutorial, there were large sections left out and it basically didn't work nearly as easily as I’d hoped it would. Sorry Android Developers, but not your best work. Still the steps to get started were simple enough:
  1. Create a super simple Android app. Basic Hello world stuff.
  2. Give your app Internet permissions
  3. Create a new Google Cloud Module
    • File -> New Module
    • Click “Google Cloud Module”
    • Select App Engine Java Endpoints Module
Android studio will now create a GAE backend module for you and automatically tie it into your Android app. Now you need a bean and an endpoint.

MyBean.java
package com.example.myapplication.backend;

public class MyBean {

    private String myData;

    public String getData() {
        return myData;
    }

    public void setData(String data) {
        myData = data;
    }
}


MyEndpoint.java
package com.example.myapplication.backend;

import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiNamespace;

import javax.inject.Named;

/**
 * An endpoint class we are exposing
 */
@Api(name = "myApi", version = "v1", namespace = @ApiNamespace(ownerDomain = "backend.myapplication.example.com", ownerName = "backend.myapplication.example.com", packagePath = ""))
public class MyEndpoint {

    /**
     * A simple endpoint method that takes a name and says Hi back
     */
    @ApiMethod(name = "sayHi")
    public MyBean sayHi(@Named("name") String name) {
        MyBean response = new MyBean();
        response.setData("Hi, " + name);

        return response;
    }

}
and here’s the Gradle file:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.google.appengine:gradle-appengine-plugin:1.9.14'
    }
}

repositories {
    mavenCentral();
}

apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'appengine'

sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7

dependencies {
    appengineSdk 'com.google.appengine:appengine-java-sdk:1.9.14'
    compile 'com.google.appengine:appengine-endpoints:1.9.14'
    compile 'com.google.appengine:appengine-endpoints-deps:1.9.14'
    compile 'javax.servlet:servlet-api:2.5'
}

appengine {
    downloadSdk = true
    appcfg {
        oauth2 = true
    }
    endpoints {
        getClientLibsOnBuild = true
        getDiscoveryDocsOnBuild = true
    }
}


Frustratingly you’ll get red errors all over the place. Cannot resolve symbol api. This really winds me up and I’ve not yet figured out how to fix it. However it does build and run with these problems, so not really an error!

If you change the run drop down to “backend” and hit run hopefully this will all compile and you’ll get an Android Studio message with a localhost url. This is Android Studio setting up a local version of Google App Engine and using Jetty to host it. You should see a url output which you can copy to your browser, something like:
http://localhost:8080/

Hitting this url you should get an index file saying Hello Endpoints or something with a nice pretty bootstrap wrapper. You can enter something into the text field and your GAE application will say Hi to you.

Now we need to plug this into our Android app. First we need a new AsyncTask

package tester.example.com.myapplication;

import android.content.Context;
import android.os.AsyncTask;
import android.support.v4.util.Pair;
import android.widget.Toast;

import com.example.myapplication.backend.myApi.MyApi;

import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.extensions.android.json.AndroidJsonFactory;
import com.google.api.client.googleapis.services.AbstractGoogleClientRequest;
import com.google.api.client.googleapis.services.GoogleClientRequestInitializer;


import java.io.IOException;

class EndpointsAsyncTask extends AsyncTask<Pair<Context, String>, Void, String> {
    private static MyApi myApiService = null;
    private Context context;

    @Override
    protected String doInBackground(Pair<Context, String>... params) {
        if(myApiService == null) {  // Only do this once
            MyApi.Builder builder = new MyApi.Builder(AndroidHttp.newCompatibleTransport(),
                    new AndroidJsonFactory(), null)
                    // options for running against local devappserver
                    // - 10.0.2.2 is localhost's IP address in Android emulator
                    // - turn off compression when running against local devappserver
                    .setRootUrl("http://10.0.2.2:8080/_ah/api/")
                    .setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
                        @Override
                        public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest) throws IOException {
                            abstractGoogleClientRequest.setDisableGZipContent(true);
                        }
                    });
            // end options for devappserver

            myApiService = builder.build();
        }

        context = params[0].first;
        String name = params[0].second;

        try {
            return myApiService.sayHi(name).execute().getData();
        } catch (IOException e) {
            return e.getMessage();
        }
    }

    @Override
    protected void onPostExecute(String result) {
        Toast.makeText(context, result, Toast.LENGTH_LONG).show();
    }
}
Now in your app activityMain or somewhere, fire a call to the AsyncTask:

new EndpointsAsyncTask().execute(new Pair(this, "Manfred"));

The dependencies in your Android app should look like this:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
    compile 'com.google.android.gms:play-services:6.1.71'
    compile project(path: ':backend', configuration: 'android-endpoints')
}

Now if you run your Android app in a Android Virtual Device, you should see your local server respond with a Hi Message.

This is a pretty basic example, but you get the idea and its a great first step on the path toward Android and Google Cloud playing well together.