|
|
I just downloaded Filezilla for my mac. I thought I should verify the checksum before installing the soft.
That’s how I did it :
openssl dgst -sha512 FileZilla_xxx.tar.bz2
and I compared the output with the corresponding hash in the checksum file.
… I guess this post is for my own reference
I have deployed a new version of the Accelerometer Values application on the Android market. I left the previous app as I have changed a lot of things in the code and in the package organization. However, I will remove the old one soon, once everybody is happy with the new one
Now, you can log the values of the accelerometer to a file on the sdcard (many people requested this feature). You can also change the colors (background and x,y,z values) and you can decide how often the application should catch the sensor values. However, depending on the phone, if you choose to catch the values too fast (like every 10 ms) and at the same time log the values to a file, the app or even the phone might get frozen for a couple of seconds (eventually, you might need to kill the activity).
I hope you will find the logging feature useful, let me know if you are fine with how the data are stored in the file.
What I enjoy with frameworks like Grails or Rails is that they are taking care of all the object relational mapping for me. So, I can really concentrate on the domain object model and the framework will care about the underlying work. Fortunately, when needed, I can still “talk” to the database directly. Also, with the scaffolding I can quickly get a feeling for the application and see if the domain model makes any sense.
The many-to-many relationship and how Grails treats it is kind of interesting.
Let’s take an example. In a project, I have two domain classes that are connected with a many-to-many relationship, ExpDesign, ExpConditionValue. ExpDesign represents an experimental design, ExpConditionValue represents a value for a condition in a design. So an experimental design (ExpDesign) can have multiple condition values (ExpConditionValue) and those can belong to many ExpDesign. So, that is clearly a many-to-many relationship which needs a join table and Grails knows it.
This is how we tell Grails (with hasMany) about the many-to-many relationship:
class ExpDesign {
static hasMany = [expConditionValues: ExpConditionValue]
...
}
class ExpConditionValue {
static hasMany = [expDesigns: ExpDesign]
...
}
But actually, that’s not enough. We also need to tell Grails (with belongsTo) which class is the owner of the other (more about belongsTo later) :
class ExpConditionValue {
static hasMany = [expDesigns: ExpDesign]
static belongsTo = [ExpConditionType]
}
It’s clear that ExpDesign owns ExpConditionValue, therefore I put the belongsTo in ExpConditionValue.
Before I run the code, I want to modify it to specify the names of the mapping tables for my two classes. My convention is to add underscores before upper case letters and pluralize the domain name to define the table name. So here, the tables would be called EXP_DESIGNS and EXP_CONDITION_VALUES. To define the join table name, Grails appends both names with an underscore, so here it would be EXP_DESIGNS_EXP_CONDITION_VALUES. However, as I use Oracle, it will not work because of the length of the table name. I figured this out running describe all_tab_columns (did you know that Oracle limits table name length to 30 characters?). So, I want to specify not only the tables names but also the join table name.
The modified code:
class ExpDesign {
static mapping = {
table 'EXP_DESIGNS'
expConditionValues joinTable: 'EXP_COND_VALS_DESIGNS'
}
static hasMany = [expConditionValues: ExpConditionValue]
...
}
class ExpConditionValue {
static mapping = {
table ' EXP_COND_VALUES'
expDesigns joinTable: 'EXP_COND_VALS_DESIGNS'
}
static hasMany = [expDesigns: ExpDesign]
static belongsTo = [ExpDesign]
...
}
With that I let Grails take care about the relationship, I just enforced the names of the domain tables and the join table.
belongsTo
belongsTo tells grails that the other class is the owning class in the relationship. In my case, ExpDesign owns (many) ExpConditionValue. The first consequence is that ExpDesign deletes will be cascaded to ExpConditionValues. Whenever a ExpDesign will be deleted all its associated ExpConditionValues will be deleted as well, without the belongsTo they would not.
In the case above, I have used the unidirectional belongsTo clause but a bidirectional version exists as well (e.g. static belongsTo = [expD : ExpDesign]) which would enable to navigate from the object to its owning object.
What is interesting as well is that belongsTo combined to hasMany tell Grails enough about our model that it will be able to add up some dynamic methods like exp.addToExpConditionValues(val1) that will automatically persist objects to the DB.
Thanks to grails, a lot of the magic happens in the background and for us much less tedious code to write!
Grails has an incredible amount of very useful features, amongst those the dynamic methods on domain objects. When we generate the scaffolding for a controller for a domain object we get the default list method in the controller which uses the list method on the domain object. The list method takes params as argument containing max, offset, order and sort. With this method we can already paginate through a collection of the domain objects. That’s what the scaffolding gives us for free.
But that’s not always enough. In the current system I’m working on I decided to add a boolean flag deleted on some domain objects. The reason is that I cannot allow normal users to really delete the objects from the db, so when a user deletes an object I just flag the object as being deleted, thus I can always recover it. However, I don’t want this object to appear anymore in the list. So, an easy way to achieve that is withCriteria. If you wonder what the difference is between withCriteria and createCriteria, from what I understood withCriteria is just a shorter form of createCriteria.
First, the default list method in the controller is generated by the scaffolding:
def list = {
params.max = Math.min( params.max ? params.max.toInteger() : 10, 100)
[ dataTypeInstanceList: DataType.list( params ), dataTypeInstanceTotal: DataType.count() ]
}
And that the method I first added to my domain object DataType using createCriteria:
static notDeleted(params) {
createCriteria().list(max: params.max, offset: params.offset, sort: params.sort, order: params.order) {
and {
eq('deleted', false)
}
}
}
There should be a shorter version with withCriteria which should work as good as the previous one from what I have read. I tried something like the following but the pagination didn’t work.:
static notDeleted(params) {
withCriteria {
eq('deleted', false)
}
}
It looks pretty simple but it’s pretty powerful as you can combine a lot of operator.
And below my modified list method in the controller with a modified count:
def list = {
params.max = Math.min( params.max ? params.max.toInteger() : 10, 100)
[ valueInstanceList: Value.notDeleted( params ), valueInstanceTotal: Value.countByDeleted(false) ]
}
First my use case. A user inserted a couple of thousands records into a database describing animal samples for a transcriptomics study. In this table there is a column ‘description’ which is for free text. The user made a mistake: among other information in this description column he put ‘rat’ instead of ‘mouse’. So now, how to keep the text just replacing ‘rat’ by ‘mouse’? Groovy to our rescue!
def sql = groovy.sql.Sql.newInstance("jdbc:oracle:thin:@server.domain:1521:database", "user", "password", "driver")
sql.eachRow("select * from database.table where table_column_ = 'xxxx") {
newDescription = (it.description =~ /Rat/).replaceAll('Mouse')
id = it.id
updateCall = "update database.table set description = '$newDescription' where id = $id"
sql.executeUpdate(updateCall)
}
- Line 1 creates a sql connection to the database
- Line 3 iterates through the results of the passed select statement (each row will be in the it and fields can be accessed by their name)
- Line 4 does the regular expression find&replace in the description string
- =~ looks if there is a match (takes it.description as argument)
- The slash defines the RegEx. So in our case we are looking for Rat (/Rat/, for first letter lower and upper case we could have put /[R|r]at/)
- and finally .replaceAll(‘Mouse’) to replace what was found with the regular expression
- Line 6 & 7 to build and call the update
Scripting languages like groovy can sometimes be very painful but luckily more often they are just great!
Here is the code of the accelerometer values application for Android. I did this application in a couple of hours to test the Android platform so the features are very basic. I’m currently working on a new version that will include logging of the values and a few other things.
However, here is the code of the two main classes of the application. It will compile with recent versions of the Android SDK even though some methods have been deprecated meanwhile.
package com.arak.sensor.accele;
import android.view.View;
import android.hardware.SensorManager;
import android.hardware.SensorListener;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Paint;
import android.graphics.Color;
import java.util.LinkedList;
import java.text.DecimalFormat;
public class AcceleView extends View implements SensorListener {
public final static int MAX_VALUES = 200;
public final static int SCALING = 3; // for G to graphic
public final static int GSCALING = 2; // for panels
public final static int MARGIN_TOP = 15;
public final static int SEPARATION = 20;
public final static int MARGIN_LEFT = 10;
private long timekeeper;
private final LinkedList<float[]> fifo;
private float height;
private float width;
private float halfRectHeight;
private float xYLine;
private float yYLine;
private float zYLine;
private float pX;
private float pY;
private float pZ;
private float minX;
private float minY;
private float minZ;
private float maxX;
private float maxY;
private float maxZ;
public AcceleView(Context context, SensorManager sma) {
super(context);
timekeeper = android.os.SystemClock.uptimeMillis();
fifo = new LinkedList<float[]>();
int mask = 0;
mask |= SensorManager.SENSOR_ORIENTATION;
mask |= SensorManager.SENSOR_ACCELEROMETER;
sma.registerListener(this, mask, SensorManager.SENSOR_DELAY_FASTEST);
pX = 0f;
pY = 0f;
pZ = 0f;
minX = 0f;
minY = 0f;
minZ = 0f;
maxX = 0f;
maxY = 0f;
maxZ = 0f;
}
protected void onDraw(Canvas canvas) {
height = canvas.getHeight();
width = canvas.getWidth();
halfRectHeight = SCALING * 10 *GSCALING;
xYLine = MARGIN_TOP + SCALING * 10 *GSCALING;
yYLine = xYLine + halfRectHeight * 2 + SEPARATION;
zYLine = yYLine + halfRectHeight * 2 + SEPARATION;
clear(canvas);
drawGridAndLastValues(canvas);
drawValues(canvas);
}
public void onSensorChanged(int sensor, float[] values) {
if (android.os.SystemClock.uptimeMillis() < timekeeper + 20) return;
timekeeper = android.os.SystemClock.uptimeMillis();
final float[] val = new float[]{values[0], values[1], values[2]}; // defensive copy because keeps the same object
if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
if (fifo.size() > MAX_VALUES) fifo.poll();
fifo.add(val);
minX = Math.min(minX, val[0]);
minY = Math.min(minY, val[1]);
minZ = Math.min(minZ, val[2]);
maxX = Math.max(maxX, val[0]);
maxY = Math.max(maxY, val[1]);
maxZ = Math.max(maxZ, val[2]);
invalidate();
}
}
public void onAccuracyChanged(int i, int i1) {
/* @todo implement method */
}
private void clear(Canvas canvas) {
Rect rect = new Rect();
rect.set(0, 0, canvas.getWidth(), canvas.getHeight());
Paint p = new Paint();
p.setStyle(Paint.Style.FILL);
p.setColor(Color.WHITE);
canvas.drawRect(rect, p);
}
private void drawGridAndLastValues(Canvas canvas) {
Paint p = new Paint();
// print measured values
DecimalFormat df = new DecimalFormat("##.#");
String xStringVal = df.format(pX);
String yStringVal = df.format(pY);
String zStringVal = df.format(pZ);
String xMinStringVal = df.format(minX);
String yMinStringVal = df.format(minY);
String zMinStringVal = df.format(minZ);
String xMaxStringVal = df.format(maxX);
String yMaxStringVal = df.format(maxY);
String zMaxStringVal = df.format(maxZ);
//x
String xText = "X values [last: " + xStringVal + " - min:" + xMinStringVal + " - max:" + xMaxStringVal + "]";
p.setColor(Color.LTGRAY);
canvas.drawRect(MARGIN_LEFT, xYLine - halfRectHeight, width - MARGIN_LEFT, xYLine + halfRectHeight, p);
p.setColor(Color.BLACK);
canvas.drawLine(MARGIN_LEFT, xYLine, width - MARGIN_LEFT, xYLine, p);
canvas.drawText(xText, MARGIN_LEFT + width / 6, xYLine - halfRectHeight - 2, p);
canvas.drawText("+2G", MARGIN_LEFT, xYLine - halfRectHeight + 10, p);
canvas.drawText("-2G", MARGIN_LEFT, xYLine + halfRectHeight, p);
//y
String yText = "Y values [last: " + yStringVal + " - min:" + yMinStringVal + " - max:" + yMaxStringVal + "]";
p.setColor(Color.LTGRAY);
canvas.drawRect(MARGIN_LEFT, yYLine - halfRectHeight, width - MARGIN_LEFT, yYLine + halfRectHeight, p);
p.setColor(Color.BLACK);
canvas.drawLine(MARGIN_LEFT, yYLine, width - MARGIN_LEFT, yYLine, p);
canvas.drawText(yText, MARGIN_LEFT + width / 6, yYLine - halfRectHeight - 2, p);
canvas.drawText("+2G", MARGIN_LEFT, yYLine - halfRectHeight + 10, p);
canvas.drawText("-2G", MARGIN_LEFT, yYLine + halfRectHeight, p);
//z
String zText = "Z values [last:" + zStringVal + " - min:" + zMinStringVal + " - max:" + zMaxStringVal + "]";
p.setColor(Color.LTGRAY);
canvas.drawRect(MARGIN_LEFT, zYLine - halfRectHeight, width - MARGIN_LEFT, zYLine + halfRectHeight, p);
p.setColor(Color.BLACK);
canvas.drawLine(MARGIN_LEFT, zYLine, width - MARGIN_LEFT, zYLine, p);
canvas.drawText(zText, MARGIN_LEFT + width / 6, zYLine - halfRectHeight - 2, p);
canvas.drawText("+2G", MARGIN_LEFT, zYLine - halfRectHeight + 10, p);
canvas.drawText("-2G", MARGIN_LEFT, zYLine + halfRectHeight, p);
}
private void drawValues(Canvas canvas) {
float len = (width - MARGIN_LEFT * 2) / MAX_VALUES;
Paint p = new Paint();
float xVal = MARGIN_LEFT;
boolean first = true;
for (float[] f : fifo) {
float x = f[0];
float y = f[1];
float z = f[2];
if (first) {
pX = x;
pY = y;
pZ = z;
first = false;
}
p.setColor(Color.GREEN);
canvas.drawLine(xVal, xYLine - pX * SCALING, xVal + len, xYLine - x * SCALING, p);
p.setColor(Color.RED);
canvas.drawLine(xVal, yYLine - pY * SCALING, xVal + len, yYLine - y * SCALING, p);
p.setColor(Color.BLUE);
canvas.drawLine(xVal, zYLine - pZ * SCALING, xVal + len, zYLine - z * SCALING, p);
xVal += len;
pX = x;
pY = y;
pZ = z;
}
}
}// END
package com.arak.sensor.accele;
import android.app.Activity;
import android.os.Bundle;
import android.hardware.SensorManager;
import android.content.Context;
public class ShowSensor extends Activity {
private AcceleView av;
@Override
public void onCreate(Bundle args) {
super.onCreate(args);
av = new AcceleView(this, (SensorManager) getSystemService(Context.SENSOR_SERVICE));
setTitle("Show Sensor Values");
setContentView(av);
}
}
We can do it with initialization blocks. I find it actually a very interesting feature of java even though I would recommend to be very careful when using it. Indeed, initialization blocks might confuse people looking at your code especially if there is not only one and if it’s not placed close to the constructor.
So an initialization block looks like that:
{
list = new ArrayList()
}
Assuming the list member has been defined, this code will be executed just as it would have been inserted at the very beginning of the constructor.
And if there would be many of them, they would all be called in the order they appear in the class (ok, that’s even more dangerous !). Initialization blocks can also throw exceptions, as long as the constructor throws the same exceptions as well.
Now the question is: why would you use an initialization block instead of putting everything in the constructor or in a init() method like we always do. I guess, it depends. For sure, init() cannot set final members, initialization blocks can.
Also, in an anonymous inner classes, we cannot define constructors, a initialization block can play the constructor role. Code generators can also take advantage of initialization blocks, UI builders for instance.
Here is a little examples of a class with two initialization blocks and random exception.
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class TryItOut {
private List list;
{
System.out.println("calling Hello()");
hello();
}
{
System.out.println("adding element to list");
list.add("blabla");
if (new Random().nextBoolean())throw new Exception("exception!");
}
public TryItOut() throws Exception {
System.out.println("starting constructor, how many elements? ");
System.out.println(list.size());
}
public void hello() {
System.out.print("hello");
list = new ArrayList();
for (int i = 0; i < 10; i++) list.add("hello" + i);
System.out.println(" world " + list.size());
}
public final static void main(String[] args) {
try {
new TryItOut();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Interesting, isn't it??
I’m currently working on refactoring an UI/ORM application and the database it connects to. I need to change a lot of things in the db design so I was looking for a simple java tool that would allow me to easily export tables from the database to a defined XML format.
A tool that would produce something like that:
value_col1
value_val2
value_col1
value_val2
I briefly googled but I couldn’t find anything free and easy to use. I know there must be! Anyway, I found an elegant way to do it with Groovy and wanted to share it.
def sql = groovy.sql.Sql.newInstance("connectionString", "user", "password", "db_driver")
def fileOut = new FileWriter("/path/to/out/put/file.xml")
def xml = new groovy.xml.MarkupBuilder(fileOut)
xml.table_entries {
sql.eachRow("select * from schema.table") {row ->
entry {
column1(row.column1)
column2(row.column2)
...
}
}
}
1 minute to write the code to export one table, isn’t Groovy great?
You want your android application to be responsive, so you have to “multithread” it. But actually, “twothreading” should be enough in many cases.
The main thread, the one on which the application started, can be used to wait for user input like touchscreen events. So whenever the user does something, the event is caught on the main thread. The second thread’s job is just to draw on the screen. So, one thread for catching events and one for drawing, that’s it!
However, as they are separated thread, accessing their common data needs some synchronization. Obviously, when the user clicks something on the screen (once again, event caught by the main thread), the drawing thread needs to modify the drawing in consequence.
So, how did I do it concretely?
I created a drawing class that implements the interface Runnable. As you know, implementing Runnable is a much better approach than extending Thread. This class is responsible for all the drawing tasks in the game, responsible does not mean that it draws everything itself.
To be able to stop the thread, I use a volatile boolean run, which has to be set to truebefore the thread is started. The boolean is declared volatile to ensure that any thread that reads it sees its most recent value (I’m not sure it’s really needed here). Once runis false, the thread will be stopped for ever.
Here some pieces of my drawing class with the runmethod that implements Runnable:
public class SilhouDrawing implements Runnable {
...
private final SurfaceHolder surfaceHolder;
private final Handler handler;
private final Context context;
...
private volatile boolean run;
...
public SilhouDrawing(SurfaceHolder surfaceHol, Context cont, Handler hand) {
surfaceHolder = surfaceHol;
handler = hand;
context = cont;
}
...
public void run() {
while (run) {
Canvas c = null;
try {
c = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
if (state == STATE_RUNNING) {
doDraw(c);
}
}
} finally {
if (c != null) {
surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
...
public void setRunning(boolean b) {
run = b;
}
...
}
As soon assetRunninghas been called with falsethe thread stops doing anything because of the while condition. It does not mean that the thread has yet been destroyed, only that nothing is happening anymore in the run method.
With the statemember, the class knows if it’s worth drawing or not. If the activity would be hidden, the state value would be STATE_PAUSED and thus no CPU would be wasted drawing something that would not appear on the screen.
As already said, the doDraw method controls the drawing.
private void doDraw(Canvas canvas) {
long now = System.currentTimeMillis();
if (now - lastTime < 20) return;
lastTime = now;
...
canvas.drawBitmap(backgroundImage, 0, 0, null);
...
for (Card c : CardsFactory.cards) {
c.draw(canvas);
}
...
}
So the first three lines (using the timing) are only there to save resources and to make sure the drawing happens 50 times per seconds (1000 / 50 = 20). I could put this in the run method or use the try{...Thread.sleep(20)... call. I don’t know what is better.
If time is fine, I draw the background image and then every card (try the game you will understand) is responsible to draw itself on the canvas.
So now, how do I create and use this class. That happens in the SurfaceView of my game.
public class SilhouView extends SurfaceView implements SurfaceHolder.Callback {
...
private SilhouDrawing painter;
private Thread thread;
public SilhouView(Context context, AttributeSet attrs) {
super(context, attrs);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
painter = new SilhouDrawing(holder, context, new Handler());
setFocusable(true); // make sure we get key events
}
...
So the SurfaceViewcreates the painter and passes it a reference to its SurfaceHolder to enable the drawing.
When the SurfaceView is created it will call (because of the callback mechanism) the surfaceCreated method which in turn gives our painter the right to start its job:
public void surfaceCreated(SurfaceHolder holder) {
thread = new Thread(painter);
painter.setRunning(true);
thread.start();
}
If setRunning(true)would be called after thread.start(), the thread would never do anything as the while loop in the run code would fail.
To finally get rid of the thread, I use the thread.join()which will wait for the thread to die as the Java Api Specification says. I do this in the surfaceDestroyed(...) of my SurfaceView.
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
painter.setRunning(false);
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
Ok, the code is very similar to examples that you might have seen somewhere else. But it seems to work. I will explore different ways to do it and let you know later about my experiments.
I hope you enjoy coding Java-Android as much as I do!
It’ s pretty straight forward to add music and sound to an android application.
For music, I use the Mediaplayer class. For simple short sounds that I need at different stages in the application (transitions, selections, etc.) I use the SoundPool class. SoundPool enables to load short sound sequences directly in memory at the start of the application, sounds that can be used later on at any time in the application.
In Silhouette, I use a class with static members and methods. So the music player and the sounds are available during the whole game life cycle and they can be called from anywhere. It works pretty well.
Continue reading Adding sound and music to an android game
|
|