Archive for the ‘Android’ Category

how i made my samsung fascinate not suck

Last week, I got a new Samsung Fascinate (Verizon’s Galaxy S phone).  It was the free phone at Best Buy, and it was time to add a new line to the family plan.

On the surface it’s a decent enough phone, and the hardware is great.  Sure, it’s not a 4.3″ screen with a dual core 1.2Ghz processor, but for last year’s model it’s nice.  The big problem with this phone is the software.  Here are the big gripes that I and others have with this phone:

GPS

Out of the box, my it took 3-5 minutes to get a GPS fix (completely unacceptable).  Once I got a fix, it was accurate within reason; however, others have reported that their accuracy was way off with this phone.

I’m not sure why, but an app from the Market fixes the problem all together:  GPS Status & Toolbox

Once I installed this and ran it, I was getting a GPS fix in 5-10 seconds.  I don’t have a clue why this works, but it did for me.  Your mileage may vary; in any case, it’s a very cool little app to have.

TouchWiz UI

Any UI is subjective, but there seems to be a general disdain for Samsung’s TouchWiz interface.  I personally could have lived with it, but I was not a fan either.

Install this:  LauncherPro

I had never used LauncherPro before, but I’m pretty sure it might find its way onto any of my future Android phones.  It allows you to customize your homescreens, doc, app drawer, and a ton of other things.  Very nice, and it got rid of 99% of all the TouchWiz annoyances.

Bing

This isn’t really Samsung’s fault, but Verizon has felt the need to have Bing as the default search engine and map provider on the Fascinate.  There’s really no way to change this, but installing Google’s Search and Maps goes a long way.  May others have changed their browser home page to google.com, but I haven’t felt the need.  I just put the Google Search widget on my homescreen, and I’m good to go.

In the original phone (with Android 2.1), you could not download and install Google Search.  However, since the Froyo update last month, it’s no problem.  I’m not sure how long you’ll still be able to buy one of these phones new, but mine came out of the box with Froyo.

But, after all this, the Search button on the phone still uses Bing … Oh well.

Verizon Navigator

Verizon Navigator is the default (and unchangeable) navigation program on the phone.  The icon on the Car Dock screen will ALWAYS open VZW Navigator (making this screen basically useless).

Get the Google Navigation app from the Market and put a shortcut on your homescreen.

Crazy Bloatware

I don’t think I’ve ever seen a phone with this much useless software preinstalled.  You can’t remove it, but at least with LauncherPro (above) I can hide the icons from the app drawer.

So, contrary to popular belief, it is possible to make the Fascinate tolerable (even likable) without rooting and custom ROMs.  I don’t know that we’ll ever get Gingerbread, but for now I’m happy.

Simple Android Speedometer

UPDATE

There’s been quite a bit of activity on this post. Some of the info is old, and people keep asking for the full Eclipse project.

Here’s something even better… Step-by-step tutorial for the simple speedometer:

Nothing but old info below here…

I’ve seen lots of questions concerning the use of the GPS functionality in Android.  It’s super easy, but some of the explanations are needlessly complicated.

The code below is a simple speedometer that uses the GPS chip to show your current speed.  There are optimations that can be made (specifically in the “locationManager.requestLocationUpdates” call), but this is good enough to get you going.  The Android API documentation should fill in the gaps. As always … take it, run, and share with the rest of us.

Check out the interface and class below, and make sure to see the previous post for the “CLocation” class.

import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;

public interface IBaseGpsListener extends LocationListener, GpsStatus.Listener
{
  public void onLocationChanged(Location location);

  public void onProviderDisabled(String provider);

  public void onProviderEnabled(String provider);

  public void onStatusChanged(String provider, int status, Bundle extras);

  public void onGpsStatusChanged(int event);
}
import java.util.Formatter;
import java.util.Locale;

import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;

public class CSpeedometer extends Activity implements IBaseGpsListener
{
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.speedometer_main);

    LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                                           0,
                                           0,
                                           this);

    this.updateSpeed(null);

    CheckBox chkUseMetricUnits = (CheckBox)this.findViewById(R.id.chkUseMetricUnits);
    chkUseMetricUnits.setOnCheckedChangeListener(new OnCheckedChangeListener()
    {
      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
      {
        CSpeedometer.this.updateSpeed(null);
      }
    });
  }

  public boolean onCreateOptionsMenu(Menu menu)
  {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.speedometer_main, menu);
    return true;
  }

  public boolean onOptionsItemSelected(MenuItem item)
  {
    switch (item.getItemId())
    {
      case R.id.menuItemQuit:
        this.finish();
        return true;
      default:
        return super.onOptionsItemSelected(item);
    }
  }

  public void finish()
  {
    super.finish();
    System.exit(0);
  }

  public void updateSpeed(CLocation location)
  {
    float nCurrentSpeed = 0;

    if( location!=null )
    {
      location.setUseMetricUnits(this.useMetricUnits());
      nCurrentSpeed = location.getSpeed();
    }

    Formatter fmt = new Formatter(new StringBuilder());
    fmt.format(Locale.US, "%5.1f", nCurrentSpeed);
    String strCurrentSpeed = fmt.toString();
    strCurrentSpeed = strCurrentSpeed.replace(' ', '0');

    String strUnits = "miles/hour";
    if (this.useMetricUnits())
    {
      strUnits = "meters/second";
    }

    TextView txtCurrentSpeed = (TextView) this.findViewById(R.id.txtCurrentSpeed);
    txtCurrentSpeed.setText(strCurrentSpeed + " " + strUnits);
  }

  public boolean useMetricUnits()
  {
    CheckBox chkUseMetricUnits = (CheckBox)this.findViewById(R.id.chkUseMetricUnits);
    return chkUseMetricUnits.isChecked();
  }

  public void onLocationChanged(Location location)
  {
    if (location != null)
    {
      CLocation myLocation = new CLocation(location, this.useMetricUnits());
      this.updateSpeed(myLocation);
    }
  }

  public void onProviderDisabled(String provider)
  {
    // TODO: do something one day?
  }

  public void onProviderEnabled(String provider)
  {
    // TODO: do something one day?
  }

  public void onStatusChanged(String provider, int status, Bundle extras)
  {
    // TODO: do something one day?

  }

  public void onGpsStatusChanged(int event)
  {
    // TODO: do something one day?
  }
}

