5/19/18

Xamarin Android Build Java Exited with Code 1 ProGuard

When building a Xamarin Android app and using the option to Enable ProGuard, we may get the following error:


error MSB6006: "java.exe" exited with code 1


Note: Proguard is a file shrinker/optimizer which is often used on a release version. This can be found on the Android Options tab.



The error means that java is not able to build the application due to some an error that is raised during the build process. To find out what the error details, we need to set the MSBuild verbosity mode to Diagnostic which provides detail log on each step during the build. We can change the verbosity mode from Visual Studio Build and Run settings which can be found on the following menu option:

Tools->Options->Project and Solutions-Build and Run



Once this option is set, we should be able to compile again and see more detail about what is happening. If we look at the MSBuild output (output window on Visual Studio), we can find the error or exception that can provide more insight on the problem.

For this case, we can see that there is an error associated to the proguard tool. The error reads that there is an unknown option on the configuration file proguard.cfg.


proguard.ParseException: Unknown option '∩┐-dontwarn' in line 1 of file 'proguard.cfg', (TaskId:226)


If we look carefully, we can see that there is a funny character on the error message.  This leads us to think that there is some junk data in the proguard.cfg file, or there is an encoding problem.

Solution:

The proguard tool does not handle files that contain Byte Order Mark BOM. Visual Studio creates files with this information. The BOM is used to indicate the file encoding type. To see and remove that encoding, use a tool like Notepad++ and save the file without the BOM encoding which is a menu option when saving the file.

After removing the BOM from the file, we should be able to build the project again and see a successful build. Inspecting the log, we can also see that the proguard task completes with no errors:


Done executing task "Proguard". (TaskId:179)



Hopefully this can help solve similar errors when building Xamarin Android Apps.

Originally published by ozkary.com

5/5/18

Xamarin Android Device Mac and IP Address on a WebView JavaScript App

When using JavaScript applications with any framework, we cannot get access to some of the device information like the MAC and IP Address because JavaScript runs on an Isolated Sandbox due to security concerns.

When building hybrid applications using the WebView control on a Xamarin Android app, we can leverage the nature of the native app layer to provide the device information to the JavaScript layer. There are several ways to enable this interaction/bridge between the Native and JavaScript layers, but there is a more direct integration that can be used to handle this with less effort.

Browser UserAgent

All browsers provide a way to identify their information using the Navigator UserAgent property.  This property tells us the type of browser that is running the application like Internet Explorer, Safari, and Chrome etc.

When using the WebView control on a native app, we have more permission to control this information. This can enable our apps to set a UserAgent property that can provide the JavaScript application with device specific information.  Let’s review how that can be done by looking at a code sample with Xamarin Android project (C#) and JavaScript.

Xamarin Android Project

On the Xamarin Android project, we can set some of the WebView control properties on the OnCreate override of our activity as shown below:


private void SetWebView()
{
    WebView view = FindViewById<WebView>(Resource.Id.webView1);
    view.Settings.JavaScriptEnabled = true;
    view.Settings.UserAgentString = GetDeviceInfo();
}

private static string GetDeviceInfo()
{
    string mac = string.Empty;
    string ip = string.Empty;

    foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces())
    {
        if (netInterface.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 ||
            netInterface.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
        {
            var address = netInterface.GetPhysicalAddress();
            mac = BitConverter.ToString(address.GetAddressBytes());

            IPAddress[] addresses = Dns.GetHostAddresses(Dns.GetHostName());                   
            if (addresses != null && addresses[0] != null)
            {
                ip = addresses[0].ToString();
                break;
            }                 

        }
    }



The code loads the reference to the control. This enables us to set the control settings to enable the JavaScript functionality to run on and set the user agent with the device information.

Notice that on the GetDeviceInfo function, we get both the MAC and IP address and return the information as a delimited string similar to the format used by most browsers. This enables us to parse the information and display/use it as needed.

JavaScript Code

When navigating to the web page on the WebView control, we can now query the windows user agent property and request the information that is set by the native code as shown below:


var device = window.navigator.userAgent;
console.log(device);              
 

The console log should print out the content of the string with a pattern similar to aa-bb-cc-dd/100.10.0.0 which represents the MAC and IP address of the device.

Using this approach, we can easily provide device information to the JavaScript app to enable it to display the device MAC and IP address which is usually hidden from the JavaScript layer due to security concerns on the device.

Originally published by ozkary.com