One of the features in Codename One that just never got any attention is builtin support for analytic instrumentation. Currently Codename One has builtin support for Google Analytics which provides reasonable enough statistics of application usage.
The infrastructure is there to support any other form of analytics solution of your own choosing.
Analytics is pretty seamless for a GUI builder application since navigation occurs via the Codename One API and can be logged without developer interaction. However, to begin the instrumentation one needs to add the line:
AnalyticsService.init(agent, domain);
To get the value for the agent value just create a Google Analytics account and add a domain, then copy and paste the string that looks something like UA-99999999-8 from the console to the agent string. Once this is in place you should start receiving statistic events for the application.
If your application is not a GUI builder application or you would like to send more detailed data you can use the Analytics.visit() method to indicate that you are entering a specific page.
Monday, April 30, 2012
Monday, April 23, 2012
Code Of The Zebra - Zxing on Codename One
Bharath, a long time user of LWUIT asked on Stack Overflow whether Codename One supported QRCode/ZXing. Since he is one of many who asked for this feature I decided now would probably be a good time to push that feature forward.
Initially I planned to add the support directly into Codename One (and I intend to do this soon enough) but right now I wanted to get something going as soon as possible and also show a more realistic example of using the native API's. So I decided to write everything using the standard Codename One native API support which allows me to define a native interface and implement the code in C/Dalvik etc.
The Android implementation was a breeze! Its just an intent:
public void scan() {
result = ZXingNativeCalls.PENDING;
com.codename1.impl.android.CodenameOneActivity ctx = (com.codename1.impl.android.CodenameOneActivity)Zxing.getContext();
android.content.Intent intent = new android.content.Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
ctx.setIntentResultListener(new IntentResultListener() {
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 0) {
if (resultCode == com.codename1.impl.android.CodenameOneActivity.RESULT_OK) {
contents = data.getStringExtra("SCAN_RESULT");
format = data.getStringExtra("SCAN_RESULT_FORMAT");
result = ZXingNativeCalls.OK;
} else if (resultCode == com.codename1.impl.android.CodenameOneActivity.RESULT_CANCELED) {
// Handle cancel
result = ZXingNativeCalls.ERROR;
}
}
}
});
ctx.startActivityForResult(intent, 0);
}
Notice that I store the context in the application then I can just access it easily from Android and work with that. The iOS application seemed simple enough when I started but took me a couple of days mostly because of the inherent complexity of the zxing code base which relies on compiling and linking an underlying C++ library and invoking it from the Objective-C code. I tried following their tutorials repeatedly ending with linker errors (the joys of native code... ugh).
Eventually I decided to just refactor all the code and just take the entire zxing project into the build environment. While this eventually worked it turned out to be pretty difficult to do. The main issue is that due to our current native implementation on iOS hierarchies of source files are flattened when building the project. The C++ code and the Objective-C code rely heavily on hierarchies and have duplicate file names that differ only in their hierarchy. Flattening this hierarchy was painful work but eventually I got the whole thing flattened. The mixing of C++ with Objective-C code was also pretty painful to work with.
Eventually I got a basic project working and you can see the full source code (including the modified Zxing) in the demos directory in the repository.
Initially I planned to add the support directly into Codename One (and I intend to do this soon enough) but right now I wanted to get something going as soon as possible and also show a more realistic example of using the native API's. So I decided to write everything using the standard Codename One native API support which allows me to define a native interface and implement the code in C/Dalvik etc.
The Android implementation was a breeze! Its just an intent:
public void scan() {
result = ZXingNativeCalls.PENDING;
com.codename1.impl.android.CodenameOneActivity ctx = (com.codename1.impl.android.CodenameOneActivity)Zxing.getContext();
android.content.Intent intent = new android.content.Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
ctx.setIntentResultListener(new IntentResultListener() {
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 0) {
if (resultCode == com.codename1.impl.android.CodenameOneActivity.RESULT_OK) {
contents = data.getStringExtra("SCAN_RESULT");
format = data.getStringExtra("SCAN_RESULT_FORMAT");
result = ZXingNativeCalls.OK;
} else if (resultCode == com.codename1.impl.android.CodenameOneActivity.RESULT_CANCELED) {
// Handle cancel
result = ZXingNativeCalls.ERROR;
}
}
}
});
ctx.startActivityForResult(intent, 0);
}
Notice that I store the context in the application then I can just access it easily from Android and work with that. The iOS application seemed simple enough when I started but took me a couple of days mostly because of the inherent complexity of the zxing code base which relies on compiling and linking an underlying C++ library and invoking it from the Objective-C code. I tried following their tutorials repeatedly ending with linker errors (the joys of native code... ugh).
Eventually I decided to just refactor all the code and just take the entire zxing project into the build environment. While this eventually worked it turned out to be pretty difficult to do. The main issue is that due to our current native implementation on iOS hierarchies of source files are flattened when building the project. The C++ code and the Objective-C code rely heavily on hierarchies and have duplicate file names that differ only in their hierarchy. Flattening this hierarchy was painful work but eventually I got the whole thing flattened. The mixing of C++ with Objective-C code was also pretty painful to work with.
Eventually I got a basic project working and you can see the full source code (including the modified Zxing) in the demos directory in the repository.
Friday, April 20, 2012
Multi The Button
I've just added a new tutorial on using the new MultiButton component which is designed to provide UI's similar to the UITableView in Codename One. This is not a breakthrough component since all the functionality was previously available, it is just much simpler to implement now.
Saturday, April 14, 2012
Cross Platform Beats Native When Done Right
Reading Juhani Lehtimaki's posts on dzone in which he claims inferior results when using cross platform frameworks finally convinced me to write about this.
He has a point. Most developers look at Cross Platform tools as a means of saving money and cut corners when using them. Resulting in lower ratings and low quality apps.
However, there are great cross platform apps e.g. Music Cloud (LWUIT/Codename One based), Waze & Telmap (LWUIT 1.2, a pretty old version).
I won't talk about the frameworks Juhani mentioned, since I would tend to agree that they all fall into 1 of two categories: HTML or Lowest Common Denominator. Both are IMO terrible approaches for cross platform unlike Codename One which is radically different.
When users ask for Native apps they mean: High quality, fast app that received developer investment and QA. They aren't asking you to code your app in Objective-C or make it look like all the other apps.
Waze, looks nothing like a native app yet has a tremendous user rating. How come?
The developers took the time saved on porting & QA (which is faster since bug fixes are ported too) to deliver functionality. Functionality trumps everything.
When creating a native app you are giving up on some functionality and on niche platforms.
The problem is that throwing money/developers at the problem of building mobile apps doesn't make it scale better/faster. So even if you have an unlimited financial budget you will end up with less functionality and longer release cycles when doing native coding.
A friend recently told me: "The only reason anyone ever does cross platform is to save money".
Unfortunately that's usually true, but my response was: "They shouldn't. They should use cross platform to provide a distinct experience and more features.".
He has a point. Most developers look at Cross Platform tools as a means of saving money and cut corners when using them. Resulting in lower ratings and low quality apps.
However, there are great cross platform apps e.g. Music Cloud (LWUIT/Codename One based), Waze & Telmap (LWUIT 1.2, a pretty old version).
I won't talk about the frameworks Juhani mentioned, since I would tend to agree that they all fall into 1 of two categories: HTML or Lowest Common Denominator. Both are IMO terrible approaches for cross platform unlike Codename One which is radically different.
When users ask for Native apps they mean: High quality, fast app that received developer investment and QA. They aren't asking you to code your app in Objective-C or make it look like all the other apps.
Waze, looks nothing like a native app yet has a tremendous user rating. How come?
The developers took the time saved on porting & QA (which is faster since bug fixes are ported too) to deliver functionality. Functionality trumps everything.
When creating a native app you are giving up on some functionality and on niche platforms.
The problem is that throwing money/developers at the problem of building mobile apps doesn't make it scale better/faster. So even if you have an unlimited financial budget you will end up with less functionality and longer release cycles when doing native coding.
A friend recently told me: "The only reason anyone ever does cross platform is to save money".
Unfortunately that's usually true, but my response was: "They shouldn't. They should use cross platform to provide a distinct experience and more features.".
Thursday, April 12, 2012
Monitoring It
We just uploaded an update to Codename One into the servers which includes a couple of new monitoring tools allowing you to easily track network and performance issues in Codename One applications (see the tutorial on the Codename One site).
These tools show off some of the things we can do by leveraging the Codename One infrastructure which is completely different from any other tool in the market. We have allot of ideas like these planned for the future including similar tools directly on the target devices.
Friday, April 6, 2012
Native Themeing In Codename One
I just posted a new tutorial on native themeing in Codename One for more information please go to the tutorial page.
Let us know what subjects you wish that we cover/revisit in our tutorials and we will try to address them in the coming weeks. In the meantime I highly recommend you subscribe to Eric's blog who is doing some amazing work in explaining the features of Codename One.
Subscribe to:
Comments (Atom)