How can I use getSystemService in a non-activity class (LocationManager)?

Android

Android Problem Overview


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.

Any help would be greatly appreciated :)

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;
    }
}

Android Solutions


Solution 1 - Android

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);
    }
}

Solution 2 - Android

You can go for this :

getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);

Solution 3 - Android

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);

Solution 4 - Android

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();
    }

}

Solution 5 - Android

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

LocationManager locationManager  = (LocationManager) context.getSystemService(context.LOCATION_SERVICE);

Solution 6 - Android

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)

Solution 7 - Android

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

requireActivity().getSystemService(LOCATION_SERVICE) as LocationManager

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKevin ParkerView Question on Stackoverflow
Solution 1 - AndroidLabeeb PanampullanView Answer on Stackoverflow
Solution 2 - AndroidMaddyView Answer on Stackoverflow
Solution 3 - AndroidbrenjtView Answer on Stackoverflow
Solution 4 - AndroiddimvolkView Answer on Stackoverflow
Solution 5 - AndroidRuchir BaroniaView Answer on Stackoverflow
Solution 6 - Androidauspicious99View Answer on Stackoverflow
Solution 7 - AndroidIvan LopesView Answer on Stackoverflow