How to prevent service from quitting in Android? - android

My service is using the ActivityRecognition API and a LocationListener to save the current location when a user stops driving.
It works fine while the app is open, but I'm having no luck keeping detection going after the app has closed.
This is the service to detect activity & save location:
public class ActivityRecognitionService extends IntentService implements LocationListener {
public Location currentBestLocation;
private LocationManager locationManager ;
private String provider;
private String TAG = this.getClass().getSimpleName();
public ActivityRecognitionService() {
super("ActivityRecognitionService");
}
#Override
public void onCreate() {
super.onCreate();
try {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
if (provider != null && !provider.equals("")) {
Location location = locationManager.getLastKnownLocation(provider);
locationManager.requestLocationUpdates(provider, 1000, 1, this);
if (location != null)
onLocationChanged(location);
else
Toast.makeText(this, "Location can't be retrieved", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "No Provider Found", Toast.LENGTH_SHORT).show();
}
} catch(SecurityException e) {
Toast.makeText(this, "Enable location permissions from settings", Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onHandleIntent(Intent intent) {
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
Log.i(TAG, "Detected activity being called... ");
// Get the list of the probable activities associated with the current state of the
// device. Each activity is associated with a confidence level, which is an int between
// 0 and 100.
ArrayList<DetectedActivity> detectedActivities = (ArrayList) result.getProbableActivities();
for (final DetectedActivity activity : detectedActivities) {
Log.i(TAG, "Detected activity: " + getActivityString(activity.getType()) + ", " + activity.getConfidence());
if(activity.getConfidence() < 60)
continue;
logActivity(getActivityString(activity.getType()), activity.getConfidence());
List<UserActivity> userActivities = UserActivity.listAll(UserActivity.class);
if(!userActivities.isEmpty()) {
UserActivity last = userActivities.get(userActivities.size() - 1);
if(last.activity.equals("in vehicle") && activity.getType() != DetectedActivity.IN_VEHICLE) {
logParking();
}
}
}
}
private void logActivity(String type, int confidence) {
UserActivity ua = new UserActivity(type, confidence, (System.currentTimeMillis() / 1000L));
ua.save();
}
private void logParking() {
Location l = currentBestLocation;
CarLocation cl = new CarLocation(l.getLongitude(), l.getLatitude(), (System.currentTimeMillis() / 1000L));
cl.save();
}
static String getActivityString( int detectedActivityType) {
switch(detectedActivityType) {
case DetectedActivity.IN_VEHICLE:
return "in vehicle";
case DetectedActivity.ON_BICYCLE:
return "on bicycle";
case DetectedActivity.ON_FOOT:
return "on foot";
case DetectedActivity.RUNNING:
return "running";
case DetectedActivity.STILL:
return "still";
case DetectedActivity.TILTING:
return "tilting";
case DetectedActivity.UNKNOWN:
return "unknown";
case DetectedActivity.WALKING:
return "walking";
default:
return "unknown";
}
}
/**
* Only replaces current location if this reading is
* more likely to be accurate
* #param location
* #return
*/
private static final int TWO_MINUTES = 1000 * 60 * 2;
protected boolean isBetterLocation(Location location) {
if (currentBestLocation == null) {
// A new location is always better than no location
return true;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use the new location
// because the user has likely moved
if (isSignificantlyNewer) {
return true;
// If the new location is more than two minutes older, it must be worse
} else if (isSignificantlyOlder) {
return false;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and accuracy
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return true;
}
return false;
}
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
#Override
public void onLocationChanged(Location location) {
if(isBetterLocation(location)) {
currentBestLocation = location;
}
}
#Override
public void onProviderDisabled(String provider) {
permissionsCheck();
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public void permissionsCheck() {
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
) {
// Check Permissions Now
ActivityCompat.requestPermissions(
LocationScene.mActivity,
new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
0);
}
}
}
This service is being used to start the above service and keep it running:
public class BackgroundDetectedActivitiesService extends Service {
private static final String TAG = BackgroundDetectedActivitiesService.class.getSimpleName();
IBinder mBinder = new BackgroundDetectedActivitiesService.LocalBinder();
private Intent mIntentService;
private PendingIntent mPendingIntent;
private ActivityRecognitionClient mActivityRecognitionClient;
public BackgroundDetectedActivitiesService() {
}
#Override
public void onCreate() {
super.onCreate();
mActivityRecognitionClient = new ActivityRecognitionClient(this);
mIntentService = new Intent(this, uk.co.appoly.wheres_my_car.services.ActivityRecognitionService.class);
mPendingIntent = PendingIntent.getService(this, 1, mIntentService, PendingIntent.FLAG_UPDATE_CURRENT);
requestActivityUpdatesButtonHandler();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
public void requestActivityUpdatesButtonHandler() {
Task<Void> task = mActivityRecognitionClient.requestActivityUpdates(
20000,
mPendingIntent);
task.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void result) {
Toast.makeText(getApplicationContext(),
"Successfully requested activity updates",
Toast.LENGTH_SHORT)
.show();
}
});
task.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getApplicationContext(),
"Requesting activity updates failed to start",
Toast.LENGTH_SHORT)
.show();
}
});
}
public void removeActivityUpdatesButtonHandler() {
Task<Void> task = mActivityRecognitionClient.removeActivityUpdates(
mPendingIntent);
task.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void result) {
Toast.makeText(getApplicationContext(),
"Removed activity updates successfully!",
Toast.LENGTH_SHORT)
.show();
}
});
task.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getApplicationContext(), "Failed to remove activity updates!",
Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
//removeActivityUpdatesButtonHandler();
/**/
}
public class LocalBinder extends Binder {
public BackgroundDetectedActivitiesService getServerInstance() {
return BackgroundDetectedActivitiesService.this;
}
}
}
I have this in my android manifest:
<service
android:name="uk.co.appoly.wheres_my_car.services.ActivityRecognitionService"
android:exported="false" />
<service android:name="uk.co.appoly.wheres_my_car.services.BackgroundDetectedActivitiesService"></service>
(plus correct permissions)
I am starting the service from my MainActivity like so:
activityRecognitionClient = ActivityRecognition.getClient(mContext);
transitionIntent = new Intent(MainActivity.this, BackgroundDetectedActivitiesService.class);
startService(transitionIntent);
I've been trying to fix this for about a day but to no avail. What am I doing wrong?

