Tuesday, March 26, 2013

Publishing "RekenMaar" to Google Play

One of the first ever dot42 apps is called "RekenMaar" (which is Dutch for Let's do some mathematics). This apps (written by my wife) is intended to let our children practice mathematics while "playing" on the tablet.

We've now published this app in Google Play.
This articles talks about what was needed to publish this app.

Publishing in Google Play

Publishing the app in Google Play was an easy process.
 We first uploaded the APK to Google Play (Android Developer Console). After the upload, Google Play complaint about a missing version code. That was indeed correct, so we added this line to our code:
[assembly: Package(VersionName = "1.0.0",
        VersionCode = 2)]
Then we re-compiled, re-tested and re-uploaded. This time everything was fine.

We then had to upload screenshots (press Volume Down and Power button at the same time on Android 4.1 to make one), add a high resolution icon and a product description. During that process Google Play warned us several times that the application was for free. "Did we really want that?"

Finally we activated the APK and published the app.
Now all we had to do was to wait a few hours until the app appeared in Google Play.

Thursday, March 14, 2013

Reference a JAR file

Roughly there are two types of JAR files: JAR files that act like a stub and JAR files that contain an actual implementation.

Stub JAR 

The Google maps API (v1) is a good example of a stub JAR. The maps funtionality is implemented elsewhere and the stub basically forwards calls to it.

We already support this type of JAR file. When you right-click your project in Visual Studio, you will see a menu item 'Add Jar Reference...'. This will generate some C# code in the background that reflects the API of the stub JAR. You can code against it and dot42 will link this accordingly during compilation. In order to link to the actual implementation, you had to enter the library name in the "Add Jar Reference..." dialog. This library name is used in the generated C# code in an assembly attribute like this:
[assembly: UsesLibrary("com.google.android.maps")]
This assembly attribute is the equivalent of the uses-library element as in the following application's manifest file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.example.package.name">
  ...
  <application android:name="MyApplication" >
    <uses-library android:name="com.google.android.maps" />
    ...
  </application>
  ...
</manifest>

Implementation JAR

The second type contains an actual implementation. The Google Cloud Message JAR (gcm.jar) falls under this category. Unfortunately we do not support this one yet. The good news is that it is not on our 5-years roadmap but is being implemented right now. It involves converting Java byte code to Dex just like we already convert IL code to Dex. We expect to release it in the next 4 weeks.

How to determine the type of JAR?

So, how to tell what type a given JAR file is? dot42 ships with a handy tool: dot42ApkSpy. Although its name suggests differently, it allows you to inspect both APK and JAR files. You can find this tool at "c:\Program files\dot42\dot42ApkSpy.exe".

When we open the Google Cloud Messaging gcm.jar and navigate to onReceive, we see that there is actual code:


So, this is a JAR that contains the actual implementation.

But if we then open the Google Maps maps.jar, and navigate to method Overlay.draw, we see the following:


It has no implementation. It just throws a runtime exception. Also note the "stub" in the code. This is a stub JAR.


Wednesday, March 13, 2013

1.0.0.60: What's new?

To get the latest version, run "Check for updates" or download.


New: Modify target version of project depending on your device's Android version.

When you create a new dot42 project it will automatically target the latest Android version (currently 4.2). If your device supports this version, there is no problem, but if your device supports an older Android version, you have to remember to change the target version to the version of your device.

We have canged the device dialog that pops up when you run your dot42 project from Visual Studio.


When you select a device that does not support the Android version your project targets, it shows a warning and gives you the option to change the target version of your project. You do this by simply clicking "Yes change project version". Next, you rebuild your project and run it again.

New: Added OpenGL, R.Layout.Simple_item_list1, Camera and Simple HttpServer samples.

We've added several new samples:
  • Animation\SpinningCube showing the use of OpenGL in dot42.
  • Widgets\SimpleListItem1 showing the use of the build-in Android.R.Layout.Simple_list_item_1 resource used for listview items.
  • Camera\SimpleCamera showing how to create a simple camera app that previews the camera image and allows you to take pictures.
  • Network\SimpleHttpServer showing how to use server sockets to implement a very simple HTTP server. It will respond with "Hello world" on each request.

New: Added support for "supports-screens" element in Android manifest.

The <supports-screens> element of the Android manifest can now be created using the Dot42.Manifest.SupportsScreens attribute.
For example:
[assembly: SupportsScreens(
    NormalScreens = true, 
    XLargeScreens = true, 
    SmallScreens = false)]

New: Added update check to Visual Studio plugin.

When you use dot42 inside Visual Studio it will check for updates of dot42. This is done atmost once a day.

Change: "static readonly string" constants in the Android API are now available as "const string".

All static literal string-type fields in the Android API are now converted as "const" string in the dot42 assembly. As a result you can use them in attribute definitions like this:
[assembly: UsesPermission(Android.Manifest.Permission.ACCOUNT_MANAGER)]

Change: Changed debugger attachment process.

Currently, the most reported issue is that the debugger fails to attach to the app running on the device. In this version we have made further changes to resolve this and to enhance diagnostics. If you encounter this issue, please open the Device log and send screenshots of its content to support@dot42.com.

Change: Sign converted method (sbyte parameters to byte parameters) have been removed from interfaces.

Almost all primitive types supported by Java are a perfect match for their countersparts in .NET. For example int is int, float is float and so on. The byte type is the exception. A byte is a signed 8-bit integer in Java and and an unsigned 8-bit integer in .NET. To make matters worse, .NET uses unsiged bytes all over the place while Java only has signed bytes.

To make this easier for a C# developer, dot42 has sign converted methods for all API methods that have a signed byte in it. That means there are 2 methods, one with sbyte parameters and one with byte parameters. The dot42 compiler takes care of the correct mapping and conversion.

This caused problems with interfaces. As an interface is a contract you now had to implement 2 methods for some interfaces instead of 1. That is why we removed the byte methods from interfaces.

Fixed: '.' in resource ID breaks compilation of R.cs.

If you use a '.' in a resource ID (which is valid in Android) it is now correctly handled by dot42.
For example a resource id of "my.resource" is now accessible as R.Ids.my_resource in C#.

Fixed: Missing resources.arsc due to MSBuild 'optimization'.

In rare cases the dot42 MSBuild "forgot" to build some resource elements.

Fixed: IntentFilter manifest support fails.

The use of the (Dot42.Manifest).IntentFilter attribute caused a compiler error. This has been resolved.

Friday, March 8, 2013

Spinning cube: an OpenGL code sample

This code sample demonstrates how to write an OpenGL application using dot42.


Download the Visual Studio 2010/2012 Professional project. Make sure you have dot42 installed.

About OpenGL

Android includes support for high performance 2D and 3D graphics with the Open Graphics Library (OpenGL), specifically, the OpenGL ES API. OpenGL is a cross-platform graphics API that specifies a standard software interface for 3D graphics processing hardware. OpenGL ES is a flavor of the OpenGL specification intended for embedded devices. Read more.

OpenGL and dot42

Since dot42 supports the entire Android framework API, OpenGL is fully at your disposal. Note that dot42 does NOT introduce a performance penalty. Your compiled code calls directly into OpenGL.

MainActivity

Here is the code for the main activity:

[Activity]
public class MainActivity : Activity
{
  protected override void OnCreate(
    Bundle savedInstance)
  {
    base.OnCreate(savedInstance);          
        
    GLSurfaceView glView = new GLSurfaceView(this);
    glView.SetRenderer(new MyRenderer());

    SetContentView(glView);
  }     
}

GLSurfaceView is a View where you can draw and manipulate objects using OpenGL API calls and is similar in function to a SurfaceView.

MyRenderer implements interface GLSurfaceView.IRenderer. This interface defines the methods required for drawing graphics in an OpenGL GLSurfaceView. MyRenderer is attached to the GLSurfaceView instance using GLSurfaceView.SetRenderer().

MyRenderer

Here is the code for MyRenderer:

public class MyRenderer : GLSurfaceView.IRenderer
{
  private Cube mCube = new Cube();
  private float mCubeRotation;

  public void OnSurfaceCreated(
    IGL10 gl, EGLConfig config)
  {
    gl.GlClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    gl.GlClearDepthf(1.0f);
    gl.GlEnable(IGL10Constants.GL_DEPTH_TEST);
    gl.GlDepthFunc(IGL10Constants.GL_LEQUAL);

    gl.GlHint(
      IGL10Constants.GL_PERSPECTIVE_CORRECTION_HINT,
      IGL10Constants.GL_NICEST);
  }

  public void OnDrawFrame(IGL10 gl)
  {
    gl.GlClear(IGL10Constants.GL_COLOR_BUFFER_BIT |;
      IGL10Constants.GL_DEPTH_BUFFER_BIT);
    gl.GlLoadIdentity();

    gl.GlTranslatef(0.0f, 0.0f, -10.0f);
    gl.GlRotatef(mCubeRotation, 1.0f, 1.0f, 1.0f);

    mCube.Draw(gl);

    gl.GlLoadIdentity();
    mCubeRotation -= 0.7f;
  }

  public void OnSurfaceChanged(
    IGL10 gl, int width, int height)
  {
    gl.GlViewport(0, 0, width, height);
    gl.GlMatrixMode(IGL10Constants.GL_PROJECTION);
    gl.GlLoadIdentity();
    GLU.GluPerspective(
      gl, 45.0f, (float) width/(float) height, 
      0.1f, 100.0f);
    gl.GlViewport(0, 0, width, height);
    gl.GlMatrixMode(IGL10Constants.GL_MODELVIEW);
    gl.GlLoadIdentity();
  }
}

Much of this is boiler-plate code. The interesting method is OnDrawFrame. This method is responsible for drawing the current frame. The implementation is delegated to Cube which is discussed next.

Cube

Class Cube contains both the definition of the cube itself (geometry and colors) and the code to draw to the OpenGL surface. Here is the code:
internal class Cube
{
  private FloatBuffer mVertexBuffer;
  private FloatBuffer mColorBuffer;
  private ByteBuffer mIndexBuffer;

  // every 3 entries represent the 
  // position of one vertex
  private float[] vertices =
  {
    -1.0f, -1.0f, -1.0f, 
    1.0f, -1.0f, -1.0f, 
    1.0f, 1.0f, -1.0f, 
    -1.0f, 1.0f, -1.0f,
    -1.0f, -1.0f, 1.0f, 
    1.0f, -1.0f, 1.0f, 
    1.0f, 1.0f, 1.0f, 
    -1.0f, 1.0f, 1.0f
  };

  // every 4 entries represent the color (r,g,b,a) 
  // of the corresponding vertex in vertices
  private float[] colors =
  {
    0.0f, 1.0f, 0.0f, 1.0f, 
    0.0f, 1.0f, 0.0f, 1.0f, 
    1.0f, 0.5f, 0.0f, 1.0f, 
    1.0f, 0.5f, 0.0f, 1.0f, 
    1.0f, 0.0f, 0.0f, 1.0f, 
    1.0f, 0.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f, 1.0f,
    1.0f, 0.0f, 1.0f, 1.0f
  };

  private byte[] indices =
  {
    0, 4, 5, 0, 5, 1, // two triangles for side 1
    1, 5, 6, 1, 6, 2, // two triangles for side 2
    2, 6, 7, 2, 7, 3, // etc.
    3, 7, 4, 3, 4, 0, 
    4, 7, 6, 4, 6, 5, 
    3, 0, 1, 3, 1, 2
  };

  public Cube()
  {
    ByteBuffer byteBuf = ByteBuffer.AllocateDirect(
      vertices.Length * 4);
    byteBuf.Order(ByteOrder.NativeOrder());
    mVertexBuffer = byteBuf.AsFloatBuffer();
    mVertexBuffer.Put(vertices);
    mVertexBuffer.Position(0);

    byteBuf = ByteBuffer.AllocateDirect(
      colors.Length * 4);
    byteBuf.Order(ByteOrder.NativeOrder());
    mColorBuffer = byteBuf.AsFloatBuffer();
    mColorBuffer.Put(colors);
    mColorBuffer.Position(0);

    mIndexBuffer = ByteBuffer.AllocateDirect(
      indices.Length);
    mIndexBuffer.Put(indices);
    mIndexBuffer.Position(0);
  }

  public void Draw(IGL10 gl)
  {
    gl.GlFrontFace(IGL10Constants.GL_CW);

    gl.GlVertexPointer(
      3, IGL10Constants.GL_FLOAT, 0, mVertexBuffer);
    gl.GlColorPointer(
      4, IGL10Constants.GL_FLOAT, 0, mColorBuffer);

    gl.GlEnableClientState(
      IGL10Constants.GL_VERTEX_ARRAY);
    gl.GlEnableClientState(
      IGL10Constants.GL_COLOR_ARRAY);

    // draw all 36 triangles
    gl.GlDrawElements(
      IGL10Constants.GL_TRIANGLES, 36, 
      IGL10Constants.GL_UNSIGNED_BYTE, mIndexBuffer);

    gl.GlDisableClientState(
      IGL10Constants.GL_VERTEX_ARRAY);
    gl.GlDisableClientState(
      IGL10Constants.GL_COLOR_ARRAY);
  }
}

Acknowledgement

Large part of the code was taken from http://intransitione.com/blog/create-a-spinning-cube-with-opengl-es-and-android/.

Thursday, March 7, 2013

Error: Unable to find manifest signing certificate in the certificate store.


You may get the following error while compiling a dot42 project: "Unable to find manifest signing certificate in the certificate store.".


To solve this, go to the project properties and select the 'Android' tab:


Most likely, the problem is that the path in the highlighted section is invalid. Either browse to an existing certificate file, or generate a new one.

Monday, March 4, 2013

1.0.0.55 - What's new?

To get the latest version, run 'Check for updates' or download.


New: Improved exception debugging support

It is now possible to inspect exceptions in the Visual Studio debugger.

New: Added device log in Visual Studio

Select Debug - Windows - Device log to show a device log window inside Visual Studio. This window shows the Main device log for the device you're debugging on filtered on the process you're debugging.

Changed: Debugger attachment process

Many reports have been send about a problem with attaching the debugger to the app on the device. The problem is and was that we've never been able to reproduce this is a controlled environment. We've made several modifications to the attachment process which we hope will solve this issue. If the problem remains, please report it and send a copy of the Device log (see above) output.

Changed: Device log shows Main log instead of System log.

The device log (both in the device center as well as in Visual Studio) now show the contents of the Main log instead of the System log. This means that output from Android.Util.Log is now visible.

Fixed: Resource errors do not show in the Visual Studio error window

If you make an error in the content of a resource (.xml) file it will now show as a build error inside Visual Studio.

Fixed: Debugger does not detect stopped app on device.

If an app stops on the device (because you remove it from the app list or it crashes), the current debugging session will terminate.

Various

As with each release, lots of (unreported) minor issues have been solved and/or improved.