我正在使用 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");
}
}
}