Monday, December 23, 2013

Code to Set Up Billing and Query Inventory

When enabling in-app purchases,the first step is to set up in app billing, the second should be to check to see what upgrades the user has purchased in the past. Here's code from my own app, which was adapted from the Android TrivialDrive sample code:

Initial set-up, (In on create):

        Log.d(TAG, "Starting setup."); //Log that we will start setting up In App Billing (IAB)
        mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { //Start setup. This is asynchronous and the specified listener will be called once setup completes.
            public void onIabSetupFinished(IabResult result) {
                Log.d(TAG, "Setup finished.");   
                if (!result.isSuccess()) { //If billing setup not a success
                    Log.d(TAG, "Problem setting up in-app billing: " + result);
                if (mHelper == null) return;  // Have we been disposed of in the meantime? If so, quit.
                // if successfullly set up then do this:
                Log.d(TAG, "Setup successful. Querying inventory."); //Log that our setup was successful
                mHelper.queryInventoryAsync(mGotInventoryListener); // Call inventory method of stuff we own

Method for inventory check

    IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
        public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
            Log.d(TAG, "Query inventory started"); //Log that were checking inventory 
            if (mHelper == null) return; // Have we been disposed of in the meantime? If so, quit
            if (result.isFailure()) { // Is inventory query a failure?
                Log.d(TAG, "Failed to query inventory: " + result);           
                Toast query = Toast.makeText(Shoulders.this, "Failed to query inventory: " + result, Toast.LENGTH_LONG);
            Log.d(TAG, "Query inventory was successful."); //if query not a failure then log success          
            Purchase premiumPurchase = inventory.getPurchase(SKU_SHOULDERS); // Do we already have the premium upgrade?
            mIsPremium = (premiumPurchase != null);//) && verifyDeveloperPayload(premiumPurchase));
            Log.d(TAG, "User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM")); //log if premium or not
            if (mIsPremium) updateUi(); //if we are  premium, show premium upgrade
            Log.d(TAG, "Initial inventory query finished; enabling main UI.");

Tuesday, December 10, 2013

In App Building Tutorial

1.) Add permission to app Manifest file
<uses-permission android:name="" />

2.) Create billing Package in app
Call it and make sure its at /src level, not within your other package

3.) Place IInAppBillingService.aidl file in billing Package
This file is called IInAppBillingService.aidl, downloadable through SDK manager under Extras, and is located in your SDK folder (for me, it was here: \AppData\Local\Android\android-sdk\extras\google\play_billing and you can drag it right into the package in Eclipse)

4.) Create billing utils Package in app
Call it and make sure its at /src level, not within your other packages

5.) Copy all files from the Android TrivialDrive sample app into billing Utils package to help us implement billing
Nine .java files, through, located in a subfolder of Step 3's folder.

6.) Make a button in your app that will allow the user to buy something!

7.) Get your public license key from the App's page in your Developer's Console. It's a long Base64-encoded RSA public key.

8.) Code using those borrowed utils! Examples to follow

Sunday, December 8, 2013

Just released, BodyBuild 1.4 beta. I released this update to 5% of active users for testing. I'm not sure if that means new downloads get 1.4, or the old 1.3. Here are some of the updates:

More leg and arm workouts!
Increased image resolutions
Updated launcher icon
Clickable workout names
Larger muscle diagrams
Formatting issues for workout descriptions fixed
Greater device compatibility
Male and female body builder backgrounds

and coming soon in 1.4 alpha, in app upgrading!

Thursday, December 5, 2013

BodyBuild Update

It has been a while since the great app "BodyBuild" has received an update from Nirmal. Just in time for Christmas, here comes a new version complete with a shiny new launcher icon. More importantly, there are extra workouts.

ImageButton Background

When making an ImageButton, android seems to want to give you a background. To show only your image, and not the background, open up that XML layout and put your image in the src tag:


and then, for the background, toss it a null:


And that should do it. So simple. Don't forget the monkeytail in front of the null!

Wednesday, November 20, 2013

Folder in SD Card's Root Directory

If you check out the files in your phone, you'll see several folders in the root directory. Usually you have a Downloads folder, a Music folder, and sometimes, there are custom folders created by your apps. How can you do this? Here are some steps to make a folder and to put a txt file in it.

