IntentService PEGAJOSO e sensor de monitoramento de pára quando não deve, no Android
-
14-11-2019 - |
Pergunta
Na minha aplicação onCreate eu verificação de algumas condições e, em seguida, eu iniciar uma Atividade como esta:
Intent startIntent = new Intent(getApplicationContext(), EnableLocationProviderActivity.class);
startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(startIntent);
De que a Atividade de eu começar um IntentService que registrar alguns ouvintes para os sensores, ele é iniciado como STICKY o que significa que deve ser interrompido de forma explícita.Que IntentService monitora os sensores.
O meu problema é que quando eu voltar para a primeira Atividade, os sensores não estão de detecção mais (eu coloquei um Log.v em onSensorChanged (a começar mostrando dados e, em seguida, ele pára).
Por que pode ser que ela deixa se eu não parei, explicitamente?Além disso, eu vejo às vezes OnDestroy do IntentService ser chamado, mas, novamente, Como pode ser chamado, se é PEGAJOSO e eu não chamar stopself() e não parou de alguma outra forma?
Obrigado!Guillermo.
EDITAR
Este é o código do IntentService (que deve estar em execução o tempo todo, apesar de se o celular entra em modo de suspensão ou de casa de botão é pressionado (que eu sei sobre a bateria e tudo mais, o usuário será avisado sobre isso e terá a oportunidade de fechar o aplicativo quando ele quer.
O serviço é chamado de MainActivity como este:
Intent startIntent = new Intent(GdpTesisApplication.getInstance().getApplicationContext(), SensingService.class);
startService(startIntent);
E o serviço de código é esse:
public class SensingService extends IntentService implements SensorEventListener {
private float[] mAccelerationValues;
private SensorManager mSensorManager = null;
String sensorType = "";
public SensingService(String name) {
super(name);
setIntentRedelivery(true);
}
public SensingService() {
super("SensingService");
setIntentRedelivery(true);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v(ApplicationName,"SensingService.onStartCommand");
super.onStartCommand(intent, flags, startId); // If this is not written then onHandleIntent is not called.
return START_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
Log.v(ApplicationName, "SensingService.onCreate");
initialize();
}
private void initialize() {
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); // This must be in onCreate since it needs the Context to be created.
mAccelerationValues = new float[3];
Log.v(ApplicationName, "Opening Location Service from Sensing Service");
LocationService myLocation = new LocationService();
myLocation.getLocation(this, locationResult);
}
@Override
public void onDestroy() {
Log.v(ApplicationName, "SensingService.onDestroy");
super.onDestroy();
if (mSensorManager != null) {
mSensorManager.unregisterListener(this);
}
}
@Override
protected void onHandleIntent(Intent intent) {
Log.v(ApplicationName, "SensingService.onHandleIntent");
if (mSensorManager != null) {
registerListeners();
}
}
public LocationResult locationResult = new LocationResult() {
@Override
public void gotLocation(final Location location) {
if (location != null) {
Log.v(ApplicationName, "Location != null : (" + location.getLatitude() + "," + location.getLongitude() + ")");
} else {
Log.v(ApplicationName, "Location == null : (0,0)");
}
}
};
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent currentEvent) {
if (currentEvent.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) {
return;
}
synchronized (this) {
float[] accelVals = null;
float totalForce = 0.0f;
int sensor = currentEvent.sensor.getType();
System.arraycopy(currentEvent.values, 0, mAccelerationValues, 0, 3); // We use System.arraycopy because of this:
switch (sensor) {
case Sensor.TYPE_ACCELEROMETER:
sensorType = "Accelerometer";
totalForce = SensorsHelpers.getTotalForceInGs(mAccelerationValues);
break;
case Sensor.TYPE_LINEAR_ACCELERATION:
sensorType = "LinearAcceleration";
totalForce = SensorsHelpers.getTotalForceInGs(mAccelerationValues) + 1;
break;
case Sensor.TYPE_GRAVITY:
totalForce = SensorsHelpers.getTotalForceInGs(mAccelerationValues);
sensorType = "Gravity";
break;
}
Log.v(ApplicationName,DateHelper.GetUTCdatetimeFromDate(new Date()) + " - from sensingService");
}
}
private void registerListeners() {
Log.v(ApplicationName, "Registering sensors listeners");
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION), SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY),SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);
}
}
ATUALIZAÇÃO 2
Agora eu adicionei este no método onCreate:
int NOTIFICATION_ID = 1;
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 1, intent, 0);
Notification notification = new Notification(R.drawable.ic_dialog_info, "Running in the Foregound", System.currentTimeMillis());
notification.setLatestEventInfo(this, "Title", "Text", pi);
notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;
startForeground(NOTIFICATION_ID, notification);
para iniciá-lo como startForground, mas coloca o ícone na barra de notificação e, em seguida, onDestroy é chamado no serviço e o ícone de notificação desaparece.
Eu estou desesperado agora!Por favor, ajude um presente!
Obrigado!Guillermo.
Solução 2
Ok, eu vi uma resposta para outra pergunta, e há um cara que disse que é um bug no Android, eu segui a sua sugestão para mover o código para onCreate em vez de onHandleIntent e funcionou!Assim, se não um show para mim é um problema com o meu código, para mim ele vai ser um bug.Obrigado!
Outras dicas
Como por IntentService documentação:
o serviço é iniciado, conforme necessário, alças de cada Intenção, por sua vez, utilizando um thread de trabalho, e pára automaticamente quando ele é executado fora do trabalho
Também, de acordo com a mesma documentação, você não deve substituir onStartCommand()
e onDestroy()
em seu IntentService
, Eu suponho, porque ele implementa seu próprio comportamento especial, conforme especificado acima.Talvez você precisa para ampliar Service
em vez de IntentService
.