Testing asynchronous calls it is not always an easy task.
Let's take as reference this simple interface:
The first thing is: how can we test it through an Android unit test class?
We can't test the value inside the callback. Infact, an async call runs usually in worker thread. When the thread has done some computation, it calls the callback. The simplest case is when the callback is run in the same worker thread.
But still, we need to find a way to block the main thread, otherwise the test class will simply don't wait before the callback is called! Remember that the method testDoSync() is called in the main thread.
We can use a semaphore, and make the test method wait until the callback is delivered. Then we can easily test the return value. The Semaphore class has some interesting properties: first, we can use it to put a thread in wait; the acquire() method stops the thread until a resource is available. As we have created the Semaphore with 0 resources available, this will cause the next call to acquire() to stop the thread.
But what if there is the unlikely case that the listener, returns before the acquire() call is made? No worries, as the signal() will simply increment the number of resources available and so the acquire() method will not nlock but will return straight away. Yay, this is for sure a better way to handle threads synchronization that the usual pattern wait-notify!
This is the code that covers this case:
And now, the worst case. Let's imagine that the code run by the worker thread do some stuff, and then it posts the results of its work in the calling thread (for instance through a handler). Then, onValueChanged() will never be called. Why? It is because we needed to stop the main thread. The main thread is a looper thread: normally a thread do some stuff and then it dies. Instead, a thread with a looper processes events by looping continuously. Another thread can post events on it: the events are put in the thread queue and they are processed one at time. If we block the main thread, the event posted by the worker thread will NEVER get processed.
How to handle this case?
We still need to block the main thread. But we need to launch the callback from a secondary thread with the looper.
We will use a facility offered by android: HandlerThread.
It will create a thread with looper for us; then the callback will be called in the secondary thread looper that is not blocked, and from that thread we can release the semaphore of the main thread.
Finally, remember to quit() the thread handler (that will quit the embedded looper too and will cause the death of that thread).
Showing posts with label java. Show all posts
Showing posts with label java. Show all posts
Friday, July 26, 2013
Friday, July 12, 2013
Dynamic resize of views and offscreen view size calculation in LinearLayout
The layout is usually handled by a set of xml files, where we specify how the components of our view group are displayed.
It should be the preferred way of generating and composing the views. It is possible to merge layouts, to inflate custom views etc.
There are some occasions, though, where the xml syntax and attributes are not powerful enough.
For example, we can have a vertical linear layout where, at some point, we inflate a custom view. We don't know how big (and, above all), tall is this view at compile time. The problem is, all or some views below it can disappear because our "big" view takes all available space.
A solution might be to wrap the views in a relative layout. All good, all fine, in that way we can specify that the big view must be below a child, and above another. Then we align the first view to the top, and the last to the bottom.
But the problem is that the height of the relative layout can't be wrapped!
As stated also in the documentation (which should have read before spending a couple of hours in adapting the layout :P)
A problem is that we can't get simply the height of the offscreen views! Since they are offscreen, Android will give us 0 as the height.
What we can do, is using the class called View.MeasureSpec and calculate the view size like this:
Then, we need to find a way to adjust the size of the big view; again, we can't do that in onCreate() or other similar callbacks, as the view is not rendered yet and we will get 0 as height of the view.
We could override the View.onMeasure() method but as it gets called multiple times by the framework, it is not very reliable.
Best thing is adding a ViewTreeObserver and do all the calculations in its callback:
The code of this example is available here:
https://github.com/nalitzis/TestDynamicViews
It should be the preferred way of generating and composing the views. It is possible to merge layouts, to inflate custom views etc.
There are some occasions, though, where the xml syntax and attributes are not powerful enough.
For example, we can have a vertical linear layout where, at some point, we inflate a custom view. We don't know how big (and, above all), tall is this view at compile time. The problem is, all or some views below it can disappear because our "big" view takes all available space.
A solution might be to wrap the views in a relative layout. All good, all fine, in that way we can specify that the big view must be below a child, and above another. Then we align the first view to the top, and the last to the bottom.
But the problem is that the height of the relative layout can't be wrapped!
As stated also in the documentation (which should have read before spending a couple of hours in adapting the layout :P)
Note that you cannot have a circular dependency between the size of the RelativeLayout and the position of its children. For example, you cannot have a RelativeLayout whose height is set toThe only way is adjusting the layout at runtime: we must calculate the height of the big view and if its bottom point is at the end of the layout and there are still views to draw, then we need to calculate their value and resize it accordingly.WRAP_CONTENTand a child set toALIGN_PARENT_BOTTOM.
A problem is that we can't get simply the height of the offscreen views! Since they are offscreen, Android will give us 0 as the height.
What we can do, is using the class called View.MeasureSpec and calculate the view size like this:
Then, we need to find a way to adjust the size of the big view; again, we can't do that in onCreate() or other similar callbacks, as the view is not rendered yet and we will get 0 as height of the view.
We could override the View.onMeasure() method but as it gets called multiple times by the framework, it is not very reliable.
Best thing is adding a ViewTreeObserver and do all the calculations in its callback:
The code of this example is available here:
https://github.com/nalitzis/TestDynamicViews
Friday, April 5, 2013
Threads signaling mechanisms in Java
In Java, there might be situations where you want to perform an operation on a certain thread and then, the same thread should wait for a certain condition before completing its task. This condition happens after another thread completes its execution.
A first option to do this is by using the wait() and notify() methods provided by Object class.
The first thread calls wait() and the callback thread calls notify().
We must be carful though, because if the notify() method happens-before the wait() one, the waiting thread will wait forever.
To prevent this, we need a boolean variable, that can be used to prevent a similar scenario:
It is also possible to use Semaphore class, from java.util.concurrent package and call acquire() and release() methods to do the same thing.
Take a look also at this interesting tutorial that deals with many important Java concurrency topics:
http://tutorials.jenkov.com/java-concurrency/index.html
For instance, we want to run a syncronous method on thread-1:
A first option to do this is by using the wait() and notify() methods provided by Object class.
The first thread calls wait() and the callback thread calls notify().
We must be carful though, because if the notify() method happens-before the wait() one, the waiting thread will wait forever.
To prevent this, we need a boolean variable, that can be used to prevent a similar scenario:
It is also possible to use Semaphore class, from java.util.concurrent package and call acquire() and release() methods to do the same thing.
Take a look also at this interesting tutorial that deals with many important Java concurrency topics:
http://tutorials.jenkov.com/java-concurrency/index.html
Sunday, December 23, 2012
Threading, loopers and messaging queues in Android
Android provides an efficient way to allow communication between different threads.
One thread can communicate with another by creating a Message object. Usually a Message is not created with the normal constructor; instead, it is used one of the static factory methods provided by the class, for instance obtain(Handler h, int what, Object data).
One way to send a message to another thread is to create a Messenger object and invoke the send method with the Message to send.
But how can we pass to the messenger which thread will receive the message? In the constructor, it is specified the handler bound to the target thread, i.e. the thread that will receive a messenger. An Handler is an object that, as its name suggests, when created, binds itself with the thread that is creating it.
Consequently, the receiver thread will create the handler, that will be used by the sender thread that calls the send() method with a Messenger object.
This is the basic behavior.
But usually we want that, at least the receiver thread, will be running indefinitely, or at least, as long as we need it running.
We can use a Looper object to transform a simple "one-shot" thread, in a thread that runs indefinitely, or at least, as long as the quit() method is not called, to quit the loop.
The Looper class "enriches" the behavior of a thread in two ways:
The Handler subclass manages the incoming message. In the example above, it just prints the data received and sleeps for 2 seconds.
I have created a short demo project consisting of a main activity and a looper thread. The looper thread processes in its queue messages sent by the main thread (ui thread) of MainActivity. A message is sent each time the button send is pressed by the user. I have inserted a sleep of 2 seconds in the handler() method of the handler bound to the receiver thread, to show that if a user clicks quickly many times on the send button, the message queue handles the incoming messages sequentially, one after the other.
The demo project can be downloaded from here:
TestLooper
Pleas note that I had to use wait() and notify() methods because the code that trasforms the thread in a looper is not so immediate, so before getting the handler we must be sure that the looper has been created.
One thread can communicate with another by creating a Message object. Usually a Message is not created with the normal constructor; instead, it is used one of the static factory methods provided by the class, for instance obtain(Handler h, int what, Object data).
One way to send a message to another thread is to create a Messenger object and invoke the send method with the Message to send.
But how can we pass to the messenger which thread will receive the message? In the constructor, it is specified the handler bound to the target thread, i.e. the thread that will receive a messenger. An Handler is an object that, as its name suggests, when created, binds itself with the thread that is creating it.
Consequently, the receiver thread will create the handler, that will be used by the sender thread that calls the send() method with a Messenger object.
This is the basic behavior.
But usually we want that, at least the receiver thread, will be running indefinitely, or at least, as long as we need it running.
We can use a Looper object to transform a simple "one-shot" thread, in a thread that runs indefinitely, or at least, as long as the quit() method is not called, to quit the loop.
The Looper class "enriches" the behavior of a thread in two ways:
- transforms a thread in an indefinite one
- creates internally a messaging queue that provides a serialized handling of the messages received. A message received is handled in the handleMessage() method of Handler.Callback.
The Handler subclass manages the incoming message. In the example above, it just prints the data received and sleeps for 2 seconds.
I have created a short demo project consisting of a main activity and a looper thread. The looper thread processes in its queue messages sent by the main thread (ui thread) of MainActivity. A message is sent each time the button send is pressed by the user. I have inserted a sleep of 2 seconds in the handler() method of the handler bound to the receiver thread, to show that if a user clicks quickly many times on the send button, the message queue handles the incoming messages sequentially, one after the other.
The demo project can be downloaded from here:
TestLooper
Pleas note that I had to use wait() and notify() methods because the code that trasforms the thread in a looper is not so immediate, so before getting the handler we must be sure that the looper has been created.
Thursday, July 12, 2012
Android fragments for beginners
Fragments have been introduced in Android with the Honeycomb milestone (aka Android 3.0). The main reason was to provide a flexible and powerful solution to deal with different kind of screens (i.e tablets and phone displays).
An activity layout is composed by one or more viewgroups, at the end, by simple views. Every view group is also called layout. An activity has one root layout, usually set with the setContentView(int resId) call.
If a layout is composed by many sublayouts/views, having all the UI code and the application logic code for the activity inside one class might quickly increase the complexity and lower the maintainability of the component.
A solution I've used in the past was to subclass the layout class and create a custom layout where I put all the UI code related to such layout. This approach has a drawback: a view group is not an activity. You've to put the app logic code inside the activity and consiquently to provide some sort of communication channel between the view and the activity when, for instance, you want to react to user actions (tap on a button, typing of a text). Components became tightly coupled and difficult to maintain/change.
With Honeycomb (but also in previous releases of the platform, thanks to the compatibility package), you can use fragments. These are like layouts but they have their own lifecycle, they have been created with the aim to contain both UI and app logic code, and can be used to provide an efficient way to deal with layouts that must be placed in different positions depending on the device the app is running on, or on the orientation of the device itself (portrait, landscape).
I've create a simple test project that shows how a layout can be created by different fragments that place themselves in a different way based on the orientation of the device.
The activity has provided a main layout for portrait and another for landscape. Fragments are placed in the LinearLayout in a different way depending on the orientation of the device:
The app logic that manages the fragment is inside the fragment itself:
As you can see, the fragment has framework methods that allow to save the current state. In the sample, a simple counter value is saved and if you change device orientation its valued isn't lost. As you can see, all the application logic pertaining the fragment is inside the fragment. The activity can handle other higher level tasks, such as fragment repositioning/move or orchestrating tasks affecting different portions of the UI.
The sample code can be found here:
https://github.com/nalitzis/SampleFragments
An activity layout is composed by one or more viewgroups, at the end, by simple views. Every view group is also called layout. An activity has one root layout, usually set with the setContentView(int resId) call.
If a layout is composed by many sublayouts/views, having all the UI code and the application logic code for the activity inside one class might quickly increase the complexity and lower the maintainability of the component.
A solution I've used in the past was to subclass the layout class and create a custom layout where I put all the UI code related to such layout. This approach has a drawback: a view group is not an activity. You've to put the app logic code inside the activity and consiquently to provide some sort of communication channel between the view and the activity when, for instance, you want to react to user actions (tap on a button, typing of a text). Components became tightly coupled and difficult to maintain/change.
With Honeycomb (but also in previous releases of the platform, thanks to the compatibility package), you can use fragments. These are like layouts but they have their own lifecycle, they have been created with the aim to contain both UI and app logic code, and can be used to provide an efficient way to deal with layouts that must be placed in different positions depending on the device the app is running on, or on the orientation of the device itself (portrait, landscape).
I've create a simple test project that shows how a layout can be created by different fragments that place themselves in a different way based on the orientation of the device.
The activity has provided a main layout for portrait and another for landscape. Fragments are placed in the LinearLayout in a different way depending on the orientation of the device:
The app logic that manages the fragment is inside the fragment itself:
As you can see, the fragment has framework methods that allow to save the current state. In the sample, a simple counter value is saved and if you change device orientation its valued isn't lost. As you can see, all the application logic pertaining the fragment is inside the fragment. The activity can handle other higher level tasks, such as fragment repositioning/move or orchestrating tasks affecting different portions of the UI.
The sample code can be found here:
https://github.com/nalitzis/SampleFragments
Saturday, June 2, 2012
Audio mix and record in Android
iOS offers, among its frameworks, many interesting features that allow to create audio tracks by simply mixing multiple tracks together. You can use Audio Unit and its methods, as described here:
http://developer.apple.com/library/ios/#documentation/AudioUnit/Reference/AUComponentServicesReference/Reference/reference.html#//apple_ref/doc/uid/TP40007291
But what if you need a similar result on Android? Android does't offer such feature in its audio framework. So I've spent a couple of days on google groups and stackoverflow, reading unanswered questions of android devs searching for a similar functionality on the Google mobile platform, or developed and released by third party contributors and external devs.
It appears there isn't nothing available.
So I've studied the problem and the tools I had to solve it. First let's see what possibilities the platform offers to play files.
Android audio framework consists of these main classes for audio playback:
Unluckily this is not always precise: sometimes you can experience a delay before a certain sound is played, and in such cases the final result is far from acceptable.
Another option is to mix sounds before playing them. This option offers you a nice plus: you obtain the mixed sound that is ready to be stored on file. If you mix sounds with SoundPool for instance, then when you play it, you cannot grab the output and redirect it to a file descriptor instead of to the audio hardware (headphones or speaker).
As mentioned at the beginning, there is no ready solution for such problem. But actually we will see the solution is rather trivial.
Before delving in the details of how 2 sounds can be mixed together, let's see how can we record a sound on Android. The main classes are:
AudioRecord offers all the features we want be able to control: we can specify the frequency, the number of channels (mono or stereo), the number of bit per sample (8 or 16).
In the fragment of code posted above, there is a simple function that can be used to record a 44.1khz mono 16 bit PCM file on the external storage. The function is blocking so it must be run on a secondary thread; it continues to record until the boolean isRecording is set to false (for example when a timeout expires or when a user taps on a button).
And now comes the most interesting part: how to mix two sounds together?
Two digital sounds can be mixed easily if files have the same features (same number of channels, same bit per samples, same frequency). This is the simplest scenario and is the only one I'm covering in this post.
Every sample in such case is a 16 bit number. In java a short can be used to represent 16 bit numbers, and infact AudioRecord and AudioTrack work with array of shorts, which simply constitute the samples of our sound.
This is the main function used to mix 3 sounds together:
There are some complementary methods I'm not posting here because this post is already too long :) but these are some small hints of what they do:
Of course this is the simplest scenario; if the samples have different frequency we should do other computations. But I think most of the time we want to mix sounds we can also control how they are recorded thus reducing its complexity a lot.
Once we have a PCM mixed sound, it can be transformed in a .wav file so that every player can read it. EDIT: as many people have asked me some more help, below it is the code snippet to build a short array from a file containing a raw stream.
http://developer.apple.com/library/ios/#documentation/AudioUnit/Reference/AUComponentServicesReference/Reference/reference.html#//apple_ref/doc/uid/TP40007291
But what if you need a similar result on Android? Android does't offer such feature in its audio framework. So I've spent a couple of days on google groups and stackoverflow, reading unanswered questions of android devs searching for a similar functionality on the Google mobile platform, or developed and released by third party contributors and external devs.
It appears there isn't nothing available.
So I've studied the problem and the tools I had to solve it. First let's see what possibilities the platform offers to play files.
Android audio framework consists of these main classes for audio playback:
- MediaPlayer: useful to play compressed sources (m4a, mp3...) and uncompressed but formatted ones (wav). Can't play multiple sounds at the same time. [HIGH LEVEL methods]
- SoundPool: can be used to play many raw sounds at the same time.
- AudioTrack: can be used as SoundPool (raw sounds), but need to use threads to play many sounds at the same time. [LOW LEVEL methods]
Unluckily this is not always precise: sometimes you can experience a delay before a certain sound is played, and in such cases the final result is far from acceptable.
Another option is to mix sounds before playing them. This option offers you a nice plus: you obtain the mixed sound that is ready to be stored on file. If you mix sounds with SoundPool for instance, then when you play it, you cannot grab the output and redirect it to a file descriptor instead of to the audio hardware (headphones or speaker).
As mentioned at the beginning, there is no ready solution for such problem. But actually we will see the solution is rather trivial.
Before delving in the details of how 2 sounds can be mixed together, let's see how can we record a sound on Android. The main classes are:
- MediaRecorder: sister-class of MediaPlayer, can be used to record audio using different codecs (amr, aac). [HIGH LEVEL methods]
- AudioRecord: sister class of AudioTrack. It records audio in PCM (Pulse Code Modulation) format. It is the uncompressed digital audio format used in CD Audio, and it is very similar to .wav file format (the .wav file has 44 bytes header before the payload). [LOW LEVEL methods].
AudioRecord offers all the features we want be able to control: we can specify the frequency, the number of channels (mono or stereo), the number of bit per sample (8 or 16).
In the fragment of code posted above, there is a simple function that can be used to record a 44.1khz mono 16 bit PCM file on the external storage. The function is blocking so it must be run on a secondary thread; it continues to record until the boolean isRecording is set to false (for example when a timeout expires or when a user taps on a button).
And now comes the most interesting part: how to mix two sounds together?
Two digital sounds can be mixed easily if files have the same features (same number of channels, same bit per samples, same frequency). This is the simplest scenario and is the only one I'm covering in this post.
Every sample in such case is a 16 bit number. In java a short can be used to represent 16 bit numbers, and infact AudioRecord and AudioTrack work with array of shorts, which simply constitute the samples of our sound.
This is the main function used to mix 3 sounds together:
There are some complementary methods I'm not posting here because this post is already too long :) but these are some small hints of what they do:
- createMusicArray reads the stream and returns a list of short objects (the samples)
- completeStreams normalizes the streams by adding a series of '0' shorts at the end of smaller files. At the end the 3 files have all the same length.
- buildShortArray converts the list in an array of short numbers
- saveToFile saves to file :)
Of course this is the simplest scenario; if the samples have different frequency we should do other computations. But I think most of the time we want to mix sounds we can also control how they are recorded thus reducing its complexity a lot.
Once we have a PCM mixed sound, it can be transformed in a .wav file so that every player can read it. EDIT: as many people have asked me some more help, below it is the code snippet to build a short array from a file containing a raw stream.
Monday, March 12, 2012
Tables and cell selections: iOS UITableView vs Android ListView
One of the first things every dev learns when he/she starts developing on a mobile platform is how to present sets of data. They could be a list of shops, an array of products and so on.
Both Android and iOS have a component to manage this kind of data: ListView for the former, and UITableView for the latter.
These classes surprisingly offer a similar interface, and have similar ways to provide the datasource to it.
Both platforms have a component to show the elements on screen and a datasource (or adapter) that manages the presentation of the tableview cells, the cells reuse and how data are presented (in which order).
iOS has a protocol, UITableViewDataSource, that every class that wants to provide some data to a UITableView must implement. The key method used to provide the tableView cells is
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
On the other side, Android datatsource is a class that extends ListAdapter.
Also this class has a method that must be always implemented:
public View getView (int position, View convertView, ViewGroup parent)
In both platforms it is very important to reuse the cells: with iOS 5 the cell recycle is managed by the system, in case the cell is declared in the .xib file as the default subview of the UITableView. It is very important though to specify a cell-id in code that matches the one declared in the .xib file.
Android use a system quite similar to that used by iOS 4.x and lower. You fetch a view inflating it from an xml file only if the view provided by the framework is null (i.e. there isn't currently a reusable cell).
This is a typical iOS 5.0 implementation:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellId"];
cell.textLabel.text = [_list objectAtIndex:indexPath.row];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
return cell;
}
While this one is an Android implementation of getView():
public View getView (int position, View convertView, ViewGroup parent){
LinearLayout layout;
if(convertView == null){
LayoutInflater inflater = (LayoutInflater)context.getSystemService(LAYOUT_INFLATER_SERVICE);
layout = (LinearLayout)inflater.inflate(R.layout.cell, null);
}
else{
layout = (LinearLayout)convertView;
}
((TextView)layout.findViewById(R.id.cell_title)).setText(dataSource.get(position));
return layout;
}
The highlithed row shows the comparision made to establish if a convertView is available. If not, it is inflated from the XML layout file.
Another important issue to face is how to customize the list selector.
In iOS it is a very straightforward procedure: just specify the selection style, or if you want a different color, create a background view with the color you want as its background and assign it to the selectedBackgroundView property (see: http://stackoverflow.com/questions/1998775/uitableview-cell-selected-color).
On Android, a premise is necessary. Every component (button, tetview, and also cell views) has different states that define how the rendering engine should show them on screen. The states are: pressed, focused, selected, enabled.
Concerning the ListView component, the system provides a way to select cells that is specified by a property called listSelector. The listSelector is an xml file with a set of rules, similar to the rules you specify on a css web page, that define how an item is shown in a set of possible states.
I've found very difficult to customize this behavior. Every time I tried to customize the cell selection appeareance, I came across many different issues: some times the selection changed the appeareance of all the tableview items, some other times the cell divider disappeared from screen.
In the official samples app there isn't a single example on how to customize such property, and also watching the World of ListView Google IO Session didn't helped me a lot (see link here : http://www.youtube.com/watch?v=wDBM6wVEO70 )
So I came up with a simple yet effective solution: get rid of the listSelector property by imposing a transparent view for every possible state, and by modifying the background of the cell items instead.
This is the selector I've used:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- <item android:drawable="@color/test_color" android:state_pressed="true" android:state_selected="true"></item> -->
<!-- <item android:drawable="@color/test_color" android:state_pressed="false" android:state_selected="true"></item> -->
<item android:drawable="@color/test_color" android:state_pressed="true" android:state_selected="false"></item>
<item android:drawable="@color/black" android:state_pressed="false" android:state_selected="false"></item>
</selector>
You can also uncomment the first two rows if you want to manage the selected state (it is useful if your device has a D-Pad).
the source code is available at github.
iOS: https://github.com/nalitzis/tableview-iphone
android: https://github.com/nalitzis/tableview-android
iOS: https://github.com/nalitzis/tableview-iphone
android: https://github.com/nalitzis/tableview-android
Labels:
Android,
iOS,
java,
ListView,
Objective-C,
UITableView,
XML
Saturday, February 25, 2012
NFC, Android, accelerometer and Node.JS can transform your mobile in a brush!
Last saturday I went to Bologna with two colleagues (@robb_casanova as frontend artisan/dev and @emme_giii as mobile UX guru), and together we participated in a contest called HackReality. http://www.whymca.org/evento/whymca-hack-reality-bologna-04-02-2012
Our intent was to mix up some native and web based technologies to transform a mobile phone into a brush, and a wall into a virtual canvas where a user, with its Android phone, could draw multi colored traits.
We used some NFC tags sticked on a paper-made palette:
We used my Galaxy Nexus as a "brush": by tapping the phone on a NFC tag on the palette we changed the paint color. Then we used the accelerometer data to detect accelerations on X and Y axis.
Data were sent to a server running socket.io on top of Node.js. We finally implemented a canvas and we used Processing language to perform the actual drawing.
The source code for the client-side part of project is available at github: https://github.com/nalitzis/hackday_client
If I'll have time, in next posts I will explain how the NFC part works.
Our intent was to mix up some native and web based technologies to transform a mobile phone into a brush, and a wall into a virtual canvas where a user, with its Android phone, could draw multi colored traits.
We used some NFC tags sticked on a paper-made palette:
We used my Galaxy Nexus as a "brush": by tapping the phone on a NFC tag on the palette we changed the paint color. Then we used the accelerometer data to detect accelerations on X and Y axis.
Data were sent to a server running socket.io on top of Node.js. We finally implemented a canvas and we used Processing language to perform the actual drawing.
The source code for the client-side part of project is available at github: https://github.com/nalitzis/hackday_client
If I'll have time, in next posts I will explain how the NFC part works.
Labels:
accelerometer,
Android,
Android4.0,
github,
hack,
java,
javascript,
NFC,
node.js,
socket.io,
websocket,
whymca,
XML
Sunday, December 4, 2011
Android PowerManager and wake locks
Today I've tested the new version of my DroidRunner Android app that now relies on a background service to track gps location updates.
To my surprise when I finished my run, I've discovered that the GPS signal had been lost many times.
That was strange since with the previous versions the GPS tracking was much more precise.
After some googling I've found that I had forgot to add a wake lock that prevents the CPU from going asleep. In previous versions that was happening much less frequently maybe because I didin't had any background service and as there was always an activity running, probably would prevent the system from going in a sleep mode.
To add a wakelock just setup a new "use-permission" in AndroidManifest.xml:
To my surprise when I finished my run, I've discovered that the GPS signal had been lost many times.
That was strange since with the previous versions the GPS tracking was much more precise.
After some googling I've found that I had forgot to add a wake lock that prevents the CPU from going asleep. In previous versions that was happening much less frequently maybe because I didin't had any background service and as there was always an activity running, probably would prevent the system from going in a sleep mode.
To add a wakelock just setup a new "use-permission" in AndroidManifest.xml:
<uses-permission android:name="android.permission.WAKE_LOCK"/>
Then, just decide which level of wake lock you want to have (for example, prevent CPU from going to sleep, with a PARTIAL_WAKE_LOCK).
Here is the list of possible options: PowerManager
This is the code snipped that can be used to request a wake lock:
PowerManager powerManager = (PowerManager)this.getApplicationContext().getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Service");
Finally, request the wakelock and release it as soon as you don't use it:
wakeLock.acquire();
...
wakeLock.release();
Tuesday, November 29, 2011
.gitignore file for Android projects
If you have an Android project and you want to share it you can setup your .gitignore file as follows:
*.class
*.apk
*.ap_
*.dex
*.DS_Store
*.proguard
.metadata/
bin/
gen/
local.properties
Don't add the .classpath entry or others will not be able to correctly setup your project.
If you have a local git repository but you use git-svn as a bridge to commit changes on a SVN remote server, then be careful to manually add empty folders to SVN as Git ignores empty folders.
Subscribe to:
Posts (Atom)



