I need my app to send its location updates twice a day at specific intervals. The code i have written is not working. Can any body see whats wrong?

StackOverflow https://stackoverflow.com/questions/21201968

Frage

This is the code which i have written to wake my app every day at 2pm. and sense the location. But my service doesn't wake up at all. What am i missing?

 public class MyService extends Service implements LocationListener {

    private final Context mContext;
    boolean isGPSEnabled = false;
    boolean canGetLocation = false;
    Location location; // location
    double latitude; // latitude
    double longitude; // longitude

    // The minimum distance to change Updates in meters
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0;

    // The minimum time between updates in milliseconds
    private static final long MIN_TIME_BW_UPDATES = 0;

    // Declaring a Location Manager
    protected LocationManager locationManager;
    private long YOUR_ALARM_TRIGGER_AT_TIME = 43200000;
    private long YOUR_ALARM_INTERVAL = 600000;

    @SuppressLint("Registered")
    public MyService(Context context) {
        this.mContext = context;
        getLocation();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        AlarmManager alarmMgr = (AlarmManager) this
                .getSystemService(Context.ALARM_SERVICE);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
                new Intent(this, AlarmSetter.class),
                PendingIntent.FLAG_CANCEL_CURRENT);
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        // Set the alarm's trigger time to 8:30 a.m.
        calendar.set(Calendar.HOUR_OF_DAY, 14);
        calendar.set(Calendar.MINUTE, 0);

        // Use inexact repeating which is easier on battery (system can phase
        // events and not wake at exact times)
        alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY,
                pendingIntent);
        if (canGetLocation) {
            Location l = getLocation();
            new GetAddressAsync().execute(l);

        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (canGetLocation) {
            Location l = getLocation();
            new GetAddressAsync().execute(l);

        }

        return super.onStartCommand(intent, flags, startId);
    }

    public Location getLocation() {
        try {
            locationManager = (LocationManager) mContext
                    .getSystemService(LOCATION_SERVICE);
            isGPSEnabled = locationManager
                    .isProviderEnabled(LocationManager.GPS_PROVIDER);
            if (!isGPSEnabled) {
                // Do Nothing
            } else {
                this.canGetLocation = true;
                if (location == null) {

                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("GPS Enabled", "GPS Enabled");
                    if (locationManager != null) {

                        location = locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (location != null) {
                            latitude = (location.getLatitude());
                            longitude = (location.getLongitude());
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return location;
    }

    /**
     * Stop using GPS listener Calling this function will stop using GPS in your
     * app
     * */
    public void stopUsingGPS() {
        if (locationManager != null) {
            locationManager.removeUpdates(MyService.this);
        }
    }

    public double getLatitude() {
        if (location != null) {
            latitude = location.getLatitude();
        }

        // return latitude
        return latitude;
    }

    /**
     * Function to get longitude
     * */
    public double getLongitude() {
        if (location != null) {
            longitude = location.getLongitude();
        }

        // return longitude
        return longitude;
    }

    /**
     * Function to check GPS/wifi enabled
     * 
     * @return boolean
     * */
    public boolean canGetLocation() {
        return this.canGetLocation;
    }

    @Override
    public void onLocationChanged(Location location) {
    }

    @Override
    public void onProviderDisabled(String provider) {
    }

    @Override
    public void onProviderEnabled(String provider) {
    }

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

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

    }

    class GetAddressAsync extends AsyncTask<Location, Void, String[]> {

    @Override
    protected String[] doInBackground(Location... params) {
        Location l = params[0];
        try {
            List<Address> address = Parser.getStringFromLocation(l);
            if (address != null) {
                for (Address address2 : address) {
                    String locality = address2.getLocality();
                    String subLocality = address2.getSubLocality();
                    Log.e("Serive", "Locality : " + locality
                            + ", sub locality: " + subLocality);

                }
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    }

This is my Alarm Receiver

public class AlarmSetter extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent arg1) {
        context.startService(new Intent(context, MyService.class));

    }

    }
War es hilfreich?

Lösung

I don't see the association between getLocation() and the AlarmManager. So while you are performing an AsyncTask the calendar is not synchronized with it. In response to the comment:

alarmMgr.setInexactRepeating

here is where you give the AlarmManager your intent to call your service. Actually it's called, when the user cancels the alarm.
The service itself maybe in running state or not started.
If it is in running state or the AlarmMananger doesn't start the service but sends a broadcast to it, both onCreate and onStartCommand won't be called. So your AnsychTask wont be restarted and the update process will not be performed.
EDITED: Sorry, my fault. So it's actually not the service which is passing his
pendingintent to the alarm manager, but the intent is supposed to control the broadcast
receiver which then starts the service.
Hm .. I personally would prefer the following setup:
Move the logic for the controlling of the AlarmManager into the AlarmSetter. :
The Service is responsible for getting the current location and updating it.:
The AlertSetter when launched starts the service (and binds to it), passes the PendingIntent to the
AlarmManager, so that he can send his broadcast when the user has canceled the alarm.
The AlertSetter then requests the update operation of the service.
I guess that the passing of the PendingIntent from one class (as source) for broadcasting to another class (the destination) may arise issues.
And you won't spread the logic for scheduling the service in two different classes: the service itself and the AlarmSetter. Besides I don't see any reason for not using http://developer.android.com/reference/java/util/concurrent/ScheduledExecutorService.html in this requirements definition.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top