Wednesday, March 5, 2014

Set color of Android button, programmatically

Here's a little problem that had Nirmal frustrated. If there is a layout with multiple buttons to switch layouts or views, how can the user be shown which layout he/she/ze is currently viewing? One idea: change the color of the text on the button which corresponds to the current layout. To do that is so easy!

Button whateverButton = (Button) findViewById(R.id.whateverButton);
whateverButton.setTextColor(Color.parseColor("#00a2ff")); //set text color

of course, you will need to import Button and Color if you haven't already, in Eclipse

How to swipe between layouts in Android apps

Is it easy to open a new layout by swiping horizontally? Yes, it is. When you want to drag your fingers across the screen to switch view layouts, just follow this code!

First, import the Android support library. Right click on your project in ecplise, go to Android Tools, then select Add Support Library. If you don't see that, go to your SDK manager under the Window menu, and find and download it! Now we have all the resources we need.

Paste this in your oncreate to set up the horizontal swipe:
   MyPagerAdapter adapter = new MyPagerAdapter();
   ViewPager pager = (ViewPager) findViewById(R.id.pager);
   pager.setAdapter(adapter);
   pager.setCurrentItem(0);
//set the opening screen
      
Add this class somewhere after the oncreate:
 public class MyPagerAdapter extends PagerAdapter {
    @Override
    public int getCount() {
        return 2; //set  number of swipe screens here 
    }
    @Override
    public Object instantiateItem(final View collection, final int position) {
        LayoutInflater inflater = (LayoutInflater collection.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        int resId = 0;
        switch (position) {
        case 0:
            resId = R.layout.coffee; //set which layout will show on load
            break;
        case 1:
            resId = R.layout.subway; //what layout swiping shows                 break;
        }
        View view = inflater.inflate(resId, null);
        ((ViewPager) collection).addView(view, 0);
        return view;
     }
    @Override
    public void destroyItem(final View arg0, final int arg1, final Object arg2) {
         ((ViewPager) arg0).removeView((View) arg2);
    }
    @Override
    public boolean isViewFromObject(final View arg0, final Object arg1) {
        return arg0 == ((View) arg1);
    }

}

And put this in the default layout, which is actually never seen because it gets replaced with the first swipe screen
    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    </LinearLayout>

Thursday, February 27, 2014

Easiest way to get current location on an android

The newest update of the NY Coffee Map app has a feature to launch navigation to the nearest coffee shop on the map. Android makes location-finding easy. Every device can find its coordinates through GPS  and NETWORK (includes cell tower triangulation and WiFi) It has it's own class "Criteria" to determine which of these is best, taking into account battery, accuracy, whats on, etc.
Here's code (nestled in onCreate) to find the Location we've cleverly named 'devicelocation'

Criteria criteria = new Criteria(); provider = locationManager.getBestProvider(criteria, true); 
Location devicelocation = locationManager.getLastKnownLocation(provider);

n.b. The true in the .getBestProvider tells the method to only select a provider that is currrently enabled.
Once you have that location, getting the latitude an longitude is as easy as requesting it! We save them as doubles called 'currentlat' and 'currentlong'


currentlat = location.getLatitude();
currentlong = location.getLongitude();

And, bingo, you have your latitude and longitude coordinates saved. Note that since we put the Location code in onCreate, we only get a new set of coordinates when the Activity is launched. Adding this method to your code, outside of onCreate obviously, will give you more updates:

@Overrideprotected void onResume() {
  super.onResume();

  if (provider != null){    
    locationManager.requestLocationUpdates(provider, 400, 1, this);
  }

}

@Override 
public void onLocationChanged(Location location) { 
  currentlat = location.getLatitude(); 
  currentlong = location.getLongitude(); 
}

In the next post, I will show how to launch navigation to get to these coordinates!

Thursday, February 13, 2014

The best coffee in Brooklyn and Queens!

In response to the popularity of the original map/app, the entire team at Butterfruit Labs has been investigating the coffee in Brooklyn and Queens (the birthplace of NY's coffee scene may it be argued). There has never been such a rampant, highly-caffeinated, group of geeks. Dozens of shops encountered mysterious interviewers demanding specifics about their coffee. 

Ok, so it's not all of Brooklyn and Queens, but it has the areas with good coffee. A few lines, such as the L and the G, had fierce competition. Other stops (ahem, Woodside and Corona - and come on Barclays Center) had our researchers struggling to find one good cup. Overall, this map should not disappoint, and hopefully, will incite some passionate (yet hiply nonchalant) rage! Without further ado, the map:


Wednesday, February 12, 2014

release date!

Tomorrow morning, Butterfruit Labs will be releasing the newest coffee map: a revision of Manhattan, addition of WiFi symbols, and the much-requested, Brooklyn + Queens. Follow @butterfruitlabs on twitter, check this blog, or watch the nyc subreddit! The app will be updated overnight!

Sunday, February 9, 2014

Lucky Nirms

Nirmal had the very fortunate opportunity of having his dinner last night cooked by done other than Steph, head chef of Steph's Apartment Kitchen. Kofta, baba ganoush, shepherd's salad... oh my Ghandi!

Saturday, February 8, 2014

Map updates

Our coffee map has become very popular, and we've received a ton of suggestions and feedback! And, it's official, the map will be expanding to other boroughs. I also think that WiFi icons will be added. WiFi is a little bit of a paradox for 2014 - there shouldn't be any coffeeshops that can't provide WiFi, but then again, there shouldn't be anyone who needs to rely on a coffee shop to provide it. There are some (looking at you, Juliano) that don't allow laptops at all, but that's a different story. Anyway, stay tuned, I'll post the new stuff right here. You can also follow @rickymikeabono or @butterfruitlabs on twitter, and the NYC subreddit is highly recommended. If you have a favorite spot of your own, please tweeit it, share it below, or email butterfruitlabs@gmail.com

Tuesday, February 4, 2014

NYC Best Coffee

Nirmal and Ricky have been spending a lot of time together in NYC lately, and, cappuccino fuels Nirmal's programming. This weekend Butterfruit Labs put together a list of the best coffeehouses in Manhattan, by subway stop.

The coffeehouses which made the cut were selected based on their equipment, the type/source of beans used, stop proximity, and reviews from both customers and professionals. Unique spots also got priority. In cases of multiple stores, the original or most popular location of that chain was weighted more heavily. Shops which embraced their neighborhoods feel were also favored. Some locations didn't have great options, and Dunkin Donuts or Starbucks had be chosen.



 

Thursday, January 30, 2014

In App Billing Launch

Nirmal has launched BodyBuild v2.0, which includes in-app-billing for the first time. Instead of requiring users to download BodyBuild Pro, a separate app, extra workouts become part of the same BodyBuild. There is also an option to remove ads, making BodyBuild essentially the Pro version. There are also other upgrades, such as more workouts in both free and upgraded versions, enhanced image quality for large screens, and some memory bug fixes. 
This update will be slowly rolled out to existing users, starting with 10%. As long as there are no crash reports, this will be increased to 100% over the course of about a week. There is definitely convenience in the in-app-billing, but users may see less of a value proposition. Hopefully 80+ workouts is enough to convince the cheapest of bodybuilders.

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);
                    return;
                }
                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);
                query.show();
                return;
            }
            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="com.android.vending.BILLING" />

2.) Create billing Package in app
Call it com.android.vending.billing 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 com.android.vending.billing 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, Base64.java through SkuDetails.java, 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:

android:src="@drawable/YOURIMAGE"

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

android:background="@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) {
                e.printStackTrace();
            }

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" />
            </intent-filter>
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.

http://wikitravel.org/en/Manhattan/Upper_West_Side#Drink

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:
http://developer.android.com/training/basics/firstapp/index.html

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:
 
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE

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

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