Monday, 2 May 2016

Quran SDK (library) for Android

I've got a couple of Android apps that I've put together in my spare time the last few years which make use of verses of the Quran (Hifdh Tracker and Hifdh Tester). I'm in the process of making the code for these apps entirely open source. As a first step I've just extracted the database and helper methods for accessing verses of the Quran out of the apps and into an Android library of its own. You can find the code repository for the library here. The README in the repository explains how to incorporate and make use of the library in your own apps.

Thursday, 31 December 2015

Bash - basic script for requesting input from the user

As mentioned in this post, my know-how of Bash scripting is pretty nil so I've been skimming through this guide the last few days to get to grips with the basic concepts. I've put together this basic script as a reminder to myself for future reference of how to request and parse input from the user:

#!/bin/bash

echo "Enter the word that you'd like to add to the dictionary and then press [Enter]."

read WORD

PATH_DICTIONARY="/Users/adil/Downloads/MyDictionary.txt"
COUNT=`grep -c "^$WORD$" $PATH_DICTIONARY`

if [ $COUNT -gt 0 ]
then echo "Word is already contained in the dictionary."; exit;
fi

echo "\$COUNT = $COUNT"

echo "Adding $WORD to the dictionary..."

echo "$WORD" >> $PATH_DICTIONARY

echo "Done"

Bash - basic script for checking positional params

My know-how of Bash scripting is pretty nil so I've been skimming through this guide the last few days to get to grips with the basic concepts. I've put together this basic script as a reminder to myself for future reference of how to pass in and parse positional params in a script:

#!/bin/bash

if [ $# -lt 2 ];
then echo "Must pass in at least two params."; exit 1;
fi

#set -x
GREETING="Hello"
echo "$GREETING $USER"
#set +x

echo ""
echo "\$0 = $0"
echo "\$1 = $1"
echo "\$2 = $2"
echo ""

[ -f $0 ] && (echo "File $0 exists.";) || (echo "File $0 doesn't exist.";)

echo ""

if [ $1 -eq $2 ]; then
echo "The value of \$1 is equal to the value of \$2.";
elif [ $1 -lt $2 ]; then
echo "The value of \$1 is less than the value of \$2.";
else echo "The value of \$1 is greater than the value of \$2.";
fi

echo ""

AREA=$[$1 * $2]
echo "\$AREA = \$1 * \$2 = $AREA"

case $AREA in
([-][0-9]*)
    echo "The value of \$AREA is negative.";;
([0-9])
    echo "The value of \$AREA is < 10.";;
([1-9][0-9])
    echo "The value of \$AREA is < 100.";;
*)
    echo "The value of \$AREA is >= 100.";;
esac

echo ""
echo "Goodbye $USER"

If I run this script as follows: bash MyScript.sh, then I'll see this output:

Must pass in at least two params.

If, however, I run this script as follows: bash MyScript.sh 5 4, then I'll see this output:

Hello adil

$0 = MyScript.sh
$1 = 5
$2 = 4

File MyScript.sh exists.

The value of $1 is greater than the value of $2.

$AREA = $1 * $2 = 20
The value of $AREA is < 100.

Goodbye adil

That's it. That's a basic script which demonstrates how to perform some conditional checks on positional params passed into a script.

Saturday, 12 December 2015

Proguard: rules for building a library

So you have a library defined and you want to run proguard on it when building it to remove unused code and to obfuscate code. Of course you do not want to remove or obfuscate classes/interfaces/enums/methods/fields that are public since these will be called on by the projects that depend on your library.

Here are the rules that you need in your proguard config file:

-keepparameternames

-keep public interface com.mycompany.mylibrary.** {
    <methods>;
}

-keep public class com.mycompany.mylibrary.** {
    public <init>(...);
    public <fields>;
    public static <fields>;
    public <methods>;
    public static <methods>;
}

-keep public enum com.mycompany.mylibrary.** {
    public <init>(...);
    public <fields>;
    public static <fields>;
    public <methods>;
    public static <methods>;
}

The above is not an exhaustive list of all the rules which you might need but it's a starting point and should suffice for most libraries. If you need to add some more rules you'll need to get a grasp of the proguard rules syntax here: http://proguard.sourceforge.net/manual/usage.html

Wednesday, 2 December 2015

Android: start Service of another app

So you want to start a Service which belongs to another app? There's two ways to do this depending on how the Service has been defined.

Let's assume first that the Service is defined in the manifest of the first app with the exported attribute as follows:

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.thinkincode.someapp" >
    <application>
        <service
            android:name=".SomeService"
            android:exported="true" />
    </application>
</manifest>

In this case the Service can be started from the second app as follows:

