I'm having some troubles trying to stop a services which I started previously on the onCreate() of class that is extended of an Android Application class. The GPS is supposed to be running during the execution of the app (that part is working fine) but when the app is closed the service is still running. I tried to use the onTerminate() because onClose() doesn´t exist in Applicaction class and the service keep running.
public class ControlEntrega extends Application {
public GPSBean posicion;
public ServicioGPS servicio;
public void onCreate() {
Log.d(TAG,"onCreate");
super.onCreate();
usuario=null;
cliente=null;
entrega=null;
dal=new DAL(getApplicationContext());
crearDB();
util=new Utilitario();
servicio=new ServicioGPS();
posicion=new GPSBean();
iniciarGPS();
}
#Override
public void onTerminate() {
super.onTerminate();
Log.d(TAG,"onTerminate");
try {
stopService(new Intent(this,ServicioGPS.class));
} catch (Exception e) {
Log.d(TAG,"onTerminate error: "+e.getMessage());
}
}
}
The Service Class:
public class ServicioGPS extends Service implements LocationListener{
String TAG=ServicioGPS.class.getCanonicalName();
LocationManager locationManager=null;
public int tiempoGPS=1;
public int distanciaMetros=10;
Intent notificacion;
ControlEntrega controlador;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG,"onDestroy");
locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
locationManager.removeUpdates(this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
controlador= (ControlEntrega)getApplicationContext();
if(controlador!=null){
if(controlador.posicion!=null){
controlador.posicion.imprimir();
}
}
locationManager =(LocationManager)getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria,true);
//LocationManager.GPS_PROVIDER
//LocationManager.NETWORK_PROVIDER
locationManager.requestLocationUpdates(provider,1000 * 60 * tiempoGPS,distanciaMetros,this);
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "onLocationChanged");
//Seteando los valores del objeto location
if(controlador!=null){
Log.d(TAG, "seteando bean GPS");
controlador.posicion=new GPSBean();
controlador.posicion.latitud=location.getLatitude();
controlador.posicion.longitud=location.getLongitude();
controlador.posicion.altitud=location.getAltitude();
controlador.posicion.precision=location.getAccuracy();
controlador.posicion.proveedor=location.getProvider();
controlador.posicion.tiempo=location.getTime();
controlador.posicion.velocidad=location.getSpeed();
controlador.posicion.imprimir();
}
//Notificación
Intent notificacion = new Intent(getString(R.string.intentGPS));
sendBroadcast(notificacion);
//Se para asi mismo, ya se calendarizo antes
stopSelf();
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
There is a way I could know when the application stops completely? So I can stop the service.
Regards
Alfredo
public class EyeCastApplication extends Application {
static Context context;
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
context = getApplicationContext();
}
/***
* start Heart Beat Loop
*/
public static void stopHeartBeatLoop() {
context.stopService(new Intent(context, CmdConnectService.class));
}
enter code here
enter code here
}
Related
I am trying to run intent service in background even if the app is closed and have written this code. But the service doesn't runs in the background.Here is my code.
MainActivity.java
package com.example.h.intentservice;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void startService(View view){
Intent intent = new Intent(this,MyIntentService.class);
startService(intent);
}
public void stopService(View view){
Intent intent=new Intent(this,MyIntentService.class);
stopService(intent);
}
}
MyIntentService.java
public class MyIntentService extends IntentService {
public MyIntentService() {
super("My_Worker_Thread");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"Service started",Toast.LENGTH_LONG).show();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this,"Stopped",Toast.LENGTH_LONG).show();
}
#Override
protected void onHandleIntent(Intent intent) {
synchronized (this){
int count=0;
while(count<=10)
{
try{
wait(1500);
count++;
}
catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
}
First of all an intent service cannot run in the background after closing the application. An intentService is run only once and it automatically closes the thread once the task assigned to it is done. You will have to use a service for background requests.
Secondly you have not called the startService() method from the onCreate and therefore the serviceIntent has not been initiated.
In both the startService() method and the stopService() method you are passing a view which i can see is unused inside the method body. So therefore i can advice you to adjust your code this way
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService();
//here you have started the service intent
//if you want to stop the same just call stopService()
}
public void startService(){
Intent intent = new Intent(this,MyIntentService.class);
startService(intent);
}
public void stopService(){
Intent intent=new Intent(this,MyIntentService.class);
stopService(intent);
}
Am also posting sample code for a service that can run in the background.
Below is sample code for a service
public class UploadService extends Service {
public int counter = 0;
public UploadService(Context applicationContext) {
super();
Log.i("SERVICE", "hService started");
}
public UploadService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
//instantiate your variables here
//i call my startUpload method here to doing the task assigned to it
startUpload();
return START_STICKY;
}
public void startUpload() {
//call the method with your logic here
//mine is a sample to print a log after every x seconds
initializeTimerTask();
}
/**
* it sets the timer to print the counter every x seconds
*/
public void initializeTimerTask() {
// timerTask = new TimerTask() {
//we can print it on the logs as below
Log.i("in timer", "in timer ++++ " + (counter++));
//or use the print statement as below
System.out.println("Timer print " + counter++);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
stopSelf();
}
}
I have been trying to find a way to implement the SpeechRecognizer API in a Service (runs in background) so that when a condition is met, it will open the speech recognizer without having to be within the application. My question is whether this is even possible natively? And if so, how would it be done?
Here is my code snippet. You can use the recognition listener like this in a service.
I'm not sure how you are scheduling your services, I have left that to you. But you can do something like this. (I have not added code for restarting service / starting it in a timer etc.)
public class MyService extends Service {
protected static SpeechRecognizer mSpeechRecognizer;
protected Intent mSpeechRecognizerIntent;
Context c;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//if condition is met then do this
SpeechRecognitionListener h = new SpeechRecognitionListener();
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizer.setRecognitionListener(h);
mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
Log.d("avail", " " + mSpeechRecognizer.isRecognitionAvailable(this));
if (mSpeechRecognizer.isRecognitionAvailable(this))
Log.d("created", "onBeginingOfSpeech");
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
this.getPackageName());
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
c= getApplicationContext();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
class SpeechRecognitionListener implements RecognitionListener {
#Override
public void onReadyForSpeech(Bundle bundle) {
Log.d("onReady", "service");
}
#Override
public void onBeginningOfSpeech() {
}
#Override
public void onRmsChanged(float v) {
}
#Override
public void onBufferReceived(byte[] bytes) {
}
#Override
public void onEndOfSpeech() {
}
#Override
public void onError(int i) {
Log.d("ERROR","ERROR");
}
#Override
public void onResults(Bundle resultsBundle) {
Log.d("Results", "onResults");
}
#Override
public void onPartialResults(Bundle bundle) {
}
#Override
public void onEvent(int i, Bundle bundle) {
}
}
}
The thing is that I'm trying on the emulator, and it works but only once I press the "send location to device" on the emulator but before that I don't have the chance to get the location....How do I get the location for the first time using this service?. I don't have a real device right know and the emulator is my only way of testing this for now.....I tried to send a 0,0 at first to see if that would trigger a location update but it's not working as well......any ideas?
#SuppressWarnings("MissingPermission")
public class GPSService extends Service {
private LocationListener listener;
private LocationManager locationManager;
private String lastKnownLatitude;
private String lastKnownLongitude;
private Boolean isFirstTime=true;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
broadcastLocation("0","0");
listener= new LocationListener() {
#Override
public void onLocationChanged(Location location) {
//To transfer the data to the main activity I use broadcast receiver in the main activity, using an intent filter location_update
Intent intentSendLocationMainActivity = new Intent("location_update");
lastKnownLatitude=""+location.getLatitude();
lastKnownLongitude=""+location.getLongitude();
Log.d("LOCATION-UPDATE",lastKnownLatitude+" long:"+lastKnownLongitude);
broadcastLocation(lastKnownLatitude,lastKnownLongitude);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
Log.d("GPS-Stat-Changed",s);
}
#Override
public void onProviderEnabled(String s) {
Log.d("GPS-Provider-Enabled",s);
}
#Override
public void onProviderDisabled(String s) {
Intent activateGPSIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
activateGPSIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(activateGPSIntent);
}
};
locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
//noinspection MissingPermission, listen for updates every 3 seconds
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,5000,0,listener);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("ClearFromRecentService", "Service Started");
Log.d("LAST_LAT_AND_LONG",lastKnownLatitude+" "+lastKnownLongitude);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("ClearFromRecentService", "Service Destroyed, Removing update location listener");
//unregistering the listener
/*if(locationManager != null){
locationManager.removeUpdates(listener);
}*/
}
public void onTaskRemoved(Intent rootIntent) {
Log.e("ClearFromRecentService", "END");
//here you can call a background network request to post you location to server when app is killed
Toast.makeText(getApplicationContext(), "I'm still getting user coordinates", Toast.LENGTH_LONG).show();
//stopSelf(); //call this method to stop the service
}
public void broadcastLocation(String latitude,String longitude){
Intent intentSendLocationMainActivity = new Intent("location_update");
intentSendLocationMainActivity.putExtra("latitude",latitude);
intentSendLocationMainActivity.putExtra("longitude",longitude);
//I need to differentiate here if the app is killed or not to send the location to main activity or to a server
sendBroadcast(intentSendLocationMainActivity);
}
}
EDIT: This is the complete service working. For the first time it gets the coordinates with the getLastKnownLocation() and the on sucesive times with the listener onLocationChanged()
#SuppressWarnings("MissingPermission")
public class GPSService extends Service {
private LocationListener listener;
private LocationManager locationManager;
private String lastKnownLatitude;
private String lastKnownLongitude;
private Boolean isFirstTime=true;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
listener= new LocationListener() {
#Override
public void onLocationChanged(Location location) {
//To transfer the data to the main activity I use broadcast receiver in the main activity, using an intent filter location_update
Intent intentSendLocationMainActivity = new Intent("location_update");
lastKnownLatitude=""+location.getLatitude();
lastKnownLongitude=""+location.getLongitude();
Log.d("LOCATION-UPDATE",lastKnownLatitude+" long:"+lastKnownLongitude);
broadcastLocation(lastKnownLatitude,lastKnownLongitude);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
Log.d("GPS-Stat-Changed",s);
}
#Override
public void onProviderEnabled(String s) {
Log.d("GPS-Provider-Enabled",s);
}
#Override
public void onProviderDisabled(String s) {
Intent activateGPSIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
activateGPSIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(activateGPSIntent);
}
};
locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
//noinspection MissingPermission, listen for updates every 3 seconds
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,5000,0,listener);
Map<String, String> coordinates=getLastKnownLocation(locationManager);
broadcastLocation(coordinates.get("latitude"),coordinates.get("longitude"));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("ClearFromRecentService", "Service Started");
Log.d("LAST_LAT_AND_LONG",lastKnownLatitude+" "+lastKnownLongitude);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("ClearFromRecentService", "Service Destroyed, Removing update location listener");
//unregistering the listener
/*if(locationManager != null){
locationManager.removeUpdates(listener);
}*/
}
public void onTaskRemoved(Intent rootIntent) {
Log.e("ClearFromRecentService", "END");
//here you can call a background network request to post you location to server when app is killed
Toast.makeText(getApplicationContext(), "I'm still getting user coordinates", Toast.LENGTH_LONG).show();
//stopSelf(); //call this method to stop the service
}
private void broadcastLocation(String latitude,String longitude){
Intent intentSendLocationMainActivity = new Intent("location_update");
intentSendLocationMainActivity.putExtra("latitude",latitude);
intentSendLocationMainActivity.putExtra("longitude",longitude);
//I need to differentiate here if the app is killed or not to send the location to main activity or to a server
sendBroadcast(intentSendLocationMainActivity);
}
private Map<String, String> getLastKnownLocation(LocationManager lm){
Location lastKnownLocation=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
String ll=""+lastKnownLocation.getLatitude();
Map<String, String> coordinates = new HashMap<String, String>();
// Check everytime this value, it may be null
if(lastKnownLocation != null){
coordinates.put("latitude",""+lastKnownLocation.getLatitude());
coordinates.put("longitude",""+lastKnownLocation.getLongitude());
}else{
coordinates.put("latitude","0");
coordinates.put("longitude","0");
}
return coordinates;
}
}
#Override
public void onCreate() {
super.onCreate();
locationManager = (LocationManager) getApplicationContext()
.getSystemService(Context.LOCATION_SERVICE);
Location lastKnownLocation = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
// Check everytime this value, it may be null
if(lastKnownLocation != null){
double latitude = lastKnownLocation.getLatitude();
double longitude = lastKnownLocation.getLongitude();
// Use values as you wish
}
broadcastLocation("0","0");
....
}
I am working on a simple GeoFence Service. I am not using the GeofencingApi because I am working with a jni bridge and making the library available would be to much overhead for my project.
So my Problem now is, that the LocationManager is not removing Updates after I am calling removeUpdates. I don't understand why. My code is as follows:
public class GeoFenceService extends Service {
public GeoFenceService() { Log.v("GeoFenceService","GeoFenceService init"); }
public static LocationManager mlocManager;
public static LocationListener mlocListener;
public void updateLocationAndCheckGeoFences() {
Log.d("GeoFenceService","Updating Location");
GeoFenceService.mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
GeoFenceService.mlocListener = new MyLocationListener();
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
String bestProvider = GeoFenceService.mlocManager.getBestProvider(criteria, true);
GeoFenceService.mlocManager.requestLocationUpdates(bestProvider, 0, 0, GeoFenceService.mlocListener);
//Location loc = mlocManager.getLastKnownLocation(bestProvider);
//checkGeoFences4(loc);
}
public void checkGeoFences4(Location locCurrent) {
Log.d("GeoFenceService","Checking GeoFence for Location:"
+locCurrent.getLatitude()+"/"+locCurrent.getLongitude());
for (Voucher voucher : listVouchers) {
Location locVoucher = new Location("Voucher");
locVoucher.setLatitude(voucher.dblLat);
locVoucher.setLongitude(voucher.dblLon);
float distance = locCurrent.distanceTo(locVoucher);
Log.d("GeoFenceService","\tGeoFence for Voucher"+voucher.strText+" Distance:"+distance);
if (distance < voucher.dblRadius) {
showNotification(voucher.strText,voucher.intEntryId);
}
}
}
public class MyLocationListener implements LocationListener
{
#Override
public void onLocationChanged(Location loc)
{
try {
checkGeoFences4(loc);
try {
GeoFenceService.mlocManager.removeUpdates(GeoFenceService.mlocListener);
Log.d("GeoFenceService","Location Update suspended");
} catch(Exception e) {
Log.e("GeoFenceService","Failed to suspend Location Update"+e.getMessage());
}
} catch (Exception e) { }
}
#Override
public void onProviderDisabled(String provider)
{
}
#Override
public void onProviderEnabled(String provider)
{
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}
//Stuff for class GeoFenceService (simplyfied)
private final int UPDATE_INTERVAL = 15 * 60 * 1000;
private Timer timer = new Timer();
public void onCreate() { Log.d("GeoFenceService","GeoFenceService created"); }
public void onDestroy() { if (timer != null) { timer.cancel(); } }
public int onStartCommand(Intent intent, int flags, int startid) {
Log.d("GeoFenceService","GeoFenceService started");
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
updateLocationAndCheckGeoFences();
}
}, 0, UPDATE_INTERVAL);
return START_STICKY;
}
}
While updateLocationAndCheckGeoFences is succesfully starting the Location Updates removing them is not working.
The Log continuely logging:
D/GeoFenceService( 9953): Checking GeoFence for Location:♣♣.♣♣♣♣♣♣♣♣♣♣♣♣♣♣/♣♣.♣♣♣♣♣♣♣♣♣♣♣♣♣♣
D/GeoFenceService( 9953): GeoFence for VoucherRestaurant ♣♣♣♣: GUTSCHEIN jetzt einlösen Distance:315341.0
D/GeoFenceService( 9953): Location Update suspended
I hope someone can help me,
thanks in advance
I am using a Service to play background Music. The problem is that the music continues playing when i have finished the activity.
Here is code From Main Activity which starts the service
Intent svc=new Intent(HomeActivity.this, BackgroundSoundService.class);
startService(svc);
BackgroundSoundService.java
public class BackgroundSoundService extends Service {
private static final String TAG = null;
public static MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.d("atMedia", "Backround Music playing");
player = MediaPlayer.create(this, R.raw.background);
player.setLooping(true); // Set looping
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {
}
public void onPause() {
}
#Override
public void onDestroy() {
super.onDestroy();
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
}
Try to stop service from your MainActivity:
Intent svc=new Intent(HomeActivity.this, BackgroundSoundService.class);
stopService(svc);
You have to call selfStop() method inside your service.
or use stopService() API