Bahamit Bahamit - 3 months ago 8
Android Question

Android app modulization (classes)

thank you for taking the time to load my post and view my question.

For the longest time I have been creating long android activities just because I didn't quite understand classes and how they worked. Earlier this week, I learned how easy it is to send information between methods. Today, I am struggling to send information between classes. Instead of having one very long page of code to sift through, I want to break it down into chunks, and have the information reference and interact with eachother. This way it is easier to keep my code organized and faster to make changes. I have tried to remove two separate classes from my main thread and created them in the same directory, the code shows no errors so they should execute just fine. However, I am messing up somewhere with the context. I don't fully grasp the concept of context either. I have one class to get my phones location, and another class to upload to my server. Both these classes return null values when trying to be executed. However, when it was all stream-lined on one main activity, there was no null errors. I have been reading context is the issue here.

I have referenced the other classes from my mainthread like this:

LocationClass LocationClass;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mapfrag);
LocationClass = new LocationClass();


@Override
public void onMapReady(GoogleMap googleMap) {
Map = googleMap;
Map.setOnMapClickListener(this);
Map.setOnMapLongClickListener(this);
Map.setMapType(1);
Map.setOnMarkerClickListener(this);
LocationClass.GETLOCATION();
}


and my location class looks like this:

public class LocationClass extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
private Location mLastLocation;
private GoogleApiClient mGoogleApiClient;
public LatLng reallifelocation;
public static final String userdata = "userdata";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (checkPlayServices()) {
buildGoogleApiClient();
}
check_perms();
}


and then it checks the permissions and does what it has to to get the location. This code is all tested and working from the main thread, I'm just trying to create my own class for it

error:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:112)
at biz.tanners.geo_x.LocationClass.GETLOCATION(LocationClass.java:49)


where the error sits(LocationClass.java):

public void GETLOCATION() {
if (ActivityCompat.checkSelfPermission(this.getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {return;}
final SharedPreferences prefs = getSharedPreferences(userdata, MODE_PRIVATE);
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
reallifelocation = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
}
//add to prefs or offline db
}

Answer

Your error stems from here

 if (ActivityCompat.checkSelfPermission(
    this.getApplicationContext(), 
        android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
     return;
}

Here this probably should correspond to the Context and being another class, the context is different.

A quick fix would be to pass the Activity's context as a parameter to the LocationClass's object. By adding it in the constructor and assigning it to the right variable, which later you could use instead of this.

Hope this helps.