【问题标题】:Java/Android override methodsJava/Android 覆盖方法
【发布时间】:2014-09-28 05:50:36
【问题描述】:

我正在练习 Android 进行实习,我已经能够编写一个处理地理定位的类,以便我尝试找到最佳位置,并且每当调用 onLocationChanged 时我都会不断更新内容。

现在我需要使用我的位置在 GoogleMaps 上放置标记我显然可以从我的类处理地理定位中更改 onLocationChanged 方法,但我很想提取我需要在课堂外执行的操作,因为将来我可能会需要我当前的位置来执行很多不同的事情。

package com.example.soueuls.swipe;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

public class GeoLocation {
    private final Context context;
    private final LocationManager locationManager;
    private Location currentLocation;
    private int updateLimit = 0;
    private long timeLimit = 0;

    public GeoLocation(Context context) {
        this.context = context;
        this.locationManager = (LocationManager)this.context.getSystemService(Context.LOCATION_SERVICE);
        this.currentLocation = this.locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if (this.currentLocation == null) {
            this.currentLocation = this.locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        }
    }

    private LocationListener locationListener = new LocationListener() {

        @Override
        public void onLocationChanged(Location newLocation) {
            if (isBetterLocation(GeoLocation.this.currentLocation, newLocation)) {
                GeoLocation.this.currentLocation = newLocation;
            }

            if (--GeoLocation.this.updateLimit == 0) {
                GeoLocation.this.stopLocationUpdate();
            } else if (System.currentTimeMillis() / 1000 > GeoLocation.this.timeLimit) {
                GeoLocation.this.stopLocationUpdate();
            }
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {

        }

        @Override
        public void onProviderEnabled(String provider) {

        }

        @Override
        public void onProviderDisabled(String provider) {

        }
    };

    private boolean isBetterLocation(Location currentLocation, Location newLocation) {
        if (currentLocation == null) {
            return true;
        }

        int twoMinutes = 1000 * 60 * 2;

        long timeDelta = newLocation.getTime() - currentLocation.getTime();
        int accuracyDelta = (int) (newLocation.getAccuracy() - currentLocation.getAccuracy());

        boolean isSignificantlyNewer = timeDelta > twoMinutes;
        boolean isSignificantlyOlder = timeDelta < -twoMinutes;
        boolean isNewer = timeDelta > 0;

        if (isSignificantlyNewer) {
            return true;
        } else if (isSignificantlyOlder) {
            return false;
        }

        boolean isMoreAccurate = accuracyDelta < 0;
        boolean isLessAccurate = accuracyDelta > 0;
        boolean isSignificantlyLessAccurate = accuracyDelta > 200;
        boolean isFromSameProvider = isSameProvider(currentLocation.getProvider(), newLocation.getProvider());

        if (isMoreAccurate) {
            return true;
        } else if (isNewer && !isLessAccurate) {
            return true;
        } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
            return true;
        } else {
            return false;
        }
    }

    private boolean isSameProvider(String provider1, String provider2) {
        if (provider1 == null) {
            return provider2 == null;
        }
        return provider1.equals(provider2);
    }

    public void setUpdateLimit(int limit) {
        this.updateLimit = limit;
    }

    public void setTimeLimit(long limit) {
        this.timeLimit = System.currentTimeMillis() / 1000 + limit;
    }

    public void setLocationUpdate(String provider, int minTimeInterval, int minDistance) {
        this.locationManager.requestLocationUpdates(provider, minTimeInterval, minDistance, this.locationListener);
    }

    public void stopLocationUpdate() {
        this.locationManager.removeUpdates(this.locationListener);
    }

    public Location getCurrentLocation() {
        return this.currentLocation;
    }
}

这是 GeoLocation 类,我仍然需要在每次调用 onLocationChanged 时更新 this.currentLocation。

但我希望能够检测到何时调用 onLocationChanged 以在我的活动内部执行更新,该活动在此类之外。

我该怎么做?

编辑: 在我尝试听的活动的 onResume 方法中,我这样做了

GeolocationListener locationListener = new GeolocationAdapter() {
            @Override
            public void onLocationChanged(Location newLocation) {
                System.out.println("OHOHOH");
                displayWeatherInformation(weatherCache, geoLocation.getCurrentLocation());
            }
        };

【问题讨论】:

  • 你应该实现监听器模式。
  • 肯定是听众!我将发布一个示例。

标签: java android methods overriding


【解决方案1】:

使用监听器

您将接口添加到您的 Geolocation 类

public class GeoLocation {

添加您的听众

   // listeners
   private List<LocationListener> listeners = new ArrayList<LocationListener>();
   public void addListener(LocationListener l){
      listeners.add(l);
   }
   public void removeListener(LocationListener l){
      listeners.remove(l);
   }

然后在你的private LocationListener locationListener = new LocationListener() 里面放

    @Override
    public void onLocationChanged(Location newLocation) {
        if (isBetterLocation(GeoLocation.this.currentLocation, newLocation)) {
            GeoLocation.this.currentLocation = newLocation;
            for(LocationListener l:listeners){
                l.onLocationChanged(newLocation);
            }
        }
   ... the rest of the code

那么任何班级都可以注册以接收有关您的 Geolocation 班级的更新

编辑:

像这样声明你的活动:

public class MyActivity extends Activity implements LocationListener{

    @Override
    public void onResume(){
        geoLocation.addListener(this);
    }

    @Override     
    public void onPause(){
        geoLocation.removeListener(this);
    }

    @Override
    public void onLocationChanged(Location newLocation) {

    }

}

【讨论】:

  • 我在注册地理定位课程时遇到了一些困难。我将用我正在做的事情更新我的初始帖子。
  • 而不是创建一个new,你应该像这样声明活动:public class MyActivity extends Activity implements LocationListener,然后你在活动中编写方法onLocationChanged(Location)和onResume/onPause你必须调用geoLocation.addListener(this);geoLocation.removeListener(this);
  • 请看我的编辑。不要问你如何获得对geolocation 的引用,这是一个不同的问题,答案是Singleton
【解决方案2】:

您可以使用观察者模式 - 活动在 onResume() 中使用 GeoLocation 类注册自身以接收更新,并在 onPause() 中取消注册。

网上有很多学习观察者模式的资料-http://en.wikipedia.org/wiki/Observer_pattern

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-30
    • 2018-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多