UPDATE

I’ve uploaded the source, layout xml, and manifest xml here:

speedometer_test.zip

 

Android Location class with U.S. customary units (instead of metric)

I’m a big proponent of going metric; I’ve never fully understood why we don’t just do it.  Then again, I’d also like the entire world to be on UTC time.  But since we insist on using our own bass-ackward units of measure, I needed an Android Location class that returned U.S. customary units instead of metric.

So, here goes…

import android.location.Location;

public class CLocation extends Location
{
  private boolean bUseMetricUnits = false;

  public CLocation(Location location)
  {
    this(location, true);
  }

  public CLocation(Location location, boolean bUseMetricUnits)
  {
    super(location);
    this.bUseMetricUnits = bUseMetricUnits;
  }

  public boolean getUseMetricUnits()
  {
    return this.bUseMetricUnits;
  }

  public void setUseMetricUnits(boolean bUseMetricUnits)
  {
    this.bUseMetricUnits = bUseMetricUnits;
  }

  @Override
  public float distanceTo(Location dest)
  {
    float nDistance = super.distanceTo(dest);

    if (!this.getUseMetricUnits())
    {
      // Convert meters to feet
      nDistance = nDistance * 3.28083989501312f;
    }

    return nDistance;
  }

  @Override
  public float getAccuracy()
  {
    float nAccuracy = super.getAccuracy();

    if (!this.getUseMetricUnits())
    {
      // Convert meters to feet
      nAccuracy = nAccuracy * 3.28083989501312f;
    }

    return nAccuracy;
  }

  @Override
  public double getAltitude()
  {
    double nAltitude = super.getAltitude();

    if (!this.getUseMetricUnits())
    {
      // Convert meters to feet
      nAltitude = nAltitude * 3.28083989501312d;
    }

    return nAltitude;
  }

  @Override
  public float getSpeed()
  {
    float nSpeed = super.getSpeed();

    if (!this.getUseMetricUnits())
    {
      // Convert meters/second to miles/hour
      nSpeed = nSpeed * 2.2369362920544f;
    }

    return nSpeed;
  }
}

This class really isn’t anything special, it just allows you to toggle which units you would like to use:

  • U.S. Customary Units:  feet and miles/hour
  • Metric:  meters and meters/second

Please, take it and make it better :)

Gingerbread on my 1st gen Droid

My first leap into the Android world was the 1st generation Motorola Droid.  When it was released, it was THE droid to have.  I still love the phone, but when my contract was up, I couldn’t resist the call to a newer/better phone.

Because I’m cheap, I upgraded to an HTC Incredible (it was free at BestBuy).  A decent phone in it’s own right, but it’s last year’s technology.  Even though, it’s a good bit above my old trusty droid.  I wanted to hold out for Thunderbolt or Bionic, but it just didn’t happen that way.

So, now that I’ve got this shiny new phone, I can be geeky with the old one.  Thanks to the folks over at Ultimate Droid, I’ve got Gingerbread up and running on the old droid.  I must say, it’s amazing!  It’s almost making me have a few second thoughts about my upgrade.

Perhaps it’s time for me to consider rooting my main phone?

Android Market Web Fail [updated]

The new Android Market web site looks to be impressive.

The “invalid request” error I get when I (and everyone else in the world) attempt to log in is not impressive.  Sigh…

I’ll try again later…  Good job Google.

[update]

Good job Google.

After the initial issues with logging in, I noticed a few small hiccups:

  • The apps I already had were not recognized as “INSTALLED”.  Each app in the market will tell you whether or not it is installed or can be installed.
  • When installing, I would get an error message telling me to try again later.  Then (even with the error), the app would begin installing on my phone.

But … with a bit of time (I’m guessing to sync somehow with my device).  All of my apps were detected, and I am not getting error messages any more.

I’m diggin’ the new market web site right now … I think mainly because I HATE using the market app on the phone.