I work on a service that need to be stared/stopped from a specific time, collect user's locations and send them to an API.
I start my service like so
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, CONSTANTES.START_HOURS); //6
calendar.set(Calendar.MINUTE, CONSTANTES.START_MINUTES); //30
calendar.set(Calendar.SECOND, CONSTANTES.START_SECOND);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
new Intent(MainActivity.this, AlarmTask.class).setAction("START_SERVICE"), PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarm.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else {
alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
My Receiver
public class AlarmTask extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase("STOP_SERVICE")) {
System.out.println("service : got stop instruction");
if (isMyServiceRunning(context, ScheduleOffsetService.class)) {
context.stopService(new Intent(context, ScheduleOffsetService.class));
}
} else if (intent.getAction().equalsIgnoreCase("START_SERVICE")) {
System.out.println("service : got start instruction");
if (!isMyServiceRunning(context, ScheduleOffsetService.class)) {
context.startService(new Intent(context, ScheduleOffsetService.class));
}
}
}
private boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
And my service :
public class ScheduleOffsetService extends Service {
private LocationManager mLocationManager;
private ArrayList<Location> locations = new ArrayList<>();
private String token;
public ScheduleOffsetService() {
}
private class LocationListener implements android.location.LocationListener {
Location mLastLocation;
public LocationListener(String provider) {
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location) {
System.out.println("Scheduler location : " + location);
mLastLocation.set(location);
locations.add(location);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
LocationListener[] mLocationListeners = new LocationListener[] {
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
stopSelf();
}
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
try {
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000 * 60, 10f, mLocationListeners[1]);
} catch (java.lang.SecurityException ex) {
} catch (IllegalArgumentException ex) {
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 1000 * 60, 10f, mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
} catch (IllegalArgumentException ex) {
}
PropertyApp app = new PropertyApp(this);
System.out.println("ScheduleOffset token : " + app.getToken());
if (app.getToken() != null) {
token = app.getToken();
} else {
stopSelf();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("Scheduler : created");
return START_STICKY;
}
private boolean gpsIsEnable() {
LocationManager manager = (LocationManager) getSystemService(LOCATION_SERVICE);
return manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
#Override
public void onDestroy() {
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
}
}
}
onEnd();
System.out.println("Scheduler : got destroyed");
super.onDestroy();
}
private void onEnd() {
if (locations.isEmpty()) {
return;
}
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(/*URL*/)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
WebServiceInterface webServiceInterface = retrofit.create(WebServiceInterface.class);
JsonObject object = new JsonObject();
for (int i = 0; i < locations.size(); i++) {
JsonObject content = new JsonObject();
content.addProperty("lat", locations.get(i).getLatitude());
content.addProperty("lng", locations.get(i).getLongitude());
Date c = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = df.format(c);
content.addProperty("date", formattedDate);
object.add(String.valueOf(i), content);
}
String data = object.toString();
Call<ResponseRetrofitIreby> call = webServiceInterface.jetLagService(token, PropertyApp.PARNTER_ID, data);
call.enqueue(new Callback<ResponseRetrofitIreby>() {
#Override
public void onResponse(Call<ResponseRetrofitIreby> call, Response<ResponseRetrofitIreby> response) {
if (response.isSuccessful()) {
System.out.println("RESPONSE : " + response.body().getTrackingPosition().getErreur());
}
}
#Override
public void onFailure(Call<ResponseRetrofitIreby> call, Throwable t) {
t.printStackTrace();
}
});
}
}
The thing is : When the user asks to be tracked, the listener of my service is no longer called.
Moreover, if the user kill the application the service seems to restart, and thus empty my list of locations.
Can someone, explain me do to ?
you can try this library location tracker background
Related
I want to track the user location. So I have made a code so that on every 10 mins of interval its location should be hit on server. If it is not moving also the location should hit at 10 min of interval. I set Location interval minutes for 10 min public static final long LOCATION_INTERVAL_MINUTES = 10 * 60 * 1000;
It should update the location with 10 min, but it hits randomly. I also increase the gps frequency distance from 10 to gpsFreqInDistance = 100 .Random hits are stopped but it will not updated on 10 mins of interval.
So what to do to get location at 10 min of interval.
Below is my manifiest
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
As for Android above 10version u cant use background location and foreground location simultaneously. So i comment the ACCESS_BACKGROUND_LOCATION" in my project.
public class LocationMonitoringService implements LocationListener, GpsStatus.Listener {
private static final String TAG = LocationMonitoringService.class.getSimpleName();
private Context mContext;
private LocationRepository mLocationRepository;
private ShareLocationAdapterClass mAdapter;
private SyncOfflineRepository syncOfflineRepository;
private long updatedTime = 0;
private List<UserLocationPojo> mUserLocationPojoList;
private SyncOfflineAttendanceRepository syncOfflineAttendanceRepository;
public LocationMonitoringService(final Context context) {
mContext = context;
mLocationRepository = new LocationRepository(AUtils.mainApplicationConstant.getApplicationContext());
syncOfflineRepository = new SyncOfflineRepository(AUtils.mainApplicationConstant.getApplicationContext());
syncOfflineAttendanceRepository = new SyncOfflineAttendanceRepository(AUtils.mainApplicationConstant.getApplicationContext());
mUserLocationPojoList = new ArrayList<>();
mAdapter = new ShareLocationAdapterClass();
mAdapter.setShareLocationListener(new ShareLocationAdapterClass.ShareLocationListener() {
#Override
public void onSuccessCallBack(boolean isAttendanceOff) {
if (isAttendanceOff && !syncOfflineAttendanceRepository.checkIsAttendanceIn()) {
AUtils.setIsOnduty(false);
((MyApplication) AUtils.mainApplicationConstant).stopLocationTracking();
}
}
#Override
public void onFailureCallBack() {
}
});
}
public void onStartTacking() {
LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
//Exception thrown when GPS or Network provider were not available on the user's device.
try {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
criteria.setAltitudeRequired(false);
criteria.setSpeedRequired(true);
criteria.setCostAllowed(false);
criteria.setBearingRequired(false);
//API level 9 and up
criteria.setHorizontalAccuracy(Criteria.ACCURACY_HIGH);
criteria.setVerticalAccuracy(Criteria.ACCURACY_HIGH);
int gpsFreqInDistance = 100;
assert locationManager != null;
locationManager.addGpsStatusListener(this);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, AUtils.LOCATION_INTERVAL,
gpsFreqInDistance, this, null);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, AUtils.LOCATION_INTERVAL,
gpsFreqInDistance, this, null);
} catch (IllegalArgumentException | SecurityException e) {
Log.e(TAG, Objects.requireNonNull(e.getLocalizedMessage()));
Log.d(TAG, "onStartTacking: " + e.getMessage());
Log.d(TAG, "onStartTacking: " + e.getLocalizedMessage());
e.printStackTrace();
} catch (RuntimeException e) {
Log.e(TAG, Objects.requireNonNull(e.getLocalizedMessage()));
Log.d(TAG, "onStartTacking: " + e.getMessage());
e.printStackTrace();
}
}
public void onStopTracking() {
mAdapter.shareLocation();
LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
locationManager.removeUpdates(this);
}
/*
* LOCATION CALLBACKS
*/
//to get the location change
#Override
public void onLocationChanged(Location location) {
Log.d("okh ", "onLocationChanged: "+System.currentTimeMillis());
if (location != null) {
Log.d(TAG, String.valueOf(location.getAccuracy()));
if (!AUtils.isNullString(String.valueOf(location.getLatitude())) && !AUtils.isNullString(String.valueOf(location.getLongitude()))) {
Prefs.putString(AUtils.LAT, String.valueOf(location.getLatitude()));
Prefs.putString(AUtils.LONG, String.valueOf(location.getLongitude()));
if (Prefs.getBoolean(AUtils.PREFS.IS_ON_DUTY, false)) {
if (updatedTime == 0) {
updatedTime = System.currentTimeMillis();
Log.d(TAG, "updated Time ==== " + updatedTime);
}
if ((updatedTime + AUtils.LOCATION_INTERVAL_MINUTES) <= System.currentTimeMillis()) {
updatedTime = System.currentTimeMillis();
Log.d(TAG, "updated Time ==== " + updatedTime);
}
sendLocation();
}
}
} else {
Log.d(TAG, "onLocationChanged: no location found !!");
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, "onStatusChanged" + provider + "Status" + status);
}
#Override
public void onProviderEnabled(String provider) {
Log.d(TAG, " onProviderEnabled" + provider);
}
#Override
public void onProviderDisabled(String provider) {
Log.d(TAG, " onProviderDisabled" + provider);
}
#Override
public void onGpsStatusChanged(int event) {
}
private void sendLocation() {
// mAdapter.shareLocation(getTempList());
Log.d("okh", "sendLocation: Current Time In Millies "+ System.currentTimeMillis());
try {
Calendar CurrentTime = AUtils.getCurrentTime();
Calendar DutyOffTime = AUtils.getDutyEndTime();
if (CurrentTime.before(DutyOffTime)) {
Log.i(TAG, "Before");
UserLocationPojo userLocationPojo = new UserLocationPojo();
userLocationPojo.setUserId(Prefs.getString(AUtils.PREFS.USER_ID, ""));
userLocationPojo.setLat(Prefs.getString(AUtils.LAT, ""));
userLocationPojo.setLong(Prefs.getString(AUtils.LONG, ""));
double startLat = Double.parseDouble(Prefs.getString(AUtils.LAT, "0"));
double startLng = Double.parseDouble(Prefs.getString(AUtils.LONG, "0"));
userLocationPojo.setDistance(String.valueOf(AUtils.calculateDistance(
AUtils.mainApplicationConstant.getApplicationContext(), startLat, startLng)));
// userLocationPojo.setDatetime(AUtils.getServerDateTime()); //TODO
userLocationPojo.setDatetime(AUtils.getServerDateTimeLocal());
userLocationPojo.setOfflineId("0");
if (AUtils.isInternetAvailable() && AUtils.isConnectedFast(mContext))
userLocationPojo.setIsOffline(true);
else
userLocationPojo.setIsOffline(false);
String UserTypeId = Prefs.getString(AUtils.PREFS.USER_TYPE_ID, AUtils.USER_TYPE.USER_TYPE_GHANTA_GADI);
if (AUtils.isInternetAvailable()) {
TableDataCountPojo.LocationCollectionCount count = syncOfflineRepository.getLocationCollectionCount(AUtils.getLocalDate());
if ((UserTypeId.equals(AUtils.USER_TYPE.USER_TYPE_GHANTA_GADI) || UserTypeId.equals(AUtils.USER_TYPE.USER_TYPE_WASTE_MANAGER))
&& (count.getLocationCount() > 0 || count.getCollectionCount() > 0)) {
syncOfflineRepository.insetUserLocation(userLocationPojo);
} else {
mUserLocationPojoList.add(userLocationPojo);
mAdapter.shareLocation(mUserLocationPojoList);
mUserLocationPojoList.clear();
}
} else {
if (UserTypeId.equals(AUtils.USER_TYPE.USER_TYPE_EMP_SCANNIFY)) {
Type type = new TypeToken<UserLocationPojo>() {
}.getType();
mLocationRepository.insertUserLocationEntity(new Gson().toJson(userLocationPojo, type));
} else {
syncOfflineRepository.insetUserLocation(userLocationPojo);
}
mUserLocationPojoList.clear();
}
}
else {
Log.i(TAG, "After");
syncOfflineAttendanceRepository.performCollectionInsert(mContext,
syncOfflineAttendanceRepository.checkAttendance(), AUtils.getCurrentDateDutyOffTime());
AUtils.setIsOnduty(false);
((MyApplication) AUtils.mainApplicationConstant).stopLocationTracking();
Activity activity = ((Activity) AUtils.currentContextConstant);
if (activity instanceof DashboardActivity) {
((Activity) AUtils.currentContextConstant).recreate();
AUtils.DutyOffFromService = true;
}
if (!AUtils.isNull(AUtils.currentContextConstant)) {
((Activity) AUtils.currentContextConstant).recreate();
}
}
} catch (Exception e) {
e.printStackTrace();
}
Below is the foreground service which i have used
public class ForgroundService extends Service {
private LocationMonitoringService monitoringService;
private Handler locationHandler;
private Runnable locationThread;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
// Toast.makeText(this, " MyService Created ", Toast.LENGTH_LONG).show();
Log.d("okh", "onCreate: " +System.currentTimeMillis());
monitoringService = new LocationMonitoringService(this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Toast.makeText(this, " MyService Started", Toast.LENGTH_LONG).show();
Log.d("okh", "onCreate: " +System.currentTimeMillis());
Log.d("okh", "onStartCommand: ");
final int currentId = startId;
locationThread = new Runnable() {
public void run() {
monitoringService.onStartTacking();
}
};
locationHandler = new Handler(Looper.getMainLooper());
locationHandler.post(locationThread);
startLocationForeground();
return Service.START_STICKY;
// return Service.START_NOT_STICKY;
}
#Override
public void onDestroy() {
//Toast.makeText(this, "MyService Stopped", Toast.LENGTH_LONG).show();
locationHandler.removeCallbacks(locationThread);
monitoringService.onStopTracking();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
{
stopForeground(STOP_FOREGROUND_REMOVE);
}
if(Prefs.getBoolean(AUtils.PREFS.IS_ON_DUTY,false))
{
Intent broadcastIntent = new Intent(this, RestarterBroadcastReceiver.class);
sendBroadcast(broadcastIntent);
}
}
private void startLocationForeground() {
if (Build.VERSION.SDK_INT >= 26) {
String channelId = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
? this.createNotificationChannel("my_service", "My Background Service")
: "";
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder((Context) this,
channelId);
Notification notification = notificationBuilder
.setOngoing(true)
.setContentText("Please don't kill the app from background. Thank you!!")
.setSmallIcon(getNotificationIcon(notificationBuilder))
.setPriority(-2)
.setCategory("service")
.build();
startForeground(101, notification);
}
}
#RequiresApi(26)
private String createNotificationChannel(String channelId, String channelName) {
NotificationChannel chan = new NotificationChannel(channelId, (CharSequence)channelName,
NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager service = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
service.createNotificationChannel(chan);
return channelId;
}
private int getNotificationIcon(NotificationCompat.Builder notificationBuilder) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int color = 0x008000;
notificationBuilder.setColor(color);
return R.drawable.ic_noti_icon;
}
return R.drawable.ic_noti_icon;
}
}
Why you are passing null in the last parameter? Did you try without passing that?
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, AUtils.LOCATION_INTERVAL,
gpsFreqInDistance, this, null);
First of all Google Location Services are far better than Traditional LocationManager to achieve this requirement.
https://developer.android.com/training/location/request-updates
I am using retrofit 1.9 in order to create and use connections with server , its working perfectly in app , but when i am trying to hit api in a service , it is returning me this error
"retrofit.RetrofitError: unexpected end of stream on Connection{, proxy=DIRECT# cipherSuite=none protocol=http/1.1} (recycle count=0)"
and only in some devices like for instance in my Xiaomi Redmi note 3.
Here is my code:-
public class TrackingService extends Service implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private String latitude = "", longitude = "";
private PrefsManager mPrefs;
int requestID = 42;
private int time = 120000;
private static final long SERVICE_INTERVAL = 60000;
private static final long SERVICE_FASTEST = 30000;
private static final long ONE_MIN = 1000;
private GoogleApiClient googleApiClient;
private FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
private boolean canGetLocation = false;
private LocationRequest locationRequest;
private LocationManager locationManager;
private final String TAG = "MyAwesomeApp";
private Runnable runnable = new Runnable() {
#Override
public void run() {
updateLocation();
}
};
private Handler handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
getHandler1().postDelayed(runnable, time);
return true;
}
});
private Handler handler1 = new Handler();
public Handler getHandler1() {
return handler1;
}
private NotificationCompat.Builder mBuilder;
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
canGetLocation = !(!locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER) && !locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER));
}
};
private BroadcastReceiver receiverNetwork = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
handler.removeCallbacksAndMessages(null);
getHandler1().removeCallbacks(runnable);
time = 5000;
handler.sendMessage(new Message());
}
};
private static API REST_CLIENT;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
registerReceiver(receiverNetwork, new IntentFilter(Constants.NETWORK_BROADCAST));
registerReceiver(receiver, new IntentFilter(Constants.INTENT_LOCATION_SERVICE));
}
private void init() {
mPrefs = new PrefsManager(this);
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
locationRequest.setInterval(SERVICE_INTERVAL);
locationRequest.setFastestInterval(SERVICE_FASTEST);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
canGetLocation = !(!locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER) && !locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER));
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
try {
googleApiClient.connect();
} catch (Exception e) {
e.printStackTrace();
}
updateLocation();
}
#Override
public void onDestroy() {
Log.e(TAG, "GPSTrackerNew destroyed!");
googleApiClient.disconnect();
try {
unregisterReceiver(receiverNetwork);
unregisterReceiver(receiver);
} catch (Exception e) {
e.printStackTrace();
}
this.stopForeground(true);
super.onDestroy();
}
/**
* Update driver location for live tracking
*/
private void updateLocation() {
if (canGetLocation()) {
/*setNotification(this, getResources().getString(R.string.tracking));*/
if (!TextUtils.isEmpty(latitude) && !TextUtils.isEmpty(longitude)) {
get().updateLocation(mPrefs.getAccessToken(), latitude, longitude,
new Callback<PojoBase>() {
#Override
public void success(PojoBase pojoBase, Response response) {
try {
if (pojoBase.status == Constants.SUCCESS) {
time = 120000;
handler.removeCallbacksAndMessages(null);
getHandler1().removeCallbacks(runnable);
handler.sendMessage(new Message());
setNotification(TrackingService.this, getResources().getString(R.string.tracking));
} else if (pojoBase.status == Constants.LOGIN_EXPIRED) {
onDestroy();
}
} catch (Exception e) {
onDestroy();
e.printStackTrace();
}
}
#Override
public void failure(RetrofitError error) {
time = 5000;
setNotification(TrackingService.this, getResources().getString(R.string.network_error));
handler.removeCallbacksAndMessages(null);
getHandler1().removeCallbacks(runnable);
handler.sendMessage(new Message());
}
});
} else {
time = 5000;
handler.removeCallbacksAndMessages(null);
getHandler1().removeCallbacks(runnable);
handler.sendMessage(new Message());
}
} else {
time = 5000;
handler.removeCallbacksAndMessages(null);
getHandler1().removeCallbacks(runnable);
handler.sendMessage(new Message());
setNotification(this, getResources().getString(R.string.not_able_to_fetch_location));
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
init();
return START_STICKY;
}
private void setNotification(Context context, String message) {
Intent intent = null;
intent = new Intent(this, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, requestID,
intent, 0);
mBuilder = new NotificationCompat.Builder(context)
.setContentTitle(getResources().getString(R.string.app_name))
.setOngoing(true)
.setContentText(message)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent);
this.startForeground(requestID, mBuilder.build());
}
#Override
public void onConnected(#Nullable Bundle bundle) {
fusedLocationProviderApi.requestLocationUpdates(googleApiClient,
locationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "GoogleApiClient connection has been suspend");
}
#Override
public void onLocationChanged(Location location) {
if (location != null) {
Log.i("From service:", "Location received: " + location.toString());
canGetLocation = true;
latitude = String.valueOf(location.getLatitude());
longitude = String.valueOf(location.getLongitude());
} else {
canGetLocation = false;
}
}
public boolean canGetLocation() {
return canGetLocation;
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "GoogleApiClient connection has been failed");
}
public static API get() {
if (REST_CLIENT == null) {
RestAdapter.Builder adapter = new RestAdapter.Builder()
.setClient(new OkClient(getClient()));
adapter.setLogLevel(RestAdapter.LogLevel.BASIC);
adapter.setEndpoint(Constants.ROOT);
RestAdapter mAdapter = adapter.build();
REST_CLIENT = mAdapter.create(API.class);
}
return REST_CLIENT;
}
private static OkHttpClient getClient() {
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(30, TimeUnit.SECONDS);
return client;
}
}
Can anyone tell why is this happening ?
TIA
Try to use execute instead enqueue call.Services is already on different thread. So if you are making a network call on different thread you should run api on same thread.
I have made a location update foreground service which gets locations directly(requestLocationUpdates) when interval is less than 30 secs and if its more than 30 sec, I use ScheduledExecutorService to get the location result and pool location results to get the best location. Only issue I am facing is I am not getting location updates when screen goes off. This code is working well till mobile screen goes off.
Please take care its a foreground service.
My Code is as below:
private boolean currentlyProcessingLocation = false;
public static int intervalForLocationRequestMethod = 500;
public static int intervalForLocationUpdates = 30000;
public int locationUpdateMethodThreshold = 5000;
public int sameLocationCounter = 0;
boolean locationUpdateMethodChanged = false;
ScheduledExecutorService sch;
Runnable periodicTask = new Runnable() {
#Override
public void run() {
Log.i(TAG, "run: repeat ");
Intent i = new Intent(LocationService.this, LocationService.class);
i.setAction(Constants.ACTION.STARTLOCATIONREPEAT_ACTION);
startService(i);
}
};
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate: ");
buildGoogleApiClient();
if (intervalForLocationUpdates <= locationUpdateMethodThreshold) {
intervalForLocationRequestMethod = intervalForLocationUpdates;
}
showOnGoingLocationServiceNotification();
}
private void showOnGoingLocationServiceNotification() {
Log.i(TAG, "showOnGoingLocationServiceNotification: ");
Intent notificationIntent = new Intent(this, MapsActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MapsActivity.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("Forcee")
.setTicker("Forcee Tracking")
.setColor(Color.GREEN)
.setContentText("Forcee is tracking your location....Tap to stop")
.setSmallIcon(R.drawable.cast_ic_notification_small_icon)
.setWhen(System.currentTimeMillis())
.setContentIntent(resultPendingIntent)
.setOngoing(true).build();
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, notification);}
#Override
public void onConnected(#Nullable Bundle bundle) {
mLocationRequest = LocationRequest.create();
mLocationRequest.setFastestInterval(intervalForLocationRequestMethod);
mLocationRequest.setInterval(intervalForLocationRequestMethod);
if (intervalForLocationUpdates <= locationUpdateMethodThreshold || locationUpdateMethodChanged) {
mLocationRequest.setSmallestDisplacement(50);
}
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand: ");
Thread thread = new Thread(new LocationUpdateThread(intent, startId));
thread.start();
return START_STICKY;
}
#Override
public void onLocationChanged(Location location) {
Log.i(TAG, "onLocationChanged: " + location);
if (lastLocation != null) {
if (location.distanceTo(lastLocation) >= 40.0f && locationUpdateMethodChanged && location.getAccuracy() <= 100.0f) {
locationUpdateMethodChanged = false;
currentlyProcessingLocation = false;
sch = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1);
sch.scheduleAtFixedRate(periodicTask, intervalForLocationUpdates, intervalForLocationUpdates, TimeUnit.MILLISECONDS);
}
}
if (location.getAccuracy() <= 100.0f) {
if (firstLocationUpdateCall) {
updatingLocation(location);
firstLocationUpdateCall = false;
} else {
if (location.distanceTo(lastLocation) >= 40.0f) {
updatingLocation(location);
sameLocationCounter = 0;
} else {
if (intervalForLocationUpdates > locationUpdateMethodThreshold && !locationUpdateMethodChanged) {
sameLocationCounter++;
lastLocation = location;
Log.i(TAG, "onLocationChanged: " + sameLocationCounter);
if (sameLocationCounter == 5) {
locationUpdateMethodChanged = true;
intervalForLocationRequestMethod = 1000;
stopLocationUpdates();
sameLocationCounter = 0;
sch.shutdownNow();
sch = null;
Intent i = new Intent(LocationService.this, LocationService.class);
i.setAction(Constants.ACTION.STARTLOCATIONREPEAT_ACTION);
startService(i);
}
Log.i(TAG, "onLocationChanged: " + locationUpdateMethodChanged);
}
}
if (intervalForLocationUpdates> locationUpdateMethodThreshold && !locationUpdateMethodChanged) {
stopLocationUpdates();
Log.i(TAG, "onLocationChanged: stopcheckshift");
}
}
}
}
public void updatingLocation(Location location) {
lastLocation = location;
Log.i(TAG, "onLocationChanged: First " + locationPoints.size());
locationPoints.add(location);
Log.i(TAG, "onLocationChanged: Last " + locationPoints.size());
sendLocationsToActivity(locationPoints);
if (intervalForLocationUpdates > locationUpdateMethodThreshold) {
stopLocationUpdates();
}
}
public void sendLocationsToActivity(ArrayList<Location> locationPoints) {
Log.i(TAG, "sendLocationsToActivity: ");
Intent intent = new Intent("LocationUpdates");
intent.putParcelableArrayListExtra("Locations", locationPoints);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
private void stopLocationUpdates() {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, LocationService.this);
mGoogleApiClient.disconnect();
currentlyProcessingLocation = false;
}
}
final class LocationUpdateThread implements Runnable {
int service_id;
Intent intent;
LocationUpdateThread(Intent intent, int service_id) {
this.intent = intent;
this.service_id = service_id;
}
#Override
public void run() {
Log.i(TAG, "run: ");
if (intent != null) {
Log.i(TAG, "run: " + intent.getAction());
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
toastHandler("Tracking Started!");
mGoogleApiClient.connect();
currentlyProcessingLocation = true;
if (intervalForLocationUpdates > locationUpdateMethodThreshold) {
sch = Executors.newScheduledThreadPool(1);
sch.scheduleAtFixedRate(periodicTask, intervalForLocationUpdates, intervalForLocationUpdates, TimeUnit.MILLISECONDS);
}
} else if (intent.getAction().equals(Constants.ACTION.STARTLOCATIONREPEAT_ACTION)) {
if (!currentlyProcessingLocation) {
Log.i(TAG, "run: curt");
checkLocationSettings();
currentlyProcessingLocation = true;
mGoogleApiClient.connect();
}
} else if (intent.getAction().equals(Constants.ACTION.STOPFOREGROUND_ACTION)) {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, LocationService.this);
mGoogleApiClient.disconnect();
}
if (sch != null) {
sch.shutdownNow();
}
stopForeground(true);
stopSelf();
toastHandler("Tracking Stopped!");
}
}
}
void toastHandler(final String msg) {
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
public void run() {
Toast.makeText(LocationService.this, msg, Toast.LENGTH_SHORT).show();
}
});
}
}
---------UPDATE -----------------------------------------
When the app starts I receive numberformat exception at line :
final long thetime=Long.parseLong(time_value);
But the above aren't in the main activity...
In the xml file I have in the edittex
android:inputType="number" .
This line is in myservice class in which I have the alarmamanager(note I can't use catch because below(alarm.setRepeating) it doesn't recognize "thetime" value.
protected void onHandleIntent(Intent intent) {
//try{
String time_value;
time_value=(String) intent.getStringExtra("time_value");
final long thetime=Long.parseLong(time_value);// }
// catch (NumberFormatException e) {
//}
mContext = getApplicationContext();
mHandler.post(new Runnable(){
#Override
public void run() {
// Start service using AlarmManager
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 10);
Intent intent = new Intent(myservice.this,selection.class);
PendingIntent pintent = PendingIntent.getService(myservice.this, 0, intent,
0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
thetime*1000, pintent);
// Tell the user about what we did.
Toast.makeText(myservice.this, "Configured time interval",
Toast.LENGTH_LONG).show();
}
});
}
}
I load the time_value from another activity:
public void onClick(View v) {
switch (v.getId()){
case R.id.btn:
edit11=edit1.getText().toString();
edit22=edit2.getText().toString();
Intent i=new Intent(this,selection.class);
i.putExtra("code_value",edit11);
Intent k=new Intent(this,myservice.class);
k.putExtra("time_value",edit22);
this.startService(k);
Intent l=new Intent(this,MainActivity.class);
startActivity(l);
break;
}
}
because I made lonfitude and latitude Strings (I had them as double before). How can I overcome that?
To get String from double use String.valueOf();
String latitude = String.valueOf(location.getLatitude());
Repeat
Also,how can I select to send the data in time intervals that the user will define?
To repeat at specific interval use AlarmManager.
how can I select to send the data in time intervals that the user will define
You can use Timer and TimerTask. Take the user input for time interval and pass it to schedule() of Timer. Thing that should be taken into consideration is when app is closed or user changes time interval then cancel previous TimerTask and purge Timer, if any.
For Alarm, do the following in your activity class:
PendingIntent Sender = null;
Intent AlarmIntent = new Intent("com.example.gpstrackdemo.RECEIVEALARM");
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);
AlarmIntent is the intent for BroadcastReceiver. Here is its code:
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");
}
}
On receiving the broadcast, it will start Location service, in which we will get current location of user.
Service Class:
public class MyLocationService extends Service implements
OnLocationReceivedListener {
private LocationManager manager;
private Location location = null;
PowerManager powerManager;
private WakeLock wakeLock;
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 count = 0;
boolean isGPS;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v(TAG, "onStartCommand called");
getCurrentLocation();
return START_STICKY;
}
#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 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, 1000L,
50.0f, mGPSLocationListener);
}
if(manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000L,
50.0f, mNetworkLocationListener);
}
myLocTimer = new Timer("LocationRunner", true);
myLocTimer.schedule(mTimerTask, 0, 500);
}
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) {
}
}
public class NetworkLocationListener 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() {
count++;
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");
onLocationReceived(location);
myLocTimer.cancel();
myLocTimer.purge();
mTimerTask.cancel();
return;
} else {
isGPS = false;
if (location == null && count == MAX_ATTEMPTS) {
turnGPSOff();
location = manager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
onLocationReceived(location);
myLocTimer.cancel();
myLocTimer.purge();
mTimerTask.cancel();
return;
}
} else {
return;
}
}
count = 0;
}
};
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:
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:
break;
case GpsStatus.GPS_EVENT_STARTED:
break;
case GpsStatus.GPS_EVENT_STOPPED:
break;
default:
break;
}
}
};
public void onDestroy() {
super.onDestroy();
if (myLocTimer != null) {
myLocTimer.cancel();
myLocTimer.purge(); //Timer not required any more
}
if (mTimerTask != null) {
if (mTimerTask.r != null) {
mTimerTask.mHandler.removeCallbacks(mTimerTask.r);
}
}
if (manager != null) {
if (mGPSLocationListener != null) {
manager.removeUpdates(mGPSLocationListener);
}
//remove location updates for listener once your work is done, otherwise it will drain battery
if (mNetworkLocationListener != null) {
manager.removeUpdates(mNetworkLocationListener);
}
if (mGPSStatusListener != null) {
manager.removeGpsStatusListener(mGPSStatusListener);
}
}
}
#Override
public void onLocationReceived(Location mLoc) {
//Send data to http server once you get location.
}
}
Here my service class implements a listener which have a callback method onLocationReceived in which you can do your stuff after you get location.
public interface OnLocationReceivedListener {
public void onLocationReceived(Location mLoc);
}
And in your manifest, declare broadcast receiver and service respectively:
<receiver
android:name=".receiver.StartServiceReceiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="com.example.gpstrackdemo.RECEIVEALARM" />
</intent-filter>
</receiver>
<service android:name=".service.MyLocationService"
android:enabled="true"></service>
Ok, I had forgot the :
startService() im my main activity.
I had to put it in myservice activity.
Thanks to all
I am using locationListener with Gps.When my Gps symbol gets stable(i.e stop blinking) means it has got the new location ,at that time it hangs my app for a while.I am using locationListener in Service.But when I run "Maps" application(google maps.apk application) it runs smoothly on Gps.so Whats is the problem whit my app that runs very smoothly if Gps is off.
My Code is here
public class LocationUpdateService extends Service implements IActionController{
private LocationManager _locationManager;
private String _provider;
private boolean _gpsEnabled;
private boolean _networkEnabled;
private String _json;
private boolean _locationSendingByCheckIn;
private Intent _intent;
int i=1;
//private boolean _locationAvailable;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
i=1;
String tracking_key = MySharedPreference.getString(MySharedPreference.APP_TRACKING_KEY,"",getApplicationContext());
if (tracking_key == null || tracking_key.equals("")||!MySharedPreference.getBoolean(MySharedPreference.APP_ALLOWED_TO_POST_LOCATION, false, getApplicationContext()))
{
stopService(new Intent(getApplicationContext(),LocationUpdateService.class));
}
else
{
_locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
setLocationSendingAlarm(AppConstants.PENDING_INTENET_LOCATION_PROVIDER_ENABLE_ALARM_ID);
getLocation();
}
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
try {
if(!MySharedPreference.getBoolean(MySharedPreference.APP_ALLOWED_TO_POST_LOCATION, false, getApplicationContext()))
{
stopService(new Intent(getApplicationContext(),LocationUpdateService.class));
return;
}
else if (intent.getExtras() != null)
{
if (intent.getExtras().getBoolean("locationSendingAlarm"))
{
_locationSendingByCheckIn=false;
_gpsEnabled=_locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
_networkEnabled=_locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
String _providerOld=MySharedPreference.getString(MySharedPreference.PREVIOUS_LOCATION_PROVIDER, "", getApplicationContext());
if(_providerOld.equalsIgnoreCase(LocationManager.GPS_PROVIDER)&&_locationManager!=null&&!_gpsEnabled&&_networkEnabled)
{
_locationManager.removeUpdates(locationListener);
getLocation();
sendLocationOnServer(LocationUpdateService.this,AppConstants.APP_REPORT_TYPE_SOS);
}
else if((_providerOld.equalsIgnoreCase(LocationManager.NETWORK_PROVIDER))&&_gpsEnabled)
{
sendLocationOnServer(LocationUpdateService.this,AppConstants.APP_REPORT_TYPE_SOS);
if(_locationManager != null) _locationManager.removeUpdates(locationListener);
getLocation();
}
else if(_providerOld.equalsIgnoreCase(""))
{
if(_locationManager != null) _locationManager.removeUpdates(locationListener);
getLocation();
}
else
{
sendLocationOnServer(LocationUpdateService.this,AppConstants.APP_REPORT_TYPE_SOS);
}
}
else if(intent.getExtras().getBoolean(AppConstants.APP_REPORT_TYPE_CHECK_IN))
{
_intent=new Intent(AppConstants.CHECK_IN_BROADCAST_RECEIVER);
_locationSendingByCheckIn=true;
sendLocationOnServer(LocationUpdateService.this,AppConstants.APP_REPORT_TYPE_CHECK_IN);
}
else if(intent.getExtras().getBoolean(AppConstants.APP_SETTINGS_CHANGED))
{
setLocationSendingAlarm(AppConstants.PENDING_INTENET_LOCATION_PROVIDER_ENABLE_ALARM_ID);
if(_locationManager != null) _locationManager.removeUpdates(locationListener);
getLocation();
}
}
}
catch (Exception e) {
}
}
private void getLocation()
{
try{
_gpsEnabled=_locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
_networkEnabled=_locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
/*if(!_gpsEnabled && !_networkEnabled)
{
}*/
/*Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
_provider = _locationManager.getBestProvider(criteria, false);*/
/* Bundle bundle = new Bundle();
// they would help boost my gps,
boolean xtraInjection=_locationManager.sendExtraCommand(LocationManager.GPS_PROVIDER,
"force_xtra_injection",bundle);
boolean timeInjection=_locationManager.sendExtraCommand(LocationManager.GPS_PROVIDER,
"force_time_injection",bundle);*/
long timeInterval=getTimeInterval();
try
{
if(timeInterval==1000*60)
timeInterval=1000*60*2-1000*20; //100 seconds
else if(timeInterval==1000*60*5)
timeInterval=1000*60*5-1000*30;// 4.5 minutes
else timeInterval=1000*60*5-1000*30; //4.5 minutes
}
catch (Exception e) {
timeInterval=1000*60*5-1000*30; //4.5 min
}
if(_gpsEnabled)
{
_locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,timeInterval,200,locationListener);
return;
}
else if(_networkEnabled)
{
_locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,timeInterval,200,locationListener);
return;
}
else
{
MySharedPreference.putString(MySharedPreference.PREVIOUS_LOCATION_PROVIDER, "", getApplicationContext());
}
/*Location location = _locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(null==location)
{
location = _locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
if(null==location)
{
location = _locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
}
else if(location != null && location.getProvider()!=null)
{
_locationManager.requestLocationUpdates(location.getProvider(),5*60*1000,0,locationListener);
_locationAvailable=true;
}*/
}
catch(Exception ex)
{
MySharedPreference.putString(MySharedPreference.PREVIOUS_LOCATION_PROVIDER, "", getApplicationContext());
}
}
/**
*
* Location listener
*/
LocationListener locationListener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
/*
Toast.makeText(getApplicationContext(), "status changed", Toast.LENGTH_SHORT).show();
switch (status) {
case LocationProvider.OUT_OF_SERVICE:
break;
case LocationProvider.TEMPORARILY_UNAVAILABLE:
break;
case LocationProvider.AVAILABLE:
break;
}*/
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onLocationChanged(final Location location) {
Toast.makeText(getApplicationContext(), ""+i, Toast.LENGTH_SHORT).show();
i++;
saveLocation(getApplicationContext(),location);
}
};
public void saveLocation(Context context, Location location)
{
if(location!=null)
{
double _latitude=location.getLatitude();
double _longitude=location.getLongitude();
double _altidude=location.getAltitude();
float _accuracy=location.getAccuracy();
float _bearing=location.getBearing();
float _speed=location.getSpeed() * 3.6f;
long _time=location.getTime();
String _address=getAddress(location);
double _latitudeOld =MySharedPreference.getFloat(MySharedPreference.PREVIOUS_LOCATION_LATITUDE, 0.0f, context);
double _longitudeOld=MySharedPreference.getFloat(MySharedPreference.PREVIOUS_LOCATION_LONGITUDE, (float)0.0, context);
MySharedPreference.putBoolean(MySharedPreference.IS_LOCATION_STATIC, _latitude == _latitudeOld && _longitude == _longitudeOld, context);
MySharedPreference.putFloat(MySharedPreference.PREVIOUS_LOCATION_LATITUDE, (float)_latitude, context);
MySharedPreference.putFloat(MySharedPreference.PREVIOUS_LOCATION_LONGITUDE, (float)_longitude, context);
MySharedPreference.putFloat(MySharedPreference.PREVIOUS_LOCATION_ALTITUDE, (float)_altidude, context);
MySharedPreference.putFloat(MySharedPreference.PREVIOUS_LOCATION_ACCURACY, _accuracy, context);;;
MySharedPreference.putFloat(MySharedPreference.PREVIOUS_LOCATION_BEARING, _bearing, context);;
MySharedPreference.putFloat(MySharedPreference.PREVIOUS_LOCATION_SPEED, _speed, context);; ;
MySharedPreference.putLong(MySharedPreference.PREVIOUS_LOCATION_TIME, _time, context);
MySharedPreference.putString(MySharedPreference.PREVIOUS_LOCATION_ADDRESS, _address, context);
MySharedPreference.putString(MySharedPreference.PREVIOUS_LOCATION_PROVIDER, location.getProvider(), context);
if(NativeHelper.getDistanceInMeter(_latitude, _longitude, _latitudeOld, _longitudeOld) >= 330)
{
sendLocationOnServer( LocationUpdateService.this, AppConstants.APP_REPORT_TYPE_SOS);
setLocationSendingAlarm(AppConstants.PENDING_INTENET_LOCATION_PROVIDER_ENABLE_ALARM_ID);
}
}
}
public void sendLocationOnServer(Context context, String reportType)
{
try{
String tracking_key = MySharedPreference.getString(MySharedPreference.APP_TRACKING_KEY,"",context);
String _providerOld=MySharedPreference.getString(MySharedPreference.PREVIOUS_LOCATION_PROVIDER, "", context);
if (tracking_key == null || tracking_key.equals("") ||_providerOld.equals(""))
{
return ;
}
double _latitudeOld=MySharedPreference.getFloat(MySharedPreference.PREVIOUS_LOCATION_LATITUDE, 0.0f, context);
double _longitudeOld=MySharedPreference.getFloat(MySharedPreference.PREVIOUS_LOCATION_LONGITUDE, (float)0.0, context);
double _altidudeOld=MySharedPreference.getFloat(MySharedPreference.PREVIOUS_LOCATION_ALTITUDE, (float)0.0, context);
float _accuracyOld=MySharedPreference.getFloat(MySharedPreference.PREVIOUS_LOCATION_ACCURACY, (float)0.0, context);;;
float _bearingOld=MySharedPreference.getFloat(MySharedPreference.PREVIOUS_LOCATION_BEARING, (float)0.0, context);;
float _speedOld=MySharedPreference.getFloat(MySharedPreference.PREVIOUS_LOCATION_SPEED, (float)0.0, context);; ;
boolean isStatic = MySharedPreference.getBoolean(MySharedPreference.IS_LOCATION_STATIC, false, context);
String _addressOld=MySharedPreference.getString(MySharedPreference.PREVIOUS_LOCATION_ADDRESS, "Address not available", context);
RequestAppLocationSending appLocationSending=new RequestAppLocationSending();
appLocationSending.setImei(NativeHelper.getDeviceId(context));
appLocationSending.setBattery((int)TrackMyDeviceUtils.getBatteryLevel(context));
appLocationSending.setLatitude(_latitudeOld);
appLocationSending.setLongitude(_longitudeOld);
appLocationSending.setAltitude((int)_altidudeOld );
appLocationSending.setAccuracy(_accuracyOld);
appLocationSending.setCouse(_bearingOld);
appLocationSending.setSpeed(_speedOld);
appLocationSending.setTracking_key(tracking_key);
appLocationSending.setAddress(_addressOld);
appLocationSending.setDate(TrackMyDeviceUtils.getFormatedDateForLocationSending());
appLocationSending.setReportType(reportType);
appLocationSending.setStatic(isStatic);
if(_providerOld.equalsIgnoreCase(LocationManager.GPS_PROVIDER))
appLocationSending.setData_source("G");
else
appLocationSending.setData_source("N");
_json= appLocationSending.toJson();
LocationSendingController locationSendingController=new LocationSendingController((IActionController)context, EventType.APP_LOCATION_SENDING);
try {
locationSendingController.requestService(_json);
} catch (Exception e) {
}
}
catch (Exception e) {
e.printStackTrace();
}
}
private String getAddress(Location location)
{
List<Address> addresses;
try{
addresses = new Geocoder(this,Locale.getDefault()).getFromLocation(location.getLatitude(), location.getLongitude(), 1);
return findAddress(addresses);
}
catch (Exception e) {
try{
addresses= ReverseGeocode.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
return findAddress(addresses);
}
catch (Exception e1) {
return "Address not available";
}
}
//return "Address not available";
}
private String findAddress(List<Address> addresses)
{
String address="Address not available";
if(addresses!=null)
{
for(int i=0;i<addresses.size();i++){
Address addre=addresses.get(i);
String street=addre.getAddressLine(0);
if(null==street)
street="";
String city=addre.getLocality();
if(city==null) city="";
/*if(city!=null)
MySharedPreference.putString(MySharedPreference.PREVIOUS_CITY_NAME, city, getApplicationContext());
else
city=MySharedPreference.getString(MySharedPreference.PREVIOUS_CITY_NAME, "", getApplicationContext());*/
String state=addre.getAdminArea();
if(state==null) state="";
/*if(state!=null)
MySharedPreference.putString(MySharedPreference.PREVIOUS_STATE_NAME, state, getApplicationContext());
else
state=MySharedPreference.getString(MySharedPreference.PREVIOUS_STATE_NAME, "", getApplicationContext());*/
String country=addre.getCountryName();
if(country==null) country="";
/*if(country!=null)
MySharedPreference.putString(MySharedPreference.PREVIOUS_COUNTRY_NAME, country, getApplicationContext());
else
country=MySharedPreference.getString(MySharedPreference.PREVIOUS_COUNTRY_NAME, "", getApplicationContext());*/
address=street+", "+city+", "+state+", "+country;
}
return address;
}
return address;
}
private void setLocationSendingAlarm(int alarmId) {
AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), LocationUpdateService.class);
intent.putExtra("locationSendingAlarm", true);
PendingIntent pendingIntent = PendingIntent.getService(this, AppConstants.PENDING_INTENET_LOCATION_PROVIDER_ENABLE_ALARM_ID, intent,0);
try {
alarmManager.cancel(pendingIntent);
} catch (Exception e) {
}
long timeForAlarm=getTimeInterval();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+timeForAlarm, timeForAlarm,pendingIntent);
}
private void cancleAlarm(int alarmId)
{
AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), LocationUpdateService.class);
intent.putExtra("locationSendingAlarm", true);
PendingIntent pendingIntent;
pendingIntent = PendingIntent.getService(this, AppConstants.PENDING_INTENET_LOCATION_PROVIDER_ENABLE_ALARM_ID, intent, 0);
try {
alarmManager.cancel(pendingIntent);
}
catch (Exception e) {
}
}
#Override
public Activity getMyActivityReference() {
return null;
}
#Override
public void setScreenData(Object screenData, int event, long time) {
Message msg=new Message();
msg.obj=screenData;
msg.arg1=event;
handler.sendMessage(msg);
}
protected Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
updateUI(msg);
}
};
public void updateUI(Message o)
{
try{
if(o.obj instanceof MyError) {
switch(((MyError)o.obj).getErrorcode())
{
case MyError.NETWORK_NOT_AVAILABLE:
{
if(_locationSendingByCheckIn)
{
_intent.putExtra("Response","Network not available");
_intent.putExtra("LocationPostedSuccessfuly", false);
sendBroadcast(_intent);
_locationSendingByCheckIn=false;
}
break;
}
case MyError.EXCEPTION:
case MyError.UNDEFINED:
{
if(_locationSendingByCheckIn)
{
_intent.putExtra("Response","Server not responding. Please try later");
_intent.putExtra("LocationPostedSuccessfuly", false);
sendBroadcast(_intent);
_locationSendingByCheckIn=false;
}
}
}
}
else if (o.obj instanceof ResponseAppLocationSending) {
ResponseAppLocationSending responseAppLocationSending=(ResponseAppLocationSending) o.obj;
if(responseAppLocationSending.getResponce().contains("saved"))
{
if(_locationSendingByCheckIn)
{
_intent.putExtra("Response","Check In Submitted");
_intent.putExtra("LocationPostedSuccessfuly", true);
sendBroadcast(_intent);
}
//else setLocationSendingAlarm(AppConstants.PENDING_INTENET_LOCATION_PROVIDER_ENABLE_ALARM_ID);
}
else {
if(_locationSendingByCheckIn)
{
_intent.putExtra("Response","Server not responding. Please try later");
_intent.putExtra("LocationPostedSuccessfuly", false);
sendBroadcast(_intent);
}
}
}
}
catch (Exception e) {
if(_locationSendingByCheckIn)
{
_intent.putExtra("Response","Server not responding. Please try later");
_intent.putExtra("LocationPostedSuccessfuly", false);
sendBroadcast(_intent);
_locationSendingByCheckIn=false;
}
}
_locationSendingByCheckIn=false;
}
private long getTimeInterval()
{
try{
String s=MySharedPreference.getString(MySharedPreference.APP_REPORTING_TIME, "10", getApplicationContext());
int time = Integer.parseInt(s);
if(time<1) time=10;
return time*1000*60;
}
catch (Exception e) {
return 1000*60*10; //10 minutes
}
}
#Override
public void onDestroy()
{
if(_locationManager!=null)
_locationManager.removeUpdates(locationListener);
cancleAlarm(AppConstants.PENDING_INTENET_LOCATION_PROVIDER_ENABLE_ALARM_ID);
super.onDestroy();
}
}
Finaly I got the solution of my problem.I was doing Geo coding frequently but not in a different thread.So I did this(Did Geo coding in a new Thread)
public void onLocationChanged(final Location location) {
new Thread(new Runnable(){
public void run(){
_address=getAddress(location);
}
}).start();
}
};
private String getAddress(Location location)
{
List<Address> addresses;
try{
addresses = new Geocoder(this,Locale.getDefault()).getFromLocation(location.getLatitude(), location.getLongitude(), 1);
return findAddress(addresses);
}
catch (Exception e) {
try{
addresses= ReverseGeocode.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
return findAddress(addresses);
}
catch (Exception e1) {
return "Address not available";
}
}
//return "Address not available";
}
private String findAddress(List<Address> addresses)
{
String address="Address not available";
if(addresses!=null)
{
for(int i=0;i<addresses.size();i++){
Address addre=addresses.get(i);
String street=addre.getAddressLine(0);
if(null==street)
street="";
String city=addre.getLocality();
if(city==null) city="";
String state=addre.getAdminArea();
if(state==null) state="";
String country=addre.getCountryName();
if(country==null) country="";
address=street+", "+city+", "+state+", "+country;
}
return address;
}
return address;
}
}