我有一个奇怪的问题,我很难理解。我可以使用LocationManager及其requestLocationUpdates方法来接收位置更新。我有一个实现LocationListener的简单类:
public class PrisLocationListener implements LocationListener
{
@Override
public void onLocationChanged(Location location)
{ ... }
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
{ ... }
@Override
public void onProviderEnabled(String provider)
{ ... }
@Override
public void onProviderDisabled(String provider)
{ ... }
}
我在Activity中使用此类,为它创建一个单独的线程:
// create seperate thread for location callbacks
mPrisLocationListener = new PrisLocationListener();
mLocationHandlerThread = new HandlerThread("LocationHandlerThread");
mLocationHandlerThread.start();
然后将其传递给LocationManager:
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,
mPrisLocationListener,
mLocationHandlerThread.getLooper());
以上按预期工作,我可以获得设备的GPS位置。
我还想要GPS状态信息(卫星计数,TTFF等),所以我创建了另一个实现GpsStatus.Listener的类:
public class PrisGpsListener implements GpsStatus.Listener
{
@Override
public void onGpsStatusChanged(int event)
{ ... }
}
当我尝试使用上述课程时,麻烦就开始了。在我的Activity和LocationListener的同一点,我初始化GpsListener的一个实例并将其传递给LocationManager:
mPrisGpsListener = new PrisGpsListener();
if(!mLocationManager.addGpsStatusListener(mPrisGpsListener)) {
Log.i("Activity: ","addGpsStatusListener failed"); // doesn't fail, addGpsStatusListener returns true
}
// LocationManager.requestLocationUpdates called after addGpsStatusListener
问题是,如果我添加' addGpsStatusListener'调用我的代码,没有任何关于位置服务的事情。也就是说,我不仅没有从GpsListener获得任何状态更新,而且我也不能获得正常的位置更新。当调用相关函数时,Logcat根本没有向我显示任何内容。
奇怪的是requestLocationUpdates本身工作正常,但调用addGpsStatusListener使混乱失败。我不知道在这里尝试什么,所以任何建议都会受到赞赏。
编辑:
正如Rafael指出的那样,当从Activity :: onCreate()调用时,所有这一切都可以正常工作......但是,(这应该是我提到的第一件事之一),那里有一个单独的函数main调用上述LocationManager方法并实例化相关对象的Activity。 我从本机代码通过JNI
调用该方法在创建Activity之后的某个时间使用JNI调用该方法。
答案 0 :(得分:1)
刚试过这个:
public class TestActivity extends Activity {
private LocationManager mLocationManager;
private PrisLocationListener mLocationListener;
private PrisGpsListener mGpsListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
PrisLocationListener locationListener = new PrisLocationListener();
HandlerThread t = new HandlerThread("LocationHandlerThread");
t.start();
mLocationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener, t.getLooper());
mGpsListener = new PrisGpsListener();
mLocationManager.addGpsStatusListener(mGpsListener);
}
@Override
protected void onPause() {
super.onPause();
mLocationManager.removeUpdates(mLocationListener);
mLocationManager.removeGpsStatusListener(mGpsListener);
}
public static class PrisLocationListener implements LocationListener{
private static final String TAG = PrisLocationListener.class.getSimpleName();
@Override
public void onLocationChanged(Location arg0) {
Log.d(TAG, "onLocationChanged: loc=" + arg0);
}
@Override
public void onProviderDisabled(String provider) {
Log.d(TAG, "onProviderDisabled: provider=" + provider);
}
@Override
public void onProviderEnabled(String provider) {
Log.d(TAG, "onProviderEnabled: provider=" + provider);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, "onStatusChanged: provider=" + provider + ", status=" + status + ", extras=" + extras);
}
}
public static class PrisGpsListener implements GpsStatus.Listener{
private static final String TAG = PrisGpsListener.class.getSimpleName();
@Override
public void onGpsStatusChanged(int event) {
Log.d(TAG, "onGpsStatusChanged: event=" + event);
}
}
}
我的日志输出
11-26 12:03:58.707:D / PrisGpsListener(24412):onGpsStatusChanged:event = 1 11-26 12:04:00.199:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4 11-26 12:04:01.199:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4 11-26 12:04:02.199:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4 11-26 12:04:03.207:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4 11-26 12:04:04.207:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4 11-26 12:04:05.199:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4 11-26 12:04:06.199:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4 11-26 12:04:07.191:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4 11-26 12:04:08.207:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4 11-26 12:04:09.215:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4 11-26 12:04:10.207:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4 11-26 12:04:11.207:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4 11-26 12:04:12.207:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4 11-26 12:04:13.215:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4 11-26 12:04:14.223:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4 11-26 12:04:15.223:D / PrisGpsListener(24412):onGpsStatusChanged:event = 4
所以GpsStatus.Listener
实际上正在发挥作用。如果移动手机,我想你会收到位置修复。
答案 1 :(得分:0)
似乎我需要从主线程调用LocationManager.addGpsStatusListener(...)。使用Runnable封闭调用可以解决问题:
public void someFunctionCalledWithJNI()
{
this.runOnUiThread(new Runnable() {
public void run() {
if(!mLocationManager.addGpsStatusListener(mPrisGpsListener)) {
Log.i("Activity: ","addGpsStatusListener failed");
}
}
});
}
同样的事情适用于LocationManager.requestLocationUpdates,但会抛出一个异常,明确告诉你:“无法在未调用Looper.prepare()的线程内创建Handler”,所以我为它创建了一个单独的HandlerThread
您也可以将两者都放在主线程上:
public void someFunctionCalledWithJNI()
{
this.runOnUiThread(new Runnable() {
public void run() {
if(!mLocationManager.addGpsStatusListener(mPrisGpsListener)) {
Log.i("Activity: ","addGpsStatusListener failed");
}
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,mPrisLocationListener);
}
});
}