【问题标题】:How to get location when it changes位置变化时如何获取位置
【发布时间】:2014-01-23 03:48:21
【问题描述】:

我想知道如果位置发生变化,是否有办法获取位置?我知道android提供了这个http://developer.android.com/training/location/receive-location-updates.html 获取位置更新,正如它所说:

“如果您的应用程序进行导航或跟踪,您可能希望定期获取用户的位置。虽然您可以使用 LocationClient.getLastLocation() 执行此操作,但更直接的方法是从位置服务请求定期更新。在作为响应,定位服务会根据当前可用的位置提供程序(如 WiFi 和 GPS)自动使用最佳可用位置更新您的应用。”

如何在不使用定期间隔的情况下做到这一点?主要目标是最小化功耗。例如,如果我在房间里坐着,就不会改变位置。如果我开始移动,它应该报告位置变化。

如果只是更新,我确实需要获取位置,所以不需要经常更新。

该方法应在后台连续运行,并以节能的方式提供所有位置更新。

我在这里找到了 android fused location API https://developer.android.com/google/play-services/location.html

用这个怎么样?

我可以在不使用定期间隔的情况下实现它吗?

【问题讨论】:

  • 您可以在后台使用服务

标签: android android-location


【解决方案1】:
 protected void updateNotification() {
         LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
         LocationListener locationListener = new MyLocationlistener();

         lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, normallocationwait, 0.250f, locationListener);
         location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
   }

   private class MyLocationlistener implements LocationListener {

     public void onLocationChanged(Location location){
         if(location!=null){
             if(location.hasAccuracy()){
                   dumpLocation(location);
             }else{
                   dumpLocation(location);
            }
         } 
     }

     public void onProviderDisabled(String provider){
         Log.v("Loc Update","\nProvider disabled: " + provider);
     }

     public void onProviderEnabled(String provider){
         Log.v("Loc Update","\nProvider enabled: " + provider);
     }

     public void onStatusChanged(String provider, int status, Bundle extras){
         Log.v("Loc Update","\nProvider status changed: " + provider + ", status="
                    + status + ", extras=" + extras);
     }

【讨论】:

  • 您的代码获得“LastKnownLocation”,对吗?但如果 GPS 信号不可用怎么办?
  • 你能解释一下“normallocationwait”吗?
  • LastKnownLocation 方法是否获取每个位置更改?我需要及时捕捉到每个位置的变化吗?
  • onLocationChanged(Location location) 为您提供位置变化
  • 我需要不断地获取位置变化。当我实现您的代码时,它会更改位置,但是当我单击活动中的按钮时。要让服务捕获所有位置变化,该怎么做?
【解决方案2】:
// try this way
// declaration
public static LocationManager mlocManager;
public static LocationListner mListner;
private static String latitude;
public static String longitude;

//initialization
try {
    if (mlocManager == null)
            mlocManager = (LocationManager) getSystemService(Activity.LOCATION_SERVICE);
    if (mListner == null)
            mListner = new LocationListner();
            runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    try {
                        try {
                            mlocManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, mListner);
                        } catch (Throwable e) {
                            e.printStackTrace();
                        }

                        mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mListner);
                    } catch (Throwable e) {
                        e.printStackTrace();
                    }
                    try {
                        mlocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mListner);
                    } catch (Throwable e) {
                        e.printStackTrace();
                    }

                }
            });
} catch (Throwable e) {
    e.printStackTrace();
}

//listener
class LocationListner implements LocationListener {

        @Override
        public void onLocationChanged(Location location) {
            setLatitude("" + location.getLatitude());
            setLongitude("" + location.getLongitude());
            setCurrentLocation(location);
        }

        @Override
        public void onProviderDisabled(String provider) {
        }

