0

我的应用程序是一个使用 GPS 的跟踪器应用程序。每 15 分钟,它会找到用户的当前位置。为此,我使用了AlarmManager. 我通过后台服务获取当前位置,该服务计划在每个15 minutes. 该服务将由广播接收器在警报时启动。但是,问题是警报在时间之前触发,即一旦服务启动并完成其工作,服务应该在 15 分钟后被调用。但是,它每隔 2-3 分钟就会被调用一次。

活动代码

AlarmManager AlmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Sender = PendingIntent.getBroadcast(GpsTrackActivity.this, 0,
                AlarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        AlmMgr.setRepeating(AlarmManager.RTC_WAKEUP, 0, 15 * 60 * 1000,
                Sender);

广播接收器

public class StartServiceReceiver extends BroadcastReceiver 
{
    private static final String TAG = "StartServiceReceiver";
    @Override
    public void onReceive(Context context, Intent intent) 
    {
        Intent serviceIntent = new Intent(context, MyLocationService.class);
        context.startService(serviceIntent);
        Log.v(TAG, "onReceive called");
    }
}

服务等级

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;
GPSLocationListener mGPSLocationListener;
NetworkLocationListener mNetworkLocationListener;
private static final int MAX_ATTEMPTS = 250;
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");
    mGPSLocationListener = new GPSLocationListener();
    mNetworkLocationListener = new NetworkLocationListener();
    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, 5000L,
                50.0f, mGPSLocationListener);
    } else {
        turnGPSOn();
        manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000L,
                50.0f, mGPSLocationListener);
    }

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

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;
}

public class GPSLocationListener 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() {
            i++;
            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");
                isGPS = true;
                onLocationReceived(location);
                myLocTimer.cancel();
                myLocTimer.purge();
                mTimerTask.cancel();
                return;
            } else {
                Log.v(TAG, "in timer task run in else location null");
                isGPS = false;
                if (location == null && i == MAX_ATTEMPTS) {
                    Log.v(TAG, "if 1 max attempts done");
                    turnGPSOff();
                    location = manager
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    if (location != null) {
                        Log.v(TAG,
                                "if 1 max attempts done Location from network not null");
                        Log.v(TAG,
                                "if 1 max attempts done Location from network not null coordinates not null");
                        onLocationReceived(location);
                        myLocTimer.cancel();
                        myLocTimer.purge();
                        mTimerTask.cancel();
                        i = 0;
                        return;
                    } else {
                        i = 0;
                        return;
                    }
                } else {
                    return;
                }
            }
        }
    };

    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);
        }
    }

    if (manager != null) {
        if (mGPSLocationListener != null) {
            manager.removeUpdates(mGPSLocationListener);
        }

        if (mNetworkLocationListener != null) {
            manager.removeUpdates(mNetworkLocationListener);
        }

        if (mGPSStatusListener != null) {
            manager.removeGpsStatusListener(mGPSStatusListener);
        }
    }
     Toast.makeText(getApplicationContext(), "Service onDestroy called",
     Toast.LENGTH_LONG).show();
}

@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");
    }
}
}

我有一个疑问,确实AlarmManager会受到 Timer 或 TimerTask 的影响。我问这个是因为在我的服务中我使用了 Timer,因为 GPS 需要时间来找到第一个修复。

4

0 回答 0