i'm creating an app that show user's location into a map, now i want to update the user location when the app is in background,especially i want to start the Service when the Activity's method onPause() is called.
my activity:
public class MapsActivity extends Activity implements OnClickListener, GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener, LocationListener, OnInfoWindowClickListener {
private static final long UPDATE_INTERVAL = 5000;
private static final long FASTEST_INTERVAL = 1000;
private GoogleMap map = null;
private LocationClient locationClient;
private Location myLocation;
private LocationRequest locationRequest;
private LatLng newPosition;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
locationClient = new LocationClient(this, this, this);
locationRequest = LocationRequest.create().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY).setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL).setSmallestDisplacement(10);
if (locationClient != null)
// connect the client to the Google Play services
locationClient.connect();
}
#Override
public void onLocationChanged(Location location) {
newPosition = new LatLng(location.getLatitude(), location.getLongitude());
myLocation = location;
if (myLocation != null)
button.setClickable(true);
else
button.setClickable(false);
map.animateCamera(CameraUpdateFactory.newLatLngZoom(newPosition, 20));
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
}
#Override
public void onConnected(Bundle arg0) {
Toast.makeText(this, "I'm bringing you to your area.", Toast.LENGTH_SHORT).show();
// start periodic updates
locationClient.requestLocationUpdates(locationRequest, this);
}
#Override
public void onDisconnected() {
Toast.makeText(this, "Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
}
public ProgressDialog getProgress() {
return progress;
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onRestart() {
super.onRestart();
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onStop() {
super.onStop();
}
#Override
protected void onDestroy() {
if (locationClient.isConnected() && locationClient != null) {
locationClient.removeLocationUpdates(this);
locationClient.disconnect();
}
super.onDestroy();
}
}
my Service Class:
public class locationBackgroundService extends Service implements LocationListener, GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
private LocationRequest mLocationRequest;
private LocationClient mLocationClient;
public locationBackgroundService() {
}
#Override
public void onCreate() {
mLocationRequest = LocationRequest.create();
// mLocationRequest.setInterval(CommonUtils.UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// mLocationRequest.setFastestInterval(CommonUtils.FAST_INTERVAL_CEILING_IN_MILLISECONDS);
mLocationClient = new LocationClient(getApplicationContext(), this, this);
mLocationClient.connect();
}
#Override
public void onStart(Intent intent, int startId) {
int start = Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
public void onConnected(Bundle arg0) {
Log.i("info", "Location Client is Connected");
mLocationClient.requestLocationUpdates(mLocationRequest, this);
Log.i("info", "Service Connect status :: " + isServicesConnected());
}
#Override
public void onDisconnected() {
Log.i("info", "Location Client is Disconnected");
}
#Override
public void onLocationChanged(Location location) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
}
private boolean isServicesConnected() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(locationBackgroundService.this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
return true;
} else {
return false;
}
}
#Override
public void onDestroy() {
mLocationClient.removeLocationUpdates(this);
super.onDestroy();
}
}
is it possible to do that?
thanks in advance.
example of LocationService.class
package com.example.myapp;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.example.myapp.activities.MainActivity;
public class LocationService extends Service implements
LocationListener,
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
public static final String LOCATION_SERVICE = "LocationService";
private LocationClient mLocationClient;
private LocationRequest mLocationRequest;
float minDist = 100f;
int minTime = 10000;
PendingIntent contentIntent;
public static String USER_LATITUDE = "user_latitude";
public static String USER_LONGITUDE = "user_longitude";
#Override
public void onCreate() {
Log.d("onCreate", "");
super.onCreate();
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
mLocationClient = new LocationClient(this, this, this);
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(minTime);
//mLocationRequest.setSmallestDisplacement(minDist);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mLocationClient.connect();
return Service.START_NOT_STICKY;
}
#Override
public void onLocationChanged(Location location) {
float latitude = (float) location.getLatitude();
float longitude = (float) location.getLongitude();
Log.d("onLocationChanged. latLng", latitude + ", " + longitude);
Intent intent = new Intent(LOCATION_SERVICE);
intent.putExtra(USER_LATITUDE, latitude);
intent.putExtra(USER_LONGITUDE, longitude);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
#Override
public void onDestroy() {
super.onDestroy();
if (mLocationClient.isConnected() ) {
stopPeriodicUpdates();
}
}
#Override
public void onConnected(Bundle bundle) {
Log.d(LOCATION_SERVICE, "onConnected");
startPeriodicUpdates();
}
#Override
public void onDisconnected() {
Log.d(LOCATION_SERVICE, "onDisconnected");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(LOCATION_SERVICE, "onConnectionFailed");
}
public void startPeriodicUpdates() {
mLocationClient.requestLocationUpdates(mLocationRequest, this);
Log.d(LOCATION_SERVICE, "startPeriodicUpdates");
}
private void stopPeriodicUpdates() {
mLocationClient.removeLocationUpdates(this);
Log.d(LOCATION_SERVICE, "stopPeriodicUpdates");
}
}
add in MainActivity.class
private boolean servicesConnected() {
int resultCode =
GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == resultCode) {
Log.d("servicesConnected", "Google play services isConnected");
return true;
} else {
return false;
}
}
private BroadcastReceiver mLocationReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
float latitude = intent.getFloatExtra(LocationService.USER_LATITUDE, 0);
float longitude = intent.getFloatExtra(LocationService.USER_LONGITUDE, 0);
//do something
}
};
#Override
public void onPause() {
super.onPause();
Intent service = new Intent(this, LocationService.class);
IntentFilter intentLocationServiceFilter = new IntentFilter(LocationService
.LOCATION_SERVICE);
LocalBroadcastManager.getInstance(this)
.registerReceiver(mLocationReceiver, intentLocationServiceFilter);
if (servicesConnected()) {
startService(service);
}
}
And do not forget add to AndroidManifest file your LocationService
Related
I want to use locationListener in my android fragment. But I am getting an error. My code is in below.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocationListener locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
}
};
locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 1, locationListener);
}
else {
}
}
I am getting this error.
Can't resolve method requestLocationUpdates
Implement all the methods of LocationListener
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView textView = new TextView(getActivity());
textView.setText(R.string.hello_blank_fragment);
LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
if (new Utility().checkAndGrantPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION, 101, "your custom message"))
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 1, locationListener);
}
return textView;
}
Outside from onCreate
LocationListener locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
//Todo your code
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
//Todo your code
}
#Override
public void onProviderEnabled(String provider) {
//Todo your code
}
#Override
public void onProviderDisabled(String provider) {
//Todo your code
}
};
And the checkAndGrantPermission method is
public boolean checkAndGrantPermission(final Context context, final String permissionString, final int requestCode, String permissoinTypeMessage)
{
int currentAPIVersion = Build.VERSION.SDK_INT;
if(currentAPIVersion>=android.os.Build.VERSION_CODES.M)
{
if (ContextCompat.checkSelfPermission(context, permissionString) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, permissionString)) {
// your custom dialog screen when user deny permission
} else {
ActivityCompat.requestPermissions((Activity) context, new String[]{permissionString}, requestCode);
}
return false;
} else {
return true;
}
} else {
return true;
}
}
In Activity override onRequestPermissionsResult
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 101) {
yourFragmentInstance.onRequestPermissionsResult(requestCode,permissions,grantResults);
}
}
In Your Framgent override onRequestPermissionsResult
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 101) {
if (requestCode == AppConstants.runtimePermissionCode) {
if (permissions[0].equals(Manifest.permission.ACCESS_FINE_LOCATION) && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 1, locationListener);
}
}
}
}
Got your issue.
You have used Location listener from
com.google.android.gms.location.LocationListener;
You have to import LocationListener from
android.location.Location;
Try this one:
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 1, new android.location.LocationListener() {
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
});
Hope it helps:)
Create this class:
public class GetCurrentLocation implements
ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
private static final String TAG = "location-updates-sample";
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 0;
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
UPDATE_INTERVAL_IN_MILLISECONDS / 2;
private final String REQUESTING_LOCATION_UPDATES_KEY = "requesting-location-updates-key";
private final String LOCATION_KEY = "location-key";
private final String LAST_UPDATED_TIME_STRING_KEY = "last-updated-time-string-key";
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private Context mContext;
private getLocation mGetCurrentLocation;
public GetCurrentLocation(Context context) {
mContext = context;
buildGoogleApiClient();
}
private synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(mContext)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
}
public interface getLocation{
public void onLocationChanged(Location location);
}
public void startGettingLocation(getLocation location) {
mGetCurrentLocation = location;
connect();
}
public void stopGettingLocation() {
stopLocationUpdates();
disconnect();
}
private void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private void startLocationUpdates() {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}
private void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
private void connect() {
mGoogleApiClient.connect();
}
private void disconnect() {
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "Connected to GoogleApiClient");
startLocationUpdates();
}
#Override
public void onLocationChanged(Location location) {
mGetCurrentLocation.onLocationChanged(location);
}
#Override
public void onConnectionSuspended(int cause) {
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
}
In your fragment class:
private GetCurrentLocation mListen;
mListen = new GetCurrentLocation(this);
mListen.startGettingLocation(new GetCurrentLocation.getLocation() {
#Override
public void onLocationChanged(Location location) {
// Here is my working with location object
}
});
make sure you have added latest googleplayservice library in your gradle file.
Calling FusedLocationApi within jobscheduler doesn't work. I have tried in 2 ways but onConnected() are never called in both of them. How can I make it work? Thankyou
MainActivity.class
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnStartJob = (Button)findViewById(R.id.startjob);
jobScheduler = (JobScheduler)getSystemService(JOB_SCHEDULER_SERVICE);
btnStartJob.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
ComponentName jobService =
new ComponentName(getPackageName(), MyJobService.class.getName());
PersistableBundle bundle = new PersistableBundle();
bundle.putString("lat", latitude+"");
bundle.putString("lon", longitude+"");
JobInfo jobInfo =
new JobInfo.Builder(MYJOBID, jobService).setPeriodic(10000).
setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY).
setRequiresCharging(false).
setRequiresDeviceIdle(false).
setPersisted(true).
setExtras(bundle).
build();
int jobId = jobScheduler.schedule(jobInfo);
if(jobScheduler.schedule(jobInfo)>0){
}else{
}
}
});
}
}
Try 1:
Here I have implemented ConnectionCallbacks, OnConnectionFailedListener in JobService but its onConnected() method is never called...
public class MyJobService extends JobService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
protected JobParameters mJobParameters;
private GoogleApiClient mGoogleApiClient;
LocationRequest mLocationRequest;
public MyJobService() {
}
#Override
public boolean onStartJob(JobParameters jobParameters) {
Log.e("token", "Start Job Called");
setUpLocationClientIfNeeded();
mLocationRequest = LocationRequest.create();
// Use high accuracy
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(5000);
return true;
}
#Override
public boolean onStopJob(JobParameters jobParameters) {
Toast.makeText(this,
"MyJobService.onStopJob()",
Toast.LENGTH_SHORT).show();
return false;
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(this.mGoogleApiClient,
mLocationRequest, this); // This is the changed line.
Log.e("onConnected", "onConnected");
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
private void setUpLocationClientIfNeeded()
{
if(mGoogleApiClient == null)
buildGoogleApiClient();
}
protected synchronized void buildGoogleApiClient() {
this.mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
this.mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
Log.e("token",location.getLatitude()+""+location.getLongitude());
}
}
Try 2:
Called innerClass that implements ConnectionCallbacks, OnConnectionFailedListener in onStartJob of JobService but still onConnected method is never called
public class MyJobService extends JobService {
private Location mLastLocation;
String latitude = null;
String longitude = null;
protected JobParameters mJobParameters;
private class GetLocation extends AsyncTask<Integer, Void, Integer> implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
protected Integer doInBackground(Integer... jobID) {
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(getBaseContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
return jobID[0];
}
protected void onPostExecute(Integer jobID) {
//h2 = new Handler();
//Runnable run = new Runnable() {
// #Override
// public void run() {
// long millis = System.currentTimeMillis() - 0;
// int seconds = (int) (millis / 1000);
// int minutes = seconds / 60;
// seconds = seconds % 60;
// Log.i("JobSchedulerTest","Job Finished!");
// h2.postDelayed(this, 1500);
jobFinished(mJobParameters, true);
}
};
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.e("onConnected " , "onConnected" );
createLocationRequest();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (ActivityCompat.checkSelfPermission(MyJobService.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MyJobService.this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, new LocationCallback() {
#Override
public void onLocationResult(final LocationResult locationResult) {
latitude = locationResult.getLastLocation().getLatitude() + "";
longitude = locationResult.getLastLocation().getLongitude() + "";
Log.e("onLocationResult lat", latitude);
Log.e("onLocationResult Lon", longitude);
}
#Override
public void onLocationAvailability(LocationAvailability locationAvailability) {
}
}, null);
}
}
public MyJobService() {
}
#Override
public boolean onStartJob(JobParameters jobParameters) {
Log.d("onstart", "onStartJob() :: ");
mJobParameters=jobParameters;
Integer i=new Integer(jobParameters.getJobId());
new GetLocation().execute(i);
return false;
}
#Override
public boolean onStopJob(JobParameters jobParameters) {
Toast.makeText(this,
"MyJobService.onStopJob()",
Toast.LENGTH_SHORT).show();
return false;
}
}
I have used GoogleApiClient for getting GPS location. i have create one service and every 10 seconds getting data from GPS but the problem is there are so many times onConnectionSuspended() called and i am not geeting any GPS data.
following is my service code that i am getting GPS location
<service
android:name="com.GPSService"
android:enabled="true"
android:exported="false"
android:process=":ServiceProcess"
android:stopWithTask="false" />
Service code
public class GPSService extends Service implements LocationListener, ConnectionCallbacks, OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
protected GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
protected boolean requestingLocationUpdate = true;
private Location mLastLocation;
// Location updates intervals in sec
private static int UPDATE_INTERVAL = 10000; // 10 sec
private static int FASTEST_INTERVAL = 5000; // 5 sec
private static int DISPLACEMENT = 5; // 5 meters
private static final String LOCATION = "Location Not Available";
private double latitude;
private double longitude;
private String mLastUpdateTime;
Intent intents;
RequestParams requestParams = null;
private static final String TAG = "GPSService";
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
helper.insertServiceLog("oncreate");
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d("GPSService", "onCreate");
//
mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
public void onDestroy() {
Log.i("MyReceiver", "onTaskRemoved called Oooooooooooooppppssssss!!!!");
mGoogleApiClient.disconnect();
}
#Override
public void onStart(Intent intent, int startid) {
super.onStart(intent, startid);
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d("GPSService", "onStart");
mGoogleApiClient.connect();
if (mGoogleApiClient.isConnected() && requestingLocationUpdate) {
startLocationUpdates();
}
}
#Override
public final int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onLocationChanged(Location loc) {
//String imei = "2";
mLastLocation = loc;
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onConnected(Bundle arg0) {
if (requestingLocationUpdate) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
//LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest,this);
startLocationUpdates();
Toast.makeText(this, "Started the location update", Toast.LENGTH_LONG).show();
}
}
#Override
public void onConnectionSuspended(int arg0) {
Log.d("GPSService", "onConnectionSuspended called");
}
/**
* Starting the location updates
*/
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.i("MyReceiver", "onTaskRemoved called Oooooooooooooppppssssss!!!!");
super.onTaskRemoved(rootIntent);
}
}
can somebody please help me to figure out this issue.
Is there a particular reason why you're running the service in a different process? I think it might be related that. Try changing the declaration of the service to
<service
android:name="com.GPSService"
android:enabled="true"
android:exported="false" />
In my project, there is a service that retrieves location of users. It continuously runs in background. I want to set location on my textview.
So, I have ManinActivity as follows:
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MainActivity extends Activity {
GPSTracker gps;
double mylatitude, mylongitude;
TextView txt_location;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt_location = (TextView)findViewById(R.id.current_location);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();
}
}
public void btn_remember_Clicked(View v)
{
Intent i = new Intent(MainActivity.this,RememberActivity.class);
startActivity(i);
}
public void btn_show_places_Clicked(View v)
{
Intent i = new Intent(MainActivity.this,ShowPlacesActivity.class);
startActivity(i);
}
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
}
}
And my LocationService class is as follows:
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
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;
#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();
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 4000, 0, listener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 0, listener);
return super.onStartCommand(intent, flags, startId);
}
#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();
} catch(Exception e) {
System.out.print(e);
}
}
};
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);
}
}
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 I have LocationBroadcast class as follows:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class LocationBroadcast extends BroadcastReceiver{
#Override
public void onReceive(Context ctx, Intent intent) {
ctx.startService(new Intent(ctx, LocationService.class));
}
}
I want to set location on textview txt_location in MainActivity. I do not know much about services and how we can communicate within Activity. How can I get latitude and longitude in MainActivity? Please help.
Update:
I have just updated my code according to answers:
public class LocationService extends Service
{
private static final int TWO_MINUTES = 1000 * 60 * 2;
public LocationManager locationManager;
public MyLocationListener listener;
public Location previousBestLocation = null;
Intent i;
#Override
public void onCreate()
{
super.onCreate();
i = new Intent("LOCATION_CHANGED");
}
#Override
public int onStartCommand(Intent intent,int flags, int startId)
{
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new MyLocationListener();
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 4000, 0, listener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 0, listener);
return super.onStartCommand(intent, flags, startId);
}
#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();
} catch(Exception e) {
System.out.print(e);
}
}
};
t.start();
return t;
}
public class MyLocationListener implements LocationListener
{
public void onLocationChanged(final Location loc)
{
Log.i("**************************************", "Location changed");
if(isBetterLocation(loc, previousBestLocation)) {
String newLocation = "Lat: " + loc.getLatitude() + " and Long: " + loc.getLongitude();
i = new Intent("LOCATION_CHANGED");
i.putExtra("location", newLocation);
sendBroadcast(i);
}
}
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 I have received broadcasted intent in MainActivity as follows:
public class MainActivity extends Activity {
TextView txt_location;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt_location = (TextView)findViewById(R.id.current_location);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
public class LocationBroadcast extends BroadcastReceiver {
#Override
public void onReceive(Context ctx, Intent intent) {
txt_location.setText(intent.getExtras().getString("location"));
}
}
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
}
}
As you can see, it is not showing any location updates. Logcat isn't showing any errors. Can anyone please guide me what is the mistake?
Create a BroadcastReceiver in the MainActivity like
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context appContext, Intent intent) {
.......
//get location from Service and create Method for set location on textview txt_location
}
};
registerReceiver in onResume of MainActivity
registerReceiver(broadcastReceiver, new IntentFilter(GET_LOCATION));
and declare this in starting MainActivity
private static final String GET_LOCATION = "com.pkg.location";
and in your service pass your location as a broadcase
Intent intent = new Intent(GET_LOCATION);
intent.putExtra("location", "your_location_got_from_service");
sendBroadcast(intent);
and dont forget to unregisterReceiver in MainActivity
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
You can use BroadcastReceiver to receive the event of your LOCATION_CHANGED, and update the TextView from its onReceive method:
In your activity:
TextView textView = (TextView) findViewById(R.id.location_text); //global variable
registerReceiver(locationChangedReceiver, new IntentFilter("LOCATION_CHANGED"));
//your receiver class as inner class of activity.
private BroadcastReceiver locationChangedReceiver= new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
textView.setText(intent.getExtras().getString("location"));
}
};
In your service, you can simply broadcast for "LOCATION_CHANGED", and pass String location as intent's extra argument.
String newLocation = "Lat: " + loc.getLatitude() + " and Long: " + loc.getLongitude();
Intent i = new Intent("LOCATION_CHANGED");
i.putExtra("location", newLocation);
sendBroadcast(i);
If you want to keep a separate receiver class (not in activity), you can use your context to update views like this:
public class LocationBroadcast extends BroadcastReceiver{
#Override
public void onReceive(Context ctx, Intent intent) {
TextView textView = (TextView) ctx.findViewById(R.id.location_text);
textView.setText(intent.getExtras().getString("location"));
}
}
Hope it helps.
In my project, i have used a service to retrieving location continuously in background. My LocationService is as follows:
public class LocationService extends Service
{
private static final int TWO_MINUTES = 1000 * 60 * 2;
public LocationManager locationManager;
public MyLocationListener listener;
public Location previousBestLocation = null;
Intent i;
#Override
public void onCreate()
{
super.onCreate();
i = new Intent("LOCATION_CHANGED");
}
#Override
public int onStartCommand(Intent intent,int flags, int startId)
{
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new MyLocationListener();
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 4000, 0, listener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 0, listener);
return super.onStartCommand(intent, flags, startId);
}
#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();
} catch(Exception e) {
System.out.print(e);
}
}
};
t.start();
return t;
}
public class MyLocationListener implements LocationListener
{
public void onLocationChanged(final Location loc)
{
Log.i("**************************************", "Location changed");
if(isBetterLocation(loc, previousBestLocation)) {
String newLocation = "Lat: " + loc.getLatitude() + " and Long: " + loc.getLongitude();
i = new Intent("LOCATION_CHANGED");
i.putExtra("location", newLocation);
sendBroadcast(i);
}
}
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 I have received broadcasted intent in MainActivity as follows:
public class MainActivity extends Activity {
TextView txt_location;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt_location = (TextView)findViewById(R.id.current_location);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
public class LocationBroadcast extends BroadcastReceiver {
#Override
public void onReceive(Context ctx, Intent intent) {
txt_location.setText(intent.getExtras().getString("location"));
}
}
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container,
false);
}
}
}
All i want to do is to set location's latitude and longitude on txt_location. this code isn't working and showing txt_location as it is:
As you can see, it is not showing any location updates...Logcat isn't showing any errors..Can anyone please guide me what is the mistake?
Use this class as Service. but before this define service class in manifest
<service android:name="com.example.androidservice.beckend.EndlessService" />
and use in activity class
startService(new Intent ( this , EndlessService.class)) ;
import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.util.Log;
import android.widget.Toast;
public class EndlessService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg)
{
new HitToTheInternet().execute("");
}
}
#Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the
// job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
if ( intent == null )
{
Log.e("intentStatus", "intent is null");
}
// If we get killed, after returning from here, restart
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
#Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
class HitToTheInternet extends AsyncTask<String, String, String>
{
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
Log.e("doInBackground", "Running") ;
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
new Handler().postDelayed(new Runnable() {
public void run() {
Message msg = mServiceHandler.obtainMessage();
mServiceHandler.sendMessage(msg);
}
}, 10000);
}
}
}
for starting service says at 5 seconds:
AlarmManager alarm =(AlarmManager)context.getSystemService(context.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getService(context, 0, new Intent(context,MonitorService.class), 0);
alarm.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 5*1000, pi);
For stopping alarm:
AlarmManager mgr =(AlarmManager)getSystemService(ALARM_SERVICE);
PendingIntent pi = PendingIntent.getService(context, 0, new Intent(this,MonitorService.class), 0);
mgr.cancel(pi);
pi.cancel();