I have a problem that is as follows: My application sends the coordinates from time to time (I get this interval from the WebService). But the biggest problem is when the phone is turned off or even restarted the service does not return in backgroud, has anyone ever gone through this? as I could solve.
public class LembreDeMandarLocalizacao extends BroadcastReceiver {
private static final String TAG = "enviarLocalizacao";
public static final String ACTION = "com.routerbox.routerboxosoficial.LEMBRE_DE_MANDAR_LOCALIZACAO";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Enviou dados do dispositivo: " + new Date());
context.startService(new Intent(context, MandarLocalizacaoService.class));
}
}
public class MandarLocalizacaoService extends IntentService implements LocationListener,
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = "enviarLocalizacao";
private static final String CICLO_SERVICE = "cicloService";
private ChaveIntegracao chaveIntegracaoClasse;
private List<DadosDispositivo> dadosDispositivos;
private NivelDeBateria nivelDeBateria;
private String nivelBateria;
private float nivelBateriaFloat;
private NumberFormat format;
private Intent intent;
private GoogleApiClient mGoogleApiClient;
private double latitude;
private double longitude;
private String dataFormatada;
private ConexaoComInternet conexaoComInternet = new ConexaoComInternet(this);
private DatabaseHelper databaseHelper;
private DadosDispositivoDAO dadosDispositivoDAO;
private static final int CONSTANTE_PERMISSOES = 1;
private SharedPreferencesClasse sharedPreferencesClasse = new SharedPreferencesClasse();
public MandarLocalizacaoService() {
super("nomeDaThreadAqui");
}
@Override
public void onCreate() {
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addApi(LocationServices.API)
.build();
databaseHelper = new DatabaseHelper(getBaseContext());
dadosDispositivoDAO = new DadosDispositivoDAO();
mGoogleApiClient.connect();
Log.d(CICLO_SERVICE, "onCreate::MandarLocalizacaoService");
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
Log.d(CICLO_SERVICE, "onStartCommand::MandarLocalizacaoService");
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(CICLO_SERVICE, "onBind::MandarLocalizacaoService");
return super.onBind(intent);
}
@Override
public boolean onUnbind(Intent intent) {
Log.d(CICLO_SERVICE, "onUnbind::MandarLocalizacaoService");
return super.onUnbind(intent);
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
Log.d(CICLO_SERVICE, "onHandleIntent::MandarLocalizacaoService");
enviarDados();
}
private void enviarDados() {
try {
// Simula algum processamento
Thread.sleep(1000);
Log.d(CICLO_SERVICE, "enviarDados::MandarLocalizacaoService");
iniciadorComponente();
String urlBase = sharedPreferencesClasse.obterSharedPreferences(getBaseContext(), "urlBase");
int idDispositivo = sharedPreferencesClasse.obterSharedPreferences(getBaseContext(), "idDispositivo", 1);
String usuario = sharedPreferencesClasse.obterSharedPreferences(getBaseContext(), "usuario");
format = NumberFormat.getInstance();
format.setMaximumFractionDigits(0);
nivelBateriaFloat = nivelDeBateria.verficaNivelBateria(getBaseContext());
nivelBateriaFloat = nivelBateriaFloat * 100;
Log.d(TAG, "Nível Bateria Float: " + nivelBateriaFloat);
dataFormatada = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(new Date());
Log.d(TAG, "Data formatada: " + dataFormatada);
if (latitude > 0 && longitude > 0){
}
else {
try {
latitude = Double.parseDouble(sharedPreferencesClasse.obterSharedPreferences(this,"latitude"));
longitude = Double.parseDouble(sharedPreferencesClasse.obterSharedPreferences(this,"longitude"));
}catch (NullPointerException e){
}
}
if (conexaoComInternet.estaConectadoComAInternet()) {
Log.d(TAG, "verifica registros: " + dadosDispositivoDAO.verificaSeExisteRegistros(databaseHelper));
if (dadosDispositivoDAO.verificaSeExisteRegistros(databaseHelper)) {
Autenticacao autenticacao = new Autenticacao(chaveIntegracaoClasse.criarChaveIntegracao(sharedPreferencesClasse.obterSharedPreferences(getBaseContext(), "cnpjEmpresa")),usuario);
Log.d(TAG, "Lista de dados do dispositivo: " + dadosDispositivoDAO.listarDadosDispositivo(databaseHelper));
RecebeDadosDispositivo recebeDadosDispositivo = new RecebeDadosDispositivo(autenticacao, dadosDispositivoDAO.listarDadosDispositivo(databaseHelper));
EnvelopeLocalizacao envelopeLocalizacao = new EnvelopeLocalizacao(recebeDadosDispositivo);
//chama o retrofit para fazer a requisição no webservice
EnviarLocalizacaoCallback enviarLocalizacaoCallback = new EnviarLocalizacaoCallback(
getBaseContext(),
urlBase);
enviarLocalizacaoCallback.enviarDadosDispositivo(envelopeLocalizacao);
Log.d(TAG, "ExemploServico processando com internet, tem registros no banco");
} else {
Autenticacao autenticacao = new Autenticacao(chaveIntegracaoClasse.criarChaveIntegracao(sharedPreferencesClasse.obterSharedPreferences(getBaseContext(), "cnpjEmpresa")),usuario);
dadosDispositivos.add(new DadosDispositivo(usuario, dataFormatada, String.valueOf(latitude), String.valueOf(longitude), String.valueOf(nivelBateriaFloat), String.valueOf(idDispositivo)));
RecebeDadosDispositivo recebeDadosDispositivo = new RecebeDadosDispositivo(autenticacao, dadosDispositivos);
EnvelopeLocalizacao envelopeLocalizacao = new EnvelopeLocalizacao(recebeDadosDispositivo);
//chama o retrofit para fazer a requisição no webservice
EnviarLocalizacaoCallback enviarLocalizacaoCallback = new EnviarLocalizacaoCallback(
getBaseContext(),
urlBase);
enviarLocalizacaoCallback.enviarDadosDispositivo(envelopeLocalizacao);
Log.d(TAG, "ExemploServico processando com internet, não tem registros no banco");
}
} else {
dadosDispositivos.add(new DadosDispositivo(usuario, dataFormatada, String.valueOf(latitude), String.valueOf(longitude), String.valueOf(nivelBateriaFloat), String.valueOf(idDispositivo)));
dadosDispositivoDAO.inserirDadosDispositivo(databaseHelper, dadosDispositivos);
Log.d(TAG, "verifica registros: " + dadosDispositivoDAO.verificaSeExisteRegistros(databaseHelper));
Log.d(TAG, "ExemploServico processando sem internet, salva registros no banco");
}
} catch (InterruptedException e) {
Log.e(TAG, e.getMessage(), e);
}
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
Log.d(CICLO_SERVICE, "onStart::MandarLocalizacaoService");
super.onStart(intent, startId);
}
@Override
public boolean stopService(Intent name) {
Log.d(CICLO_SERVICE, "stopService::MandarLocalizacaoService");
return super.stopService(name);
}
@Override
public void onDestroy() {
// stopLocationUpdates();
mGoogleApiClient.disconnect();
super.onDestroy();
// Ao encerrar o serviço, altera a flag para a thread parar
Log.d(CICLO_SERVICE, "onDestroy::MandarLocalizacaoService");
}
private void iniciadorComponente() {
Log.d(CICLO_SERVICE, "iniciadorComponente::MandarLocalizacaoService");
chaveIntegracaoClasse = new ChaveIntegracao();
nivelDeBateria = new NivelDeBateria();
dadosDispositivos = new ArrayList<>();
intent = new Intent();
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.d(CICLO_SERVICE, "onConnected::MandarLocalizacaoService");
startLocationUpdates();
}
@Override
public void onConnectionSuspended(int i) {
Log.d(CICLO_SERVICE, "onConnectionSuspended::MandarLocalizacaoService");
stopLocationUpdates();
}
protected void startLocationUpdates() {
Log.d(CICLO_SERVICE, "startLocationUpdates::MandarLocalizacaoService");
LocationRequest locationRequest = new LocationRequest();
locationRequest.setInterval(10000);
locationRequest.setFastestInterval(5000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, this);
}
protected void stopLocationUpdates(){
Log.d(CICLO_SERVICE, "stopLocationUpdates::MandarLocalizacaoService");
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
@Override
public void onLocationChanged(Location location) {
Log.d(CICLO_SERVICE, "onLocationChanged::MandarLocalizacaoService");
latitude = location.getLatitude();
longitude = location.getLongitude();
Log.d(TAG, "latitude: " + latitude);
Log.d(TAG, "longitude: " + longitude);
sharedPreferencesClasse.gravarSharedPreferences(this,"latitude", String.valueOf(location.getLatitude()));
sharedPreferencesClasse.gravarSharedPreferences(this,"longitude", String.valueOf(location.getLongitude()));
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
}
Here I use this alarm to trigger how much time has passed:
public class AlarmUtil {
private static final String TAG = "enviarLocalizacao";
// Agenda o alarme na data/hora informado.
public static void schedule(Context context, Intent intent, long triggerAtMillis){
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarme = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarme.set(AlarmManager.RTC_WAKEUP, triggerAtMillis, pendingIntent);
Log.d(TAG, "Alarme agendado com sucesso.");
}
// Agendar o alarme com a opção de repetir
public static void scheduleRepeat (Context context, Intent intent, long triggerAtMillis, long intervalMillis){
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarme = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarme.setInexactRepeating(AlarmManager.RTC_WAKEUP, triggerAtMillis, intervalMillis, pendingIntent);
Log.d(TAG, "Alarme agendado com sucesso com repeat. ");
Log.d(TAG, "Alarme agendado com sucesso triggerAtMillis (Agendar): " + triggerAtMillis);
Log.d(TAG, "Alarme agendado com sucesso intervalMillis (Intervalo): " + intervalMillis);
}
// Cancela o alarme
public static void cancel(Context context, Intent intent) {
AlarmManager alarme = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarme.cancel(pendingIntent);
Log.d(TAG, "Alarme cancelado com sucesso.");
}
// Verifica se alarme está ativo
public static boolean checkAlarm(Context context, Intent intent){
boolean alarmUp = (PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_NO_CREATE) != null);
if (alarmUp) {
Log.d(TAG, "Alarme está ativo.");
} else {
Log.d(TAG, "Alarme não está ativo.");
}
return alarmUp;
}
}
In main activity I have this method where I check my alarm
private void verificaAlarme() {
Intent intent = new Intent(LembreDeMandarLocalizacao.ACTION);
boolean verificaAlarme = AlarmUtil.checkAlarm(MenuActivity.this, intent);
Log.d(TAG, "Verifica alarme: " + verificaAlarme);
if (!verificaAlarme) {
// Agenda para repetir no horário que retornar o ws
AlarmUtil.scheduleRepeat(MenuActivity.this, intent, getTime(), intervaloCoordenadas * 60 * 1000);
}
}