Friday 9 March 2012

Java Multipart Upload Code (Android Friendly)



This is a quick function to do a multipart upload of a file in android (and Java in general). It is adapted from Adrian Smith's code here: http://www.17od.com/2010/02/18/multipart-form-upload-on-android/.

 The differences are:
  1. This function will not try to read the file into a string (which imposes size restrictions).
  2. You can pass the content type of the file upon execution
  3. It returns whether or not it was successful and the HTTP response code.
  4. It does not read the response to the upload (if you want to add it back in, the code is in Adrian Smith's page above).

Thursday 5 January 2012

Setting up a second monitor as the primary one in Gnome 3 (Ubuntu 11.10))

Gnome 3 (at least under Ubuntu 11.10) seems to have been shipped with a number of features missing. For example:

  1. No easy way to change the screensaver (follow this: http://www.makeuseof.com/tag/change-screensaver-ubuntu-1110/).
  2. No out-of-the-box way to change the system fonts (you have to use gnome-tweak-tool)
  3. No out-of-the-box way to change the theme settings (follow this: http://www.omgubuntu.co.uk/2011/10/how-to-install-gnome-shell-themes-in-ubuntu-11-10/)
For me, the most annoying one is the lack of a user-friendly way to set any second/external monitor as your primary one (i.e. where the Gnome bar/task bar will appear). 

You can set the orientation of the monitors in the settings, and how you want them aligned but that's about it. Here is a screenshot of the Display settings dialogue: 



Long story short, open a terminal and enter the following:

$xrandr --output VGA-0 --primary

Root is not needed. 
If you don't know how your external port is called (VGA-0 in my case), you can press Tab after the "--output" to see the list of interfaces X recognises. Simply replace VGA-0 with what you see fit.

Thursday 29 December 2011

Decompiling and displaying the source of an Android APK

This is a Windows-centric post, but it should be fairly straight-forward to make this work in Linux/MacOS by porting the script file and downloading the platform-correct version of JD-GUI.

Why do it
  1. You are curious to see how an application does what it does by reading its code.
  2.  You want to make sure that your application is properly obfuscated before making it public (i.e. you don't want people doing #1 and/or ProGuard is giving you grief).
You will need
What to do
  • Create a directory and name it something appropriate (for example apk-decompile).
  • Download and extract dex2jar and JD-GUI in the directory you created.
  • Make sure you rename the folders to match the file structure below:
  • Create a new text file in the root directory (apk-decompile in our example) and name it "go.bat".
  • Open it in notepad and paste the following:
echo off

REM Make sure we are working off the local directory.
set _=%~dp0
chdir /d "%_%"
echo Working directory is: "%_%"

IF "%~1"=="" GOTO BAD_SYNTAX

echo Converting dex to jar:
call dex2jar\dex2jar %1
echo.

echo Opening Class Viewer:
start "" jd-gui\jd-gui.exe %1.dex2jar.jar
echo.

echo DONT CLOSE THIS DIALOGUE UNTIL YOU'VE FINSHED CHECKING THE FILE AS IT WILL AUTOMATICALLY BE DELETED.
pause

del %1.dex2jar.jar

exit 0

:BAD_SYNTAX
echo Error! Incorrect syntax.
echo The correct syntax is:
echo  %0 ^<path_to_apk^>;
pause
exit 1

How to use this
  • You can either use the command line and type the following: go.bat <path_to_apk>
  • You can drag and drop an apk file onto go.bat.
Notes
 I'm certain that there are other, probably more efficient ways to do this but this suits my purposes (for now).

Tuesday 20 September 2011

Two ListViews Side by Side in Android

The following XML shows how to place two ListViews side by side, add some seperator views and button bars for any actions needed.
Even though fragment now make the creation and maintenance this type of layout much easier, simple application might benefit from this without having to include the compatibility library.

The result will look like this:


(The layout file is after the break)

Monday 19 September 2011

Getting a Bitmap out of a Zip file in Android (or Java in general)

The following function will extract an image from a zip file stored anywhere on the filesystem (for as long as the application has access to it).

It will return a bitmap object if the image is found or null otherwise. This function should work in pure java as well with minor alterations (replacing the Log calls with system.outs).


public Bitmap getBtimapFromZip(final String zipFilePath, final String imageFileInZip){
	Log.d(TAG, "Getting image '" + imageFileInZip + "' from '" + zipFilePath +"'");
	Bitmap result = null;
	try {
		FileInputStream fis = new FileInputStream(zipFilePath);
		ZipInputStream zis = new ZipInputStream(fis);
		ZipEntry ze = null;
		while ((ze = zis.getNextEntry()) != null) {
			if (ze.getName().equals(imageFileInZip)) {
				result = BitmapFactory.decodeStream(zis);
				break;
			}
		}
	} catch (FileNotFoundException e) {
		Log.e(Constants.TAG, "Extracting file: Error opening zip file - FileNotFoundException: ", e);
		e.printStackTrace();
	} catch (IOException e) {
		Log.e(Constants.TAG, "Extracting file: Error opening zip file - IOException: ", e);
		e.printStackTrace();
	}
	return result;
}

If you you use a wrapper function like this:
private void loadImage(ImageButton button, String image){
	// Use this drawable by default
	Drawable d = context.getResources().getDrawable(R.drawable.no_image);
	Bitmap b = getBtimapFromZip("path_to_zip_file", image);
	
	if(b != null){ // if the bitmap is not null, load that instead.
		d = new BitmapDrawable(b);
	}
	
	button.setImageDrawable(d);
}

you can have a fallback drawable to display if something goes wrong (the above bit is Android specific).

A few things to keep in mind:
  1. To get the image out of the zip file you are scanning through all records in the archive sequentially. This could be a performance hit if you have many images. 
  2. If the function returns null but you know that the image is in there, check that you havent accidentally archived the top directory along with the images when creating the zip.

Thursday 11 August 2011

Sending emails via Gmail (and others) in Java.

The following class will send emails from a java program. It definitely works on Gmail accounts and if you know the settings it should work on others as well. Keep in mind that it needs the javax.mail jar in your classpath.

You can use it like this:

private static void sendEmail(){  
     String[] toRecipients = {"he@it.com", "you@yes.you", "hey@there.com"};  
     String[] ccRecipients = {"this@concerns.you", "and@you.too"};  
     EmailSender es = new EmailSender("smtp.gmail.com", 465, "myEmail@gmail.com", "myPassword");  
     boolean res = es.sendEmail("myEmail@gmail.com", toRecipients, ccRecipients, "Hey guys!", "I can automate email sending now!");  
     if(res){  
          System.out.println("Woohoo!");  
     } else {  
          System.err.println("Hmmmm... Something went wrong...");  
     }  
}  
And here is the class:

Monday 27 June 2011

Fixing the "Error getting final archive: Debug certificate expired on xx/xx/xxxx" problem

If you are developing Android applications for a while on the same computer (specifically for more than 365 days) you should be familiar with the "Error getting final archive: Debug certificate expired" error which will stop you from testing your applications.

When the Android SDK is installed, it creates a Debug Key which is used to automatically sign applications when you hit the run button and upload them to the Emulator/Test device. The certificate is only valid for 365 days after which you get the error above.

There are two ways to tackle this issue:
  1. You can either get the Android SDK to recreate a debug key - and repeat this every 1 year.
  2. You can create your own key and set the expiry date yourself.