Showing posts with label Google App Engine. Show all posts
Showing posts with label Google App Engine. Show all posts

Wednesday, June 22, 2011

Android Market observations

It's been a few weeks since my last post - I've been super busy launching my first app on Android Market. The prototype was built a couple months ago and it's mature enough to be released into the wild. Homepage here and Android Market entry here.

Anyway, the work necessary to get my app on Android Market was suprisingly minimal. Here are some general observations:

  • Google does a great job tying into Eclipse: You can code with any IDE you want but for my money, I have to use Eclipse because it works so seemlessly with Google stuff. Even signing the app is simple.


  • Be very distrustful about network connections: I've been using my app for a couple months and never got presented with a "Force Close" (a crash). However, some of the errors being logged are the result of devices dropping network connection and my code was not catching these conditions sufficiently. I'm pushing an update this week which catches these exceptions, presents an alert dialog that states the network isn't working, and takes the user to a safe activity.


  • Be careful about security: There as a good article this week warning users of Amazon Web Services (which I am one) to get better with protecting credentials. I spent a good amount of time developing authentication middleware and don't use the VMs this article focuses on but it scared me enough to take a closer look at how I use IAM. I'm rolling credentials more, beefing up my personal password security, and paying more attention to my server logs.


  • Testing is hard: I got caught not checking for some basic weird user behavior, like putting spaces in usernames then putting that string in a GET request. Now that I have a bunch of users, I'm fixing these shortcomings.


  • Android Market exhibits some weird behavior for publishers: When trying to push my update, I was presented with "An unexpected error occurred. Please try again later." after clicking the "Upload" button. It seems like this is a catch-all error message that the Market displays whenever there's a problem. Back in April 2011, some servers were down and this was getting displayed all the time. I finally resolved it by logging out of Android Market and back in.

Friday, May 6, 2011

Google App Engine is pretty great (if you go all the way)

So I'm starting to bang around another project. As I describe it on my Careers 2.0 profile:
Project is still in its infancy but it will have server (GAE-hosted Python program evaluating JSON feeds of stock data with Cloundant [CouchDB] backend) and mobile (Android app to visualize/manipulate the data from Cloundant) components. There really isn't a point behind this program and I don't necessarily condone algorithmic trading - it's just a fun hack.

Or so I thought. Doesn't look like I'll be using Google App Engine because I don't want to do it the "GAE way" (not that there's anything wrong with that). Deploying an app to GAE is super simple but I ran into problems when starting to incorporate 3rd-party libraries (couchdbkit and restkit to be exact). These libs are too small to be part of the standard runtime environment. It's interesting to note that even Django is implemented in a slightly different way on GAE.

I'll spare the details (though they are available in my stackoverflow question) but I was having importing couchdbkit into my script. It was choking on things likes sockets and resources, which made me think I was running afoul of the sandbox rules:
An App Engine application cannot:
  • write to the filesystem. Applications must use the App Engine datastore for storing persistent data. Reading from the filesystem is allowed, and all application files uploaded with the application are available.
  • open a socket or access another host directly. An application can use the App Engine URL fetch service to make HTTP and HTTPS requests to other hosts on ports 80 and 443, respectively.
  • spawn a sub-process or thread. A web request to an application must be handled in a single process within a few seconds. Processes that take a very long time to respond are terminated to avoid overloading the web server.
  • make other kinds of system calls.

I put a question on the Cloudant discussion board and got not 1 but 2 answers from Cloudant techs within an hour (these dudes are good - I don't even have a paying account and they are very responsive). Anyway, they tipped me off to this telling Quora answer. It looks like the Django/Python hosting space is about to blow up with Heroku-like solutions.

Both the Cloudant tech and Django responder (a Django co-inventor) had good things to say about WebFaction. It is not a free hosting service ($9.50 per month and goes down with longer term contracts). After a quick Q&A session with a sales rep, I took the plunge. 1 hour later, my program was working perfectly on my WebFaction account. Success! The only thing that makes me nervous is having to do any sys admin stuff at all - getting my script and installations to reference the right Python version (WebFaction comes everything from 2.4 [default] up through 3.2) is about all I care to handle.

Sunday, January 23, 2011

Super simple identification code

So I'm working on an Android app and I really don't care about authentication (yet) but need a way to identify a user. I can assume the user will have at least 1 google (or gmail) account and I'm also going to leverage off the Google App Engine for many services. I'll probably add in the AuthToken functionality eventually - hopefully the Authentication features of Android and Google App Engine will continue to improve in the meantime.

So here's a class that extends ListActivity:


Account[] mAccts;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main);

// get google/gmail accounts
AccountManager acctMan = AccountManager.get(this);
mAccts = acctMan.getAccountsByType("com.google");

// put the account names into a String[]
String[] acctnames = new String[mAccts.length];
for (int i=0; i< mAccts.length; i++) {
acctnames[i] = mAccts[i].name;
}

this.setListAdapter(new ArrayAdapter(this, R.layout.accts_row, acctnames));
}


That will show the user a list of their Google accounts. Here's the onListItemClick:


super.onListItemClick(l, v, position, id);

// find the account clicked and send the intent on its way
Account acct = mAccts[position];
Intent i = new Intent(this, PayMain.class);
i.putExtra(PayMain.KEY_ACCT, acct);
startActivity(i);


In your target activity class (PayMain in this case), the account will be bundled into the Intent.

The XML files are basic for ListActivity programs. Make sure you ask for GET_ACCOUNTS permission in AndroidManifest.xml (plus USE_CREDENTIALS and INTERNET if you're going to get an AuthToken).

I ran this on my Droid X with 2 gmail accounts and it works fine. Works with no Google accounts also (says the user needs to get a Google account and try again). Having problems adding an account to the emulator. I believe I'm supposed to do it through Dev Tools but can't seem to get it to work. I'm able to add a gmail account to the email app but it's not added to the system as a real account. Plus I can't locate any good documentation of Dev Tools. Strange...