Kah – The Developer

Defining a Context Menu for your View

Posted by: kahgoh on: 10 December, 2008

In Building a Menu for your Android (V1.0 R1) App, a menu was created for an application. The context menu can create menus based on the current view that has focus.

In order to create context menus, the application needs to know which views will have a menu. This is done by calling registerForContextMenu with the view. In this example, a context menu will be created for two text views.

 1 package com.android.Context;
 2
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.view.ContextMenu;
 6 import android.view.MenuItem;
 7 import android.view.View;
 8 import android.widget.TextView;
 9
10 public class Context extends Activity {
11   /**
12    * This will keep track of which item is selected.
13    */
14   public String checkedItem = "";
15   
16   @Override
17   public void onCreate(Bundle savedInstanceState) {
18     super.onCreate(savedInstanceState);
19     setContentView(R.layout.main);
20
21     registerForContextMenu(findViewById(R.id.primaryText));
22     registerForContextMenu(findViewById(R.id.secondaryText));
23   }
24

To set what gets displayed in the menu, the method onCreateContextMenu is overridden. This method will be told which view the context menu is being built for. Depending on the type of view that is passed in, the menuInfo parameter provides additional information. In this example, the information is not used.

25   public void onCreateContextMenu(
26       ContextMenu menu,
27       View v,
28       ContextMenu.ContextMenuInfo menuInfo)
29   {
30     // Show different menu items, depending on what is
31     // selected.
32     if (v.getId() == R.id.primaryText) 
33     {
34       menu.setHeaderTitle("Primary context");
35       addMenuItem(menu, "Primary 1", true);
36       addMenuItem(menu, "Primary 2", true);
37       addMenuItem(menu, "Primary 3", false);
38     }
39     else
40     {
41       menu.setHeaderTitle("Secondary context");
42       addMenuItem(menu, "Secondary 1", true);  
43       addMenuItem(menu, "Secondary 2", true);
44       addMenuItem(menu, "Secondary 3", false);
45     }    
46   }
47   
48   public MenuItem addMenuItem(ContextMenu menu,
49       String itemName,
50       boolean checkable)
51   {
52     MenuItem item = menu.add(itemName);
53     item.setCheckable(checkable);
54
55     if (itemName.equals(checkedItem))
56     {
57       item.setChecked(true);
58     }
59     return item;
60   }
61

Finally, to handle item selections from the context menu, the onContextItemSelected method is overridden. In the following example, the method will simply update a text view to display what was last selected.

62   public boolean onContextItemSelected(MenuItem item)
63   {
64     TextView statusText = (TextView) findViewById(R.id.statusView);
65     
66     if (item.isCheckable() == true)
67     {
68       // Visually display what is checked.
69       checkedItem = item.getTitle().toString();
70     }
71     
72     statusText.setText("Last item " + item.getTitle());
73     return true;
74   }
75 }
76

At line 57, notice the call to set the “checked” menu item, even though the method handling the event will also be given the menu item. It may seem like it is possible simply call the setChecked method in the onContextItemSelected method, but, if you try it with this example, you’ll notice that the menu item will NEVER be checked. This is because the method onCreateContextMenu will be called every time the context menu is going to be shown (with, possibly, a different instance of the ContextMenu). In doing so, a new instance of the menu items are added to the menu via the call to the addMenuItem method.

If you compare this example with that of Building a Menu for your Android (V1.0 R1) App, you’ll notice that they follow a similar pattern for setting up menus – override the menu creation method to control what gets shown in the menu and override the receiving selection event method to control what happens when an item is selected. In fact, this same pattern is followed for an options menu (override onCreateOptionsMenu to set what gets put in there).

Tags:

In A Certificate’s Subject, Issuer and its keyUsage, a certificate was read into memory and its subject and issuer names and its key usage extension contents were outputted. Here, the subject alternate names and extended key usage names are extracted. Both of these extensions are defined in RFC 3280 as a SEQUENCE of something. In the code, this would mean the extension would be parsed into a STACK_OF something.

The ASN.1 description for the extended key usage as defined in RFC 3280:

ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId

KeyPurposeId ::= OBJECT IDENTIFIER

As mentioned before, the extended key usage is an ASN.1 SEQUENCE, which in our code will be a STACK_OF something. The definition states its a SEQUENCE of KeyPurposeId, which is just an OBJECT IDENTIFIER. In our code, we would extract this as an ASN1_OBJECT. Since KeyPurposeId is an OBJECT IDENTIFIER (aka OID), there will be a unique object for each extended key usage value type. The name of the extend key usage value in the extension can be obtained from OpenSSL.


 1 #include <iostream>
 2 #include <openssl/pem.h>
 3 #include <openssl/x509v3.h>
 4
 5 // Extract the extended key usage values from the
 6 // certificate and output them.
 7 void extractExtendedKeyUsage (X509 *cert)
 8 {
 9   std::cout << std::endl <<
10     "Extended key usages: ";
11   int usageId = 0;
12   const char *kuValue = NULL;
13   STACK_OF(ASN1_OBJECT) *extKu =
14     (STACK_OF(ASN1_OBJECT) *)
15     X509_get_ext_d2i(cert, NID_ext_key_usage,
16      NULL, NULL);
17

As with the stack data structure, a STACK_OF(ASN1_OBJECT) support pop and push operations. With each object in the stack, you can obtain its numeric identifier (NID) or a textual representation of its name by using the OBJ functions. For the code above, it will give back each extend key usage value in the certificate.

18   while (sk_ASN1_OBJECT_num(extKu) > 0)
19   {
20     usageId = OBJ_obj2nid(
21       sk_ASN1_OBJECT_pop(extKu));
22     kuValue = OBJ_nid2sn(usageId);
23     std::cout << " [" << kuValue << "]";
24   }
25   std::cout << std::endl;
26 }
27

