Java 将活动上下文强制转换到接口会引发ClassCastException
我制作了一个类Java 将活动上下文强制转换到接口会引发ClassCastException,java,android,classcastexception,Java,Android,Classcastexception,我制作了一个类LocationFinder,用于获取用户的位置 我正在实例化类和类,并调用所需的方法来获取位置 现在,在LocationFinder类中找到位置后,我想与我的MainActivity通信,以便在某些文本视图上更新用户的位置 为此,我做了以下工作: myLocationFinder类的构造函数如下所示: private Context context; private OnLocationFoundListener onLocationFoundListener; public
LocationFinder
,用于获取用户的位置
我正在实例化类和类,并调用所需的方法来获取位置
现在,在LocationFinder
类中找到位置后,我想与我的MainActivity
通信,以便在某些文本视图上更新用户的位置
为此,我做了以下工作:
myLocationFinder
类的构造函数如下所示:
private Context context;
private OnLocationFoundListener onLocationFoundListener;
public LocationFinder(Context context) {
this.context = context;
onLocationFoundListener = (OnLocationFoundListener) context; // here is the exception is thrown
}
其中,OnLocationFoundListener
是一个类似于:
public interface OnLocationFoundListener
{
void setOnLocationFoundListener(String cityName, String stateName, String countryName);
}
在成功找到位置后,我使用的是onLocationFoundListener.setOnLocationFoundListener(cityName、stateName、countryName)
通知main活动
,我正在执行OnLocationFoundListener
并重写所需的方法
代码示例为:
LocationFinder
类:
public class LocationFinder implements LocationListener {
private Context context;
private OnLocationFoundListener onLocationFoundListener;
public LocationFinder(Context context) {
this.context = context;
onLocationFoundListener = (OnLocationFoundListener) context;
}
private static final int MY_PERMISSIONS_ACCESS_FINE_LOCATION = 1;
private LocationManager locationManager;
private ProgressDialog progressDialog;
void getCityByLocation() {
locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity)context,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Explanation not needed, since user requests this himself
} else {
ActivityCompat.requestPermissions((Activity)context,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_ACCESS_FINE_LOCATION);
}
} else if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) ||
locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
progressDialog = new ProgressDialog(context);
progressDialog.setMessage(context.getString(R.string.getting_location));
progressDialog.setCancelable(false);
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
try {
locationManager.removeUpdates(LocationFinder.this);
} catch (SecurityException e) {
e.printStackTrace();
}
}
});
progressDialog.show();
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
}
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
} else {
showLocationSettingsDialog();
}
}
@Override
public void onLocationChanged(Location location) {
progressDialog.hide();
try {
locationManager.removeUpdates(this);
} catch (SecurityException e) {
Log.e("LocationManager", "Error while trying to stop listening for location updates. This is probably a permissions issue", e);
}
Log.i("LOCATION (" + location.getProvider().toUpperCase() + ")", location.getLatitude() + ", " + location.getLongitude());
double latitude = location.getLatitude();
double longitude = location.getLongitude();
getCityDetails(latitude, longitude);
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
private void getCityDetails(double lat, double lon)
{
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(lat, lon, 1);
} catch (IOException e) {
e.printStackTrace();
}
String cityName = addresses.get(0).getAddressLine(0);
String stateName = addresses.get(0).getAddressLine(1);
String countryName = addresses.get(0).getAddressLine(2);
progressDialog.dismiss();
onLocationFoundListener.setOnLocationFoundListener(cityName, stateName, countryName);
}
private void showLocationSettingsDialog() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
alertDialog.setTitle(R.string.location_settings);
alertDialog.setMessage(R.string.location_settings_message);
alertDialog.setPositiveButton(R.string.location_settings_button, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(intent);
}
});
alertDialog.setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog.show();
}
public interface OnLocationFoundListener
{
void setOnLocationFoundListener(String cityName, String stateName, String countryName);
}
}
日志:
ComponentInfo{com.amitupadhyay.citybasedlocation/com.amitupadhyay.citybasedlocation.MainActivity}:
java.lang.ClassCastException:android.app.Application无法强制转换
到
com.amitupadhayay.citybasedlocation.LocationFinder$OnLocationFoundListener
在
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2456)
在
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2523)
在android.app.ActivityThread.access$900(ActivityThread.java:168)
在
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1373)
位于android.os.Handler.dispatchMessage(Handler.java:102)
位于android.os.Looper.loop(Looper.java:148)
位于android.app.ActivityThread.main(ActivityThread.java:5609)
位于java.lang.reflect.Method.invoke(本机方法)
在
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
原因:java.lang.ClassCastException:android.app.Application
不能投靠
com.amitupadhayay.citybasedlocation.LocationFinder$OnLocationFoundListener
在
com.amitupadhayay.citybasedlocation.LocationFinder.(LocationFinder.java:38)
在
com.amitupadhyay.citybasedlocation.MainActivity.onCreate(MainActivity.java:21)
位于android.app.Activity.performCreate(Activity.java:6307)
在
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
在
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2409)
在
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2523)
在android.app.ActivityThread.access$900(ActivityThread.java:168)
在
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1373)
位于android.os.Handler.dispatchMessage(Handler.java:102)
位于android.os.Looper.loop(Looper.java:148)
位于android.app.ActivityThread.main(ActivityThread.java:5609)
位于java.lang.reflect.Method.invoke(本机方法)
在
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
我不明白为什么会发生这种情况?尝试将其作为上下文而不是应用程序上下文传递
LocationFinder locationFinder = new LocationFinder(this);
locationFinder.getCityByLocation();
编辑这正是日志猫所说的。您正在尝试将应用程序上下文传递给活动。您应该使用
OnLocationFoundListener
更改构造函数中的OnLocationFoundListener
上下文参数
public LocationFinder(OnLocationFoundListener context) {
this.context = context;
onLocationFoundListener = context; // here is the exception is thrown
}
你应该通过
MainActvity.this.
LocationFinder locationFinder = new LocationFinder(MainActvity.this);
像下面这样改变它
public LocationFinder(Context context, OnLocationFoundListener listener) {
this.context = context;
onLocationFoundListener = listener;
}
从活动开始,像这样开始
LocationFinder locationFinder = new LocationFinder(getApplicationContext(), this);
添加异常pleasepost logcat Please必须使用活动上下文,而不是ap
public LocationFinder(Context context, OnLocationFoundListener listener) {
this.context = context;
onLocationFoundListener = listener;
}
LocationFinder locationFinder = new LocationFinder(getApplicationContext(), this);