【问题标题】:Creating a blank location object创建空白位置对象
【发布时间】:2010-11-05 18:56:00
【问题描述】:

我和其他几个人正在开发一个适用于 Android 的应用程序。它需要在纬度和经度上定位设备。我们已经能够创建一个位置对象,但该对象始终是空白的。我们甚至尝试在一个完全空的项目中重新创建代码,但这也失败了。这是我们的根活动:

package com.app.Locationtest;

import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;

public class locationtest extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        LocationManager locman =(LocationManager)getSystemService(Context.LOCATION_SERVICE); 
        Location loc = locman.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if (loc==null)
        {
           finish();
        }
    }
}

这是清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.app.Locationtest"
      android:versionCode="1"
      android:versionName="1.0">
      <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
      <uses-permission android:name="android.permission.ACCESS_GPS" />
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".locationtest"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
    <uses-sdk android:minSdkVersion="8" />

</manifest> 

我们如何解决这个问题?

【问题讨论】:

    标签: android location latitude-longitude locationmanager


    【解决方案1】:

    getLastKnownLocation() javadoc 说:“.. 如果提供程序当前被禁用,则返回 null。”

    所以它依赖于 GPS,但它并没有打开它。它用于搭载使用 GPS 的其他应用程序。

    【讨论】:

    • 那么,我们应该改用什么?
    • 取决于您的应用程序的要求。您需要准确的位置吗?总是或只是有时?您是否经常记录位置但不需要很高的准确性?你应该阅读这个developer.android.com/guide/topics/location/…
    • 那么,我们必须使用LocationProvider吗?我们希望得到非常好的结果,但我们只需要一次。
    • 你必须实现LocationListener并用LocationManager注册:locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener)
    • 我们只需要一次经度和纬度。之后的数据我们真的没用了。
    【解决方案2】:

    有时设备需要太多时间来检索位置,这是检索android site上列出的位置的流程:

    1. 启动应用程序。
    2. 稍后,开始监听来自所需位置提供商的更新。
    3. 通过过滤掉新的但不太准确的修复来维护“当前最佳估计”位置。
    4. 停止监听位置更新。
    5. 利用最后的最佳位置估计。

    我使用自定义位置监听器并开始监听位置更新,因为我的应用已初始化,即使我没有显示地图:

    locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
    locationListener = new CustomLocationListener(); 
    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
    

    我有一个线程正在监听位置,所以当用户点击并调用我的地图视图时,如果位置为空,我们会向用户发送一条消息,等待我们检索他的位置。

    您可能想开发一种方法来选择更好的位置,因为最后一个位置可能不是最佳位置,试试这个:

    private static final int TWO_MINUTES = 1000 * 60 * 2;
    
    /** Determines whether one Location reading is better than the current Location fix
      * @param location  The new Location that you want to evaluate
      * @param currentBestLocation  The current Location fix, to which you want to compare the new one
      */
    protected boolean isBetterLocation(Location location, Location currentBestLocation) {
        if (currentBestLocation == null) {
            // A new location is always better than no location
            return true;
        }
    
        // Check whether the new location fix is newer or older
        long timeDelta = location.getTime() - currentBestLocation.getTime();
        boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
        boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
        boolean isNewer = timeDelta > 0;
    
        // If it's been more than two minutes since the current location, use the new location
        // because the user has likely moved
        if (isSignificantlyNewer) {
            return true;
        // If the new location is more than two minutes older, it must be worse
        } else if (isSignificantlyOlder) {
            return false;
        }
    
        // Check whether the new location fix is more or less accurate
        int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
        boolean isLessAccurate = accuracyDelta > 0;
        boolean isMoreAccurate = accuracyDelta < 0;
        boolean isSignificantlyLessAccurate = accuracyDelta > 200;
    
        // Check if the old and new location are from the same provider
        boolean isFromSameProvider = isSameProvider(location.getProvider(),
                currentBestLocation.getProvider());
    
        // Determine location quality using a combination of timeliness and accuracy
        if (isMoreAccurate) {
            return true;
        } else if (isNewer && !isLessAccurate) {
            return true;
        } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
            return true;
        }
        return false;
    }
    
    /** Checks whether two providers are the same */
    private boolean isSameProvider(String provider1, String provider2) {
        if (provider1 == null) {
          return provider2 == null;
        }
        return provider1.equals(provider2);
     }
    

    此代码在我链接的同一页面上提供。

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 2013-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多