The subject alternate name’s ASN.1 definition is:

SubjectAltName ::= GeneralNames

GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName

GeneralName ::= CHOICE {
otherName [0] OtherName,
rfc822Name [1] IA5String,
dNSName [2] IA5String,
x400Address [3] ORAddress,
directoryName [4] Name,
ediPartyName [5] EDIPartyName,
uniformResourceIdentifier [6] IA5String,
iPAddress [7] OCTET STRING,
registeredID [8] OBJECT IDENTIFIER }

OtherName ::= SEQUENCE {
type-id OBJECT IDENTIFIER,
value [0] EXPLICIT ANY DEFINED BY type-id }

EDIPartyName ::= SEQUENCE {
nameAssigner [0] DirectoryString OPTIONAL,
partyName [1] DirectoryString }

Notice that ASN.1 definition states that a subject alternate name is a sequence of GeneralName. It also happens that OpenSSL has define a structure called GENERAL_NAME in x509v3.h.

 1 typedef struct GENERAL_NAME_st {
 2
 3 #define GEN_OTHERNAME 0
 4 #define GEN_EMAIL 1
 5 #define GEN_DNS   2
 6 #define GEN_X400  3
 7 #define GEN_DIRNAME 4
 8 #define GEN_EDIPARTY  5
 9 #define GEN_URI   6
10 #define GEN_IPADD 7
11 #define GEN_RID   8
12
13 int type;
14 union {
15   char *ptr;
16   OTHERNAME *otherName; /* otherName */
17   ASN1_IA5STRING *rfc822Name;
18   ASN1_IA5STRING *dNSName;
19   ASN1_TYPE *x400Address;
20   X509_NAME *directoryName;
21   EDIPARTYNAME *ediPartyName;
22   ASN1_IA5STRING *uniformResourceIdentifier;
23   ASN1_OCTET_STRING *iPAddress;
24   ASN1_OBJECT *registeredID;
25
26   /* Old names */
27   ASN1_OCTET_STRING *ip; /* iPAddress */
28   X509_NAME *dirn;    /* dirn */
29   ASN1_IA5STRING *ia5;/* rfc822Name, dNSName, uniformResourceIdentifier */
30   ASN1_OBJECT *rid; /* registeredID */
31   ASN1_TYPE *other; /* x400Address */
32 } d;
33 } GENERAL_NAME;

Notice that the definition of the GENERAL_NAME structure in the header mirrors that of as defined in the RFC. The member type reveals exactly kind of information is in the structure and, hence, which member of the union, d, to use to access the actual data. In case you are wondering, the definition for the OTHERNAME and EDIPARTYNAME structures are also defined in the same file. Again, their definitions mirrors that as specified by the RFC.

1 typedef struct otherName_st {
2 ASN1_OBJECT *type_id;
3 ASN1_TYPE *value;
4 } OTHERNAME;
5
6 typedef struct EDIPartyName_st {
7   ASN1_STRING *nameAssigner;
8   ASN1_STRING *partyName;
9 } EDIPARTYNAME;

First, to obtain the subject alternate name:

28 // Extract the subject alternate name and output
29 // its contents.
30 void extractSubjectAltName (X509 *cert)
31 {
32   std::cout << std::endl <<
33     "Subject alternate name" << std::endl;
34   GENERAL_NAME *namePart = NULL;
35   STACK_OF(GENERAL_NAME) * san =
36     (STACK_OF(GENERAL_NAME) *)
37     X509_get_ext_d2i(cert,
38       NID_subject_alt_name, NULL, NULL);
39
40   while (sk_GENERAL_NAME_num(san) > 0)
41   {
42     std::cout << "Entry type: ";
43     namePart = sk_GENERAL_NAME_pop(san);
44

Next, we can output the information. The type of information in the GENERAL_NAME is given by the member type, which will also indicate which of the other in the union to use to access the data. Since there are many different types of entry values possible in a GENERAL_NAME, I’ve kept it short here by outputting only URI and email entries. Note that the email entry is stored in the rfc822Name member (yes, RFC 822 is about email, although it has been updated by later RFCs).

45     // Determine what kind of data we have
46     // and handle it appropriately.
47     switch (namePart->type)
48     {
49       case GEN_URI:
50         std::cout << "URI = " <<
51           ASN1_STRING_data(namePart->
52           d.uniformResourceIdentifier);
53         break;
54       case GEN_EMAIL:
55         std::cout << "Email = " <<
56         ASN1_STRING_data(namePart->
57         d.rfc822Name);
58         break;
59       default:
60         // Going to be lazy for this
61         // example.
62         std::cout << "Unrecognisable";
63         break;
64     }
65     std::cout << std::endl;
66   }
67 }

