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.
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.
When constructing your class, you can have a constructor that takes in a Context and assigns it a local Context object within your class.
public class LocationFinder {
private Context myContext;
private Geocoder geocoder;
public LocationFinder(Context context)
{
myContext = context;
geocoder = new Geocoder(myContext);
}
}
And then when you try to access this class, make sure you initialise it like:
public class TestActivity extends Activity {
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LocationFinder lFinder = new LocationFinder(getApplication());
}
}
Of course, you can't access a context from every class that you will be running. So a reference to a View can suffice.
LocationFinder lFinder = new LocationFinder(anyView.getApplication());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With