×

Code snippets for common tasks

Overview

This section compares the commonly used APIs in Android with the APIs in Java ME. The goal of this section is to help developers that are familiar with Android application development get a clear understanding of the counterparts of the APIs in Java ME.

Where a strict one-to-one mapping between an Android and a Java ME API does not exist, an alternative implementation strategy will be discussed. The following table presents a rough outline of the topics in the following sections:

Table 1. Common use cases
Topic Android Nokia Asha and Series 40
Touch input View#onTouchEvent, GestureDetector pointerPressed, pointerDragged, pointerReleased (Canvas, CustomItem), GestureInteractiveZone for receiving GestureEvent objects that define the type of the gesture
Maps MapView (Google Maps) MapCanvas, initialised with a Display object (HERE Maps)
Sensors SensorManager, updates via Listener SensorManager, open a Connection and then get updates via Listener (Nokia Asha and Series 40 full touch)
Network connections HttpUrlConnection, Apache HTTP Client HttpConnection, Tantalum library also provides abstractions like HttpGetter and HttpPoster
Messaging SmsManager for sending text messages Sending a TextMessage into a MessageConnection (Wireless Messaging API)
Notifications Google Cloud Messaging for Android (GCM) Service Nokia Notifications API (Nokia Asha), Push Registry
File access Many methods for accessing the file system in the Context class FileSelect (FileSelect API) for displaying a file selection dialog (Nokia Asha). FileConnection (FileConnection API) provides programmatical access to file system.
JSON parsing JSONObject or Tantalum5 cross-platform library Tantalum5 cross-platform library (Tantalum 3 in Series 40)
Persistent Storage Activity#onSaveInstanceState, SharedPreferences Persistent storage access via the RecordStore class
Personal information management (PIM) A number of ContentProvider classes for various data sources Accessing contact lists, calendars, and to-do lists via the Personal Information Management (PIM) API
Multimedia playback MediaPlayer (audio+video), SoundPool, JetPlayer General-purpose Player class (created using Manager) for audio and video

Touch input

Touch input is supported by the Views in Android and LCDUI components in Java ME. For customised touch input handling there are some differences.

Android supports touch events through View#onTouchEvent and View.OnTouchListener#onTouch methods. GestureDetector can be used for detecting basic gestures (tap, drag, fling, etc.) and Gestures API for detecting complicated gestures.

In Java ME, Canvas and CustomItem objects support touch events through calls to pointerPressed, pointerReleased, and pointerDragged methods, through Gesture API and through Multipoint Touch API. Gesture API uses higher level abstraction and provides support for events like tap, longtap, drag, flick, pinch, etc.

Pointer Events

The simplest way to receive touch events in Nokia Asha software platform is to override the pointer methods in Canvas or CustomItem classes.

// Nokia Asha
protected void pointerPressed(int x, int y) {
}

protected void pointerDragged(int x, int y) {
}

protected void pointerReleased(int x, int y) {
}
The Android counterpart is creating and setting OnTouchListener for a View. You can also override the onTouchEvent method of a View.
// Android
OnTouchListener onTouchListener = new OnTouchListener() {
      @Override
     public boolean onTouch(View view, MotionEvent me) {
         switch (me.getAction()) {
         case MotionEvent.ACTION_DOWN:
             // pointer pressed
             break;
         case MotionEvent.ACTION_MOVE:
             // pointer dragged
             break;
         case MotionEvent.ACTION_UP:
             // pointer released
             break;
         }
         return true;
     }
};

view.setOnTouchListener(onTouchListener);

Gestures

In Nokia Asha software platform the gestures can be listened with Gesture API. To use this API, MIDlets must first create a GestureInteractiveZone. This defines a bounding rectangle for the gesture event notifications. Only gesture events that are initiated within the confines of the zone are passed to the MIDlet. The GestureInteractiveZone also defines the types of Gesture events to register for.

// Nokia Asha
GestureInteractiveZone zone = new GestureInteractiveZone(GestureInteractiveZone.GESTURE_ALL);

This zone is then registered with the GestureRegistrationManager by passing in the container (either a Canvas or CustomItem) and the GestureInteractiveZone.

// Nokia Asha
GestureRegistrationManager.register(canvas, zone);