Tags: ,

Building a Menu for your Android (V1.0 R1) App

Posted by: kahgoh on: 25 November, 2008

In Building a simple menu in Android, a menu was built using the MenuBuilder. Since the release of version 1.0 (release 1), MenuBuilder has been removed. In this tutorial, we’ll set up a custom menu that gets displayed when the menu button is pressed.

To add the menu for your application, your activity needs to override the onCreateOptionsMenu method. The method will be given the instance of the menu to popuplate. Our overridden method will add the items to the instance that is given. To control what happens when an item on the menu is selected, override the onOptionsItemSelected method. Here is the first part of the code that sets up the activity and adds a couple of items to our menu:


 1 package com.android.menu;
 2
 3 import android.app.Activity;
 4 import android.app.AlertDialog;
 5 import android.os.Bundle;
 6 import android.view.Menu;
 7 import android.view.MenuInflater;
 8 import android.view.MenuItem;
 9 import android.view.SubMenu;
10
11 public class MenuDemo extends Activity
12 {
13   /** 
14    * Called when the activity is first created. 
15    */
16   @Override
17   public void onCreate(Bundle savedInstanceState) 
18   {
19     super.onCreate(savedInstanceState);
20     setContentView(R.layout.main);      
21   }
22     
23   /**
24    * {@inheritDoc}
25    */
26   @Override
27   public boolean onCreateOptionsMenu(Menu menu) 
28   {
29     super.onCreateOptionsMenu(menu);
30     
31     MenuItem item = menu.add("Painting");
32     item.setIcon(R.drawable.paint);
33     
34     item = menu.add("Photos");
35     item.setIcon(R.drawable.photos);
36     

The call to to the setIcon method attachs an image to the menu item. In the example above, the images have been placed in the appropriate resources directory and is being referenced from there.

The items added so far are top level items. Now let’s say we want to attach a submenu. This is as easy as calling the addSubMenu method.


37     SubMenu subScience = menu.addSubMenu(
38         R.string.scienceMenuName);
39     subScience.setIcon(R.drawable.science);
40

To add items to our submenu, we can create the menu items programatically (like we did with the top level menu). However, just to show you another way of setting up the menu, we’ll use load up a menu specified by a menu XML file here instead. You can use the Android Menu Editor to edit the XML if you want (in Eclipse, create an XML file and then right click on the file Open With -> Android Menu Editor) or you can use the text editor to manually create the XML. Below is the contents of the XML file that I used:


1 <menu xmlns:android="http://schemas.android.com/apk/res/android">
2   <item android:title="Physics" />
3   <item android:title="Chemistry" />
4   <item android:title="Biology" />
5 </menu>
6

It should be noted that we could have also created our top level menu the same way! The loading of the menu from an XML file is done through the use of a MenuInflater.


41     // Now, inflate our submenu.
42     MenuInflater inflater = new MenuInflater(this);
43     inflater.inflate(R.menu.menu, subScience);
44

Of course, once the menu has been loaded from an XML file, we can still add items to the submenu.


45     // Programatically, add one item to the submenu.
46     subScience.add("Meteorology");
47

To make the menu displayable when the menu button is pressed, the method needs to return true.


48     // Return true so that the menu gets displayed.
49     return true;
50   }
51

With the menu setup, we now override the onOptionsItemSelected method to handle menu selections. The selected menu item is given back as the method parameter. In this example, the an alert dialog simply pops up, showing what item was selected.


52   /**
53    * {@inheritDoc}
54    */
55   public boolean onOptionsItemSelected(MenuItem item)
56   {
57
58     if (item.hasSubMenu() == false)
59     {
60       // For this demo, lets just give back what
61       // we found.
62       AlertDialog.Builder dialogBuilder = new 
63         AlertDialog.Builder(this);
64   
65       dialogBuilder.setMessage(" You selected " +
66           item.getTitle());
67   
68       dialogBuilder.setCancelable(true);
69       dialogBuilder.create().show();
70     }
71     
72     // Consume the selection event.
73     return true;
74   }
75 }
76

Tags:

A Certificate’s Subject, Issuer and its keyUsage

Posted by: kahgoh on: 23 November, 2008

The first code that I ever wrote using OpenSSL was one that read the certificate into memory and examined the values of the keyUsage extension. In fact, OpenSSL provides the functionality to extract all of the information from an X509 certificate that you possibly want. In this tutorial, an X509 certificate is read into memory and the subject and issuer are extracted and the keyUsage extension is examined.