1.) Create a File object for the directory:
exampleDirectory = new File("/sdcard/foldername/"); 
2.) Make that File object build the directory structure with the built in mkdrs() method:
example Directory.mkdirs();
3.) Create a File object for the output file, and attach the OutputStream to the file. You have to put this in a try and catch method to make Android happy:
File outputFile = new File(exampleDirectory, astringorfileyoucreated+".txt");        
            try {
                FileOutputStream fos = new FileOutputStream(outputFile);           
            } catch (FileNotFoundException e) {

4.)  Add these permissions to your manifest:
       <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
       <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

That is all there is to it. Try it and check out that nice new folder in your root directory.

Monday, November 11, 2013

Set Start Activity

A splash page is the first page the user sees, it's a little advertisement for your app. Most people think it's there because your app is loading, but in reality, its just a page with a time delay. If you want a splash page in an Android app, you need to set the Splash activity to the launching activity. To do that, just go to the manifest file and move this from the activity previously launching during startup, to the one you want to launch during startup:

             <intent-filter >
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
It's that easy! Make sure your splash page calls your other activity!

Tuesday, November 5, 2013

Timeline for New App

Many Desis know that Desis enjoy slacking off, maybe for cricket, maybe for watching entire seasons of popular USA television shows, maybe for Minecraft. To prevent this, Nirmal has created  a timeline for the new app, herewith known as "Project Intro" or just "Intro" for short.

Deadline November 5th: Timeline (completed, horay!)
Deadline November 8th: New workspace, copied useful data, beta logo & promo
Deadline November 15th: EULA/introduction sequence
Deadline November 22nd: Working SD card data save for user, local entries
Deadline November 28th (Thanksgiving): "Intro" BETA LAUNCH!!! (Like autowalla)
Deadline December 6th: Issues fixed from launch, moved data retrieve to website
Deadline December 13th: Graphics (gifs?), alpha logo & promo
Deadline December 20th: Fully populated lists with new entries
Deadline December 23rd (Christmas): "Intro" ALPHA LAUNCH!!! (Like bossmanwalla)

Upper West Sliders on WikiTravel!

Check out WikiTravel, which give a shoutout to Upper West Sliders!

While a relatively quiet nightlife spot, the Upper West Side offers many options to grab a drink and socialize. Trendy wine and cocktail bars are common along Columbus Ave between 70th and 80th Street. Amsterdam Ave around 80th street contains several sports bars and Irish pubs. Further uptown, near Columbia University, cheap college bars are the norm. Some excellent places to grab a drink include:
  • Abbey Pub, 105th Street (off Broadway). An old style pub popular with Columbia University students.  edit
  • Smoke Jazz Club and Lounge, 2751 Broadway (between 105th and 106th Sts.), [19]. Live jazz seven days a week. Performers often jam late into the night so go for the late set if you can.  edit
  • Amsterdam Ale House, (75th and Amsterdam). Local pub specializing in microbrews  edit
  • George Keeleys, (84th and Amsterdam). Excellent beer selection  edit
Happy Hour specials are very popular among bars in the Upper West Side, with most establishments offering deals such as 1/2 price drinks and $1 oysters after work on weekdays. This can be a great way to go out on a budget, or to interact with New York's after work crowd. Websites such as Hour Drinks and Mobile Apps such as Upper West Sliders maintain up-to-date listings of happy hours in the area.

New App in the Works

Now that Nirmal launched, Upper West Sliders, the greatest happy hour app for the Upper West Side, he as lots of free time. A life of leisure and curry have added quite satisfactorily to his paunch. 

That's all over. A new app is in the works, an app bigger than the others (but not bigger than Project B12).

How can an average boy from Bangalore just go about creating a new app? Here are some friendly steps:
1. Download the Android SDK and Eclipse (takes a while even with a fast internet connection)
2. Open Eclipse
3. File->New->Android Application Poject.
4. Profit like a Boss Man Walla.

Here's a little more detail from the source:

Just look at all of Nirmal's rupees already! After new app, his wealth will flow like the Ganges!

Tuesday, October 29, 2013

Saving to device

UWS and Grubby Boston use a remote file for data, an XML on a website. According to the Android himself, these are the storage methods apps can utilize:
Shared Preferences - Store private primitive data in key-value pairs.
Internal Storage - Store private data on the device memory.
External Storage - Store public data on the shared external storage.
SQLite Databases - Store structured data in a private database.
Network Connection - Store data on the web with your own network server
The next app to come from Butterfruit Labs will store a user profile on the device directly, as in, Internal Storage. External storage saves space on the device, but takes more battery to download and upload. Since the files for our next undisclosed app will be so small, we go internal. From my research, the only read/write permissions are:

So its not even necessary to add an extra permission to write internally. To do that, just:

