问题
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'
}
回答1:
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
来源:https://stackoverflow.com/questions/65700139/android-java-lang-abstractmethoderror-on-requestlocationupdates