Sony Xperia S – ICS Update Fail. No Call Volume.

Just a quick post to hopefully help those out there who have just updated to the latest ICS(Android 4.0.4 at the time of writing), and have a Sony Xperia S mobile phone.

Problem

After updating from Gingerbread(2.3.3) to Android ICS (4.0.4) on your Sony Xperia S, you loose in call volume. When making/receiving phone calls, you can’t hear anyone on the other end.

Solution

Plug in a set of earphones/headphones. Now unplug it. Problem solved!

Reason

For some bizarre and ridiculous reason if you open the LiveWare Manager application on the phone, after the update has occurred, you’ll notice that the Headphones item has a little green dot next to it indicating that headphones mode is activated, hence why you can hear sweet nothing when making/receiving calls.

The above solution worked for me, I hope it manages to help others out there frustrated by the same thing.

Android Development Part 2 – RoboGuice & Robolectric

Wow, this really is a belated post! I apologise for taking nearly 6 months to write this, but things have gotten me rather distracted over the past couple of months which hopefully I’ll share in the next few blog posts to come (I promise I won’t take another 6 more months to write those either! 🙂 )

So, as promised in my previous post, I said I’d talk about some frameworks to get you up and running quickly with building android applications. In fact there are 2 which I found invaluable. RoboGuice, and Robolectric.

RoboGuice

If you’re familiar with dependency injection and your normal run of the mill IoC frameworks, then RoboGuice will make you feel right at home! I’d already had quite a bit of experience with Spring, so using RoboGuice was relatively straight forward. They have a very good “Getting Started” guide on their site,  which I encourage you to read if you need a little nudge in the right direction. What sealed it for me was that RoboGuice could take care of the boring stuff for me, like injecting my Views, Resources and Services which I would have normally had to painstakingly code the lookups for myself. You’ll find that without RoboGuice, you’ll be coding a lot of lines that look like this (Unashamedly plagiarized from RoboGuice’s getting started page!):

class AndroidWay extends Activity {
    TextView name;
    ImageView thumbnail;
    LocationManager loc;
    Drawable icon;
    String myName;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        name      = (TextView) findViewById(R.id.name);
        thumbnail = (ImageView) findViewById(R.id.thumbnail);
        loc       = (LocationManager) getSystemService(Activity.LOCATION_SERVICE);
        icon      = getResources().getDrawable(R.drawable.icon);
        myName    = getString(R.string.app_name);
        name.setText( "Hello, " + myName );
    }
}

So as you can see, there is a fair amount of plumbing going on here, and this is just a simple view. Imagine a form input view which has a myriad of input and label fields, from drop downs, to TextViews, to Lists etc. Man I’m getting a headache just thinking how messy it could get! 🙂 So, lets face it, who really wants to have to type that line to find the view, and remember to cast it correctly,  or do that laborious resource lookup – quite frankly, its a waste of time!

So by simply using the @InjectView, @InjectResource or just plain @Inject, you can avoid all this pain quite easily, and here is a sample of the above example using RoboGuice (Unashamedly plagiarized from RoboGuice’s getting started page!):

class RoboWay extends RoboActivity {
    @InjectView(R.id.name)             TextView name;
    @InjectView(R.id.thumbnail)        ImageView thumbnail;(Unashamedly plagiarized from Roboguice's getting started page!)
    @InjectResource(R.drawable.icon)   Drawable icon;
    @InjectResource(R.string.app_name) String myName;
    @Inject                            LocationManager loc;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        name.setText( "Hello, " + myName );
    }
}

Robolectric

Now with RoboGuice and all its injectable goodness, you wouldn’t be accused of wondering if this makes your testing easier… well let me put your mind at rest and tell you, that YES, it most certainly does! And what better way to test your functionality, than with an android testing framework known as Robolectric. I’ve seen in the past, quite a few approaches to testing android apps, and some of them involved actually booting up an emulator, deploying the package, and running the app with the tests. This is a very time-consuming operation, and to be honest, most of the time, we just want to test the functionality that we have written, which can’t be done without the inclusion of the activities and views along with their respective interactions. How does Robolectric achieve this? Well, to quote from their website:

Robolectric makes this possible by intercepting the loading of the Android classes and rewriting the method bodies. Robolectric re-defines Android methods so they return null (or 0, false, etc.), or if provided Robolectric will forward method calls to shadow Android objects giving the Android SDK behavior. Robolectric provides a large number of shadow objects covering much of what a typical application would need to test-drive the business logic and functionality of your application. Coverage of the SDK is improving every day.