The OpenSSL library provides a few different ways of loading a certificate into memory. For certificates that are in the DER format, the d2i_X509 functions can be used. OpenSSL provides two of these functions – one to read from a file pointer and another to read from a BIO. For anything in the PEM format, openssl provides a set of PEM_read functions. Again, there is a function to read from a BIO and another to read from a file pointer.

  1 #include <iostream>
  2
  3 #include <openssl/pem.h>
  4
  5 // Prototypes
  6 void printSubject (X509 *cert);
  7 void breakdownIssuer (X509 *cert);
  8 void extractNameEntry (X509_NAME *name, int nid);
  9 void checkKeyUsageExtension (X509 *cert);
 10 void testKeyUsage (ASN1_BIT_STRING *keyUsage,
 11   int usageBit, const char *usageName);
 12
 13 int main (int argc, char *argv[])
 14 {
 15   FILE *certFile = fopen("cert.pem", "r");
 16   X509 *cert = NULL;
 17
 18   if (certFile != NULL)
 19   {
 20     cert = PEM_read_X509(certFile, NULL, NULL,
 21       NULL);
 22     printSubject(cert);
 23     breakdownIssuer(cert);
 24     checkKeyUsageExtension(cert);
 25     fclose(certFile);
 26   }
 27   else
 28   {
 29     std::cout << "Could not open file cert.pem";
 30   }
 31
 32   X509_free(cert);
 33 }
 34

Extracting the certificate’s subject name is as simple as a single function call.

 35 // Simple function that prints out the subject name
 36 // using the RFC2253 format.
 37 void printSubject (X509 *cert)
 38 {
 39   std::cout << "— Certificate subject" <<
 40     std::endl;
 41   X509_NAME *subject = X509_get_subject_name(cert);
 42

With the subject name stored in a X509_NAME structure, we can go throught each of the structure’s members and output their values. Alternatively, if we want to obtain a readable format of the entire subject name, we can use OpenSSL’s X509_NAME_print_ex function. However, this function outputs the subject name to a BIO. Fortunately, it is quite easy to extract the string from the BIO and make our own copy.

 43   // Set up a BIO to put the subject line into.
 44   BIO *subjectBio = BIO_new(BIO_s_mem());
 45
 46   // Now, put the subject line into the BIO.
 47   X509_NAME_print_ex(subjectBio, subject, 0,
 48     XN_FLAG_RFC2253);
 49
 50   // Obtain a reference to the data and copy out
 51   // just the length of the data.
 52   char *dataStart = NULL;
 53   char *subjectString = NULL;
 54   long nameLength = BIO_get_mem_data(subjectBio,
 55     &dataStart);
 56   subjectString = new char[nameLength + 1];
 57   memset(subjectString, 0×00, nameLength + 1);
 58   memcpy(subjectString, dataStart, nameLength);
 59
 60   std::cout << "Certificate subject name: " <<
 61     subjectString << std::endl;
 62 }
 63

If you had a look at the documentation for X509_NAME_print_ex, you might have noticed the function X509_NAME_oneline and X509_NAME_print would have done also printed out the subject name in a readable format, with far less code. So then, why have I not used X509_NAME_oneline? It is because the same documentation also states that the two functions are “legacy functions which produce a non standard output form, they don’t handle multi character fields and have various quirks and inconsistencies. Their use is strongly discouraged in new applications.”.

Next, we’ll extract the issuer name and extract the individual parts, such as the common name, country and organisation names. Since the issuer and subjects are stored and retrieved using the X509_NAME structure, this same method can be applied to the subject name (and a readable form of the issuer name can be obtained using the same method as above).

 64 // Simple method that takes the issuer name to
 65 // pieces and prints out a couple of the fields.
 66 void breakdownIssuer (X509 *cert)
 67 {
 68   std::cout << std::endl << "— Issuer breakdown" 
 69     << std::endl;
 70   X509_NAME *issuer = X509_get_issuer_name(cert);
 71
 72   extractNameEntry(issuer, NID_commonName);
 73   extractNameEntry(issuer, NID_countryName);
 74   extractNameEntry(issuer, NID_organizationName);
 75 }
 76

The function extractNameEntry is defined later and is where the individual fields in the issuer name will be extracted. The constants NID_commonName, NID_countryName and NID_organizationName are defined by OpenSSL and references the fields in the issuer name to be extracted. There are defined in objects.h and obj_mac.h.

To extract the actual field from the issuer name, we must determine the location of the field in the name and then extract the entry as a X509_NAME_ENTRY.

 77 // Obtains an entry from a X509 name (i.e. either
 78 // the certificate’s issuer or subject) and
 79 // prints out on standard output.
 80 void extractNameEntry (X509_NAME *name, int nid)
 81 {
 82   // First, let us get the common name from the
 83   // certificate.
 84   int position = X509_NAME_get_index_by_NID(name,
 85     nid, -1);
 86   X509_NAME_ENTRY *entry = X509_NAME_get_entry(
 87     name, position);
 88     

Obtaining a readable string representation of the field requires one more level extraction and conversion.

 89   // This will obtain just the name entry.
 90   ASN1_STRING *asn1Data =
 91     X509_NAME_ENTRY_get_data(entry);
 92
 93   // Next use obtain the actual string data and
 94   // output to standard output.
 95   unsigned char *entryString = ASN1_STRING_data(
 96     asn1Data);
 97
 98   std::cout << OBJ_nid2ln(nid) << ": " <<
 99     entryString << std::endl;
100 }
101

The function OBJ_nid2ln converts the our NID value that we passed in to the name of the field.

Lastly, we’ll extract the keyUsage extension and examine its contents. The method of extracting the extension is same for any extension. RFC 3820 provides a description of the keyUsage extension (actually, it also provides descriptions of other extension as well). Have a look at the RFC if you also want to know what the extension is for. The keyUsage extension is encoded as a bit string, so in OpenSSL, this is extracted as bit string. Furthermore, take note of the meaning of each of the bits in the bit string from RFC.

102 // Extracts the key usage extension from the
103 // certificate.
104 void checkKeyUsageExtension (X509 *cert)
105 {
106   int criticality = -1;
107   int extIndex = -1;
108
109   std::cout << std::endl <<
110     "— Key Usage extension" << std::endl;
111
112   // Obtain the keyUsage extension in the form
113   // of a bit string.
114   ASN1_BIT_STRING *keyUsage = (ASN1_BIT_STRING *)
115     X509_get_ext_d2i(cert, NID_key_usage,
116     &criticality, &extIndex);
117
118   // Output the contents of the keyUsage
119   // extension.
120   const char *usages[] = {"digitalSignature",
121                           "nonRepudiation",
122                           "keyEncipherment",
123                           "dataEncipherment",
124                           "keyAgreement",
125                           "keyCertSign",
126                           "cRLSign",
127                           "encipherOnly",
128                           "decipherOnly"};
129
130   for (int index = 0; index < 8; index++)
131   {
132     testKeyUsage(keyUsage, index, usages[index]);
133   }
134 }
135
136 // Tests the value of the key usage extension to
137 // determine for a given value and outputs the
138 // result to standard output.
139 //
140 // The parameter usageBit is which bit in the
141 // keyUsage to check. RFC 3280 lists the meaning
142 // of each of the bits in the extension.
143 void testKeyUsage (ASN1_BIT_STRING *keyUsage,
144   int usageBit, const char *usageName)
145 {  
146   std::cout << usageName << ": " <<
147     ASN1_BIT_STRING_get_bit(keyUsage, usageBit) <<
148     std::endl;
149 }
150

If you compile and run this program, you should see the output of the contents of cert.pem’s subject and issuer names and its keyUsage extension (if it can find the certificate). More importantly, note one thing that has been omitted in the sample code above – the lack of checking for successful operations. Throughout the code, I had not checked for things such as whether the subject name was successfully obtained from the certificate, whether we managed to get the individual fields from the issuer name or a keyUsage extension really exists before their contents are used. This was omitted to shorten the amount of code that would have to be displayed in this tutorial. Adding the checks yourself is as simple as checking the return values (usually, a null or -1 is returned on error).

Tags: ,

The Java Thread Pool

Posted by: kahgoh on: 30 October, 2008

A thread pool helps to constrain the number of threads that may be running in an application at any one time. As threads require system resources, having too many threads executing simultaneously will negatively impact on a system’s performance.

Threads can be represented as objects. To define what our threads will be doing, we create a class that implements the Callable interface. In this example, the thread will computer an integer. The interface, itself, provides only one method – call. This is the method that is actually executed when the thread is running. Since we have assigned the integer as the generic type in the class definition, the method must also return an integer (see the generics guide for information on generics).


 1    import java.util.concurrent.Callable;
 2    
 3    public class ExecAdd implements Callable<Integer>
 4    {
 5      private int id = 0;
 6      
 7      public ExecAdd (int threadId) 
 8      {
 9          id = threadId;
10      }
11    
12      /**
13       * This is the method that will be executed
14       * when the thread is running.
15       */
16      @Override
17      public Integer call() throws Exception
18      {
19          int result = 1;
20          System.out.println("Thread " + id +
21                  " calculating …");
22          
23          // Compute the result.
24          for (int value = 1; value <= id; value++)
25          {
26              result = result + value;
27          }
28          
29          // Delay for a visible amount of time.
30          // This is just for show.
31          try {
32              Thread.sleep(2000);
33          } catch (InterruptedException e) {
34              System.out.println("Interrupted");
35          }
36    
37          return result;
38      }
39    }