Intent intent = new Intent();
intent.setComponent(new ComponentName(
    "com.thinkincode.someapp",
    "com.thinkincode.someapp.SomeService"));

startService(intent);

The better way of declaring a Service to be used by other apps is of course to use intent filters. So, going back to the manifest of the first app, this is how we'd define the Service:

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.thinkincode.someapp" >
    <application>
        <service
            android:name=".SomeService"
            android:exported="true">
            <intent-filter>
                <action android:name="StartSomeService" />
            </intent-filter>
        <service/>
    </application>
</manifest>

And this is how we'd now start the Service from the second app:

Intent intent = new Intent();
intent.setAction("StartSomeService");

startService(intent);

That's it! You should now be able to (1) define Services which can be used by other apps and (2) call on Services defined by other apps.

Monday, 23 November 2015

Head First Design Patterns, by Eric Freeman and Elisabeth Robson

I'm still reading this book so this is a Blog post in development. I'll add to this Blog post as I progress through the book.

Design Patterns

Strategy
  • Encapsulates interchangeable algorithms/behaviours and uses delegation to decide which algorithm to use.
  • Allows the algorithm to vary independently from the clients that use it.
Observer
  • Defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are updated and notified automatically.
Decorator
  • Attaches additional responsibilities to an object dynamically.
  • Provides a flexible alternative to subclassing for extending functionality.
  • Doesn't alter the interface but adds responsibility.
Factory Method
  • Defines an interface for creating an object, but lets subclasses decide which class to instantiate.
  • Lets a class defer instantiation to subclasses.
Abstract Factory
  • Provides an interface for creating families of related or dependent objects without specifying their concrete classes.
Singleton
  • Ensures a class has only one instance, and provides a global point of access to it.
Command
  • Encapsulates a request as an object, thereby letting you parameterise other objects with different requests, queue or log requests, and support undoable operations.
  • Decouples an object making a request from the one that knows how to perform it.
Adapter
  • Converts one interface to another.
  • Converts the interface of a class into another interface the clients expect.
  • Lets classes work together that couldn't otherwise because of incompatible interfaces.
Facade
  • Makes an interface simpler.
  • Provides a unified interface to a set of interfaces in a subsystem. Defines a higher-level interface that makes the subsystem easier to use.
Template Method
  • Encapsulates algorithms.
  • Defines the skeleton (/steps) of an algorithm in a method, deferring some steps to subclasses.
  • Subclasses decide how to implement steps in an algorithm (without changing the algorithm's structure).

Design Principles

Encapsulate what varies – Identify the aspects of your application that vary and separate them from what stays the same. Take the parts that vary and encapsulate them.

Program to an interface, not to an implementation.

Composition over inheritance – Favour composition over inheritance.

Loose coupling – Strive for loosely coupled designs between objects that interact.

Open-Closed – Classes should be open for extension, but closed for modification.

Dependency inversion – Design upon abstractions. Do not depend on concrete classes.
  • High-level components should not depend on low-level components; rather, they should both depend on abstractions.
  • No variable should hold reference to a concrete class.
  • No class should derive from a concrete class.
  • No method should override an implemented method of any of its base classes.
Principle of least knowledge – Talk only to your immediate friends.

The Hollywood Principle – Don't call us, we'll call you.
  • High level components call low level components, and not vice-versa.
Single responsibility – A class should have only one reason to change.

Sunday, 4 October 2015

Android - how to pass data from DialogFragment to Activity

So you've started a DialogFragment from within an Activity and want to request an action or pass data from the DialogFragment to the Activity. The best, cleanest way I find to do so is by means of local broadcasts. Here's how...

First, define a BroadcastReceiver in your Activity as follows:

private class LocalBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // safety check
        if (intent == null || intent.getAction() == null) {
            return;
        }

        if (intent.getAction().equals("SOME_ACTION")) {
           doSomeAction();
        }
    }
}

Second, declare an instance of LocalBroadcastReceiver in your Activity, as follows:

private BroadcastReceiver localBroadcastReceiver;

Third, instantiate the BroadcastReceiver in the activity's onCreate(Bundle) method:

localBroadcastReceiver = new LocalBroadcastReceiver();

Fourth, register for the activity to listen out for the local broadcasts in the activity's onResume() method:

LocalBroadcastManager.getInstance(this).registerReceiver(
        localBroadcastReceiver,
        new IntentFilter("SOME_ACTION"));

Fifth, unregister the broadcast receiver in the activity's onPause() method:

LocalBroadcastManager.getInstance(this).unregisterReceiver(
        localBroadcastReceiver);

Sixth and final, send the broadcast from wherever makes sense in your DialogFragment, as follows:

LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(
    new Intent("SOME_ACTION"));