如何从Android服务访问GPS?

时间:2015-01-28 17:51:04

标签: android gps android-service

我正在尝试从后台服务获取位置。我正在使用以下代码从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:我在手机上运行代码,而不是在模拟器上运行。

2 个答案:

答案 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>

Ref Source

答案 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" />