fileoutputstream = new FileOutputStream( root + "/" saveFileName );

Saturday, October 26, 2013

Update released

Upper West Sliders version 1.1 has just been released.

More deals in the 90's and 100's
New no deals button (hopefully you will never see this)
Food search bug fix
Faster splash screen

 Check it out on Google Play here:

Button vs ImageButton

All ImageButtons are buttons but not necessarily Buttons, and obviously not all buttons are ImageButtons. Are all TextButtons Buttons? Yes, but it's a trick question, because TextButtons don't exist, since Buttons are text buttons.

When Upper West Sliders couldn't come up with any deals (rare),  some simple text would be displayed informing the user of this sorry state. That's not really helpful, so I wanted to turn that text into a Button, which lets them search again. What's a Button? According to Google, inventor of the Android Button, a Button:

"Represents a push-button widget. Push-buttons can be pressed, or clicked, by the user to perform an action.
A typical use of a push-button in an activity would be the following:
 public class MyActivity extends Activity {
     protected void onCreate(Bundle icicle) {


         final Button button = (Button) findViewById(;
         button.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
                 // Perform action on click
A button looks pretty basic. Instead of just some text with a rectangular background, why not make the button look like something fun, and delicious, like a hamburger? Yes, Hindus will not like this app, but it will be a big hit in Johnson Market (a Muslim meat market, not a gay bar). To do that we need an ImageButton. Remember that dude, mkyong, I love? Let's ask him for help with an ImageButton:

In Android, you can use “android.widget.ImageButton” to display a normal “Button“, with a customized background image.
In this tutorial, we show you how to display a button with a background image named “android_button.png“, when user click on it, display a short message. As simple as that.
1. Add Image to Resources
Put image “android_button.png” into “res/drawable-?dpi” folder. So that Android know where to find your image.
2. Add ImageButton
Open “res/layout/main.xml” file, add a “ImageButton” tag, and defined the background image via “android:src“.
3. Code Code
Here’s the code, add a click listener on image button.
import android.os.Bundle;
import android.widget.ImageButton;
import android.widget.Toast;
import android.view.View;
import android.view.View.OnClickListener;
public class MyAndroidAppActivity extends Activity {
 ImageButton imageButton;
 public void onCreate(Bundle savedInstanceState) {
 public void addListenerOnButton() {
  imageButton = (ImageButton) findViewById(;
  imageButton.setOnClickListener(new OnClickListener() {
   public void onClick(View arg0) {
    "ImageButton is clicked!", Toast.LENGTH_SHORT).show();

4. Demo

Run the application.
1. Result, a button with a customized background image.
2. Click on the button, a short message is displayed.

Android help shoutout

Lars (see post below) has helped me out a lot with my apps, but I'd like to recognize another super star, 
I won't even hide his Android page in a hyperlink:
Such great tutorials. If you poke around his site, you'll see tutorials for lots of other languages, too. What's his real name? Nobody knows. Actually, I just checked his Google+ page and it says his name is Yong Mook Kim. Here is a picture of this handsome hero:

XML from a remote database

UWS uses an XML format data file, hosted on the internet. To help me with this, I went to the site of Lars Vogel. Thank you please, Lars. First, you have to chose a built in parser

" The Java programming language provides several standard libraries for processing XML files. The SAX and the DOM XML parsers are also available on Android.
The SAX and DOM parsers API is on Android the same as in standard Java. SAX and DOM have their limitations, therefore it is not recommended to use them on Android. Therefore this tutorial does not give an example for the usage of this library.
The Java standard provides also the Stax parser. This parser is not part of the Android platform.
Android provides for XML parsing and writing the XmlPullParser class. This parser is not available in standard Java but is similar to the Stax parser. The parser is hosted at .
On Android it is recommended to use the XmlPullParser. It has a relatively simple API compared to SAX and DOM and is fast and requires less memory then the DOM API."

With one of these parsers ready, add the permission to open external web pages, then point your parser to the page you want! I made my page very simple, with only XML data. 

Friday, October 25, 2013

Live, planned updates, listview intro

Upper West Sliders is already on the market, but I have updates in the works. UWS relies heavily on ListView. 
"ListView is a view group that displays a list of scrollable items. The list items are automatically inserted to the list using an Adapter that pulls content from a source such as an array or database query and converts each item result into a view that's placed into the list."
Right now, when there are no deals to be shown, you just get a little message saying so. I am going to learn how to make a ListView entry that shows when the next deal is happening. That's a lot more helpful. 
Here is an example of a ListView populated with burgers and maybe a pizza: