Facebook Status: Facebook Syndication Error Updated 40 minutes ago
WISHLIST 2011 Posted on 12/06/11 at 1:02AM
[ mandlar ]

Here’s my annual birthday/Christmas wishlist. In no particular order.

Xbox 360 games:

Books:

Other:

  • Running shirts or other running gear (more socks or winter gear, such as wind breaker, running pants, etc.)
  • UNC shirts, etc.
  • a new Firefox shirt?  Android shirts?
  • polo shirts for work
  • giftcards
  • Galaxy Nexus accessories (if it ever will release, won’t know accessories until after Dec 9, maybe)
  • Any sort of French stuff, children/young adult reading level, videos, etc.
Posted in Uncategorized | No Comments »
CAR DASHBOARD RELEASED! Posted on 03/05/11 at 1:42AM
[ mandlar ]

After about 3-4 months of work, I’ve finally released my second application to the Android market!

Car Dashboard is both a speedometer and a Car Home dock replacement app. Use this app to watch your speed and easily access 20 customizable shortcuts!

The app automatically launches when placed in a car dock (that has a magnet).

Features include:
* Speedometer
* Speed Alerts (fully customizable by speed, colors, flashing, and sounds)
* Compass
* Current location
* Current temperature
* Current altitude
* Max speed
* US and Metric units/speed alerts: knots, km/h or mph, Fahrenheit or Celsius, meters or feet
* Custom text colors
* 20 customizable shortcuts – launch favorite applications, directly dial important numbers, navigate to common locations, and more!

Avoid getting a speeding ticket by keeping track and being alerted of your speed accurately via GPS!

What’s supported? The application should run on Android 1.6+

Download: You can find the app in the market by scanning the following QR code or by visiting the following links:

Free: https://market.android.com/details?id=net.mandaria.cardashboardfree

Paid: https://market.android.com/details?id=net.mandaria.cardashboardpro

Screenshots:

I also released a new marketing website for all of my applications. You can find it here.

What’s next? I have another application already in the pipe line to start working on (more details later). I also have quite a few features that I plan on adding to Car Dashboard.  The first additional feature will most likely be music controls via emulating head set controls.

Posted in android | 2 Comments »
ANDROID 2.3 GINGERBREAD SDK, ADB, AND DDMS Posted on 12/07/10 at 10:51AM
[ mandlar ]

The Android 2.3 Gingerbread SDK was released yesterday!

The first problem I encountered is the fact that adb.exe was moved to the /platform-tools/ folder.  So every time I tried to run DDMS I received the following error message:

Failed to get adb version: Cannot run program “adb”: CreateProcess error=2, The system cannot find the file specified.

I managed to fix this by adding the platform-tools folder to my PATH in my Environment Variables.

Posted in android | 3 Comments »
WISHLIST Posted on 11/21/10 at 1:46PM
[ mandlar ]

Since I’ve been asked to make a wishlist for my birthday/Christmas, here it is.  Nothing is really in any sort of particular order.  I listed cheaper games separately because I’m fine with getting more of older, cheaper games, than one or two newer games.  Prices fluctuate a lot, so be sure to actually check out the links.

Xbox 360 games:

CHEAP Xbox 360 games:

Books:

Other:

  • UNC shirts, etc.
  • a new Firefox shirt?  Android shirts?
  • polo shirts for work
  • giftcards
Posted in Uncategorized | 1 Comment »
ROOTING AND FLASHING CYANOGEN MOD ON MY PHONE Posted on 09/19/10 at 2:50PM
[ mandlar ]

Well, I finally got around to rooting my phone (Motorola Droid) last month using the Easy Root method.  I was quite content with sticking the stock 2.2 Froyo ROM since all I really wanted was some basic under/over clocking and Wifi tethering.

Then this month a new OTA update for Froyo came out and the Easy Root method no longer works for it.  So I was stuck at Froyo build FRG01B and kept getting the dialog that I had an OTA update ready to install.  You can ignore it, but it keeps coming back every few hours. Needless to say that gets annoying fast.

Yesterday I finally said to hell with it and installed ROM Manager.  I made an immediate backup of my phone and then promptly installed CyanogenMod 6 (including a wipe of all data from the phone, but I backed up everything with Titanium Backup. Hands down an amazing backup utility).  That went quite successfully other than having to flash a lower version of Clockwork Recovery and then back to the latest version of it (the recovery was refusing to flash the ROM).

Now I’ve been playing with ChevyNo1’s kernels (found in the premium version of ROM Manager).  So far I’ve gotten my phone to work with the Low Voltage 1ghz kernel and the Ultra Low Voltage 0.8 Ghz kernel.  Going to see how high of a clock speed I can push it up on the ultra low voltage and keep things stable.

Android has most certainly been one of my biggest passions this past year since I received my phone last November. I love programming for it (I have another app in the works too).  I love the communities I am a part of.  I wrote a couple of questions and answers to the Android StackExchange (it’s currently in private beta) about rooting and what to do after rooting.  I’ll cross post them here when that StackExchange goes public.

Posted in android | No Comments »
HOW TO ACCESS VERIZON TOWERS WITH MOTOROLA DROID (FOR FORMER ALLTEL CUSTOMERS) Posted on 09/19/10 at 12:02PM
[ mandlar ]

Note: I had written this a few months ago but just now got around to finally posting it.

So I had a weird problem in Mt Airy with my Motorola Droid. I could only receive 1x data signal. Well, at first I didn’t realize it was a problem because I knew that Verizon didn’t have any towers in Mt Airy. But the weird thing was that my coworker (who also has a Motorola Droid) wasn’t even getting a data signal, period. He tried getting this problem explained to Verizon customer service, but they didn’t seem to understand his problem.

Now our IT guy also has a Motorola Droid. He told us that we needed to enable data roaming. This should be fine without incurring any charges so long as we remain in the US. My coworker did this and instantly went from no data signal to 3G. I did it and…. I was stuck at 1x still!  Wtf, right?

Well the only reason I could explain this is that my coworker has always been a Verizon customer and I used to be an Alltel customer who was merged over to Verizon. I still have an old grandfathered (and cheaper) Alltel plan (with the old MyCircle). But I’m a Verizon customer now so I should get access to all Verizon towers, right? Well I sent an email to Verizon customer service asking if this was the case with me being on an Alltel plan. I never heard back and didn’t feel like calling them either.

There was also no way I was going to pay more for a plan with more unnecessary minutes AND less features (cheapest Verizon plan doesn’t include Friends and Family). My brother then passed along some information from his coworker (who also owns a Motorola Droid) about PRLs.  PRLs are the lists of roaming towers that your phone knows about and connect to. Usually you can dial *228 to update your PRL.  Well, I look up my PRL number on my phone (Settings > About Phone > Status > PRL Version), and sure enough it is a 3XXXX number (an Alltel PRL). I ask my coworker to look up his and it was a 5XXXX number (a Verizon PRL). So this explains it! My phone doesn’t have the Verizon towers in its PRL!

Unfortunately, dialing *228 kept my PRL in the 3XXXX range, so updating my towers via that method wasn’t going to work. But my brother’s coworker also shared a link to a tutorial to both backup a PRL on a phone and flash a new one onto it: Flash the Droid to any network.

Following that tutorial I found a 5XXXX PRL, flashed it on my phone, and then finally received 3G data in Mt Airy! Hooray!

So if you are a former Alltel customer and think you could be getting a better roaming data signal, then give this tutorial a whirl and see if it helps you out.  You’ll have to find your own PRL file because they are different for different regions of the United States.

Disclaimer: try this at your own risk. I am not responsible for any damage you may do to your phone.

Posted in android | 2 Comments »
BOWMAN GRAY STADIUM RADIO FREQUENCIES FOR DRIVERS Posted on 08/26/10 at 8:01PM
[ mandlar ]

My brother, his wife and I have been going to a lot of Bowman Gray Races this year.  Towards the end of the season, he started using his scanner to pick up on the chatter that the drivers and their spotters were having during the races.  So I ordered myself a scanner too, a Uniden BC72XLT, which has an awesome close call capture feature that will pick up radio frequencies within about line of sight distance.  That feature alone beats scanning a frequency range if you are close enough to the action.

