I am trying to write a background service which shares location through SMS whenever the change in distance is more than 650 meters after every 3 minutes.
The code works fine but the service automatically closes after few minutes when I stop travelling. I want to keep the app running all the time so that the app sends data whenever a person is travelling.
Here is the code I wrote..
Main.java
package com.example.locationtest;
import android.support.v7.app.ActionBarActivity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
// Method to start the service
public void startService(View view) {
startService(new Intent(getBaseContext(), BackgroundService.class));
}
// Method to stop the service
public void stopService(View view) {
stopService(new Intent(getBaseContext(), BackgroundService.class));
}
}
BackgroundService.java
package com.example.locationtest;
import java.util.Date;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
public class BackgroundService extends Service {
private static DataSharing data=new DataSharing();
private Thread triggerService;
protected LocationManager locationManager;
protected MyLocationListener MyLocationListener;
protected Criteria criteria;
public static final int MIN_TIME = 18000;
public static final long MIN_DISTANCE = 650;
private SharedPreferences settings;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
data.setContext(getApplicationContext());
addLocationListener();
return START_STICKY;
}
private void addLocationListener()
{
triggerService = new Thread(new Runnable(){
public void run(){
try{
Looper.prepare();
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
final String PROVIDER = locationManager.getBestProvider(criteria, true);
updateLocation(getLastBestLocation(MIN_TIME, MIN_DISTANCE));
MyLocationListener = new MyLocationListener();
locationManager.requestLocationUpdates(PROVIDER, MIN_TIME, MIN_DISTANCE, MyLocationListener);
Looper.loop();
}catch(Exception ex){
ex.printStackTrace();
}
}
}, "LocationThread");
triggerService.start();
}
public Location getLastBestLocation(int minDistance, long minTime) {
Location bestResult = null;
float bestAccuracy = Float.MAX_VALUE;
long bestTime = Long.MIN_VALUE;
List<String> matchingProviders = locationManager.getAllProviders();
for (String provider: matchingProviders) {
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
float accuracy = location.getAccuracy();
long time = location.getTime();
if ((time > minTime && accuracy < bestAccuracy)) {
bestResult = location;
bestAccuracy = accuracy;
bestTime = time;
}
else if (time < minTime && bestAccuracy == Float.MAX_VALUE && time > bestTime) {
bestResult = location;
bestTime = time;
}
}
}
return bestResult;
}
public static void updateLocation(Location location)
{
double latitude, longitude;
latitude = location.getLatitude();
longitude = location.getLongitude();
data.sendSms(latitude, longitude, new Date());
}
class MyLocationListener implements LocationListener
{
@Override
public void onLocationChanged(Location location)
{
updateLocation(location);
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status,
Bundle extras) {
// TODO Auto-generated method stub
}
}
}
DataSharing.java
package com.example.locationtest;
import java.util.Date;
import android.content.Context;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
public class DataSharing {
String message="";
String phoneNo="0300phone#";
Context mAppContext;
public DataSharing()
{
}
public DataSharing(Context context)
{
mAppContext=context;
}
public void setContext(Context context)
{
mAppContext=context;
}
public void sendSms(double clat,double clong,Date d)
{
message="Traffic-Advisor123 Latitude:"+String.valueOf(clat)+"\nLongitude:"+String.valueOf(clong)+"\nTime:"+String.valueOf(d);
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNo, null, message, null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendViaNetwork(double clat,double clong,Date d)
{
TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
}
}
Another problem that I face is that sometimes SMS gets sent even before the 3 minutes have passed. May be that is because some other app asks for location which gets shared with my app as well. I can only process data if its sent with an interval no less than 2 minutes. How can I restrict it to 2+ minutes?
I am looking for some guidance. Thank You.