2017-03-16 2 views
0

Ich habe eine Klasse LocationFinder gemacht, die den Standort des Benutzers erhält.Casting-Aktivität Kontext zu einer Schnittstelle wirft ClassCastException

Ich bin instanziieren die Klasse und Klasse und Aufruf erforderlichen Methoden, um den Speicherort zu erhalten.

Jetzt, nachdem der Standort in LocationFinder Klasse gefunden wurde, möchte ich mit meinem MainActivity kommunizieren, so dass ich den Standort des Benutzers auf einigen TextView aktualisieren kann.

Der Konstruktor meiner LocationFinder Klasse wie folgt aussieht::

Um dies zu tun, ich habe dies getan

private Context context; 
private OnLocationFoundListener onLocationFoundListener; 

public LocationFinder(Context context) { 
    this.context = context; 
    onLocationFoundListener = (OnLocationFoundListener) context; // here is the exception is thrown 
} 

Wo OnLocationFoundListener eine Schnittstelle wie ist:

public interface OnLocationFoundListener 
{ 
    void setOnLocationFoundListener(String cityName, String stateName, String countryName); 
} 

Danach auf erfolgreicher Standort gefunden Ich verwende onLocationFoundListener.setOnLocationFoundListener(cityName, stateName, countryName);, um die MainActivity zu benachrichtigen, wo ich dieimplementiereund Überschreiben der erforderlichen Methode.

Das Codebeispiel ist:

Die LocationFinder Klasse:

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); 
    } 
} 

Die 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 nicht zu com.amitupadhyay.citybasedlocation.LocationFinder $ OnLocationFoundListener bei android gegossen werden. app.ActivityThread.performLaunchActivity (ActivityThread.java:2456) bei android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2523) bei android.app.ActivityThread.access $ 900 (ActivityThread.java:168) bei android .app.ActivityThread $ H.handleMessage (ActivityThread.java:1373) bei android.os.Handler.dispatchMessage (Handler.java:102) bei android.os.Looper.loop (Looper.java:148) bei android.app.ActivityThread.main (ActivityThread.java:5609) bei java.lang.reflect.Method.invoke (Native Methode) um com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:797) bei com.android.internal.os.ZygoteInit.main (ZygoteInit.java:687) verursacht durch: java.lang.ClassCastException: android.app.Application nicht gegossen werden kann com.amitupadhyay.citybasedlocation.LocationFinder $ OnLocationFoundListener um com.amitupadhyay.citybasedlocation.LocationFinder. (LocationFinder.Java: 38) bei com.amitupadhyay.citybasedlocation.MainActivity.onCreate (MainActivity.java:21) bei android.app.Activity.performCreate (Activity.java:6307) bei android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1118) bei android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2409) bei android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2523) bei android.app.ActivityThread.access $ 900 (ActivityThread.java:168) bei android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1373) bei android.os.Handler.dispatchMessage (Handler.java:102) bei android.os.Looper.loop (Looper.java:148) bei android.app.ActivityThread.main (ActivityThread.java:5609) bei java.lang.reflect.Method.invoke (Mutter Methode) bei com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java: 797) bei com.android.internal.os.ZygoteInit.main (ZygoteInit.java:687)

I under nicht Warum passiert das?

+0

Fügen Sie die Ausnahme bitte – Jens

+1

Post logcat bitte –

+0

u haben Aktivität Kontext zu verwenden, nicht Anwendung –

Antwort

2

versuchen, dies als Kontext statt Anwendungskontext übergeben.

LocationFinder locationFinder = new LocationFinder(this); 
      locationFinder.getCityByLocation(); 

EDIT Das ist genau das, was Ihr logcat sagt. Sie versuchen, einen Anwendungskontext an die Aktivität zu übergeben.

0

sollten Sie ändern OnLocationFoundListenerContext Parameter in Konstruktor mit OnLocationFoundListener

public LocationFinder(OnLocationFoundListener context) { 
    this.context = context; 
    onLocationFoundListener = context; // here is the exception is thrown 
} 

Und Sie sollten

MainActvity.this. 



LocationFinder locationFinder = new LocationFinder(MainActvity.this); 
1

ändern es wie folgt,

public LocationFinder(Context context, OnLocationFoundListener listener) { 
     this.context = context; 
     onLocationFoundListener = listener; 
} 

Und von Aktivität passieren, initiieren sie so,

LocationFinder locationFinder = new LocationFinder(getApplicationContext(), this); 
Verwandte Themen