La surveillance collante et des capteurs d'intensification s'arrête alors qu'elle ne devrait pas dans Android

StackOverflow https://stackoverflow.com/questions/9501163

Question

Dans mon application, je vérifie certaines conditions, puis je commence une activité comme ceci:

Intent startIntent = new Intent(getApplicationContext(), EnableLocationProviderActivity.class);
startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(startIntent);

À partir de cette activité, je commence un service d'intention qui enregistre certains auditeurs pour les capteurs, il est démarré comme collant, ce qui signifie qu'il doit être arrêté explicitement. Cette intention surveille surveille les capteurs.

Mon problème est que lorsque je reviens à la première activité, les capteurs ne sent plus (je mets un log.v dans onSensorChanged (le début affichant les données, puis il s'arrête).

Pourquoi cela pourrait-il s'arrêter si je ne l'avais pas arrêté explicitement? De plus, je vois parfois que l'appel de l'intention de l'entretien, mais encore une fois, comment peut-il être appelé s'il est collant et que je n'ai pas appelé Stopelf () et je ne m'arrêtais pas autrement?

Merci! Guillermo.

ÉDITER

Ceci est le code de l'intervention (qui devrait s'exécuter tout le temps, malgré le fait que le téléphone portable s'endort ou si le bouton d'accueil est enfoncé (je sais sur la batterie et tout le reste, l'utilisateur sera averti à ce sujet et aura l'oportunité pour fermer la demande quand il veut.

Le service est appelé de mainactivité comme ceci:

Intent startIntent = new Intent(GdpTesisApplication.getInstance().getApplicationContext(), SensingService.class);
startService(startIntent);

Et le code de service est celui-ci:

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);
    }
}

MISE À JOUR 2

Maintenant, j'ai ajouté ceci sur la méthode 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);

Pour le démarrer comme StartForground, mais il met l'icône dans la barre de notification, alors onDestroy est appelé dans le service et l'icône de notification disparaît.

Je suis désespéré maintenant! Aidez-vous dans celui-ci!

Merci! Guillermo.

Était-ce utile?

La solution 2

OK, j'ai vu une réponse à une autre question, et il y a un gars qui a dit que c'était un bug dans Android, j'ai suivi sa suggestion de déplacer le code vers ONCreate au lieu de la main-d'œuvre et cela a fonctionné! Donc, si personne ne me montre, c'est un problème avec mon code, pour moi, ce sera un bug. Merci!

Autres conseils

Selon Documentation InterService:

Le service est démarré au besoin, gère chaque intention à son tour en utilisant un fil de travail, et s'arrête quand il manque de travail

De plus, selon la même documentation, vous n'êtes pas censé remplacer onStartCommand() et onDestroy() dans ton IntentService, Je suppose car il implémente son propre comportement spécial comme spécifié ci-dessus. Peut-être que vous devez étendre Service à la place de IntentService.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top