The MIDlet must then define a class that implements the GestureListener interface. This interface defines a single method, gestureAction, which gets called when the platform's gesture recognition engine detects a gesture in one of the registered GestureInteractiveZones. The gestureAction method will receive a GestureEvent instance each time it is called. This GestureEvent holds the properties of the recently recognised gesture, such as the type (tap, drag, etc). For all event types the MIDlet can get the x and y location. For drag and drop events the MIDlet can also get the change in x and y distance since the last drag event. For flick events the MIDlet can get the flick speed and direction. For pinch events the MIDlet can get starting points and current distance between the fingers, distance change between the fingers since the last pinch gesture, center position between the fingers in horizontal and vertical directions, and change in the center position between the fingers in horizontal and vertical directions since the last pinch gesture.

// Nokia Asha
public void gestureAction(Object container, 
    GestureInteractiveZone gestureZone, 
    GestureEvent gestureEvent) {
    // do something with the gestureEvent
}
In Android, gestures are listened with GestureDetector and GestureListener. GestureDetector is used to interpret gestures of touch events, while GestureListener contains methods for handling the interpreted gesture events.
// Android
GestureListener gestureListener = new GestureListener() {
   
    // implement gesture handling methods here

};
GestureDetectorCompat gestureDetector = new GestureDetectorCompat(activity, gestureListener);

Additionally, you need to delegate the touch events received by your View to the GestureDetector.

// Android
public boolean onTouchEvent(MotionEvent event) {
     gestureDetector.onTouchEvent(event);
     // Be sure to call the superclass implementation
     return super.onTouchEvent(event);
}

Multipoint Touch

To listen for multipoint touch events in Nokia Asha software platform, MIDlets must implement and register MultipointTouchListener. This defines a listener for the MultipointTouch event notifications. The pointersChanged method receives an array of pointer Ids for all changed pointers. The MultipointTouch class keeps track of all fingers in the touchpad. A MIDlet can use MultipointTouch class to get the state and x- and y-coordinates of each pointer at any given time, not only in pointersChanged method.

Note that Nokia Asha 305, Nokia Asha 306, and Nokia Asha 501 support two-point touch instead of true multipoint touch.

// Nokia Asha
public void pointersChanged(int[] pointerIds) {
    int pointerId;
    int x;
    int y;
    int state;
    // Go through the array
    for(int i=0; i < pointerIds.length; i++) {
        // Get pointerId.
        pointerId = pointerIds[i];
        // Read the pointer state.
        state = MultipointTouch.getState(pointerId);
        // Read the pointer X and Y coordinate.
        x = MultipointTouch.getX(pointerId);
        y = MultipointTouch.getY(pointerId);
        switch(state) {
            case MultipointTouch.POINTER_PRESSED:
                // A new finger was pressed.
                break;
            case MultipointTouch.POINTER_DRAGGED:
                // An existing finger was moved.
                break;
            case MultipointTouch.POINTER_RELEASED:
                // An existing finger was lifted.
                break;
            default:
                break;
        }
    }
}

Android similarly has a unique identifier for each pointer. You can get the ID of the changed pointer in onTouch method of the OnTouchListener and then handle the action for the identified pointer.

// Android
OnTouchListener onTouchListener = new OnTouchListener() {
      @Override
     public boolean onTouch(View view, MotionEvent me) {
         int pointerIndex = ((me.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT);
         int action = me.getAction() & MotionEvent.ACTION_MASK;
         int pointerId = me.getPointerId(pointerIndex);
         switch (action) {
         case MotionEvent.ACTION_UP:
             // A finger was released.
             break;
         case MotionEvent.ACTION_DOWN:
             // A finger was pressed.
             break;
         case MotionEvent.ACTION_POINTER_UP:
             // Additional finger was released. 
             break;
         case MotionEvent.ACTION_POINTER_DOWN:
             // Additional finger was pressed. 
             break;
         case MotionEvent.ACTION_MOVE:
             // A finger was moved. 
             break;
         }
         return false;
     }
};

Maps

Google Maps API for Android and Nokia HERE Maps API for Java ME provide very similar APIs for showing a map. Biggest difference is that the HERE Maps API provides also search, geocoding, reverse geocoding and routing functionalities. Both require you to register with the map service before you can use the map data.

Table 2. Comparison of Maps APIs
  Google Maps API for Android Nokia HERE Maps API for Java ME
Multiple map types street map, satellite, terrain, hybrid street map, satellite, terrain, transit, hybrid and night
Touch support pan and zoom pan and zoom
Customisable markers supported supported
Polygons, polylines supported supported
Overlay support supported supported
Download indicator not provided provided as a standard UI component
Search not provided local search and places look-up by category
Geocoding/Reverse Geocoding not provided street address to geographic coordinates or geo coordinates to address
Routing not supported supported

The example applications both show a fullscreen map which supports panning and zooming and contains a single marker located in Helsinki.

 

Figure 1. Google Maps and Here Maps Example Applications

Google Maps example application

Simple map example in Android using Google Maps API:

// Android
public class MapExampleActivity extends MapActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        MapView mapView = (MapView) findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);

        GeoPoint helsinki = new GeoPoint(60171617, 24941368);
        MapController controller = mapView.getController();
        controller.setZoom(16);
        controller.setCenter(helsinki);
        controller.animateTo(helsinki);

        // Add Helsinki marker
        Drawable drawable = this.getResources()
                .getDrawable(R.drawable.location);
        ExampleOverlay itemizedOverlay = new ExampleOverlay(drawable);
        itemizedOverlay.add(new OverlayItem(helsinki, "Helsinki",
                "I'm in Helsinki!"));
        List<Overlay> mapOverlays = mapView.getOverlays();
        mapOverlays.add(itemizedOverlay);
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }

    private static class ExampleOverlay extends ItemizedOverlay<OverlayItem> {
        private ArrayList<OverlayItem> mOverlayItems = new ArrayList<OverlayItem>();

        public ExampleOverlay(Drawable defaultMarker) {
            super(boundCenterBottom(defaultMarker));
        }

        public void add(OverlayItem overlay) {
            mOverlayItems.add(overlay);
            populate();
        }

        @Override
        protected OverlayItem createItem(int i) {
            return mOverlayItems.get(i);
        }

        @Override
        public int size() {
            return mOverlayItems.size();
        }
    }
}
The api key for using the map data is configured in the main layout:
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mapview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:apiKey="<apiKey>"
    android:clickable="true" />

HERE Maps example application

Simple map example in Nokia Asha software platform using HERE Maps API. The API is included as a plugin in Nokia Asha SDK 1.0, you need to reference the library in your project in order to use the API.

// Nokia Asha
public class MapMIDlet
    extends MIDlet {

    protected void startApp()
        throws MIDletStateChangeException {
        ApplicationContext.getInstance().setAppID("<appID>");
        ApplicationContext.getInstance().setToken("<token>");
        Display display = Display.getDisplay(this);
        MapCanvas mapCanvas = new MapCanvas(display) {

            public void onMapUpdateError(String description, Throwable detail,
                boolean critical) {
                // an error has occurred during map rendering
            }

            public void onMapContentComplete() {
            }
        };
        mapCanvas.setFullScreenMode(true);

        MapDisplay mapDisplay = mapCanvas.getMapDisplay();
        mapDisplay.setZoomLevel(16, 0, 0);

        GeoCoordinate helsinki = new GeoCoordinate(60.171617, 24.941368, 0);
        mapDisplay.setCenter(helsinki);

        // Add Helsinki marker
        try {
            Image image = Image.createImage("/location.png");
            MapMarker marker = mapCanvas.getMapFactory().createMapMarker(
                helsinki, image);
            marker.setAnchor(
                new Point(-image.getWidth() / 2, -image.getHeight()));
            mapDisplay.addMapObject(marker);
        }
        catch (IOException e) {
        }
        display.setCurrent(mapCanvas);
    }

    protected void pauseApp() {
    }

    protected void destroyApp(boolean unconditional) {
    }
}

Sensors

The Mobile Sensor API in Java ME (introduced in Java Runtime 2.0.0 for Series 40) is very similar to Android Sensor API.

Listing available sensors

In Android, you can get all the available sensors with:

// Android
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
In Java ME, you can get information about all the available sensors with:
// Nokia Asha
SensorInfo[] infos = SensorManager.findSensors(null, null);

Listening sensor events

In Android, you can listen a sensor after registering a listener:

