I am trying to bound a service to my activity and get location values from it.
I have the following service:
GPSService.java
public class GPSService extends SensorElement {
// Binder given to clients
private final IBinder mBinder = new LocalBinder();
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
public GPSService getService() {
// Return this instance of GPSService so clients can call public
// methods
return GPSService.this;
}
}
private static final String TAG = "GPSServive";
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 1000;
private static final float LOCATION_DISTANCE = 10f;
private Location location;
private boolean canGetLocation;
private double latitude;
private double longitude;
private double accuracy;
private long timestamp;
public SensorType type = SensorType.SOFTWARE_SENSOR;
public SensorName name = SensorName.GPS_SENSOR;
private class LocationListener implements android.location.LocationListener {
Location mLastLocation;
public LocationListener(String provider) {
Log.e(TAG, "LocationListener " + provider);
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location) {
Log.e(TAG, "onLocationChanged: " + location);
mLastLocation.set(location);
}
#Override
public void onProviderDisabled(String provider) {
Log.e(TAG, "onProviderDisabled: " + provider);
}
#Override
public void onProviderEnabled(String provider) {
Log.e(TAG, "onProviderEnabled: " + provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.e(TAG, "onStatusChanged: " + provider);
}
}
LocationListener[] mLocationListeners = new LocationListener[] {
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER) };
#Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onCreate() {
Log.e(TAG, "onCreate");
initializeLocationManager();
if (!isNetworkAvailable() && !isGPSAvailable()) {
// no network provider is enabled
setCanGetLocation(false);
} else if (isNetworkAvailable()){
setCanGetLocation(true);
try {
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL,
LOCATION_DISTANCE, mLocationListeners[1]);
location = mLocationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
accuracy = location.getAccuracy();
timestamp = System.currentTimeMillis();
}
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "gps provider does not exist " + ex.getMessage());
}
} else if (isGPSAvailable()) {
setCanGetLocation(true);
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL,
LOCATION_DISTANCE, mLocationListeners[0]);
location = mLocationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
accuracy = location.getAccuracy();
timestamp = System.currentTimeMillis();
}
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG,
"network provider does not exist, " + ex.getMessage());
}
}
}
#Override
public void onDestroy() {
Log.e(TAG, "onDestroy");
super.onDestroy();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
Log.i(TAG, "fail to remove location listners, ignore", ex);
}
}
}
}
private void initializeLocationManager() {
Log.e(TAG, "initializeLocationManager");
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext()
.getSystemService(Context.LOCATION_SERVICE);
}
}
private boolean isNetworkAvailable() {
return mLocationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
private boolean isGPSAvailable() {
return mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
public double getAccuracy() {
return accuracy;
}
public long getTimestamp() {
return timestamp;
}
public SensorType getType() {
return type;
}
public void setType(SensorType type) {
this.type = type;
}
public SensorName getName() {
return name;
}
public void setName(SensorName name) {
this.name = name;
}
public boolean isCanGetLocation() {
return canGetLocation;
}
public void setCanGetLocation(boolean canGetLocation) {
this.canGetLocation = canGetLocation;
}
}
This is the abstract class that the GPSService extends. The goal for this is to have something that generalizes a sensor, gps sensor accelerometer sensor, whatever sensor.
SensorElement.java
public abstract class SensorElement extends Service{
protected SensorType type;
protected SensorName name;
#Override
public abstract IBinder onBind(Intent arg0);
#Override
public int onStartCommand(Intent intent, int flags, int startId){
return super.onStartCommand(intent, flags, startId);
}
#Override
public abstract void onCreate();
#Override
public void onDestroy(){
super.onDestroy();
}
}
Now i have my activity that is trying to bind to the GPSService.
InSituApp.java
public class InSituApp extends Activity{
GPSService gpsService;
boolean mBound = false;
public Button buttonGPS;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent(this, GPSService.class));
//startService(new Intent(this, MyService.class));
// buttonGPS = (Button) findViewById(R.id.button1);
}
#Override
protected void onStart() {
super.onStart();
System.out.println("ENTERED IN ONSTART");
// Bind to GPSService
Intent intent = new Intent(this, GPSService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
/** Called when a button is clicked (the button in the layout file attaches to
* this method with the android:onClick attribute) */
public void onButtonClick(View v) {
System.out.println("DIDNT ENTERED IN BOUND");
if (mBound) {
// Call a method from the LocalService.
// However, if this call were something that might hang, then this request should
// occur in a separate thread to avoid slowing down the activity performance.
System.out.println("ENTERED IN BOUND");
double latitude = gpsService.getLatitude();
double longitude = gpsService.getLongitude();
double accuracy = gpsService.getAccuracy();
long timestamp = gpsService.getTimestamp();
Toast.makeText(this, "latitude: " + latitude, Toast.LENGTH_SHORT).show();
Toast.makeText(this, "longitude: " + longitude, Toast.LENGTH_SHORT).show();
Toast.makeText(this, "accuracy: " + accuracy, Toast.LENGTH_SHORT).show();
Toast.makeText(this, "timestamp: " + timestamp, Toast.LENGTH_SHORT).show();
}
}
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
System.out.println("ENTERED IN ONSERVICE CONNECTED");
LocalBinder binder = (LocalBinder) service;
gpsService = binder.getService();
System.out.println("GPSService: "+gpsService!=null);
mBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
System.out.println("ENTERED IN ONSERVICE DISCONNECTED");
}
};
}
This code never calls the onServiceConnected method inside mConnection. What is wrong in here? The bindService call in onStart returns false. Why is that?
EDIT:
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="main.inSituApp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:label="#string/app_name"
android:name="main.inSituApp.InSituApp" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".GPSService" />
<service android:name=".FileObservingService" />
</application>
</manifest>
I found the solution.
The problem is in the manifest file where the service must be the total path of the package.
in my case sensors.GPSService
Hope it helps someone
Related
How to send user location data to server every five second using restful API even app is closed in android?
Please help me
you can create a background service that it works when user lock screen or close your app from background
you must create service with this way:
first create a Service class like this:
public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks {
public static double latitude;
public static double longitude;
private int retryGPS = 0;
private int retryNetwork = 0;
private Handler handler;
private Runnable runnable;
private GoogleApiClient mGoogleApiClient;
private LocationManager mLocationManager;
private LocationListener[] mLocationListeners = new LocationListener[]{
new LocationListener(LocationManager.GPS_PROVIDER),
};
private static final int LOCATION_INTERVAL = 0;
private static final float LOCATION_DISTANCE = 1;
private static final String TAG = "LocationService";
#Override
public void onCreate() {
buildGoogleApiClient();
initializeLocationManager();
locationRequest();
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
sendLocation();
}
};
sendLocation();
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addApi(LocationServices.API)
.build();
}
private void initializeLocationManager() {
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
private void locationRequest() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
}
private void sendLocation() {
//TODO: you can use location here
handler.postDelayed(runnable,5000);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
if (!mGoogleApiClient.isConnected())
mGoogleApiClient.connect();
return START_STICKY;
}
#Override
public void onConnected(Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
} else {
try {
Thread.sleep(3000);
onConnected(null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onDestroy() {
handler.removeCallbacks(runnable);
if (mLocationManager != null) {
for (LocationListener mLocationListener : mLocationListeners) {
try {
mLocationManager.removeUpdates(mLocationListener);
} catch (Exception e) {
e.printStackTrace();
}
}
}
super.onDestroy();
}
private class LocationListener implements android.location.LocationListener, ActivityCompat.OnRequestPermissionsResultCallback {
Location mLastLocation;
public LocationListener(String provider) {
Log.d(TAG, "LocationListener: " + provider);
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(final Location location) {
mLastLocation.set(location);
latitude = location.getLatitude();
longitude = location.getLongitude();
Log.d(TAG, "onLocationChanged: { latitude: " + latitude + " ,longitude: " + longitude + " , accuracy: " + location.getAccuracy() + " }");
}
#Override
public void onProviderDisabled(String provider) {
Log.d(TAG, "onProviderDisabled: " + provider);
}
#Override
public void onProviderEnabled(String provider) {
Log.d(TAG, "onProviderEnabled: " + provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, "onStatusChanged: " + status);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
}
}
}
then register service in manifest:
<service
android:name=".service.LocationService"
android:enabled="true"
android:process=":process" />
then start service from any activity or fragment :
public static void mStopService(Context context) {
context.stopService(new Intent(context, LocationService.class));
}
public static void mStartService(Context context) {
context.startService(new Intent(context, LocationService.class));
}
if you want to make your code run even when the app is closed you need to use services, services can run in the background even if the app is closed, and you may need to use a broadcast receiver with the service to keep running it every time it finishes.
this is the Service:
public class myService extends Service {
public static int counter = 0;
public myReceiver myReceiver = new myReceiver();
#Override
public void onCreate() {
super.onCreate();
//this line register the Receiver for the first time
myService.this.registerReceiver(myReceiver, new IntentFilter("com.example.myApp"));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Here you have to put the code that gets the location and send it
}
#Override
public void onDestroy() {
super.onDestroy();
//here you sent a broadcast message to start the reciever
//note that the broadcast message that you send has to be unique writing you package name will be fine ex: com.example.myApp
Intent sendBroadCast = new Intent("com.example.myApp");
sendBroadcast(sendBroadCast);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
and this is the broadcast receiver:
public class myReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
if("com.example.myApp".equals(intent.getAction())){
//the handler is used as a timer here
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
Intent myServ = new Intent(context, myService.class);
try {
context.startService(myServ);
}catch (Exception e){
}
}
},5000);
}
}
}
I have a service that runs in both foreground and background to get the user location at all times, I simply use a LocalBroadCastManager to send the location from the foreground to an activity in my application and then start my API call.
How to achieve the same when the service is running in the background or when the application is closed.
The service:
public class LocationService extends Service {
private static final String TAG = "LocationService";
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 0;
private static final float LOCATION_DISTANCE = 1000f;
private HandlerThread mHandlerThread;
private Handler mHandler;
private final IBinder mBinder = new MyLocalBinder();
Location mLastLocation;
private class LocationListener implements android.location.LocationListener
{
public LocationListener(String provider)
{
Helper.showLog(TAG, "LocationListener " + provider);
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location)
{
Helper.showLog(TAG, "onLocationChanged: " + location);
mLastLocation.set(location);
sendBroadcast();
}
#Override
public void onProviderDisabled(String provider)
{
Helper.showLog(TAG, "onProviderDisabled: " + provider);
}
#Override
public void onProviderEnabled(String provider)
{
Helper.showLog(TAG, "onProviderEnabled: " + provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
Helper.showLog(TAG, "onStatusChanged: " + provider);
}
}
LocationListener[] mLocationListeners = new LocationListener[] {
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.e(TAG, "onStartCommand");
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onCreate()
{
Log.e(TAG, "onCreate");
mHandlerThread = new HandlerThread("LocalServiceThread");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
initializeLocationManager();
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "network provider does not exist, " + ex.getMessage());
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "gps provider does not exist " + ex.getMessage());
}
sendBroadcast();
}
public void postRunnable(Runnable runnable) {
mHandler.post(runnable);
}
public class MyLocalBinder extends Binder {
public LocationService getService() {
return LocationService.this;
}
}
#Override
public void onDestroy()
{
Helper.showLog(TAG, "onDestroy");
super.onDestroy();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
Log.i(TAG, "fail to remove location listeners, ignore", ex);
}
}
}
}
private void initializeLocationManager() {
Helper.showLog(TAG, "initializeLocationManager");
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
private void sendBroadcast(){
Intent intent = new Intent ("message"); //put the same message as in the filter you used in the activity when registering the receiver
intent.putExtra("latitude",mLastLocation.getLatitude() );
intent.putExtra("longitude",mLastLocation.getLongitude() );
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
I have to get location updates from location manager. I want the service remains continue if app is killed.
I have the following service class. I am using broadcast receiver. In onTaskRemove() method i send broadcast. in receiver class I restart the service, but not restarted. Please help. Thanks.
public class GoogleService extends Service implements LocationListener{
boolean isGPSEnable = false;
boolean isNetworkEnable = false;
double latitude,longitude;
LocationManager locationManager;
Location location;
private Handler mHandler = new Handler();
private Timer mTimer = null;
long notify_interval = 1000;
public static String str_receiver = "servicetutorial.service.receiver";
Intent intent;
public GoogleService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
mTimer = new Timer();
mTimer.schedule(new TimerTaskToGetLocation(),5,notify_interval);
intent = new Intent(str_receiver);
fn_getlocation();
}
#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) {
}
#Override
public void onDestroy() {
super.onDestroy();
sendBroadcast(new Intent("ChangeStatus"));
}
#Override
public void onTaskRemoved(Intent rootIntent) {
/*rootIntent = new Intent("ChangeStatus");
rootIntent.putExtra("action", "statusChange");
sendBroadcast(rootIntent);*/
super.onTaskRemoved(rootIntent);
sendBroadcast(new Intent("ChangeStatus"));
}
#SuppressLint("MissingPermission")
private void fn_getlocation(){
locationManager = (LocationManager)getApplicationContext().getSystemService(LOCATION_SERVICE);
isGPSEnable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnable && !isNetworkEnable){
}else {
if (isNetworkEnable){
location = null;
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,1000,0,this);
if (locationManager!=null){
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location!=null){
Log.e("latitude",location.getLatitude()+"");
Log.e("longitude",location.getLongitude()+"");
latitude = location.getLatitude();
longitude = location.getLongitude();
fn_update(location);
}
}
}
if (isGPSEnable){
location = null;
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000,0,this);
if (locationManager!=null){
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location!=null){
Log.e("latitude",location.getLatitude()+"");
Log.e("longitude",location.getLongitude()+"");
latitude = location.getLatitude();
longitude = location.getLongitude();
fn_update(location);
}
}
}
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
private class TimerTaskToGetLocation extends TimerTask{
#Override
public void run() {
mHandler.post(new Runnable() {
#Override
public void run() {
fn_getlocation();
}
});
}
}
private void fn_update(Location location){
intent.putExtra("latutide",location.getLatitude()+"");
intent.putExtra("longitude",location.getLongitude()+"");
sendBroadcast(intent);
}
}
**my Reciver class is**
public class RestartServiceReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context.getApplicationContext(), GoogleService.class));
}
}
my Manifest
<service android:name=".GoogleService"
android:enabled="true"
android:exported="true"
android:stopWithTask="false"
></service>
<receiver android:name=".RestartServiceReceiver" >
<intent-filter>
<action android:name="ChangeStatus" >
</action>
</intent-filter>
</receiver>
What i am doing wrong .
Use Pending Intent to get LocationUpdates using service upto android 7.0 above use you have to use Broadcast receiver:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_PROCESS_UPDATES.equals(action)) {
LocationResult result = LocationResult.extractResult(intent);
if (result != null) {
List<Location> locations = result.getLocations();
Log.d("servicelocation","*******lastupdate "+result.getLastLocation());
Log.d("servicelocation","******* "+locations.size()+
"\n"+locations.get(locations.size()-1).getLatitude() +" " +
"lng "+locations.get(locations.size()-1).getLongitude());
Toast.makeText(getApplicationContext(),"Service Stared "+locations.size(),Toast.LENGTH_SHORT).show();
}
}
}else {
Log.d("serviceintentvalues","********");
}
return START_STICKY;
}
Here complete reference given be google samples : https://github.com/googlesamples/android-play-location
it's working well for me check...
I have a problem with my android service. In the "onLocationChanged", i want to access a static member of my class "Device".
I start my service with :
Intent i = new Intent(this, LocationService.class);
startService(i);
This is my class LocationListener with the service:
private class LocationListener implements android.location.LocationListener{
Location mLastLocation;
LocationListener(String provider)
{
Log.e(TAG, "LocationListener " + provider);
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location)
{
Device.getLocationType().setLocationData(location);
}
#Override
public void onProviderDisabled(String provider)
{
//...
}
#Override
public void onProviderEnabled(String provider)
{
//...
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
//...
}
}
LocationListener[] mLocationListeners = new LocationListener[] {
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
super.onStartCommand(intent, flags, startId);
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onStartCommand");
return START_STICKY;
}
#Override
public void onCreate()
{
super.onCreate();
Log.d(TAG, "onCreate");
initializeLocationManager();
try {
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, MIN_TIME, MIN_DISTANCE,
mLocationListeners[1]);
Log.d(TAG, "try");
} catch (java.lang.SecurityException ex) {
Log.d(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "network provider does not exist, " + ex.getMessage());
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, MIN_TIME, MIN_DISTANCE,
mLocationListeners[0]);
Log.d(TAG, "try2");
} catch (java.lang.SecurityException ex) {
Log.d(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "gps provider does not exist " + ex.getMessage());
}
}
#Override
public void onDestroy()
{
Log.e(TAG, "onDestroy");
super.onDestroy();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
Log.i(TAG, "fail to remove location listners, ignore", ex);
}
}
}
}
private void initializeLocationManager() {
Log.e(TAG, "initializeLocationManager");
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
My class Device
public class Device {
private static LocationType locationType;
//...
}
And the class LocationType
public class LocationType {
private Location location;
public LocationType(){
//...
}
Location getLocationData() {
return location;
}
void setLocationData(Location location) {
this.location = location;
}
}
My application failed because, i don't have the right to access static member from service? How can i access this static member?
Thanks a lot for your answer.
You use Device.getLocationType() are you sure this method is also static ? So either make it static or make locationType public and access it directly.
Whether you'd want to is another thing entirely.
Also, try to replace :
private static LocationType locationType;
with :
private static LocationType locationType = new LocationType();
You field is private
private static LocationType locationType;
Make it public and it should be accessible
public static LocationType locationType;
If that isn't desired you should at least make a static getter which is either public or package private. If it's package private, make sure both classes are within the same package.
My object "locationType" is always defined to null... In my MainActivity, i call the method Device.init(...). This method create the object LocationType in the static member.
public class Device {
private static LocationType locationType;
public static void init(...){
Device.locationType = new LocationType(...);
if(Device.locationType != null){
Intent i = new Intent(activity, LocationService.class);
activity.startService(i);
}
}
My service is launched, but in the service method "onLocationChanged", the Device.locationType is null.
My app has a widget and shows information depending on the location of the device.
I would like to get the location by using a IntentService, because it destroys itself after the job is done, however the algorythm executes the
#Override
protected void onHandleIntent(Intent intent)
method and finishes. so there is no time to listen for some locations and give the info back.
is it possible to let the LocationListener wait until the
#Override
public void onLocationChanged(Location location) {
is called?
how to use properly the Looper in the
LocationManager.requestLocationUpdates(
method?
here the entire code for the IntentService:
public class GetLocation extends IntentService {
public GetLocation() {
super("GetLocation");
// TODO Auto-generated constructor stub
}
private static final String TAG = "GetLocation";
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 1000;
private static final float LOCATION_DISTANCE = 10f;
private ResultReceiver resultReceiver;
public static final String RECEIVER = "receiver";
public static final String GPS = "gps";
private int result = Activity.RESULT_CANCELED;
public static String RESULT = "result";
Location mLastLocation;
private class LocationListener implements android.location.LocationListener {
public LocationListener(String provider) {
Log.e(TAG, "LocationListener " + provider);
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location) {
Log.e(TAG, "onLocationChanged: " + location);
mLastLocation.set(location);
result = Activity.RESULT_OK;
publishResults(new double[] { mLastLocation.getLatitude(),
mLastLocation.getLongitude() }, result);
}
#Override
public void onProviderDisabled(String provider) {
Log.e(TAG, "onProviderDisabled: " + provider);
}
#Override
public void onProviderEnabled(String provider) {
Log.e(TAG, "onProviderEnabled: " + provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.e(TAG, "onStatusChanged: " + provider);
}
}
LocationListener[] mLocationListeners = new LocationListener[] {
// new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER) };
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
Log.e(TAG, "onHandleIntent");
resultReceiver = intent.getParcelableExtra(RECEIVER);
initializeLocationManager();
try {
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL,
LOCATION_DISTANCE, mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "network provider does not exist, " + ex.getMessage());
}
}
#Override
public void onDestroy() {
Log.e(TAG, "onDestroy");
super.onDestroy();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
Log.i(TAG, "remove location listners");
} catch (Exception ex) {
Log.i(TAG, "fail to remove location listners, ignore", ex);
}
}
}
}
private void initializeLocationManager() {
Log.e(TAG, "initializeLocationManager");
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext()
.getSystemService(Context.LOCATION_SERVICE);
}
}
private void publishResults(double[] gps, int result) {
Bundle bundle = new Bundle();
bundle.putDoubleArray(GPS, gps);
bundle.putInt(RESULT, result);
resultReceiver.send(Activity.RESULT_OK, bundle);
}
}
EDIT:
I would like to add the final code for the Service that gives the coordinates to a receiver:
However, it is only the gps provider working, the network is ignored on the device (everything is activated in the settings)
public class LocationGetter extends Service {
private static final String TAG = "LocationGetter";
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 1000;
private static final float LOCATION_DISTANCE = 10f;
private ResultReceiver resultReceiver;
public static final String RECEIVER = "receiver";
public static final String GPS = "gps";
private int result = Activity.RESULT_CANCELED;
public static String RESULT = "result";
Location mLastLocation;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.e(TAG, "onStartCommand");
resultReceiver = intent.getParcelableExtra(RECEIVER);
initializeLocationManager();
try {
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL,
LOCATION_DISTANCE, mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "network provider does not exist, " + ex.getMessage());
}
return super.onStartCommand(intent, flags, startId);
}
private class LocationListener implements android.location.LocationListener {
public LocationListener(String provider) {
Log.e(TAG, "LocationListener " + provider);
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location) {
Log.e(TAG, "onLocationChanged: " + location);
mLastLocation.set(location);
result = Activity.RESULT_OK;
publishResults(new double[] { mLastLocation.getLatitude(),
mLastLocation.getLongitude() }, result);
}
#Override
public void onProviderDisabled(String provider) {
Log.e(TAG, "onProviderDisabled: " + provider);
}
#Override
public void onProviderEnabled(String provider) {
Log.e(TAG, "onProviderEnabled: " + provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.e(TAG, "onStatusChanged: " + provider);
}
}
LocationListener[] mLocationListeners = new LocationListener[] {
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER) };
private void initializeLocationManager() {
Log.e(TAG, "initializeLocationManager");
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext()
.getSystemService(Context.LOCATION_SERVICE);
}
}
private void publishResults(double[] gps, int result) {
Bundle bundle = new Bundle();
bundle.putDoubleArray(GPS, gps);
bundle.putInt(RESULT, result);
resultReceiver.send(Activity.RESULT_OK, bundle);
}
}
You had select the wrong way to go - you should use Service to listen for Location updates, because Service will not be closed after it's code have been executed.
Another way - is to subscribe some service component to Location updates via AndroidManifest.xml by defining proper IntentFilter. In this situation - it can be an IntentService, as only it's OnReceive() method will be executed.