1

我正在尝试提供一项服务来跟踪设备的移动(获取位置更新)并根据设备的当前位置启动警报。在他们那一刻,当我在计算机上的模拟器上测试应用程序时,它确实获得了位置更新,但是当我在我的设备上尝试它时,它总是返回起始位置,因此我怀疑设备无法获得 gps 服务,但我我不确定。清单中的权限:

<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />

服务:

package com.example.fgps;

import java.util.ArrayList;
import java.util.List;

import android.app.Service;
import android.content.Intent;
import android.content.IntentSender;
import android.database.Cursor;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
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.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.model.LatLng;

public class BackgroundLocationService extends Service implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
    public static final String TAG = BackgroundLocationService.class.getSimpleName();

    private List<LocationAlarm> alarms;
    private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;

    private GoogleApiClient mGoogleApiClient;
    private boolean mInProgress;

    private LocationRequest mLocationRequest;



    public void onCreate(){
        super.onCreate();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
        .addConnectionCallbacks(this)
        .addOnConnectionFailedListener(this)
        .addApi(LocationServices.API)
        .build();

        // Create the LocationRequest object
        mLocationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setInterval(3 * 1000)        // 3 seconds, in milliseconds
                .setFastestInterval(1 * 500); // 1/2 second, in milliseconds
        openDB();
    }
    @Override
    public int onStartCommand (Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);

        if(mGoogleApiClient.isConnected() || mInProgress)
            return START_STICKY;


        if(!mGoogleApiClient.isConnected() || !mGoogleApiClient.isConnecting() && !mInProgress) {
            mInProgress = true;
            mGoogleApiClient.connect();
        }

        return START_STICKY;
    }
    /*private void setUpLocationClientIfNeeded() {
        Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if (location == null) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
    }*/

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }
    private void setlist()
    {
        Log.d("create", "got here");
        Cursor c =Mdb.getAllRows(); 
        LatLng latLng;
        if(alarms!=null)
            alarms.clear();
        for(alarms = new ArrayList<LocationAlarm>(); !c.isAfterLast(); c.moveToNext()) {
            if(c.getInt(c.getColumnIndex(c.getColumnName(4))) != 0)
            {
                latLng=new LatLng(c.getDouble(c.getColumnIndex(c.getColumnName(2))),c.getDouble(c.getColumnIndex(c.getColumnName(3))));
                alarms.add(new LocationAlarm(c.getLong(c.getColumnIndex(c.getColumnName(0))),c.getInt(c.getColumnIndex(c.getColumnName(4))) != 0, latLng, c.getDouble(c.getColumnIndex(c.getColumnName(5))), c.getString(c.getColumnIndex(c.getColumnName(1)))));
            }
        }

    }

    @Override
    public void onConnected(Bundle bundle) {
        setlist();
        Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if (location == null) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
        else {
            handleNewLocation(location);
        }
        stopS();
    }

    @Override
    public void onConnectionSuspended(int i) {

    }


    public void onConnectionFailed(ConnectionResult connectionResult) {
        mInProgress = false;

        // * Google Play services can resolve some errors it detects.
        // * If the error has a resolution, try sending an Intent to
        // * start a Google Play services activity that can resolve
        //* error.

        if (connectionResult.hasResolution()) {
            try {
                // Start an Activity that tries to resolve the error
                connectionResult.startResolutionForResult(null, CONNECTION_FAILURE_RESOLUTION_REQUEST);

                // * Thrown if Google Play services canceled the original
                // * PendingIntent

            } catch (IntentSender.SendIntentException e) {
                // Log the error
                e.printStackTrace();
            }
        } else {

            //* If no resolution is available, display a dialog to the
            // * user with the error.

            Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
        }
    }
    @Override
    public void onDestroy(){
        mInProgress = false;
        if (mGoogleApiClient.isConnected()) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
            mGoogleApiClient.disconnect();
        }
        super.onDestroy();
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.d("loc changed", "got here");
        handleNewLocation(location);
    }
    private void stopS()
    {
        if(alarms.isEmpty())
        {
            this.stopSelf();
            onDestroy();
        }

    }
    private int iii;
    private DBAdapter Mdb;
    private void handleNewLocation(Location location) {
        Log.d(TAG, location.toString());
        boolean flagS=true;
        double currentLatitude = location.getLatitude();
        double currentLongitude = location.getLongitude();
        LatLng latLng = new LatLng(currentLatitude, currentLongitude);
        for(iii=0;iii<alarms.size();iii++)
        {
            if(distanceCal(latLng, alarms.get(iii).getLatlng())<=alarms.get(iii).getDistance())
            {
                if(flagS==true)
                {
                    setOffAlarm(alarms.get(iii).getTitle(),alarms.get(iii).getId());
                    /*new Thread() {
                        public void run()
                        {
                            setOffAlarm(alarms.get(iii).getTitle(),alarms.get(iii).getId());
                        }
                    }.start();*/
                    flagS=false;
                }else{
                    setOffAlarm2(alarms.get(iii).getId());
                }

                Log.d("loop", "got here "+iii);
            }
        }

    }
    private void updList(Long id)
    {
        for(int i=0;i<alarms.size();i++)
        {
            if(alarms.get(i).getId()==id)
                alarms.remove(i);
        }
    }
    private void setOffAlarm(String title,Long id) {
        Log.d("setoff", "got here");
        updList(id);
        Mdb.updateRowsState(id, 0);
        Intent intent = new Intent(this, AlarmReceiverActivity.class);
        intent.putExtra("titl", title);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }
    private void setOffAlarm2(Long id) {
        Log.d("setoff2", "got here");
        updList(id);
        Mdb.updateRowsState(id, 0);
    }
    private double distanceCal(LatLng Mloc,LatLng destination)
    {
        final int R = 6371; // Radius of the earth
        Double lat1 = Mloc.latitude;
        Double lon1 = Mloc.longitude;
        Double lat2 = destination.latitude; 
        Double lon2 = destination.longitude;
        Double latDistance = toRad(lat2-lat1);
        Double lonDistance = toRad(lon2-lon1);
        Double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) + 
                Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * 
                Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
        Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        Double distance = R * c;
        return distance;
    }
    private Double toRad(Double value) {
        return value * Math.PI / 180;
    }

    private void openDB(){
        Mdb = new DBAdapter(this);
        Mdb.open();
    }

    /*public class LocalBinder extends Binder {
        BackgroundLocationService getService() {
            // Return this instance of LocalService so clients can call public methods
            return BackgroundLocationService.this;
        }
    }*/
}

我该如何解决?

4

0 回答 0