Wednesday, January 30, 2013

troubleshooting the Play store, yikes!

Bird Calling is a pretty specialized app, so we've had few sales so far (sad face).  Niki promoted it on FB today and got a few people interested enough to shell out $1.99.  One of the users though had a problem with an infinitely long download ... tech support to the rescue ... who, ME?

Yes, me.  Who else is going to do it?  Former IT manager to the rescue.

So I ask him if he's downloading via Wifi connection or his data plan.  Data plan.
Does he have any other problems with the data plan, like is it slow to get Maps.  No.
Can he download another large app from Play?  I find a free 58 MB game called Factory96, ask him to download.  It doesn't work either. (Whew. Not my app.)
I tell him that Wifi is a much more stable data connection, and can he connect to his Wifi network and try again.

A few minutes later... SUCCESS.  Yay!

Thursday, January 24, 2013

at the Play Store

Searches:
bird calling - Angry Birds Star Wars tops a list of over 1000 hits; of course my app is nowhere to be seen.
nicole bird calling - my app plus two "zombie solitaire" games
perretta - my app plus two others
nicole bird - my app plus five or six others
nicole calling - my app close to the top of ~35 others
bird call lady - 0 app results
"bird calling" and "bird call lady" (in quotes) return only my app

I'm not displeased. Those who don't spell Perretta correctly can still find  it with Nicole.  The thing I find quirky is how bird call lady without quotes brings up nothing, but with quotes, it finds it (it's a phrase in the description).  I want it to be findable by people like your mom, or my mom, or anyone who doesn't really get that UI has certain common patterns.  You know, the type who would have been better off with an iPhone ;) .