// Android
sensorManager.registerListener(listener, sensor,
    SensorManager.SENSOR_DELAY_NORMAL);

In Java ME, you create a connection to the sensor and set a listener for the connection:

// Nokia Asha
connection = (SensorConnection) Connector.open(info.getUrl());
connection.setDataListener(listener, bufferSize);

The bufferSize parameter defines how many data points are collected before the listener is notified.

In Android, the listener has to implement SensorEventListener interface:

// Android
public void onAccuracyChanged(Sensor sensor, int accuracy) {
    // accuracy of the sensor has changed
}

public void onSensorChanged(SensorEvent event) {
    // do something with the event
}

For example, acceleration sensor returns acceleration along x-, y- and z-axis, so the length of the event.values array is 3.

// Android
public void onSensorChanged(SensorEvent event) {
    float x = event.values[0];
    float y = event.values[1];
    float z = event.values[2];
    // do something with the values
}

In Java ME, the listener has to implement DataListener interface:

// Nokia Asha
public void dataReceived(SensorConnection connection, Data[] data,
    boolean isDataLost) {
    // do something with the data
}

For example, acceleration sensor returns acceleration along x-, y- and z-axis, so the length of the data array is 3. Acceleration sensor usually provides data of type double, so the Data#getDoubleValues() method can be used to get the values. How many values are returned depends on the bufferSize parameter given when the listener was set.

// Nokia Asha
public void dataReceived(SensorConnection connection, Data[] datas,
    boolean isDataLost) {
    switch (data[0].getChannelInfo().getDataType()) {
        case ChannelInfo.TYPE_DOUBLE:
            double x = datas[0].getDoubleValues()[0];
            double y = datas[1].getDoubleValues()[0];
            double z = datas[2].getDoubleValues()[0];
            // do something with the values
            break;
        default:
            break;
    }
}

Releasing sensor

In Android, when you no longer need the sensor, the listener can be unregistered with:

// Android
sensorManager.unregisterListener(listener);

In Java ME, when you no longer need the sensor, the connection can be closed with:

// Nokia Asha
connection.close();

Network

Android provides two ways to create HTTP connections: HttpURLConnection and Apache Http Client. The way HTTP connections work in Java ME is similar to the HttpURLConnection.

HttpURLConnection in Android:

// Android
URL url = new URL("http://www.example.com"); 
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
try {
    BufferedInputStream in = new BufferedInputStream(connection.getInputStream());
    // retrieve the response from server using the in stream
} finally {
    urlConnection.disconnect();
}

HTTP connection in Java ME:

// Nokia Asha
String url = "http://www.example.com";
HttpConnection connection = null;
DataInputStream in = null;
try {
    // an HttpConnection with both read and write access
    connection = (HttpConnection) Connector.open(url);
    if (connection == null) {
        throw new IOException("No network access");
    }
 
    // obtain DataInputStream for receiving server response
    in = connection.openDataInputStream();
    // retrieve the response from server using the in stream
}
finally {
    // free up i/o streams and http connection
    try {
        if (in != null) {
            in.close(); 
        } 
        if (connection != null) {
            connection.close();
        }
    }
    catch (IOException ioe) {
    }
}

You can use Tantalum5 cross-platform library to create asynchronous HTTP requests. This code is compatible with both Android and Java ME.

// Cross-platform example for Android and Nokia Asha

// Create HTTP GET request 
final HttpGetter httpGetter = new HttpGetter("http://www.nokia.com/fi-fi/");

// Chain callback code for handling the request response. This code gets executed when the HttpGetter is finished.
httpGetter.chain(new Task() {
     protected Object exec(Object o) throws CancellationException, TimeoutException {
         // Handle response
         if (httpGetter.getResponseCode() == HttpGetter.HTTP_200_OK) {
             try {
                 // Convert byte array response to UTF-8 encoded String
                 String response = new String((byte[]) o, "utf-8");
                 // In this example we just print the response to the std out
                 System.out.println(response);
             } catch (UnsupportedEncodingException ex) {
                 ex.printStackTrace();
             }
         }
         else {
             // If response code not 200 / OK, print error note to std out
             System.out.println("Error " + httpGetter.getResponseCode());
         }
         return o;
     }
});

// Start executing the request asynchronously
httpGetter.fork();

