latest posts

This morning I will be presenting at the Maryland Code Camp with the topic of Developing Once and Deploying to Many, specifically talking to practices and patterns I've found to help create rich mobile applications efficiently over the last 3 years I've been actively developing for the mobile space. WCF, WPF, PCL, MonoDroid, Azure Mobile Services and Windows Phone 8 are to be discussed.

For the Powerpoint 2013 presentation, all of the code going to be mentioned during the session, the SQL, PSD files and external libraries used, click here to download the zip file.

In addition during the session I will be making reference to an app I wrote earlier this year, jcLOG-IT, specifically the Mobile Azure Service and Windows Live Integration elements.

The code block mentioned for Authentication:
public async Task AttemptLogin(MobileServiceAuthenticationProvider authType) {
     try {
     if (authType == MobileServiceAuthenticationProvider.MicrosoftAccount) {
     if (!String.IsNullOrEmpty(Settings.GetSetting(Settings.SETTINGS_OPTIONS.LiveConnectToken))) {
     App.CurrentUser = await App.MobileService.LoginAsync(Settings.GetSetting(Settings.SETTINGS_OPTIONS.LiveConnectToken)); }
else {
     var liveIdClient = new LiveAuthClient(Common.Constants.APP_AUTHKEY_LIVECONNECT); while (_session == null) {
     var result = await liveIdClient.LoginAsync(new[] {
    "wl.signin"}
); if (result.Status != LiveConnectSessionStatus.Connected) {
     continue; }
_session = result.Session; App.CurrentUser = await App.MobileService.LoginAsync(result.Session.AuthenticationToken); Settings.AddSetting(Settings.SETTINGS_OPTIONS.LiveConnectToken, result.Session.AuthenticationToken); }
}
}
Settings.AddSetting(Settings.SETTINGS_OPTIONS.AuthType, authType.ToString()); Settings.AddSetting(Settings.SETTINGS_OPTIONS.IsFirstRun, false.ToString()); return true; }
catch (Exception ex) {
     Settings.AddSetting(Settings.SETTINGS_OPTIONS.LiveConnectToken, String.Empty); return false; }
}
]]>
The Settings class:
public class Settings {
     public enum SETTINGS_OPTIONS {
     IsFirstRun, LiveConnectToken, AuthType, LocalPassword, EnableLocation }
public static void CheckSettings() {
     var settings = IsolatedStorageSettings.ApplicationSettings; if (!settings.Contains(SETTINGS_OPTIONS.IsFirstRun.ToString())) {
     WriteDefaults(); }
}
public static void AddSetting(SETTINGS_OPTIONS optionName, object value) {
     AddSetting(optionName.ToString(), value); }
public static void AddSetting(string name, object value) {
     var settings = IsolatedStorageSettings.ApplicationSettings; if (!settings.Contains(name)) {
     settings.Add(name, value); }
else {
     settings[name] = value; }
settings.Save(); }
public static T GetSetting(SETTINGS_OPTIONS optionName) {
     return GetSetting(optionName.ToString()); }
public static T GetSetting(string name) {
     if (IsolatedStorageSettings.ApplicationSettings.Contains(name)) {
     if (typeof(T) == typeof(MobileServiceAuthenticationProvider)) {
     return (T) Enum.Parse(typeof (MobileServiceAuthenticationProvider), IsolatedStorageSettings.ApplicationSettings[name].ToString()); }
return (T) Convert.ChangeType(IsolatedStorageSettings.ApplicationSettings[name], typeof (T)); }
return default(T); }
public static void WriteDefaults() {
     AddSetting(SETTINGS_OPTIONS.IsFirstRun, false); AddSetting(SETTINGS_OPTIONS.EnableLocation, false); AddSetting(SETTINGS_OPTIONS.LocalPassword, String.Empty); AddSetting(SETTINGS_OPTIONS.LiveConnectToken, String.Empty); AddSetting(SETTINGS_OPTIONS.AuthType, MobileServiceAuthenticationProvider.MicrosoftAccount); }
}
]]>
Something I am used to checking in my Windows Phone apps that utilize your WiFi or 3G/4G/LTE signal is an active connection. Nothing is worse as an end user than an app that immediately crashes because you don't have a connection. Sad part at least for me, when I encounter a crash in an app that isn't my own, my first inclination is to check that I have a signal. Why have we gotten "programmed" to do this? I think the main reason, often when testing your own app, especially if you're a one person team, you never check the worse case scenarios. Most likely not intentionally, you're just focused on delivering your app on time (and budget if applicable). Luckily enough in MonoDroid (and Windows Phone 8), it is very easy to check for an active internet connection. In MonoDroid:
public bool HasInternetConnection {
     get {
     var connectivityManager = (ConnectivityManager)GetSystemService(Context.ConnectivityService); return connectivityManager.ActiveNetworkInfo != null && connectivityManager.ActiveNetworkInfo.IsConnectedOrConnecting; }
}
]]>
And in Windows Phone 8:
public bool HasInternetConnection {
     get {
     return NetworkInterface.GetIsNetworkAvailable(); }
}
]]>
One thing to note on MonoDroid, if you do not have the ACCESS_NETWORK_STATE permission checked under your Project's Properties -> Android Manifest -> Required Permissions: [caption id="attachment_1964" align="aligncenter" width="300"]Android Manifest - ACCESS_NETWORK_STATE required <span classfor checking Internet Connectivity" width="300" height="146" class="size-medium wp-image-1964" /> Android Manifest - ACCESS_NETWORK_STATE required for checking Internet Connectivity[/caption] You will get the following exception: [caption id="attachment_1966" align="aligncenter" width="300"]Android Exception when there <span classis no permission to check Network Connectivity" width="300" height="170" class="size-medium wp-image-1966" /> Android Exception when there is no permission to check Network Connectivity[/caption] Simply check the ACCESS_NETWORK_STATE, rebuild, deploy and you will have detection working properly.
Wrapping up the large MonoDroid application for work, one thing I had been putting off for one reason or another was handling non-image files. I was semi-fearful the experience was going to be like on MonoTouch, but surprisingly it was very similar to what you find on Windows Phone 8 where you simply tell the OS you need to open a specific file type and let the OS handle which program to open it in for you. There's drawbacks of this approach, you don't have an "in-your-app" experience, but it does alleviate the need to write a universal display control in your app - in my case this would have involved supporting iOS, Windows Phone 7.1/8 and Android, something I did not want to develop or maintain. So how do you accomplish this feat? Pretty simple assuming you have the following namespaces in your Class:
using System.IO; using Android.App; using Android.Content; using Android.Graphics; using Android.OS; using Android.Webkit; using Android.Widget; using File = Java.IO.File; using Path = System.IO.Path; ]]>
I wrote a simple function to get the Android MimeType, if none exists then return a wildcard:
public string getMimeType(string extension) {
     if (extension.Length > 0) {
     if (MimeTypeMap.Singleton != null) {
     var webkitMimeType = MimeTypeMap.Singleton.GetExtensionFromMimeType(extension); if (webkitMimeType != null) {
     return webkitMimeType; }
}
}
return "*/*"; }
]]>
And then the actual function that accepts your filename, file extension and the byte array of the actual file:
private void loadFile(string filename, string extension, byte[] data) {
     var path = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, filename); using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) {
     fs.Write(data, 0, data.Length); fs.Close(); }