We’ve started compiling a list of drivers and their frequencies in a Google document that you can find here: http://www.bowmangrayfrequencies.com which is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.  That means you can use it, share it, do whatever you want with it so long as you attribute Scott Denny and don’t sell it.

You can also find my bank setup for my scanner here: http://bit.ly/BryansScanner which includes local radio frequencies for Stokes, Surry and Forsyth county, as well as the frequencies of the  Bowman Gray drivers broken down by both banks and sorted by driver number.  The spread sheet document is separated into three separate sheets called Local (banks for Stokes, Surry and Forsyth), Bowman Gray (banks for Officials, Stadium Stock, Street Stock, Sportsman, my favorites, and Modifieds) and Drivers (list of drivers and their frequencies sort by their car number for quick look-ups at the track).  My spread sheet document is also licensed under the same Creative Commons license.

Posted in Uncategorized | 1 Comment »
HOW TO NOT HANDLE EXCEPTIONS: GDI+ GENERIC EXCEPTION Posted on 06/09/10 at 1:13PM
[ mandlar ]

A few months ago at work, I came across the worst possible exception I have ever seen thrown by a program:

A generic error occurred in GDI+

For those who don’t know, GDI+ is the graphics library for Windows that is supported in .NET via the System.Drawing namespace.

So, what is so bad about this?  It doesn’t tell me why this error occurred!  There is no inner exception passed along.  If I don’t know the source of the problem that is causing the exception, then how can I prevent the exception from being thrown?  Heck, how can I even catch this exception and know what to do with it? Did the memory get full?  Was a file not found? Is a file being used by another process? Did the world blow up?  WHAT THE HELL HAPPENED?

After a quick search on StackOverflow I came up with a number of possible sources of the problem, but at best we are guessing because the exception tell us absolutely nothing!

And the list goes on and on with further suggestions.  The thing that baffled me is that my GDI+ exception occurs randomly.  It doesn’t happen every single time I run my GDI+ functions.  I think it has to do with some sort of file lock going on, but honestly, I have no idea because the GDI+ generic exception is a worthless piece of information.  I re-wrote my code to ensure that all file handles are closed after being used.  I even tried copying the bitmap created from a file into a NEW bitmap to remove the dependency between the bitmap and the original file.  Nothing.

Personally, I would love to meet the developer who thought swallowing up the inner exceptions was a fabulous idea and reprimand the hell out of him or her. And why hasn’t Microsoft updated the library with better exceptions?

So, the moral of the story folks is to don’t write code like this:

1
2
3
4
5
6
7
8
try
{
     // one or a million lines of code
}
catch (Exception ex)
{
     throw new Exception("A generic error occured in [program name]!");
}
Posted in computers | 2 Comments »
WHAT I LEARNED FROM WRITING MY FIRST ANDROID APPLICATION Posted on 05/25/10 at 1:48AM
[ mandlar ]

I just recently released my first Android application, Tippy Tipper, a tipping calculator. From writing this app I learned a number of things as a new Android developer and decided that I should write down and share some of these tips and tricks for other new Android developers who might come across them. My application is open source and you can find the source code at its Google Code project site here. My hope is that someone else can benefit and learn from what I have gone through these past couple of months.

Choosing an application to build

What should you write? Well, that is up to you, but if this is your first Android application then my recommendation is to choose something simple. You may know Java, but you do not know the Android framework. Gently ease yourself into the Android framework instead of creating a lot of frustration and headaches as you attempt to do something overly complex when you do not even grasp how layouts work. I recommend creating an application that you should be able to complete within a month or two at most, because once you complete this simple application you will have a sense of accomplishment which will encourage you to build something even more difficult and challenging. This positive reinforcement will keep you from burning out early in frustration. You essentially want to aim your application a couple of notches beyond the Hello World app.

Personally, I chose a tip calculator for a few key reasons:

  • Tip calculators are common, so there are a lot of examples out there. I can learn from other people’s UIs and see how I can make mine better
  • I wasn’t happy with any of the available tip calculators on the market
  • I can use it, nearly every day. Therefore, I can dog food my app
  • It is simple and covers most of the Android basics: 20 buttons (event handling), preference, multiple activities, etc.

How I designed my application

My approach to my Android app was to try and fit it into a MVC (Model-View-Controller) design pattern. In Android, the Activity classes act as both the View and the Controller. It behaves as a View because it renders the layouts to the screen and it behaves as a Controller by adding event handlers (onClick(), etc.) to objects in the View. The last piece is the Model, which in my case is a completely independent service (not an Android service, I simply am calling it a service in general) that provides functions to access and manipulate data (calculate tip, get the tip amount, split the bill, etc.). My service is stand alone and therefore easily unit tested by JUnit. For the most part, the UI of my app simply calls functions found in my service and then updates the View with new information from my service.

MVC Example

On the first main activity of the application (the keypad screen) we have an EditBox that shows the current entered BillAmount and some buttons (0-9) to append to the BillAmount, delete the last digit of the BillAmount, or to continue to the next Activity.

1
2
3
4
5
6
7
8
9
10
...
<EditText
     android:id="@+id/txt_amount"
     style="@style/BillAmountEditText"/>
...
<Button
     android:id="@+id/btn_five"
     style="@style/CalculatorButton"
     android:text="5" />
...