Messaging

In Android, you can use the SmsManager class for sending text messages.

// Android

// Send SMS using SmsManager
SmsManager smsManager = SmsManager.getDefault();
String smsNumber = "12345";
String smsText = "SMS content";
smsManager.sendTextMessage(smsNumber, null, smsText, null, null);

You can also use Intent to invoke the built-in SMS application with pre-filled message content and recipient.

// Android

// Launch platform message editor with pre-filled message content and recipient
Intent smsIntent = new Intent(Intent.ACTION_VIEW);
smsIntent.putExtra("sms_body", "Pre-filled message content");
smsIntent.putExtra("address", "12345");
smsIntent.setType("vnd.android-dir/mms-sms");
startActivity(smsIntent);
On Nokia Asha software platform the Wireless Messaging API enables applications to send and receive MMS and SMS messages.
// Nokia Asha

new Thread() {
    public void run() { 
        // Open a message connection
        MessageConnection connection = null;
        TextMessage message;
        try {
            if(sendToInbox) {  // Prepare and send this sms directly to inbox
                connection = (MessageConnection) Connector.open("sms://<number>");
                message = (TextMessage)connection.newMessage(
                        MessageConnection.TEXT_MESSAGE);
            }
            else {  // Prepare and send this sms to another MIDlet listening at the specified port   
                connection = (MessageConnection) Connector.open("sms://:5000");   
                message = (TextMessage)connection.newMessage(
                        MessageConnection.TEXT_MESSAGE);
                message.setAddress("sms://<number>");
            }
            message.setPayloadText("<text>");
            // Send the message
            connection.send(message);
            connection.close(); 
        }
        catch (IOException ex) {
            // Exception handling
        } 
        catch (IllegalArgumentException ex) {
            // Exception (e.g. too big or otherwise invalid message) handling
        } 
        catch (SecurityException ex) {
            // Exception (e.g. insufficient permissions) handling
        }
    } }.start();
}

Notifications

Google Cloud Messaging for Android (GCM) Service can be used for push notifications on Android.

On Nokia Asha software platform you can use Nokia Notifications API (NNA) for propagating information from application-specific Internet services.

Here's how you can register your MIDlet for receiving notifications. For more detailed information see Receiving Nokia Notifications example.

// Nokia Asha

// Create NotificationSessionListener
NotificationSessionListener nsl = new NotificationSessionListener() {
 
    public void infoReceived(NotificationInfo info) {
        // Handle received notification info. Your service can send notifications to the device by using this identifier information.
    }

    public void messageReceived(NotificationMessage message) {
        // Handle received notification message
    }

    public void stateChanged(NotificationState state) {
        switch (state.getSessionState()) {
        case NotificationState.STATE_OFFLINE:
            // Handle state change
            break;
        case NotificationState.STATE_CONNECTING:
            // Handle state change
            break;
        case NotificationState.STATE_ONLINE:
            // Handle state change
            break;
        }
        final int error = state.getSessionError();
        if (error != NotificationError.ERROR_NONE) {
            // Handle error
        }
    }

};

try {
    // Create session
    NotificationSession session =
        NotificationSessionFactory.openSession(
            main, // The MIDlet instance
            "example.com", // Service ID (Deprecated)
            "com.example", // Application ID
            nsl); // NotificationSessionListener
    // Register application
    session.registerApplication();
    // Receive Notification ID
    session.getNotificationInformation();
}
catch (NotificationException ne) {
     // Handle exception;
}

File access

Android provides many methods for accessing files in the Context class: getFilesDir, getCacheDir, getExternalFilesDir, etc.

You can list files in a directory by having a File object representing the directory and using its listFiles method.

// Android
File musicDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
File[] files = musicDirectory.listFiles();
if (files != null) {
    for (File file : files) {
         // do something with files
    }

}

To read a file in Android create a FileInputStream for the File object.