var targetUri = Android.Net.Uri.FromFile(new File(path)); var intent = new Intent(Intent.ActionView); intent.SetDataAndType(targetUri, getMimeType(extension)); StartActivity(intent); }
]]>
Granted if you've already got your file on your device you can modify the code appropriately, but in my case I store everything on a NAS and then pull the file into a WCF DataContract and then back down to the phone. This approach has numerous advantages with a little overhead in both complexity and time to deliver the content - however if you have another approach I'd love to hear it. I hope this helps someone out there, I know I couldn't find a simple answer to this problem when I was implementing this functionality today.
Back at MonoDroid Development at work this week and ran into a serious issue with a DataContract and an InvalidDataContractException. Upon logging into my app instead of receiving the DataContract class object, I received this: [caption id="attachment_1943" align="aligncenter" width="300"]MonoDroid InvalidDataContractException MonoDroid InvalidDataContractException[/caption] The obvious suspect would be to verify the class had a getter and setter - sure enough both were public. Digging a bit further MonoTouch apparently had an issue at one point with not preserving all of the DataMembers in a DataContract so I add the following attribute to my class object:
[DataContract, Android.Runtime.Preserve(AllMembers=true)] ]]>
Unfortunately it still threw the same exception - diving into the forums on Xamarin's site and Bing, I could only find one other developer who had run into the same issue, but had 0 answers. Exhausting all avenues I turned to checking different combinations of the Mono Android Options form in Visual Studio 2012 since I had a hunch it was related to the linker. After some more time I found the culprit - in my Debug configuration the Linking dropdown was set to Sdk and User Assemblies. [caption id="attachment_1944" align="aligncenter" width="300"]MonoDroid Linking Option <span classin Visual Studio 2012" width="300" height="138" class="size-medium wp-image-1944" /> MonoDroid Linking Option in Visual Studio 2012[/caption] As soon as I switched it back over to Sdk Assemblies Only I was back to receiving my DataContract. Though I should also note - DataContract objects are not treated in MonoDroid like they are in Windows Phone, MVC or any other .NET platform I've found. Null really doesn't mean null, so what I ended up doing was changing my logic to instead return an empty object instead of a null object and both the Windows Phone and MonoDroid apps work perfectly off the same WCF Proxy Class.
This morning as I was continuing to dive into porting V2 of the product I recently wrapped up the ASP.Net and Windows Phone versions, I got the following exception when attempting to populate a few EditText objects after a WCF request completed: [caption id="attachment_1884" align="aligncenter" width="559"]Lovely exception when trying to update EditText Fields on another thread Lovely exception when trying to update EditText Fields on another thread[/caption] The solution, assuming you're in another thread is to use RunOnUiThread on the function you wish to update the UI with, like so:
private void setUserProfileFields() {
     editTextEmailAddress = FindViewById<EditText>(Resource.Id.txtBxProfileEmailAddress); editTextEmailAddress.Text = App.ViewModel.CurrentUserProfile.EmailAddress; }
void MainModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) {
     switch (e.PropertyName) {
     case "UP_LOADED": RunOnUiThread(setUserProfileFields); break; }
}
]]>
Ran into a fun MonoTouch error inside of Visual Studio 2012 today: [caption id="attachment_1877" align="aligncenter" width="550"]Could not load file or assembly 'moscorlib' Could not load file or assembly 'moscorlib'[/caption] Oddly enough, it only started doing that prior to a successful remote deployment. The solution is to go into your Visual Studio 2012 project properties, Build Tab and switch Generate serialization assembly to off. [caption id="attachment_1878" align="aligncenter" width="661"]Visual Studio 2012 Generate Serialization Assembly Dropdown Visual Studio 2012 Generate Serialization Assembly Dropdown[/caption]
Jumping back into MonoDroid development the last couple days at work after having not touched it in almost a year, I knew I was going to be rusty. Interestingly enough I'm finding it much closer to Windows Phone development than I remembered. Having had no luck in finding MonoDroid for Windows Phone Developers I figured I'd start an ongoing post.

Open a Browser

In Windows Phone you would open a Web Browser with the following function:
private void openBrowser(string url) {
     var task = new WebBrowserTask(); task.Uri = new Uri(url); task.Show(); }
]]>
However in MonoDroid you have to do this:
private void openBrowser(string url) {
     var browserIntent = new Intent(Intent.ActionView, Android.Net.Uri.Parse(url)); StartActivity(browserIntent); }
]]>

New Line in TextView

In Windows Phone in your XAML you'd do something like this to insert a new line into your TextBlock:
<TextBlock>This line is awesome<LineBreak/>but this one is better</TextBlock> ]]>
However in MonoDroid you need to be sure to set the singleLine property to false like so:
<TextView android:layout_width="fill_parent" android:singleLine="false" android:text="This line is awesome\r\nbut this one is better" /> ]]>

Login form (aka tapping enter goes to next field, with the last field hiding the keyboard)

In your XAML on Windows Phone you might have something like the following:
<StackPanel Orientation="Vertical"> <TextBox x:Name="TextBoxUsername" /> <TextBox x:Name="TextBoxPassword" /> </StackPanel> ]]>
And then in your code behind:
public LoginPage() {
     InitializeComponent(); TextBoxUsername.KeyDown += TextBoxUsername_KeyDown; TextBoxPassword.KeyDown += TextBoxPassword_KeyDown; }
void TextBoxUsername_KeyDown(object sender, KeyEventArgs e) {
     if (e.Key == Key.Enter) {
     TextBoxPassword.Focus(); }
}
void TextBoxPassword_KeyDown(object sender, KeyEventArgs e) {
     if (e.Key == Key.Enter) {
     Focus(); }
}
]]>
Basically upon hitting the enter key while in the TextBoxUsername field it will set the focus to the TextBoxPassword field. Upon hitting enter in the TextBoxPassword field, it will set the focus to the main page and close the keyboard. For MonoDroid, it is a little different. In your axml:
<EditText android:id="@+id/TextBoxUsername" android:imeOptions="actionNext" android:singleLine="true" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <EditText android:id="@+id/TextBoxPassword" android:imeOptions="actionDone" android:singleLine="true" android:layout_width="fill_parent" android:layout_height="wrap_content" /> ]]>
The key part is the android:imeOptions values, actionNext will move the focus to the next EditText field and the actionDone will send the done command back to your keylisteners etc. In your Activity code behind, you need to add this override. Update the Resource.Id.xxxxxxx with the name of the field you want the keyboard to hide upon hitting enter:
public override bool DispatchKeyEvent(KeyEvent e) {
     if (CurrentFocus.Id == Resource.Id.TextBoxPasswordKey && (e.KeyCode == Keycode.NumpadEnter || e.KeyCode == Keycode.Enter)) {
     var imm = GetSystemService(Context.InputMethodService) as InputMethodManager; if (imm != null) {
     imm.HideSoftInputFromWindow(this.CurrentFocus.WindowToken, 0); }
return true; }
return base.DispatchKeyEvent(e); }
]]>
I should also note you'll need the using Android.Views.InputMethods; line added to your code behind as well.

Capturing Images via the Camera

In Windows Phone capturing images from your Library or Taking a new picture is pretty trivial, assuming you have a Button to choose/take the picture:
PhotoChooserTask _pcTask = null; private byte[] _pictureBytes; public PictureUpload() {
     InitializeComponent(); _pcTask = new PhotoChooserTask(); _pcTask.Completed += new EventHandler<PhotoResult>(_pcTask_Completed); }
void _pcTask_Completed(object sender, PhotoResult e) {
     if (e.TaskResult == TaskResult.OK) {
     MemoryStream ms = new MemoryStream(); e.ChosenPhoto.CopyTo(ms); _pictureBytes = ms.ToArray(); ms.Dispose(); }
}
private void btnChooseImage_Click(object sender, RoutedEventArgs e) {
     _pcTask.ShowCamera = true; _pcTask.Show(); }
]]>
From there just upload the _pictureBytes to your WCF Service or wherever. In MonoDroid as expected is a little different, assuming you have a button click event to take the picture and an ImageView to display the image:
private string _imageUri; // Global variable to access the image's Uri later void btnChooseImage_Click(object sender, EventArgs e) {
     var uri = ContentResolver.Insert(isMounted ? Android.Provider.MediaStore.Images.Media.ExternalContentUri : Android.Provider.MediaStore.Images.Media.InternalContentUri, new ContentValues()); _imageUri = uri.ToString(); var i = new Intent(Android.Provider.MediaStore.ActionImageCapture); i.PutExtra(Android.Provider.MediaStore.ExtraOutput, uri); StartActivityForResult(i, 0); }
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) {
     if (resultCode == Result.Ok && requestCode == 0) {
     imageView = FindViewById<ImageView>(Resource.Id.ivThumbnail); imageView.DrawingCacheEnabled = true; imageView.SetImageURI(Android.Net.Uri.Parse(_imageUri)); }
}
]]>
At this point you have the picture taken and the Uri of the image. In your Layout:
<Button android:text="Choose Image" android:id="@+id/btnChooseImage" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <ImageView android:id="@+id/ivThumbnail" android:layout_width="300dp" android:layout_height="150dp" /> ]]>

Loading a picture from local storage and avoiding the dreaded java.lang.outofmemory exception

A fairly common scenario, maybe pulling an image from the code described above, now you want to upload it some where? In the Windows Phone above in addition to taking/capturing the picture, we have a byte[] with the data, on MonoDroid it is a little different. A situation I ran into on my HTC Vivid was a java.lang.outofmemory exception. Further investigation, apparently Android has a 24mb VM limit per app (and some devices it is set to 16mb). Doing some research, I came across Twig's post. As expected it was in Java, so I converted it over to MonoDroid and added some additional features to fit my needs. So literally this function will return a scaled Bitmap object for you to turn around and convert to a Byte[]. The function:
private Android.Graphics.Bitmap loadBitmapFromURI(Android.Net.Uri uri, int maxDimension) {
     var inputStream = ContentResolver.OpenInputStream(uri); var bfOptions = new Android.Graphics.BitmapFactory.Options(); bfOptions.InJustDecodeBounds = true; var bitmap = Android.Graphics.BitmapFactory.DecodeStream(inputStream, null, bfOptions); inputStream.Close(); var resizeScale = 1; if (bfOptions.OutHeight > maxDimension || bfOptions.OutWidth > maxDimension) {
     resizeScale = (int)Math.Pow(2, (int)Math.Round(Math.Log(maxDimension / (double)Math.Max(bfOptions.OutHeight, bfOptions.OutWidth)) / Math.Log(0.5))); }
bfOptions = new Android.Graphics.BitmapFactory.Options(); bfOptions.InSampleSize = resizeScale; inputStream = ContentResolver.OpenInputStream(uri); bitmap = Android.Graphics.BitmapFactory.DecodeStream(inputStream, null, bfOptions); inputStream.Close(); return bitmap; }
]]>
For a practical use, loading the image, scaling if necessary and then getting a Byte[]:
var bitmap = loadBitmapFromURI(Android.Net.Uri.Parse(_imageUri), 800); var ms = new MemoryStream(); bitmap.Compress(Android.Graphics.Bitmap.CompressFormat.Jpeg, 100, ms); ]]>
At this point doing a ms.ToArray() will get you to the same point the Windows Phone code above did, so if you had a WCF Service, you could at this point upload the byte array just as you could with a Windows Phone above.

Transparent Background on a ListView, LayoutView etc?

In Windows Phone you can set the Background or Foreground properties to simply Transparent like so:
<StackPanel Background="Transparent" Orientation="Vertical"> <TextBlock>Transparentcy is awesome</TextBlock> </StackPanel> ]]>
In MonoDroid it's simply "@null" like so for the ListView
<ListView android:background="@null" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:text="Transparentcy is awesome" android:gravity="center" /> ]]>

Locking Orientation

In Windows Phone you can set your page's orientation to be forced into Landscape or Portrait in your xaml like so:
<phone:PhoneApplicationPage SupportedOrientations="Portrait" Orientation="Portrait"> ]]>
In MonoDroid I couldn't figure out a better way to do it than the following line inside your Activity's OnCreate function like so:
protected override void OnCreate(Bundle bundle) {
     base.OnCreate(bundle); RequestedOrientation = ScreenOrientation.Portrait; }
]]>
On a side note, you'll need to add this line to the top of your Activity if it isn't already there: using Android.Content.PM;
For the last 2.5 years I've been using the default MonoDevelop Web Reference in my MonoTouch applications for work, but it's come to the point where I really need and want to make use of the WCF features that I do in my Windows Phone applications. Even with the newly released iOS Integration in Visual Studio 2012, you still have to generate the proxy class with the slsvcutil included with the Silverlight 3.0 SDK. If you're like me, you probably don't have Version 3.0 of the Silverlight SDK, you can get it from Microsoft here. When running the tool you might get the following error: Error: An error occurred in the tool. Error: Could not load file or assembly 'C:\Program Files (x86)\Microsoft Silverl ight\5.1.10411.0\System.Runtime.Serialization.dll' or one of its dependencies. T his assembly is built by a runtime newer than the currently loaded runtime and c annot be loaded. Basically the tool is incorrectly trying to pull the newer 4.0 or 5.0 Silverlight Assemblies, to make it easy, I created a config file to simply drop into your c:\Program Files (x86)\Microsoft SDKs\Silverlight\v3.0\Tools folder, you can download it here. From a command line (remember the shortcut to hold shift down and right click in the folder to open a command prompt): [caption id="attachment_1853" align="aligncenter" width="593"]Silverlight 3 WCF Proxy Generation Silverlight 3 WCF Proxy Generation[/caption] Enter the following, assuming you want to create a proxy for a localhost WCF Service to your c:\tmp folder: SlSvcUtil.exe http://localhost/Service.svc?wsdl /noconfig /d:c:\tmp Though I should note, this will generate Array collections and not List or ObservableCollection collections. If you want to generate your Operation Contracts with return types of those collections simply add for List Collections: /collectionType:System.Collections.Generic.List`1 or ObservableCollection: /collectionType:System.Collections.ObjectModel.ObservableCollection`1
Had a fun time today getting a picture taken from an Android 2.3.4 HTC Vivid to my Mobile WCF Platform. Oddly enough, I could not find any tutorials on it for Monodroid like there are for MonoTouch. Piecing together several stackoverflow posts, I finally figured it out. Here is a possible solution (most likely not the best): At the top of your class, add the following:
private string _imageUri; private ImageView imageView; private Boolean isMounted {
     get {
     return Android.OS.Environment.ExternalStorageState.Equals(Android.OS.Environment.MediaMounted); }
}
]]>
Inside your Button Click Event:
var uri = ContentResolver.Insert(isMounted ? Android.Provider.MediaStore.Images.Media.ExternalContentUri : Android.Provider.MediaStore.Images.Media.InternalContentUri, new ContentValues()); _imageUri = uri.ToString(); var i = new Intent(Android.Provider.MediaStore.ActionImageCapture); i.PutExtra(Android.Provider.MediaStore.ExtraOutput, uri); StartActivityForResult(i, 0); ]]>
Right below your Click Event function (or anywhere inside the Activity Class you're in):
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) {
     if (resultCode == Result.Ok && requestCode == 0) {
     imageView = FindViewById(Resource.Id.ivThumbnail); imageView.DrawingCacheEnabled = true; imageView.SetImageURI(Android.Net.Uri.Parse(_imageUri)); btnUploadImage.Visibility = ViewStates.Visible; }
}
]]>
Then inside your "Upload Button Click" function:
Bitmap bitmap = imageView.GetDrawingCache(true); MemoryStream ms = new MemoryStream(); // Note anything less than 50 will result in very pixelated images from what I've seen bitmap.Compress(Android.Graphics.Bitmap.CompressFormat.Jpeg, 100, ms); // At this point set your Byte[] variable/property with ms.ToArray(); // for instance I have a SyncFile object with a FileData Property, so I use // SyncFile sFile = new SyncFile() {
     FileData = ms.ToArray(); }
; ]]>
Effectively this code captures a picture, puts it in an ImageView as a thumbnail on the Activity and then upon hitting your Upload Button it converts the image into a Byte Array after compressing it (or not like in my case) and from there call your WCF service upload function. Hopefully that helped someone out.
Monodroid gave me headaches this afternoon, trying to mimic the Pivots on Windows Phone 7 on Android using the TabActivity. You would think you access an Activity after attaching it to a TabActivity. Well the answer is you can, but figuring it out on Monodroid will make your hair go gray. After digging through the Java based Android Documentation I finally figured it out. I don't know if this is the right way, but it works: Declare an enumeration object with each of your tabs:
public enum TABS {
     BasicInformation = 0, Detailinformation = 1, OptionalInforation = 2 }
; ]]>
Then add an abstract class to each of your Activity Objects:
public abstract class MyDroidActivity : Activity {
     public abstract bool SaveActivity(); // Any other custom code you had }
Then inside your inherited Activity: public class BasicInfoActivity : MyDroidActivity {
     public override bool SaveActivity() {
     // Error handling to return false if for instance the fields weren't populated }
}
]]>
Then in your TabActivity Class:
private void SaveAllTabs() {
     TabHost.CurrentTab = (int)TABS.BasicInformation; BasicInformation biTab = (BasicInformation)LocalActivityManager.GetActivity(TabHost.CurrentTabTag); if (!biTab.SaveActivity()) {
     return; }
// And continue with your other Tabs }
]]>
Not the most elegant, but works. The inherited class and enumerations are not necessary, but helps keep things in order, especially if you have a larger application in my opinion.
Chances are you'll get this error after adding images from either another project, an artist etc. I got it with an image that had a "-" in it. Ensure your drawable assets are 0-9, a-z or _.
Last night when working on my Silicon Graphics Origin 300 and suffering with an old version Mozilla circa 2005 as seen below: [caption id="attachment_896" align="aligncenter" width="300" caption="Mozilla 1.7.12 on IRIX"][/caption] I started wondering, these machines can function as a Web Server, MySQL server, firewall etc especially my Quad R14k Origin 300, yet web browsing is seriously lacking on them. Firefox 2 is available over at nekoware, but that is painfully slow. Granted I don't use my Origin for web browsing, but when I was using a R12k 400mhz Octane as my primary machine a few years ago as I am sure others around the world are doing it was painful. This problem I don't think is solely for those on EOL'd Silicon Graphics machines, but any older piece of hardware that does everything but web browsing decently. Thinking back to the Amazon Silk platform, using less powerful hardware, but a brilliant software platform, Amazon is able to deliver more with less. The problem arises for the rest of the market because of the diversity of the PC/Workstation market. The way I see it you've got 2 approaches to a "universal" cloud web renderer. You could either:
  1. Write a custom lightweight browser tied to an external WCF/Soap Web Service
  2. Write a packet filter inspector for each platform to intercept requests and return them from a WCF/Soap service either through Firefox Extensions or a lower level implementation, almost like a mini-proxy
Plan A has major problems because you've got various incarnations of Linux, IRIX, Solaris, VMS, Windows etc, all with various levels of Java and .NET/Mono support (if any), so a Java or .NET/Mono implementation is probably not the right choice. Thus you're left trying to make a portable C/C++ application. To cut down on work, I'd probably use a platform independent library like Gsoap to handle the web service calls. But either way the amount of work would be considerable. Plan B, I've never done anything like before, but I would imagine would be a lot less work than Plan A. I spent 2 hours this morning playing around with a WCF service and a WPF application doing kind of like Plan A. [caption id="attachment_897" align="aligncenter" width="300" caption="jcW3CLOUD in action"]in action" width="300" height="189" class="size-medium wp-image-897" />[/caption] But instead of writing my own browser, I simply used the WebBrowser control, which is just Internet Explorer. The Web Service itself is simply:
public JCW3CLOUDPage renderPage(string URL) {
     using (WebClient wc = new WebClient()) {
     JCW3CLOUDPage page = new JCW3CLOUDPage(); if (!URL.StartsWith("http://")) {
     URL = "http://" + URL; }
page.HTML = wc.DownloadString(URL); return page; }
}
]]>
It simply makes a web request based on the URL from the client, converts the HTML page to a String object and I pass it into a JCW3CLOUDPage object (which would also contain images, although I did not implement image support). Client side (ignoring the WPF UI code):
private JCW3CLOUDReference.JCW3CLOUDClient _client = new JCW3CLOUDReference.JCW3CLOUDClient(); var page = _client.renderPage(url); int request = getUniqueID(); StreamWriter sw = new StreamWriter(System.AppDomain.CurrentDomain.BaseDirectory + request + ".html"); sw.Write(page.HTML); sw.Close(); wbMain.Navigate(System.AppDomain.CurrentDomain.BaseDirectory + request + ".html"); ]]>
It simply makes the WCF request based on the property and then returns the HTML and writes it to a temporary HTML file for the WebBrowser control to read from. Nothing special, you'd probably want to add handling for specific pages, images and caching, but this was far more than I wanted to play with. Hopefully it'll help someone get started on something cool. It does not handle requests from with the WebBrowser control, so you would need to override that as well. Otherwise only the initial request would be returned from the "Cloud", but subsequent requests would be made normally. This project would be way too much for myself to handle, but it did bring up some interesting thoughts:
  1. Handling Cloud based rendering, would keeping images/css/etc stored locally and doing modified date checks on every request be faster than simply pulling down each request fully?
  2. Would the extra costs incurred to the 3G/4G providers make it worthwhile?
  3. Would zipping content and unzipping them outway the processing time on both ends (especially if there was very limited space on the client)
  4. Is there really a need/want for such a product? Who would fund such a project, would it be open source?
After some additional work getting used to the XAML-ish layout I'm done with the initial jcBENCH Android port. You can download it from here. You will need Android 2.2 or higher for it to run. [caption id="attachment_874" align="aligncenter" width="244" caption="jcBENCH Android"][/caption] I've only tested this on a Dual 1.2ghz HTC Vivid. However, the results were interesting. Comparing single-threaded and multi-threaded operations was curious. Running it in multi-threaded mode was actually 3 times slower. I'm not sure if the way the Task Parallel Library was implemented on Monodroid was done poorly or if there is a bug in the detection for how many cores/cpus there are inside the Mono implementation or not, but something isn't right. Single threaded versus my HTC Titan 1.5ghz SnapDragon it lost out by ~23%. Which makes sense, 300mhz difference or 20% comparing single cores to each other. All that being said I'm content with jcBENCH for the moment until I hear feedback or come up with more features to add.
With this new release I've fixed a bunch of things in Web Service and the main library that powers all of the clients. In addition I'm tracking a bit more information like the platform and benchmark version (thinking more down the road when specific versions are going to change in the logic in the actual algorithm). Also this release marks the first release of the GUI Mac OS X 10.6 (and later) client. [caption id="attachment_848" align="aligncenter" width="565" caption="jcBENCH on Mac OS X"][/caption] You'll need GTK 2.12 or newer and Mono 2.10.8 or newer to run it. Being my first Mac OS X application ever outside of iOS development, I can without a doubt say I cannot stand development on anything Apple. KVC has got to be the most bloated way of doing things I have ever seen. I am so glad I do not have to do native Mac OS X applications for a living. That being said though, I think it turned out pretty well in matching the WPF version.
Found a bug in either mono or WCF, not sure which one. But if you go to add a Web Reference in Mono Develop (2.8.5) and have an Entity Model Object as a parameter for an object some of the properties will be null. Debugging had me scratching my head as the object was populated prior to sending to the WCF Service. I hadn't tried it as a Native WCF Service in Mono Develop because I've had prior problems with that route. The solution I came up with was create a serializable object in your WCF Service that wraps the object like so: [Serializable] public class BenchResult { public string CPUName; .... } Then in your application your reference will contain (in my case a BenchResult object) the object you defined and upon populating and passing it to your WCF Service all of the data will be populated. Nearly 2 hours gone down the drain on that issue, hopefully it helps someone else.