This was a simple app that lets the user scan a bar-code, take a photo then upload both the photo and bar-code to a website, it was an interesting first app.
Coming from the world of Xamarin iOS development there was a bit of culture shock with Activities and Fragments compared to view controllers. Plus if you want to access a form control you have to find it. Every control ends up as a constant in a large compiler generated file Resource.Designer.cs and to use objects mapped to them you need code like this. The controls objects are declared elsewhere.
ScanButton = FindViewById<Button>(Resource.Id.barcodeButton);
Barcode = FindViewById<TextView>(Resource.Id.barcode);
StatusView = FindViewById<TextView>(Resource.Id.status);
ImageView = FindViewById<ImageView>(Resource.Id.imageView1);
PhotoButton = FindViewById<Button>(Resource.Id.photoButton);
UploadButton = FindViewById<Button>(Resource.Id.uploadButton);
SettingsButton = FindViewById<ImageButton>(Resource.Id.settingsButton);
The first big problem was bar-code scanning but the excellent open source Apache Licensed Zxing mobile barcode scanner component solved that. Tips for working with that, get a 5″ screen phone and scan under good light. I’m very impressed with that.
Taking a photo wasn’t rocket science, there’s plenty of source for that around. But photos that are large (typically 3,000 x 2,000 pixels) need to be reduced and converted. I set a maximum largest dimension of 750 and ran this loop to calculate the new size.
float height = App.Height;
float width = App.Width;
float ratio = height/width;
while (height > 750 || width > 750)
height -= 100;
width = height/ratio;
then this code to rescale the bitmap and compress to a jpg with a quality of 80.
var reducedBitmap = Bitmap.CreateScaledBitmap(App.bitmap, (int)width, (int)height,false);
StatusView.Text = "Processing Image";
var stream = new MemoryStream();
reducedBitmap.Compress(Bitmap.CompressFormat.Jpeg, 80, stream);
var bitmapData = stream.ToArray();
Leaving me with an array of bytes to upload. Sending a string and an image together in one http post is a little bit harder. Here’s how I did it. I found Brian Grinstead’s post and used his FormUpload class.
var postParameters = new Dictionary<string, object>();
postParameters.Add("file", new FormUpload.FileParameter(bitmapData, "image.jpg", "image/jpg"));
// Create request and receive response
var postURL = UploadUrl;
var userAgent = "Someone";
var webResponse = FormUpload.MultipartFormDataPost(postURL, userAgent, postParameters);
As easy as that!
Unless you want to write it in code, you’ll find that you use XML for lots of things- the Android Manifest file, the layout of each form, strings, styles and preferences. Plus if you are targetting specific versions, screen sizes, you’ll have versions for that as well. It can add up to a lot of XML files. The layout alone is 65 lines long for just three buttons, one image button, one image view plus a couple of labels.
Debugging on Android
You have a choice of running the Xamarin simulator in VirtualBox which is ok but doesn’t really work well for scanning barcodes or taking photos so I found the USB device drivers for two handsets I had and debugged on the phones. For some phones the drivers are easy to find, others not so. Once they’re installed, ADB (Android Debug Bridge) is your friend to get going and after that just plug the phone in and Xamarin picks it up.
I found a slight bug and I’m not sure if it’s Xamarin or the phone’s drivers. I’d make a change do a rebuild and deploy and even though it said the previous version was removed it ran the previous version. Uninstalling the App fixed that but it only happened on three occasions so not a big deal.
This wasn’t for the Google Play store but a private client. All I had to do was build for Release then click Export Android Package on the build menu. That creates two .apk files and I uploaded the one that had signed in its name.
Did you know that an .apk file like a java .jar file is actually a zip file? Just rename the extension to .zip and you can see everything in it. Note that the XML files may be XML binary files but there are tools to convert them to text XML files.