Sunday, March 25, 2012

SQLite Exception and Course Assignment Requirements


The SQLite Exception:
java.lang.RuntimeException: Unable to destroy activity: android.database.sqlite.SQLiteException: unable to close due to unfinalised statements

I have gotten this exception while trying to close the SQLite database. It was due to trying to close the database before closing the Cursor object I was using to operate on the database. Closing the cursor before trying to close the database did the job here. ;) 

The Course Assignment Requirements:
You can download the pdf version for the requirements using the link below:
BeatSketch - requirements - pdf


Sunday, March 18, 2012

Course Project Ideas

The first idea is a game, more specifically an enhanced version of PacMan where the character would not only eat ghosts but also use special skills to make catch the ghosts or easily escape from them. The game would be a combination of PacMan, Mortal Kombat and Dragon Ball .. the last two being my favorite game and respectively tv series when I was a child.

The second idea refers to a translation application. It should be possible to take a picture of a text and than the application should extract the text from the picture using an OCR (Optical Character Recognition) and post it in a TextEdit view for the user to modify it in case there are errors in the spelling of the text. Then the user should be able to select the language the text is written in and the language he wants the text to be translated into and send the text to google translate API using the internet connection from the phone. It should also display the translated text the google API sent back to the application.

The third idea is a beat sketch application. The user should be able the sketch a beat by using a certain number of pads on the screen of the device. He should be able to make changes when it comes to the tempo of the beat, the samples selected to play when the pads are touched and also to save the file as mp3. The user should also receive help when it comes to the timing part of the beat, meaning a special sound indicating the bar number he is on at the moment and also after he finishes recording a small part of the beat the app should play the recorded layers of the beat so the user hears what he composed. Below is a screen shot of what the application could look like (this is the screen shot of the iMaschine, the iPhone application Native Instruments released not a long time ago; this application is designed to work with Maschine, a Native Instruments product ):


Monday, March 12, 2012

Draw App


For this week's hand in we have had to develop an application which allows the user to draw on the screen using gestures.
Our application (see the screen shot below) includes several controls for the app, controls like clearing the screen, increase or decrease the size of the dots, selecting the color, draw different shapes (dots, lines, squares and circles) and also controls for undoing and redoing.



The main view of the application consists of a view with a linear layout (with vertical orientation) which nests a draw view as it's first child and the controls as the second child. The reason for using a nested view is purely esthetic, its role being to hold the drawing area on top of the screen and the controls on the bottom.

The drawing is done by using an ArrayList of DrawingElement and than in the onDraw() method just paint all the elements in the ArrayList on the screen.

In order to be able to store all the elements the application uses the onTouch() method together with the actions provides by the event calling this method.

Each DrawingElement contains fields for storing the x and y coordinates when the user touches the screen and x and y coordinates for the case when the user releases the screen (these last two coordinates help in drawing all the figures except for the dots). The element also contains fields for storing the color the element has, its type and also its size (in case of the dots).

After each element is stored the invalidate() method is called in order to tell the AndroidOS to draw every element on the screen.

One could thing is that the user can select the color to draw with by using the color control. This control opens a ColorPickerDialog which changes the value of the color field in the DrawView (the nested view):


It is able to change the value of the color field because the nested view implements the ColorPickerDialog.OnColorChangedListener and than because I have implemented the colorChanged() method required for the listener:

public void colorChanged(int color) {
paint.setColor(color);

}



Another cool thing about the application is that it allows the user to see the size of the shapes he is drawing while dragging on the screen. This is done by implementing the case of MotionEvent.MOTION_MOVE. The code snippet below demonstrates this case:

in the onTouch(View view, MotionEvent event) method:

if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (moveFlag == 1 && elements.size() != 0) {
if (lineFlag == 1 || circleFlag == 1 || squareFlag == 1) {
// remove the element added by the move event
elements.remove(elements.size() - 1);
}

}

// get the end point of the line
element.x2 = event.getX();
element.y2 = event.getY();
element.color = paint.getColor();
element.size = drawSize;
if (dotFlag == 1) {
element.type = 1;
} else if (lineFlag == 1) {
element.type = 2;
} else if (circleFlag == 1) {
element.type = 3;
} else if (squareFlag == 1) {
element.type = 4;
}
// prepare a temporary element to be added to the array of
// drawing elements
DrawingElement tempElement = new DrawingElement();
tempElement.x1 = element.x1;
tempElement.y1 = element.y1;
tempElement.x2 = element.x2;
tempElement.y2 = element.y2;
tempElement.type = element.type;
tempElement.color = element.color;
tempElement.size = element.size;
elements.add(tempElement);

invalidate();
if (moveFlag == 0) {
if (lineFlag == 1 || circleFlag == 1 || squareFlag == 1) {
moveFlag = 1;
}

}

}