Related

How to send user location to server every 5 second in android?

In the Android app that I am working on.
I want to take the user location and send it to the server on a post request every 5 seconds; Even when the app is running in the background
I want to send all geolocation info included bearing.
I need a method to call to start the sending job and a method to stop the sending job.
The plan is to only send the new data as the old ones have already been sent. To avoid overloading data all at once to the server.
you must be writing service and for getting location you use from smartlocation library
public class StatusUserServices extends Service {
public static final String BROADCAST_ACTION = "reporter";
private static final int TWO_SECONDS = 1000 * 2;
public LocationManager locationManager;
public MyLocationListener listener;
public Location previousBestLocation = null;
Intent intent;
int counter = 0;
protected Handler handler;
double lat,longi;
private final LocalBinder mBinder = new LocalBinder();
boolean speed;
public class LocalBinder extends Binder {
public StatusUserServices getService() {
return StatusUserServices .this;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public void onCreate() {
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new MyLocationListener();
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
}
if (locationManager != null){
boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if( !isGPSEnabled && !isNetworkEnabled) {
showGPSDisabledAlertToUser();
} else {
if(isGPSEnabled) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2*1000, 100, listener);
} else if(isNetworkEnabled) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,2*1000,100, listener);
}
}
}
return START_STICKY;
}
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null) {
return true;
}
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
if (isSignificantlyNewer) {
return true;
} else if (isSignificantlyOlder) {
return false;
}
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 3000;
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return true;
}
return false;
}
private void showGPSDisabledAlertToUser(){
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage(getResources().getString(R.string.ActivateGPSQuestion))
.setCancelable(false)
.setPositiveButton(R.string.GoToTheSettingsPage,
(dialog, id) -> {
Intent callGPSSettingIntent = new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(callGPSSettingIntent);
});
alertDialogBuilder.setNegativeButton(R.string.cancel,
(dialog, id) -> dialog.cancel());
AlertDialog alert = alertDialogBuilder.create();
alert.show();
}
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.v("STOP_SERVICE", "DONE");
if (locationManager != null) {
try {
locationManager.removeUpdates(listener);
} catch (Exception ex) {
Log.i("******", "fail to remove location listners, ignore", ex);
}
}
}
public class MyLocationListener implements LocationListener
{
public void onLocationChanged(final Location loc)
{
if(isBetterLocation(loc, previousBestLocation)) {
SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
SimpleDateFormat time= new SimpleDateFormat("HH:mm:ss", Locale.US);
if(loc.getLatitude() == 0.0 && loc.getLongitude() == 0.0){
SmartLocation.with(getApplicationContext()).location()
.start(location -> {
lat = location.getLatitude();
longi = location.getLongitude();
speed = location.hasSpeed();
});
}else{
lat = loc.getLatitude();
longi = loc.getLongitude();
speed = loc.hasSpeed();
}
String times = time.format(new Date());
String dates = date.format(new Date());
intent.putExtra("Latitude", lat);
intent.putExtra("Longitude", longi);
intent.putExtra("Speed", speed);
intent.putExtra("Time", times);
intent.putExtra("Date", dates);
intent.setAction(BROADCAST_ACTION);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public void onProviderDisabled(String provider)
{
}
public void onProviderEnabled(String provider)
{
}
}
}

How to Set permissions for marshmallow and above in background service?

i am having service in which i am getting latitude and longitude from background service. The code is working fine but not working in marshmallow and above
because i need to set permission but i am not getting how to set permission in marshmallow.
This my service class
public class Example_services extends Service {
public static final String BROADCAST_ACTION = "com.guards.anshul.hindguard.CUSTOM_INTENT";
private static final int TWO_MINUTES = 1000 * 60 * 2;
public LocationManager locationManager;
public MyLocationListener listener;
public Location previousBestLocation = null;
public String editTextValue;
Intent intent;
String restoredText;
private final static int MY_PERMISSION_FINE_LOCATION = 101;
#Override
public void onCreate() {
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
if(editTextValue!=null){
editTextValue = intent.getStringExtra("B");
SharedPreferences.Editor editor = getSharedPreferences("Guard_Id", MODE_PRIVATE).edit();
editor.putString("guard_id", editTextValue);
editor.apply();
}else{
SharedPreferences prefs = getSharedPreferences("Guard_Id", MODE_PRIVATE);
restoredText = prefs.getString("guard_id", null);
}
Toast.makeText(Example_services.this.getApplicationContext(),restoredText,Toast.LENGTH_SHORT).show();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new MyLocationListener();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
Toast.makeText(Example_services.this.getApplicationContext(),"Need Permission",Toast.LENGTH_SHORT).show();
return Service.START_STICKY;
}
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 4000, 0, listener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 0, listener);
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null) {
return true;
}
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
if (isSignificantlyNewer) {
return true;
} else if (isSignificantlyOlder) {
return false;
}
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return true;
}
return false;
}
private boolean isSameProvider(String provider1, String provider2){
if(provider1==null){
return provider2 == null;
}
return provider1.equals(provider2);
}
#Override
public void onDestroy() {
// handler.removeCallbacks(sendUpdatesToUI);
super.onDestroy();
Log.v("STOP_SERVICE", "DONE");
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
locationManager.removeUpdates(listener);
}
public static Thread performOnBackgroundThread(final Runnable runnable) {
final Thread t = new Thread() {
#Override
public void run() {
try {
runnable.run();
} finally {
}
}
};
t.start();
return t;
}
public class MyLocationListener implements LocationListener
{
public void onLocationChanged(final Location loc)
{
if(isBetterLocation(loc, previousBestLocation)) {
double v = loc.getLatitude();
double b = loc.getLongitude();
//Log.e("<<a--b>>>>>>",String.valueOf(v)+ String.valueOf(b));
Toast.makeText(getApplicationContext(), String.valueOf(v)+String.valueOf(b), Toast.LENGTH_SHORT).show();
intent.setAction("com.guards.anshul.hindguard.CUSTOM_INTENT");
intent.putExtra("latitude",v);
intent.putExtra("longitude", b);
intent.putExtra("A",restoredText);
intent.putExtra("Provider", loc.getProvider());
sendBroadcast(intent);
}
}
public void onProviderDisabled(String provider)
{
Toast.makeText(getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT).show();
}
public void onProviderEnabled(String provider)
{
Toast.makeText( getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
}
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}
}
You cannot request permissions for your service separately. But your problem is in fact different - you start the service regardless the permission status and this is wrong. You need to fix the logic and check permissions first. IF you got it granted - start the service. If not, let user know if is mandatory for your app to work and let him decide to quit or grant.
You cannot request runtime permissions from a service. You can call checkSelfPermission() to see if you hold the runtime permission, but that is it.
Check to see if you have the right runtime permissions before your activity starts the service. Then, if the service determines that it does not have the permissions (e.g., the user revoked them from Settings), raise a Notification that leads the user back to the activity.

