If you want to add an animation to your app the first thing you think about is to use animated gifs. But when you perform some research on how to use animated gifs in android you will find out that android does not support this file type. Instead android will always just display one static frame of the animation. But android provides two powerful mechanisms which allow developers to create various types of animations. One way is to use tweened animations where you can define transformation operations such as acceleration, alpha, rotation, scaling, position, etc. on your objects. The other possibility is to use a frame-by-frame mechanism where it’s possible to define different drawable resources and time intervals in which these resources will be displayed. In this blog post I want to give an introduction on how this frame by frame animation can be implemented in android.
Continue reading →
May, 2011
27
May 11
Playing Animations in Android
27
May 11
Industrial Applications of Augmented Reality
The technical advances in the last years, like fast processors, rapid data transmission, better displays and enhanced miniaturization, permit applications based on augmented reality to be processed on a smartphone or a tablet computer. Thus, such applications penetrate more and more into the everyday world. They are mostly designed for marketing, sales and advertising; many are simply playing around, just to demonstrate the possibilities of the new technology.
In industry, augmented reality applications have been used for quite some time. However, the necessary hardware is complex, such as special camera systems, sensors, displays and eye-tracking devices. Therefore, the applications are limited to specific areas. Continue reading →
13
May 11
Using self-defined Parcelable objects during an Android AIDL RPC / IPC call
In my previous post “Using the Android Interface Definition Language (AIDL) to make a Remote Procedure Call (RPC) in Android” I’ve explained the basics on how inter-process communication can be implemented in Android. Now we will take a look at a specialized field in this area: Using Parcelables as parameters of an AIDL method.
As described in the previous post it is possible to either use primitive java types within a remote method signature or any class which implements the android.os.Parcelable interface. Using this interface it is possible to define arbitrarily complex data types which can be used as parameters or return values of methods during a remote method call.
I’ve created a modified version of the first example app to give you a basic example which relies on a Parcelable object as a method return value. Continue reading →
13
May 11
Augmented Reality
Augmented Reality (Abbreviation: AR) generally refers to the enlargement of the human perception of reality by information generated by a computer. An artificial second level is added to the natural environment that provides additional data in real-time. Continue reading →
2
May 11
iOS: Interfacing WebView Content via JavaScript
A WebView element is a smart and easy way to integrate both platform-independent and dynamic content into an ordinary iOS app. While using it to display webpages might be simple things become more complicated when some kind of interaction between the parent app and the webpage is needed. At the moment there is no common way for a page to send any messages to its WebView controller. This article shows basic principles of a two-way communication, providing a work-around for the function missing.
At the end you’ll find a download link to a full iOS sample project.
Calling JavaScript code from your App
This part is easy: Assuming you have a WebView set up in your project displaying just any page. There is a method called stringByEvaluatingJavaScriptFromString which does the job. Example:
[myWebView stringByEvaluatingJavaScriptFromString:@"alert('Hello World!');"];
Will display – you guessed it – an alert message sent by your webpage. That way you can call any JavaScript function available to your webpage from outside, making it a snap to alter pages on the fly.
Calling functions in your App from inside a WebView
As I mentioned earlier, the other way around is far more complicated. First, we have to think about a way a webpage can communicate to an app. Fortunately, the WebView element provides some interesting attributes and events.
First of all an event called shouldStartLoadWithRequest is fired when a page is requested. Here is an example implementation:
-(BOOL)myWebView:(UIWebView*)myWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNaviagtionType)navigationType {
[...]
}
The great thing about this function is that it is called before the page actually gets loaded and that it expects a boolean as a return. Returning YES makes the WebView start loading the desired page while returning NO stops it from doing so.
Now the plan is as follows: A JavaScript function loads a fictional page including some GET parameters via window.location. Because of the special URL keyword the app is able to figure out whether a real page should be loaded or an in-app function is called (namely an app-call). At that point the function can stop the request and execute the action or just let it load.
So the above function needs to get two things done:
- check whether a normal link or an app call is requested and returning the proper boolean
- extract given parameters and check if they fit into predefined actions
Based on a sample by tetontech this is the code we are going to talk about:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *url = [[request URL] absoluteString];
NSLog(@"Requesting: %@",url);
NSArray *urlArray = [url componentsSeparatedByString:@"?"];
NSString *cmd = @"";
NSMutableArray *paramsToPass = nil;
// isolate command and parameters
if([urlArray count] < 1){
NSString *paramsString = [urlArray objectAtIndex:1];
NSArray *urlParamsArray = [paramsString componentsSeparatedByString:@"&"];
cmd = [[[urlParamsArray objectAtIndex:0] componentsSeparatedByString:@"="] objectAtIndex:1];
int numCommands = [urlParamsArray count];
paramsToPass = [[NSMutableArray alloc] initWithCapacity:numCommands-1];
for(int i = 1; i < numCommands; i++){
NSString *aParam = [[[urlParamsArray objectAtIndex:i] componentsSeparatedByString:@"="] objectAtIndex:1];
[paramsToPass addObject:aParam];
}
}
if([cmd compare:@"toggleWorking"] == NSOrderedSame){
NSLog(@"Turning working indicator...");
if([UIApplication sharedApplication].networkActivityIndicatorVisible == NO) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSLog(@"...on");
} else {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSLog(@"...off");
}
} else if([cmd compare:@"logMessage"] == NSOrderedSame) {
NSString *message = [[paramsToPass objectAtIndex:0] stringByReplacingOccurrencesOfString:@"%20" withString:@" "];
NSString *message = [[paramsToPass objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSLog(@"Received JS message: %@",message);
}
// only load the page if it is the initial index.html file
NSRange aSubStringRange = [url rangeOfString:@"index.html"];
if(aSubStringRange.length != 0){
return YES;
} else {
NSLog(@"App call found: request cancelled");
return NO;
}
}
As stated before this function extracts and isolates every parameter and command given and runs through a couple of if-statements to check whether a command is recognized. If that’s the case additional arguments might be used to execute an action.
In this example there are just two possible actions to call: By requesting ?cmd=toggleWorking a spinning wheel in iPads’ tab bar is turned on or off depending on it’s current state. Second action logMessage might be called like this: ?cmd=logMessage¶m=Hello%20World. It will forward any given message to the debug console as a log.
NSRange aSubStringRange = [url rangeOfString:@"index.html"];
if(aSubStringRange.length != 0){
The last check is really important! Assuming your mainpage is named index.html this makes sure the page gets loaded once at start. Other requests are blocked right now but you can most likely think of different approaches to make sure app calls don’t get loaded.
Download sample project
Header over to GitHub and download the WebViewInterface-Example
Source: