Android java.lang.AbstractMethodError on requestLocationUpdates
Asked Answered
F

2

4

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'
}
Frederigo answered 13/1, 2021 at 10:35 Comment(3)
That might be a version conflict, i.e. you might be using a library that has an implementation of LocationListener but that isn't implementing that abstract method because it has been compiled using a different version of the Android SDK than you're running you app on atm.Shopworn
Have a look here on what that AbstractMethodError generally means in Java: baeldung.com/java-abstractmethoderrorShopworn
i have read the post. The thing is that if you see the link on the top of my question i mention another post where it says that there are some un-implemented methods. As the error suggests and the article from baeldung, it makes sense. But when i try to implement these methods i just cannot ! Nowhere in my two classesFrederigo
F
4

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

Frederigo answered 20/1, 2021 at 9:55 Comment(1)
Why even need to override if source is compiled against compileSdkVersion 30 ?Bhutan
P
0

override the methods in your code

...

override fun onProviderDisabled(provider: String) {}
override fun onProviderEnabled(provider: String) {}
override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {}
...
Piscatelli answered 10/9, 2021 at 5:19 Comment(1)
Pretty much. If anyone is using Kotlin, don't forget to remove the super calls, or else your default empty implementations will be redundant.Mentality

© 2022 - 2024 — McMap. All rights reserved.