我遇到了从服务启动的线程请求位置更新的问题。
我的应用程序需要从后台服务获取位置更新(没有任何UI线程)。我将解释我的申请结构。
onStartCommand()
服务中,它启动一个调度程序线程。问题是调度程序调用{{1}}时
它说locationMgr.requestLocationUpdates()
我已经看到其他人遇到类似的问题,但无法找到任何解决方案。我听说我们可以直接从服务中调用以获得位置更新而没有任何问题,但由于我无法找到一种睡眠服务的方式(如调度程序线程),我想我需要一个单独的线程。
请解释为什么会这样? android是否需要UI线程来请求位置?通过改变我的应用程序结构有没有解决方案?
答案 0 :(得分:2)
Looper
是轮询Message
的/ Runnable
(通过该线程上的Handler
发布的线程队列)的线程队列的原因。 UI线程默认有一个。对于自定义线程,您需要在启动线程之前进行设置。
用于为线程运行消息循环的类。默认情况下的线程 没有与之关联的消息循环;创建一个,打电话 prepare()在运行循环的线程中,然后循环()到 让它处理消息,直到循环停止。
现在,RequestLocationUpdates()
需要一种机制来为您的线程提供更新,但您的线程没有Looper
轮询。
考虑将RequestLocationUpdates()
及其相应的removeUpdates()
移至服务主题。很可能是服务开始和停止的地方。
答案 1 :(得分:1)
发生的原因是:getLooper连接到上下文的UI,但服务是ackground进程不直接连接到UI。所以你得到了错误。
您的问题的解决方案:
1)将位置类放在其他包中。 2)导入该包名称。 3)在包中使用一个回调接口。 4)使用Service组件中的接口实例。 5)它会工作!!
答案 2 :(得分:1)
我已经用过这个并且工作正常:获取服务中的位置
此处的服务类:
public class MyService extends Service {
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
// start location manager
LocationDetermined objLocationDetemined = new LocationDetermined(this);
objLocationDetemined.getlocation(this);
objLocationDetemined.getRecentKnownLocation(this);
}
位置类:
public class LocationDetermined implements OnInitListener {
String TAG = "LocationDeterminedClass";
private static LocationManager locationManager;
double Lat = 0.0;
double Long = 0.0;
GeoPoint geoPoint;
private Toast mToast;
Context appContext;
static MyLocationListener locationListener;
public LocationDetermined(Context context) {
this.appContext = context;
}
public MyLocationListener getlocation(Context appContext) {
locationManager = (LocationManager) appContext
.getSystemService(Context.LOCATION_SERVICE);
locationListener = new MyLocationListener();
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
String provider = locationManager.getBestProvider(criteria, true);
Log.d(TAG, "------provider------" + provider);
if (provider != null && locationManager.isProviderEnabled(provider)) {
locationManager.requestLocationUpdates(provider, 0, 0,
locationListener);
} else {
Toast.makeText(appContext, "No provider available to get loctaion",
2000).show();
}
return locationListener;
}
private class MyLocationListener implements LocationListener {
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
public void onLocationChanged(final Location argLocation) {
// TODO Auto-generated method stub
if (argLocation != null) {
Lat = argLocation.getLatitude();
Long = argLocation.getLongitude();
Log.e("OnLocationChanged:", "lat:" + Lat + " long:" + Long);
Log.d("service gps", "lat" + argLocation.getLatitude() + "-"
+ argLocation.getLongitude());
Constant.mLatitude = argLocation.getLatitude();
Constant.mLongitude = argLocation.getLongitude();
}
}
}
public GeoPoint getRecentKnownLocation(Context appContext) {
Location locGps = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Location locNet = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Location locPassive = locationManager
.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
if (locGps != null) {
Lat = locGps.getLatitude();
Long = locGps.getLongitude();
Constant.mLatitude = locGps.getLatitude();
Constant.mLongitude = locGps.getLongitude();
geoPoint = new GeoPoint((int) (Lat * 1000000),
(int) (Long * 1000000));
return geoPoint;
} else if (locNet != null) {
Lat = locNet.getLatitude();
Long = locNet.getLongitude();
Constant.mLatitude = locNet.getLatitude();
Constant.mLongitude = locNet.getLongitude();
geoPoint = new GeoPoint((int) (Lat * 1000000),
(int) (Long * 1000000));
return geoPoint;
}
return geoPoint;
}
private void fetchedSavedLocationDetail(Context mContext) {
}
@Override
public void onInit(int status) {
// TODO Auto-generated method stub
}
public static void removeLocationListener() {
locationManager.removeUpdates(locationListener);
}
}
我在Constants类中使用这些变量来存储位置 public static double mLatitude = 0.0,mLongitude = 0.0;
启动服务 startService(new Intent(this,MyService.class));
答案 3 :(得分:0)
我已经使用处理程序修复了它。
handleMessage()
handleMessage()