我正在尝试从后台服务获取位置。我正在使用以下代码从Activity启动服务。
Intent serviceIntent = new Intent(this, LocationService.class);
startService(serviceIntent);
这是我的服务代码。
public class LocationService extends Service {
private Thread t;
Looper threadLooper = null;
public int onStartCommand(Intent intent, int flags, int startId){
Log.i("Imp", "Inside service.");
new LooperThread().start();
return Service.START_NOT_STICKY;
}
private void logLocation(String lat, String lng){
//write to database.
}
class LooperThread extends Thread {
public void run() {
Log.i("Imp", "inside thread");
Looper.prepare();
Context context = getApplicationContext();
String svcName = Context.LOCATION_SERVICE;
LocationManager locationManager = (LocationManager) context.getSystemService(svcName);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setPowerRequirement(Criteria.POWER_HIGH);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setSpeedRequired(false);
criteria.setCostAllowed(false);
Log.i("Imp", "Regestring event.");
locationManager.requestSingleUpdate(criteria, locationListener, Looper.myLooper());
Log.i("Imp", "event reg.");
Looper.loop();
stopSelf();
}
}
final LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Log.i("Imp", "Inside event");
if(location != null){
String lat = Double.toString(location.getLatitude());
String lng = Double.toString(location.getLongitude());
Log.i("Imp", "Lat " + lat);
Log.i("Imp", "lng " + lng);
logLocation(lat, lng);
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
}
最初我用来获取错误,因为我已经为Looper对象传递了null参数。但是在传递了looper对象后,我没有得到任何错误,但我甚至没有得到任何坐标。
每次运行代码时都会收到event reg.
消息但由于某种原因它从不调用listner。
PS:我在手机上运行代码,而不是在模拟器上运行。
答案 0 :(得分:0)
您可能尚未在清单文件中注册该服务。 所有服务必须由清单文件中的元素表示。任何未在此处声明的内容都不会被系统看到,也永远不会被运行。
<service android:enabled=["true" | "false"]
android:exported=["true" | "false"]
android:icon="drawable resource"
android:isolatedProcess=["true" | "false"]
android:label="string resource"
android:name="string"
android:permission="string"
android:process="string" >
</service>
答案 1 :(得分:0)
推荐的方法是使用Google Play服务中的Location API。
添加Google Play服务依赖项。
compile 'com.google.android.gms:play-services:+'
以下代码。
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class FusedLocationProvider implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
com.google.android.gms.location.LocationListener,
ArchitectViewHolderInterface.ILocationProvider {
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private LocationListener listener;
private String TAG = "FusedLocationProvider";
public FusedLocationProvider(Context ctx, LocationListener locationListener){
mGoogleApiClient = new GoogleApiClient.Builder(ctx)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
Log.i(TAG, "Connecting...");
this.listener = locationListener;
}
@Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "onConnected");
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(1000); // Update location every second
try{
if(mGoogleApiClient.isConnected()) {
Log.i(TAG, "requestLocationUpdates");
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}catch (SecurityException se){
Log.i(TAG, se.toString());
}catch (Exception e){
Log.i(TAG, e.toString());
}
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "onConnectionSuspended");
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "onConnectionFailed");
}
@Override
public void onLocationChanged(Location recentLoc) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Log.i(TAG, Double.toString(recentLoc.getLongitude()));
listener.onLocationChanged(recentLoc);
}
public void onPause() {
Log.i(TAG, "onPause");
if(mGoogleApiClient.isConnected()) {
Log.i(TAG, "removeLocationUpdates");
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
}
@Override
public void onResume() {
Log.i(TAG, "onResume");
try{
if(mGoogleApiClient.isConnected()){
Log.i(TAG, "requestLocationUpdates");
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}catch (SecurityException se){
Log.i(TAG, se.toString());
}catch (Exception e){
Log.i(TAG, e.toString());
}
}
public void onStop(){
Log.i(TAG, "onStop");
if(mGoogleApiClient.isConnected()) {
Log.i(TAG, "disconnect");
mGoogleApiClient.disconnect();
}
}
}
以下是android清单文件中的权限。
<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" />