mercredi 24 février 2016

how to update latitude and longitude through a background service at regular intervals?

I have written a background service to insert latitude , longitude and some other details into my sqlite database based on the time limit set in my AlarmManager. I am using GoogleApiClient to calculate latitude and longitude , but i am facing some problems.

Problem

When i am travelling outside without net , the latitude and longitude is not getting updated at regular intervals. The data is getting inserted in my sqlite at regular intervals but latitude and longitude remains same even after half an hour though i am travelling some about 10 kms. I want the latitude and longitude to change while i am travelling like auto update.

I wanted to know if the FusedLocationApi calculates latitude longitude properly even if i am not connected to the internet , if yes then i need some suggestions to improve the code that i have tried.

Code i have tried.

AlarmManagerService.java

public class AlarmManagerService extends Service implements 
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener, LocationListener {

private static final String TAG = "AlarmManagerService";
AlarmReceiver alarmReceiver;
DriverDbHelper driverDbHelper;
Handler handler;
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
private Location mLastLocation;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
// boolean flag to toggle periodic location updates
private boolean mRequestingLocationUpdates = false;
private LocationRequest mLocationRequest;
// Location updates intervals in sec
private static int UPDATE_INTERVAL = 120000; // 2 mins
private static int FATEST_INTERVAL = 60000; // 1 min
private static int DISPLACEMENT = 10; // 10 meters
public Activity activity;
protected String mLastUpdateTime;
String areaName0, areaName1, areaName2, areaName3, fullAreaName,  
sessionMobileNo, sessionDriverName, sessionDID, sessiondriverUserId, 
date, time, dateTime, doc, trac_transId;
double latitude, longitude;
PowerManager.WakeLock mWakeLock;
SessionManager session;
ConnectionDetector cd;
Boolean isInternet = false;
String sync_no = "No";
String sync_yes = "Yes";

public AlarmManagerService() {
    alarmReceiver = new AlarmReceiver();
    driverDbHelper = new DriverDbHelper(this);
    cd = new ConnectionDetector(this);
}

public void setActivity(Activity activity) {
    this.activity = activity;
}

@Override
public void onCreate() {
    super.onCreate();
    try {
        driverDbHelper.open(AlarmManagerService.this);
    } catch (Exception e) {
        e.printStackTrace();
    }

    Log.d("Service created", "Alarm Service Created");
    // First we need to check availability of play services
    if (checkPlayServices()) {
        // Building the GoogleApi client
        buildGoogleApiClient();
        createLocationRequest();
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    PowerManager mgr = (PowerManager) 
    getSystemService(Context.POWER_SERVICE);
    if (this.mWakeLock == null) {
        this.mWakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 
        "MyWakeLock");
    }

    if (!this.mWakeLock.isHeld()) {
        this.mWakeLock.acquire();
    }
    if (mGoogleApiClient != null) {
        mGoogleApiClient.connect();
    }
    Log.d("Service started", "Alarm Service Started");
    handler = new Handler(Looper.myLooper());
    handler.post(new Runnable() {
        @Override
        public void run() {
            postDatabaseDetails();
        }
    });
    return START_STICKY;
}

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

@Override
public void onDestroy() {
    super.onDestroy();
    Log.d("Service started", "Alarm Service Destroyed");
    if (mGoogleApiClient.isConnected()) {
        stopLocationUpdates();
        mGoogleApiClient.disconnect();
    }
    if (this.mWakeLock != null) {
        this.mWakeLock.release();
        this.mWakeLock = null;
    }
}

private void displayLocation() {

    if (mLastLocation != null) {
        latitude = mLastLocation.getLatitude();
        longitude = mLastLocation.getLongitude();
        List<Address> addressList = null;
        try {
            Geocoder gcd = new Geocoder(getBaseContext(), 
            Locale.getDefault());
            addressList = gcd.getFromLocation(mLastLocation.getLatitude(), 
            mLastLocation.getLongitude(), 1);
            if (addressList != null && addressList.size() > 0) {
                Address address = addressList.get(0);
                areaName0 = address.getLocality(); // city name
                areaName1 = address.getSubLocality(); 
                areaName2 = address.getAdminArea();// statename
                //areaName3 = address.getFeatureName(); plot no
                //areaName3 = address.getCountryCode();// IN
                areaName3 = address.getThoroughfare();
                fullAreaName = areaName3 + "\n" + areaName1 + "\n" + 
                areaName0 + "," + areaName2;
            } else {
                Log.i("Location ", "Location null");
            }
        } catch (IOException e1) {
            Log.e("HomePage", "IO Exception in getFromLocation()");
            e1.printStackTrace();
        } catch (IllegalArgumentException e2) {
            // Error message to post in the log
            String errorString = "Illegal arguments " + 
                    Double.toString(mLastLocation.getLatitude()) + " , " +
                    Double.toString(mLastLocation.getLongitude()) +
                    " passed to address service";
            Log.e("HomePage", errorString);
            e2.printStackTrace();
        }
    }
}

/**
 * Creating google api client object
 */
protected synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API).build();
}

