Archive for February 2013

Writing your first Android App (GDG Columbus meeting, February 21, 2013)

Last night, I attended the Google Developers Group Columbus meeting “Writing your first Android App presentation” at the Blue Diesel offices here in town. Special thanks to Casey Borders, the main presenter who kept us moving through the code heavy presentation. I am still a novice when it comes to Android development, so I did learn quite a bit at the meeting.

BTW, happy birthday to Jeri Ryan, who capably portrayed Seven of Nine in Star Trek Voyager.

Fix the SQLite error “The database disk image is malformed”

I suppose it was only a matter of time before someone’s database got corrupted. Of course, customers don’t want to hear that their issue is a once-in-a-year issue, they just want to get their data back. (Of course, they have used the app for a long time and not done any backups, but that topic could fill an entire blog.) Here are the steps I took to fix the SQLite error “The database disk image is malformed”:

1. Use the sqlite3 app in the Mac OS X Terminal to create a .SQL export file

So I fired up the Terminal and changed to the directory where I had saved the bad database file, and entered the command:

sqlite3 DB.sqlite

This launches the sqlite> prompt, at which I entered the following commands:

.mode insert
.output dump_all.sql
.dump
.exit

At this point, you have the .SQL file in the same directory as the bad database file.

2. Remove transaction statements from the file

I received some errors in the next step, so I would recommend that you manually edit the .SQL file and remove any kind of transaction statements. In my example, there was a BEGIN TRANSACTION statement on the 2nd line of the file and a ROLLBACK statement on the last line. I removed both of these lines and re-saved the file.

3. Use the SQLite Manager extension for Firefox to create a new database file and import the .SQL file

The last step is to launch your Firefox and open the SQLite Manager extension, create a brand new database, select Import from the Database menu, click Select File and find the .SQL file, make sure the BEGIN TRANSACTION/COMMIT check box is clear, and click OK.

At this point, I had a new SQLite file that did not give the malformed error message any more. As with any database file corruption issues, I probably got a bit lucky that the file was not too badly damaged, or damaged beyond repair.

Here was the blog post by Sergei Dorogin that I found that got me part way to the solution in my instance:

SQLiteException “database disk image is malformed”

BTW, Happy Birthday to Roy Face, the former great Pittsburgh Pirates pitcher. He was one of the coaches at this past year’s Pirates Fantasy Camp, and seemed like a very nice person.

.NET regex to find strings inside curly braces

Regular expressions all by themselves have the magical ability to amaze and confound all at the same time. Throw in a dash of .NET string interpretation and you have a recipe for pulling out the remaining hair that you might have on your head.

So I was trying to use a regex to do some searching inside of a large string for strings inside curly braces, such as {this} and {these three words}. My string matching routine would return “this” and “these three words”, without the quotes of course. It took a bit of trial and error, but here is the important stuff for the routine that I put together to accomplish this task:

const string pattern = @"\{([^\}]+)\}";
foreach (Match match in Regex.Matches(theLargeString, pattern))
{
    Console.WriteLine("Found a field match: " + match);
}

BTW, a special birthday shout out to one of the mega stars of our generation, who turns 50 years young today. Happy birthday, Larry The Cable Guy.

Migrating ASIHTTPRequest to AFNetworking (submit to a URL with POST variables)

For my third and final AFNetworking migration series of posts, let us consider calling a web service URL with POST variables.

Here was the ASIHTTPRequest code:

    NSMutableString *fileURL = [NSMutableString stringWithString:THE_URL];
    NSURL *url = [NSURL URLWithString:fileURL];
    __block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
    [request setDelegate:self];
    [request addRequestHeader:@"Content-Type" value:@"application/json; charset=utf-8"];
    [request setRequestMethod:@"POST"];
    [request setPostValue:theID forKey:@"id"];
    [request setCompletionBlock:^{
        NSLog(@"success with response string %@", request.responseString);
    }];
 
    [request setFailedBlock:^{
        NSLog(@"error: %@", request.error.localizedDescription);
    }];
 
    [request startAsynchronous];

And here is the corresponding AFNetworking code:

    NSMutableString *fileURL = [NSMutableString stringWithString:THE_URL];
    AFHTTPClient *client = [[[AFHTTPClient alloc] initWithBaseURL:url] autorelease];
    NSDictionary *params = @ { @"id" : theID };
    NSMutableURLRequest *request = [client requestWithMethod:@"POST" path:fileURL parameters:params];
    AFHTTPRequestOperation *op = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease];
    [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"success with response string %@", operation.responseString);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"error: %@", error.localizedDescription);
    }];
    [op start];

BTW, Happy Valentine’s Day to one and all.

Migrating ASIHTTPRequest to AFNetworking (uploading a PNG to a web service)

For part 2 of my AFNetworking migration experiences, let’s cover uploading a file to a web service.

Here is the original code:

    NSString *ws = [NSString stringWithFormat:@"http://myurl.com?id=%@", theID];
    NSURL *url = [NSURL URLWithString:ws];
    NSData *postData = [[[NSData alloc] initWithContentsOfFile:filePath] autorelease];
    ASIFormDataRequest *request;
    request = [[[ASIFormDataRequest alloc] initWithURL:url] autorelease];  
    [request setPostValue:pictureFileName forKey:@"file"];  
    [request setData:postData withFileName:pictureFileName andContentType:@"image/png" forKey:@"file"];
    [request setRequestMethod:@"POST"];
    [request setShouldAttemptPersistentConnection:YES];
    [request setUploadProgressDelegate:progressView];
    [request setCompletionBlock:^{
        NSLog(@"success with response string %@", request.responseString);
    }];
 
    [request setFailedBlock:^{
        NSLog(@"error: %@", request.error.localizedDescription);
    }];
 
    [request startAsynchronous];

And here is the AFNetworking code:

    NSString *ws = [NSString stringWithFormat:@"http://myurl.com?id=%@", theID];
    NSURL *url = [NSURL URLWithString:ws];
    NSData *postData = [[[NSData alloc] initWithContentsOfFile:filePath] autorelease];
    NSDictionary *sendDictionary = [NSDictionary dictionaryWithObject:postData forKey:@"file"];
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
    NSMutableURLRequest *afRequest = [httpClient multipartFormRequestWithMethod:@"POST"
                                                                           path:@""
                                                                     parameters:sendDictionary
                                                      constructingBodyWithBlock:^(id < AFMultipartFormData > formData)
                                      {
                                          [formData appendPartWithFileData:postData
                                                                      name:pictureFileName
                                                                  fileName:pictureFileName
                                                                  mimeType:@"image/png"];
                                      }
                                      ];
 
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:afRequest];
    [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
        if (totalBytesExpectedToWrite == 0)
        {
            progressView.progress = 0.0;
        }
        else
        {
            progressView.progress = totalBytesWritten * 1.0 / totalBytesExpectedToWrite;
        }
    }];
 
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
     {
        NSLog(@"success with response string %@", operation.responseString);
     }
                              failure:^(AFHTTPRequestOperation *operation, NSError *error)
     {
        NSLog(@"error: %@", error.localizedDescription);
     }];
 
    [operation start];

The AFNetworking code is somewhat longer, so that is a bit of a problem. If anyone has any suggestions on how to make the AFNetworking code a bit more concise, please let me know.

BTW, Happy Birthday to Joe Don Baker, a distinguished actor with such outstanding films to his credit such as Mitchell, Final Justice, Fletch, and of course the all-time classic, Joysticks.

Migrating ASIHTTPRequest to AFNetworking

After using the ASIHTTPRequest library for a long time (so sad that Ben Copsey decided to abandon it), I finally decided to give in and switch to AFNetworking by Mattt Thompson and Scott Raymond. It has taken some trial and error to get it working correctly, so here is what I have found so far.

Conversion #1: Simple call to a URL

For this conversion, I am just making a call to a web service URL. I don’t really care about the return value, I just care if the call went through or whether there was an error in communications with the web service.

The ASI code:

    NSString *urlString = [NSString stringWithFormat:@"http://myurl.com?id=%@", theID];
    NSURL *url = [NSURL URLWithString:urlString];
    __block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
    [request setDelegate:self];
    [request setCompletionBlock:^{
        NSLog(@"success");
    }];
 
    [request setFailedBlock:^{
        NSError *error = [request error];
        NSLog(@"error: %@", error.localizedDescription);
    }];
 
    [request startAsynchronous];

The AFNetworking code:

    NSString *urlString = [NSString stringWithFormat:@"http://myurl.com?id=%@", theID];
    NSURL *url = [NSURL URLWithString:urlString];
    AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:[NSURLRequest requestWithURL:url]];
    [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
     {
         NSLog(@"success");
     }
                              failure:^(AFHTTPRequestOperation *operation, NSError *error)
     {
        NSLog(@"error: %@", error.localizedDescription);
     }];
 
    [op start];

Yeah, admittedly this one was not very hard to convert. Stay tuned, other more complicated conversions are coming.

BTW, Happy Birthday to Jim J. Bullock, who excellently portrayed Prince Valium in Spaceballs.

Thoughts about Ubuntu on my Chromebook

For my extended vacation that I just got back from, I decided to leave the MacBook Air at home and try to purchase the Acer Chromebook from the Google Play store for the price of $199. Upon receiving the first one, there was a problem with the screen backlighting not working properly, and after conversing with the Google Play customer service people, I got a replacement unit that worked just fine.

The next step was to put something else on it than the Chrome OS. Not that I am against the idea of the Chrome OS, but I knew that I was not going to be in internet service areas all of the time, which would limit the functionality of the Chromebook. So I found this posting on how to install Ubuntu on a Chromebook:

How to install Ubuntu on Acer’s $199 C7 Chromebook

And I must say that it works very well, even though the stock Acer Chromebook has a slow processor, slow hard drive, and only 2 GB of RAM. I highly recommend it for someone looking for an inexpensive travel computer that you can use for web surfing, e-mail checking, light document work, watching movies, etc.

One snag I ran into was an error that came up while updating. When using the Update Manager, I would get the following error after selecting some updates to install:

Requires installation of untrusted packages

So I found a posting on the Ubuntu forums on how to fix this. Basically, I just went to the terminal and ran the following two commands:

sudo apt-get update

and:

sudo apt-get upgrade

After these were done, I was able to get through all of the updates just fine.

BTW, Happy Anniversary to Darryl Sittler, the former Toronto Maple Leafs captain, who on this day in 1976 scored an NHL record 10 points (6 goals and 4 assists) in a game vs. the Boston Bruins.