Android Context without being in an activity? And other activity-less programming?

bob picture bob · Jul 3, 2013 · Viewed 21.7k times · Source

I'll try really hard to turn this into one comprehensive question:

I'm writing a method to get a String that contains the name of an Android device's city, as determined by the LocationManager and getLastKnownLocation() and all that.

Then I realized I'd need to do the same thing again in another activity, so why not just make an entirely separate class (LocationFinder) that I could use across my program, instead of writing duplicate code everywhere?

But I've run into problems that confuses me. For instance, if I make this class (LocationFinder), should it extend Activity, even though it is never actually visualized? All this class would do is have a variety of getters like getLastKnownCity() or getCurrentCity() and return strings. I assumed it wouldn't HAVE to extend the Activity class, since it's really not an activity.

But then what Context do I use for:

Geocoder geocoder = new Geocoder(Context context, Locale locale)

?

This made me assume it MUST be an activity. So I extended Activity, and replaced the constructor with

@Override
protected void onCreate(..............

but for some reason, that never ends up getting called, even when I put

String city = new LocationFinder().getLastKnownCity();

My very first line of LocationFinder's onCreate() is

System.out.println("HEY!")

and it never even gets to that. I get a null pointer at android.internal.os.LoggingPrintStream.println() and other stuff.

Plus, there's a bunch of system constants that come from Activity classes. For instance, I need to get at LOCATION_SERVICE, which is a String, which I can't get without extending Activity. Sure, I could cheat and just put in the literal string, but that feels wrong.

Answer

Alex Gittemeier picture Alex Gittemeier · Jul 3, 2013

EDIT: If possible, use frogmanx's answer. This should only be used when his answer is not possible to use. (ie. singletons that need a context right off the bat.)

Sounds like you should extend Application and not Activity.

Make your Application something like this:

public class MyApplication extends Application {
    private static MyApplication instance;

    public MyApplication() {
        instance = this;
    }

    public static MyApplication getInstance() {
         return instance;
    }

Then add this attribute to the application tag of the manifest:

 <application android:name=".your.package.MyApplication" ... />

After all that, you can get a Context by calling MyApplication.getInstance() from anywhere.