私はクラスLocationFinder
を作成してユーザの場所を取得しました。インターフェイスへのキャストアクティビティコンテキストがClassCastExceptionをスローする
私は、クラスとクラスをインスタンス化し、必要なメソッドを呼び出して場所を取得します。
LocationFinder
クラスの場所が見つかった後、MainActivity
と通信して、一部のTextViewでユーザーの場所を更新できるようにしたいと思います。
そうするために、私はこの行っている:
私LocationFinder
クラスのコンストラクタは次のようになります。で、この後
public interface OnLocationFoundListener
{
void setOnLocationFoundListener(String cityName, String stateName, String countryName);
}
:OnLocationFoundListener
はインタフェースのようなものです
private Context context;
private OnLocationFoundListener onLocationFoundListener;
public LocationFinder(Context context) {
this.context = context;
onLocationFoundListener = (OnLocationFoundListener) context; // here is the exception is thrown
}
成功した場所が見つかりましたを実装しているMainActivity
に通知するのにonLocationFoundListener.setOnLocationFoundListener(cityName, stateName, countryName);
を使用しています必要なメソッドをオーバーライドします。
サンプルコードは、次のとおり
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);
}
}
MainActivity:
public class MainActivity extends AppCompatActivity implements LocationFinder.OnLocationFoundListener {
Button getCurrentLocation;
TextView locationTextview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getCurrentLocation = (Button) findViewById(R.id.getCurrentCity);
locationTextview = (TextView) findViewById(R.id.current_city);
LocationFinder locationFinder = new LocationFinder(getApplicationContext());
locationFinder.getCityByLocation();
}
@Override
public void setOnLocationFoundListener(String cityName, String stateName, String countryName) {
locationTextview.setText("City : "+cityName+", "+"\nState : "+stateName+", "+"\nCountry : "+countryName);
}
}
Logcat:
Process: com.amitupadhyay.citybasedlocation, PID: 18474 java.lang.RuntimeException: Unable to start activity
ComponentInfo {com.amitupadhyay.citybasedlocation/com.amitupadhyay.citybasedlocation.MainActivity}: とjava.lang.ClassCastException:android.app.Applicationをキャストすることはできません にcom.amitupadhyay.citybasedlocation.LocationFinder $ OnLocationFoundListener アンドロイドで。 アンドロイドでandroid.app.ActivityThread.access $ 900からapp.ActivityThread.performLaunchActivity android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2523)で(ActivityThread.java:2456) (ActivityThread.java:168) .app.ActivityThread $ H.handleMessage(ActivityThread.java:1373)アンドロイド.os.Handler.dispatchMessageの(Handler.java:102)android.os.Looper.loop(Looper.java:148)の とandroid.app.ActivityThread.main(ActivityThread.java:5609) at java.lang.reflect.Method.invoke(ネイティブメソッド) com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:797) at com.android.internal.os.ZygoteInit.main ZygoteInit.java:687) 原因:java.lang.ClassCastException:android.app.Application はキャストできません com.amitupadhyay.citybasedlocation.LocationFinder $ OnLocationFoundListener at com.amitupadhyay.citybasedlocation.LocationFinder。(LocationFinder。Javaの:38) android.app.Instrumentation.callActivityOnCreateでandroid.app.Activity.performCreateで com.amitupadhyay.citybasedlocation.MainActivity.onCreate(MainActivity.java:21) (Activity.java:6307) (でandroid.app.ActivityThread.access $ 900からInstrumentation.java:1118) でandroid.app.ActivityThread.performLaunchActivity(ActivityThread.java:2409) でandroid.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2523) (ActivityThread.java:168) at android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1373)android.os.Handler.dispatchMessage(Handler.java:102)の とandroid.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5609) at java.lang.reflect.Method.invoke(ネイティブメソッド) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java: com.android.internal.os.ZygoteInit.mainで797) (ZygoteInit.java:687)
私には分かりません。なぜこれは起こっているのですか?
例外を追加してください。 – Jens
投稿してください。 –
あなたはアプリケーションではなくアクティビティコンテキストを使用してください –