2017-03-16 5 views
0

私はクラス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)

私には分かりません。なぜこれは起こっているのですか?

+0

例外を追加してください。 – Jens

+1

投稿してください。 –

+0

あなたはアプリケーションではなくアクティビティコンテキストを使用してください –

答えて

2

これをアプリケーションコンテキストの代わりにコンテキストとして渡してみてください。あなたのlogcatが言うまさにある

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

EDIT。アプリケーションコンテキストをアクティビティに渡そうとしています。

0

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

と活動から

は、それを開始し、あなたは OnLocationFoundListener

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

でコンストラクタでOnLocationFoundListenerContextパラメータを変更する必要があり、あなたは、次のような

MainActvity.this. 



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

変更、それを渡す必要がありますこのように、

LocationFinder locationFinder = new LocationFinder(getApplicationContext(), this); 
関連する問題