        @Override
        public void onProviderEnabled(String provider) {
        }

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

}
// Setter
public void setLatitude(String latitide) {
    this.latitude = latitide;
}
// Getter
public String getLatitude() {

    try {
        if (latitude != null) {
            return latitude;
        }
        if(mlocManager==null)
        {
            mlocManager = (LocationManager) getSystemService(Activity.LOCATION_SERVICE);
        }
        Location loc = mlocManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if (loc == null) {
            loc = mlocManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            if (loc == null) {
                loc = mlocManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
            }
            if (loc != null) {
                    return "" + loc.getLatitude();
            }
            } else {
                    return "" + loc.getLatitude();
            }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "0";
}
  // Setter
public void setLongitude(String longitude) {
    this.longitude = longitude;
}
// Getter
public String getLongitude() {
    try {
        if (longitude != null) {
            return longitude;
        }
        if(mlocManager==null)
        {
            mlocManager = (LocationManager) getSystemService(Activity.LOCATION_SERVICE);
        }
        Location loc = mlocManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if (loc == null) {
            loc = mlocManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            if (loc == null) {
                loc = mlocManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
            }
            if (loc != null) {
                return "" + loc.getLongitude();
            }
            } else {
                return "" + loc.getLongitude();
            }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "0";
}

【讨论】:

  • 这是一种省电的方式吗?
  • 你的方法和android的fused api有什么区别?我猜两者都在寻找可用的传感器来获取位置,那么有什么区别?
【解决方案3】:

我已经多次搜索这篇文章了!我发现了类似的东西,但它不是很准确,虽然这个策略可能对你有帮助,但我没有发现任何有用的东西,除非朋友给你的其他答案,所以这就是我使用它的方法,它叫做PhoneStateListener

首先你需要添加权限:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
public class LocationService extends PhoneStateListener {
    private TelephonyManager telephonyManager;
    private boolean isLocationChanged;

    public LocationService(Context context) {
        telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

        if (telephonyManager != null){
            isLocationChanged= telephonyManager.isNetworkRoaming();
            telephonyManager.listen(this,PhoneStateListener.LISTEN_CELL_LOCATION);
        }
    }

    public boolean locationChanged(){
        return isLocationChanged;
    }

    void unregisterListener(){
        telephonyManager.listen(this,PhoneStateListener.LISTEN_NONE);
    }

    @Override
    public void onCellLocationChanged(CellLocation location) {
        if (location != null){
            isLocationChanged = true;
        }
    }
}

documentations

监听器类,用于监视设备上特定电话状态的变化,包括服务状态、信号强度、消息等待指示器(语音邮件)等。

覆盖您希望接收更新的状态的方法,并将您的 PhoneStateListener 对象以及 LISTEN_ 标志的按位或传递给TelephonyManager#listen。当状态改变时调用方法,以及在初始注册时调用一次。

我还不确定它是否有效,所以请告诉我它是否适合您! :)

这是另一个例子:Add PhoneStateListener

【讨论】:

    【解决方案4】:

    这种方法需要GooglePlayService,而且不需要太多的电量,或许你可以试试。

    private LocationClient locationClient;
    private static final int LOCATION_UPDATES_INTERVAL = 10000;
    private static final int LOCATION_NUM_UPDATES = 5;
    
    public void startLocationUpdate() {
        if (!(locationClient.isConnected() || locationClient.isConnecting())) {
            locationClient.connect(); // Somehow it becomes connected here
            return;
        }
        // Request for location updates
        LocationRequest request = LocationRequest.create();
        request.setInterval(LOCATION_UPDATES_INTERVAL);
        request.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        request.setNumUpdates(LOCATION_NUM_UPDATES);
        locationClient.requestLocationUpdates(request, this);
    }
    

    并且在 Activity 中你应该实现以下回调

    private Location mLastLocation;
        @Override
    public void onLocationChanged(Location location) {
        if (location == null) {
            Log.v(TAG, "onLocationChanged: location == null");
            return;
        }
    
        if (mLastLocation != null &&
                mLastLocation.getLatitude() == location.getLatitude() &&
                mLastLocation.getLongitude() == location.getLongitude()) {
            return;
        }
        LogUtil.i(TAG, "LocationChanged == @" +
                location.getLatitude() + "," + location.getLongitude());
        mLastLocation = location;
    }
    

    【讨论】:

    • 您使用了融合位置 API,它仍然使用 LOCATION_UPDATES_INTERVAL。不使用间隔会更好吗?
    • 您以 10 秒的间隔获得该位置 5 次。那么,它停止了吗?或者会发生什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多