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.

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top