// Android
File file = ...
InputStream in = null;
try {
    in = new FileInputStream(file);
    // Read data from FileInputStream

finally {
    if (in != null) {
        in.close();
    }
}

Similarly, you can write to a file using FileOutputStream.

// Android
File file = ...
OutputStream out = null;
try {
    out = new FileOutputStream(file);
    // Write data to FileOutputStream

finally {
    if (out != null) {
        out.close();
    }
}

On Nokia Asha the FileConnection API (FC API) allows MIDlets to access files and directories on devices and removable media (such as memory cards) and to perform file-related operations (such as creating and deleting files or directories).

Content of a directory can be listed by opening a file connection to the directory and calling the list method.

// Nokia Asha
String url = System.getProperty("fileconn.dir.music");
FileConnection fc;
try {
    fc = (FileConnection) Connector.open(url);

    if (fc.exists()) {
        Enumeration enumeration = fc.list();
        while (enumeration.hasMoreElements()) {
            String fileName = (String) enumeration.nextElement();
            String fileUrl = fc.getURL() + fileName;
            // do something with the fileName or open a new file connection using the fileUrl
        }
    }

    fc.close();
} 
catch (IllegalArgumentException iae) { 
} 
catch (ConnectionNotFoundException cnfe) { 
} 
catch (IOException ioe) { 
}
catch (SecurityException se) { 
}
// catch any other exceptions

Content of a file can be read through a data input stream.

// Nokia Asha
FileConnection fc;
try {
    fc = (FileConnection) Connector.open(fileUrl);

    if (fc.exists() && fc.canRead()) {
        DataInputStream dataInputStream = fc.openDataInputStream();
        // read data from the dataInputStream 
        
        dataInputStream.close();
    }

    fc.close();
} 
catch (IllegalArgumentException iae) { 
} 
catch (ConnectionNotFoundException cnfe) { 
} 
catch (IOException ioe) { 
}
catch (SecurityException se) { 
}
// catch any other exceptions

You can write data by using DataOutputStream instead of DataInputStream.

// Nokia Asha

FileConnection fc;
try {
    fc = (FileConnection) Connector.open("file:///MemoryCard/testfile.out");
    if (fc.exists()) {
        fc.delete();
    }
    fc.create();
    DataOutputStream dataOutputStream = fc.openDataOutputStream();

    // write data to the dataOutputStream
    
    dataOutputStream.close();
    fc.close();
}
catch (IllegalArgumentException iae) {
}
catch (ConnectionNotFoundException cnfe) {
}
catch (IOException ioe) {
}
catch (SecurityException se) {
}  

FileSelect can be used to display a dialog for listing and selecting files based on file URL path and media type on Nokia Asha. On Android you can use Intent for displaying a selector for intended content.

// Nokia Asha
try {
     // Instantiate the FileSelect with types
     FileSelectDetail [] arrSelectedFiles = FileSelect.launch(FILE_SYSTEM_ALL, MEDIA_TYPE_PICTURE, false);
      // If files were selected and returned
     if (arrSelectedFiles != null) {
         System.out.println("number of selected files " + arrSelectedFiles.length);
         for (int i = 0; i < arrSelectedFiles.length; i++) {
             System.out.println("mime_type " + arrSelectedFiles[i].mimeType);
             System.out.println("display_name " + arrSelectedFiles[i].displayName);
             System.out.println("url " + arrSelectedFiles[i].url);
             System.out.println("size" + arrSelectedFiles[i].size);
         }
     }
} catch (Exception ex) {
     log("Exception: " + ex.toString());
}  

JSON parsing

JavaScript Object Notation (JSON) is a popular format for human-readable structured data. You can use JSONObject class in Tantalum5 cross-platform library for parsing and manipulating JSON data in both Nokia Asha and Android targets. There is also JSONGetter and JSONPoster classes for conveniently getting or posting JSON data via HTTP.

// Cross-platform example for both Nokia Asha and Android
String jsonString =
            "{"
         + "    'people': ["
         + "        {"
         + "            'firstname': 'John',"
         + "            'lastname': 'Smith'"
         + "        },"
         + "        {"
         + "            'firstname': 'Jill',"
         + "            'lastname': 'Smith'"
         + "        }"
         + "    ]"
         + "}";
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray people = jsonObject.getJSONArray("people");
for (int i = 0; i < people.length(); i++) {
    System.out.println(people.getJSONObject(i).get("firstname"));
    System.out.println(people.getJSONObject(i).get("lastname"));
}

Persistent storage

In Android, the Activity#onSaveInstanceState method is used for saving the state of the UI temporarily when switching between activities. SharedPreferences can be used for saving the internal state of the application permanently and content providers can be used when dealing with data shared between applications.

Java ME applications consist of a MIDlet so there is no need to save the UI state temporarily. Record management system (RMS) provides a mechanism through which MIDlets can persistently store data and retrieve it later. If there is a need to store the instance state while the MIDlet is running to release resources, it needs to be implemented using the RMS.

// Nokia Asha
// Open a record store
RecordStore store = RecordStore.openRecordStore("store", true);

// Add some data to the record store
byte[] data = "some content".getBytes();
int recordId = store.addRecord(data, 0, data.length);

// Update the record
data = "new content".getBytes();
store.setRecord(recordId, data, 0, data.length);

// Delete the record 
store.deleteRecord(recordId);

// List all records
RecordEnumeration enumeration = store.enumerateRecords(null, null, false);
while (enumeration.hasNextRecord()) {
    int id = enumeration.nextRecordId();
    byte[] record = store.getRecord(id);
    // do something with the record
}

// Close the record store
store.closeRecordStore();

Databases

In Android, Content providers are the interface that connects data between processes. Android ships with a number of content providers that store common data, such as contact informations, calendar information, and media files.

Here's how you can use Contacts Provider to loop through the contacts in device and get their IDs and names.

// Android
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
         null, null, null, null);
if (cur.getCount() > 0) {
    while (cur.moveToNext()) {
        String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
        String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
    }
}

In Java ME, The Personal Information Management (PIM) API provides access to PIM databases, such as contact lists, calendars, and to-do lists.

// Nokia Asha
// List the names of contacts databases
PIM pim = PIM.getInstance();
String[] listNames = pim.listPIMLists(PIM.CONTACT_LIST);
// Typically, the first name returned in the string array identifies the default contacts database
// stored on the device, and the second name identifies the contacts database stored on the SIM card.

// Open contacts list
ContactList contacts = (ContactList) pim.openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE, listNames[0]);