When you click the “5″ button, the following event handler is called:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public void onCreate(Bundle savedInstanceState) 
{
...
     View btn_five = findViewById(R.id.btn_five);
     btn_five.setOnClickListener(new OnClickListener()
     {
          public void onClick(View v)
          {
               AddBillAmount("5");
          }
     );
...
}
 
private void AddBillAmount(String number)
{
     TippyTipperApplication appState = ((TippyTipperApplication)this.getApplication());
 
     appState.service.AppendNumberToBillAmount(number);
 
     BindData();
}

The AddBillAmount gets the instance of the service (more about this below, see Global Singleton) and calls the service’s AppendNumberToBillAmount():

1
2
3
4
5
6
7
8
9
10
11
12
public void AppendNumberToBillAmount(String number)
{
     if(BillEntry.length() < 15)
     {
          BillEntry = BillEntry + "" + number;
     }
     double amount = Double.valueOf(BillEntry);
     amount = amount / 100;
 
     BillAmount = amount;
     BillAmountBeforeTax = BillAmount;
}

Which appends the number to the end of our service’s BillEntry string and then converts it into a double amount which is saved to BillAmount and BillAmountBeforeTax. Now the Controller will call BindData (ASP.NET term; I’m a C#/ASP.NET developer by day) which will refresh our View with the service’s updated BillAmount:

1
2
3
4
5
6
private void BindData()
{
      TippyTipperApplication appState = ((TippyTipperApplication)this.getApplication());
      EditText txt_amount = (EditText)findViewById(R.id.txt_amount);
      txt_amount.setText(appState.service.GetBillAmount());
}

Viola! A simple MVC pattern put to good use. Now we can easily take out Model/service and apply unit testing to it:

1
2
3
4
5
6
@Test public void AppendNumberToBillAmount()
{
     TipCalculatorService service = new TipCalculatorService();
     service.AppendNumberToBillAmount("1");
     assertTrue(service.GetBillAmount().equals("$0.01"));
};

Global Singleton

One of the first problems I had with my Model was always having a singleton of it available. An important thing to note with Activities is that they are destroyed and re-created whenever the user rotates their phone from vertical to landscape or vice-versa. Therefore, if you declare a singleton inside of you Activity, then it will be gone when the Activity is re-created. The workaround for this is to instead create the singleton at the Application layer, making it globally accessible to ALL activities.

First you have to create a class that extends Application and contains your singleton:

1
2
3
4
public class TippyTipperApplication extends Application 
{     
      public TipCalculatorService service = new TipCalculatorService();
}

As seen earlier, you now simply have to get an instance of the Application in order to access your service:

1
2
TippyTipperApplication appState = ((TippyTipperApplication)this.getApplication());
appState.service.AppendNumberToBillAmount(number);

Using Preferences

Creating the preference activity is perhaps one of the easiest things to do in Android. You simply have to create a layout and attach the Layout to a class that extends PreferenceActivity:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Settings extends PreferenceActivity
{
     @Override
     protected void onCreate(Bundle savedInstanceState)
     {
          super.onCreate(savedInstanceState);
          addPreferencesFromResource(R.xml.settings);
     }
 
     public static int getDefaultTipPercentage(Context context)
     {
          return PreferenceManager.getDefaultSharedPreferences(context).getInt("default_tip_percentage", 15);
     }
....
 
}

So long as you don’t need a custom dialog, then Android handles the saving/loading of dialog values for you in the background. In order to retrieve the preference value:

1
double defaultTipPercentage = (double)Settings.getDefaultTipPercentage(getBaseContext());

But what if you do need to have a custom preference dialog?

Creating and using a custom preference dialog

For setting the default tip percentage values, I wanted to use the SeekBar similar to how it is done on the Activity in which you choose a tip percentage:

No such thing exists in the Android SDK so I either had to create my own or see if someone had already made their own. Thankfully, someone had already made a SeekBar preference.

The key important thing to rolling your own custom preference dialog is knowing how to get your stored value:

1
2
if (shouldPersist())
     mValue = getPersistedInt(mDefault);

And updating your stored value:

1
2
if (shouldPersist())
      persistInt(value + mMin);

Extending preference with min value (How to add attributes to your widgets)

When I originally used the SeekBarPreference, I was also using it for the preference dialog of setting the default number of people to split the bill by. This means that the SeekBar has to go from 2 to max_value, instead of 0 to max_value. So I had to extend the SeekBarPreference to allow this. My first problem was that the Android name space does not have an android:min defined, only an android:max.

I have to create a min attribute in a res/values/attr.xml file:

1
2
3
4
5
<resources>
     <declare-styleable name="SeekBarPreference">
          <attr name="min" format="string" >
     </declare-styleable>
</resources>

Then I have to reference the namespace in the Preference layout:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<PreferenceScreenxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/net.mandaria.tippytipper">
     <PreferenceCategory android:title="Tipping Options">
          <net.mandaria.tippytipper.preferences.SeekBarPreference
          android:key="default_tip_percentage"
          android:title="Default Tip Percentage"
          android:summary="Percentage to tip by default"
          android:dialogMessage="Percentage to tip by default"
          android:defaultValue="15"
          android:text="%"
          android:max="40"
          app:min="0"
     />
...

Finally, to get the min value programmatically:

1
2
3
private static final String appns="http://schemas.android.com/apk/res/net.mandaria.tippytipper";
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SeekBarPreference);
mMin = a.getInt(R.styleable.SeekBarPreference_min, 0);

Note the usage of the TypedArray against the attrs.xml file created above. This is different than grabbing android:max programmatically (I could simply be missing something above, but it works):

1
2
private static final String androidns="http://schemas.android.com/apk/res/android";
mMax = attrs.getAttributeIntValue(androidns,"max", 100);

Android is missing the NumberPicker widget in the SDK

For whatever reason, the NumberPicker widget is not publicly available to developers. It is there, but it is hidden in the internals of Android and I didn’t want to access private APIs by finding it by reflection. Instead I found it in the Android source code and was about to pull it out when I found that someone else had already beat me to it.

I really do not understand why this widget is not publicly available, because forcing a user to only select an integer value is very nice (with the ability to enter the integer with the +/- buttons or typing it in).

I used the NumberPicker in my own custom dialog preference called DecimalPreference:

Using LDPI, MDPI, and HDPI with Android 1.5+ (How to set a min API and have a higher target API)

In order to get my app’s launcher icon to work with multiple DPIs (LDPI, MDPI, and HDPI), a feature of Android 1.6+, and to have my app still work on Android 1.5 phones, I had to set the app’s minSDK value to 1.5 and set the targetSDK to 1.6:

1
<uses-sdk android:minSdkVersion="3"  android:targetSdkVersion="4" />


Applications with multiple versions (free / paid / donate)

If you plan on having more than one version of your app, then it must be noted that they MUST have different package names on the Android Market. I did not realize this until I was ready to release and had to spend about an hour or so creating a Donate branch in my SVN and renaming the package references everywhere from “net.mandaria.*” to “net.mandaria.tippytipper.*” and “net.mandaria.tippytipperdonate.*”

I feel like my Donate branch isn’t the best idea. For every release I will have to merge the trunk into the Donate branch and rename the package from “net.mandaria.tippytipper.*” to “net.mandaria.tippytipperdonate.*” and I cannot think of a better way to do it. Any suggestions?

Reporting error handling

One thing I have yet to implement is reporting any errors thrown in the app by users to me. The Android Remote Stacktrace project looks promising, but I would have to enable internet privileges in my app when it does not need them otherwise (how acceptable is that?). Or I could create an e-mail intent on errors (but that is less anonymous and they may be less willing to submit the report). Any thoughts on this?

PayPal API == Better way to donate?

PayPal just recently released an Android API for making PayPal transactions inside of apps. This could be an alternative way to collect donations for an open source app instead of (or in addition to) dealing with a second donate version of the app. But it could also potentially break the Developer’s Distribution Agreement:

3.3 You may also choose to distribute Products for free. If the Product is free, you will not be charged a Transaction Fee. You may not collect future charges from users for copies of the Products that those users were initially allowed to download for free. This is not intended to prevent distribution of free trial versions of the Product with an “upsell” option to obtain the full version of the Product: Such free trials for Products are encouraged. However, if you want to collect fees after the free trial expires, you must collect all fees for the full version of the Product through the Payment Processor on the Market. In this Agreement, “free” means there are no charges or fees of any kind for use of the Product. All fees received by Developers for Products distributed via the Market must be processed by the Market’s Payment Processor.

Technically, the donation is not required for use of the Product as it is still provided 100% free. But it isn’t being processed by Google’s Payment Processor. So I do not know whether or not to explore this route.

Conclusion

I’m very excited about Android. I’m very happy to now be a part of its developer community. I’m still very new at it and am learning something new every day. I hope that these comments of mine help someone else, or if any of them are totally wrong, please feel free to correct me. I appreciate all the constructive criticism I can get to improve both my application and myself as a developer.

Posted in android | 23 Comments »
TIPPY TIPPER: THE TIP CALCULATOR RELEASED Posted on 05/24/10 at 8:01PM
[ mandlar ]

After a couple of months of diving into the programming world of Android, I have finally released my first Android phone application! Tippy Tipper is a simple and open source Android Tipping Calculator. It is the result of my first experience with learning Android and I have made it an open source project so that hopefully other new Android programmers can use it as an example application to learn from. Since it is open source, it is completely free (no ads) and donations are always welcome (although I honestly do not expect many).

Some features of Tippy Tipper include:

  • Enter bill via custom keypad
  • Select tip by slider or three configurable buttons
  • Real time calculations
  • Round up or down by tip or total
  • Can split the bill
  • Can optionally exclude a tax rate from the bill

I still have a list of things to do with the app, so I will continue to work on it as time allows (but I am planning on starting another app soon, most likely a game).  I am also open for any new feature requests and I am sure there will also be bug reports.

Supported: The app is built against the 1.6 API, but should run on any phone with Android 1.5 or greater.  I primarily tested the app on my Motorola Droid, but I also tested it against other resolutions and DPIs using the Android emulator.

Why: I made this app because I did not want to get in over my head with an impossible first project while learning Android. I wanted something simple that I know I could do in my spare time.  That and I thought I could make a better tipping calculator than the other ones on the Android Market.  Plus, I plan on using it when I go out to eat. Dog fooding at its finest!

Download: You can find the app in the market by scanning the following QR code or you can obtain the source code from the project’s Google Code site.

Screenshots:

Vertical layouts:

Horizontal layouts:

 

Posted in android | 4 Comments »

Back to top