Note that the call to sleep at line 32 is only intended to make the thread last a bit longer. It will, later, cause the thread pool to fill up and force other threads to wait before executing. The creation of the thread pool in which to execute these threads and the extraction of the return values from them is done in the main method of another class.


 1    
 2    import java.util.ArrayList;
 3    import java.util.List;
 4    import java.util.concurrent.ExecutionException;
 5    import java.util.concurrent.ExecutorService;
 6    import java.util.concurrent.Executors;
 7    import java.util.concurrent.Future;
 8    
 9    public class ThreadCreator {
10      public static void main(String[] args) {

The thread pool Executors class provides several methods for creating different types of thread pools. For this example, the fixed thread pool is used. A fixed thread pool will allow up to a certain number of threads to run at any one time. To show this behaviour, the example uses a thread pool size of ten but will later give thirty threads to the pool to execute.


11          // Use a thread pool executor to generate
12          // the lists.
13          ExecutorService calcExecutor =
14              Executors.newFixedThreadPool(10);
15    
16          // Maintains a reference to our adders.
17          ArrayList<ExecAdd> adders = new 
18              ArrayList<ExecAdd>();
19    

The use of a list to maintain references to the threads is so that the threads will be started simultaneously (the execution of the threads comes later). When the thread pool finishes executing a thread, the return value from the thread execution is obtained through the Future object.


20          // Reference to the results.
21          List<Future<Integer>> allResults = null;
22    

Next, we create the instances of the thirty threads that will be executed in the thread pool.


23          // Create an instance of the calculators
24          // to be executed.
25          for (int index = 0; index < 30; index++) 
26          {
27              adders.add(new ExecAdd(index));
28          }
29    

To execute the threads, the list of the threads are given to the thread pool.


30          try {
31              // Perform the calculations.
32              allResults = calcExecutor.
33                  invokeAll(adders);
34              
35              // Output the results.
36              for (Future<Integer> calcResult:
37                  allResults) 
38              {
39                  System.out.println(
40                          calcResult.get());
41              }
42    

When the get() method is called, the system will wait for the thread to finish execution if it has not finished already and then return the result. All that is left is the handling of the exceptions that can possibly be thrown.


43          } catch (InterruptedException e) {
44              System.out.println("Interrupted");
45          } catch (ExecutionException e) {
46              System.out.println(
47                      "Execution exception");
48          }
49          
50      }
51    }

When you execute the code, you should notice a slight pause in between a batch of threads. This is because we have a thread pool of ten that executes at any one time, but we gave it thirty threads!!

Tags:

Making a custom Android button using a custom view

Posted by: kahgoh on: 13 September, 2008

Creating a custom view is as simple as inheriting from the View class and overriding the methods that need to be overridden. In this example, a custom button is implemented in this way. The button shall feature a labelled image (i.e. an image with text underneath).



1   public class CustomImageButton extends View {
2       private final static int WIDTH_PADDING = 8;
3       private final static int HEIGHT_PADDING = 10;
4       private final String label;
5       private final int imageResId;
6       private final Bitmap image;
7       private final InternalListener listenerAdapter = new InternalListener();
8

The constructor can take in the parameters to set the button image and label.


9       /**
10       * Constructor.
11       *
12       * @param context
13       *        Activity context in which the button view is being placed for.
14       *
15       * @param resImage
16       *        Image to put on the button. This image should have been placed
17       *        in the drawable resources directory.
18       *
19       * @param label
20       *        The text label to display for the custom button.
21       */
22      public CustomImageButton(Context context, int resImage, String label) 
23       {
24           super(context);
25           this.label = label;
26           this.imageResId = resImage;
27           this.image = BitmapFactory.decodeResource(context.getResources(),
28                  imageResId);
29  
30           setFocusable(true);
31           setBackgroundColor(Color.WHITE);
32
33           setOnClickListener(listenerAdapter);
34           setClickable(true);
35       }
36

With the constructor defined, there are a number of methods in the View class that needs to be overridden to this view behave like a button. Firstly, the onFocusChanged gets triggered when the focus moves onto or off the view. In the case of our custom button, we want the button to be “highlighted” when ever the focus is on the button.


37       /**
38       * The method that is called when the focus is changed to or from this
39       * view.
40       */
41       protected void onFocusChanged(boolean gainFocus, int direction,
42                      Rect previouslyFocusedRect)
43       {
44           if (gainFocus == true)
45           {
46               this.setBackgroundColor(Color.rgb(255, 165, 0));
47           }
48           else
49          {
50              this.setBackgroundColor(Color.WHITE);
51          }
52      }
53      

The method responsible for rendering the contents of the view to the screen is the draw method. In this case, it handles placing the image and text label on to the custom view.


54      /**
55       * Method called on to render the view.
56       */
57      protected void onDraw(Canvas canvas)
58      {
59          Paint textPaint = new Paint();
60          textPaint.setColor(Color.BLACK);
61          canvas.drawBitmap(image, WIDTH_PADDING / 2, HEIGHT_PADDING / 2, null);
62          canvas.drawText(label, WIDTH_PADDING / 2, (HEIGHT_PADDING / 2) +
63                  image.getHeight() + 8, textPaint);
64      }
65      

For the elements to be displayed correctly on the screen, Android needs to know the how big the custom view is. This is done through overriding the onMeasure method. The measurement specification parameters represent dimension restrictions that are imposed by the parent view.


 66        @Override
 67        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
 68        {
 69         setMeasuredDimension(measureWidth(widthMeasureSpec),
 70                 measureHeight(heightMeasureSpec));
 71        }
 72    

The call to setMeasuredDimension in the onMeasure method is important. The documentation states that the call is necessary to avoid a IllegalStateException.


 73     private int measureWidth(int measureSpec)
 74     {
 75         int preferred = image.getWidth() * 2;
 76         return getMeasurement(measureSpec, preferred);
 77     }
 78    
 79     private int measureHeight(int measureSpec)
 80     {
 81         int preferred = image.getHeight() * 2;
 82         return getMeasurement(measureSpec, preferred);
 83     }
 84    

To calculate the width and height measurements, I’ve chosen to keep the logic simple by using a simple formula to calculate the dimensions. This simple formula computes the dimensions based on the dimensions of the image. The measureSpec parameter specifies what restrictions are imposed by the parent layout.


 85     private int getMeasurement(int measureSpec, int preferred)
 86     {
 87         int specSize = MeasureSpec.getSize(measureSpec);
 88         int measurement = 0;
 89        
 90         switch(MeasureSpec.getMode(measureSpec))
 91         {
 92             case MeasureSpec.EXACTLY:
 93                 // This means the width of this view has been given.
 94                 measurement = specSize;
 95                 break;
 96             case MeasureSpec.AT_MOST:
 97                 // Take the minimum of the preferred size and what
 98                 // we were told to be.
 99                 measurement = Math.min(preferred, specSize);
100                 break;
101             default:
102                 measurement = preferred;
103                 break;
104         }
105    
106         return measurement;
107     }
108

To make the customised button useful, it needs to trigger some kind of action when it is clicked (i.e. a listener). The view class already defines methods for setting the listener, but a more specialised listener could be better suited to the custom button. For example, the specialised listener could pass back information on the instance of the custom button.


109     /**
110      * Sets the listener object that is triggered when the view is clicked.
111      *
112      * @param newListener
113      *        The instance of the listener to trigger.
114      */
115     public void setOnClickListener(ClickListener newListener)
116     {
117         listenerAdapter.setListener(newListener);
118     }
119    

If the custom listener passes information about this instance of the custom button, it may as well have accessors so listener implementation can get useful information about this custom button.


120     /**
121      * Returns the label of the button.
122      */
123     public String getLabel()
124     {
125         return label;
126     }
127    
128     /**
129      * Returns the resource id of the image.
130      */
131     public int getImageResId()
132     {
133         return imageResId;
134     }
135    

Finally, for our custom button class that is using a custom listener, the custom listener class needs to be defined.


136     /**
137      * Internal click listener class. Translates a view’s click listener to
138      * one that is more appropriate for the custom image button class.
139      *
140      * @author Kah
141      */
142     private class InternalListener implements View.OnClickListener
143     {
144         private ClickListener listener = null;
145    
146         /**
147          * Changes the listener to the given listener.
148          *
149          * @param newListener
150          *        The listener to change to.
151          */
152         public void setListener(ClickListener newListener)
153         {
154             listener = newListener;
155         }
156        
157         @Override
158         public void onClick(View v) 
159         {
160             if (listener != null)
161             {
162                 listener.onClick(CustomImageButton.this);
163             }
164         }
165     }
166    }
167    

Tags:

Android SDK 0.9 beta released

Posted by: kahgoh on: 19 August, 2008

If you haven’t heard yet, Android SDK 0.9 beta has been released. Examples from my earlier posts were tested on m5. There has been some API changes and it has broken at least on example in one of my previous posts. I hope to go through the rest of the posts and have the examples updated sometime soon …

Building a simple menu in Android

Posted by: kahgoh on: 5 August, 2008

25 Nov 2008, This tutorial has been superceded by Building a Menu for your Android (V1.0 R1) App.

19 Aug 2008, Note: Due to changes to the Android SDK, the code in this example does not work in 0.9 beta.

The menu builder class provides a way to build a simple menu, similar to the one below, in Android.

Menu built with the menu builder class.

To do anything useful with the menu, you need to specify what to do when an item is selected. A class that implements the MenuItem.OnClickListener interface is required to perform these actions. Here is an example of a listener that popups a dialog with the selection:

1   public class AndroidMenuButton extends Activity
2   {
3       private View menuInstance = null;
4  
5       private class ReactToClick
            implements Menu.OnClickListener
6       {
7           public ReactToClick()
8           {
9               // Empty constructor. Do nothing.
10          }
11          
12          /**
13           * React to an item being clicked.
14           */
15          public boolean onClick(Item item) 
16          {
17              // Display a that "echoes" the item that was
                // selected.

18              AlertDialog.Builder dialogBuilder = new 
19                  AlertDialog.Builder(AndroidMenuButton.this);
20              
21              dialogBuilder.setMessage(" You selected " +
22                      item.getTitle());
23              dialogBuilder.setCancelable(true);
24              dialogBuilder.create().show();
25  
26              // Click has been processed, so consume it.
27              return true;
28          }
29      }
30  

A layout can be setup to place the view on. For this example, I’ve set up a vertical linear view using XML and I grab the layout with the findViewById method:

31      /** 
32       * Called when the activity is first created. 
33       */
34      @Override
35      public void onCreate(Bundle icicle) 
36      {
37          super.onCreate(icicle);
38          setContentView(R.layout.capbutton);
39  
40          // Grab the view’s layout.
41          LinearLayout backView = (LinearLayout) 
42              findViewById(R.id.backgroundView);
43          

Next, create an instance of a MenuBuilder object and use the add method to place the menu items. Images for the menu items should be placed as a resource in res/drawables.

44          // Create the menu builder.
45          MenuBuilder builder = new MenuBuilder(this);
46          builder.setHeader("Menu Demo");
47          Item newItem = null;
48          ReactToClick action = new ReactToClick();
49          
50          // Tell the menu builder how to build the menu.
51          newItem = builder.add(0, 1, "Photos",
                R.drawable.item1);

The class, R, should be automatically be generated for you by the Android Eclipse plugin. R should contain references to all of your resources. The add method will return an Item object, to which you add your listeners to.

52          newItem.setClickListener(action);
53          newItem = builder.add(0, 2, "Painting",
                R.drawable.item2);
54          newItem.setClickListener(action);
55          newItem = builder.add(0, 3, "Science",
                R.drawable.item3);
56          newItem.setClickListener(action);
57          

Once all of the menu items have been added, the menu view can be constructed by the viewer and added to your own view.

58          // Get the menu instance and add it the view.
59          menuInstance = builder.getMenuView
60              (MenuBuilder.TYPE_ICON, backView, true);
61          menuInstance.setBackgroundColor(Color.WHITE);
62  
63          backView.addView(menuInstance);
64      }
65  }

