Android java.lang.AbstractMethodError on requestLocationUpdates

Tags: , , ,



i get this error java.lang.AbstractMethodError: abstract method "void android.location.LocationListener.onProviderDisabled(java.lang.String)

when i call locationManager.requestLocationUpdates(). I saw another post where the answer was to override some methods i.e.

 @Override
public void onProviderDisabled(@NonNull String provider) {}

But the thing is i cannot override them anywhere in my project.

I have simplified the code in order to help the readers and instead of two classes i have one

MainActivity:

public class MainActivity extends AppCompatActivity {
    LocationManager locationManager;
    LocationListener  locationListener = location -> Toast.makeText(MainActivity.this,location.getLatitude()+" "+location.getLongitude(),Toast.LENGTH_LONG).show();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        findViewById(R.id.button).setOnClickListener(v -> showLoc());

        findViewById(R.id.button2).setOnClickListener(v -> locationManager.removeUpdates(locationListener));

    }
    private void showLoc(){
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 13);
            return;
        }
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 2, locationListener);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 13) {
            for (int i = 0; i < permissions.length; i++) {
                if (permissions[i].equals(Manifest.permission.ACCESS_FINE_LOCATION) && grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                    System.out.println("DEBUG Request Permissions ");
                    showLoc();
                }
            }
        }
    }
}

The exception is thrown at locationManager.requestLocationUpdates and has something to do with library version.

And lastly this is my build.gradle(app)

plugins {
    id 'com.android.application'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"

    defaultConfig {
        applicationId "com.example.app"
        minSdkVersion 25
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

Answer

Found the solution. After android 10(Q) you won’t need lot’s of the the unimplemented methods of LocationListener like onProviderDisabled.

But most of our apps have high “margin” of backwards compatibility supporting much older Android versions so you will need to override these ones.

So in order to implement these we can do this by two approaches:

First solution is creating a new LocationListener as a variable and implement these methods straight away

locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new LocationListener() {
            @Override
            public void onLocationChanged(@NonNull Location location) {
                System.out.println("DEBUG 1");
                Toast.makeText(MainActivity.this,location.getLatitude()+" "+location.getLongitude(),Toast.LENGTH_LONG).show();
            }

            @Override
            public void onProviderEnabled(@NonNull String provider) {
                System.out.println("DEBUG 2");
                Toast.makeText(MainActivity.this,"onProviderEnabled",Toast.LENGTH_LONG).show();
            }

            @Override
            public void onProviderDisabled(@NonNull String provider) {
                System.out.println("DEBUG 3");
                Toast.makeText(MainActivity.this,"onProviderDisabled",Toast.LENGTH_LONG).show();
            }

            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {
                System.out.println("DEBUG 4");
                Toast.makeText(MainActivity.this,"onStatusChanged",Toast.LENGTH_LONG).show();

            }
        };
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0.5f, locationListener);

A Second approach is to implement LocationListener in your class and implement these methods

public class MainActivity extends AppCompatActivity implements LocationListener

And now you must implement the methods

    @Override
    public void onLocationChanged(@NonNull Location location) {

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(@NonNull String provider) {

    }

    @Override
    public void onProviderDisabled(@NonNull String provider) {

    }

And your LocationListener is your own class

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0.5f, this);

Last thing to take in mind is that even tho public void onStatusChanged(String provider, int status, Bundle extras) {} is deprecated you SHOULD implement because as i said Android phones that use Android 9 or lower are going to trigger that method when taking location updates with locationManager.requestLocationUpdates



Source: stackoverflow