我正在尝试提供一项服务来跟踪设备的移动(获取位置更新)并根据设备的当前位置启动警报。在他们那一刻,当我在计算机上的模拟器上测试应用程序时,它确实获得了位置更新,但是当我在我的设备上尝试它时,它总是返回起始位置,因此我怀疑设备无法获得 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;
}
}*/
}
我该如何解决?