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.

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);




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")]

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...

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)

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:
  1. 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
  2. add the following class to your test project
  3. using System;
    namespace MyTests
    {
        class NUnitDebugRunner
        {
            [STAThread]
            static void Main(string[] args)
            {
                NUnit.ConsoleRunner.Runner.Main(args);
            }
        }
    }

  4. 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
  5. set the test project as the startup project
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

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:

  1. open the additional drivers application and install the recommended drivers and restart the machine
  2. open the NVIDIA settings and enable the second monitor and check the Xinemara box
  3. 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();

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!

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>

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/

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:


  1. find the iTunes media folder. For me this is C:\My Music\iTunes\iTunes Media
  2. in there there is a folder called "Automatically Add to iTunes"
  3. choose the music you want to put on the phone/iPod and copy it to a new location
  4. from this new location, drag and drop the music files to the "Automatically Add to iTunes" folder
  5. 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
  6. 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
  7. 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

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