android location manager wrong coordinates for different country

I have made an android app using android services location manager .In which I am using network based location manage to fetch location. App is running good in India and it is giving correct location, but when some of friends outside India (like USA, UK) run this app ,I get wrong coordinate thats points to china or kazakistan. I am not able to understand this problem.If any one has come across this issue , Please let me know.
Thanks in advance.
CODE IS BELOW :
//changes - start for fused location
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
//import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
//changes end for fused location with one comment above library
public class LocationService extends Service
{
//public static final String BROADCAST_ACTION = "Hello World";
private static final int TWO_MINUTES = 1000 * 60 * 2;
public LocationManager locationManager;
public MyLocationListener listener;
public Location previousBestLocation = null;
public String userMobile;
Intent intent;
int counter = 0;
#Override
public void onCreate()
{
super.onCreate();
}
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnected();
}
#Override
public int onStartCommand(Intent intent,int flag, int startId)
{
try {
if (isOnline()) {
try {
int time = 2 * 60 * 1000;
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new MyLocationListener();
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, time, 0, listener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, time, 0, listener);
} catch (Exception e) {
String error = e.getMessage();
}
}
return Service.START_STICKY;
} catch (Exception e){
stopService(new Intent(LocationService.this,LocationService.class));
return Service.START_STICKY;
}
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null) {
// A new location is always better than no location
return true;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use the new location
// because the user has likely moved
if (isSignificantlyNewer) {
return true;
// If the new location is more than two minutes older, it must be worse
} else if (isSignificantlyOlder) {
return false;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and accuracy
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return true;
}
return false;
}
/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
#Override
public void onDestroy() {
// handler.removeCallbacks(sendUpdatesToUI);
super.onDestroy();
//Log.v("STOP_SERVICE", "DONE");
locationManager.removeUpdates(listener);
}
public static Thread performOnBackgroundThread(final Runnable runnable) {
final Thread t = new Thread() {
#Override
public void run() {
try {
runnable.run();
} finally {
}
}
};
t.start();
return t;
}
public class MyLocationListener implements LocationListener
{
class RequestTask extends AsyncTask<String, String, String> {
int timeOut = 0;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... uri) {
String responseString = null;
if(isOnline()) {
///do something....
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
public void onLocationChanged(final Location loc)
{
if(isBetterLocation(loc, previousBestLocation)) {
Double latitude = loc.getLatitude();
Double longitude = loc.getLongitude();
String mainUrl = "www.xyz.com";
Uri.Builder builder = new Uri.Builder();
float invAccuracy = loc.getAccuracy();
float accuracy = 0;
if(invAccuracy > 0.0){
accuracy = 100 - invAccuracy;
}
builder.scheme("http")
.authority(mainUrl)
.appendQueryParameter("acc",Float.toString(accuracy))
.appendQueryParameter("lt",latitude.toString())
.appendQueryParameter("ln",longitude.toString());
String urlStr = builder.build().toString();
new RequestTask().execute(urlStr);
}
}
public void onProviderDisabled(String provider)
{
//Toast.makeText( getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT ).show();
}
public void onProviderEnabled(String provider)
{
//Toast.makeText( getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
}
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}
}

Can't start locationlistener service in Android

I'm trying to implement locationlistener but when I try to start the service nothing happend.
This is what I implemented in the manifestfile:
<service android:name="LocationService"
android:enabled="true"
android:exported="false"
android:label="LocationService"
/>
I implemented a class Locationservice with the following code:
public class LocationService extends Service
{
public static final String BROADCAST_ACTION = "Hello World";
private static final int TWO_MINUTES = 1000 * 60 * 2;
public LocationManager locationManager;
public MyLocationListener listener;
public Location previousBestLocation = null;
Intent intent;
int counter = 0;
#Override
public void onCreate()
{
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
}
#Override
public void onStart(Intent intent, int startId)
{
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new MyLocationListener();
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, listener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null) {
// A new location is always better than no location
return true;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use the new location
// because the user has likely moved
if (isSignificantlyNewer) {
return true;
// If the new location is more than two minutes older, it must be worse
} else if (isSignificantlyOlder) {
return false;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and accuracy
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return true;
}
return false;
}
/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
#Override
public void onDestroy() {
// handler.removeCallbacks(sendUpdatesToUI);
super.onDestroy();
Log.v("STOP_SERVICE", "DONE");
locationManager.removeUpdates(listener);
}
public static Thread performOnBackgroundThread(final Runnable runnable) {
final Thread t = new Thread() {
#Override
public void run() {
try {
runnable.run();
} finally {
}
}
};
t.start();
return t;
}
public class MyLocationListener implements LocationListener
{
public void onLocationChanged(final Location loc)
{
Log.i("**************************************", "Location changed");
if(isBetterLocation(loc, previousBestLocation)) {
loc.getLatitude();
loc.getLongitude();
intent.putExtra("Latitude", loc.getLatitude());
intent.putExtra("Longitude", loc.getLongitude());
intent.putExtra("Provider", loc.getProvider());
sendBroadcast(intent);
//Toast.makeText(MainActivity.this, "Location changed! Data sended to GCM & you are " + distance + "meters away from geofence",Toast.LENGTH_SHORT).show();
}
}
public void onProviderDisabled(String provider)
{
Toast.makeText(getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT).show();
}
public void onProviderEnabled(String provider)
{
Toast.makeText( getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
}
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}
}
And in my Activity class I want to start the service,
Intent LocationService = new Intent(this, HomeActivity.class);
this.startService(LocationService);
Nothing happend when I change from location, anyone know what i'm missing?
An intent is a message to the system. Here you want to tell it to start your LocationService class as a service. To do it you need to provide the class of the Service you want to start: LocationService.class
Intent service = new Intent(this, LocationService.class);
this.startService(service);

Finding Longitudes and latitudes when the app is off

I am new in android.Now i am developing one location based alarm .But in this one i need to take latitudes and longitudes continuously when the user is moving and also the app will be in off mode.I got many codes but all these are working when the app is on.I gave the code below.
Service class
public class LocationLoggerService extends Service {
public static final String BROADCAST_ACTION = "Hello World";
private static final int TWO_MINUTES = 1000 * 60 * 2;
public LocationManager locationManager;
public MyLocationListener listener;
public Location previousBestLocation = null;
Intent intent;
int counter = 0;
#Override
public void onCreate() {
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
}
#Override
public void onStart(Intent intent, int startId) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new MyLocationListener();
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, listener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null) {
// A new location is always better than no location
return true;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use the new location
// because the user has likely moved
if (isSignificantlyNewer) {
return true;
// If the new location is more than two minutes older, it must be worse
} else if (isSignificantlyOlder) {
return false;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and accuracy
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return true;
}
return false;
}
/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
#Override
public void onDestroy() {
// handler.removeCallbacks(sendUpdatesToUI);
super.onDestroy();
Log.v("STOP_SERVICE", "DONE");
locationManager.removeUpdates(listener);
}
public static Thread performOnBackgroundThread(final Runnable runnable) {
final Thread t = new Thread() {
#Override
public void run() {
try {
runnable.run();
} finally {
}
}
};
t.start();
return t;
}
public class MyLocationListener implements LocationListener
{
public void onLocationChanged(final Location loc)
{
Log.i("**************************************", "Location changed");
if(isBetterLocation(loc, previousBestLocation)) {
loc.getLatitude();
loc.getLongitude();
intent.putExtra("Latitude", loc.getLatitude());
intent.putExtra("Longitude", loc.getLongitude());
intent.putExtra("Provider", loc.getProvider());
System.out.println("location"+loc.getLatitude());
sendBroadcast(intent);
/*final Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
String Text = "";
try {
List<Address> addresses = geocoder.getFromLocation(loc.getLatitude(), loc.getLongitude(), 1);
Text = "My current location is: "+addresses.get(0).getAddressLine(0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Text = "My current location is: " +"Latitude = " + loc.getLatitude() + ", Longitude = " + loc.getLongitude();
}
*/
//Toast.makeText( getApplicationContext(), "Location polled to server", Toast.LENGTH_SHORT).show();
}
}
public void onProviderDisabled(String provider)
{
Toast.makeText( getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT ).show();
}
public void onProviderEnabled(String provider)
{
Toast.makeText( getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
}
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}
}
Activity code
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ComponentName comp = new ComponentName(getPackageName(), LocationLoggerService.class.getName());
ComponentName service = startService(new Intent().setComponent(comp));
}
#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;
}
}
Add onStartCommand Method in your Service class
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service onStartCommand");
}
return Service.START_STICKY;
}
here returned is Service.START_STICKY
it will start service even if you kill from recent and app is not running in foreground.
here is more explanation about Service.START_STICKY and START_NON_STICKY

Categories

Resources