It is also possible to have Android create the menu in different formats, such as the icon view (pictured in the first screenshot) or the context menu (pictured in the screenshot below).

Example of a context type menu.

The type of menu displayed is controlled by the first parameter to the MenuBuilder’s getMenuView method. The other two types of menus that have not been mentioned are the expanded menu and submenus. The MenuBuilder documentation details which constants the parameter needs to be set to in order to obtain the different types of menus (see the Constants section).

Tags:

Generating random characters in C.

Posted by: kahgoh on: 21 July, 2008

In C, when you type cast an integer to a character, the character that is assigned is the ASCII character corresponding to that number.  This property can be used to generate a set of random of characters, as follows:


1   #include <stdio.h>
2   #include <stdlib.h>
3   #include <time.h>
4  
5   int main(int argc, char *argv[])
6   {
7       char randChar = ‘ ‘;
8       int counter = 0;
9       int randNum = 0;
10  
11      // Provide seed for the random number
12      // generator.
13      srand(time(NULL));
14      for (counter = 0; counter < 10; counter++)
15      {
16          // First, pick a number between 0 and
17          // 25.
18          randNum = 26 * (rand() / (RAND_MAX +
19              1.0));
20  
21          // The ASCII code for ‘a’ is 97, so
22          // add 97 to the random number to get
23          // a lower case letter.
24          randNum = randNum + 97;
25  
26          // Type cast to character to convert
27          // it to a char type.
28          randChar = (char) randNum;
29  
30          printf ("Random char: %c\n", randChar);
31      }
32  }

The documentation for rand() states that it returns a pseudorandom number between 0 and MAX_RAND. Some people would use the modulus operator (“%”) to choose a number between 0 and 26 like this:

randNum = rand() % 26;

The problem with using this technique is that it is reliant on the fact that MAX_RAND is greater than 26 to get the full range of possible values. If it was not greater than 26, then you would not be able to get any random values between MAX_RAND and 26. By normalising dividing the random value by MAX_RAND + 1 and then multiplying by 26, you are do not need to worry about whether MAX_RAND is greater than 26.

Note that at line 13, the call to srand() provides a seed for the call to rand() later. If this seed was not provided, then the exact same sequence would be generated everytime. Also, if you also compile and run the example enough times, you should notice that the exact same sequence will appear after a number of tries. This is because rand is a pseudo random number generator (PRNG – see this wiki page for a detailed description).

Tags:

Changing the Ubuntu Boot Screen

Posted by: kahgoh on: 19 July, 2008

While installing some packages in Ubuntu, I once installed installed the edubuntu-artkwork package. At the time, I was just looking for alternatives to the default Ubuntu themes that I had. Once it was installed, I was asked to reboot it. That was when I found out that the boot screen (Uslpash) image was replaced with a rather (in my opinion) ugly one … Wanting to change it back to the original, I went searching on Google to find out how to change the boot screen back. I could only find instructions that required some building and configuration file editing (at this page). Since I just wanted to restore the previous boot screen image, I sought (and found) an easier way …

To change boot screens easily in Ubuntu, you need to first install the StartUp-Manager. This can be easily done by going to System -> Administration -> Synaptic Package Manager. In the manager, search for “startupmanager” (yes, one word). Right click on the start manager and select “mark for installation” and click on apply (the apply option becomes enabled once you have marked the start up manager for installation.

Installing the start up manager using the Synaptic package manager.

Installing the start up manager using the Synaptic package manager.

Once the manager is installed, you can access the startup manager by the menu System -> Administration -> StartUp-Manager.Now, go to the Appearance tab and you should see the options for changing the Usplash theme at the bottom.

Choose the theme you want to use. The next time Ubuntu boots up, you should see the new theme that you have selected.

Ubuntu Bootscreen

Ubuntu Bootscreen

Tags: