Thursday, April 29, 2010

Android Development

DroidDraw Beta


User Interface (UI) designer/editor for programming the Android Cell Phone Platform

News! - DroidDraw standalone executable available: (Mac OS X, Windows, Linux)

AnDroidDraw - Tutorials - Widget Guide - Report Bugs/Problems - Older Version (r1b13) - Dev. Blog


Image courtesy of Open Handset Magazine
Your browser needs to support Java Applets to run DroidDraw
Version dd.r1.b14
source
This tool was written to make my Java programming life easier. It can be used to build graphical user interfaces for the Android cell phone platform. I hope you find it useful for whatever Android/Java cell phone software development projects you have planned!
Please post any bugs that you find or requests for improvement on the issues list.
Thanks and enjoy!

Wednesday, April 14, 2010

Mobile Application Development


  • Digg

  • del.icio.us

  • Google
  • TwitThis
  • Reddit

  • StumbleUpon


    Like this page?

    Support
    future add-ons by downloading
    iPhone driving game (99c)




    Logging

    In Xcode, click Run > Console to see NSLog statements.
    NSLog(@"log: %@ ", myString);
    NSLog(@"log: %f ", myFloat);
    NSLog(@"log: %i ", myInt);

    Display Images


    Display an image anywhere on the screen, without using UI Builder. You can use this for other types of views as well.

    CGRect myImageRect = CGRectMake(0.0f, 0.0f, 320.0f, 109.0f);
    UIImageView *myImage = [[UIImageView alloc] initWithFrame:myImageRect];
    [myImage setImage:[UIImage imageNamed:@"myImage.png"]];
    myImage.opaque = YES; // explicitly opaque for performance
    [self.view addSubview:myImage];
    [myImage release];

    Application Frame

    Use "bounds" instead of "applicationFrame" -- the
    latter will introduce a 20 pixel empty status bar (unless you want that..)

    Web view

    A basic UIWebView.

    CGRect webFrame = CGRectMake(0.0, 0.0, 320.0, 460.0);
    UIWebView *webView = [[UIWebView alloc] initWithFrame:webFrame];
    [webView setBackgroundColor:[UIColor whiteColor]];
    NSString *urlAddress = @"http://www.google.com";
    NSURL *url = [NSURL URLWithString:urlAddress];
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
    [webView loadRequest:requestObj];
    [self addSubview:webView];
    [webView release];

    Display the Network Activity Status Indicator


    This is the rotating icon displayed on the iPhone status bar in the
    upper left to indicate there is background network activity taking place.
    UIApplication* app = [UIApplication sharedApplication];
    app.networkActivityIndicatorVisible = YES; // to stop it, set this to NO

    Animation: Series of images

    Show a series of images in succession

    NSArray *myImages = [NSArray arrayWithObjects:
    [UIImage imageNamed:@"myImage1.png"],
    [UIImage imageNamed:@"myImage2.png"],
    [UIImage imageNamed:@"myImage3.png"],
    [UIImage imageNamed:@"myImage4.gif"],
    nil];

    UIImageView *myAnimatedView = [UIImageView alloc];
    [myAnimatedView initWithFrame:[self bounds]];
    myAnimatedView.animationImages = myImages;
    myAnimatedView.animationDuration = 0.25; // seconds
    myAnimatedView.animationRepeatCount = 0; // 0 = loops forever
    [myAnimatedView startAnimating];
    [self addSubview:myAnimatedView];
    [myAnimatedView release];


    Animation: Move an object

    Show something moving across the screen. Note: this type of
    animation is "fire and forget" -- you cannot obtain any information about the objects during
    animation (such as current position). If you need this information, you will want to animate
    manually using a Timer and adjusting the x&y coordinates as necessary.

    CABasicAnimation *theAnimation;
    theAnimation=[CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
    theAnimation.duration=1;
    theAnimation.repeatCount=2;
    theAnimation.autoreverses=YES;
    theAnimation.fromValue=[NSNumber numberWithFloat:0];
    theAnimation.toValue=[NSNumber numberWithFloat:-60];
    [view.layer addAnimation:theAnimation forKey:@"animateLayer"];

    NSString and int

    The following example displays an integer's value as a text label:
    currentScoreLabel.text = [NSString stringWithFormat:@"%d", currentScore];

    Regular Expressions (RegEx)


    There is currently no easy way to do RegEx with the framework. You
    cannot use any regex involving NSPredicate on iPhone -- it may work in Simulator, but does
    not work on the device!

    Draggable items

    Here's how to create a simple draggable image.
    1. Create a new class that inherits from UIImageView
    @interface myDraggableImage : UIImageView {
    }
    2. In the implementation for this new class, add the 2 methods:

    - (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {

    // Retrieve the touch point
    CGPoint pt = [[touches anyObject] locationInView:self];
    startLocation = pt;
    [[self superview] bringSubviewToFront:self];

    }
    - (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {

    // Move relative to the original touch point
    CGPoint pt = [[touches anyObject] locationInView:self];
    CGRect frame = [self frame];
    frame.origin.x += pt.x - startLocation.x;
    frame.origin.y += pt.y - startLocation.y;
    [self setFrame:frame];
    }
    3. Now instantiate the new class as you would any other new image
    and add it to your view
    dragger = [[myDraggableImage alloc] initWithFrame:myDragRect];
    [dragger setImage:[UIImage imageNamed:@"myImage.png"]];
    [dragger setUserInteractionEnabled:YES];

    Vibration and Sound

    Here is how to make the phone vibrate (Note: Vibration does not work
    in the Simulator, it only works on the
    device.)

    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    Sound will work in the Simulator, however some sound (such as
    looped) has been reported as not working in Simulator or even altogether depending on the
    audio format. Note there are specific filetypes that must be used (.wav in this example).
    SystemSoundID pmph;
    id sndpath = [[NSBundle mainBundle]
    pathForResource:@"mySound"
    ofType:@"wav"
    inDirectory:@"/"];
    CFURLRef baseURL = (CFURLRef) [[NSURL alloc] initFileURLWithPath:sndpath];
    AudioServicesCreateSystemSoundID (baseURL, &pmph);
    AudioServicesPlaySystemSound(pmph);
    [baseURL release];

    Threading

    1. Create the new thread:

    [NSThread detachNewThreadSelector:@selector(myMethod)
    toTarget:self
    withObject:nil];

    2. Create the method that is called by the new thread:
    - (void)myMethod {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    *** code that should be run in the new thread goes here ***

    [pool release];
    }

    What if you need to do something to the main thread from inside your
    new thread (for example, show a loading symbol)? Use performSelectorOnMainThread.

    [self performSelectorOnMainThread:@selector(myMethod)
    withObject:nil
    waitUntilDone:false];

    Reading crash logs

    If you're in the unfortunate position of having to decipher a crash
    to give them meaning.

    Testing

    1. In Simulator, click Hardware > Simulate Memory Warning to test. You may need to enable this setting on each
    new page of your app.
    2. Be sure to test your app in Airplane Mode.

    Access properties/methods in other classes


    One way to do this is via the AppDelegate:
    myAppDelegate *appDelegate
    = (myAppDelegate *)[[UIApplication sharedApplication] delegate];
    [[[appDelegate rootViewController] flipsideViewController] myMethod];

    Random Numbers

    Use arc4random(). There is also random(), but you must
    seed it manually, so arc4random() is preferred.

    Timers

    This timer will call myMethod every 1 second.
    [NSTimer scheduledTimerWithTimeInterval:1
    target:self
    selector:@selector(myMethod)
    userInfo:nil
    repeats:YES];

    What if you need to pass an object to myMethod? Use the
    "userInfo" property.

    1. First create the Timer
    [NSTimer scheduledTimerWithTimeInterval:1
    target:self
    selector:@selector(myMethod)
    userInfo:myObject
    repeats:YES];

    2. Then pass the NSTimer object to your method:
    -(void)myMethod:(NSTimer*)timer {

    // Now I can access all the properties and methods of myObject

    [[timer userInfo] myObjectMethod];
    }
    To stop a timer, use "invalidate":
    [myTimer invalidate];
    myTimer = nil; // ensures we never invalidate an already invalid Timer

    Application analytics


    When you release, you might want to collect data on how often
    your app is being used. Most people are using PinchMedia for this. They give you
    Obj-C code that is easy to add to your app and then view statistics through their website.

    Time

    Calculate the passage of time by using
    CFAbsoluteTimeGetCurrent().
    CFAbsoluteTime myCurrentTime = CFAbsoluteTimeGetCurrent();
    // perform calculations here


    Alerts

    Show a simple alert with OK button.
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"An Alert!"
    delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    [alert release];

    Plist files


    Application-specific plist files can be stored in the Resources
    folder of the app bundle. When the app first launches, it should check if there is an
    existing plist in the user's Documents folder, and if not it should copy the plist from the
    app bundle.
    // Look in Documents for an existing plist file
    NSArray *paths = NSSearchPathForDirectoriesInDomains(
    NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    myPlistPath = [documentsDirectory stringByAppendingPathComponent:
    [NSString stringWithFormat: @"%@.plist", plistName] ];
    [myPlistPath retain];

    // If it's not there, copy it from the bundle
    NSFileManager *fileManger = [NSFileManager defaultManager];
    if ( ![fileManger fileExistsAtPath:myPlistPath] ) {
    NSString *pathToSettingsInBundle = [[NSBundle mainBundle]
    pathForResource:plistName ofType:@"plist"];
    }
    Now read the plist file from Documents
    NSArray *paths = NSSearchPathForDirectoriesInDomains(
    NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectoryPath = [paths objectAtIndex:0];
    NSString *path = [documentsDirectoryPath
    stringByAppendingPathComponent:@"myApp.plist"];
    NSMutableDictionary *plist = [NSDictionary dictionaryWithContentsOfFile: path];

    Now read and set key/values
    myKey = (int)[[plist valueForKey:@"myKey"] intValue];
    myKey2 = (bool)[[plist valueForKey:@"myKey2"] boolValue];

    [plist setValue:myKey forKey:@"myKey"];
    [plist writeToFile:path atomically:YES];



    Info button

    Increase the touchable area on the Info button, so it's easier to
    press.
    CGRect newInfoButtonRect = CGRectMake(infoButton.frame.origin.x-25,
    infoButton.frame.origin.y-25, infoButton.frame.size.width+50,
    infoButton.frame.size.height+50);
    [infoButton setFrame:newInfoButtonRect];


    Detecting Subviews


    You can loop through subviews of an existing view. This works
    especially well if you use the "tag" property on your views.

    for (UIImageView *anImage in [self.view subviews]) {
    if (anImage.tag == 1) {
    // do something
    }
    }

    Handy References