So, what this essentially boils down to is that, Robolectric has its own Test runner(which you use with the @RunWith annotation), which will mimic your android device, by returning what effectively is a mock object for things like location services, or views, or resources etc. You can then even override these mock objects – also referred to “shadow objects” – which you can code yourself to return a predicted outcome. This allows you to test your android app from within a JVM, even inside your own IDE! No need for bootstrapping an emulator, no need for compiling and packaging it into a dex and deploying. Just write the test, and run. The beauty of this, at least for me, is that I can now run these tests via maven, and include them as part of my CI build. Job Done. You might not be able to catch form factor bugs in this manner, but I believe that trying to test for different form factors on different devices provided by different vendors actually requires a different approach which I haven’t yet had to tackle – but when I do, my solution will be up here. 🙂

Well that’s all for now. I hope this helps any of you out there thinking of writing an android app, and need help getting started. If you can get your project structure right, and use these two frameworks I’ve mentioned, you’ll be well on your well to a painless and happily filled developement life! 🙂

Android Development Part 1 – Choosing the right project structure

I’ve been doing some android development now for a little over 4 months, and I thought I’d try to convey my lessons learnt while both celebrating my successes, and bashing my head on my not so grandest moments. I’ll attempt to break my journey into a few blog posts which will talk about project setup, all they way through to choosing the right frameowkrs, and deployment of the app.

So to start, lets talk about how to structure your project. I’ve used eclipse to develop my android goodness, and I’ve found it to suffice for what I need – although I am pretty tempted these days to IntelliJ, but thats a story for another blog post! 🙂

The best way I found to structure my project, was to use maven. Honestly, I could have just stuck with the standard project that comes with the android SDK, but there’s something that really erks me about not describing my dependiencies in a POM file! This also makes me feel a little more cosier inside for when I eventually try and set the beast up to run a Jenkins build!

OK, so we’ve established that we need to use Maven. Thats great, but how do I go about trying to structure where my files go, and what about the nice feature in eclipse that allows me to build my android project, and even deploy it?! Well, here comes the neat little plugin called : maven-android-plugin This is a fantastic little maven plugin to help you build you project, and to help you along, below is a xml snippet of what it would look like configured in your pom:

<dependencies>
	<dependency>
		<groupId>com.google.android</groupId>
		<artifactId>android</artifactId>
		<version>2.2.1</version>
		<scope>provided</scope>
	</dependency>
</dependencies>
<!-- Other config ommited for brevity -->
<build>
<plugins>
	<plugin>
		<groupId>com.jayway.maven.plugins.android.generation2</groupId>
		<artifactId>maven-android-plugin</artifactId>
		<version>2.9.0-SNAPSHOT</version> <!-- 2.8.4 -->
		<configuration>
			<sdk>
				<path>${env.ANDROID_HOME}</path>
				<!-- platform or api level (api level 4 = platform 1.6)-->
				<platform>8</platform>
			</sdk>
			<device><!-- Insert the device ID here if you want to deploy to an actual device --></device>
			<!--  emulator>emulator_name</emulator -->
			<deleteConflictingFiles>true</deleteConflictingFiles>
			<undeployBeforeDeploy>true</undeployBeforeDeploy>
			<coreLibrary>true</coreLibrary>
		</configuration>
		<extensions>true</extensions>
	</plugin>
</plugins>
</build>

One thing worth mentioning here, is the version of the maven-android-plugin I’m using. Its actually my own rolled version which I forked from the github repo because I needed to fix a bug. The bug fix has been included into the currently 3.0.0-alpha-1 release. You can read about it here. I haven’t yet updated to the 3.0.0-alpha-1 version, because I haven’t had time yet to make sure everything still works. I can’t see anything majorly wrong with using this version for now, but do be warned.. it is an alpha after all!

With that started, I’ll be writing next about some really cool frameworks there are for the android platform, that could easily cut down on the amount of code you’d have to write!

Till next time…

Maven android plugin, “–core-library” option not quite working

I’ve recently been working on building some android based applications now for the passed 3 or so months, and its been a fantastic journey so far. However, there have been times where I’ve found I talk to myself quite a bit, and for most part, I find myself muttering “what the heck is that supposed to mean?!”

This was one such occasion. I use maven for building my android project, but I had recently started using Springs RestTemplate, and there were a few libraries that I had to import while attempting to build REST based communications.

One thing that caught me off-guard, was, that when I came to build the project, I was now presented with a number of errors, all with the same sort of warning which read as:

[INFO] [android:dex {execution: default-dex}]
[INFO] C:\Program Files\Java\jdk1.6.0_20\jre\bin\java [-jar, C:\Program Files (x86)\Android\android-sdk-windows\platform-tools\lib\dx.jar, –dex, –output=C:\dev\android-sample\target\classes.dex, C:\dev\android-sample\target\android-classes]
[INFO]
[INFO] trouble processing “javax/xml/bind/annotation/adapters/CollapsedStringAdapter.class”:
[INFO]
[INFO] Ill-advised or mistaken usage of a core class (java.* or javax.*)
[INFO] when not building a core library.
[INFO]
[INFO] This is often due to inadvertently including a core library file
[INFO] in your application’s project, when using an IDE (such as
[INFO] Eclipse). If you are sure you’re not intentionally defining a
[INFO] core class, then this is the most likely explanation of what’s
[INFO] going on.
[INFO]
[INFO] However, you might actually be trying to define a class in a core
[INFO] namespace, the source of which you may have taken, for example,
[INFO] from a non-Android virtual machine project. This will most
[INFO] assuredly not work. At a minimum, it jeopardizes the
[INFO] compatibility of your app with future versions of the platform.
[INFO] It is also often of questionable legality.
[INFO]
[INFO] If you really intend to build a core library — which is only
[INFO] appropriate as part of creating a full virtual machine
[INFO] distribution, as opposed to compiling an application — then use
[INFO] the “–core-library” option to suppress this error message.
[INFO]
[INFO] If you go ahead and use “–core-library” but are in fact
[INFO] building an application, then be forewarned that your application
[INFO] will still fail to build or run, at some point. Please be
[INFO] prepared for angry customers who find, for example, that your
[INFO] application ceases to function once they upgrade their operating
[INFO] system. You will be to blame for this problem.
[INFO]
[INFO] If you are legitimately using some code that happens to be in a
[INFO] core package, then the easiest safe alternative you have is to
[INFO] repackage that code. That is, move the classes in question into
[INFO] your own package namespace. This means that they will never be in
[INFO] conflict with core system classes. JarJar is a tool that may help
[INFO] you in this endeavor. If you find that you cannot do this, then
[INFO] that is an indication that the path you are on will ultimately
[INFO] lead to pain, suffering, grief, and lamentation.
[INFO]
[INFO] 1 error; aborting
[INFO] ————————————————————————
[ERROR] BUILD ERROR
[INFO] ————————————————————————
[INFO]

Now that’s a pretty scary error to have, and on subsequent investigation, it seems like some marshalling libraries I’ve imported have the same namespace as some included java namespaces. Not to worry, I trust that the developers of this marshalling library know what they’re doing, so I just want it to build. But alas, following the instructions to use the –core-library option, the maven-android-plugin still refuses to build, and you just get back the same build error message.

I then found this nice bug report, which detailed pretty much everything I was experiencing – thank you to whoever you might be! So I thought the least I could do was fix the bug, if it was so well logged!

It turns out that the maven-android-plugin had a small bug in it, where the order of the options weren’t quite 100%. The GitHub pull request is here, and it has been accepted, so I assume it will be available in the next release.

I hope this helps anyone else out there experiencing this problem.

Null Intent passed back On Samsung Galaxy Tab…

So, I’ve had a rough few days, and by rough, I’m talking about the equivilant of a goats knee kinda rough. And if you haven’t guessed it yet, it has to do with the Samsung Galaxy Tab(the 7 inch guy), and null intents when using the camera from inside your app.

Let me set the scene, first, and tell you my story.  I was über excited to recieve my very own “work purchased” Samsung galaxy tablet yesterday, to be used for, among other things, developing some Android applications. I couldn’t contain my excitement, and this was way more fun than filling in my timesheets, so, I cracked the sucker open and began developing a little something that basically made use of the camera functionality. So I initially set off to create a test Activity which had a Gallery control, and a button to activate the camera. All I wanted to do was create a sample app, which would populate the gallery with the photos that I’d take. However, I couldn’t help but be reminded of how similar grappling with the camera functionality on the Samsung Galaxy tab is issuing a command to my ridgeback dog Bruno. Neither of them does what you expect it to! Instead, you’re just left surprised while it does its own crazy thing!  🙂

So in my example, I thought I’d try something simple. Just start the camera activity with the method call to startActivityForResult, and in the method onActivityResult, when the camera returns, I expected to be able to get both the thumbnail and the actual image in the intent’s data. Alas, this is not the case. It appears that if you populate the EXTRA_OUTPUT extra with a URI of where to store the new photo, then the camera will store the photo there for you. Now in my experience, this is true, however, with a little annoying caveat. Not only will the camera store it in the URI location that you supplied, but it also stores it in the default location of its own!

I had another problem. I wanted not only the thumbnail, but also the actual image. For the purpose of this, I didn’t really need the actual image, but more the location of where I could go and get it. Now when using the method I just previously spoke about, by providing the EXTRA_OUTPUT extra on the request intent, the camera on return to the onActivityResult, ends up passing back a NULL intent, which used to have the thumbnail image in the extra key called “data“. Now you have diddley squat!

Yet another problem I faced was that, the URI I was passing in the request intent, to tell the camera where to save this image, always ended up being NULL when the onActivityResult method was called. So now, not only do I have to somehow persist the URI that I had already passed into the request intent (to prevent it from becoming null), I now also didn’t have a thumbnail to speak of – which I used to get from the “data” extra in the return intent.

Plan B…..

It seemed that from all my reading, the best way was to create a temp file, that always had a deterministic name and location, create the file, then create a URI from that, and pass that as part of the request intent, and you could reconstruct the URI when the onActivityResult was called. Thats great, but where’s my thumbnail? Still not there? <sarcasm>Nice!</sarcasm>

Plan C….

So this is what I eventually had to resort to, in order to get both the thumbnail, AND actual image location in order to populate my gallery control with the thumbnails, and retain the actual image location so that I could display it when the user tapped on the thumbnail, and thereby also avoiding any duplicate images being stored :

Call the Camera activity as per normal Don’t do anything fancy, just create the intent with the ACTION_IMAGE_CAPTURE constant. That way, you don’t create duplicate images all over the place.

On the return call of onActivityResult, you need to do a managedQuery on the MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI and MediaStore.Images.Media.EXTERNAL_CONTENT_URI locations, and selecting the last image that was captured. This way, you are able to obtain a handle to both the thumbnail, and the image without having to deal with all the weirdness of before. Once you have these, then you’re good to go! I’ve posted some sample code below to show you what I’m talking about.


private static final int CAMERA_IMAGE_CAPTURE = 0;

public void btnTakePhoto_onClick(View view){
 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
 startActivityForResult(intent, CAMERA_IMAGE_CAPTURE);
 }

&nbsp;

@Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 super.onActivityResult(requestCode, resultCode, data);
 if(requestCode==CAMERA_IMAGE_CAPTURE && resultCode==Activity.RESULT_OK){

// Describe the columns you'd like to have returned. Selecting from the Thumbnails location gives you both the Thumbnail Image ID, as well as the original image ID
String[] projection = {
 MediaStore.Images.Thumbnails._ID,  // The columns we want
 MediaStore.Images.Thumbnails.IMAGE_ID,
 MediaStore.Images.Thumbnails.KIND,
 MediaStore.Images.Thumbnails.DATA};
 String selection = MediaStore.Images.Thumbnails.KIND + "="  + // Select only mini's
 MediaStore.Images.Thumbnails.MINI_KIND;

 String sort = MediaStore.Images.Thumbnails._ID + " DESC";

//At the moment, this is a bit of a hack, as I'm returning ALL images, and just taking the latest one. There is a better way to narrow this down I think with a WHERE clause which is currently the selection variable
Cursor myCursor = this.managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, projection, selection, null, sort);

long imageId = 0l;
long thumbnailImageId = 0l;
String thumbnailPath = "";

try{
 myCursor.moveToFirst();
imageId = myCursor.getLong(myCursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.IMAGE_ID));
thumbnailImageId = myCursor.getLong(myCursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID));
thumbnailPath = myCursor.getString(myCursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA));
}
finally{myCursor.close();}

 //Create new Cursor to obtain the file Path for the large image

 String[] largeFileProjection = {
 MediaStore.Images.ImageColumns._ID,
 MediaStore.Images.ImageColumns.DATA
 };

 String largeFileSort = MediaStore.Images.ImageColumns._ID + " DESC";
 myCursor = this.managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, largeFileProjection, null, null, largeFileSort);
String largeImagePath = "";

try{
 myCursor.moveToFirst();

//This will actually give yo uthe file path location of the image.
largeImagePath = myCursor.getString(myCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
}
finally{myCursor.close();}
 // These are the two URI's you'll be interested in. They give you a handle to the actual images
 Uri uriLargeImage = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, String.valueOf(imageId));
 Uri uriThumbnailImage = Uri.withAppendedPath(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, String.valueOf(thumbnailImageId));

// I've left out the remaining code, as all I do is assign the URI's to my own objects anyways...

}
}

I hope this helps someone else out there, cause this had me baffeled for a while. I don’t know what this just can’t be easier. Surely there’s no need to have to jump through hoops like this. Anyhoo, I’m working on getting the better managed query working, and I’ll just use this when I need it. It seems to work for the most part anyway.

Mobile Workforce on Android

So, just recently my company, G3 Global, tasked me with investigating mobile application development, with the intention to integrate into SAP. So as a proof of concept, I managed to put together a prototype mobile application that simply mimics the role of your mobile engineering workforce out in the field.

The idea simply demonstrates a job listing for an engineer, allowing them to review the job details, and contains the ability to take before and after photos of the job, as well as geo tagging the images with their current GPS location, to pin point where the images were taken. I believe Drew has already beaten me to the post (no pun intended) but if you haven’t seen it there yet, then check out the cool video we put together:

You can also find the original post on my company blog here: ‘Mobile Workforce On Android