One other cool thing for the application is that the user can undo and redo all of his actions. This has been achieved using a stack to push the elements when the user select the undo control and pop the elements when the user selects the redo control.

public boolean onUndoClick() {
if (elements.size() != 0) {
// get the last elements
DrawingElement d = elements.get(elements.size() - 1);
// remove last element from the elements array
elements.remove(elements.size() - 1);
// insert the element in the stack
undoStack.push(d);
invalidate();
// add the action to the log
Log.d(TAG, "Undo: " + d);
}

return true;
}

public boolean onRedoClick() {
if (!undoStack.isEmpty()) {
// get the last element added to the undoStack
DrawingElement d = undoStack.pop();
// add the element to the elements array
elements.add(d);
// draw the screen
invalidate();
// add the action to the log
Log.d(TAG, "Redo: " + d);

}

return true;

}


The application can be downloaded from the link below:
The apk:

The source code:



It took me approximately 10 hours to develop this app. I have spent most of the time dealing with the motion event. The undo and redo controls took me approximately 10 minutes to implement. ;)  

Tuesday, March 6, 2012

Swipe Application

For this third hand in we have made a Swipe Application which offers the user the ability to swipe between three activities.
The activities themselves follow the same design meaning each of them contain a list.
The list is displayed on the screen using a ListView which offers the ability to scroll up and down on the list.
Below there is a screen shot of the first activity of the application (AVD targer Android 2.2 SDK version 8):



All the activities in the application follow the same layout set in the list_item.xml file.
The layout contains on a text view in which we have to specify the attributes for each of the list's element:


<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textview"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="16sp"
    android:textSize="20dp" />


The steps the activities follow on their creation are very simple ones, with the first being retrieving the array of Strings used to populate the ListView from the strings.xml file in the res/values folder of the application.


 <string-array name="countries_array">
        <item>Bahrain</item>
        <item>Bangladesh</item>
        <item>Barbados</item>
        <item>Belarus</item>
        <item>Belgium</item>
        <item>Belize</item>
        <item>Benin</item>
        <item>Romania</item>
        <item>Bulgaria</item>
        <item>Sweden</item>
        <item>Denmark</item>
        <item>Norvway</item>
        <item>Irak</item>
        <item>Afganistan</item>
    </string-array>


Then the ListView is populated with the retrieved values:

//get the String array from the strings.xml
String[] countries = getResources().getStringArray(
R.array.countries_array);
// populate the list
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item,
countries));

final ListView lv = getListView();
lv.setTextFilterEnabled(true);

These steps being done the running activity has a populated ListView which allows the user to scroll up and down through the displayed data.
Now all that is left to do is to add the swipe capabilities so that the user would swipe when he / she wants to change the activity / screen.
We do that by setting the OnTouchListener for the ListView since it covers all the screen of the activity.

                // set the listener for the swipe
lv.setOnTouchListener(new OnTouchListener() {

public boolean onTouch(View view, MotionEvent event) {
synchronized (event) {
try {
// wait for 16 ms
event.wait(16);
// when the user touches the screen
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// reset deltaX
deltaX = 0;
// get initial positions
initialX = event.getRawX();
event.getRawY();
}
// when the user releases the screen
if (event.getAction() == MotionEvent.ACTION_UP) {
deltaX = event.getRawX() - initialX;
// swiped to the left
if (deltaX > 100) {
Toast.makeText(getApplicationContext(),
"Swipe to the other direction",
Toast.LENGTH_SHORT).show();
}
// swiped to the right
else if (deltaX < -100) {
startActivity(new Intent(activity, SecondActivity.class));
}
return false;
}
} catch (InterruptedException e) {
return false;
}
}
return false;
}

});

 By calculating the difference of the x coordinate of the point when the user touches the screen and the x coordinate of the point when the user releases the screen we can determine on which direction the user swiped. If the deltaX is greater than 0 the user swiped to the left otherwise the user swiped to the right.
When we test if there was a right or a left swipe we compare deltaX with the absolute value of 100, if deltaX is greater than 100 the activity will launch the code for swiping to the left otherwise if deltaX is smaller than -100 is launches the code for swiping to the right. The reason we chose to compare deltaX with     the absolute value of 100 is so that we will be sure that the user wants to swipe and not only touching the screen since the android phone can not detect with very high precision the point the user touches the screen on.
After the OnTouchListener is set the application displays a simple text informing the user what type of information the ListView is displaying, and this is done with the help of a Toast object:

Toast.makeText(getApplicationContext(), "Countries", Toast.LENGTH_SHORT).show();


The project can be downloaded by following the link below:
http://uploading.com/files/c6ma4618/Swipper.rar/


Surprisingly the development time of this application is around 5 hours, give or take some minutes, most of this time being spent on creating the swipe capabilities.