我有一项工作正常,但当应用程序崩溃时服务停止,我希望服务继续运行
清单中的我有这个
<service
android:name=".Services.SSubProcesoGps"
android:enabled="true"
android:exported="true"
/>
但如果我将清单更新为
<service
android:name=".Services.SSubProcesoGps"
android:enabled="true"
android:exported="true"
android:process=":foo"
/>
该服务运作不佳 这项服务有什么作用? 保存gps坐标 发送gps坐标 使用sendbroadcast更新UI 但随后更新了清单,UI未更新 (我不知道其他的东西或gps是否有效,因为当添加冒号时我无法调试服务)
public class SSubProcesoGps extends RoboService implements LocationListener{
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
LocationManager locationManager;
double latitud = 0;
double longitud = 0;
public static int hacambiado = 0;
public static boolean isRunning = false;
double contadorCronometro = 0;
long iniciocontador=0;
public static boolean guardarDatos = false;
boolean gpsIniciado = false;
Notification notification = null;
long startTime;
Posicion mPosicion = null;
//Location mLocation=null;
Posicion mPosicionAnterior = null;
//Location mLocationAnterior=null;
boolean crearNuevaPosicion = false;
public static final String response_result = "myresult";
public static final String response_message = "mymessaje";
public static final String response_messageGps = "mymessajeGps";
public static final String response_messageEncenderGps = "mymessajeEncenderGps";
private Recorrido recorrido = null;
@Inject
RecorridoSync recorridoSync;
@Inject
PosicionesSync posicionesSync;
@Inject
ConnectionStatusSync connectionStatusSync;
public static Thread threadCronometro;
static Thread ThreadTiempoLanzar;
static Thread ThreadCoordenadas;
@Inject
DataManagerSubProcesoGps mDataManager;
int Maxsegundos = 30; // un hilo/thread ejecutara(creará) cada N segundos
// otro hilo que envia informacion (recorridos y posiciones)
int segundos = 0;//este es el contador del anterior si es igual a MaxSegundos vuelve a 0
int tiempoGps = 0;//el tiempo en cada cuantos segundos guardará datos
int tiempoGpsListener=2; // cada cuanto tiempo el listener intentará obtener informacion
boolean monitorearVariacionVelocidad=false;
float velocidadMinimaVariacion=0;
int distanciaMonitoreo=0;
boolean MonitorearXTiempo=false;
boolean mEsPrimero=true;
Location currentLoc=null;
Location oldLoc=null;
boolean ListenerRegistrados=false;
private void getConfiguracion()
{
ParametrosRecorrido parametrosRecorrido=mDataManager.getParametrosRecorrido();
Maxsegundos= tiempoGps=parametrosRecorrido.getIntervaloTiempoMonitoreo();
monitorearVariacionVelocidad= parametrosRecorrido.getMonitorearVariacionVelocidad();
velocidadMinimaVariacion= parametrosRecorrido.getVelocidadMinimaVariacion();
distanciaMonitoreo=parametrosRecorrido.getIntervaloDistanciaMonitoreo();
if(distanciaMonitoreo>0) {
MonitorearXTiempo=false;
}else{
distanciaMonitoreo = 0;
MonitorearXTiempo=true;
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
@Override
public void onLocationChanged(Location loc) {
LocationListener(loc,false);
}
void LocationListener(Location loc, boolean esSegundoListener)
{
AvisarGpsEstaFuncionando(true,false);
if (guardarDatos) {
oldLoc=currentLoc;
currentLoc=loc;
inicializaPosicion(loc,esSegundoListener);
} else {
oldLoc=currentLoc=null;
mPosicionAnterior = mPosicion = null;
}
}
float calculaAceleracion()
{
if(oldLoc!=null && currentLoc!=null)
{
if(currentLoc.hasSpeed() && oldLoc.hasSpeed())
{
//formula es velocidad actual -velocidad anterior / el intervalo de tiempo
// (tiempo final - tiempo anterior)
float aceleracion= (currentLoc.getSpeed()-oldLoc.getSpeed())/((currentLoc.getTime()-oldLoc.getTime())/1000);
String texto="("+String.valueOf(currentLoc.getSpeed())+"\n"
+"-"+String.valueOf(oldLoc.getSpeed())+")\n"
+"/(("+String.valueOf(currentLoc.getTime())+"\n"
+"-"+oldLoc.getTime()+")/1000)";
MensajeAceleracion(aceleracion,texto);
return aceleracion;
}
}
return 0;
}
void inicializaPosicion(Location loc, boolean esSegundoListener) {
if (mPosicion == null || crearNuevaPosicion && loc != null) {
mPosicion = new Posicion();
crearNuevaPosicion = false;
}
if (loc != null) {
float Aceleracion = calculaAceleracion();
mPosicion.setEstatusEnviado(EstatusEnviado.Sin_Enviar.getValue());
if (loc.hasAccuracy())
mPosicion.setPrecision(loc.getAccuracy());
if (loc.hasSpeed()) {
mPosicion.setVelocidad(loc.getSpeed());
// velocidadfinal= loc.getSpeed();
}
if (loc.hasBearing())
mPosicion.setOrientacion(loc.getBearing());
if (loc.hasAltitude())
mPosicion.setAltitud(loc.getAltitude());
mPosicion.setFechaLectura(longtoDate(loc.getTime()));
mPosicion.setLatitud(loc.getLatitude());
mPosicion.setLongitud(loc.getLongitude());
mPosicion.setAceleracion(Aceleracion);
float AceleracionPositiva= (Aceleracion>0)? Aceleracion: (Aceleracion*(-1));
//guarda cuando se detecta una aceleracion mayor o igual configurada por el usuario
if (monitorearVariacionVelocidad && AceleracionPositiva >= velocidadMinimaVariacion) {
GuardarenHilo();
}
//significa que guardara información cuando esté configurado que guarde por tiempo
if ( !esSegundoListener && guardarDatos && (!MonitorearXTiempo ) || mEsPrimero) {
if (mPosicion != null && mPosicion.getFechaLectura() != null) {
GuardarenHilo();
mEsPrimero=false;
}
}
}
}
void GuardarenHilo()
{
Thread hilo = new Thread(new Runnable() {
@Override
public void run() {
guardarDatos(mPosicion);
mPosicionAnterior = mPosicion;
crearNuevaPosicion = true;
}
});
hilo.start();
}
void guardarDatos(Posicion posicion1) {
if (posicion1 != null && posicion1.getFechaLectura()!=null) {
Date date = posicion1.getFechaLectura();
iniciarRecorrido(date);
CreaPosicionGps(posicion1);
}
}
private Date longtoDate(long longDate) {
// See notes below
DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Date date = new Date(longDate);
String formatted = format.format(date);
return date;
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
String xx = s;
}
@Override
public void onProviderEnabled(String s) {
String xx = s;
}
@Override
public void onProviderDisabled(String s) {
String xx = s;
AvisarGpsEstaFuncionando(false,false);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
isRunning = true;
mEsPrimero=true;
getConfiguracion();
LanzarThreadIntervaloTiempo();
int value = super.onStartCommand(intent, flags, startId);
if (guardarDatos) {
iniciarCronometro();
IniciarForeGround();
//RecorridosIdBackground();
} else {
currentLoc=oldLoc=null;
recorrido = null;
IniciarGps();
AvisarGpsEstaFuncionando(false,true);
detenerCronometro();
detenerForeground();
//detenerSaveCoordenadas();
}
//esta fuera por que el proceso inicia cuando se entra al servicio
//pero no guarda nada hasa que tenga "guardarDatos" como true
if(MonitorearXTiempo)
SaveGpsCoordenadas();
return START_STICKY;
//return value;
}
void gpsEnable() {
// getting GPS status
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
isNetworkEnabled = false;//actualmente solo gps
}
void IniciarForeGround() {
if (guardarDatos) {
Intent intent = new Intent(getBaseContext(), MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendIntent = PendingIntent.getActivity(this, 0, intent, 0);
if (notification == null)
notification = new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_menu_gallery) // the status icon
.setTicker("hola muy myintentservice") // the status text
.setWhen(System.currentTimeMillis()) // the time stamp
.setContentTitle("content title") // the label of the entry
.setContentText("content teext") // the contents of the entry
.setContentIntent(pendIntent) // The intent to send when the entry is clicked
.build();
startForeground(1, notification);
}
}
void detenerForeground() {
if (notification != null)
stopForeground(true);
}
@Override
public void onCreate() {
super.onCreate();
isRunning = false;
}
public void AvisarGpsEstaFuncionando(boolean valor, boolean fake) {
Intent intent1 = new Intent("mx.twothePoint.app.gps");
intent1.putExtra(response_messageGps, valor);
intent1.putExtra("isFake", fake);
sendBroadcast(intent1);
}
public void MensajeAceleracion(float valor,String texto) {
/* Intent intent1 = new Intent("mx.twothePoint.app.aceleracion");
intent1.putExtra("x", valor);
intent1.putExtra("y", texto);
sendBroadcast(intent1);
*/
}
public void sendResult() {
Intent intent1 = new Intent("mx.twothePoint.app.Cronometro");
intent1.putExtra(response_message, contadorCronometro);
sendBroadcast(intent1);
}
@Override
public void onDestroy() {
super.onDestroy();
isRunning = false;
startService(new Intent(this, SSubProcesoGps.class));
}
void iniciarRecorrido(Date fechaInicio) {
if (recorrido == null)
recorrido = mDataManager.creaRecorrido(fechaInicio);
}
void CreaPosicionGps(Posicion posicion1) {
if (recorrido != null)
mPosicion = mDataManager.creaPosicion(recorrido, posicion1.getAceleracion()
, posicion1.getAltitud(), posicion1.getFechaLectura(), posicion1.getLatitud()
, posicion1.getLongitud(), posicion1.getOrientacion(), posicion1.getVelocidad()
, posicion1.getPrecision());
}
void iniciarCronometro() {
contadorCronometro =0;
iniciocontador=new Date().getTime(); //obtengo el inicio
if(threadCronometro==null)
threadCronometro = new Thread(new Runnable() {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
sendResult();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
contadorCronometro = (new Date().getTime()-iniciocontador)/1000;
//contadorCronometro++;
}
}
});
//if(!threadCronometro.isAlive())
if(threadCronometro.getState() == Thread.State.NEW)
threadCronometro.start();
}
void SaveGpsCoordenadas() {
if (ThreadCoordenadas == null)
ThreadCoordenadas = new Thread(new Runnable() {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
if (guardarDatos) {
if (mPosicion != null && mPosicion.getFechaLectura()!=null) {
guardarDatos(mPosicion);
mPosicionAnterior = mPosicion;
crearNuevaPosicion = true;
Thread.sleep(1000 * tiempoGps);
}
} else {
Thread.sleep(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
});
//if (!ThreadCoordenadas.isAlive())
if(ThreadCoordenadas.getState() == Thread.State.NEW)
ThreadCoordenadas.start();
}
void RecorridosIdBackground() {
/*Intent Intent = new Intent(this, SSubProcesoSendRecorrido.class);
startService(Intent);
*/
Thread EnviarCoordenadasHilo = new Thread(new Runnable() {
public void run() {
ObtenerRecorridoId();
EnviarPosiciones();
}
});
Command command = new Command() {
@Override
public void execute() {
}
};
connectionStatusSync.CheckConnection(EnviarCoordenadasHilo,command);
}
void LanzarThreadIntervaloTiempo() {
if (ThreadTiempoLanzar == null)
ThreadTiempoLanzar = new Thread(new Runnable() {
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (segundos == Maxsegundos) {
segundos = 0;
RecorridosIdBackground();
}
segundos++;
}
}
});
//if (!ThreadTiempoLanzar.isAlive())
if(ThreadTiempoLanzar.getState() == Thread.State.NEW)
ThreadTiempoLanzar.start();
}
/**
* Obteiene el recorridoId para todos los recorridos que estan guardados en la BD interna
*/
void ObtenerRecorridoId() {
//solo consigo los recorridos que tienen gps (obviamente sin enviar)
//pues no tiene caso conseguir un recorrido que no tiene coordenadas gps
List<Recorrido> recorridos = mDataManager.getRecorridosSinIdSinEnviar();
if(recorridos.size()>0) {
mDataManager.UpdateEnviandoList(recorridos);
int uno=1;
//recorridos.forEach(x->recorridoSync.getRecorridoId(x));
for (int i = 0; i < recorridos.size(); i++) {
recorridoSync.getRecorridoId(recorridos.get(i));
}
}
}
void EnviarPosiciones() {
//consigos los recorridos que tienen gps sin enviar
List<Recorrido> recorridos = mDataManager.getRecorridosConGpsSinEnviar();
List<Posicion> allPosicion = new ArrayList<>();
for (int i = 0; i < recorridos.size(); i++) {
recorridos.get(i).resetPosiciones();
allPosicion.addAll( mDataManager.getPosicionesSinEnviarById(recorridos.get(i).getId()));
}
//quiere decir que solo esta el ultimo recorridoID
//por que los demás ya los ha enviado
if(recorridos.size()==1)
{
mDataManager.EliminaRecorridosFinalizados(recorridos.get(0).getId());
}
//elimino los que estan marcados como enviado (aunque ya deben estar eliminados)
// mDataManager.removeEnviandoListPosiciones(allPosicion);
//actulizo como "enviando"
mDataManager.UpdateEnviandoListPosiciones(allPosicion);
//despues de actualizar el estatus empiezo a enviar los detalles de cada recorrido
for (int i = 0; i < recorridos.size(); i++) {
//este select esta obteniendo los que tienen el estatus sin_enviar
List<Posicion> posicions = mDataManager.getPosicionesSinEnviarByIdRecorridoinMemory(recorridos.get(i).getId(), allPosicion);
if (posicions.size() > 0) {
posicionesSync.sendPosiciones(posicions, recorridos.get(i).getRecorridoId());
}
}
}
void detenerCronometro() {
if (threadCronometro != null && threadCronometro.isAlive())
threadCronometro.interrupt();
}
void IniciarGps() {
try {
locationManager = (LocationManager) getBaseContext().getSystemService(LOCATION_SERVICE);
gpsEnable();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
//si los listener aun no estan registrados entonces los regitro
if(!ListenerRegistrados)
if(MonitorearXTiempo) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, (tiempoGpsListener * 1000), 0, this);
}else {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, distanciaMonitoreo, this);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, (tiempoGpsListener * 1000), 0, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
LocationListener(location,true);
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
});
}
ListenerRegistrados=true;
} catch (Exception e) {
e.printStackTrace();
}
}
}