Full details here:
http://mobilebytes.wordpress.com/2010/06/30/classes-source-for-eclipse/
This site tells you the names of the tags for checking out particular versions:
http://grepcode.com/snapshot/repository.grepcode.com/java/ext/com.google.android/android/1.6_r2/
This may also be useful:
http://android.opensourceror.org/2010/01/18/android-source/
Sunday, November 13, 2011
Sunday, October 2, 2011
Android Asset Folder
There seems to be a limit to the size of file you can read from if it placed in the assets folder in Android. Trying to read bytes from a file over 1MB results in an IOException.
Stackoverflow suggests splitting files into 1MB chunks (or giving the file an extension such as .mp3 - i.e. already compressed), and that the problem is due to Android compressing files in the assets folder when they're above a certain size.
Stackoverflow suggests splitting files into 1MB chunks (or giving the file an extension such as .mp3 - i.e. already compressed), and that the problem is due to Android compressing files in the assets folder when they're above a certain size.
Saturday, October 1, 2011
Ignoring Case in SQLite Android Queries
Instead of using the "=?" string to match strings exactly, use "like?":
db.query(TABLE_NAME, COLUMNS, REG_COLUMN + " LIKE? ", new String[] {searchQuery}, null, null, null);
instead of:
db.query(TABLE_NAME, COLUMNS, REG_COLUMN + "=? ", new String[] {searchQuery}, null, null, null);
db.query(TABLE_NAME, COLUMNS, REG_COLUMN + " LIKE? ", new String[] {searchQuery}, null, null, null);
instead of:
db.query(TABLE_NAME, COLUMNS, REG_COLUMN + "=? ", new String[] {searchQuery}, null, null, null);
Saturday, September 17, 2011
Testing internal C# methods in Visual Studio Express
Just add the following to AssemblyInfo.cs in the project under test:
[assembly: InternalsVisibleTo("NameOfTestProject")]
[assembly: InternalsVisibleTo("NameOfTestProject")]
Saturday, September 10, 2011
Building Android with Ant and External Libraries
Android seems set up by default to look in a folder called libs for libraries, so just drop your jars in there and it should just work!
Friday, September 2, 2011
Android Process Monitor
I have an app which needs to monitor whether another app is running or not. I used the following code:
List runningAppProcessInfos =
((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getRunningAppProcesses();
and search the List of RunningAppProcessInfos for the process in question, after filtering out the running services. It works perfectly, except when a search for the process in question coincides with plugging the device into a usb charger (laptop in this case). For some reason, this code fails; the process I am interested in never stops running according to logcat, but it seems to be missing from the List as my app doesn't find it, so exits (part of the logic, not a crash).
Oh well, one to look out for...
List
((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getRunningAppProcesses();
and search the List of RunningAppProcessInfos for the process in question, after filtering out the running services. It works perfectly, except when a search for the process in question coincides with plugging the device into a usb charger (laptop in this case). For some reason, this code fails; the process I am interested in never stops running according to logcat, but it seems to be missing from the List as my app doesn't find it, so exits (part of the logic, not a crash).
Oh well, one to look out for...
Saturday, August 27, 2011
Copying files in Java
This is something I've never really done much of, but when I've seen snippets of code which do this I've always thought how ugly and cumbersome it looks:
File srcFile = new File(sourceFilePath);
File destFile = new File(destinationFilePath);
FileInputStream in = new FileInputStream(srcFile);
FileOutputStream out = new FileOutputStream(destFile);
byte[] buf = new byte[2048];
int len;
while ((len = in.read(buf)) > 0)
{
try
{
out.write(buf, 0, len);
}
catch (Exception e)
{
}
}
out.flush();
in.close();
out.close();
etc...
But there is now, at last, an easier way:
import java.nio.channels.FileChannel;
...
File srcFile = new File(sourceFilePath);
File destFile = new File(destinationFilePath);
FileInputStream in = new FileInputStream(srcFile);
FileOutputStream out = new FileOutputStream(destFile);
FileChannel srcFileChannel = in.getChannel();
FileChannel destFileChannel = out.getChannel();
destFileChannel.transferFrom(srcFileChannel, 0, srcFileChannel.size());
srcFileChannel.close();
destFileChannel.close();
...
Sunday, August 7, 2011
Building Android with Ant
To create a build using an ant build.xml script, you'll need a local.properties file. This point to your sdk installation directory.
You can create this with the android tool like so:
android update project --path .
Execute from your project's directory. The full stop is important!
Remember you'll need to add keystore and proguard if you want to sign/obfustcate etc:
key.store=/path_to_keystore/keystore
key.alias=key_store_alias
proguard.dir=/path_to_proguard/lib (seems to use lib dir rather than bin)
(See here for more about signing and obfuscation)
You can create this with the android tool like so:
android update project --path .
Execute from your project's directory. The full stop is important!
Remember you'll need to add keystore and proguard if you want to sign/obfustcate etc:
key.store=/path_to_keystore/keystore
key.alias=key_store_alias
proguard.dir=/path_to_proguard/lib (seems to use lib dir rather than bin)
(See here for more about signing and obfuscation)
Saturday, July 23, 2011
Debugging with Nunit and Visual Studio Express
It's possible to set breakpoints in unit tests in the freebie versions of MS Visual Studio:
- add a reference to the C:\Program Files\NUnit 2.5.10\bin\net-2.0\lib\nunit-console-runner.dll to your test project
- add the following class to your test project using System;
- in the test project properties, under 'Application' set the output type as 'Windows Application and the Startup objects as the class created in the previous step. Under the debug tab, browse to the folder containing the csproj for the test project in the 'Working directory' field and put the name of the csproj file in the C'Command line arguments' field
- set the test project as the startup project
namespace MyTests
{
class NUnitDebugRunner
{
[STAThread]
static void Main(string[] args)
{
NUnit.ConsoleRunner.Runner.Main(args);
}
}
}
Now when you hit F5, any breakpoints in the tests will be hit.
Thanks to Blokley
Wednesday, July 20, 2011
Executing a script at startup
Having just reinstalled Linux Mint, I needed to install and setup Twonky media server again. Installing was easy with the supplied script, but to start the server (and kill it on shutdown - don't know if this is strictly necessary) you have to create a symbolic link in /etc/rc2.d which points to the twonky script in /etc/init.d and give it a name starting with Snn, where nn is a 2 digit number from 01 to 99:
sudo ln -s /etc/init.d/twonkyserver /etc/rc2.dS99twonky
To kill the server, do the same in /etc/rc0.d but call the symbolic link Knn:
sudo ln -s /etc/init.d/twonkyserver /etc/rc0.d/K99twonky
sudo ln -s /etc/init.d/twonkyserver /etc/rc2.dS99twonky
To kill the server, do the same in /etc/rc0.d but call the symbolic link Knn:
sudo ln -s /etc/init.d/twonkyserver /etc/rc0.d/K99twonky
Monday, July 18, 2011
Dual monitor setup on Linux Mint
I had a dual monitor setup running perfectly on Linux Mint 10, but struggled to get it going under Mint 11. From Googling it appears I was not alone, so I decided to skip 11 and revert to 10.
These are the steps for a clean Mint 10 installation:
These are the steps for a clean Mint 10 installation:
- open the additional drivers application and install the recommended drivers and restart the machine
- open the NVIDIA settings and enable the second monitor and check the Xinemara box
- restart the machine
That's it!
Sunday, July 3, 2011
Forcing screen to stay on
Here's a nice way to make the screen stay on for a particular activity. Just put this in the onCreate method:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
It's nicer than the POWERLOCK method, which requires an additional permission in the manifest:
<uses-permission android:name="android.permission.WAKE_LOCK">
And in your Activity:
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
this.mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");
this.mWakeLock.acquire();
//and when you're done with the WakeLock:
this.mWakeLock.release();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
It's nicer than the POWERLOCK method, which requires an additional permission in the manifest:
<uses-permission android:name="android.permission.WAKE_LOCK">
And in your Activity:
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
this.mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");
this.mWakeLock.acquire();
//and when you're done with the WakeLock:
this.mWakeLock.release();
Monday, May 30, 2011
Android strings.xml
Here's a strange one - I was working on an Android application, using the strings.xml file for the apps string resources. It so happened that I needed to have two strings in both underlined and non-underlined forms. So I added:
<string name="average_underlined"><u>average</u></string>
<string name="recent_underlined"><u>recent*</u></string>
<string name="average">average</string>
<string name="recent">recent</string>
to the strings.xml file. However, when I ran the app the underlined versions appeared where I expected the regular version to appear. After checking and rechecking I was happy the code was correct. Bizarrely, the fix was to have the non-underlined versions declared first:
<string name="average">average</string>
<string name="recent">recent*</string>
<string name="average_underlined"><u>average</u></string>
<string name="recent_underlined"><u>recent*</u></string>
If anyone can explain this to me please do get in touch!
<string name="average_underlined"><u>average</u></string>
<string name="recent_underlined"><u>recent*</u></string>
<string name="average">average</string>
<string name="recent">recent</string>
to the strings.xml file. However, when I ran the app the underlined versions appeared where I expected the regular version to appear. After checking and rechecking I was happy the code was correct. Bizarrely, the fix was to have the non-underlined versions declared first:
<string name="average">average</string>
<string name="recent">recent*</string>
<string name="average_underlined"><u>average</u></string>
<string name="recent_underlined"><u>recent*</u></string>
If anyone can explain this to me please do get in touch!
Thursday, May 26, 2011
Android - Aligning Two Views Side-by-Side
This was harder than I thought it would be - I tried playing about with relative views plus alignment settings, table views, gravity and so on.
The answer turned out to be use a LinearLayout with orientation set to horizontal and for each view (buttons in my case) set width to fill parent and layout_weight to "1":
<LinearLayout
android:id="@+id/Table01"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:orientation="horizontal"
android:layout_alignParentBottom="true">
<Button
android:id="@+id/button1"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="15sp"
android:layout_width="fill_parent"
android:layout_weight="1"
android:text="reset">
</Button>
<Button
android:id="@+id/button2"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="15sp"
android:layout_width="fill_parent"
android:layout_weight="1"
android:text="delete">
</Button>
</LinearLayout>
The answer turned out to be use a LinearLayout with orientation set to horizontal and for each view (buttons in my case) set width to fill parent and layout_weight to "1":
<LinearLayout
android:id="@+id/Table01"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:orientation="horizontal"
android:layout_alignParentBottom="true">
<Button
android:id="@+id/button1"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="15sp"
android:layout_width="fill_parent"
android:layout_weight="1"
android:text="reset">
</Button>
<Button
android:id="@+id/button2"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="15sp"
android:layout_width="fill_parent"
android:layout_weight="1"
android:text="delete">
</Button>
</LinearLayout>
Monday, May 2, 2011
Android ListViews
I've been working on an Android ListActivity which needs to have two TextViews anchored to the bottom of the screen. The anchoring was fairly simple, but when the list extended to the bottom of the screen, it obscured the anchored TextViews.
The solution is to declare the ListView last in your xml layout file, and specify what you want to be above it and what you want to be below it. I.e.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android
....>
<TextView
android:id="@+id/my_screen_header"
.......>
</TextView>
<RelativeLayout
android:id="@+id/my_screen_footer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<TextView
android:id="@+id/first_footer_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp">
</TextView>
<TextView
android:id="@+id/second_footer_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/first_footer_text_view"
android:textSize="15sp">
</TextView>
</RelativeLayout>
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@id/my_screen_footer"
android:layout_below="@id/my_screen_header"/>
</RelativeLayout>
Thanks to http://blog.maxaller.name/2010/05/attaching-a-sticky-headerfooter-to-an-android-listview/
The solution is to declare the ListView last in your xml layout file, and specify what you want to be above it and what you want to be below it. I.e.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android
....>
<TextView
android:id="@+id/my_screen_header"
.......>
</TextView>
<RelativeLayout
android:id="@+id/my_screen_footer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<TextView
android:id="@+id/first_footer_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp">
</TextView>
<TextView
android:id="@+id/second_footer_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/first_footer_text_view"
android:textSize="15sp">
</TextView>
</RelativeLayout>
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@id/my_screen_footer"
android:layout_below="@id/my_screen_header"/>
</RelativeLayout>
Thanks to http://blog.maxaller.name/2010/05/attaching-a-sticky-headerfooter-to-an-android-listview/
Saturday, April 23, 2011
Pain-free iTunes
Well, relatively pain free anyway. What a horrible horrible piece of software it is too - massive, slow, unintuitive. It make me feel tense using it. I use Linux as my OS but find that I have to use iTunes to manage music for my iPhone.
A little background - I have a lot of mp3s, all from CD ripped to the Uberstandard. Basically, this standard ensures the best possible mp3 reproduction of the CD, with all mp3 files tagged correctly. When I first started ripping CDs this way, I was told to avoid letting iTunes manage mp3s as it could change the tags, meaning the mp3 no longer met the standard. I'm not certain that this is still true, but I don't want to simply point iTunes at my music folder and let it do its stuff. I'm sure for people who are happy for their mp3s to be altered, iTunes does a fine job. For me, however, using iTunes means copying tracks to a new location before iTunes gets its paws on them.
I tried dragging and dropping from the new location onto the iTunes UI, but iTunes created duplicates of every track. Useless...
Anyway, because I use iTunes so infrequently (occasionally stick a load of tracks on the phone, get annoyed, and get the hell out of there) I've never really worked out the steps to follow each time that will work for me. I have now, and here they are:
A little background - I have a lot of mp3s, all from CD ripped to the Uberstandard. Basically, this standard ensures the best possible mp3 reproduction of the CD, with all mp3 files tagged correctly. When I first started ripping CDs this way, I was told to avoid letting iTunes manage mp3s as it could change the tags, meaning the mp3 no longer met the standard. I'm not certain that this is still true, but I don't want to simply point iTunes at my music folder and let it do its stuff. I'm sure for people who are happy for their mp3s to be altered, iTunes does a fine job. For me, however, using iTunes means copying tracks to a new location before iTunes gets its paws on them.
I tried dragging and dropping from the new location onto the iTunes UI, but iTunes created duplicates of every track. Useless...
Anyway, because I use iTunes so infrequently (occasionally stick a load of tracks on the phone, get annoyed, and get the hell out of there) I've never really worked out the steps to follow each time that will work for me. I have now, and here they are:
- find the iTunes media folder. For me this is C:\My Music\iTunes\iTunes Media
- in there there is a folder called "Automatically Add to iTunes"
- choose the music you want to put on the phone/iPod and copy it to a new location
- from this new location, drag and drop the music files to the "Automatically Add to iTunes" folder
- if iTunes is running, it will automatically move the mp3s to the library. For me, it leave empty directories behind, but I can handle that
- now, back in iTunes, select the device you want the music added to. Select Music at the top of the screen, select Sync Music and select the "Selected playlists, artists and genres" option. This means on the artists/albums etc you choose lower down on the screen will be added to the device. Anything that is already on the phone but is not checked on this screen will be removed from the device. I think it's this bit that takes some getting used to
- click Apply
Friday, April 22, 2011
Obfuscating Android
Had a play around with Proguard today. It's an obfuscation tool. Instructions for setting it up for Android are here.
However, I received an error when running
sudo ant release -v
The error was:
Expecting class path separator ':' before '{' in argument number 1
However, I received an error when running
sudo ant release -v
The error was:
Expecting class path separator ':' before '{' in argument number 1
I found the answer - I just needed to add "external.libs.dir=libs" to the default.properties file.
Thanks to Android Bridge
Friday, February 4, 2011
Rsync
Decided I'd have a go at using rsync to do my backups. I played around with a few switches, but settled upon:
-rltpDiv
I tried
-aiv
but this attempts to preserve owner/group of files. This is no good for me, as the NSLU2 changes these attributes. I'm not bothered about this at the moment, I'm just interested in getting a backup to run which does transfer 10s of GB each time when all that's changed is file ownership.
So the full command to back up my home directory is:
rsync -rltpiv /home/barry /media/nslu2/backup/rsync_home_backup --exclude '.gvfs' --exclude 'Dropbox'
where
-r means recursive
-l means copy symlinks as symlinks
-t means preserve modification times
-p means preserve permissions
-i means display differences between source and destination
-v means verbose output
-rltpDiv
I tried
-aiv
but this attempts to preserve owner/group of files. This is no good for me, as the NSLU2 changes these attributes. I'm not bothered about this at the moment, I'm just interested in getting a backup to run which does transfer 10s of GB each time when all that's changed is file ownership.
So the full command to back up my home directory is:
rsync -rltpiv /home/barry /media/nslu2/backup/rsync_home_backup --exclude '.gvfs' --exclude 'Dropbox'
where
-r means recursive
-l means copy symlinks as symlinks
-t means preserve modification times
-p means preserve permissions
-i means display differences between source and destination
-v means verbose output
Subscribe to:
Posts (Atom)