213

I'm having trouble offloading tasks from the main Activities OnCreate method onto another class to do the heavy lifting.

When I try to call getSystemService from the non-Activity class an exception is thrown.

lmt.java:

package com.atClass.lmt;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.location.Location;

public class lmt extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        fyl lfyl = new fyl();
        Location location = lfyl.getLocation();
        String latLongString = lfyl.updateWithNewLocation(location);

        TextView myLocationText = (TextView)findViewById(R.id.myLocationText);
        myLocationText.setText("Your current position is:\n" + latLongString);
    }
}

fyl.java

    package com.atClass.lmt;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.location.Location;
    import android.location.LocationManager;
    import android.os.Bundle;
    import android.widget.TextView;
    import android.content.Context;
    
    public class fyl {
        public Location getLocation(){
            LocationManager locationManager;
            String context = Context.LOCATION_SERVICE;
            locationManager = (LocationManager)getSystemService(context);
            
            String provider = LocationManager.GPS_PROVIDER;
            Location location = locationManager.getLastKnownLocation(provider);
            
            return location;
        }
    
        public String updateWithNewLocation(Location location) {
            String latLongString;
            
            if (location != null){
                double lat = location.getLatitude();
                double lng = location.getLongitude();
                latLongString = "Lat:" + lat + "\nLong:" + lng;
            }else{
                latLongString = "No Location";
            }
            
            return latLongString;
        }
    }
Robotnik
  • 3,643
  • 3
  • 31
  • 49
Kevin Parker
  • 16,975
  • 20
  • 76
  • 105
  • 3
    Adding the exception and stack trace to the question may help potential answerers – Bert F Feb 02 '11 at 04:07
  • Hi, Sorry for the mistake. The exception is thrown if I try to extend the Activity class with this one. I do not want to extend the Activity class for this class and simply want to be able to call getSystemService from within my getLocation method. Exception: java.lang.IllegalStateException: System services not available to Activities before onCreate() – Kevin Parker Feb 02 '11 at 04:14

7 Answers7

310

You need to pass your context to your fyl class..
One solution is make a constructor like this for your fyl class:

public class fyl {
 Context mContext;
 public fyl(Context mContext) {
       this.mContext = mContext;
 }

 public Location getLocation() {
       --
       locationManager = (LocationManager)mContext.getSystemService(context);

       --
 }
}

So in your activity class create the object of fyl in onCreate function like this:

package com.atClass.lmt;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.location.Location;

public class lmt extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        fyl lfyl = new fyl(this); //Here the context is passing 

        Location location = lfyl.getLocation();
        String latLongString = lfyl.updateWithNewLocation(location);

        TextView myLocationText = (TextView)findViewById(R.id.myLocationText);
        myLocationText.setText("Your current position is:\n" + latLongString);
    }
}
Krzysiek
  • 7,895
  • 6
  • 37
  • 38
Labeeb Panampullan
  • 34,521
  • 28
  • 94
  • 112
  • Sorry I don't get it, code would be more helpful. If anything I should be passing a LocationManager object to the getLocation method... I don't really see how me passing the context to the method will help when I cannot even call getSystemService without writing this class as an extended class to Activity. – Kevin Parker Feb 02 '11 at 04:23
  • did you tried this. In the onCreate if you are passing access the context by 'this' – Labeeb Panampullan Feb 02 '11 at 04:27
  • but if the `lmt` class wont get executed then `fly` wont be having context – Hunt May 14 '13 at 16:01
  • BTW `getSysytemService()`only accepts `String` as a parameter. Therefore you **cannot** pass a context to it. _How do I get around this?_ @Hunt – Parth Sane Sep 01 '14 at 19:43
  • You don't need to pass context into that class. [See my answer](http://stackoverflow.com/a/39065445/1074799) – S.M.Mousavi Aug 21 '16 at 14:47
  • 2
    Just to mention, Android managers (`BluetoothManager`, `ActivityManager` etc.) are also [constructed](https://android.googlesource.com/platform/frameworks/base/+/742a67127366c376fdf188ff99ba30b27d3bf90c/core/java/android/app/ActivityManager.java#62) that way (not necessarily passing an `Activity` context to their constructor) and this is why they can access components in application scope. – Eido95 Nov 09 '16 at 12:51
  • Instead pass context to `getLocation` and make it static. `public static Location getLocation(Context context) { locationManager = (LocationManager)context.getSystemService(context); }` – Prabs Feb 13 '17 at 12:33
  • this is now outdated – SlowLearnah May 06 '22 at 21:38
55

You can go for this :

getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
Maddy Sharma
  • 4,870
  • 2
  • 34
  • 40
17

One way I have gotten around this is by create a static class for instances. I used it a lot in AS3 I has worked great for me in android development too.

Config.java

public final class Config {
    public static MyApp context = null;
}

MyApp.java

public class MyApp extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Config.context = this;
    }
    ...
}

You can then access the context or by using Config.context

LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = Config.context.getSystemService(context);
brenjt
  • 15,997
  • 13
  • 77
  • 118
  • 4
    The problem I see with this method is it leaves something unprotected that, if someone were to assign null to it, would probably produce a catastrophic failure? – Rob Dec 25 '13 at 19:38
  • 2
    A variation on this is to put a private static in MyApp, and then add getters. `private static MyApp _context;` `public static MyApp getContext() { return _context; }` ... in onCreate: `_context = this;` in onStop: `_context = null;` ... Usage: `MyApp.getContext()`. – ToolmakerSteve Sep 20 '15 at 16:22
  • 2
    It maybe lead to memory leak – Yat3s Dec 29 '16 at 13:17
  • 3
    This will absolutely lead to memory leak. Ideally you should not use this process . – beginner Jul 18 '17 at 06:12
1

Use this in Activity:

private Context context = this;

........
if(Utils.isInternetAvailable(context){
Utils.showToast(context, "toast");
}
..........

in Utils:

public class Utils {

    public static boolean isInternetAvailable(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected();
    }

}
dimvolk
  • 338
  • 3
  • 9
0

I don't know if this will help, but I did this:

LocationManager locationManager  = (LocationManager) context.getSystemService(context.LOCATION_SERVICE);
Melquiades
  • 8,496
  • 1
  • 31
  • 46
Ruchir Baronia
  • 7,406
  • 5
  • 48
  • 83
0

For some non-activity classes, like Worker, you're already given a Context object in the public constructor.

Worker(Context context, WorkerParameters workerParams)

You can just use that, e.g., save it to a private Context variable in the class (say, mContext), and then, for example

mContext.getSystenService(Context.ACTIVITY_SERVICE)
auspicious99
  • 3,902
  • 1
  • 44
  • 58
0

If you want to get it in a fragment this would work in kotlin:

requireActivity().getSystemService(LOCATION_SERVICE) as LocationManager
Ivan Lopes
  • 148
  • 3
  • 12