/**
 * Creating location request object
 */
protected void createLocationRequest() {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(UPDATE_INTERVAL);
    //mLocationRequest.setFastestInterval(FATEST_INTERVAL);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}

/**
 * Method to verify google play services on the device
 */
private boolean checkPlayServices() {
    int resultCode = GooglePlayServicesUtil
            .isGooglePlayServicesAvailable(this);
    if (resultCode != ConnectionResult.SUCCESS) {
        if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
            GooglePlayServicesUtil.getErrorDialog(resultCode, activity,
                    PLAY_SERVICES_RESOLUTION_REQUEST).show();
        } else {
            Log.i("Google play services", "Device not supported");
            activity.finish();
        }
        return false;
    }
    return true;
}

/**
 * Starting the location updates
 */
protected void startLocationUpdates() {
    LocationServices.FusedLocationApi.requestLocationUpdates(
            mGoogleApiClient, mLocationRequest, this);
}

/**
 * Stopping location updates
 */
protected void stopLocationUpdates() {
    LocationServices.FusedLocationApi.removeLocationUpdates(
            mGoogleApiClient, this);
}

@Override
public void onConnected(Bundle bundle) {
    // Once connected with google api, get the location
    //displayLocation();
    if (mRequestingLocationUpdates) {
        startLocationUpdates();
    }
    if (mLastLocation == null) {
        mLastLocation =  
        LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
        displayLocation();
    }
}

@Override
public void onConnectionSuspended(int i) {
    mGoogleApiClient.connect();
}

@Override
public void onLocationChanged(Location location) {
    // Assign the new location
    mLastLocation = location;
    mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
    Log.d("Location changed ", "Location changed " + mLastLocation);
    Log.d("Last updated time", "Last updated location " + mLastUpdateTime);

    // Displaying the new location on UI
    displayLocation();
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
            + connectionResult.getErrorCode());
}

public void postDatabaseDetails() {
    session = new SessionManager(getApplicationContext());
    HashMap<String, String> user = session.getUserDetails();
    sessionMobileNo = user.get(SessionManager.KEY_MOBILENO);
    sessionDriverName = user.get(SessionManager.KEY_NAME);
    sessionDID = user.get(SessionManager.KEY_DEVICEID);
    sessiondriverUserId = user.get(SessionManager.KEY_DRIVERUSERID);
    Calendar in = Calendar.getInstance();
    Date dt = new Date();
    in.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    SimpleDateFormat stf = new SimpleDateFormat("HH:mm:ss");
    date = sdf.format(dt);
    time = stf.format(dt);
    String timeval = time.toString();
    String dateval = date.toString();
    dateTime = date.toString() + " " + time.toString();
    doc = sessionDID + "" + dateTime;
    isInternet = cd.isConnectingToInternet();
    if (isInternet) {
        long id = driverDbHelper.insertDriverDetails(doc, sessionDID,  
                sessiondriverUserId, latitude, longitude,
                fullAreaName, dateTime, "DEMO", sync_no, dateval, timeval);
        postDriverDetails();
        Log.d("GPS", "Service started after 2 mins with internet");
    } else {
        Log.d("Internet status", "No internet available for service");
        long id = driverDbHelper.insertDriverDetails(doc, sessionDID, 
                 sessiondriverUserId, latitude, longitude,
                "NA", dateTime, "DEMO", sync_no, dateval, timeval);
        Log.d("GPS", "Service started after 2 mins without internet");
    }
}

I am calling this service from the activity HomePage.java , but from where do i have to call the below code , from onStart() or after setContentView(R.layout.home)?

try {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MINUTE, 2);
        AlarmManager am = (AlarmManager)  
        getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent(Home_Page.this, AlarmManagerService.class);
        PendingIntent pi = PendingIntent.getService(Home_Page.this, 0, i,0);
        am.setInexactRepeating(AlarmManager.RTC_WAKEUP, 
        calendar.getTimeInMillis(), EXEC_INTERVAL, pi); 
    } catch (Exception e) {
        e.printStackTrace();
    }

I hope i can get some suggestions to improve the above service code as i want it to run smoothly in background updating the latitude and longitude at regular intervals.

Aucun commentaire:

Enregistrer un commentaire