onLocationChanged方法未被调用

5

我希望制作一个与地图相关的安卓应用,但是我发现我的应用程序中的onLocationChanged方法从未被调用过,因此地图总是停留在默认区域(美国)。

我的代码:

public class MapMainActivity extends MapActivity 
implements OnClickListener, LocationListener {

MapView mapView;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.map_main);

    //reference
    mapView = (MapView)findViewById(R.id.map_view);
    mapView.setBuiltInZoomControls(true);
    this.findViewById(R.id.btn_satellite).setOnClickListener(this);
    this.findViewById(R.id.btn_street).setOnClickListener(this);

}//onCreate

@Override
protected void onResume() {
    super.onResume();

    Toast.makeText(this, "GPS tracking started",
        Toast.LENGTH_SHORT).show();

 // Start location updates; 5s/5m
    LocationManager locManager = (LocationManager)getSystemService(
        Context.LOCATION_SERVICE);
    locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
        5000, 0, this);

    Criteria crit = new Criteria();
    crit.setAccuracy(Criteria.ACCURACY_FINE);
    String provider = locManager.getBestProvider(crit, true);
    Location loc = locManager.getLastKnownLocation(provider);

}//onResume

@Override
protected void onPause() {
    super.onPause();

    Toast.makeText(this, "GPS tracking stopped", 
        Toast.LENGTH_SHORT).show();

    LocationManager locManager = (LocationManager)getSystemService(
            Context.LOCATION_SERVICE);
        locManager.removeUpdates(this);
}//onPause

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    if(v == findViewById(R.id.btn_street))
    {
        mapView.setSatellite(false);
    }//street view

    else if (v == findViewById(R.id.btn_satellite))
    {
        mapView.setSatellite(true);
    }
}//onClick

@Override
protected boolean isRouteDisplayed() {
    // TODO Auto-generated method stub
    return false;
}//isRouteDisplayed

@Override
public void onLocationChanged(Location location) {
    // TODO Auto-generated method stub
    double lat = location.getLatitude();
    double lon = location.getLongitude();

    TextView txtLat = (TextView)findViewById(R.id.txt_lat);
    txtLat.setText(String.format("%.6f", lat));
    TextView txtLon = (TextView)findViewById(R.id.txt_lon);
    txtLon.setText(String.format("%.6f", lon));

    MapView map = (MapView)findViewById(R.id.map_view);
    map.getController().animateTo(new GeoPoint((int)(lat*1E6),//1000000), 
        (int)(lon*1E6)));
}//onLocationChanged

@Override
public void onProviderDisabled(String provider) {
    // TODO Auto-generated method stub
    Toast.makeText(this, "GPS disabled", 
            Toast.LENGTH_SHORT).show();
}//onProviderDisabled

@Override
public void onProviderEnabled(String provider) {
    // TODO Auto-generated method stub
    Toast.makeText(this, "GPS enabled", 
            Toast.LENGTH_SHORT).show();
}//onProviderEnabled

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
    // TODO Auto-generated method stub

}//onStatusChanged


}//class

当我通过我的设备运行应用程序时,以下是完整的日志记录(2011年12月16日)。

D/InputTransport(5357): Input channel constructed: name='40baf680 Toast (client)', ashmemFd=54, receivePipeFd=57, sendPipeFd=58

I/MapActivity(5357): Handling network change notification:CONNECTED

E/MapActivity(5357): Couldn't get connection factory client

I/ViewRoot(5357): !@FINISH DRAWING : sg.edu.tp/sg.edu.tp.SIP_TestMapActivity

I/ViewRoot(5357): !@finishDrawing is completed : sg.edu.tp/sg.edu.tp.SIP_TestMapActivity

I/ViewRoot(5357): !@FINISH DRAWING : Toast

I/ViewRoot(5357): !@finishDrawing is completed : Toast

D/InputTransport(5357): Input channel destroyed: name='40baf680 Toast (client)', ashmemFd=54, receivePipeFd=57, sendPipeFd=58

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="sg.edu.tp"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".SIP_MLT_TestActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <uses-library android:name="com.google.android.maps" />
        <activity android:name=".SIP_TestMapActivity"></activity>
        <activity android:name=".SIP_TestDraw1Activity"></activity>
        <activity android:name=".SIP_TestDraw2Activity"></activity>
    </application>

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

</manifest>

你是如何改变位置的? - freshDroid
嗯……我不太理解你的意思。但是,既然我不在这个状态中,当我运行该应用程序时,它不应该显示州地图。 - starvi
不,我在我的设备上运行它(三星Galaxy R)。 - starvi
2个回答

1

您是在移动中测试还是坐在开发机旁,使用USB并观看logcat日志?

如果是坐在开发机旁,我怀疑您无法移动5米以触发位置更改事件,因为您在调用requestLocationUpdates时请求了该事件。

API文档中可知:

如果minDistance大于0,则只有当设备移动minDistance米时才会广播位置。

尝试将该调用中的min distance参数减小到零,看看会发生什么。

locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,5000, 0, this);

你可能不希望将它保持为零,除了进行测试外。

如果这并没有帮助你,你可以尝试在 onResume 中执行类似以下的操作,确认 GPS 是否正常工作:

Criteria crit = new Criteria();
crit.setAccuracy(Criteria.ACCURACY_FINE);
String provider = lm.getBestProvider(crit, true);
Location loc = lm.getLastKnownLocation(provider);

并查看您是否获得了良好的位置信息。


是的,我已经插上了USB并测试了。当我从5改为0时没有任何反应。我在onLocationChanged方法中插入了一个日志并测试了该应用程序,但当我运行该应用程序时,该日志不会出现。所以我的猜测是它甚至没有进入那个方法。 - starvi
嗨,似乎没有什么反应。我已经更新了我的代码和上面的LogCat。请帮忙看看。谢谢=) - starvi
尝试在onResume的结尾处进行一些日志记录,然后查看loc包含什么内容,以确保您从位置提供程序获取了一些返回值。 - mmeyer
您是否确定您的清单包含权限<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>? - mmeyer
在 onResume 中添加了 Log.d("location",String.valueof(loc)) 后,在标准之后,返回值为 null。 - starvi
显示剩余2条评论

0

位置信息处理是一个棘手的问题。一方面,您需要快速获取最精确的最新位置信息,另一方面,您不希望电池快速耗尽。此外,API级别之间也存在差异。请参阅本手册以获取详细说明:

http://android-developers.blogspot.com/2011/06/deep-dive-into-location.html

关于您最初的问题 - 请求位置更新只是向位置管理器建议在某些变化后向您发送这些更新。它没有义务这样做。您的GPS系统可能不够精确(当连接USB电缆时肯定不够精确)以检测小的位置变化。为了测试目的,您可以创建模拟提供程序并使用其他应用程序进行操作。

http://developer.android.com/reference/android/location/LocationManager.html#addTestProvider%28java.lang.String,%20boolean,%20boolean,%20boolean,%20boolean,%20boolean,%20boolean,%20boolean,%20int,%20int%29


嗨,你能告诉我代码应该放在哪里吗?谢谢。 - starvi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接