I want to save user's location after every 30 seconds to firebase realtime database from android service,my service stops when i add firebase, there is no crash log, any suggestions? or best solution to achieve this? Thanks
public class LocationService extends Service {
double pLatitude, pLongitude;
private DatabaseReference mDatabase;
FirebaseUser user;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getApplicationContext(),"Service Started", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
//service stops(crashes) on below two lines
mDatabase = FirebaseDatabase.getInstance().getReference();
user = FirebaseAuth.getInstance().getCurrentUser();
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
Toast.makeText(getApplicationContext(), "Service Started", Toast.LENGTH_LONG).show();
pushtofirebase(getLocation());
} catch (Exception e) {
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 30000);
}
private void pushtofirebase(GPSTracker gps) {
pLatitude = gps.getLatitude();
pLongitude = gps.getLongitude();
mDatabase.child("location").child(user.getUid()).push().setValue(String.valueOf(pLatitude));
mDatabase.child("location").child(user.getUid()).setValue(pLongitude);
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
private GPSTracker getLocation() {
GPSTracker gps = new GPSTracker(getApplicationContext());
if (gps.canGetLocation()) {
Toast.makeText(getApplicationContext(), gps.getLongitude() + " " + gps.getLatitude(), Toast.LENGTH_SHORT).show();
} else {
gps.showSettingsAlert();
}
return gps;
}
}
it may be a native crash change the logcat crash level to verbose and application to no filter
Related
I am trying to provide communication between activity and service but I have a problem. Inspite of initializing id on onStartCommand method, I am getting this error
java.lang.RuntimeException: Unable to create service com.a.b.c.Services.LocationService:
java.lang.NullPointerException: println needs a message
public class LocationService extends Service {
Context context;
Timer timer;
Double latitude, longitude;
private String id;
public LocationService() {
}
#Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
Log.i("servis", "Service working...");
Log.i("id", id);
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
int isHere = isHere();
updateUserStatus(isHere);
}
}, 0, 200000);
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
id = intent.getStringExtra("id");
return START_STICKY;
}
private int isHere() {
GPSTracker gps = new GPSTracker(this);
if (!gps.canGetLocation()) {
gps.showSettingsAlert();
} else {
latitude = gps.getLatitude();
longitude = gps.getLongitude();
if(Math.abs(xxx - latitude) <= 0.001 || Math.abs(yyy - longitude) <= 0.001)
return 1;
else
return 0;
}
return 0;
}
private void updateUserStatus(int isHere){
Call<Kisi> x = ManagerAll.getInstance().updateLocation(id, isHere);
x.enqueue(new Callback<Kisi>() {
#Override
public void onResponse(Call<Kisi> call, Response<Kisi> response) {
if(response.isSuccessful())
Log.i("status", "succesful");
}
#Override
public void onFailure(Call<Kisi> call, Throwable t) {
}
});
}
}
In your onCreate() method you try to log the variable id, but it is not initialized before the onStartCommand method is run, which happens after `onCreate():
Service lifecycle
Move your logging till after id is initialized and it should work fine.
I'm developing sport tracking app that uses location manager and gps provider for getting location updates every second even if the screen is off and the phone is in the pocket.
When user pressed start button in my activity I start service in foreground, display notification and register location listener.
Service starts receiving location updates and writes them into my track file.
Suddenly I get log message 'Power manager idle mode: true', the phone goes into Doze mode and my sevice stops getting any location update until the phone wakes up.
I read docs about Doze mode and see that it shouldn't affect location services, but it does in my case.
May be I'm doing something wrong. Here is the code of my service, any help is really appreciated.
public class LocService
extends Service
implements LocationListener, GpsStatus.Listener
{
private String mName;
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private LocationManager locationManager;
public LocService(String name)
{
super();
mName = name;
}
private final class ServiceHandler extends Handler
{
public ServiceHandler(Looper looper)
{
super(looper);
}
#Override
public void handleMessage(Message msg)
{
if (msg != null && msg.obj != null)
{
onHandleIntent((Intent)msg.obj);
}
else
{
logMessage("msg for intent is not good");
}
}
}
#Override
public void onCreate()
{
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
logMessage("Enabling Doze mode listener");
IntentFilter filter = new IntentFilter();
filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
registerReceiver(new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
onDeviceIdleChanged();
}
}, filter);
}
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
}
#TargetApi(Build.VERSION_CODES.M)
private void onDeviceIdleChanged()
{
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
if(powerManager != null)
{
logMessage("Power manager idle mode: " + powerManager.isDeviceIdleMode());
} else
{
logMessage("Power manager idle changed to ?");
}
}
protected void onHandleIntent(Intent intent)
{
//call start/stop location logging on proper intent
if(intent.getIntExtra("cmd", -1) == 1)
{
startLogging();
} else
{
stopLogging();
}
}
private void startLogging()
{
logMessage("LocationService.startLogging");
try
{
locationManager.addGpsStatusListener(this);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 0, this);
logMessage("requesting gps updates");
startForeground(ONGOING_NOTIFICATION, getNotification(-1, -1, true, false));
logMessage("Sending foreground service notification");
}
catch (SecurityException ex)
{
logMessage(" SecurityException while requesting location info: " + ex);
}
}
private void stopLogging()
{
try
{
locationManager.removeUpdates(this);
stopForeground(true);
notificationManager.cancel(ONGOING_NOTIFICATION);
}
catch (SecurityException ex)
{
logMessage(" SecurityException on stopLogging with location manager: " + ex);
}
}
#Override
public void onLocationChanged(Location location)
{
//save location lat, lon directly to track file
//flush file
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
//do nothing
}
#Override
public void onProviderEnabled(String provider)
{
logMessage("Location provider enabled " + provider);
}
#Override
public void onProviderDisabled(String provider)
{
logMessage("Location provider disabled " + provider);
}
#Override
public void onGpsStatusChanged(int event)
{
try
{
logMessage(" *** onGpsStatusChanged with " + event);
GpsStatus status = locationManager.getGpsStatus(null);
int inFix = 0;
int total = 0;
for (GpsSatellite satellite : status.getSatellites())
{
if (satellite.usedInFix()) inFix++;
total++;
}
logMessage(" Sats: " + total + " in fix " + inFix);
}
catch (SecurityException sex)
{
}
catch (Exception ex)
{
}
}
#Override
public void onStart(Intent intent, int startId)
{
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
onStart(intent, startId);
return START_STICKY;
}
#Override
public void onDestroy()
{
mServiceLooper.quit();
try
{
locationManager.removeUpdates(this);
}
catch (SecurityException ex)
{
logMessage(" SecurityException on Destroy service with location manager: " + ex);
}
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
private void logMessage(String msg)
{
Log.i("LocServ", msg);
}
}
It is not a given that when ACTION_DEVICE_IDLE_MODE_CHANGED is fired, doze was either turned on or off. There are more factors that can affect idle mode.
Try to create and acquire WakeLock.
PowerManager.WakeLock getLock(Context context, String lockName) {
if (wakeLock == null) {
PowerManager mgr = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName);
}
return wakeLock;
}
//on start service
getLock(ctxt.getApplicationContext(), "lockName").acquire();
//on destroy service
#Override
public void onDestroy() {
PowerManager.WakeLock lock = getLock(this.getApplicationContext(), "lockName");
if (lock.isHeld()) {
lock.release();
}
super.onDestroy();
}
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'm a bit new to Android and I'm trying to move some location finding and volley methods out of my fragment into a service, but now sure where to put what. It's basically a weather app that gets your current location and uses volley to pull forecast.io api data.
Here is my fragment now:
public class WeatherListFragment extends ListFragment implements LocationListener {
private final String initialURL = "https://api.forecast.io/forecast/8fc2b0556e166fa4670d4014d318152a/";
Weather[] myWeatherArray = {};
Weather myWeatherObject;
WeatherAdapter weatherAdapter;
LocationManager mLocationManager;
String currentLoc;
JSONArray data;
JSONObject day;
#Override
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
makeUseOfNewLocation(location);
// Remove the listener you previously added
mLocationManager.removeUpdates(this);
}
#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 onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLocationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
makeUseOfNewLocation(mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER));
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1, 1, this);
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1, 1, this);
}
public void getData() {
String API_URL = setLatLong(initialURL, currentLoc);
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, API_URL, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONObject daily = response.getJSONObject("daily");
data = daily.getJSONArray("data");
myWeatherArray = new Weather[data.length()];
for (int i = 0; i < myWeatherArray.length; i++) {
day = data.getJSONObject(i);
myWeatherObject = new Weather();
myWeatherObject.setmDate(day.getInt("time"));
myWeatherObject.setmTempMin(day.getInt("temperatureMin"));
myWeatherObject.setmTempMax(day.getInt("temperatureMax"));
myWeatherObject.setIcon(day.getString("icon"));
myWeatherArray[i] = myWeatherObject;
}
} catch (JSONException e) {
e.printStackTrace();
}
if (weatherAdapter != null) {
weatherAdapter.setData(myWeatherArray);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), "volley died", Toast.LENGTH_SHORT).show();
}
}
);
requestQueue.add(jsonObjectRequest);
}
public void makeUseOfNewLocation(Location location) {
if (location == null) {
return;
}
mLocationManager.removeUpdates(this);
double latDouble = location.getLatitude();
double longDouble = location.getLongitude();
String latString = String.valueOf(latDouble);
String longString = String.valueOf(longDouble);
String latLong = latString + "," + longString;
Log.e("gps", latLong);
currentLoc = latLong;
getData();
}
public String setLatLong(String roughURL, String loc) {
return roughURL + loc;
}
and here is the blank Service class using a Handler:
public class NotificationService 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) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
long endTime = System.currentTimeMillis() + 5*1000;
while (System.currentTimeMillis() < endTime) {
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
Notification n = new Notification(getApplicationContext());
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}
#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",
Thread.MIN_PRIORITY);
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 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();
}
}
Today i made my first background service that keeps running if i exit from my application.
It is logging lattitude and londitude.
I would like to add some more functions to my code, and i would like to ask your help about which way should i contine coding, and is it good that i made already?
I work with an Activity, with a handler that gets messages from background service:
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_act);
BackgroundLocationService.context=this;
Intent i = new Intent(this, BackgroundLocationService.class);
i.putExtra("handler", new Messenger(this.handler));
startService(i);
/*.......more code here......*/
}
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
// get data from msg
String result = msg.getData().getString("result");
Log.i("Activiti map: Locationing Service handler: ",
"get data: " + result);
super.handleMessage(msg);
}
};
And this is my background service:
public class BackgroundLocationService extends IntentService {
private static final String TAG = "Activiti map: Locationing Service";
private LocationManager locManager;
private LocationListener locListener = new MyLocationListener();
public static Context context;
private boolean gps_enabled = false;
private boolean network_enabled = false;
private boolean DEBUG=false;
private String latitude="0";
private String londitude="0";
Messenger messenger;
Timer t=new Timer();
public BackgroundLocationService()
{
super("myintentservice");
locManager = (LocationManager) context.getSystemService
(Context.LOCATION_SERVICE);
try {
gps_enabled =
locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {
if(DEBUG)
Log.e(TAG, ex.toString());
}
try {
network_enabled =
locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {
if(DEBUG)
Log.e(TAG, ex.toString());
}
if (gps_enabled) {
if(DEBUG)
Log.i(TAG, "Gps is Enabled!");
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
0, 0, locListener);
} else {
if(DEBUG)
Log.i(TAG, "Gps is Disabled!");
}
if (network_enabled) {
if(DEBUG)
Log.i(TAG, "Network provider is enabled!");
locManager.requestLocationUpdates
(LocationManager.NETWORK_PROVIDER, 0, 0, locListener);
} else {
if(DEBUG)
Log.i(TAG, "Network provider is Disabled!");
}
}
#Override
protected void onHandleIntent(Intent intent) {
messenger=(Messenger) intent.getExtras().get("handler");
t.schedule(new TimerTask() {
#Override
public void run() {
// just call the handler every 3 Seconds
Message msg=Message.obtain();
Bundle data=new Bundle();
data.putString("result", "latitude: " + latitude+
" londitude: "+londitude);
msg.setData(data);
try {
messenger.send(msg);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 100,3000);
}
class MyLocationListener implements LocationListener {
private static final String TAG = "Activiti map: LocationListener";
public void onLocationChanged(Location location) {
if (location != null) {
locManager.removeUpdates(locListener);
londitude = Double.toString(location.getLongitude());
latitude = Double.toString(location.getLatitude());
if(DEBUG)
Log.i(TAG, "Londitude: " + londitude + " Latitude: " + latitude);
}
}
public void onProviderDisabled(String arg) {
if(DEBUG)
Log.i(TAG, "Provider just Disabled: " + arg);
}
public void onProviderEnabled(String arg) {
if(DEBUG)
Log.i(TAG, "Provider just Enabled: " + arg);
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
}
Some problems that i would like to solve:
Is it possible to control the handler the service or anything in my code to keep SURE, that the service is stopped, started, etc? So i would like to add controls for example from a widget button for turning on and off the service. How is it possible ?
And another thing: If i quickly starts and exit my application many times i got each time a handler initalized and i got multiple log messages. How can i make a singleton of this or something like that?
Thanks for helping
Use Application for those purposes.
You can implement singleton logic into Application class and manage your service.
If you close your activity, the Service asks Application if Activity alive.
On Launch Activity, Application knows about and Service can bind with above mentioned Activity by using some Interfaces that Application stores.
**
The main Activity must initiate Handler to make to Service to talk with Activity
Here is some code:
public class MyApplication extends Application{
private static MyApplication mSingleton;
private static final String PACKAGE = "com.code";
private static final String PROCESS_NAME = PACKAGE + ".ui";
private static final String SERVICE_NAME = PROCESS_NAME + "/" + PACKAGE + ".srvce.MyService";
#Override
public void onCreate() {
super.onCreate();
mSingleton = this;
}
public MyApplication getApp(){
return mSingleton;
}
....
public boolean isServiceRun() {
ActivityManager activityManager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
boolean isRunnig = false;
for (int i = 0; i < services.size(); i++) {
RunningServiceInfo inf = services.get(i);
if(PROCESS_NAME.equals(inf.process)){
ComponentName cn = inf.service;
String str = cn.toString();
if(str.contains(SERVICE_NAME)){
isRunnig = true;
return isRunnig;
}
}
}
return isRunnig;
}
}