// List contacts
Enumeration enumeration = contactList.items();
while (enumeration.hasMoreElements()) {
    Contact contact = (Contact) contacts.nextElement();
    // do something with the contact
}

// Search contacts
Contact searchItem = contacts.createContact();
String[] name = new String[contacts.stringArraySize(Contact.NAME)];
if (contacts.isSupportedArrayElement(Contact.NAME, Contact.NAME_FAMILY)) {
    name[Contact.NAME_FAMILY] = <search term>; 
}
searchItem.addStringArray(Contact.NAME, PIMItem.ATTR_NONE, name);
enumeration = contacts.items(searchItem);
while (enumeration.hasMoreElements()) {
    Contact contact = (Contact) contacts.nextElement();
    // do something with the contact
}

Multimedia

Android provides multiple ways to play media files: MediaPlayer class can be used to control playback of audio and video files and streams, SoundPool class is optimised for game sounds and manages resources on the background for low latence playback, and an interactive music soundtrack can be implemented using JetPlayer class.

In Java ME everything is done using a Player class.

Audio

Here's how you can play audio file using MediaPlayer in Android.

// Android
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
    mediaPlayer.setDataSource(getApplicationContext(),
        Uri.parse("http://www.example.com/abc.wav"));
    mediaPlayer.prepare();
    mediaPlayer.start();
}
catch (IllegalArgumentException e) {}
catch (SecurityException e) {}
catch (IllegalStateException e) {}
catch (IOException e) {}

On Nokia Asha software platform an audio file can be played by creating a player with Manager.createPlayer method.

// Nokia Asha
try {
    Player player = Manager.createPlayer("http://www.example.com/abc.wav");
    player.start();
}
catch (MediaException me) {
}
catch (IOException ioe) {
}

Video

When showing a video, a container needs to be specified for the player by using a video control object.

// Nokia Asha
try {
    Player player = Manager.createPlayer("/abc.mpg");
    player.realize();
    VideoControl vc;
    if ((vc = (VideoControl) player.getControl("VideoControl")) != null) {
        vc.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, canvas);
        vc.setVisible(true);
    }
    player.start();
}
catch (MediaException me) {
}
catch (IOException ioe) {
}

When the player is no longer needed, it should be closed to release resources:

// Nokia Asha
player.close();

Last updated 4 July 2013

Back to top