2

I'm trying to call a method from a Listener-class, but even if I declare an object for the class, it throws nullpointexception. I don't really understand why really.

I tried with sending a parameter to the method, but that didn't work neither.

The error I receive is due to the call in method checkGpsStat():

LocationServices.getSettingsClient(MainActivity.this).checkLocationSettings(builder.build())

Error:

Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference

CLASS: - LocationReceiver

public class LocationReceiver extends BroadcastReceiver {

    private static final String TAG = "LocationReceiver";
    private Context mContext;
    private Snackbar snackbar;
    private MainActivity mActicity = new MainActivity();

    public LocationReceiver(Context context, Snackbar snackbar){
        this.mContext = context;
        this.snackbar = snackbar;

    }

    @Override
    public void onReceive(Context context, Intent intent) {

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

        if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
            boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            boolean networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
            if(gpsEnabled && networkEnabled) {
                if (snackbar != null) {
                    snackbar.dismiss();
                }
                Log.d(TAG, "GPS enabled");
            } else {

                View view = snackbar.getView();
                FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)view.getLayoutParams();
                params.gravity = Gravity.TOP;
                view.setLayoutParams(params);
                view.setBackgroundColor(Color.parseColor("#123123"));
                snackbar.show();

                mActicity.checkGpsState(); // This call causes crash!

                Log.d(TAG, "GPS disabled");
            }
        }

    }

METHOD: - checkGpsState()

public void checkGpsState(){

        Log.d(TAG,"checkGpsState started...");

        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);

        // Below code is where the error is firing from! "mainactivity.this". 
        Task<LocationSettingsResponse> result =
                LocationServices.getSettingsClient(MainActivity.this).checkLocationSettings(builder.build());


        result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
            @Override
            public void onComplete(@NonNull Task<LocationSettingsResponse> task) {

                try {
                    LocationSettingsResponse response = task.getResult(ApiException.class);
                    // All location settings are satisfied. The client can initialize location
                    // requests here.

                    createLocationRequest();        // Start updating location!

                } catch (ApiException exception) {
                    switch (exception.getStatusCode()) {
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            // Location settings are not satisfied. But could be fixed by showing the
                            // user a dialog.
                            try {
                                // Cast to a resolvable exception.
                                ResolvableApiException resolvable = (ResolvableApiException) exception;
                                // Show the dialog by calling startResolutionForResult(),
                                // and check the result in onActivityResult().
                                resolvable.startResolutionForResult(
                                        MainActivity.this,
                                        LocationRequest.PRIORITY_HIGH_ACCURACY);


                            } catch (IntentSender.SendIntentException e) {
                                // Ignore the error.
                            } catch (ClassCastException e) {
                                // Ignore, should be an impossible error.
                            }
                            break;
                        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                            // Location settings are not satisfied. However, we have no way to fix the
                            // settings so we won't show the dialog.
                            break;
                    }
                }
            }
        });
    }
Gustavo Pagani
  • 6,583
  • 5
  • 40
  • 71
Rusben Wladiskoz
  • 523
  • 2
  • 9
  • 15
  • I got it to work by simply passing both context, AND activity, to the LocationListener. – Rusben Wladiskoz Jun 28 '19 at 23:25
  • Hi Rusben. It is best to add the complete solution to the answer below with an explanation. You can then accept your own answer. Best Regards. – Elletlar Jun 29 '19 at 00:07
  • @Elletlar Hi, ok I'll add it. Can you check it if there's a good solution or bad? It works, but I'm not sure if it's safe? – Rusben Wladiskoz Jun 29 '19 at 00:17
  • @Elletlar Now it's posted. Do you think this solution is safe? – Rusben Wladiskoz Jun 29 '19 at 00:26
  • Well...You have to be careful when holding an Activity reference. It can cause a memory leak in some cases and/or have a different lifecycle from the BroadcastReceiver. For best practises, I would follow the advice offered by Android author Mark Murphy: [Accessing an Activity in a BroadcastReceiver](https://stackoverflow.com/questions/43982396/accessing-main-activity-in-broadcast-reciever-without-using-intent) – Elletlar Jun 29 '19 at 00:41
  • 1
    Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – Gustavo Pagani Jun 29 '19 at 08:23
  • Sir try Null pointer exception.Use try catch block.write your code on try block and write NullPointerException in catch block. It will help to get output.. – Tarang Mishra Aug 18 '19 at 06:19
  • You shouldn't use a try-catch to catch NullPointerExceptions, you should avoid them by not dereferencing `null`. – Mark Rotteveel Aug 18 '19 at 06:52

1 Answers1

1

Wow, finally! I were able to solve this one. Very happy about this!

I'm not sure if this is the best solution, or if it's safe. But it works for me, and I hope it works for everybody else facing this problem.

So, here comes the solution! The numbers to the left in the code are the steps I implemented to get this to work. Hope it helps!

CLASS: - LocationReceiver

        public class LocationReceiver extends BroadcastReceiver {

        private static final String TAG = "LocationReceiver";
        private Context mContext;
        private Snackbar snackbar;
1       private MainActivity mainActivity;  // Declare activity object

        //NOTE: In the constructor, we pass the activity that fires for this listener, in this case MainActivity.

2        public LocationReceiver(Context context, MainActivity mActivity, Snackbar snackbar){  // Add activity to constructor parameter
            this.mContext = context;
            this.snackbar = snackbar;
3            mainActivity = mActivity;    // set activity with the passed activity.
        }

        @Override
        public void onReceive(Context context, Intent intent) {

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

            if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
                boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
                boolean networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
                if(gpsEnabled && networkEnabled) {
                    if (snackbar != null) {
                        snackbar.dismiss();
                    }
                    Log.d(TAG, "GPS is enabled");
                } else {

                    View view = snackbar.getView();
                    FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)view.getLayoutParams();
                    params.gravity = Gravity.TOP;
                    view.setLayoutParams(params);
                    view.setBackgroundColor(Color.parseColor("#123123"));
                    snackbar.show();

                    // If user turned off location, pass both context, AND activity to the method that handles the gps-dialog.

                    //MARK: - pass both context and activity that we receieved from constructor!
4                   mainActivity.checkGpsState(mContext, mainActivity); // Call method in another activity, pass both context and activity (both is for certain calls in the method in the other activity)

                    Log.d(TAG, "GPS is disabled");
                }
            }

        }
    }

METHOD: - checkGpsState()

    //checkGps
5    public void checkGpsState(Context mContext, Activity mActivity){  // Here we need to receive the parameter.

        Log.d(TAG,"checkGpsState started...");

        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);

        //MARK: - pass the context from parameter!
6        Task<LocationSettingsResponse> result =
                LocationServices.getSettingsClient(mContext).checkLocationSettings(builder.build());   // Here comes the usage of the context we passed as parameter!


        result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
            @Override
            public void onComplete(@NonNull Task<LocationSettingsResponse> task) {

                try {
                    LocationSettingsResponse response = task.getResult(ApiException.class);
                    // All location settings are satisfied. The client can initialize location
                    // requests here.

                    createLocationRequest();        // Start updating location!

                } catch (ApiException exception) {
                    switch (exception.getStatusCode()) {
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            // Location settings are not satisfied. But could be fixed by showing the
                            // user a dialog.
                            try {
                                // Cast to a resolvable exception.
                                ResolvableApiException resolvable = (ResolvableApiException) exception;
                                // Show the dialog by calling startResolutionForResult(),
                                // and check the result in onActivityResult().
                                // MARK: - Here we pass the activity from parameter!
7                               resolvable.startResolutionForResult(
                                        mActivity,
                                        LocationRequest.PRIORITY_HIGH_ACCURACY);  // And here comes the usage for the activity we passed as parameter


                            } catch (IntentSender.SendIntentException e) {
                                // Ignore the error.
                            } catch (ClassCastException e) {
                                // Ignore, should be an impossible error.
                            }
                            break;
                        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                            // Location settings are not satisfied. However, we have no way to fix the
                            // settings so we won't show the dialog.
                            break;
                    }
                }
            }
        });
    }
Rusben Wladiskoz
  • 523
  • 2
  • 9
  • 15