[A few years back I had a sort-of-boyfriend who had a Mac laptop. I know, the finest of programmers use them these days now that they're Unix based, but I'm from the era where Macs' main selling point was their friendliness to the non-technical. Watching this boyfriend browse the internet was an exercise in self-restraint against yelling "NO NO NO NO DON'T CLICK that spammy link," or expecting to peruse a website in an organized manner. When you're using a computer (or anything with a lot of visuals, like an airplane) for the first time, you have a lot to look at and have no idea what's important and what's ignoreable.  After a while, most people learn to discern what's important, but some don't -- to them, the computer screen is a Jackson Pollock painting where every place is equally important, and they click on whatever is in front of them.  That's the kind of end user I'm talking about.]


And one last bug got eradicated: I'm glad one of my beta testers had a Samsung Galaxy S3.  Despite the normal-sized screen, it's xhdpi and from what I could gather from here and here, the S3 uses about 4 times as much memory for an image than other devices.

And naturally, after that bug was done I forgot to include the typo correction in the database and forgot to add the name of the beta tester who found the typo. Hence version 1.0.2.

The uploading of a revision is a bit mystifying.  It gives this weird notification about how people who might download v1.0.0 would now be getting v1.0.2, and it gives the impression this is a bad thing.  It isn't entirely clear that you must archive the old version first in order to activate the new version, then you additionally have to publish the new version.  I'm sure there is reasoning behind this, but it's not the same as my own.

Tuesday, January 15, 2013

It's done and live!

Here's my app:

"Bird Calling" by Nicole Perretta

I had been waiting for my beta testers to get back to me on the "final" version, and I'm glad I did, because one of them found a bug. The pictures are pretty large (sized for a 7" tablet), and each time you launch an Intent (i.e. go to another bird by clicking rather than swiping) the picture goes to the back stack and stays in memory.  We had already done some work to shrink pictures for smaller/older devices, but the back stack was killing even the Nexus 7 within about 5 or 6 back stack additions.  We changed the code to recycle the bitmap sooner rather than later.

Thursday, January 10, 2013

RelativeLayout for dummies

When I started working with Android I was doing strictly LinearLayouts, but they get complicated and ugly very fast. It's analogous to rowspans and colspans in HTML tables, only messier.  Then I learned about RelativeLayout.

It's slick in that you can declare all your elements in (pretty  much) a single RelativeLayout instead of having a zillion child LinearLayouts.  All you have to do is say where an element should appear in relation to another element. To do this you have

layout_alignParentRight, ~Top, ~Left and ~Bottom to anchor your element to the layout itself.  These are ="true" (or not declared at all, I suppose).

layout_toLeftOf and ~RightOf, and layout_above and ~below for positioning relative to other elements.  The argument is the id of the other element, e.g. ="@+id/titleBox"

Things learned: the LinearLayout urge is to declare elements in order of appearance from top to bottom.  Don't do it that way.  Organize by items that are going to stay a fixed size and location versus items that you want to stretch to fill the remaining space.

So I'm laying out elements for a basic media control. It has a TextView for the title of the clip, a ProgressBar, an ImageButton that will later be coded to toggle between play and pause images, and two more TextViews, one to display the total length of the clip and one for the current time position.

I want the title on the left, the play/pause button on the right, and the progress bar to stretch to fill any space in between.

So the first two things I declare are the title and the button.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@color/offwhite">
    <ImageButton
            android:id="@+id/btnPlay"
            android:src="@drawable/playbutton"
            android:layout_alignParentRight="true"
            android:scaleType="fitEnd"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:paddingRight="10dp"
            android:background="@null"
            />

   <TextView
            android:id="@+id/songTitle"
            android:textColor="@color/d_gray"
            android:textSize="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:paddingLeft="10dp"
            android:paddingTop="22dp"
            android:text="clip title"
            />

Then we'll jam the seekbar in between, with a little padding to give it some distance from the other elements.
    <SeekBar
            android:id="@+id/songProgressBar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@+id/btnPlay"
            android:layout_toRightOf="@+id/songTitle"
            android:paddingTop="20dp"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            />
The last two textviews are anchored to the seekbar itself.  They have the same left and right padding as the seekbar.
   <TextView
            android:id="@+id/songCurrentDurationLabel"
            android:textColor="@color/d_gray"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/songProgressBar"
            android:layout_below="@+id/songProgressBar"
            android:paddingLeft="15dp"
            android:text="current time"
            />
    <TextView
            android:id="@+id/songTotalDurationLabel"
            android:textColor="@color/d_gray"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignRight="@+id/songProgressBar"
            android:layout_below="@+id/songProgressBar"
            android:paddingRight="15dp"
            android:text="total time"
            />

This is so much cleaner than having about 3 nested levels of LinearLayouts.

Monday, January 7, 2013

When worlds collide

Back in October a friend and I were talking about how I was thinking of trapping a Cooper's hawk to fly this season. The IT manager job had caused me enough stress to give away my goshawk in January.  Birdless for nine months, I was getting the itch, and being unemployed I could devote all sorts of time to a small accipiter.

Though we're both falconers, we talk about all sorts of things.  Knowing I'm a techish person, Niki mentioned she was thinking of making an iPhone version of her book/CD on bird calling. Well and good, I said, but of course she'd have to have an Android version as well!  Not everyone on the planet has an iPhone.

And before I knew it, I was offering to write that app.  By then I had written a bunch of toy apps, and one slightly serious one where the boyfriend could enter his daily weight and email himself a .csv file of the entries for incorporation into an existing Google Drive spreadsheet (we wanted to integrate the entries directly into the spreadsheet, but apparently that part of the API was still in developmental stages, so we left it at email.)  So I had some confidence that I could write something that would work, and she could have it in the Play Store and we'd both make a little money.

And that's been my project since, and I just declared it finished yesterday.  It looks a bit like a book, but includes sound files, one internally stored video, a couple links to YouTube videos, and of course 13 of Niki's paintings.  A couple friends beta'ed the first round and I just sent them the final version for another round.  I started a Play Store account and am getting screenshots together for the product launch.  In the meantime, Niki found an e-book publisher for the iPhone version and will promote both apps in her next appearance on the Ellen DeGeneres show.

That's how it starts

In June 2011 I became unemployed for the first time since graduating from university in 1986.  At the time, my best buddy suggested I consider making games for Android -- he knew I'd written an escape-the-room game in Flash some years prior, and Android was an interesting new platform which could run Flash.

I had no idea where to even begin with that, so I never did.  I was in a panic about having no job to pay the mortgage, and grabbed pretty much the first job that came my way: IT manager.  I hated the work, I hated the drive, but it paid.

Nine months later that job was dust under my feet and I was unemployed for the second time. The difference? I was totally relaxed about it. I had saved my pennies, gotten a decent severance, so I could take my time looking for a real data analysis job.

And in the middle of this I had begun dating a wonderful guy who is a Java programmer.

I'm a dinosaur. I'm a good Foxpro programmer, but nobody uses it anymore.  I can claim to know SQL but once you get to the part of the interview where they ask you T-SQL or PL-SQL or MySQL, I have to say "none of the above," and though the flavors are 95% the same as Foxpro, knowing Foxpro is worthless.  "Thanks for coming in."  "Great, look forward to hearing from you."

I touched on OOP for some Foxpro applications I wrote, but in the day-to-day stuff I had no need for it. So I never really learned OOP.  I understand it in the abstract (yes, you too can create this object called a car and give it attributes like a color and methods that tell you how many MPG it gets!) but the concrete is still powder in an unopened bag.

And this super cool Java programmer boyfriend shows me this little toy he wrote for Android. And he asks if I'd be interested in learning.  Since I have nothing better to do with my life besides playing escape-the-room games and looking at jobs I'm not getting, I say "sure."

He sets me up with an IDE and loads up the Android SDK, shows me the Hello World program. I'm goggling at IDEs and SDKs already and he says, Why don't you just make a little thing where you press a button and it plays a sound or something like that.

It takes me like two weeks of googling and searching Stack Overflow, copying barely-relevant chunks of code wholesale from sites and trying to tweak it to make it do what I want. ("Do what I want, not what I tell you to do!")  I don't know Java at all. I barely understand the purpose of a layout file. I've never even used an IDE that autocompletes -- really!  At the end of it I have a little hand-drawn cartoon goshawk .png that does a coyote howl when you click it.  It's awesome.

And the boyfriend says, hey, why don't you animate it or something?  I want to be able to fling it around the screen and have it bounce off the edges. That might be useful for a game.

And slowly, insidiously, this fantastic boyfriend (who gladly comes and helps whenever my pride breaks hard enough to ask for help) keeps throwing little projects at me, mostly Android, sometimes Java toy environments like Greenfoot, and he gets me to learn.  Classes.  Methods.  Overriding and implementing native methods.  Anonymous inner classes. Contexts.  Instead of copying code and tweaking, I'm actually writing it myself.  And I'm actually starting to understand.