Sunday, June 26, 2016

Android Development - Access Activity Instances from Other Classes

Each page on Android app is defined by an activity instance or an object. Sometimes, you may want to edit the instance externally, i.e., from other objects or classes. The following code shows how to do access the instance of MainActivity class externally:

...
public class MainActivity extends Activity {
  private static MainActivity instance;
  private static void setInstance (MainActivity instance) {
    MainActivity.instance = instance;
  }
  public static MainActivity getInstance () {
    return instance;
  }
  public void somePublicMethod () {
  ...
  }
  public void onCreate (Bundle savedInstanceState) {
    super.onCreate (savedInstanceState);
    setContentView (R.layout.activity_main);
    setInstance (this);
    ...
  }
  ...
}

As you can see from the code above, static variable instance is to be assigned in the onCreate method. Now, this instance can be accessed externally by calling the public getInstance method, as shown below:

...
public class SomeClass {
  public void someMethod () {
    MainActivity.getInstance().somePublicMethod();
  }
}

This method is called singleton design, as there is only one instance of the Activity class, which we want to access externally.

Thursday, June 23, 2016

Android Development - Schedule a Task at Certain Time

First, you will need to edit the manifest xml file and add the following:

...
<manifest ... >
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    ...
    <application ... >
       <receiver android:name=".AlarmReceiver" />
    </application>
</manifest>

The permission will enable the Android system to wake up at the specified time. The receiver field declares BroadcastReceiver element to be used. Here, I will be using the name AlarmReceiver.

Next, create AlarmReceiver.java file with something similar to below:

...
public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
        wl.acquire();

        // Put here YOUR code.
        Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example

        wl.release();
    }

    public void setAlarm(Context context) {
        AlarmManager alarmManager;
        PendingIntent pi;

        alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent (context, AlarmReceiver.class);
        pi = PendingIntent.getBroadcast(context, 0, intent, 0);

        alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+5000, pi);
    }
}

Here, setAlarm method is specifying the scheduled time to be 5 secs after the current time. At that time, onReceive method will be invoked, so you will need to place your tasks there.

Finally, edit your activity java file to add the following code to schedule:

Context context = this.getApplicationContext();
AlarmReceiver alarm = new AlarmReceiver();
alarm.setAlarm(context);

That's it!

Android Development - How to Make Buttons Respond

In the series of Android Development posts, I will go over the very basics of Android programming intended for complete beginners. I won't be able to explain every singe details of the code, so one will need to refer here for general details.

Say you have a button that you would like to respond when a user tabs on it. In the layout xml file in the res folder, you will need to have your button element defined similar to below:

    <Button
        android:id="@+id/buttonSend"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/send"
        android:onClick="buttonAction" />

The necessary field for assigning any actions to "clicks" on the button is the last field, android:onClick="buttonAction". What it says is that when the user pushes on the button, the program will execute buttonAction function. Of course, we will need to define such function in the activity java file.

...
public class MainActivity extends Activity {
...
    public void buttonAction(View v) {
        // insert code for action
    }
...
}

That's it!

Saturday, June 11, 2016

C/C++ #define Directive Not-So-Obvious Mistake

Consider the following code below:
#include <stdio.h>
#define ABS(x) (x>=0 ? x : -x)
int abs (int x) {
   return x >= 0 ? x : -x;
}
int main () {
   printf ("ABS(1) = %d\n", ABS(1));
   printf ("ABS(-1) = %d\n", ABS(-1));
   printf ("ABS(2-1) = %d\n", ABS(2-1));
   printf ("ABS(1-2) = %d\n", ABS(1-2));
   printf ("abs(1) = %d\n", abs(1));
   printf ("abs(-1) = %d\n", abs(-1));
   printf ("abs(2-1) = %d\n", abs(2-1));
   printf ("abs(1-2) = %d\n", abs(1-2));
   return 0;
}

The code defines the absolute value evaluation procedure using both the C directive and a regular subroutine. In the main function, we are printing out four example values to verify if both methods work correct. What do you think the expected output would be?

Guess the answer first, and copy the code run it.
$ gcc ABS_test.c
$ ./a.out

Does your guess agree with the output? If so, then you must be an experienced C/C++ programmer! If not, do not worry. I did not get it the first time either. Both the C directive ABS(x) and C subroutine abs(x) are defined by the same expression, but one is erroneous while the other is fine. 

It turns out that the ABS(x) directive definition is incorrect and requires an extra parenthesis pair around last x:
#define ABS(x) (x>=0 ? x : -(x))

This is because the C directive is simply literal, replacing whatever expression in the parenthesis of ABS(...) into the definition. Below is actual code that is being compiled by the compiler:
ABS(1) ---> 1 >= 0 ? 1 : -1
ABS(-1) ---> -1 >= 0 ? -1 : --1
ABS(2-1) ---> 2-1 >= 0 ? 2-1 : -2-1
ABS(1-2) ---> 1-2 >= 0 ? 1-2 : -2-1

So, it should now be clear to you why the last expression's output was -3! By the way, the subroutine abs(x) is fine because the compiler will evaluate the value of whatever in the parenthesis of abs(...) before actually calling the function.

Friday, June 3, 2016

How to Setup SSH Login Email Alert for Mac OS X

This tutorial will discuss how to setup email alert for ssh login to your Mac OS X system. In particular, this has been tested on El Capitan only, but I am pretty sure that it should work with other versions as well. This is based on this post with slight modification.

First, create /etc/ssh/sshrc file with the following content
#!/bin/bash
ADDRESS="your_email@example.com"
IP=`echo $SSH_CONNECTION | cut -d " " -f 1`
DATE=`date`
echo "User $USER just logged in from $IP at $DATE" | mail -s "ssh login alert" "$ADDRESS"

Make sure to enter your own email address above to receive the alert mails. Set the owner of the file as root and set the execution flag.
$ sudo chown root /etc/ssh/sshrc && sudo chmod u+x /etc/ssh/sshrc

By the way, make sure there is no ~/.ssh/rc file, because the above script file won't be executed if ~/.ssh/rc file exists. To see more details on this, read sshd manual and search for sshrc
$ man sshd
/sshrc

This should do it. Make sure to check your spam folder for the alert mails.