0

我正在使用 GPS 制作一个跟踪器应用程序,它将收集用户的当前位置并将其发送到服务器。整个过程将每隔 15 分钟在后台运行一次。我已经能够让它工作了。现在,实际问题是我想向 GPS 请求特定数量的尝试,例如 5 次尝试。如果在那个时期它没有提供用户的位置,那么我想切换到NETWORK PROVIDER用户的大致位置。我曾使用计时器进行位置请求。NETWORK PROVIDER但是,如果在特定的尝试次数后 GPS 信号不可用,我无法切换到。下面,我发布我的代码:

public class MyLocationService extends Service implements
    OnLocationReceivedListener {

private LocationManager manager;
private Location location = null;
PowerManager powerManager;
private WakeLock wakeLock;
private String city, time, udid;
private String country;
MyLocationListener myLocationListener;
private static final int MAX_ATTEMPTS = 5;
private static String TAG = "MyLocationService";
LocTimerTask mTimerTask;
int mSattelites;
Timer myLocTimer;
int i = 0;
boolean isGPS;

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.v(TAG, "onStartCommand called");
    getCurrentLocation();
    time = getCurrentTime();
    udid = getDeviceId();
    return 1;
}

@Override
public void onCreate() {
    Log.v(TAG, "onCreate called");
    powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
    wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
            "mywakelock");
    myLocationListener = new MyLocationListener();
    wakeLock.acquire();
    super.onCreate();
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

public String getCurrentTime() {
    String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
            Locale.getDefault()).format(new Date());

    return currentTime;
}

public String getDeviceId() {
    TelephonyManager tm = (TelephonyManager) MyLocationService.this
            .getSystemService(Context.TELEPHONY_SERVICE);
    return tm.getDeviceId();
}

public void getCurrentLocation() {
    manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    manager.addGpsStatusListener(mGPSStatusListener);
    mTimerTask = new LocTimerTask(LocationManager.GPS_PROVIDER);

    if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        Log.v(TAG, "GPS ENABLED");
        manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L, 50.0f,
                myLocationListener);
    } else {
        turnGPSOn();
        manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L, 50.0f,
                myLocationListener);
    }

    myLocTimer = new Timer("LocationRunner", true);
    myLocTimer.schedule(mTimerTask, 0, 13000);
}

public String getLong(Location loc) {
    String longi = null;
    if (loc != null) {
        longi = Double.toString(loc.getLongitude());
    }
    return longi;
}

public String getLat(Location loc) {
    String lat = null;
    if (loc != null) {
        lat = Double.toString(loc.getLatitude());
    }
    return lat;
}

class SendDataAsynctask extends AsyncTask<Void, Void, Boolean> {
    private String lati;
    private String longi;
    private String datetime;
    private String udid, city, country, address;
    private WakeLock wakelock;

    public SendDataAsynctask(String lati, String longi, String address,
            String datetime, String udid, String city, String country,
            WakeLock wakeLock) {
        this.lati = lati;
        this.longi = longi;
        this.address = address;
        this.datetime = datetime;
        this.udid = udid;
        this.city = city;
        this.country = country;
        this.wakelock = wakeLock;
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        return ServerConnection.sendData(lati, longi, address, datetime,
                udid, city, country);
    }

    @Override
    protected void onPostExecute(Boolean result) {
        Log.v(TAG, "onPostExecute");
        manager.removeUpdates(myLocationListener);
        manager.removeGpsStatusListener(mGPSStatusListener);
        if (wakeLock.isHeld()) {
            wakelock.release();
        }
        if(isGPS) {
            Log.v(TAG, "Location from GPS");
            turnGPSOff();
            Toast.makeText(getApplicationContext(), "Location from GPS", Toast.LENGTH_LONG).show();
        } else {
            Log.v(TAG, "Location from Network");
            Toast.makeText(getApplicationContext(), "Location from Network", Toast.LENGTH_LONG).show();
        }
        stopSelf();
    }
}

public class MyLocationListener implements LocationListener {

    @Override
    public void onLocationChanged(Location argLocation) {
        //location = argLocation;
    }

    public void onProviderDisabled(String provider) {

    }

    public void onProviderEnabled(String provider) {

    }

    public void onStatusChanged(String provider, int status, Bundle extras) {

    }
}

class LocTimerTask extends TimerTask {
    String provider;

    public LocTimerTask(String provider) {
        this.provider = provider;
    }

    final Handler mHandler = new Handler(Looper.getMainLooper());

    Runnable r = new Runnable() {
        @Override
        public void run() {
            Log.v(TAG, "Timer Task run" + i);
            location = manager.getLastKnownLocation(provider);

            if (location != null) {
                Log.v(TAG, "in timer task run in if location not null");
                if (location.getLatitude() != 0.0f
                        && location.getLongitude() != 0.0f) {
                    Log.v(TAG, "in timer task run location not null coordinates not 0");
                    isGPS = true;
                    onLocationReceived(location);
                    myLocTimer.cancel();
                    mTimerTask.cancel();
                    turnGPSOff();
                }
            } else {
                Log.v(TAG, "in timer task run in else location null");
                /*if (i == MAX_ATTEMPTS) {
                    turnGPSOff();
                    myLocTimer.cancel();
                    mTimerTask.cancel();
                    if (location == null) {
                        Log.v(TAG, "Location from GPS null");
                        manager.requestLocationUpdates(
                                LocationManager.NETWORK_PROVIDER, 1000L, 50.0f,
                                myLocationListener);
                        location = manager
                                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (location != null) {
                            if (location.getLatitude() != 0.0f
                                    && location.getLongitude() != 0.0f) {
                                onLocationReceived(location);
                            }
                        }
                    }
                    isGPS = false;
                }*/
            }
            i++;
        }
    };

    public void run() {
        mHandler.post(r);
    }
}

private GpsStatus.Listener mGPSStatusListener = new GpsStatus.Listener() {

    @Override
    public synchronized void onGpsStatusChanged(int event) {
        switch (event) {
        case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
            Log.v(TAG, "GPS SAtellitestatus");
            GpsStatus status = manager.getGpsStatus(null);
            mSattelites = 0;
            Iterable<GpsSatellite> list = status.getSatellites();
            for (GpsSatellite satellite : list) {
                if (satellite.usedInFix()) {
                    mSattelites++;
                }
            }
            break;

        case GpsStatus.GPS_EVENT_FIRST_FIX:
            Toast.makeText(getApplicationContext(), "Got First Fix",
                    Toast.LENGTH_LONG).show();
            break;

        case GpsStatus.GPS_EVENT_STARTED:
            Toast.makeText(getApplicationContext(), "GPS Event Started",
                    Toast.LENGTH_LONG).show();
            break;

        case GpsStatus.GPS_EVENT_STOPPED:
            Toast.makeText(getApplicationContext(), "GPS Event Stopped",
                    Toast.LENGTH_LONG).show();
            break;
        default:
            break;
        }
    }
};

public void onDestroy() {
    super.onDestroy();
    if (myLocTimer != null) {
        myLocTimer.cancel();
        myLocTimer.purge();
    }

    if (mTimerTask != null) {
        if (mTimerTask.r != null) {
            mTimerTask.mHandler.removeCallbacks(mTimerTask.r);
        }
    }
}

@Override
public void onLocationReceived(Location mLoc) {
    String lat = getLat(mLoc);
    String lon = getLong(mLoc);
    if (NetworkConnection.isOnline(getApplicationContext())) {
        new SendDataAsynctask(lat, lon, "", time, udid, city, country,
                wakeLock).execute();
        Log.v(TAG, "net available");
    } else {
        Toast.makeText(getApplicationContext(), "Network unavailable",
                Toast.LENGTH_LONG).show();
        Log.v(TAG, "net unavailable");
    }
}

private void turnGPSOff(){
    String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);

    if(provider.contains("gps")){ //if gps is enabled
        final Intent poke = new Intent();
        poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
        poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
        poke.setData(Uri.parse("3")); 
        sendBroadcast(poke);
    }
}

private void turnGPSOn(){
    Log.v(TAG, "turnGPSON Called");
    String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);

    if(!provider.contains("gps")){ 
        final Intent poke = new Intent();
        poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider"); 
        poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
        poke.setData(Uri.parse("3")); 
        sendBroadcast(poke);
        Log.v(TAG, "alarm request sent from turnGPSOn");
    }
}
} 
4

1 回答 1

1

为什么要等?同时打开网络和 GPS。然后在你的计时器中像这样:

   attempts++;  //attempts is a variable at class scope
   location = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
   if(location == null && attempts == 5){
      location = manager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
      if(location == null){
           //They must have their radio off, you aren't going to get a location.  Handle this error

       }
   }
   if(location == null){
      return; //wait for next try
   }
   attempts = 0;  //clear for next run
   //process location
于 2013-03-22T06:41:36.143 回答